> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/using-the-editor/tilemap.md).

# Tilemaps

The tilemap system lets you paint tile-based worlds using auto-tiling masks, multiple layers, and wall extrusion with built-in collision generation.

## Adding a Tilemap

Add a `Tilemap_Component` to any entity. The tilemap is centered on the entity's position and spans a grid of chunks (each 32×32 tiles). The total size in tiles is `width_in_chunks × 32` by `height_in_chunks × 32`.

## Tilemap Properties

| Property                     | Description                                                                            |
| ---------------------------- | -------------------------------------------------------------------------------------- |
| **Width / Height in Chunks** | Size of the tile grid. Each chunk is 32×32 tiles. A 10×10 tilemap gives 320×320 tiles. |

Layers are configured individually once you enter editing mode (see below).

New ground layers have transparent outlines. New wall layers have opaque black body and top outlines and no top texture, so the body texture fills the top row. Both masks default to `$AO/tile_mask.png`. Choose the ground or wall-body fill textures separately. These creation defaults apply in the editor, MCP, CSL, and C#; loading an existing layer preserves its saved settings.

For black wall tops, add a 1×1 opaque black PNG to the project as `res/ao_black.png` if it does not exist, then set it as each wall layer's top texture. The engine no longer ships `$AO/black.png`: layers saved with it load with no top texture, and scripts should load `ao_black.png` instead.

Changing layer kind switches a default ground/body outline to match the new kind. Custom outline colors are preserved.

For a building, use floor and wall layers on the same tilemap. Extend flooring underneath every wall tile as well as the interior; stopping at the inner wall edge leaves a gap. Door openings remove wall tiles while retaining the floor.

## MCP Authoring

Agents must keep tile size at its default 1, including in runtime code, and keep structural entities at unit scale. Tile size is not an MCP option. Change the footprint through tile counts and the material pattern through texture scale.

* `tilemap_inspect` reads layer settings, occupied bounds, paginated horizontal occupancy runs, and tile/world conversions.
* `asset_prepare_tileable` trims transparent border padding from downloaded fill textures through asset crop settings and enables repeating. It preserves existing crop and opaque artwork; check `opaqueEdges` for remaining edge transparency. `apply:false` previews the crop. Supply `crop` to replace the current insets when a known feathered border also needs removal. Crops use `[left,bottom,right,top]` source-pixel insets and affect all uses of the asset without changing the source image.
* `tilemap_configure` resizes the grid and adds, patches, removes, or clears layers. New layers require fill textures; providing `textures` replaces the entire list. Project fill textures are prepared for repeating without automatically cropping them. Masks are left unchanged.
* `tilemap_paint` sets or erases inclusive rectangles, connected brush strokes, and explicit cells.
* `tilemap_stamp` copies occupancy through explicit layer mappings, optionally across maps. Rotations are counterclockwise in the Y-up grid. Merge preserves destination cells beneath source holes; replace clears them.

Use `modify_scene` to create the entity and `Tilemap_Component`. Tools target an entity by AOID or name, with `componentId` when needed. Tile coordinates and layer indices are zero-based; rectangle endpoints are inclusive. Use `tilemap_inspect`'s `worldCenter` when placing objects at tile centers: native tile-to-world conversion returns the tile corner. Position and scale are respected; entity rotation is ignored.

Paint and stamp reject out-of-bounds destinations unless `clip: true`. Ordered operations validate before applying each edit and stop at the first error, retaining earlier successes. MCP limits each request to 128 operations, 1,000,000 cell visits and 1,000,000 expanded tile instances, with grids from 2 to 100 chunks per axis.

Inspect collision footprints with `editor_scene_screenshot(colliderDebug: true)`. Only wall layers with collision enabled generate these shapes; verify openings and solid boundaries with the player in game.

## Runtime Scripting

`Tilemap_Component` exposes the same persistent layer data used by the editor. Layers are addressed by zero-based index. Removing a layer shifts every later index down by one, so do not keep an index across layer removal unless you update it.

### CSL

```csl
tilemap := entity.get_component(Tilemap_Component);
ground := tilemap.add_layer(.GROUND);

tilemap.set_layer_tint(ground, v4{0.8, 0.9, 1, 1});
grass := tilemap.add_layer_texture(ground, get_asset(Texture_Asset, "tiles/grass.png"), 1);
tilemap.set_layer_texture_scale(ground, grass, {2, 1});
tilemap.set_layer_texture_offset(ground, grass, {0.5, 0});
tilemap.set_layer_mask(ground, get_asset(Texture_Asset, "$AO/tile_mask.png"));
tilemap.set_tile(ground, 10, 12);

world_position := tilemap.tile_to_world(ground, 10, 12);
tile_x, tile_y := tilemap.world_to_tile(ground, world_position);
```

CSL tilemap mutations are ordinary scene state. They participate in prediction, rollback, and server reconciliation like other CSL gameplay state.

### C\#

