CascadeLayer::Region appended per the enum's append-only Ord rule (depends only on seed/body_params/heightmap dims — documented); BodyWorldState.regions BTreeMap per the districts precedent; RegionGridLayer dense row-major all-integer encoding (season/weather repr(u8) discriminants, mean_temp deci-degC i16 with i16::MIN airless sentinel, moisture_q u8); build_region_grid mirrors build_district_grid; protocol.gd region_grid passthrough (visual overlay deliberately out of scope); wire fixtures regenerated via make fixtures. atlas:: suite 507 green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
T-960: gen_l2_roads (MaintenanceAuthority-colored polylines, rail styling, junction markers) + gen_l3_settlements (size-scaled markers, capital shape, name labels) overlays — cities render on generated bodies for the first time; left-side generation legend panel (D-226 item 3, data-driven per-overlay spec, implant component library); protocol.gd decodes road_graph/settlements + the two new response types. T-949: system_index/atlas_app/overview_screen migrated off the direct star_map_data.json read to StarMapRequest over the bridge (loading state + replay-on-connect, no silent file fallback); atlas_viewer _load_markers requests CityNamesResponse for non-Sol bodies; Sol keeps the legacy authored markers.json geometry read (D-236/T-1073, load-bearing guard). Lead fix: _send_star_map_request now carries the same guard as request_star_map — the autoload's _star_map_wanted leaked across gdUnit suites and the unguarded replay-on-CONNECTED crashed 8 pre-existing flow tests on a Nil bridge; reset_test_state clears the flag. Fixtures regenerated via gen_fixtures (road/settlement samples). Full suite 2946/2946.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Close the last D-234 piece — terrain water-direction extraction wired through
to founding orientation and the quarter waterfront rule:
- Layer 1: TerrainAnalysis::water_bearing — 8-octant integer bearing toward the
nearest water from the water_dist gradient (D-010, no atan2). Stored on
GeographicAttractor.water_bearing (360 = none).
- #956 founding orientation: coastal/river settlements now get a real
water-facing bearing (the anchoring attractor's), replacing the 0 stub.
- #957 waterfront rule (D-234b): the water-facing quarter edge (from the
settlement's Coastal founding orientation) drops its block setback to 0 so
buildings present flush to the quay (dock-orthogonal). Typed Edge + coastal_edge
+ per-block gating.
Golden + atlas_response fixture rebaked (additive water_bearing field only).
8 new tests. All integer-deterministic (D-010).
Pending: the waterfront rule reads context.founding_orientation, which
city_context_reader still stubs to Cardinal — real per-settlement orientation
reaches quarter generation once the Layer-3 placement -> Layer-4 GenerateSkeleton
dispatch is wired (the remaining cross-layer integration).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
DrainageBasin gained a territorial_status field, so the Layer-1 golden and the
atlas_response msgpack fixture pick it up. Both changes are additive/
representational — basin/attractor/river selection is unchanged.
- cascade_golden.rs: pass None dominant_faction; golden rebaked (only
"territorial_status": "FrontierUnclaimed" added per basin).
- gen_fixtures.rs: set the new field in the atlas_response generator; fixture
regenerated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
all_fixtures_deserialize panicked with "unknown fixture naming
convention: atlas_response_ready" — the test reads every .msgpack in
client/tests/fixtures/msgpack but had no branch for the atlas_response
prefix (the AtlasLayerResponse fixtures gen_fixtures emits, #969). A
pre-existing gap (present on main; the suite isn't gated by the pre-push
hook, which runs cargo-deny/ruff/JSON/stamp, not cargo test).
Add an atlas_response branch deserializing AtlasLayerResponse, and
regenerate atlas_response_ready.msgpack so its bytes match the now-integer
GeographicAttractor types (#955).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two Layer-1 generation fixes surfaced by the per-layer atlas viewer:
- Layer1Output now carries grid_w/grid_h (the downsampled working-grid the
positions live in). The client maps overlays from these, so the scale is
correct for any source heightmap resolution rather than assuming the texture
size — fixes overlays projecting at half scale into a corner.
- Drainage basin boundaries are traced as ordered, non-self-crossing contours
via Moore-neighbour tracing instead of an angle-from-centroid sort. The sort
produced star-shaped, self-crossing polygons for concave basins that rendered
as straight chords across the map.
Golden (cascade_layer1.json) and the cross-language atlas_response_ready
fixture regenerated. 100 atlas lib tests + the new tracer test pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Client half of the layer-stream protocol (codec only; transport wiring next).
- protocol.gd: encode_atlas_layer_request (bare {body_id, up_to} map so the
server demux routes it to the proxy, not the PlayerInput array) and
decode_atlas_layer_response (-> {body_id, status, error, layer1}; returns null
for non-atlas frames, e.g. a snapshot, so receive_bytes can disambiguate).
- gen_fixtures.rs: cross-language fixtures (atlas_response_ready/pending/
not_found) from real rmp_serde output, matching the test_protocol.gd pattern.
- test_protocol.gd: 5 tests decode the fixtures + verify a snapshot is not
mistaken for a response + the request encodes to the right shape. 68/68 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>