Variable-sized tiles
Tiled assumes every tile in an atlas is the same size. GridCraft doesn't. Mark a tileset as variable-size, and individual tiles can claim a 1x2, 2x1, 2x2, or any other rectangular footprint inside the atlas. A 16x16 tree trunk and a 32x48 oak in the same sheet, painted with the same brush.
Anchors and footprints
A bigger-than-1x1 tile has an anchor: the cell that holds its GID. The other cells inside its footprint hold a sentinel value, COVERED_BY_OVERSIZE = 0x10000000. The renderer skips sentinel cells, the eraser walks back to the anchor when you click a sentinel, and the writer strips sentinels to 0 before saving so other Tiled-compatible tools see a normal map.
On load, GridCraft rebuilds the sentinels by walking the data, finding anchors with sizeInAtlas > 1, and writing the sentinels back into the covered cells. The on-disk file stays interoperable; the in-memory representation knows about footprints.
Painting and erasing
Painting an anchor pre-clears any existing footprint that overlaps the target area. So dropping a 2x2 tile on top of an existing 2x2 tile replaces it cleanly, and dropping a 2x2 on top of four 1x1 tiles removes all four. Erasing an anchor or any sentinel cell removes the whole footprint.
Godot merge workflow
Godot 4 supports variable-size tiles natively via texture_region_size and size_in_atlas on a TileSetAtlasSource. The Godot exporter writes an anchor for every oversize tile and skips the covered cells so Godot doesn't reject duplicate create_tile calls. Open the .tscn in Godot and the tiles show up at their actual size.
What exporters do with it
- Godot 4: native support via
size_in_atlas. Round-trips with no data loss. - Tiled JSON: the exporter applies a polyfill, breaking oversize tiles into uniform sub-tiles so Tiled itself can open the file.
- Everything else: oversize tiles export as their top-left sub-tile. Anything below or to the right is clipped. If you need oversize support outside Godot, ship the Tiled JSON polyfill output.