Skip to content

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

Description

@marceld23

Problem

The terrain-wonders wave (#698#709, PR #710) made WorldGenerator.SurfaceHeight ~2.6x more expensive: the PR CI test job went from ~6.5 min to ~17 min, and the same cost hits the game itself (chunk generation, the ~17k-sample per-world calibration sweep, river routing, previews, settlement placement).

Root causes (all per-COLUMN work that is constant per WORLD)

  • The landmark chain re-evaluates ~10 feature gates (HasVolcanoes, HasCalderas, HasTravertine, HasCenotes, HasMegaRift, …) for every column — including Noise.Hash world rolls and field comparisons whose answers never change for a given world.
  • Several gates do string work per column: TerrainStyle.ToLowerInvariant() (allocates!), string.Equals(..., OrdinalIgnoreCase) on planet keys, StyleHybridEligible switch on a lowered string. Millions of short-lived string allocations → GC pressure.
  • PlanetSeed re-hashes the planet-key string on every call; SurfaceHeight + RawSurfaceHeight + GetExtraBands + TunnelSpans each call it again per column.
  • GrainFor re-rolls the per-world terrain grain from Noise.Hash per column; the continent profile and hybrid thresholds are similarly recomputed.

Fix

Introduce a per-world wonder profile cached like CalibFor (static dictionary keyed on seed/planet/circumference/cratered/salt/continents): planet seed, terrain grain, hybrid thresholds, continent profile, and one boolean per feature family. All hot-path callers read the profile; per-column code becomes arithmetic only.

Acceptance

Metadata

Metadata

Assignees

Labels

area: serverGameServer / Networking / WorldHost / Api / PersistenceperformanceRuntime/loading performance work

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions