Commit graph

5 commits

Author SHA1 Message Date
c1f62f6899 feat: tributaries wet full length; water fills the channel; banks flare as shores (terrain-water task 25)
The gate's two river notes.

FILL THE TRIBUTARIES. RiverTribWaterMinFlow defaults to 0, so every promoted
tributary carries water its whole length (800 of 1574 reaches are now on
tributaries, 65,364 of 268,863 wet px). The graceful tip survives: the fade zone
is now always TaperPx long starting wherever water begins, so with a threshold it
spans (WetFrom-Taper -> WetFrom) and with full watering it spans the first
TaperPx from the HEAD. Fill is about LENGTH, taper is about the END.

FILL THE CHANNEL, NOT THE FLOOR. The water surface is now RiverFillFraction (80%)
of the LOCAL bed depth rather than a fixed height, floored by RiverWaterDepthM as
an absolute minimum. A fixed height is wrong at both ends — a trickle in a 13 m
mouth and over the rim at a 1.5 m head — where a fraction is right at every
scale and cannot spill onto the plain.

BANKS AS SHORES. The shoulder flares RiverBankFlare (3.2, was a hard 2x)
half-widths with a smootherstep instead of smoothstep, so the rim leaves nearly
tangent to the water plane. That alone cut too much where a course crosses a
ridge (cells deeper than 20 m went 339 -> 1917, max 26 -> 37 m), so the SHOULDER
may not lower a cell more than RiverBankMaxCutM (3 m) — measured against the
PRE-PASS surface, because a per-write cap let overlapping stamps each take
another 3 m and changed the carved volume by 1 m3 out of 1.29 M. Gentle ground
still flares into a shore; a ridge crossing keeps steep walls, which is what a
gorge looks like. Net result is better than BOTH predecessors: max cut 16.8 m
(task 24: 26.0), zero cells past 20 m (task 24: 339), carve p95 5.26 m.

Guards unchanged: BIOME oracle md5-identical to the task-22 baseline, 0
newly-below-sea, 0 below-sea cells modified, lowest carved cell exactly
sea+margin, island top 457.65 m exact, crater core excluded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:11:41 -04:00
0e39538604 feat: tributary water (tapered), significant-lake targeting, finer steps + deeper beds (terrain-water task 24)
All three gate polish items — they interleave in the same files, so they land as
one buildable commit rather than three that do not compile independently.

1. TRIBUTARY WATER. Tributaries carved in task 22/23 but stayed dry: they were
   never registered with the water stage. They now are (as CarvedRiver entries
   named 'trib', kept OUT of the per-river console table so it stays the 6
   mains). RiverTribWaterMinFlow (40k px of along-course flow) sets where water
   starts; RiverTribTaperPx (120 px) makes the wet->dry transition a FADE, not a
   wall — across the taper the wet strip narrows (0.25x -> 1x half-width) AND its
   surface drops toward the bed, so a stream head thins out and vanishes.
   Along-course flow is modelled quadratically from headwater trickle to full
   drainage at the mouth (the plan records drainage per river, not per sample).
   RiverTribWaterMinFlow=0 waters them end to end — the documented fallback.

2. LAKE-ENDER TARGETING. The join routed to the nearest classify-water CELL,
   which a 322-px puddle satisfies; it stopped ~80 px short of the 197k-px
   lagoon beside it. It now routes to a SIGNIFICANT water mask (bodies of at
   least RiverLakeMinTargetPx = 20k cells, built from the water-body table),
   falling back to any classify water only if no significant body is reachable,
   so a seed with genuinely small ponds still connects. Proven by adjacency:
   task 23 had 63 river cells touching the puddle and 0 touching the lagoon;
   task 24 has 49 touching the lagoon and 0 touching the puddle.

3. FINER STEPS + DEEPER BEDS. RiverStepDropM 2.0 -> 0.6 and RiverWaterDepthM
   1.2 -> 2.2, RiverDepthScale 1.0 -> 1.5. Reaches 298 -> 1034; the level gap
   between adjacent reaches drops from median 0.571 m / p95 2.08 m to median
   0.124 m / p95 0.74 m — the pond-staircase reads as a graded descent. Reaches
   stay trivial bodies (median 44 px).

