Documentation
Docs/en/reference/map-format/validation.md
Map Validation Rules
Generated reference. Do not edit directly. Update
BuildTools/MapFormatInterface.jsonor the owning engine metadata, then runpython BuildTools/docs_map_format.py --write.
| Index | Syntax | Properties | Baking | Validation | Canonical JSON | Authoring guide |
These stable rule IDs let documentation CI classify format changes against an earlier engine revision.
| Stable ID | Rule | Requirement | Notes | Authority |
|---|---|---|---|---|
map-format.rule.config-syntax |
Configuration syntax | Use INI-like repeated sections, key = value assignments, # comments, backslash continuation, and key += value append where the property parser supports it. | .fomap uses the shared ConfigFile parser. | Source/Common/ConfigFile.cpp |
map-format.rule.closed-section-set |
Closed section set | Use top-level ProtoMap anchors and nested <owner>/Critter or <owner>/Item sections only. | [$Name/…] binds to the preceding anchor. An explicit owner must name a declared map; a contextual nested section before the first anchor is rejected. | Source/Common/MapLoader.cpp |
map-format.rule.map-identity |
Map identity | Give every map in a multi-map container a unique ProtoMap $Name; a single unnamed anchor inherits the source basename. | Map identity, targeted bake lookup, and baked output names come from declared map ids, not container filenames. | Source/Tools/MapBaker.cpp |
map-format.rule.shared-placement-ids |
Shared placement ids | Use explicit positive ids unique across all Critter and Item sections in one map. | The loader repairs omitted, non-positive, and duplicate ids, but repaired values can invalidate hand-authored owner references. | Source/Common/MapLoader.cpp |
map-format.rule.prototype-resolution |
Prototype resolution | Every Critter and Item section must name an existing prototype with $Proto. | Missing and unresolved prototypes are accumulated as map-load errors. | Source/Common/MapLoader.cpp |
map-format.rule.property-overrides |
Property overrides | Use properties valid for the section receiver and bake side; values override the resolved base prototype. | MapBaker copies the prototype properties, applies section text, validates resources, and serializes side-specific data. | Source/Tools/MapBaker.cpp |
map-format.rule.normalized-order |
Normalized entity order | Do not use textual interleaving as an ordering contract. | The loader processes all Critter sections before all Item sections, and mapper save emits critters with inventory items before map items with direct children. | Source/Client/MapView.cpp |
map-format.rule.ownership-references |
Ownership references | CritterInventory and ItemContainer placements must reference a materializable owner id through CritterId or ContainerId. | Unmapped owner ids skip child creation; direct children of placed critters and non-static map items are the supported mapper/runtime shape. | Source/Server/MapManager.cpp |
map-format.rule.static-items |
Static item placement | A Static item must use MapHex ownership. | Static items become immutable map-grid entries and contribute movement, shooting, trigger, and multihex state. | Source/Server/StaticMap.cpp |
map-format.rule.bounds |
Map bounds | Critter Hex and MapHex item Hex values must be inside ProtoMap Size before runtime loading. | Server load rejects invalid positions. Mapper editing commands may clamp positions, which is not a substitute for source validation. | Source/Server/MapManager.cpp |
map-format.rule.side-specific-bake |
Side-specific bake | Treat server and client map binaries as a coupled output and regenerate both after source or referenced prototype changes. | The server receives critters and all items; the client receives visible static items and all authored server-map strings, without server entity or property records. | Source/Tools/MapBaker.cpp |
map-format.rule.hidden-static-items |
Hidden static items | Do not expect a Hidden static item entity in the client map payload. | Its client-side property strings are still hashed, but the item record is omitted. | Source/Tools/MapBaker.cpp |
map-format.rule.runtime-materialization |
Runtime materialization | Use Static only for immutable map-hex fixtures; use non-static placements for generated critters, map items, inventories, and containers. | The server remaps authored ids for generated critters and non-static map items before attaching direct child items. | Source/Server/MapManager.cpp |
map-format.rule.mapper-round-trip |
Mapper round-trip | Review mapper-saved diffs as normalized output, not byte-preserving serialization. | The mapper emits $Name and normalized [$Name/…] sections for the edited map, retains $Text fields, flattens inherited map properties, and preserves sibling map blocks byte-exact in a multi-map container. | Source/Tools/Mapper.cpp |
map-format.rule.multihex-mesh |
Multihex mesh serialization | MultihexMesh must contain x/y coordinate pairs; mapper save normalizes it into backslash-continued pairs. | An odd coordinate count fails mapper serialization. | Source/Client/MapView.cpp |
map-format.rule.multihex-lines-runtime |
Runtime multihex-line footprint | Treat MultihexLines as part of an item’s complete runtime footprint around both its anchor and every valid MultihexMesh cell. | Server static and dynamic materialization index every expanded line cell to the same item and recache its blocking and interaction flags. | Source/Server/Map.cpp |
map-format.rule.error-aggregation |
Error aggregation | Treat any accumulated entity load or property/resource validation error as a failed map bake. | Entity diagnostics are logged individually before MapLoader or MapBaker throws the aggregate failure. | Source/Tools/MapBaker.cpp |
Authoring validation sequence
- Declare every map with
[ProtoMap]; name every anchor in a multi-map container. - Address placements with
[$Name/Critter]/[$Name/Item]after their anchor or use an explicit declared map id. - Assign explicit unique positive placement ids within each map and resolve every
$Protoand ownership reference. - Validate receiver properties, resources, map bounds, and static-item ownership.
- Bake both side outputs and treat warnings followed by an aggregate map error as a failed build.
- After mapper save, inspect the edited map’s normalization and verify that sibling map blocks stayed unchanged.