Current exports use the following document identifiers:
{
"format": "tile-map",
"version": 4
}Coordinates use a top-left origin. The x-axis grows to the right, the y-axis
grows downward, and flat grids use index = y * width + x.
| Field | Type | Description |
|---|---|---|
format |
string | Constant value tile-map. |
version |
number | Current schema version, 4. |
name |
string | User-defined map name. |
generatedAt |
string | ISO 8601 export timestamp. |
versioning |
object | Stable document identity and revision history. |
tileSize |
number | Tile size in pixels; currently 32. |
size.width |
number | Map width in cells. |
size.height |
number | Map height in cells. |
origin |
string | Coordinate and indexing convention. |
markBits |
object | Numeric values assigned to navigation flags. |
walkableRule |
string | Human-readable walkability rule. |
counts |
object | Summary metrics computed during export. |
playerSpawn |
object or null | Player coordinate. |
monsterSpawns |
array | Monster coordinate and catalog metadata records. |
Each monster spawn record carries both its position and the catalog metadata required to resolve its icon without a catalog lookup:
| Field | Type | Description |
|---|---|---|
x |
number | Column index of the spawn. |
y |
number | Row index of the spawn. |
dex |
number | Numeric monster identifier. |
name |
string | Monster name as stored in the catalog. |
gen |
number | Generation used to resolve the icon directory. |
folder |
string | Sprite folder name within the generation. |
Schema version and map revision are independent. The top-level version field
identifies the JSON schema. The versioning.revision field identifies a saved
state of one map document.
{
"versioning": {
"documentId": "4cf2e989-664f-4f5d-99c3-317ae01017dc",
"revision": 2,
"history": [
{
"revision": 1,
"id": "b5478864-4839-4c51-aed7-83beae159935",
"parentId": null,
"savedAt": "2026-07-22T18:00:00.000Z"
},
{
"revision": 2,
"id": "09b4e6bb-358a-427d-a354-ff60ed2fa817",
"parentId": "b5478864-4839-4c51-aed7-83beae159935",
"savedAt": "2026-07-22T18:10:00.000Z"
}
]
}
}| Field | Type | Description |
|---|---|---|
versioning.documentId |
string | Stable identity of the map across revisions. |
versioning.revision |
number | Monotonic revision counter for the document. |
versioning.history[].revision |
number | Revision number of the recorded save. |
versioning.history[].id |
string | Unique identity of that individual save. |
versioning.history[].parentId |
string or null | Identity of the preceding save. |
versioning.history[].savedAt |
string | ISO 8601 timestamp of that save. |
Each successful save increments revision, creates a unique revision ID, and
links it to the preceding entry through parentId. Files use the pattern
<map-name>.v<revision>.json, with revision numbers padded to four digits.
Importing a versioned document preserves its document ID and history; the next
save continues the sequence.
The marks grid combines flags with bitwise OR.
| Flag | Value |
|---|---|
| Collision | 1 |
| Water | 2 |
| Blocks missiles | 4 |
| Blocks pathfinding | 8 |
A cell is walkable when its ground item ID is nonzero and its collision bit is
not set. The exported walkable grid is derived and must not be treated as the
authoritative input when ground and marks are available.
The editor supports three representations.
The tiles array contains coordinate records. Untouched cells are omitted by
default. Each record includes resolved ground and object values, derived
walkability, individual mark booleans, and optional spawn data.
The grids object contains row-major arrays:
ground: ground item IDs.objects: object item IDs.marks: combined mark bits.walkable: derived values represented as0or1.
Every grid contains exactly width * height entries.
Combined export includes both tiles and grids. Autosave and direct save use
this representation without resolved item names.
{
"format": "tile-map",
"version": 4,
"name": "sample",
"generatedAt": "2026-07-22T00:00:00.000Z",
"tileSize": 32,
"size": { "width": 2, "height": 2 },
"origin": "top-left; x grows right, y grows down; index = y * width + x",
"markBits": {
"collision": 1,
"water": 2,
"blocksMissiles": 4,
"blocksPathfinding": 8
},
"walkableRule": "a tile is walkable when it has a ground item and no collision mark",
"counts": {
"tilesTotal": 4,
"tilesPainted": 1,
"ground": 1,
"objects": 0,
"walkable": 1,
"collision": 0,
"water": 0,
"monsterSpawns": 0,
"playerSpawn": 1
},
"playerSpawn": { "x": 0, "y": 0 },
"monsterSpawns": [],
"grids": {
"ground": [106, 0, 0, 0],
"objects": [0, 0, 0, 0],
"marks": [0, 0, 0, 0],
"walkable": [1, 0, 0, 0]
}
}The importer accepts version 4 grids, detailed tile records, or both. It also
recognizes legacy fields used by versions 1 through 3, including width,
height, layers, flags, and boolean collision arrays. Unknown fields are
ignored. Documents without versioning receive a new document ID and begin at
revision zero before their next save.