feat(ui): T-1138 regional map screen — click-through descent, fixed planetary view, windowed composite (D-226 T-1124 SS5)

Entry per Jeroen's 2026-07-21 revision: planetary heightmap is now
FIXED — all drag-pan/wheel-zoom input removed (set_view/get_view_*
capture API survives for the golden harness); hover shows a
not-to-scale bracket reticle with the real extent labeled (a true
n=32 rectangle is sub-pixel on the planetary canvas — the honest
representation given the morph transition is deferred), and a click
that misses every city marker descends (city-click wins — one
gesture, two contextual reads, no modifier). Descent pushes a new
'district' nav screen centered on the click point's DistrictPos via
atlas_descend_geometry.district_pos_at (the pixel-to-district inverse
of the server mapping, verified against scale.rs).

Regional mode: atlas_window_viewer draws the composite (morphology x
elev_q lightness base; temp/moisture/veg toggles — temp reuses the
region-ramp colorizer exactly; Marine=6 transparent; glaciation
always-on tint matching apply_ice_tint's REAL gate, None|Light no-op,
over the amendment's looser prose — documented); pan-on-held-composite
with edge-crossing refetch + border-fade during the queue-based
derive wait; zoom never refetches. atlas_window_cache: LRU keyed
(body_id, center, n), touch-on-read, evict-only, no freshness (D-227).
atlas_window_request mirrors the generation-proxy pending-retry shape
for None-until-derived. Codec: window params omitted from the wire
when absent — byte-identical for every existing caller.

Live-verified against the T-1137 server in-worktree: real round-trip
on a GJ380c coastal district (6 fields x 1024 cells), echo staleness
guard, genuine ~1.4s background-derive wait, pan-edge refetch to an
adjacent window, cache-hit on re-descent with zero network. Full
client suite 3194/3194; gdlint clean on all 18 files.

Open follow-ups flagged in-code: header location label always falls
back to coordinates (nearest-settlement needs a join the district
window does not carry); atlas_standalone.gd's 'atlas_app.gd is never
modified' doc line is now imprecise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 13:32:06 +02:00
co-authored by Claude Fable 5
parent 172ce124c8
commit 9e1e6db614
19 changed files with 2228 additions and 72 deletions
+12 -4
View File
@@ -776,16 +776,24 @@ static func encode_request_bookmark_catalog() -> PackedByteArray:
## above. Every function below is a thin delegate under its ORIGINAL public
## name — external callers (sim_bridge.gd, test_atlas_overlays.gd,
## test_atlas_data_delivery.gd) are unaffected by the move.
## window_center/window_n (T-1138, D-226 T-1124 amendment §1): optional
## windowed district-resolution regional-map query — see
## atlas_map_protocol.gd's encode_atlas_layer_request doc for the wire shape.
## Omitted callers (every whole-body-layer call site predating T-1138) are
## byte-unchanged.
static func encode_atlas_layer_request(
body_id: String, up_to: String = "Topography"
body_id: String,
up_to: String = "Topography",
window_center: Variant = null,
window_n: int = 0
) -> PackedByteArray:
return _amp().encode_atlas_layer_request(_mp(), body_id, up_to)
return _amp().encode_atlas_layer_request(_mp(), body_id, up_to, window_center, window_n)
## Decode an AtlasLayerResponse (#969, D-225). Returns a Dictionary
## {body_id, status, error, layer1, district_grid, road_graph, settlements,
## region_grid, quarter_footprints}, or null if the bytes are not an atlas
## response (no "status" key — e.g. an ObserverSnapshot).
## region_grid, quarter_footprints, district_window}, or null if the bytes are
## not an atlas response (no "status" key — e.g. an ObserverSnapshot).
static func decode_atlas_layer_response(bytes: PackedByteArray) -> Variant:
return atlas_response_from_raw(decode_raw(bytes))