fix(simulation): address PR #46 review — zone tests, doc accuracy, TBD comment
Add 3 zone enrichment tests to observer pipeline (tile inside zone, tile outside zone, absent ZoneMap resource). Fix misleading Decay Observatory doc comment that claimed Direct start when test starts at KnowsDetails. Add production population TBD note on ZoneMap. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2466,3 +2466,116 @@ fn blocked_entities_sorted_ascending() {
|
||||
assert!(snapshot.blocked_entities.contains(&npc_b_sid.0));
|
||||
assert!(snapshot.blocked_entities.contains(&npc_c_sid.0));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Zone enrichment tests (#523, D-077)
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn zone_map_enriches_visible_tiles_with_zone_id() {
|
||||
// Tile inside a zone should get zone_id = Some(zone_id)
|
||||
use crate::simulation::zone::ZoneMap;
|
||||
|
||||
let mut world = setup_world(32, 32);
|
||||
let mut zone_map = ZoneMap::default();
|
||||
// Zone 42 covers (14..18, 14..18) — includes the observer's tile at (16,16)
|
||||
zone_map.set_rect(14, 14, 4, 4, 0, 42);
|
||||
world.insert_resource(zone_map);
|
||||
|
||||
world.spawn((
|
||||
PlayerCharacter,
|
||||
TilePosition::new(16, 16, 0),
|
||||
Facing::default(),
|
||||
KnowledgeGraph::new(),
|
||||
NearbyInteractionBuffer::default(),
|
||||
MonologueBuffer::default(),
|
||||
));
|
||||
|
||||
run_observer_pipeline(&mut world);
|
||||
|
||||
let buffer = world.resource::<SnapshotBuffer>();
|
||||
let snapshot = buffer.snapshot.as_ref().unwrap();
|
||||
|
||||
// Observer's tile (16, 16) is inside zone 42
|
||||
let observer_tile = snapshot
|
||||
.visible_tiles
|
||||
.iter()
|
||||
.find(|t| t.x == 16 && t.y == 16 && t.z == 0)
|
||||
.expect("observer tile should be visible");
|
||||
assert_eq!(
|
||||
observer_tile.zone_id,
|
||||
Some(42),
|
||||
"tile inside zone should have zone_id"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zone_map_tiles_outside_zone_get_none() {
|
||||
// Tile outside any zone should get zone_id = None
|
||||
use crate::simulation::zone::ZoneMap;
|
||||
|
||||
let mut world = setup_world(32, 32);
|
||||
let mut zone_map = ZoneMap::default();
|
||||
// Zone only covers (0..2, 0..2) — far from observer at (16,16)
|
||||
zone_map.set_rect(0, 0, 2, 2, 0, 7);
|
||||
world.insert_resource(zone_map);
|
||||
|
||||
world.spawn((
|
||||
PlayerCharacter,
|
||||
TilePosition::new(16, 16, 0),
|
||||
Facing::default(),
|
||||
KnowledgeGraph::new(),
|
||||
NearbyInteractionBuffer::default(),
|
||||
MonologueBuffer::default(),
|
||||
));
|
||||
|
||||
run_observer_pipeline(&mut world);
|
||||
|
||||
let buffer = world.resource::<SnapshotBuffer>();
|
||||
let snapshot = buffer.snapshot.as_ref().unwrap();
|
||||
|
||||
// Observer's tile (16, 16) is outside any zone
|
||||
let observer_tile = snapshot
|
||||
.visible_tiles
|
||||
.iter()
|
||||
.find(|t| t.x == 16 && t.y == 16 && t.z == 0)
|
||||
.expect("observer tile should be visible");
|
||||
assert_eq!(
|
||||
observer_tile.zone_id, None,
|
||||
"tile outside any zone should have zone_id = None"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_zone_map_resource_tiles_have_no_zone_id() {
|
||||
// When ZoneMap resource is absent, all tiles should have zone_id = None
|
||||
let mut world = setup_world(32, 32);
|
||||
// Do NOT insert ZoneMap resource
|
||||
|
||||
world.spawn((
|
||||
PlayerCharacter,
|
||||
TilePosition::new(16, 16, 0),
|
||||
Facing::default(),
|
||||
KnowledgeGraph::new(),
|
||||
NearbyInteractionBuffer::default(),
|
||||
MonologueBuffer::default(),
|
||||
));
|
||||
|
||||
run_observer_pipeline(&mut world);
|
||||
|
||||
let buffer = world.resource::<SnapshotBuffer>();
|
||||
let snapshot = buffer.snapshot.as_ref().unwrap();
|
||||
|
||||
assert!(
|
||||
!snapshot.visible_tiles.is_empty(),
|
||||
"should have visible tiles"
|
||||
);
|
||||
// All tiles should have zone_id = None when no ZoneMap exists
|
||||
for tile in &snapshot.visible_tiles {
|
||||
assert_eq!(
|
||||
tile.zone_id, None,
|
||||
"tile ({},{}) should have zone_id = None without ZoneMap resource",
|
||||
tile.x, tile.y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ use bevy_ecs::prelude::*;
|
||||
///
|
||||
/// Zone IDs are opaque u16 values — the client maintains its own
|
||||
/// `zone_id → zone_name / temperature_tint / ambient_layer` mapping.
|
||||
///
|
||||
/// Production population path is TBD — currently populated only by
|
||||
/// Gauntlet room builders via `set_rect` / `set`.
|
||||
#[derive(Resource, Debug, Default)]
|
||||
pub struct ZoneMap {
|
||||
zones: BTreeMap<(i32, i32, i32), u16>,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
//! Decay Observatory — Room 13 (24x14)
|
||||
//!
|
||||
//! Tests D-041 (knowledge graph decay). Observer starts with Direct confidence
|
||||
//! on an NPC in LOS, then LOS is broken. Tick advances verify confidence
|
||||
//! degrades: Direct → KnowsDetails → KnowsOf → Suspects → Stale (D-041).
|
||||
//! Tests D-041 (knowledge graph decay). Observer sees an NPC (Direct), then
|
||||
//! LOS is broken (drops to KnowsDetails). Tick advances verify confidence
|
||||
//! degrades: KnowsDetails → KnowsOf → Suspects (floor). Separate test
|
||||
//! confirms Stale state triggers when age exceeds stale_after threshold.
|
||||
//!
|
||||
//! Decay runs once per game-minute (every 10 ticks, D-031). Confidence floor
|
||||
//! is Suspects — decay never removes an entity from the knowledge graph.
|
||||
|
||||
Reference in New Issue
Block a user