Tileset Slicer — Detect Tile Size, Margin and Spacing
Drop a tileset and the Studio measures candidate grids from the pixels — including the sizes where a known autotile layout fits exactly — and shows the best one as a dashed preview until you use it.
To cut a tileset you need three numbers per axis: the tile size, the margin (pixels before the first tile) and the spacing (pixels between tiles). The count is columns = floor((width − margin + spacing) ÷ (tile + spacing)), and the same for rows: Kenney Tiny Dungeon's 203 × 186 px sheet with 16 px tiles and 1 px spacing gives 12 × 11 = 132 tiles. The Studio measures these numbers from the pixels, shows the best grid dashed until you press Use this grid, and carries it into the Godot 4, Tiled, Unity and LDtk exports; a ZIP of single tile PNGs comes from the classic tile grid slicer.

- Godot 4 TileSetVerified· Godot 4.7.2
- TiledVerified· Tiled 1.12.2
- Unity 6 Rule TileVerified· Unity 6000.5.3f1 + 2D Tilemap Extras 8.0.3
- LDtkPartly verified· LDtk 1.5.3 schema + loader
The grid model, the formula, and how the numbers are measured
Every tile has the same size. The margin is skipped once before the first column (and row), the spacing sits between two neighbouring tiles, and nothing is assumed after the last tile. Tile (c, r) therefore starts at x = margin + c × (tile + spacing), y = margin + r × (tile + spacing). Godot names the same numbers Texture Region Size, Margins and Separation; Tiled names them tile size, Margin and Spacing.
n tiles need margin + n × tile + (n − 1) × spacing pixels, so the most that fit is floor((W − margin + spacing) ÷ (tile + spacing)). With the same margin on both sides the textbook form (W − 2 × margin + spacing) ÷ (tile + spacing) comes out exact; Nerulio's floor gives the same count whenever the leftover strip on the right is narrower than one tile plus spacing, which is also why a sheet with a few spare pixels still slices cleanly.
The detector reads the image one line at a time: how much each row and column differs from the previous one. It folds that profile at every period from 4 px to half the image and keeps the periods that explain the most of its variation, then checks the phase, and demands that every line a margin or spacing claims is really blank or flat. When the first or last line of every tile is blank, "16 px + 1 px spacing" beats "17 px tiles"; a multiple of the true size loses when a divisor scores within 0.02 of it. The Studio also tries the sizes at which a published autotile layout fits exactly.
It is weakest where a sheet gives no separators: packed tiles whose interiors are busier than their borders. It cannot measure one tile per axis, and the Studio measures images up to 16 megapixels; above that, type the size.
- Tile size
- Width and height of one tile in pixels (Godot: Texture Region Size).
- Margin
- Pixels before the first tile, at the left and top edge.
- Spacing
- Pixels between two neighbouring tiles (Godot: Separation). Often 1 px, sometimes extruded border pixels.
- Packed sheet
- Tiles edge to edge, no spacing: the easiest for other editors, the hardest to measure.
Example: two Kenney sheets from the test corpus
Measured with Nerulio's grid detector on the CC0 files (2026-09-28):
Kenney Tiny Dungeon tilemap.png 203 × 186 px 16 px tiles, 1 px spacing, margin 0
columns = floor((203 − 0 + 1) / (16 + 1)) = floor(204 / 17) = 12
rows = floor((186 − 0 + 1) / (16 + 1)) = floor(187 / 17) = 11 → 132 tiles
tile 13 = column 1, row 1 → x = 0 + 1 × 17 = 17, y = 17, size 16 × 16
detected: 16 × 16, spacing 1, 12 × 11, score 0.976 (high)
tilemap_packed.png 192 × 176 px same tiles, no spacing → 192 / 16 = 12, 176 / 16 = 11
detected: 16 × 16, 12 × 11, but score 0.514 (low): no blank line between tiles
Kenney Pixel Platformer tilemap.png 379 × 170 px → (379 + 1) / (18 + 1) = 20, (170 + 1) / 19 = 9
its tiles are 18 px, not 16: detected 18 × 18, spacing 1, 20 × 9, score 0.946 (high)The same art scores 0.976 with gaps and 0.514 without them: blank separator lines are the strongest evidence a sheet can give. On a packed sheet, look at the dashed grid before you press Use this grid, or type the size you know.
What it does
- Grid candidates with tile size, margin and gap, each with a confidence; published autotile layouts that fit are named.
- Blank tiles are counted and dimmed; several tilesets per project (one per sheet).
- Type the grid yourself when you already know it.
- The tileset exports with its grid to Godot 4, Tiled, Unity and LDtk, together with any terrain bits.
How to do it
- Drop the tileset.
- Check the grid candidates and press Use this grid.
- Optionally recognise an autotile layout or paint terrain bits.
- Export for your engine.
Check the grid before you use it
- The dashed lines sit in the gaps all the way to the last column and the last row. If they are right on the left and wrong on the right, the tile size or spacing is off.
- Columns × rows match what you expect (12 × 11 = 132 for Tiny Dungeon), and the tiles counted as blank are really empty.
- After export, Godot's atlas shows the same Texture Region Size, Margins and Separation; Nerulio's Godot export with margin 1 and spacing 2 reached
TileSetAtlasSourceunchanged in Godot 4.7.2. - For single tile PNGs, the classic slicer's tiles are copied region by region, never resampled: each one equals its source rectangle byte for byte.
Troubleshooting
| Symptom | Likely cause | How to check | Fix |
|---|---|---|---|
| Tiles drift further off with every column | Wrong tile size: Pixel Platformer's 18 px tiles read as 16 px + 1 px put tile c at 17 × c instead of 19 × c, 2 px more off per column | The grid fits the first column and misses the tenth by 18 px | Take the candidate with 18 px, or type tile 18, spacing 1 |
| Every tile is cut 1 px too far up and left | A border was not declared as margin | The first row and column of the image are blank or one flat colour | Set margin 1; the count formula subtracts it once |
| A partial column or row is left at the right or bottom | The tile size does not divide the sheet; the floor drops anything narrower than one tile plus spacing | Compute (W − margin + spacing) ÷ (tile + spacing): it should be a whole number or just above one | Recheck the tile size; a remainder of many pixels means the reading is wrong, not the sheet |
| The top candidate is only low or medium | A packed sheet: nothing blank between tiles, and busy tile interiors | Score and confidence next to each candidate | Confirm the dashed grid, pick another candidate, or type the size |
| No candidates at all on a huge image | The Studio measures sheets up to 16 megapixels | Image width × height | Type the tile size, margin and spacing by hand |
| Another editor refuses the sheet | Some editors take no spacing: Sprite Fusion asks that the tileset width and height be exact multiples of the tile size | Does W ÷ tile give a whole number? | Use the packed version of the sheet, or repack it without gaps |
Other ways to do it
| Option | When it is the better choice |
|---|---|
| Type the numbers in the engine: Godot's atlas (Texture Region Size, Margins, Separation) or Tiled's new-tileset dialog (tile size, Margin, Spacing) | You already know the grid, for example from the asset pack's readme. |
| The classic tile grid slicer | You want every tile as its own PNG, exact and near duplicates found, rotated and flipped variants, or an extruded atlas against bleeding. |
| The sprite slicer | The sheet has sprites of different sizes with no grid; tile slicing needs a regular grid. |
Engine exports and how each was checked
"Verified" means the exported files were loaded by the real engine or tool on real CC0 assets and the result was compared with the source. Anything that was not loaded is labelled as such.
| Target | Files | Check |
|---|---|---|
| Godot 4 TileSet | PNG · nerulio-tileset.json · nerulio_tileset_import.gd | Verified Godot 4.7.2The included import script builds the TileSet with terrain peering bits; a map painted with set_cells_terrain_connect equals the Studio preview in every cell on 9 corpus sheets. |
| Tiled | .tsx Wang set · sample.tmx | Verified Tiled 1.12.2Tiled's own readers load every Wang ID as written and the sample map renders pixel-exact. The terrain brush itself was not driven. |
| Unity 6 Rule Tile | nerulio-ruletile.json · Editor/NerulioRuleTileImporter.cs | Verified Unity 6000.5.3f1 + 2D Tilemap Extras 8.0.3Blob and side sets: a painted Tilemap shows the predicted sprite in every cell. Corner / dual-grid sets are not exported to Unity. |
| LDtk | .ldtk (1.5.3) · rules · sample level | Partly verified LDtk 1.5.3 schema + loaderAccepted by the LDtk JSON schema and its official loader, and the rules re-run to the exported tiles; not opened in the LDtk app. |
Evidence
Layouts identified from the pixels alone on the tile corpus: 4 blob-47 templates and 2 Wang templates with high confidence, a real 64 px cave tileset with medium confidence — every tile's bits right. Godot 4.7.2 painted every test cell exactly as the Studio predicted (485/485 per blob set, 251/251 on a 4-terrain dual-grid pack); Tiled 1.12.2 read every Wang ID back; Unity 6000.5 matched on every painted cell of the blob and side sets.
Limits
- Regular grids only; isometric or hexagonal sheets are not modelled.
- The Studio does not write one PNG per tile; that stays in the classic slicer.
- A sheet with a single tile per axis has no period to measure.
- Tiled's terrain brush, the LDtk app and Godot's editor painter were not driven; the checks use the engines' readers and set_cells_terrain_connect.
- Unity gets blob and side sets only; several terrains become several Rule Tiles with no transitions between them.
- Isometric and hex tiles, animated tiles, occlusion and navigation layers are out of scope.
- Suggesting bits without a known layout needs a reference "full" tile; on side-only path templates the guess can fail until you select it.
Versions and sources
The formula and the rectangles are those of tileRects in src/game/tile-grid.js; detection was checked on 10 synthetic sheets (true grid first in 10 of 10) and the Kenney numbers above were measured on the corpus files on 2026-09-28. The Godot 4.7.2 run of 2026-09-22 read margin 1 and separation 2 back from the built TileSet. Engine field names follow the linked documentation.
Official documentation used
Classic tool
A ZIP of single tile PNGs and duplicate-tile detection are still in the classic Tile Lab.
Open the classic tool →Questions
Can I download every tile as its own PNG?
Not from the Studio. The classic Tile Lab linked below still exports a ZIP of single tiles.
What about sheets with a 1 px gap between tiles?
Margin and spacing are part of every grid candidate and of the exported tileset.
Is it free, and do I need an account?
Everything on these pages is free and works without an account. There is no watermark and no export that is held back.
Are my sprites uploaded?
No. The Studio decodes, packs and exports in this browser tab. Projects are autosaved in the browser (IndexedDB) and can be saved as a .nerulio file.
Does it need Aseprite or an engine plugin installed?
No. .aseprite files are read and written in the browser, and each engine bundle carries what that engine needs (for Godot, the import settings and scene; for Unity and the Godot TileSet, a small editor script).