feat(simulation): #523 add zone_id to ObserverSnapshot (D-077, protocol v11)
Server-tracked zone_id on VisibleTile for D-073 zone crossfade and D-059 deep fog temperature tint. ZoneMap resource backed by BTreeMap, observer enrichment in snapshot assembly. Backwards-compatible: v10 payloads deserialize with zone_id: None. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+16
-1
@@ -356,6 +356,21 @@ How the player observes and interacts with the world: camera, fog, line-of-sight
|
||||
- **Amends:** [D-061](#d-061-dialogue-box--bottom-screen-max-20-height-no-portraits) (adds pixel value for max-width)
|
||||
- **Raised by:** Stig (OQ-29), revised per Tyre architecture review
|
||||
|
||||
### D-077: Zone temperature memory — server-tracked zone_id (OQ-09 resolution)
|
||||
- **Date:** 2026-02-19
|
||||
- **Decision:** Zone temperature memory is **server-tracked** via `zone_id: Option<u16>` on `VisibleTile` in `ObserverSnapshot`. The server assigns a zone ID to each tile based on the `ZoneMap` resource (spatial zone assignment). The client maps `zone_id` to temperature tint from a local lookup table for deep fog rendering ([D-059](#d-059-fog--shader-based-five-layers-knowledge-graph-driven) layer 3: ~10% zone temperature tint — bar=warm dark, hub=cool dark, corridor=neutral dark).
|
||||
- **Resolves:** OQ-09
|
||||
- **Rationale:** D-073 already mandates `zone_id` per tile in `ObserverSnapshot` for audio zone crossfade. With `zone_id` already on the wire for crossfade, zone temperature memory is essentially free — no additional protocol field needed, no additional server computation beyond the zone lookup. Client-only tracking was rejected because: (1) the server is the authoritative source of zone geometry, (2) client heuristics (remembering last-visited zone) would diverge from server truth at zone boundaries, and (3) the data is already crossing the wire for D-073.
|
||||
- **Implementation:**
|
||||
- `VisibleTile.zone_id: Option<u16>` — `None` for tiles outside any defined zone (corridors, transition spaces). Uses `#[serde(default, skip_serializing_if)]` for backwards compatibility with v10 clients.
|
||||
- `ZoneMap` resource (`simulation/zone.rs`): `BTreeMap<(i32, i32, i32), u16>` mapping tile coordinates to zone IDs. BTreeMap per [D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline) principle 4 (deterministic iteration). Populated by map builders at setup time.
|
||||
- Zone enrichment runs in `compute_observer_snapshot` — the observer pipeline's final assembly stage. `PerceptionQuery` trait remains zone-unaware (zone assignment is map data, not perception geometry).
|
||||
- Protocol version bumped to 11.
|
||||
- **Client contract:** Client maintains a `zone_id → { name, temperature_tint, ambient_layer }` lookup table. Deep fog shader (layer 3) reads `zone_id` from the last-seen `VisibleTile` data to apply the ~10% temperature tint. AudioManager reads `zone_id` to trigger crossfade between ambient layers ([D-073](architecture.md#d-073-zone-crossfade-approach--hard-boundary-soft-audio-transition)).
|
||||
- **Cross-reference:** Fog layers ([D-059](#d-059-fog--shader-based-five-layers-knowledge-graph-driven)), zone crossfade ([D-073](architecture.md#d-073-zone-crossfade-approach--hard-boundary-soft-audio-transition)), ObserverSnapshot ([D-020](architecture.md#d-020-engine-and-architecture-selection--godot-client--rust-simulation-via-subprocessipc)), deterministic simulation ([D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline))
|
||||
- **Raised by:** Tyre (architecture review, #523)
|
||||
- **Dissent:** None
|
||||
|
||||
---
|
||||
|
||||
*30 decisions. Last updated: 2026-02-19 (D-076: OQ-29 resolved — dialogue max-width 640px)*
|
||||
*31 decisions. Last updated: 2026-02-19 (D-077: OQ-09 resolved — zone temperature memory server-tracked)*
|
||||
|
||||
Reference in New Issue
Block a user