```csharp
Tilemap_Component tilemap = Entity.GetComponent<Tilemap_Component>();
int ground = tilemap.AddLayer(TilemapLayerKind.Ground);

tilemap.SetLayerTint(ground, new Vector4(0.8f, 0.9f, 1.0f, 1.0f));
int grass = tilemap.AddLayerTexture(ground, Assets.GetAsset<Texture>("tiles/grass.png"));
tilemap.SetLayerTextureScale(ground, grass, new Vector2(2.0f, 1.0f));
tilemap.SetLayerTextureOffset(ground, grass, new Vector2(0.5f, 0.0f));
tilemap.SetLayerMask(ground, Assets.GetAsset<Texture>("$AO/tile_mask.png"));
tilemap.SetTile(ground, 10, 12);

Vector2 worldPosition = tilemap.TileToWorld(ground, 10, 12);
tilemap.WorldToTile(ground, worldPosition, out int tileX, out int tileY);
```

C# calls mutate the current simulation only. For a multiplayer runtime change, use the game's existing RPC flow to invoke the same mutation on every peer; the tilemap API does not create a new replication channel.

The runtime API includes:

* `Resize`, chunk/tile dimensions, and layer-aware local/world coordinate conversion.
* Layer add, remove, clearing, kind, render mode/order, tint, masks, outlines, wall settings, and collision settings.
* Weighted texture add, replace, reweight, remove, lookup, and per-texture scale/offset.
* Individual tile query, set, and clear operations.

Tilemaps are at least 2×2 chunks. Resizing preserves the map center, moves existing tile coordinates by half the size difference, and crops tiles outside the new bounds. Out-of-bounds tile writes do nothing and queries return false. Texture weights must be non-negative, and each layer supports at most 256 textures.

Invalid layer or texture indices and invalid layer settings are rejected at the scripting boundary. Texture scale must be positive on both axes. C# throws an `ArgumentOutOfRangeException` (or `ArgumentException` for the texture-count limit), while CSL reports a script error containing the invalid value and valid range.

Layer tint multiplies the complete layer, including outlines and wall tops. Tint changes are applied as a render uniform and do not rebake tiles or rebuild collision. Multiple tile and collision changes made before the tilemap's next update are coalesced into one geometry/collision rebuild.

## Editing Mode

Select the tilemap entity and click the **Edit** button in the inspector to enter tilemap editing mode. Click **Cancel** to exit. Editing mode deactivates automatically if you deselect the entity.

While editing, a red border outlines the tilemap bounds and a grid overlay is drawn in the scene view.

## Tools

The tilemap editor has three tool modes, switched via hotkeys:

| Tool       | Hotkey | Description                                       |
| ---------- | ------ | ------------------------------------------------- |
| **Brush**  | `B/W`  | Paint tiles by clicking and dragging.             |
| **Eraser** | `E`    | Remove tiles by clicking and dragging.            |
| **Stamp**  | `S/R`  | Select a region to copy, then paste it elsewhere. |

You can also **hold Shift** while in Brush mode to temporarily erase.

## Brush Painting

Click and drag to paint tiles on the selected layer. The brush uses Bresenham line interpolation between frames so you never skip tiles even when moving fast.

**Brush size** is adjusted with `[` and `]` (range 1–32). The brush is circular — tiles within the radius are affected.

**Alt+click** draws a straight line from your last click position to the current tile, useful for long straight edges.

**Ctrl+drag** switches to rectangle fill mode — drag to define a rectangle, and all tiles in the region are filled (or erased if Shift is also held) when you release.

## Layers

Each tilemap supports multiple layers. Click a layer in the inspector to select it for painting. The selected layer is highlighted in blue.

### Adding and Removing Layers

* Click **Add Layer** at the bottom to create a new layer.
* Click **Remove Layer** inside a layer's panel to delete it.

### Layer Properties

| Property         | Description                                                                                                                                                                                                                                      |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Kind**         | `Ground` or `Wall`. Ground tiles are flat; Wall tiles extrude vertically.                                                                                                                                                                        |
| **Layer Mode**   | `Default` uses automatic layering (ground behind player, walls Y-sorted). `Manual` lets you set a fixed render layer value.                                                                                                                      |
| **Manual Layer** | Only shown in Manual mode. The explicit render layer value.                                                                                                                                                                                      |
| **Tile Size**    | Visual size of each tile in world units; defaults to 1. Agents must leave it unchanged.                                                                                                                                                          |
| **Tint**         | Color multiplier for the complete layer, including wall tops and outlines.                                                                                                                                                                       |
| **Textures**     | One or more textures with weights for randomized variety, plus independent scale and offset controls for each texture's repeating pattern. The engine hashes tile coordinates to deterministically pick a texture per tile based on the weights. |
| **Mask**         | An 8×8 grid texture used for auto-tiling. Each cell corresponds to a different adjacency configuration (edges, corners, isolated, etc.). A default map is included `$AO/tile_mask.png`                                                           |
| **Outline**      | Color for tile outlines (alpha 0 = no outline).                                                                                                                                                                                                  |

