Files
settled-reach/client/ui
jpmschweitzerandClaude Opus 5 4e503c3565 fix(simulation): a river course was one D8 hop, not a river (T-1237)
D-261 asked for contiguous river strokes, and the client got them by
chaining hops back together after the fact. That could not work: each
hop was warped independently, so a shared confluence point arrived as
two points that no longer coincided -- 375 hops rejoined into 260
pieces, and Ferrath's Global map showed scratches rather than
watercourses.

The join belongs before invention, so it now happens on the server.
river_course::build_paths walks the D8 cell graph into whole rivers
from headwater to mouth, edge-drain, or junction with an already-walked
river (including the joint cell, so a tributary visibly meets its
trunk). step_canvas emits one course per river instead of one per cell,
which also drops the per-hop warp and resampling -- a path's shape is
the terrain's, so there is nothing left to invent. It is cheaper too:
one point per river cell rather than three.

The client's _chain_runs() and its endpoint index are deleted. Runs
survive only for the reason D-261 gives them -- water splits a course,
and a river crossing a lake is genuinely two strokes that must not be
rejoined.

Pinned by a real-terrain test on GJ380c rather than a synthetic graph,
because the bug was caught by eye on real terrain: a lake must have an
outflow that runs to sea level, and no such line existed. It asserts
the property the eye was checking -- rivers are long, at least one
reaches the sea, and every path is a contiguous walk.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 14:43:41 +02:00
..