feat(simulation): lake_margin_q depth band — lake shorelines gain gradient vocabulary (T-1188)
Lake edges rendered as hard step-edges while ocean coasts got multi-tone transition bands: every coastal-transition morphology gate keys on ocean_fraction_q, definitionally 0 inside a lake basin (hypothesis (b) of the ticket; (a) disproven first — a shoreline-crossing sweep at 2048/512/128m plus a 10m fine sweep all land on the same continuous crossing, so positional refinement was never broken). New DistrictProfile.lake_margin_q (0-100 settled-hydrology depth band, from the same bilinear filled/elevation pair the lake test already samples; ceiling calibrated just above the observed p90 depth on GJ338Bd's 5,043 flooded cells), threaded through both derive paths onto EncodedStepCanvas (serde-default for shape tolerance) and down the client: protocol decode, terrain-layer plane, colorize shades Lake cells by depth band instead of elev_q (bedrock-under-water, the wrong signal). project.yaml 0.4.0 -> 0.4.1: the new wire field must invalidate the client disk cache via its version tag (T-1183's D-192 mechanism). Acceptance gates green with the new field (lossless round-trip, cache-hit==cache-miss, every rung). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -34,10 +34,17 @@ class_name StepCanvasProtocol
|
||||
## (duplicated here per browse_protocol.gd's own "genuinely standalone"
|
||||
## precedent, not shared via a Callable).
|
||||
## EncodedStepCanvas — a map: {width, height, morphology, elev_q, temp_dc,
|
||||
## moisture_q, vegetation, settlement_id, glaciation, flooded_q, courses,
|
||||
## cliffs}. The six PNG-per-field dense planes (morphology/elev_q/
|
||||
## moisture_q/vegetation/glaciation/flooded_q) are each a map
|
||||
## {"png_bytes": [...]} — png_bytes is a Rust `Vec<u8>` with NO
|
||||
## moisture_q, vegetation, settlement_id, lake_margin_q, glaciation,
|
||||
## flooded_q, courses, cliffs}. `lake_margin_q` (T-1188) is a MessagePack
|
||||
## map key that did not exist before this codec version — an older server
|
||||
## build's payload simply omits it (`d.get("lake_margin_q")` below returns
|
||||
## null, decode_png_field() then returns an empty PackedByteArray, the
|
||||
## same "field absent -> draws as the colorize fallback" posture every
|
||||
## other optional plane on this wire already has); a client this new
|
||||
## talking to that old a server is not a supported combination anyway
|
||||
## (D-192 co-ship). The seven PNG-per-field dense planes (morphology/
|
||||
## elev_q/moisture_q/vegetation/lake_margin_q/glaciation/flooded_q) are
|
||||
## each a map {"png_bytes": [...]} — png_bytes is a Rust `Vec<u8>` with NO
|
||||
## serde_bytes annotation anywhere in this codebase (confirmed: grep for
|
||||
## serde_bytes across server/src returns nothing), so serde's blanket
|
||||
## Vec<T> impl serializes it via serialize_seq — a msgpack ARRAY of
|
||||
@@ -173,6 +180,7 @@ static func _decode_encoded_canvas(raw: Variant) -> Variant:
|
||||
if settlement_id_raw is Dictionary
|
||||
else []
|
||||
),
|
||||
"lake_margin_q": decode_png_field(d.get("lake_margin_q")),
|
||||
"glaciation": decode_png_field(d.get("glaciation")),
|
||||
"flooded_q": decode_png_field(d.get("flooded_q")),
|
||||
"courses": d.get("courses", []),
|
||||
|
||||
Reference in New Issue
Block a user