### Multi-Texture Variety

Each layer can have multiple textures with weights. Tiles deterministically select a texture variant based on a hash of their grid coordinates, so the pattern is stable across saves and doesn't shift when you add/remove tiles.

Each texture is shown as a card with a full-width asset picker and separate **Weight**, **Scale (Tiles)**, and **Offset (Tiles)** rows. Weight controls how frequently the texture appears relative to the others.

Scale controls the size of one repeat in tile units. For example, a Y scale of `2` makes the texture repeat every two vertically stacked tiles. Scale must stay positive. Offset shifts the repeat origin in local tile units; a positive X or Y value moves the origin in that positive tilemap direction. These controls affect only the texture pattern, not tile geometry, masks, collision, or texture selection.

## Auto-Tiling

Tiles automatically select the correct mask cell based on their 8-directional neighbor configuration. The system:

1. Checks all 8 neighbors (N, NE, E, SE, S, SW, W, NW).
2. Diagonal neighbors only count if both adjacent cardinal neighbors are present (prevents visual artifacts at corners).
3. Maps the resulting 8-bit adjacency mask to one of 64 cells in the 8×8 mask texture.

This means you only need to paint tile presence — the correct edge, corner, and interior visuals are computed automatically.

## Wall Layers

Setting a layer's kind to **Wall** enables vertical extrusion. Wall tiles are placed on the grid like ground tiles, but each placed tile generates a column of body tiles extending upward by the **Wall Height**.

### Wall Properties

| Property        | Description                                                                                                                                                                                |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Wall Height** | Number of tiles tall each wall column is (minimum 2).                                                                                                                                      |
| **Top Texture** | Separate texture for the top row of the wall (the "cap"), with the same scale and offset controls as body textures. Its card is always visible rather than nested in the Textures section. |
| **Top Mask**    | Mask texture for the wall top (uses the same 8-neighbor auto-tiling as ground).                                                                                                            |
| **Top Outline** | Outline color for the wall top tiles.                                                                                                                                                      |

Wall bodies use the layer's main texture. Wall tops use the base row's neighbors, which keeps cap edges clean.

Walls are Y-sorted by their base row, so players walk behind walls above them and in front of walls below.

The tilemap follows its entity's X/Y scale. Rendering, scene-view painting and selection, coordinate conversion, wall collision, and navmesh input all use the scaled tile geometry. Negative scale mirrors the tilemap. A zero scale axis collapses the geometry and cannot be used for world-to-tile editing or conversion.

### Wall Collision

| Property       | Description                                                                                                                                                  |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Collision**  | Generate obstacle edges for navmesh rebuilding.                                                                                                              |
| **Inset**      | Shrinks collision edges inward from tile boundaries for tighter-fitting collision. Values are in unscaled tilemap-local world units and follow entity scale. |
| **Offset**     | Shifts all collision edges in unscaled tilemap-local world units, then follows entity scale.                                                                 |
| **Debug Draw** | Draws green collision edges in the scene view for debugging.                                                                                                 |

When collision is enabled, the engine builds obstacle edges from exposed tile boundaries. Navmeshes with automatic rebuilding enabled pick up those edges. In CSL, the edges block movement only for agents locked to such a navmesh; otherwise add colliders.

## Stamp Tool (Copy & Paste)

Press `S` to switch to Stamp mode. This enables a region selection workflow:

1. **Select**: Click and drag to highlight a rectangular region. The selected tiles are copied to the clipboard. A "Copied" popup confirms the action.
2. **Paste**: Press `Ctrl+V` to enter ghost mode. A translucent preview of the clipboard follows your cursor.
3. **Rotate**: Scroll the mouse wheel to rotate the ghost preview in 90-degree increments.
4. **Place**: Click to stamp the tiles. Hold Shift while clicking to place multiple copies without exiting ghost mode.
5. **Cancel**: Press `Escape` to exit ghost mode without placing.

Hold **Ctrl** while starting a stamp selection to copy tiles from **all layers** at once, preserving multi-layer structures.

## Keyboard Shortcuts Summary

| Shortcut       | Action                                              |
| -------------- | --------------------------------------------------- |
| `B` or `W`     | Switch to Brush tool                                |
| `E`            | Switch to Eraser tool                               |
| `S` or `R`     | Switch to Stamp tool                                |
| `Shift` (held) | Temporarily erase while in Brush mode               |
| `[` / `]`      | Decrease / increase brush size                      |
| `Ctrl+drag`    | Rectangle fill with the active Brush or Eraser tool |
| `Alt+click`    | Draw straight line from last click                  |
| `Ctrl+V`       | Enter paste/ghost mode                              |
| `Scroll wheel` | Rotate ghost preview (in ghost mode)                |
| `Shift+click`  | Place multiple copies (in ghost mode)               |
| `Escape`       | Cancel ghost mode                                   |
