Per the task-06 ground-test verdict (floor and 420 m ceiling frozen;
v2's ascent read flat-then-wall — 87% of the vertical budget in the
last 4% of input): the ascent is rebuilt as a terraced climb. Knots
recalibrated from the same pooled batch-04 land CDF at
P59/72/82/87/95/98 (K=0.509179/0.604081/0.698485/0.767213/0.930304/
1.050720), pooled land fractions exactly 59/13/10/5/8/3/2 (orange/red/
foothill-riser/bench/mid-riser/plateau/spike). Segments: frozen toe
and rise (storm anchors), smoothstep foothill riser to a near-flat
100 m bench, smoothstep mid riser to the near-flat white plateau at
220 m (relocated from 50 m — mountain towns/snow belong there),
per-seed-normalized u4 summit spike to 420 m (both retained from v2),
linear tail. Per-seed effective-curve monotonicity assertion retained.
TerrainCurve gate: "off"|"v3" (default v3); v1/v2 retired with a
loud config error (old blueprints regenerable). TCRV: knot slots carry
K1..K4 (K5/K6 are version constants), PlateauLo/Hi carry the two bench
anchors; version byte selects the semantics.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per the task-05 hillshade-gate verdict: lowlands frozen (identity/toe/
rise/shoulder/plateau byte-unchanged); the spike now maps [t4,
hMaxSeed] — each seed's own raw pre-curve maximum, computed in a new
pass-1 over GenerateTopography — onto the peak band, so every island
reaches the ceiling (v1's pooled-max domain left mid-range seeds at
110–175 m). Spike stiffened to 0.1u + 0.9u^4; peak cap raised to
420 m above sea (1.82869). Degenerate near-flat guard: spike domain
floored at t4 + 0.01. The curve is now SEED-DEPENDENT: hMaxSeed is a
pure parameter (D-035), recorded in TCRV (field renamed
HMaxCal -> SpikeMax, same byte layout; v1 semantics = pooled max, v2 =
per-seed), and the monotonicity assertion runs per generation against
the effective curve. TerrainCurve gate: "off"|"v2" (default v2);
"v1" retired with a loud config error (task-05 blueprints are
regenerable). Classify path untouched — the biome/water oracle must
hold unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The coarse and fine sampling loops both touched h=0.10 and the two
doubles round to the same float32, so the strict check compared the
identity value against itself and threw on every curve-on run. Only
strictly increasing float samples are compared now. The curve itself
was never non-monotonic.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
HeightCurve (pure static, D-035): calibrated monotonic piecewise map —
identity at/below sea 0.15; ease-out toe to the orange ceiling 0.206
(75% coverage, knot t1=P75=0.628736 from batch-04's pooled flat-sea
land CDF, 340.6M samples); linear rise to red 0.27 (t2=P90); smooth
shoulder to the 50m plateau shelf 0.3492 (t3=P93); near-flat plateau
step (t4=P96); accelerating spike to the 220m peak cap 1.0265; linear
tail past the calibrated max. Strict monotonicity asserted numerically
at startup, loud throw on violation.
Applied in GenerateTopography AFTER noise+falloff+Trench, BEFORE the
crater carve (carve cuts curved terrain; rim/bowl untouched by the
curve). Biome oracle mechanism: a retained uncurved classify heightmap
(alias of _heightMap when off, zero cost) feeds biome rules, both
flood fills, and the shared water predicates — classification is
curve-invariant by construction. Towns/roads/diagnostics/exported
heights use curved terrain; town positions may legitimately move.
Config gate TerrainCurve: "off"|"v1" (default v1), unknown values
rejected loudly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>