Skip to content

perf(worldgen): per-world wonder profile — undo the #698–#709 hot-path cost - #713

Merged
marceld23 merged 1 commit into
mainfrom
perf/worldgen-wonder-profile
Aug 3, 2026
Merged

perf(worldgen): per-world wonder profile — undo the #698–#709 hot-path cost#713
marceld23 merged 1 commit into
mainfrom
perf/worldgen-wonder-profile

Conversation

@marceld23

Copy link
Copy Markdown
Owner

Pure refactor of the terrain-wonders hot path — bit-identical terrain, verified by an FNV hash sweep (surface heights + extra bands + tunnel spans) over every planet type × two seeds × continents on/off, captured before the refactor and matched after every step.

What was slow

SurfaceHeight — the hottest function in the codebase (256 columns/chunk, ~17k-sample per-world calibration, rivers, previews, placement) — re-derived per COLUMN what is constant per WORLD: feature gates with ToLowerInvariant() string allocations, Noise.Hash world rolls, repeated planet-key hashing. Worse, the tunnel carver rebuilt its whole worm polyline (dozens of xorshift rolls) for every column of every tunnel-bearing cell (half the map), and sea stacks/hoodoos/cenotes computed a full RawSurfaceHeight anchor before checking whether the column is even inside the feature.

The fix

  • WonderProfile, cached per world like the calibration (static dict + lock-free instance fast path): planet seed, terrain grain, hybrid thresholds, continent profile, lowered style and one boolean per feature family. Per-column code reads booleans and doubles only.
  • Per-cell tunnel worm cache + XZ bounding reject in the span sampler.
  • Distance-first ordering for the sea-stack/hoodoo/cenote probes (behaviour-preserving — all gates are conjunctive).

Measured

closes #712

🤖 Generated with Claude Code

…h cost (#712)

Pure refactor, bit-identical terrain (verified via an FNV height/band/tunnel
hash sweep over every planet type x seeds x continents on/off):

- WonderProfile cached per world (CalibFor pattern + lock-free instance fast
  path): feature gates, PlanetSeed, terrain grain, hybrid thresholds, continent
  profile and the lowered style resolve once per world instead of per column —
  no more per-column ToLowerInvariant allocations or Noise.Hash world rolls.
- Tunnel worms are built once per cell (static cache + instance slot) instead
  of per column; AddSegmentSpan gains an XZ bounding reject.
- Sea stacks / hoodoos / cenotes check distance BEFORE computing their
  RawSurfaceHeight anchor (and the stack swell probe) — every column of a
  feature-bearing cell used to pay the full anchor.

Measured: harness sweep 2174 -> 1472 ms (-32%); local fast tier 7m05 -> 5m31.

Co-Authored-By: Claude Fable 5 <[email protected]>
@marceld23
marceld23 merged commit c947795 into main Aug 3, 2026
12 checks passed
@marceld23
marceld23 deleted the perf/worldgen-wonder-profile branch August 3, 2026 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(worldgen): cache per-world feature gates — SurfaceHeight got ~2.6x slower with the terrain wonders

1 participant