Tilemap
The tilemap system loads Tiled maps (.tmj / .json) and renders tile layers with automatic camera culling, per-layer tint/opacity, parallax scrolling, and collision generation.
Quick Start
The simplest way to use tilemaps is through the editor:
- Export your map from Tiled as JSON (
.tmj) - Place the
.tmjfile and tileset images in your project assets folder - Add a Tilemap component to an entity and set the Source to your
.tmjfile
The scene loader automatically parses the map, loads tileset textures via the AssetServer, and registers everything for rendering.
Components
Tilemap
A marker component that references a Tiled map source file. The scene loader reads this field to preload map data and tileset textures before the scene is instantiated.
| Property | Type | Default | Description |
|---|---|---|---|
source | string | '' | Path to the .tmj / .json map file |
TilemapLayer
Describes a single tile layer for rendering. Each visible layer in a Tiled map creates one entity with this component.
| Property | Type | Default | Description |
|---|---|---|---|
width | number | 10 | Layer width in tiles |
height | number | 10 | Layer height in tiles |
tileWidth | number | 32 | Tile width in pixels |
tileHeight | number | 32 | Tile height in pixels |
texture | number | 0 | Tileset texture handle |
tilesetColumns | number | 1 | Number of columns in the tileset image |
layer | number | 0 | Sort layer index |
tiles | number[] | [] | Flat array of tile IDs (row-major) |
tint | Color | {r:1,g:1,b:1,a:1} | Per-layer tint color |
opacity | number | 1 | Layer opacity (0–1) |
visible | boolean | true | Whether the layer is rendered |
parallaxFactor | Vec2 | {x:1,y:1} | Parallax scroll factor |
How It Works
Scene Loading Pipeline
When a scene contains an entity with a Tilemap component, the scene loader:
- Reads the
sourcefield (e.g.,maps/level1.tmj) - Loads the JSON via the
AssetServerand parses it withparseTmjJson - Resolves tileset image paths relative to the
.tmjfile - Loads tileset textures via
AssetServer.loadTexture()and registers their dimensions - Caches the parsed map data with
registerTilemapSource()
At runtime, the TilemapPlugin reads the cache and submits visible layers for rendering each frame.
Build Targets
The tilemap asset pipeline works across all build targets:
- Editor preview: Loads via
AssetServerover the preview HTTP server - WeChat MiniGame / Playable Ads: Loads via
RuntimeAssetProviderusing the bundled assets - Web build: Same as editor preview, assets served from the build output
Programmatic Loading
For cases where you need to load a tilemap from code (outside the scene loader), use the lower-level APIs:
import { parseTmjJson, loadTiledMap, registerTextureDimensions } from 'esengine';
// Parse Tiled JSON dataconst mapData = parseTmjJson(jsonObject);
// Load tileset textures through the AssetServerconst textureHandles = new Map<string, number>();for (const tileset of mapData.tilesets) { const info = await assetServer.loadTexture(tileset.image); textureHandles.set(tileset.image, info.handle); registerTextureDimensions(info.handle, info.width, info.height);}
// Spawn tilemap layer entities into the worldconst entities = loadTiledMap(world, mapData, textureHandles);C++ Parser (WASM)
For maps with external tilesets (.tsj files), use parseTiledMap which delegates to the C++ parser:
import { parseTiledMap } from 'esengine';
const mapData = await parseTiledMap(jsonString, async (source) => { // Resolve external tileset files return await assetServer.loadText(source);});loadTiledMap Options
| Option | Type | Default | Description |
|---|---|---|---|
generateObjectCollision | boolean | true | Create colliders from Tiled object layers |
collisionTileIds | number[] | auto-detected | Tile IDs that should generate collision bodies |
Collision Generation
Object Layer Collision
Tiled object layers are automatically converted to physics bodies. Supported shapes:
- Rectangle →
BoxColliderwith matching half-extents - Ellipse →
CircleColliderwith the larger axis as radius - Polygon / Polyline →
BoxColliderfitted to the bounding box - Point → skipped
Each collision object creates a static RigidBody entity with the appropriate collider.
Tile Collision
Mark tiles as collidable in Tiled by adding a custom property collision = true to the tile in the tileset. The loader reads these IDs and generates merged collision rectangles:
const entities = loadTiledMap(world, mapData, textureHandles, { collisionTileIds: [1, 2, 3],});Collision Merging
Adjacent collision tiles are automatically merged into larger rectangles to reduce physics body count. The algorithm scans row by row, expanding each rectangle rightward and downward as far as possible:
Before merge: [1][1][1] After merge: [ 1 ] [1][1][1] [ 1 ]This produces fewer, larger BoxCollider bodies for better physics performance.
TilemapAPI
Low-level API for runtime tile manipulation:
| Method | Description |
|---|---|
TilemapAPI.initLayer(entity, w, h, tw, th) | Initialize a tile layer for an entity |
TilemapAPI.destroyLayer(entity) | Destroy a tile layer |
TilemapAPI.setTile(entity, x, y, tileId) | Set a single tile |
TilemapAPI.getTile(entity, x, y) | Get a tile ID |
TilemapAPI.fillRect(entity, x, y, w, h, tileId) | Fill a rectangle with a tile |
TilemapAPI.setTiles(entity, tiles) | Set all tiles from a Uint16Array |
TilemapAPI.hasLayer(entity) | Check if an entity has an initialized layer |
Editor Workflow
- Add a Tilemap component to an entity in the Hierarchy
- Set the Source field to a
.tmjor.jsonTiled map file using the asset picker - The editor automatically loads the map, resolves tileset textures, and renders the layers
- Collision objects are visualized as gizmo overlays
Layer Properties
Tiled layer properties map directly to TilemapLayer fields:
| Tiled Property | TilemapLayer Field | Description |
|---|---|---|
opacity | opacity | Layer transparency |
tintcolor | tint | Hex color string (#AARRGGBB or #RRGGBB) |
parallaxx | parallaxFactor.x | Horizontal parallax factor |
parallaxy | parallaxFactor.y | Vertical parallax factor |
visible | visible | Layer visibility |
Next Steps
- Physics — collision components and events
- Sprite — sprite rendering alongside tilemaps
- Rendering Overview — camera, transform, render order