Guards all held: flood guard 0 newly-below-sea and 0 below-sea cells modified,
BIOME oracle md5-identical to the task-22 baseline (output-only unchanged),
island top 457.65 m exact, crater core excluded, lowest carved cell exactly
sea+margin (37.85 m). Cumulative max cut 25.98 m with 339 cells >20 m —
identical to task 23, so deepening the WATER did not deepen the worst cuts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 20:24:38 -04:00
8f5767308a feat: stepped river water + widen + lake-ender join + the task-22 nits (terrain-water task 23, C0b finale)
THE PAYOFF: rivers now carry water. Each carved main river becomes a chain of
stepped flat water-body reaches — a new reach every RiverStepDropM (2 m) of bed
descent, sitting RiverWaterDepthM (1.2 m) above its bed, strictly descending to
the outlet. Reaches are ordinary water bodies (WBID cells + WBTB type 2 'river',
fresh; WSRF derives from body levels as ever), so river water renders through
the C1 path with the task-15 presence rule at its banks, untouched. Existing
bodies are never overwritten — a river MEETS its lake or the sea. Measured on
1280587109: 298 reaches across 6 rivers, 184,620 wet px, levels stepping 278 m
down to 39.5 m; in-engine, one valley frame renders surfaces 46.2-114.5 m.

Beds widened (RiverWidthScale default 1.75). Lake-enders: the stem's pooling
terminal IS a local minimum, so the first extension attempt (blind steepest
descent) dead-ended in 0 steps — replaced with the lowground Dijkstra to the
nearest classify-water cell; the E-lagoon river now joins its lake (87 px).
Smoothing is applied ONLY to lowland routes: smoothing upland stems moved them
off their carved valley floors into the walls (max cut 14.6 -> 27.3 m measured;
split restores valley-floor fidelity). TYPE_RIVER added to the WBTB registry
(parser validation extended; doc updated in the docs commit).

Task-22 nits fixed: max-cut is now CUMULATIVE vs the pre-pass surface (the
honest number: p95 carve 7.0 m; 339 cells island-wide exceed 20 m — localized
outlet-gorge notches where stems cross deposit ridges, deepest 26 m); and
0_height/0_water are re-drawn and re-captured AFTER the river pass so the
exported snapshots show beds and water.

Guards: flood guard holds (water pixels unchanged around the carve; the water
stage touches no heights), BIOME oracle md5-identical to the task-22 baseline,
0_water changed (that IS the river water), island top 457.65 m exact, crater
core excluded.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 19:55:04 -04:00
148602b4c5 feat: lock lowground routing; smooth river courses with the road pass's RDP+Chaikin (terrain-water task 23)
LOWGROUND is the gate verdict and the locked default ('short' stays available
behind the dial for the record). Every river polyline (upland stem + lowland
reach) is now decimated with RDP(4.0) and rounded with 4 Chaikin passes —
numerically mirroring MapGenerator.SmoothPath, since this pass is Godot-free —
before the bed profile is built, so the carved centreline carries none of the
8-connected Dijkstra 45° kinks (task-22 §4 caveat a). The monotone-descent and
sea-clamp constraints are applied to the smoothed course, unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 19:37:29 -04:00
6960c2a2e8 feat: river bed carving with SHORT/LOWGROUND lowland routing A/B (terrain-water task 22, C0b part 2a)
Executes the frozen task-21b plan as real terrain — the first river pass to
modify the render map. NO WATER (part 2b waters the gated routing style).

RiverCarvePass (D-035 numeric): reruns DrainageAnalysis in-pipeline
(deterministic — same seed, same eroded surface, same plan), routes each routed
giant's lowland reach to the nearest ocean by deterministic Dijkstra under two
config-gated cost models — 'short' (distance + uphill penalty; heads direct) vs
'lowground' (cost ~ elevation above sea; follows the lowest ground and
meanders) — then carves every promoted course as a parabolic channel with a
smoothstep shoulder. Width/depth grow downstream with sqrt(drainage); bed
profile forced monotone non-increasing toward the outlet (water must flow) and
clamped to sea + RiverSeaMargin EVERYWHERE, with below-sea cells read-only and
the crater core excluded — the erosion flood-guard discipline, asserted per
generation by the water-pixel A/B (throws on any change).

Pipeline slot: AFTER GenerateTowns (towns read the render map for land/slope/
water checks — carving first would move towns and destabilise every A/B) and
BEFORE roads (a full run's A* should see the beds).

ISLA_SERVER_CONFIG env override added to ConfigManager: batch/A-B tooling loads
an alternate config file and the developer's live ServerConfig.json is never
written by tooling again (the task-19 restore near-miss class is retired).

Measured, seed 1280587109 (both variants): oracle md5-identical to baseline
(BIOM/WBID bitwise equal), 0 newly-below-sea cells, below-sea untouched, island
top 457.65 m exact, lowest carved cell exactly sea+margin (37.85 m), and
Rivers='off' is bitwise identical to the task-19 blueprint. All routed giants
reach the ocean in both styles. Wander (polyline/straight): SHORT 1.02-1.06 vs
LOWGROUND 1.24-1.38; SHORT carves 811k m3 (cuts through rises, max cumulative
cut 14.6 m), LOWGROUND 481k m3 (goes around, 14.3 m). Pass cost ~25 s (plan
21 s, routing 1.4-2.5 s, carve 0.3 s).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 19:16:37 -04:00