Skip to main content

Terrain Height Cache Fix (February 2026)

Overview

A critical bug in the terrain height cache was fixed in February 2026 that caused a consistent 50-meter offset in height lookups. This affected player positioning, pathfinding, and resource spawning.

Symptoms

  • Players floating ~50 meters above ground
  • Resources (trees, rocks) spawning in mid-air
  • Pathfinding failures (incorrect walkability checks)
  • Incorrect collision detection
  • Mobs spawning at wrong heights

Root Cause

The getHeightAtCached() function had two bugs:

Bug #1: Tile Index Calculation

Broken Code:
Problem: Doesn’t account for centered geometry. Terrain tiles use PlaneGeometry which is centered at origin, so a tile at world position (0, 0) covers the range [-50, +50], not [0, 100]. Example Failure:
Fix: Add canonical helper function:

Bug #2: Grid Index Calculation

Broken Code:
Problem: Omitted the halfSize offset from PlaneGeometry’s [-50, +50] range. Example Failure:
Fix: Add canonical helper function:

Bug #3: Cache Key Typo

Broken Code:
Problem: getTerrainColorAt() used underscore separator while cache used comma separator, so color lookups never found cached tiles. Fix: Use consistent underscore separator:

Impact

Before Fix:
  • Height lookups consistently off by ~50 meters
  • Players spawned in air or underground
  • Resources placed at wrong elevations
  • Pathfinding used incorrect heights
After Fix:
  • Accurate height lookups (±0.1m precision)
  • Players spawn at correct ground level
  • Resources placed on terrain surface
  • Pathfinding uses correct walkability

Migration

No migration needed - the fix is automatic. Steps:
  1. Update to latest main branch
  2. Restart server
  3. Heights are corrected immediately
No database changes required - height cache is runtime-only.

Testing

Verify Fix

Visual Verification

  1. Spawn player at known coordinates
  2. Verify player is on ground (not floating)
  3. Check resources are on terrain surface
  4. Verify pathfinding works correctly

Regression Test

Expected: All height lookup tests pass.

Technical Details

Coordinate Systems

World Space:
  • Origin at (0, 0, 0)
  • Tiles centered at multiples of TILE_SIZE (100m)
  • Example: Tile (0, 0) covers [-50, +50] in both X and Z
Tile Space:
  • Integer tile indices
  • Tile (0, 0) is at world position (0, 0)
  • Tile (1, 0) is at world position (100, 0)
Grid Space:
  • Per-tile vertex grid (100×100 vertices)
  • Grid (0, 0) is at local position (-50, -50)
  • Grid (99, 99) is at local position (+50, +50)

Helper Functions

worldToTerrainTileIndex:
localToGridIndex:
Usage:
Files Modified:
  • packages/shared/src/systems/shared/world/TerrainSystem.ts - Core terrain system
  • Added worldToTerrainTileIndex() helper
  • Added localToGridIndex() helper
  • Fixed getHeightAtCached() calculation
  • Fixed getTerrainColorAt() cache key
Commit: 21e08609

Debugging

Enable Height Logging

Visualize Tile Boundaries

Check Cache Contents

Performance

No performance impact - the fix only corrects calculations, doesn’t change algorithmic complexity. Cache Hit Rate: Unchanged (~95% for active gameplay areas) Lookup Time: Unchanged (~0.01ms per lookup)