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