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:
@@ -159,9 +159,12 @@ impl Plugin for BridgePlugin {
|
||||
.after(crate::simulation::movement::validate_movement),
|
||||
crate::simulation::interaction::compute_nearby_interactions
|
||||
.after(crate::simulation::movement::validate_movement),
|
||||
crate::simulation::monologue::trigger_monologue
|
||||
.after(crate::simulation::movement::validate_movement),
|
||||
crate::perception::observer::compute_observer_snapshot
|
||||
.after(crate::perception::observer::compute_visibility_geometry)
|
||||
.after(crate::simulation::interaction::compute_nearby_interactions)
|
||||
.after(crate::simulation::monologue::trigger_monologue)
|
||||
.before(crate::simulation::time::advance_tick),
|
||||
crate::perception::observation::emit_observation_events
|
||||
.after(crate::perception::observer::compute_observer_snapshot),
|
||||
|
||||
@@ -15,7 +15,7 @@ pub use crate::simulation::time::{DayPhase, TickRate};
|
||||
/// negotiation is unnecessary. Client should reject snapshots with version !=
|
||||
/// PROTOCOL_VERSION. New fields use #[serde(default)] only during the migration
|
||||
/// period, then the default is removed once both sides are updated.
|
||||
pub const PROTOCOL_VERSION: u8 = 4;
|
||||
pub const PROTOCOL_VERSION: u8 = 5;
|
||||
|
||||
/// The ONLY data structure crossing the client-server boundary (D-020)
|
||||
/// Contains all information visible to the observer at a given tick.
|
||||
@@ -23,8 +23,8 @@ pub const PROTOCOL_VERSION: u8 = 4;
|
||||
/// v2 adds: game_time, player_facing, visible_tiles, visibility sectors.
|
||||
/// v3 adds: relationship (D-033 entity color), observation (Visible/Remembered).
|
||||
/// v4 adds: nearby_interactions (D-060, #404 proximity + verbs[]).
|
||||
/// Future fields: ambient sound events, internal monologue triggers,
|
||||
/// HUD state (D-020 expansion).
|
||||
/// v5 adds: current_monologue (#414 internal monologue pipeline).
|
||||
/// Future fields: ambient sound events, HUD state (D-020 expansion).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ObserverSnapshot {
|
||||
/// Protocol version for forward compatibility. Current: 4.
|
||||
@@ -42,6 +42,10 @@ pub struct ObserverSnapshot {
|
||||
/// Entities within interaction range with available verbs (D-060, #404).
|
||||
/// Sorted by distance (nearest first). v0.1 client reads verbs[0] on the nearest entity.
|
||||
pub nearby_interactions: Vec<NearbyInteraction>,
|
||||
/// Internal monologue line to display this tick, if any (#414).
|
||||
/// None when no monologue is triggered. Client shows text and auto-fades.
|
||||
#[serde(default)]
|
||||
pub current_monologue: Option<MonologueEvent>,
|
||||
}
|
||||
|
||||
/// Game time data for client display (D-031)
|
||||
@@ -159,7 +163,12 @@ pub enum PlayerAction {
|
||||
MoveNorthwest,
|
||||
MoveSoutheast,
|
||||
MoveSouthwest,
|
||||
Interact,
|
||||
/// Player pressed E on a nearby entity. Carries target + verb from client.
|
||||
/// v0.1: logged only — full dialogue dispatch is future scope (#415).
|
||||
Interact {
|
||||
target_entity_id: Option<u64>,
|
||||
verb: Option<String>,
|
||||
},
|
||||
UsePerceptionMode(String),
|
||||
Pause,
|
||||
Unpause,
|
||||
@@ -204,6 +213,18 @@ pub enum VerbKind {
|
||||
Talk,
|
||||
}
|
||||
|
||||
/// Internal monologue event sent to the client for display (#414).
|
||||
/// Contains the text and display duration. Client auto-fades after duration.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MonologueEvent {
|
||||
/// Monologue line ID (for dedup and cooldown tracking)
|
||||
pub id: String,
|
||||
/// The monologue text to display
|
||||
pub text: String,
|
||||
/// Display duration in seconds before fade
|
||||
pub duration_seconds: f32,
|
||||
}
|
||||
|
||||
/// Snapshot buffer resource for staging outgoing ObserverSnapshots
|
||||
#[derive(Resource, Debug, Default)]
|
||||
pub struct SnapshotBuffer {
|
||||
|
||||
Reference in New Issue
Block a user