QUICKUPSCALE

PRACTICAL GUIDE

Tilesets, animation and atlas handoff

Reflow a tileset without changing its tile order

Start here

Split the original strip into twelve 16 × 16 frames, keep their numeric order, then build a four-column sheet. In Tiled, keep tile size 16 × 16, margin 0, spacing 0 and tile count 12; change columns from 12 to 4 and image size from 192 × 16 to 64 × 48. Every local ID must still name the same tile.

Expected result:

The supplied before and after maps keep identical numeric GIDs and produce identical native renders. A deliberately wrong order changes ten tile identities even though the first and last tiles still look right.

What you need

Download the original CC0 192 × 16 numbered strip, or extract the editable project below. It includes the untouched source, actual browser-exported 64 × 48 sheet, their manifests, three tilesets and three maps. Tiled opens the included files without Node or Python. Optional source generation requires Node 24; optional independent verification also needs Python and Pillow.

Tested with: Tiled 1.12.2, Qt 6.10.2, macOS arm64; native JSON tileset/TMX readers and bundled TmxRasterizer 1.0. Actual U02/U03 browser exports were consumed. No editor-dialog interaction or GUI screenshot is claimed.

1. Split the original strip without changing the cells

Open the sprite-sheet splitter with the supplied strip. Set cell width and height to 16, all four outside margins to 0, and both gaps to 0. Select all twelve cells. Inspect the first and last previews, then download the complete frame ZIP.

The strip contains one row: local ID 0 starts at (0, 0), and ID 11 starts at (176, 0). Each frame stays 16 × 16. Keep the numbered filenames and the manifest; renaming frames can change the order in a later assembly step.

Original numbered strip containing twelve tiles in one row
Original 192 × 16 input. The small alpha probes are part of each tile and are preserved in the source file.

2. Assemble the same sequence into four columns

Extract the frame ZIP and select its twelve PNGs in the sprite-sheet maker. Use natural filename order, strict equal-sized frames, top-left placement and a grid with four columns. Confirm the displayed sequence before exporting the PNG and manifest.

The result is 64 × 48: four 16 px columns and three 16 px rows, without gutters or outside margins. The actual exported PNG included here was independently compared with every real splitter output. All twelve cell rectangles and their decoded pixels match those frames.

Actual browser maker export with twelve numbered tiles arranged in four columns and three rows
Untouched actual 64 × 48 browser export. The maker manifest describes its layout; it is not a Tiled tileset file.

Compare order independently of dimensions. A valid 64 × 48 PNG can still assign different artwork to the same tile IDs.

3. Update image geometry while keeping the map IDs

Open reflow.tiled-project, then compare before.tmx and after.tmx. Their external JSON tilesets, before.tsj and after.tsj, explicitly reference their matching images. Both retain tile width/height 16, margin/spacing 0 and tile count 12. The after tileset declares four columns and a 64 × 48 image.

{"columns":4,"tilecount":12,"tilewidth":16,"tileheight":16,
 "margin":0,"spacing":0,"image":"inputs/pipeline12.png",
 "imagewidth":64,"imageheight":48}

The maps keep firstgid=1 and the same stored GIDs. Global ID 0 is empty; GIDs 1–12 refer to local IDs 0–11 in this single-tileset example. Changing the sheet shape does not require changing those IDs when row-major artwork order is preserved.

Selected 16 × 16 source rectangles, using top-left pixel coordinates
Local IDBefore: 12 columnsAfter: 4 columns
0(0, 0)(0, 0)
3(48, 0)(48, 0)
4(64, 0)(0, 16)
11(176, 0)(48, 32)

Inspect all twelve tiles, especially the row transition from ID 3 to ID 4. The recorded native procedure loaded and reread each TSJ and TMX. It checked every local ID and rectangle, repeated map tiles and an empty cell. This does not demonstrate an in-place editor replacement workflow or automatic migration of terrain, collision shapes or custom properties.

4. Compare actual map renders, then break the order deliberately

The supplied map places all twelve local IDs in a nonsequential arrangement, repeats IDs 0 and 11, and leaves one cell empty. Its actual native before and after renders are identical at 80 × 48. The renderer's nearest 4× outputs also match exactly at 320 × 192.

Actual Tiled native map render after four-column reflow, matching the original-strip map
Actual 320 × 192 native after render. The before render is byte-identical.

Now open or render wrong.tmx. Its generator-created control repacks the actual maker image in order [0,4,8,1,5,9,2,6,10,3,7,11]. This is not a browser export. IDs 1–10 now name different artwork, while first ID 0 and last ID 11 still match. The actual native map differs at 82 of 3,840 pixels.

Actual native wrong-order map render where internal tile IDs now select different artwork
Actual wrong-order native output. Checking only the first and last tiles would miss this failure.

Restore the unchanged ordered maker PNG and matching after.tsj, then compare every ID again. Do not fix an ordering error by randomly changing map GIDs.

tmxrasterizer --no-smoothing --scale 4 after.tmx /absolute/output/after.png
python3 verify.py --tiled /absolute/path/to/Tiled.app/Contents/MacOS/Tiled \
  --archive /absolute/new/evidence --zip dist/tiled-reflow-t30.zip

The optional verifier uses Tiled's --project and --evaluate reader, requires a fresh matching run ID, and invokes the bundled rasterizer for all three maps at 1× and 4×. Tiled 1.12.2 can exit 0 after a script exception; exit status alone does not establish success. The recorded project ZIP was freshly extracted and actually read and rendered.

5. Keep the measured transparent-RGB boundary visible

Native render equality does not prove raw original RGBA preservation. The actual browser path changes RGB at four probe pixels per tile: 48 pixels / 108 RGB channels across the strip, with alpha unchanged. Three of each tile's changed pixels have nonzero alpha.

Measured RGBA probes in each original tile and its actual browser export
OriginalBrowser
100,150,200,00,0,0,0
123,45,67,10,0,0,1
76,139,201,8575,138,201,85
224,80,48,128223,80,48,128

Qt rendering of the original strip produces the same observed conversion, which explains the equal native maps. The independent Pillow check records these differences without changing either PNG. Keep the original when hidden or low-alpha RGB matters. This example establishes tile identity, geometry and the supplied native renders, not byte-identical PNG encoding or lossless raw RGBA through Canvas.

The example uses one tileset, no flip flags and fixed 16 × 16 cells. It does not test multiple-tileset lookup, arbitrary art, filtering seams in another engine, animated tiles, collision metadata or editor remapping. For padded inputs, first follow Tiled margin and spacing settings.

Sources and next steps