The JSON export is a clean, self-describing format. Fields that equal their default value are omitted to keep the file small.
Top-level structure
{
"version": 3,
"map": { ... },
"sheets": [ ... ],
"tileLayers": [ ... ],
"objectLayers": [ ... ]
}
| Field | Type | Description |
version | number | Format version, currently 3. |
map | object | Map base info (type, size). |
sheets | array | Sprite-sheet metadata array. |
tileLayers | array | Tile layers, each with placed cells. |
objectLayers | array | Object layers, with placed objects. |
map โ map base info
"map": { "type": "forest", "width": 12, "height": 16, "tileSize": 32 }
| Field | Type | Description |
type | string | Theme: none/forest/desert/water/dungeon/snow/lava/cave. |
width | number | Map width in tiles. |
height | number | Map height in tiles. |
tileSize | number | Pixel size per tile (e.g. 32 = 32x32). |
sheets[] โ sprite-sheet metadata
Sheets are referenced by array index & matched by name on reload โ no unstable runtime id is exported.
"sheets": [{
"name": "Fantasy",
"cellSize": 16, "cols": 32, "rows": 24,
"imageWidth": 512, "imageHeight": 384,
"passability": [ ["3:5","none"], ["4:5","up"] ]
}]
| Field | Type | Description |
name | string | Sheet name (from import filename). |
cellSize | number | Pixel size of one tile. |
cols | number | Tile columns in the sheet. |
rows | number | Tile rows in the sheet. |
imageWidth | number | Source image width (px). |
imageHeight | number | Source image height (px). |
passability | array | Tile-level passability: ["col:row", value]. "all" omitted. |
tileLayers[] โ tile layers
"tileLayers": [{
"name": "top",
"cells": [ { "x": 3, "y": 5, "sheet": 0, "col": 3, "row": 5, "passability": "none" } ]
}]
| Field | Type | Description |
name | string | Layer name. |
index | number | Layer z-order position (0 = bottom). |
cells | array | Cells in this layer (see below). |
visible | boolean | Visible (default true, omitted if true). |
opacity | number | Opacity 0-1 (default 1, omitted if 1). |
offsetX/Y | number | Layer pixel offset (default 0, omitted if 0). |
cells[] โ map cells (self-describing, no internal id)
Sheet tiles use sheet+col+row; builtin tiles use tile. Source pixel rect = col x cellSize, derivable, omitted.
| Field | Type | Description |
x, y | number | Cell column/row in map (0-based). |
sheet | number | Sheet tile: index into sheets array. |
col, row | number | Sheet tile: col/row in source image. Pixel x = col x cellSize. |
tile | string | Builtin tile: semantic name (e.g. "grass"). |
passability | string | Cell passability (default 'all', omitted). Values: all/none/up/down/left/right/horizontal/vertical. |
Example:
{"x":3,"y":5,"sheet":0,"col":3,"row":5,"passability":"none"},
{"x":0,"y":0,"tile":"grass"}
objectLayers[] โ object layers
"objectLayers": [{
"name": "objects",
"objects": [ { "x": 2, "y": 3, "id": "hero", "type": "player" } ]
}]
| Field | Type | Description |
name | string | Layer name. |
index | number | Layer z-order position (0 = bottom). |
objects | array | Objects in this layer (see below). |
objectIdPrefix/Suffix | string | ID affix options (only if set). |
objectIdIndex | boolean | Enable auto-numbering (only if true). |
objects[] โ placed objects
"objects": [ { "x": 5, "y": 8, "id": "goblin_01", "type": "enemy", "direction": "up" } ]
| Field | Type | Description |
x, y | number | Object tile col/row (0-based). |
id | string | Object ID (user-entered or auto). |
type | string | Type (default npc): player/npc/enemy. |
direction | string | Facing (default down): up/down/left/right. |
Passability values
| Value | Meaning |
all | Passable (default, not exported) |
none | Fully impassable |
up | Up passable only |
down | Down passable only |
left | Left passable only |
right | Right passable only |
horizontal | Left-right passable |
vertical | Up-down passable |
Complete example
{
"version": 3,
"map": { "type": "forest", "width": 12, "height": 16, "tileSize": 32 },
"sheets": [{
"name": "Fantasy", "cellSize": 16, "cols": 32, "rows": 24,
"imageWidth": 512, "imageHeight": 384,
"passability": [ ["3:5","none"], ["4:5","up"] ]
}],
"tileLayers": [
{ "name": "top", "cells": [
{ "x": 3, "y": 5, "sheet": 0, "col": 3, "row": 5, "passability": "none" },
{ "x": 4, "y": 5, "sheet": 0, "col": 4, "row": 5, "passability": "up" },
{ "x": 0, "y": 0, "tile": "grass" },
{ "x": 1, "y": 0, "tile": "water", "passability": "none" }
]},
{ "name": "bottom-ground", "opacity": 0.8, "cells": [
{ "x": 0, "y": 0, "sheet": 0, "col": 0, "row": 0 }
]}
],
"objectLayers": [
{ "name": "objects", "objects": [
{ "x": 2, "y": 3, "id": "hero", "type": "player" },
{ "x": 5, "y": 8, "id": "goblin_01", "type": "enemy", "direction": "up" },
{ "x": 7, "y": 2, "id": "villager" }
]}
]
}