feat(simulation): feature-name pipeline wired + legacy window_granularity u32 retired (T-1169, T-1159)

One commit for two tickets whose changes share the bridge/plugin
plumbing files. T-1169 connects the three dormant feature-name pieces:
atlas_feature_names populated at regen (17,891 rows — 15,190 mountain,
2,701 river — via populate_atlas_feature_names mirroring the city-names
importer; systems.db regenerated, stamp fresh), attach_feature_names
wired into the cascade's Topography block with name pools threaded
DB-free through AnalyzeBody (D-225 pattern) and assignments stored on
Layer1Output/BodyWorldState for future consumers, and a
FeatureNamesRequest/Response read proxy as the bridge's 7th tagged
envelope (D-236 pattern, both SimBridge impls). Client label DRAW is
deliberately NOT here — implementation proved both river and mountain
labels need a wire-carried position (the pool is position-free; course
polylines aren't correlated with the named attractors by construction) —
deferred to T-1195's single design pass. cascade_layer1 golden re-pinned
(additive feature_names field).

T-1159 retires the legacy u32 granularity field fully shadowed by
window_granularity_v2: AtlasLayerRequest.window_granularity,
DistrictWindowLayer.granularity echo, the u32::MAX sentinel, and
resolve_window_granularity are gone server-side; client encode paths and
the caller-less atlas_window_cache legacy key component dropped;
msgpack fixtures regenerated; the T-1150 aliasing regression test now
drives through the surviving enum field. The district_window carrier
itself survives byte-compatible per D-255(c).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 16:10:27 +02:00
co-authored by Claude Fable 5
parent befdb689c1
commit 8da9670e0f
28 changed files with 1244 additions and 467 deletions
+10 -10
View File
@@ -434,21 +434,22 @@ func send_named_action(action_name: String, action_data: Variant = null) -> void
## whole-body-layer caller (show_body()'s existing request), so their wire
## traffic is byte-unchanged.
##
## window_granularity/window_min_wl_m (T-1150): struct/key plumbing for the
## zoom-ladder quarter rung — district (0/omitted) stays the default for
## every caller in this codebase today.
## window_min_wl_m (T-1150): struct/key plumbing for the octave cutoff — 0
## (omitted) stays the default for every caller in this codebase today.
##
## window_granularity_v2 (T-1152/T-1153): the R5-redesigned string-tag
## granularity ("Quarter"/"District"/"Region") — the ONLY way to request the
## coarser-than-district Region rung the legacy u32 field cannot express.
## Empty string (omitted) is the default for every caller that doesn't pass
## it, byte-compatible with every pre-T-1152 request.
## window_granularity_v2 (T-1152/T-1153): the string-tag granularity
## ("Quarter"/"District"/"Region") — the way to request the coarser-than-
## district Region rung. Empty string (omitted) is the default for every
## caller that doesn't pass it, resolving to District server-side.
##
## T-1159: the legacy `window_granularity: int` parameter this function used
## to also forward is retired — see atlas_map_protocol.gd's
## encode_atlas_layer_request doc for the full rationale.
func request_atlas_layers(
body_id: String,
up_to: String = "Topography",
window_center: Variant = null,
window_n: int = 0,
window_granularity: int = 0,
window_min_wl_m: int = 0,
window_granularity_v2: String = ""
) -> void:
@@ -459,7 +460,6 @@ func request_atlas_layers(
up_to,
window_center,
window_n,
window_granularity,
window_min_wl_m,
window_granularity_v2
)
+14 -19
View File
@@ -32,29 +32,27 @@ class_name AtlasMapProtocol
## client-side default/cap constants (DISTRICT_WINDOW_DEFAULT_N/MAX_N) live on
## the regional-window viewer, not duplicated into the codec.
##
## `window_granularity`/`window_min_wl_m` (T-1150): the derivation-granularity
## axis (district=1/omitted vs. quarter=4) and the octave cutoff, in whole
## metres. Both OMITTED (not sent as 0) when at their default — this is
## struct/key plumbing only (T-1150 scope): no caller in this codebase
## requests quarter granularity yet (that's T-1153); this function just makes
## it possible to ask, byte-compatible with every existing caller that
## doesn't pass them.
## `window_min_wl_m` (T-1150): the octave cutoff, in whole metres. OMITTED
## (not sent as 0) when at its default — struct/key plumbing, byte-compatible
## with every existing caller that doesn't pass it.
##
## `window_granularity_v2` (T-1152, R5 redesign — see
## server/src/atlas/layer_proxy.rs's `WindowGranularity` doc): the ONLY way to
## express a coarser-than-district rung (`"Region"`) the legacy `u32` field
## cannot encode. A plain STRING variant tag ("Quarter" | "District" |
## server/src/atlas/layer_proxy.rs's `WindowGranularity` doc): the derivation
## granularity, a plain STRING variant tag ("Quarter" | "District" |
## "Region"), matching `RoadNodeKind`'s existing wire precedent on this same
## carrier (a bare `#[derive(Serialize, Deserialize)]` enum with no
## `#[serde(rename_all)]` — rmp_serde encodes the Rust variant NAME verbatim,
## not an integer discriminant). OMITTED (not sent as "") when
## `window_granularity_v2` is the empty string — `#[serde(default)]` on the
## Rust side decodes absence as `None`, falling back to the legacy `u32`
## field's `resolve_window_granularity_v2()` precedence rule (that field wins
## over the legacy one whenever present — see that Rust doc for the full
## precedence contract). Every pre-T-1152 caller (and every T-1150 caller that
## only ever sends `window_granularity`) omits this field entirely and stays
## byte-compatible.
## Rust side decodes absence as `None`, resolving to District (the default
## rung).
##
## **T-1159:** the legacy `window_granularity: int` field this codec used to
## also encode (T-1150's finer-than-district-only `u32` wire encoding) is
## retired — `window_granularity_v2` fully shadowed it since T-1152, and no
## caller in this codebase (nor any external client — single-repo
## client/server pair) ever sent it as anything but the byte-compatible
## default.
##
## **Quantization split (PR #191 review, Hoshe 1 / Tyre C3):** `window_min_wl_m`
## is sent HERE as a raw, unquantized value — this codec does NOT snap it to
@@ -71,7 +69,6 @@ static func encode_atlas_layer_request(
up_to: String = "Topography",
window_center: Variant = null,
window_n: int = 0,
window_granularity: int = 0,
window_min_wl_m: int = 0,
window_granularity_v2: String = ""
) -> PackedByteArray:
@@ -80,8 +77,6 @@ static func encode_atlas_layer_request(
var center: Vector2i = window_center
msg["window_center"] = [center.x, center.y]
msg["window_n"] = window_n
if window_granularity != 0:
msg["window_granularity"] = window_granularity
if window_min_wl_m != 0:
msg["window_min_wl_m"] = window_min_wl_m
if not window_granularity_v2.is_empty():
+7 -7
View File
@@ -786,17 +786,18 @@ static func encode_request_bookmark_catalog() -> PackedByteArray:
## 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. window_granularity/window_min_wl_m (T-1150): same
## byte-compatibility contract, see atlas_map_protocol.gd.
## window_granularity_v2 (T-1152): the R5-redesigned string-tag granularity
## ("Quarter"/"District"/"Region") — the only way to request the Region rung.
## Omitted (empty string) by every caller that doesn't pass it.
## byte-unchanged. window_min_wl_m (T-1150): same byte-compatibility
## contract, see atlas_map_protocol.gd.
## window_granularity_v2 (T-1152): the string-tag granularity
## ("Quarter"/"District"/"Region"). Omitted (empty string) by every caller
## that doesn't pass it, resolving to District server-side. T-1159: the
## legacy `window_granularity: int` parameter this used to also forward is
## retired — see atlas_map_protocol.gd's encode_atlas_layer_request doc.
static func encode_atlas_layer_request(
body_id: String,
up_to: String = "Topography",
window_center: Variant = null,
window_n: int = 0,
window_granularity: int = 0,
window_min_wl_m: int = 0,
window_granularity_v2: String = ""
) -> PackedByteArray:
@@ -806,7 +807,6 @@ static func encode_atlas_layer_request(
up_to,
window_center,
window_n,
window_granularity,
window_min_wl_m,
window_granularity_v2
)