feat(simulation): complete interaction and monologue pipelines (#413, #414, #415)

Three fixes to make the gameplay loop functional end-to-end:

- Add Interactable component to NPC spawn so E-prompt detection works
- Build monologue trigger system (enter_location + time_idle) with
  MonologueBuffer/MonologueState components, wire through ObserverSnapshot
  as current_monologue field, decode on client and display via HUD
- Change PlayerAction::Interact from unit to struct variant carrying
  optional target_entity_id and verb fields

Bumps protocol version from 4 to 5. Regenerates MessagePack fixtures.
All 200 tests pass (170 unit + 30 integration).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 19:23:47 +01:00
co-authored by Claude Opus 4.6
parent 8228ef3c1c
commit 3c106aa2d0
27 changed files with 480 additions and 30 deletions
+5
View File
@@ -238,6 +238,7 @@ mod tests {
Facing(FacingDirection::North),
KnowledgeGraph::new(),
crate::simulation::interaction::NearbyInteractionBuffer::default(),
crate::simulation::monologue::MonologueBuffer::default(),
))
.id();
registry.register(player);
@@ -289,6 +290,7 @@ mod tests {
Facing(FacingDirection::North),
KnowledgeGraph::new(),
crate::simulation::interaction::NearbyInteractionBuffer::default(),
crate::simulation::monologue::MonologueBuffer::default(),
))
.id();
registry.register(player);
@@ -360,6 +362,7 @@ mod tests {
Facing(FacingDirection::North),
kg,
crate::simulation::interaction::NearbyInteractionBuffer::default(),
crate::simulation::monologue::MonologueBuffer::default(),
))
.id();
registry.register(player);
@@ -393,6 +396,7 @@ mod tests {
Facing(FacingDirection::North),
KnowledgeGraph::new(), // Empty — never seen anyone
crate::simulation::interaction::NearbyInteractionBuffer::default(),
crate::simulation::monologue::MonologueBuffer::default(),
))
.id();
registry.register(player);
@@ -440,6 +444,7 @@ mod tests {
Facing(FacingDirection::North),
kg,
crate::simulation::interaction::NearbyInteractionBuffer::default(),
crate::simulation::monologue::MonologueBuffer::default(),
))
.id();
registry.register(player);