Batch Conversion

Batch conversion turns a folder of source images into a folder of NextDAAD files in one run, under a single preset. It lives behind a switch in the same window as the preview, not a separate tool: the settings on the control rail are exactly the settings a batch run will use, so being able to see them while you queue images is the point of keeping the two together.

One preset applies to every row in a run - there is no per-row override. If two pictures need different settings, run them as two separate batches.

Switching to Batch

Click Batch next to Preview at the top of the central panel to show the queue table instead of the preview panes. The switch only changes which panel is drawn: a run in progress keeps converting while you are looking at Preview, and switching back to Batch shows exactly the progress that would have happened had you never left. Dragging a rail control while Batch is running does not touch the run either - the settings for that run were fixed the moment you pressed Run.

Adding images

Add folder... reads every file in the chosen folder and queues the ones whose extension matches png, bmp, jpg, jpeg, tif, tiff or webp, case-insensitively - the same list the Open dialog's filter matches, and the same list the command line uses. Anything else in the folder - a text note, a .psd, a readme - is left out silently; it simply never appears as a row.

Add files... opens a file-picker dialog instead, for queuing specific images one selection at a time.

Each queued row also has its own Remove button. Both add buttons, Run and Remove are all disabled while a run is in progress or while the overwrite question below is on screen, because editing the row list at either of those moments would let the queue disagree with the run already under way.

The resolved name column

Every row shows its source stem followed by a dimmer -> <name> - the file that row will actually be written as, given the naming pattern and export formats currently set in the Out tab. It is recomputed whenever the row list changes or a rail setting changes, so it always reflects what a run right now would produce, never what was true when the row was added.

Two rows whose sources share a stem - the same filename kept in two different source folders, say - resolve to the same name and are not individually flagged as wrong: the column shows each row's own name with no notion of what any other row produces, so both look fine on their own. The collision is real, though, and it is caught the moment you press Run - see below.

Naming for the authoring kit

NextDAAD's authoring kit stages an already-converted picture dropped into a game's IMAGES\ folder by reading everything before the first dot in its filename as the picture's number (authoring-kit\lib\gfx.bat, the :stage_picture routine). That number must be digits only, at most three of them, and is padded to three, so 1.NX2 loads as picture 001. A name that is not a picture number is not skipped: it stops the whole build with an explicit error (:stage_picture_bad). A title screen is the one file exempt from numbering - it belongs in the kit folder's root as DAAD.NX2/DAAD.NXI, not in IMAGES\.

This is exactly what a batch run's naming pattern has to produce. The built-in "NextDAAD Layer 2" preset's pattern is {stem}.{ext} - it keeps each source filename verbatim, so a folder of kitchen.png, cellar.png and so on comes out as kitchen.NX2, cellar.NX2 - not picture numbers, and the build fails the moment it meets one. That pattern only produces a valid number if your source files are already named with one (012.png stays 012.NX2). The {n:3} pattern sidesteps this for the ordinary case: it resolves to a zero-padded number - the leading digits of the row's own stem if it has any, otherwise the row's position in the queue - padded out to at least three digits, but not cut down to three if there are more. A stem that already starts with four or more digits, such as 2024_hallway.png, resolves to 2024.NX2 rather than a three-digit number, which the kit's build rejects exactly as it rejects kitchen.NX2. Check the resolved name column above before running a folder of already-numbered or date-stamped source files, to see the actual output name rather than assuming {n:3} has capped it. Two rows whose stems both start with the same digits still resolve to the same number and collide - see that same column, and the pre-flight check below.

Running

Pressing Run does not start converting straight away, and the first time you press it in a session it does not even know where to write to yet: with no output folder chosen, Run opens a native folder-picker dialog and asks. Once you choose a folder it is remembered for the rest of the session - later presses of Run reuse it without asking again - and it is shown beside the toolbar buttons as output: <dir>.

With the output folder settled, Run runs a pre-flight check that is only file stats and preset validation, so it completes instantly however long the batch itself will take.

The pre-flight checks

