Godot 4 Autotile & Terrain Set Generator — Peering Bits Set for You
Setting 47 × 8 peering bits by hand is where Godot 4 terrains go wrong. The Studio recognises the sheet's layout, writes the bits, shows which combinations are missing, and paints a test map exactly as set_cells_terrain_connect will.
Godot 4 has no "autotile" tile type any more: autotiling is a terrain set on the TileSet (match mode Match Corners and Sides, Match Corners or Match Sides), terrains inside it, and on every tile a terrain plus peering bits that say which terrain each neighbour must have. A 47-tile blob sheet needs 188 connected bits set on the right tiles. Nerulio reads the layout from the pixels, sets the bits and ships a GDScript that builds the TileSet inside Godot; you then paint with the Terrains tab or call set_cells_terrain_connect(). Verified in Godot 4.7.2.

- 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
Terrain sets, match modes and peering bits
The Godot 4.7 documentation calls terrains "a more powerful replacement" of Godot 3 autotiles. A TileSet owns terrain sets; each set has a mode that decides which neighbours count, and one or more terrains (name and colour). Each tile then gets a Terrain Set and a Terrain ID (both start at 0; −1 means none) and, per neighbour position, a peering bit: the terrain expected there, or −1 for empty. The docs' own example: a tile whose bits are all 0 only appears when all 8 neighbours are terrain 0.
The mode follows the art. A 47-tile blob set draws inner corners, so it needs Match Corners and Sides (all 8 positions). A 16-tile side set or a 3 × 3 box only cares about the four sides: Match Sides. A 16-tile corner set (Wang 2-corner, the dual-grid 4 × 4) needs Match Corners. Why 47 and not 256: a corner only matters when both sides next to it connect, so the 256 possible neighbourhoods of a cell reduce to 47 different tiles.
When you paint, Godot chooses for each cell the tile whose bits agree best with the neighbours. The TileMapLayer reference warns that this needs "all required terrain combinations"; when one is missing, Godot quietly draws the closest tile or leaves the cell empty — the most common reason a Godot terrain "does not work" (see wrong Godot terrain tiles).
- Terrain set
- A group of terrains that match each other under one mode; a tile belongs to one terrain set.
- Match Corners and Sides / Match Corners / Match Sides
- The three modes: which of the 8 neighbour positions a tile's bits describe.
- Peering bit
- Per neighbour position (named after
TileSet.CellNeighbor, e.g.top_right_corner): the terrain ID expected there, −1 = empty. set_cells_terrain_connect- The
TileMapLayermethod that paints terrain from code and updates neighbouring cells, the same matching the Terrains tab uses.
Example: one cell, eight neighbours, one tile
A map where X is ground and C is the cell being painted. The cr31 mask adds a weight for every ground neighbour:
map . X X
X C .
. X .
weights N 1 NE 2 E 4 SE 8 S 16 SW 32 W 64 NW 128
raw mask N + NE + S + W = 1 + 2 + 16 + 64 = 83
NE counts only when N and E are both ground; E is empty, so NE drops
tile mask 1 + 16 + 64 = 81 (one of the 47)
Godot tile terrain 0; top_side 0, bottom_side 0, left_side 0; the other 5 bits −1
whole set 47 tiles, 188 bits set to 0 (every other bit stays −1)In nerulio-tileset.json that tile reads "peering":{"top_side":0,"bottom_side":0,"left_side":0}; a missing name means −1. The import script maps each name to its TileSet.CellNeighbor constant and calls TileData.set_terrain_peering_bit().
What it does
- Recognises blob-47 (five published orders), 16-side, 16-corner / dual grid and 3×3 layouts from seam continuity, with a confidence.
- Match modes corners-and-sides, sides and corners; several terrains per set.
- The Check panel lists missing combinations — the tiles Godot would otherwise silently substitute.
- Export: PNG + JSON + nerulio_tileset_import.gd, which builds the TileSet with terrains in Godot (verified in 4.7.2).
How to do it
- Drop the autotile sheet.
- Use the grid, apply the best layout candidate.
- Check it, paint a test map with the Godot rule.
- Export for Godot 4 and run the import script in the editor.
Files you get
The Godot folder of the export ZIP, shown for a sheet called cave.png (the same ZIP also holds Tiled, LDtk, Unity and generic folders plus NOTES.txt):
| File | What it is for |
|---|---|
cave.png | The tileset image, unchanged. |
nerulio-tileset.json | Tile size, margins, separation, the terrain set (mode, terrain names and colours) and for every tile its atlas coordinates, terrain and peering bits; collision polygons and probability when you set them. |
nerulio_tileset_import.gd | An EditorScript whose Builder class creates the TileSet through Godot's own API and saves res://nerulio-tileset.tres. No hand-written .tres is shipped. |
README.txt | The steps below for this set, with its mode and tile count. |
Build the TileSet in Godot 4 and paint with it
- Copy the PNG,
nerulio-tileset.jsonandnerulio_tileset_import.gdinto the project root. The script readsres://nerulio-tileset.jsonand writesres://nerulio-tileset.tres; if you keep them in a subfolder, changeJSON_PATHandOUTPUT_PATHat the top of the script. - Wait until the FileSystem dock has imported the PNG, open the script in the script editor and run File › Run (Ctrl+Shift+X). The Output panel prints a line such as
Saved res://nerulio-tileset.tres: source 0, 47 tiles, 188 peering bits, 0 collision polygons, mode match_corners_and_sides. - Add a
TileMapLayernode and loadnerulio-tileset.tresinto its Tile Set property. - With the layer selected, open the TileMap panel at the bottom, switch to the Terrains tab, pick terrain set 0 and your terrain, choose Connect mode and paint. Path mode connects only the cells of one stroke.
- From code, paint a whole area at once:
$TileMapLayer.set_cells_terrain_connect(cells, 0, 0)wherecellsis anArray[Vector2i], 0 the terrain set and 0 the terrain. - For pixel art, set the layer's Texture › Filter to Nearest (or the project's default canvas texture filter); see blurry pixel art in Godot.
Check the result
- The Output line counts the tiles and bits: 47 tiles and 188 bits for a blob set, 16 tiles and 32 bits for a 16-side or 16-corner set.
- TileSet editor › Select mode › click a tile: the Terrains section shows Terrain Set 0, Terrain 0, and the peering bits are drawn over the tile.
- Paint a 3 × 3 square and a single cell: the square gets 9 different tiles (4 corners, 4 edges, the centre), the single cell the isolated tile.
- Paint the same shape on the Studio's test map with the Godot rule: Godot 4.7.2 put the same tile in every cell in our runs.
Troubleshooting
| Symptom | Likely cause | How to check | Fix |
|---|---|---|---|
The script prints Cannot read res://nerulio-tileset.json | The files sit in a subfolder or the JSON was renamed | Output panel, first line | Move the three files to res://, or edit JSON_PATH and OUTPUT_PATH in the script and run it again |
| Warning: the PNG "was not imported yet, so its pixels are embedded" | The script ran before the editor imported the image | The .tres is much larger than the PNG | Let the FileSystem dock finish importing, then run the script again so the TileSet points at the imported PNG |
Tile (x, y) is outside the … atlas grid; skipped | The PNG in the project is not the exported one, or the grid (margin, spacing) was set wrong before export | Compare the image size with the grid shown in the Studio's Tileset panel | Fix the grid, export again and replace both PNG and JSON |
| Painting leaves empty cells or wrong corners | The set lacks a combination; Godot substitutes the closest tile or none | Studio Check panel: combinations present / expected, ghost tiles | Draw or generate the missing tiles, then export again |
| The Terrains tab shows nothing to paint | The layer uses another TileSet, or tiles have no Terrain Set | Tile Set property of the TileMapLayer | Load nerulio-tileset.tres into that layer |
| Tiles look soft when zoomed | Linear texture filtering on the layer | Zoom the 2D viewport and look at pixel edges | Set Texture › Filter to Nearest on the layer or project-wide |
Other ways to do it
| Option | When it is the better choice |
|---|---|
| Set the bits by hand in Godot's TileSet editor (Select mode, Terrains section; or tile property painting to apply one value to many tiles) | A handful of tiles, or a sheet in no layout Nerulio knows. No extra files, but a blob set means 47 tiles to configure one by one. |
| Check or complete the set first with the autotile tester or the tileset generator | Your sheet is incomplete or you only have a small source block. |
| Draw the map in Tiled with a Wang set and export it with Tiled's Godot 4 exporter (since Tiled 1.10) | You design levels in Tiled and only need the finished map in Godot. |
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
- One terrain set per export (up to 16 terrains inside it); isometric and hexagonal tiles, animated and alternative tiles are not written.
- The Godot editor's terrain brush was not driven by our tests;
set_cells_terrain_connect, which it uses, was. - Corner (dual-grid) sets are drawn on the cells in Godot, not half a tile off: see dual-grid tilesets.
- 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
Verified in Godot 4.7.2: the shipped importer built each TileSet headless, the resource was reloaded and painted with set_cells_terrain_connect, and every painted cell equalled the Studio's prediction — 485/485 cells on each blob set of the corpus, 251/251 on a four-terrain dual-grid pack. Editor menus and node names above follow the Godot 4.7 documentation.
Official documentation used
Questions
Is the export a .tres file?
No. It is the PNG, a JSON description and a GDScript that builds the TileSet inside Godot, so the resource is written by Godot itself; the whole path was verified in Godot 4.7.2.
Does it match Godot cell for cell?
On the test corpus, every painted cell in Godot 4.7.2 equalled the Studio preview (485/485 on each blob set, 251/251 on the dual-grid pack).
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).