Merge remote-tracking branch 'origin/ci'

# Conflicts:
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_0.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_127.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_2b31m1.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_2b32.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_32767.msgpack
#	client/tests/fixtures/msgpack/snapshot_empty.msgpack
#	client/tests/fixtures/msgpack/snapshot_multi_entity.msgpack
#	client/tests/fixtures/msgpack/snapshot_one_npc.msgpack
#	client/tests/fixtures/msgpack/snapshot_player.msgpack
#	client/tests/fixtures/msgpack/snapshot_v2_full.msgpack
#	server/Cargo.toml
#	server/src/bridge/text_renderer.rs
#	server/src/bridge/types.rs
#	server/src/perception/observer/mod.rs
#	server/src/simulation/path_follow.rs
#	server/tests/bridge_ipc.rs
#	server/tests/bridge_tcp.rs
#	server/tests/gen_fixtures.rs
#	server/tests/serialization.rs
This commit is contained in:
2026-02-19 15:35:56 +01:00
38 changed files with 307 additions and 50 deletions
+1
View File
@@ -40,6 +40,7 @@ pub fn clear_anomaly_markers(mut commands: Commands, markers: Query<Entity, With
/// OR KG.state == Contradicted. Skips the player entity.
///
/// System ordering: after clear_anomaly_markers, before emit_observation_events.
#[tracing::instrument(level = "debug", skip_all)]
pub fn detect_anomalies(
mut commands: Commands,
observer_query: Query<(Entity, &KnowledgeGraph), With<PlayerCharacter>>,
+1
View File
@@ -148,6 +148,7 @@ impl CognitiveDelay {
/// Expired recognitions are converted to DirectObservation KnowledgeEvents.
///
/// System ordering: after emit_observation_events, before process_knowledge_events.
#[tracing::instrument(level = "debug", skip_all)]
pub fn process_cognitive_delay(
time: Res<SimulationTime>,
mut query: Query<(Entity, &mut CognitiveDelay)>,
+4
View File
@@ -3,6 +3,10 @@
//! Interprets what the observer sees (and doesn't see) against known NPC
//! routines and knowledge graph state. Produces high-level observation events
//! that drive monologue and investigation triggers.
//!
//! Note: HashSet is used as a per-frame lookup table (visible tiles/NPCs).
//! Only membership checks — iteration order is irrelevant. Not simulation state.
#![allow(clippy::disallowed_types)]
use bevy_ecs::prelude::*;
+6 -1
View File
@@ -22,6 +22,7 @@ use crate::simulation::interaction::NearbyInteractionBuffer;
use crate::simulation::inventory::{CarriedBy, InventorySlot, ItemName};
use crate::simulation::monologue::{MonologueBuffer, SprintAnomalyQueue};
use crate::simulation::movement::{PlayerCharacter, TilePosition, WalkabilityMap};
use crate::simulation::rng::SimRng;
use crate::simulation::sound::SoundEventQueue;
use crate::simulation::stance::Stance;
use crate::simulation::time::SimulationTime;
@@ -30,6 +31,7 @@ use crate::simulation::time::SimulationTime;
/// Stage 1 of the observer pipeline: FOV + vision cone → VisibilityGeometry.
///
/// System ordering: after validate_movement, before compute_observer_snapshot.
#[tracing::instrument(level = "debug", skip_all)]
pub fn compute_visibility_geometry(
walkability: Res<WalkabilityMap>,
mode: Res<ActivePerceptionMode>,
@@ -53,7 +55,8 @@ pub fn compute_visibility_geometry(
///
/// System ordering: after compute_visibility_geometry + compute_nearby_interactions,
/// before advance_tick.
#[allow(clippy::type_complexity)]
#[tracing::instrument(level = "debug", skip_all)]
#[allow(clippy::type_complexity, clippy::too_many_arguments)]
pub fn compute_observer_snapshot(
time: Res<SimulationTime>,
geometry: Res<VisibilityGeometry>,
@@ -85,6 +88,7 @@ pub fn compute_observer_snapshot(
)>,
inventory_items: Query<(Entity, &CarriedBy, &ItemName, &InventorySlot)>,
mut buffer: ResMut<SnapshotBuffer>,
sim_rng: Option<Res<SimRng>>,
) {
let Ok((
observer_entity,
@@ -233,6 +237,7 @@ pub fn compute_observer_snapshot(
blocked_entities,
scan_events,
sound_events,
rng_seed: sim_rng.as_deref().map(|r| r.seed()),
});
}
+5
View File
@@ -4,6 +4,11 @@
//! (natural vision, thermal, EM, etc.) implements PerceptionQuery to
//! provide mode-specific FOV and visibility sector computation.
//! v0.1 implements only NaturalVision.
//!
//! Note: HashMap is used for `sector_lookup` — a per-frame scratch buffer
//! looked up only by key. Iteration order is irrelevant here. Not subject to
//! the simulation determinism constraint (see server/.clippy.toml).
#![allow(clippy::disallowed_types)]
use std::collections::{BTreeSet, HashMap};
+6
View File
@@ -9,6 +9,12 @@
//! References:
//! - Symmetric: https://www.albertford.com/shadowcasting/
//! - Traditional: RogueBasin recursive shadowcasting
//!
//! Note: HashSet is used here as a per-frame scratch accumulator for visible
//! tile positions during the FOV sweep. Only `insert` and `contains` are used;
//! iteration order never affects the output (results are handed to BTreeSet in
//! query.rs). Not simulation state — exempt from the determinism constraint.
#![allow(clippy::disallowed_types)]
use std::collections::HashSet;