Build a Map
This page shows you how to assemble a playable level out of terrain entities: a Map that ties together a tile grid, a spawn point, and the actors placed on it when the level loads. By the end you can author a map and understand why it looks empty until an actor walks across it.
Prerequisites
You should be comfortable with the campaign data model before you build a map:
- Entities and KeyRefs explains how entities reference each other by key.
- Campaign structure explains where YAML files and assets live inside a campaign.
- Create an actor covers the actor you spawn onto the map and its
perceptionfield.
Fog of war: why a correct map looks blank
Before you build anything, you need to know that a freshly loaded map renders nothing. This is intended.
Every tile layer starts hidden. Each tile begins fully transparent over a dark, unexplored background. This is fog of war: the unexplored darkness that lifts only as an actor explores.
A tile reveals when an actor's discovery area overlaps it. That area is sized from the actor's perception field (see Create an actor). A hero with a small perception sees only the patch of terrain immediately around the spawn point when the level loads. The rest stays dark until the player moves.
Each tile is always in one of three states:
- Visible — inside an actor's discovery area right now, drawn at full strength.
- Discovered — seen before but not currently in view, drawn dimmed.
- Undiscovered — never seen, hidden.
Discovery is tracked per actor and is saved with the game, so explored areas stay explored across sessions.
Note: If your map appears completely black after loading, that is normal. Move the player actor and the terrain fades in around it. A blank screen is not a sign that your tiles are wrong.
How a map fits together
A map is a small stack of entities, each with one job. The Map entity is the top of the stack and points at the rest by KeyRef:
- A TileMap holds the ordered terrain layers and the tile definitions they draw from.
- A TileSet names the texture atlas and lists the Tile definitions.
- Each Tile maps a single symbol character to one cell in that atlas, and declares whether the tile is walkable or solid.
- Each Layer points at a plain-text grid file whose characters are tile symbols.
- A Vector marks the spawn point where the player enters.
- Deployment entities place non-player actors on the map at load time.
Note: None of the fields below are required by the validator. In practice you set the ones you need for the map to function, and the example values show a working baseline.
Define the tiles
Start with the look of the terrain. A TileSet names a texture image inside the campaign and lays it out as a grid. The columns field tells the engine how wide that grid is, so it can turn each tile's index into a position in the atlas.
The example tile set uses an 8-column atlas and defines three tiles:
TileSet:
demoTileSet:
columns: 8
texture: /assets/basic.png
tiles:
- grass
- water
- wall
Face:
roof:
northeast: true
northwest: true
Tile:
grass:
symbol: G
index: 0
navigation: roof
water:
symbol: W
index: 46
wall:
symbol: X
index: 52
obstacle: roof
Each Tile field controls one thing:
symbolis the character matched against the layer grid. It is a string by schema, but the engine reads one character at a time, so use a single character such as"G".indexpicks which cell in the grid to use, counting left to right then top to bottom, starting at0. Withcolumnsset to 8, grass0is the top-left cell, water46is column 6 row 5, and wall52is column 4 row 6.navigationpoints at a Face entity that marks the tile as walkable. Heregrassreferencesroof, so actors can walk across grass and avoid everything else.obstaclepoints at aFaceentity that marks the tile as solid. Thewallreferences the sameroof. A tile's faces just say which parts are walkable versus solid.
Tip: A tile defaults to neither walkable nor solid (both references absent). A floor tile you want actors to cross needs
navigationpointing at a walkableFace, asgrassshows. Reuse oneFaceentity (likeroof) across many tiles.
Two more Tile fields exist for special cases. origin adjusts what draws in front, and ghost makes a tile invisible while it still blocks movement. Leave both off unless you have a specific need; the example uses neither.
Warning: Do not set
ghoston your main floor tiles. A ghost tile is never drawn, so a ghosted floor leaves the terrain invisible.
Draw the layers
A Layer is a plain-text file of tile symbols, one character per cell. The file holds your map's shape: where the grass is, where the walls run, where there is nothing at all.
The grid format is deliberately simple. Each non-blank character is matched against a tile's symbol. Blank cells — a space, tab, newline, or empty position — place no tile, which is how you leave gaps. A short grass patch with a gap might look like this:
GGG
G G
GGG
Here the center cell is a space, so no tile is placed there.
The example splits its terrain across three layers, drawn in order from a TileMap:
TileMap:
demoTileMap:
tileset: demoTileSet
layers:
- demoFloor
- demoWater
- demoWalls
Layer:
demoFloor:
source: /demoMap/layer0
ysort: false
demoWater:
source: /demoMap/layer1
ysort: true
demoWalls:
source: /demoMap/layer2
ysort: true
Each layer's source is a path to a grid file, relative to the campaign root. In the example these files live under a demoMap/ folder inside the campaign and have no file extension: layer0, layer1, layer2. The floor layer draws grass, the walls layer draws the maze border, and the water layer is blank in this map.
The ysort field controls what draws in front, so taller terrain like walls draws in front of what is behind it. Leave it off for a flat floor, as demoFloor does, and on for upright features.
Note: Layers draw in the order you list them. Put your floor first and features such as walls after, so the features sit on top.
How grid characters become tile positions
The engine walks the grid in a fixed direction. Each row advances the tile position by one step along the map's X axis, and each character within a row steps by one along the Y axis. You do not set these coordinates yourself; you only arrange characters in the file. The result is that the shape you type in the text file is the shape you walk in the game.
Place the spawn point
The player needs somewhere to enter. The Map's spawn field is a KeyRef to a Vector entity that holds an x and y position in pixels. It is the fallback location for the player actor when no saved position or action override applies.
The spawn Vector sits beside the Map entity in the same file:
Vector:
demoSpawn:
x: 128
y: 16
The Map refers to it by key, as the assembled Map below shows.
Deploy non-player actors
A Deployment places one non-player actor on the map when the level loads. Each deployment pairs an actor to spawn with a location Vector that says where. The engine spawns each deployed actor as an NPC.
The example places three NPCs:
Deployment:
guardDeploy:
location: guardPos
actor: guardActor
merchantDeploy:
location: merchantPos
actor: merchantActor
patrollerDeploy:
location: patrollerPos
actor: patrollerActor
Vector:
guardPos:
x: 128
y: -48
merchantPos:
x: 160
y: 32
patrollerPos:
x: 288
y: 0
Each actor is a full Actor entity defined elsewhere in the campaign. To give a deployed NPC its own behavior, give that actor a strategy; see Add NPC AI.
Assemble the map
With the tiles, layers, spawn, and deployments in place, the Map entity ties them together:
Map:
demoMap:
name: Demo Map
tilemap: demoTileMap
spawn: demoSpawn
deployments:
- guardDeploy
- merchantDeploy
- patrollerDeploy
Vector:
demoSpawn:
x: 128
y: 16
This Map names itself for the interface, draws its terrain from demoTileMap, enters the player at demoSpawn, and deploys the three NPCs. To make this map the one a campaign starts on, point the Main entity's map field at it; see Campaign structure.
The Map also carries background and audio fields for parallax scenery and music. Those are covered in Audio and backgrounds.
Add floor overlays (optional)
A Floor draws a single texture image at a fixed position, beneath the tiles. Use it for a backdrop or a decorative surface that the tile grid sits on top of. A Floor has a texture path and a location KeyRef to a Vector for its top-left corner. The Map's floor field lists the floor overlays to draw. The example map uses none, so you can skip this until you need a painted backdrop.
Verify the map loads
Zip your campaign and check that the map loads and validates:
./isometry --validate=/path/to/mygame.zip
./isometry --campaign=mygame --network=host --port=5000 \
--username=p --secret=p --log-level=INFO
A successful load logs Campaign validation passed and Successfully created Entity lines. Remember the fog of war: a loaded map looks dark until an actor's discovery area reveals the tiles near it.