feat(simulation): add YAML content loader with hot-reload (#326)
LinePool system parses dialogue.yaml and monologue.yaml into indexed BTreeMap structures. Supports 4-layer query filtering (access > situation > trust > topic+mood) per D-028. Hot-reload via timestamp polling every 20 ticks (dev-only). Graceful failure preserves previous content on reload error. 30+ tests covering enum parsing, index building, query filtering, monologue fallback, and content watching. Ref: D-028, D-032, D-035, D-041 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -45,7 +45,10 @@ fn discover_real_content_structure() {
|
||||
assert!(!manifest.campaigns.is_empty());
|
||||
|
||||
// At least one district should be discovered
|
||||
assert!(!store.districts.is_empty(), "should discover at least one district");
|
||||
assert!(
|
||||
!store.districts.is_empty(),
|
||||
"should discover at least one district"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -298,6 +301,7 @@ fn content_plugin_loads_via_app() {
|
||||
app.add_plugins(settled_reach_server::npc::NpcPlugin);
|
||||
app.insert_resource(ContentConfig {
|
||||
content_root: root,
|
||||
..Default::default()
|
||||
});
|
||||
app.add_plugins(ContentPlugin);
|
||||
|
||||
@@ -353,13 +357,18 @@ fn spawn_real_content_with_relationships_and_secrets() {
|
||||
);
|
||||
npcs_with_want += 1;
|
||||
}
|
||||
assert_eq!(npcs_with_want, 20, "All 20 NPCs should have Want components");
|
||||
assert_eq!(
|
||||
npcs_with_want, 20,
|
||||
"All 20 NPCs should have Want components"
|
||||
);
|
||||
|
||||
// Spot-check specific Want values
|
||||
let kael_entity = registry
|
||||
.to_entity(&result.npc_ids["npc:kael-davan"])
|
||||
.unwrap();
|
||||
let kael_want = world.get::<npc::Want>(kael_entity).expect("Kael should have Want");
|
||||
let kael_want = world
|
||||
.get::<npc::Want>(kael_entity)
|
||||
.expect("Kael should have Want");
|
||||
assert_eq!(kael_want.primary, npc::WantKind::Safety);
|
||||
|
||||
// Verify Kael has a Secret component
|
||||
@@ -383,9 +392,11 @@ fn spawn_real_content_with_relationships_and_secrets() {
|
||||
let kael_kg = world
|
||||
.get::<settled_reach_server::knowledge::graph::KnowledgeGraph>(kael_entity)
|
||||
.expect("Kael should have KnowledgeGraph");
|
||||
assert!(kael_kg.knows_fact(&settled_reach_server::knowledge::types::FactId(
|
||||
"contraband.ring_exists".to_string()
|
||||
)));
|
||||
assert!(
|
||||
kael_kg.knows_fact(&settled_reach_server::knowledge::types::FactId(
|
||||
"contraband.ring_exists".to_string()
|
||||
))
|
||||
);
|
||||
|
||||
// Verify global RelationshipGraph was populated
|
||||
let graph = world.resource::<settled_reach_server::npc::relationships::RelationshipGraph>();
|
||||
@@ -400,6 +411,8 @@ fn spawn_real_content_with_relationships_and_secrets() {
|
||||
.resource::<EntityRegistry>()
|
||||
.to_entity(&result.npc_ids["npc:nils-davan"])
|
||||
.unwrap();
|
||||
let nils_want = world.get::<npc::Want>(nils_entity).expect("Nils should have Want");
|
||||
let nils_want = world
|
||||
.get::<npc::Want>(nils_entity)
|
||||
.expect("Nils should have Want");
|
||||
assert_eq!(nils_want.primary, npc::WantKind::Power);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user