Four things are checked, in this order, before anything is written:

  • A transparency slot other than 255. If the loaded preset's transparency slot is set to anything but 255, the run refuses outright:

    This preset puts transparency on palette slot 200. Only slot 255 works: the interpreter stamps that entry on load and leaves it alone, and shifts every other one, so pixels you painted #FF00FF would come out opaque and the holes would never appear. No files were written.

    A preset with no transparency slot at all is not refused - that is legitimate artwork with no holes. See Transparency for why slot 255 is the only one that works, and for what this check does and does not cover on the single-image Save As path.

  • An unwritable output folder, checked once rather than as one identical failure per row: "The output folder cannot be written to: <reason>. No files were written."

  • An invalid naming pattern - one that cannot produce a valid filename for some row: "The naming pattern cannot produce a valid filename: <reason>. No files were written."

  • Duplicate targets. If two rows would write to the same path, the run refuses before converting anything:

    Two outputs would both be written to <output folder>\photo.NX2: formats Bitmap and Bitmap. Change the naming pattern or the format list so each has its own path. No files were written.

    This is the same collision the resolved name column above can show you in advance; the pre-flight is what actually stops the run over it.

Every one of these refusals ends the same way: nothing is written. An amber line names the problem, with a Dismiss button beside it.

The overwrite question

If the pre-flight passes but some of the outputs already exist, you are asked before anything is converted, not partway through the wait:

N of the outputs already exist.

with three buttons: Replace them, Skip them and Cancel. The question is asked up front because checking whether a file exists is a stat, and the conversion itself can be minutes - being asked something you could have answered before the wait, two minutes into the wait, is exactly what a batch exists to avoid. Whichever you choose, the run then proceeds start to finish with no further interruption.

While it runs

Row states

Each row is queued, running, or settled to an outcome:

  • A queued row reads "queued" and offers Preview and Remove.
  • A running row shows a spinner and the word "running", and offers neither button - it may finish at any moment.
  • A settled row shows what happened: written: <file names> for a success, skipped - the output already existed for a skip, failed: <error> in amber for a failure, or cancelled. A settled row's outcome text always says why, never just "done" or "failed" with nothing else - scanning twenty-four rows for the one that went wrong depends on it. A settled row offers Inspect instead of Preview or Remove.

The header above the table gives the aggregate: N of N complete, N skipped, N failed, N cancelled.

Cancel

Pressing Cancel does not stop the run instantly. Core lets a row already in flight finish rather than aborting it mid-write, so the button's own label says so: Cancelling - finishing N images already started, where N counts down to zero as those rows land. With ZX0 ticked in the Out tab - about 8.6 seconds per 320x256 image - that can be several real seconds in which nothing visibly changes; the wait is real, not a stall. Every row that had not yet started settles as cancelled rather than failed, since nothing went wrong - you asked to stop. The window stays fully responsive throughout.

Clear

Clear empties the row list. It sits after Run and Cancel, and unlike Run it stays clickable on an empty queue - there is simply nothing for it to do. It is disabled under the same condition as Add folder, Add files and Run: while a run is in progress, or while the overwrite question above is on screen. Clearing the row list does not touch the remembered output folder or the run's own state; it removes rows, nothing else.

Preview and Inspect

Preview, on a queued row, and Inspect, on a finished row, look similar but answer different questions.

Preview loads that row's source image into the Preview tab and converts it under whatever is on the rail right now. It answers "what would this look like if converted with today's settings" - useful for checking a row before you commit to a run. It changes nothing else: no preset is applied, no notice appears, and if the preset status line already read "(modified)" it still does afterwards.

Inspect loads a finished row's source image and restores the exact settings that run actually used - the preset and any frozen palette snapshotted the moment you pressed Run - not whatever the rail happens to show now. It answers "what did this row actually produce". Because this replaces whatever was on the rail, it says so: "Inspect applied the batch's settings, replacing what was on the rail". Once loaded, zoom, pan, the split/flip controls and the palette dock all work on it exactly as they do on any image opened through Open.