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:
2026-02-19 18:10:06 +01:00
co-authored by Claude Opus 4.6
parent c2de509c01
commit 51abc3e3c1
20 changed files with 213 additions and 6 deletions
+16 -1
View File
@@ -26,6 +26,7 @@ use crate::simulation::rng::SimRng;
use crate::simulation::sound::SoundEventQueue;
use crate::simulation::stance::Stance;
use crate::simulation::time::SimulationTime;
use crate::simulation::zone::ZoneMap;
/// Compute visibility geometry using the active perception mode.
/// Stage 1 of the observer pipeline: FOV + vision cone → VisibilityGeometry.
@@ -61,6 +62,7 @@ pub fn compute_observer_snapshot(
time: Res<SimulationTime>,
geometry: Res<VisibilityGeometry>,
registry: Res<EntityRegistry>,
zone_map: Option<Res<ZoneMap>>,
sound_queue: Option<Res<SoundEventQueue>>,
mut observer_query: Query<
(
@@ -221,6 +223,19 @@ pub fn compute_observer_snapshot(
// Sort entities by entity_id for deterministic snapshot ordering (#457)
entities.sort_by_key(|e| e.entity_id);
// Enrich tiles with zone_id from ZoneMap (D-077, D-073)
let visible_tiles = match zone_map.as_deref() {
Some(zm) => geometry
.visible_tiles
.iter()
.map(|t| VisibleTile {
zone_id: zm.zone_at(t.x, t.y, t.z),
..t.clone()
})
.collect(),
None => geometry.visible_tiles.clone(),
};
buffer.snapshot = Some(ObserverSnapshot {
version: crate::bridge::types::PROTOCOL_VERSION,
tick: time.tick,
@@ -229,7 +244,7 @@ pub fn compute_observer_snapshot(
player_stance: stance_opt.map(|s| s.0).unwrap_or_default(),
player_inventory,
entities,
visible_tiles: geometry.visible_tiles.clone(),
visible_tiles,
nearby_interactions,
current_monologue,
pending_recognitions,
+1
View File
@@ -83,6 +83,7 @@ impl PerceptionQuery for NaturalVision {
z,
visibility: sector,
tile_kind,
zone_id: None,
}
})
.collect();