Tilemap & level design¶
The tilemap system turns a source image into a reusable tileset and lets you paint large levels with those tiles on a multi-layer, infinite map: slice an image into indexed tiles, stamp / erase / fill cells, let auto-tiling resolve borders for you, flip and rotate tiles as you place them, and export / import the whole map as Tiled-compatible JSON. Every map edit is a single undo step.
Logical vs. displayed tiles
Auto-tiling separates the tile you place (the logical tile) from the tile that is shown (the display tile). You paint one "wall" tile and the map picks the correct edge/corner variant from its neighbours; the logical placement is what is stored and what round-trips, so the result is deterministic and reversible. Turning auto-tiling off shows the logical tile directly.
Tilesets¶
A tileset is a source image sliced into a grid of equally-sized tiles. Open
the Tileset panel and add a tileset from an image; the slicer reads the
image with your tile size, optional outer margin and inter-tile
spacing, and indexes the resulting tiles left-to-right, top-to-bottom
starting at 0.
- Each tile is a region of the source buffer, so a tileset is backed by one image rather than many copies.
- Editing a source tile propagates to every placed instance of that tile across every layer — repaint the tile once and the whole level updates.
- The panel shows the sliced tiles as a pick grid; the selected tile is the one the stamp tool paints.
Margin and spacing
margin is the border skipped around the whole image; spacing is the gap
skipped between tiles. Sheets exported with a 1-px gutter typically need
spacing = 1 (and margin = 1 if the gutter also wraps the edge) so the
slicer lands exactly on each tile.
Painting a tilemap¶
The tilemap canvas paints cells on a grid, one tile per cell. Pick a tile in the tileset panel, then use the map tools:
| Tool | What it does |
|---|---|
| Stamp | Places the selected tile in the cell under the cursor (drag to paint a run). |
| Erase | Clears the cell back to empty. |
| Fill | Flood-fills the contiguous region of like cells under the cursor with the selected tile. |
Each stamp / erase / fill is exactly one undo step, and undo restores the exact prior cells. Painting near existing tiles re-resolves the auto-tile neighbourhood so borders stay correct as you draw (see below).
Flip and rotate¶
Before you stamp, you can transform the tile: H-flip and V-flip mirror it, and rotate steps it through the four right-angle orientations (the D4 rotations). The transform is stored per placed cell as a compact flag on the tile, so flipping or rotating a tile costs no extra tileset entries and round-trips losslessly. Transforms compose in a fixed order (diagonal, then horizontal, then vertical) so a given combination always renders identically.
Auto-tiling¶
Auto-tiling resolves each cell's display tile from its eight neighbours (the Blob-47 scheme: an 8-neighbour bitmask with edge-implies-corner gating, giving 47 distinct tiles). Paint a single "terrain" tile and the map fills in the correct straight edges, inner and outer corners automatically.
- Toggle auto-tiling with the auto-tile control. When it is on, painting, erasing or filling a cell also re-resolves the affected cell and its neighbours so the border is always consistent — all inside the same one undo step.
- The resolution is a pure, deterministic function of the logical placement and neighbours, so the same map always renders the same display tiles.
- Turning auto-tiling off shows the logical tile you placed directly, without border resolution.
Layers and infinite maps¶
A tilemap is multi-layer — stack a background, terrain and detail layer, each painted independently — using the same layer model as the rest of the editor (add / remove / reorder / show-hide). The Tilemap Layers panel manages the stack; visible layers composite together for display.
The map itself is infinite: cells are stored as a sparse grid of 16×16 chunks, so only the regions you actually paint consume memory. You can stamp far from the origin (in any direction) without pre-sizing the map, and empty regions cost nothing. Each cell is a 32-bit tile id (GID) carrying the tile index plus its flip/rotate flags.
Large-map rendering
Each visible chunk is rendered once and cached; panning re-uses cached chunks rather than repainting them, so scrolling a large map stays smooth. The first paint of a freshly-visible region is warmed in the background (off the GUI thread) so the window stays responsive while it catches up; a warmed chunk is a fast blit thereafter, and the cache is held within a bounded memory budget.
Tiled JSON export / import¶
The map exports to Tiled-compatible JSON and re-imports losslessly — a round-trip preserves the layers, every cell and its flip/rotate flags, and any fields the editor does not itself use (unknown fields are passed through verbatim).
- Export writes a valid Tiled map. Layer data is emitted as CSV by default; base64 (raw / gzip / zlib compressed) is also supported.
- Import reads Tiled maps written with CSV or base64 (empty / gzip / zlib)
layer data, and accepts an external
.tsjtileset reference. - Import is a defensive, validated load: a malformed map, an unsupported
zstd-compressed layer, or an external
.tsxtileset reference are rejected with a clear error rather than a crash or silent corruption.
Round-trip fidelity
Because unknown fields survive the round-trip and flip/rotate flags are preserved bit-for-bit, you can move a map between PixelArt Creator and Tiled without losing data the other tool added.
Persistence¶
Tilesets and tilemaps round-trip through .pixproj (schema version 4).
Saving then reopening a project restores every tileset (its source and slicing
config) and every tilemap (its layers, cells and per-cell flip/rotate flags)
identically. Projects saved by earlier versions (v1 / v2 / v3, before
tilemaps existed) still open — they simply load with no tilesets or tilemaps.
Undo, redo and what is not undoable¶
- Undoable (one step each): stamp / erase / fill a cell (including any auto-tile neighbour re-resolution), and add / remove / reorder / show-hide a tilemap layer.
- Not undoable (view state): selecting a tile in the tileset panel, toggling auto-tiling, choosing a flip / rotate for the next stamp, and panning the map.
What is not covered¶
- zstd-compressed Tiled layer data and external
.tsxtilesets on import — rejected by design (import accepts CSV / base64 gzip/zlib and external.tsj); use one of the supported encodings. - Corner / edge Wang tile sets beyond the Blob-47 8-neighbour scheme — the auto-tiler is designed to extend to them in a later phase.
- Animated tiles and object layers — a later phase; this release covers tile layers.