From b9c7675e78de832cfadf2b9fc65f3317a8c9f869 Mon Sep 17 00:00:00 2001 From: beezm Date: Mon, 10 Aug 2026 00:57:05 -0400 Subject: [PATCH] docs: the two-clause water presence rule (terrain-water task 15) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Server/README.md: why water presence is not just WBID. Records the classify-vs-render identity that makes the second clause both necessary (inside the crater carve) and safe (provably inert everywhere else), so the next reader does not have to re-derive it from the commit log — or, worse, "simplify" the second clause away. Co-Authored-By: Claude Opus 5 (1M context) --- Server/README.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Server/README.md b/Server/README.md index 2caac8b..2ff7955 100644 --- a/Server/README.md +++ b/Server/README.md @@ -27,11 +27,20 @@ vector ends up parallel to the view direction, so camera roll is undefined and G - **Road culling first.** Only the road segments whose bounding box reaches this chunk are kept, each tagged with its `RoadTier`. The padding is derived from the widest shoulder any tier has plus a margin, so widening a road cannot silently truncate it at chunk edges. -- **Water per column** (task 13) — the blueprint is the **authority** on where water is; the server - only reads it. `WBID` decides presence (it is the water stage's own classification output, the - same set the biome grid's Ocean/Lake pixels form by construction), `WSRF` gives the surface level - per pixel, and the `WBTB` body table is the fallback when a column is flagged wet but carries the - `WSRF` no-water sentinel. A body the table does not know leaves the column **dry** rather than +- **Water per column** (tasks 13, 15) — the blueprint is the **authority** on where water is and at + what level; the server only reads it. `WSRF` gives the surface level per pixel, and the `WBTB` + body table is the fallback when a column is flagged wet but carries the `WSRF` no-water sentinel. + + **Presence takes two clauses.** `WBID` (the water stage's own classification output) OR *the + rendered ground being under the ocean's surface*. The second exists because `WBID` was classified + from the **uncurved** heightmap while the mesh renders the **curved** one. Outside the crater + those agree exactly — the curve is identity at sea and monotonic, so `Apply(raw) < sea` iff + `raw < sea`. Inside it they do not: the carve lerps two different bases toward one target + (classify from `raw`, rendered from `Apply(raw)`, and `Apply(raw) < raw` in the lowland band), so + the rendered surface sinks faster and leaves a ring rendering below the waterline that `WBID` + still calls dry — 375,824 px on the C1 seed, all of it inside the carve. The second clause tests + the height the mesh actually uses against the **ocean body's own level from `WBTB`**, so the + runtime still derives nothing, and by the identity above it can only ever fire inside the carve. A body the table does not know leaves the column **dry** rather than guessing a level. The level is scaled by the same `HEIGHT_SCALE` as the terrain, so the sheet and the seabed cannot drift apart. Depth for shading is taken from **blueprint** heights, not rendered geometry — the terrain render clamps its floor at `Y = 2`, which would otherwise flatten every