From 2fd16f08b0d6f22e4399260207c3919e56f0b8b6 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Thu, 12 Feb 2026 18:17:55 +0100 Subject: [PATCH] =?UTF-8?q?fix(server):=20address=20PR=20#14=20review=20?= =?UTF-8?q?=E2=80=94=20ordering,=20docs,=20version=20pin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix NpcPlugin system ordering: .before(compute_paths) instead of .after(advance_tick) so PathRequests are picked up same frame - Fix stale doc comment in interpretation.rs: system runs BEFORE knowledge events, not after - Add TODO(v0.2) on RelationshipGraph about information boundary limitation for multiplayer - Document cardinal-only movement as deliberate v0.1 choice - Add comment on manhattan_distance u32::MAX fallback for cross-z - Pin pathfinding crate to 4.11 Co-Authored-By: Claude Opus 4.6 --- server/Cargo.toml | 2 +- server/src/npc/mod.rs | 2 +- server/src/npc/relationships.rs | 6 ++++++ server/src/perception/interpretation.rs | 3 ++- server/src/simulation/pathfinding.rs | 4 ++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/server/Cargo.toml b/server/Cargo.toml index 5bf983a03..61e535a49 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -11,7 +11,7 @@ rmp-serde = "1" bincode = "1" rand = "0.9" rand_chacha = "0.9" -pathfinding = "4" +pathfinding = "4.11" thiserror = "2" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/server/src/npc/mod.rs b/server/src/npc/mod.rs index 27c3f532e..d4c4f3527 100644 --- a/server/src/npc/mod.rs +++ b/server/src/npc/mod.rs @@ -25,7 +25,7 @@ impl Plugin for NpcPlugin { .add_systems( Update, routine::check_phase_transition - .after(crate::simulation::time::advance_tick), + .before(crate::simulation::pathfinding::compute_paths), ); tracing::debug!("NpcPlugin initialized"); diff --git a/server/src/npc/relationships.rs b/server/src/npc/relationships.rs index 5be72258f..44334e48c 100644 --- a/server/src/npc/relationships.rs +++ b/server/src/npc/relationships.rs @@ -25,6 +25,12 @@ pub struct RelationshipEdge { /// Global relationship graph resource. /// BTreeMap<(subject, target), edge> for deterministic iteration (D-010). /// Directed graph: edge (A, B) represents how A feels about B. +/// +/// TODO(v0.2): This is a global omniscient resource — all entities share one +/// graph. This violates information boundaries (D-009/D-010) because any +/// system can read any relationship. For multiplayer, this needs per-observer +/// projection so each entity only sees relationships they should know about. +/// Acceptable for v0.1 single-player where the server is authoritative. #[derive(Resource, Debug, Clone, Default, Serialize, Deserialize)] pub struct RelationshipGraph { edges: BTreeMap<(StableId, StableId), RelationshipEdge>, diff --git a/server/src/perception/interpretation.rs b/server/src/perception/interpretation.rs index 8d2eb9c2a..d09ce6887 100644 --- a/server/src/perception/interpretation.rs +++ b/server/src/perception/interpretation.rs @@ -68,7 +68,8 @@ impl ObservationEventQueue { /// System: interpret visible snapshot against known routines and knowledge. /// -/// Runs after knowledge events are processed so the knowledge graph is up-to-date. +/// Runs BEFORE knowledge events are processed so it can detect new entities +/// by comparing visible NPCs against the previous tick's knowledge state. /// Produces observation events for: routine deviations, absences, new entities. pub fn generate_observation_events( time: Res, diff --git a/server/src/simulation/pathfinding.rs b/server/src/simulation/pathfinding.rs index b4e53d319..6a64ef11c 100644 --- a/server/src/simulation/pathfinding.rs +++ b/server/src/simulation/pathfinding.rs @@ -55,6 +55,8 @@ pub struct PathBlocked; /// System: compute paths for entities with PathRequest components. /// Uses A* over the WalkabilityMap with cardinal movement (4 neighbors). +/// Cardinal-only is a deliberate v0.1 simplification: diagonal movement +/// would require √2 cost handling and diagonal wall-clipping checks. /// Removes PathRequest and inserts ComputedPath or PathBlocked. pub fn compute_paths( mut commands: Commands, @@ -90,6 +92,8 @@ pub fn compute_paths( .filter(|neighbor| walkability.can_move_to(neighbor)) .map(|neighbor| (neighbor, 1u32)) }, + // manhattan_distance returns None for cross-z-level pairs; + // u32::MAX makes A* deprioritize those nodes (v0.1: single z-level) |pos| pos.manhattan_distance(&goal).unwrap_or(u32::MAX), |pos| *pos == goal, );