Skip to content

Map rendering

Overview

MapView coordinates three layers: TerrainLayer, ZoneOverlayLayer, ObjectLayer. Uses @pixi/tilemap for terrain and a single Container with isRenderGroup: true for objects (GPU batching). See PIXI_TILEMAP_CHECK for technical notes.

Layers

Layer Purpose Rebuild strategy
TerrainLayer Terrain tiles Visible range, chunked (16×16)
ZoneOverlayLayer Zone overlays + labels Visible range each frame
ObjectLayer Objects, colonists, icons Full map once; incremental on invalidate

TerrainLayer

  • CompositeTilemap from @pixi/tilemap
  • Renders only visible range (with padding)
  • Chunked – rebuild when quantized visible range changes (chunk size 16)
  • Avoids rebuilding terrain on every pan
  • Uses TerrainTextureMap for tile type → texture

ZoneOverlayLayer

  • Graphics – zone rectangles (storage, sleeping)
  • Labels – zone type labels
  • Renders visible range each frame
  • ClickonZoneOverlayClick(tileX, tileY) for zone selection

ObjectLayer

  • objectRenderGroupContainer with isRenderGroup: true (GPU-batched sprites)
  • objectOverlaysContainer – all overlays (Zzz, need messages) in the same bubble style; driven by object.getOverlayDescriptor()
  • Full map – rendered once on first render() or after clearCache()
  • invalidateTiles(coords) – only affected tiles: remove sprites, re-add from ObjectManager
  • plannedTargets – chop/mine icons on targets
  • markedTrees – marked trees in area selection

Colonist rendering

  • InterpolationsetColonistMoveInterpolation(id, from, to, duration) for smooth movement
  • Walk cycle – sprite sheet frame cache per colonist
  • Overlays – Zzz (sleeping) and need messages (e.g. "I'm hungry") use the same bubble; content from getOverlayDescriptor(). Need overlays: one at a time, 5s visible, then 30s cooldown (stored on colonist via setOverlayCooldownUntil); constants OVERLAY_VISIBLE_MS / OVERLAY_COOLDOWN_MS in ObjectLayer

Stackables

  • Wood logs, stone bricks show quantity labels
  • Stack size from StackableInterface.getQuantity()

Rendering flow

  1. setMapData – update terrain data
  2. setZones – update zone overlay data
  3. setPlannedTargets / setMarkedTrees – update object layer
  4. render() – each frame:
  5. Terrain: render visible range if chunk changed
  6. Zone: render visible range
  7. Objects: full map once, or incremental invalidateTiles
  8. Colonist interpolation, object overlays (bubbles)
  9. Map container: position, scale from CameraController
  10. Cull offscreen tiles (except terrain/object groups, zone overlay, overlays)

Camera & viewport

  • mapContainer – scaled and positioned by CameraController
  • viewportMask – masks map to viewport
  • getVisibleTileRange(padding) – visible tile bounds for layer rendering

Culling

  • Individual tile sprites: culled when offscreen (margin = padding × tileSize)
  • Terrain tilemap, object render group, zone overlay, object overlays: always visible (no per-tile culling)

Performance (FPS / hover)

  • When the camera is static, full renderMapView() runs only every 2nd frame to avoid FPS drops on mouse hover (see staticRenderFrameCounter in IsometricMap).
  • ObjectLayer: updateOverlays() runs every 2nd frame; updateColonistInterpolation() runs every frame. See ../performance.md for full notes.