Cached Chunk Tile Layer
Hs2dChunkedTileLayer paints non-empty tile chunks into tight transparent surfaces, then composes only chunks visible to the camera. It is the static-terrain path for large maps where one static world surface is too large and a dynamic visible tile pool would be too expensive.
Use cached chunk tile layers for large static tilemaps. Do not replace them with per-frame loops that scan and draw map tiles.
When To Use
Use cached chunks when:
| Good fit | Better alternative |
|---|---|
| Large static tile maps. | Dynamic tile for small visible pools and frequently changing tiles. |
| Sparse maps where empty chunk areas can be skipped. | Static tile for small maps that safely fit in one surface. |
| Auto tile mode chooses cached because zoom-out would exceed the dynamic pool budget. | A custom cached surface for non-grid world art. |
This layer is for static tiles. If tile contents change during gameplay, use a dynamic tile layer or add a purpose-built dirty chunk invalidation feature.
Construction Pattern
Manual:
const terrain = world.addTileLayer({
id: 'terrain',
mode: 'cached',
tileWidth: 32,
tileHeight: 32,
worldColumns: level.width,
worldRows: level.height,
tileKinds,
regions: tileRegions,
chunkWidth: 512,
chunkHeight: 512,
surfaceClearColor: 0x00000000,
});
Tiled:
Tile layer: terrain
hs2d:mode = cached
hs2d:chunkWidth = 512
hs2d:chunkHeight = 512
hs2d:clearColor = #00000000
Builder options can override generated map JSON:
const built = Hs2dWorldBuilder.fromLevel({
level,
assets,
viewportWidth: screenWidth,
viewportHeight: screenHeight,
tileLayerModes: { terrain: 'cached' },
tileLayerChunkSizes: { terrain: { width: 768, height: 512 } },
});
Update, Render, And Compose Behavior
| Phase | Behavior |
|---|---|
| Constructor | Splits the map into configured chunk windows and records tight bounds for chunks that contain non-empty tiles. Empty chunks are not stored. |
| Attach | Creates one surface per stored chunk and paints its non-empty tiles once. |
| Update/render | No normal update or render work. |
| Compose | Computes camera world bounds, checks chunk visibility, and draws only visible chunk surfaces scaled to screen coordinates. |
Chunk placement derives screen edges from floored world edges so neighboring chunks align at fractional zoom without visible gaps.
Performance Notes
- Chunk surfaces trade memory for lower per-frame tile work.
- Use chunk sizes that keep surface count and overdraw reasonable for the map.
- Sparse maps benefit because empty chunks are skipped entirely.
- Per-frame cost is proportional to chunk count scanned plus visible chunks drawn, not visible tile count.
- Use stats to track chunk count, visible tiles, painted tiles, and drawn chunks.
Code Sample
const terrain = world.addTileLayer({
id: 'canyon-terrain',
mode: 'cached',
tileWidth: 64,
tileHeight: 64,
worldColumns: 240,
worldRows: 120,
tileKinds,
regions,
chunkWidth: 512,
chunkHeight: 512,
surfaceClearColor: 0x00000000,
});
protected override updateSceneSprites(): void {
const stats = terrain.getStats();
this.visibleTiles = stats.visibleTiles;
}
Source References
| Source | Why it matters |
|---|---|
../games/hosanna-ui/src/hosanna-game/hosanna2d/Hs2dChunkedTileLayer.ts | Chunk building, tight chunk bounds, surface painting, visible chunk compose, disposal, and stats. |
../games/hosanna-ui/src/hosanna-game/hosanna2d/Hs2dWorld.ts | addTileLayer cached mode. |
../games/hosanna-ui/src/hosanna-game/hosanna2d/Hs2dWorldBuilder.ts | auto fallback to cached chunks, hs2d:mode=cached, chunk properties, and builder overrides. |
../games/hosanna-ui/src/hosanna-game/hosanna2d/Hs2dTileLayer.ts | Dynamic pool sizing that cached mode avoids when auto estimates too many visible tiles. |