refactor(simulation): apply rustfmt formatting

Formatting-only changes across server source and test files.
No logic changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-18 01:39:44 +01:00
co-authored by Claude Opus 4.6
parent 1da81a21ea
commit d5a1f6dadb
16 changed files with 169 additions and 105 deletions
+6 -6
View File
@@ -46,9 +46,9 @@ impl TcpBridge {
// Set non-blocking so receive_inputs doesn't stall the game loop.
// read_framed handles WouldBlock by returning Ok(None).
stream.set_nonblocking(true).map_err(|e| {
BridgeError::Transport(format!("failed to set non-blocking: {}", e))
})?;
stream
.set_nonblocking(true)
.map_err(|e| BridgeError::Transport(format!("failed to set non-blocking: {}", e)))?;
// Clone stream for reader and writer
let reader_stream = stream.try_clone().map_err(|e| {
@@ -81,9 +81,9 @@ impl TcpBridge {
local_addr
);
stream.set_nonblocking(true).map_err(|e| {
BridgeError::Transport(format!("failed to set non-blocking: {}", e))
})?;
stream
.set_nonblocking(true)
.map_err(|e| BridgeError::Transport(format!("failed to set non-blocking: {}", e)))?;
let reader_stream = stream.try_clone().map_err(|e| {
BridgeError::Transport(format!("failed to clone stream for reader: {}", e))
+5 -1
View File
@@ -87,7 +87,11 @@ const MAX_WALK_DEPTH: usize = 100;
/// Stops recursing at MAX_WALK_DEPTH to guard against symlink loops.
fn walk_yaml(dir: &Path, timestamps: &mut BTreeMap<PathBuf, SystemTime>, depth: usize) {
if depth >= MAX_WALK_DEPTH {
tracing::warn!("walk_yaml: max depth {} reached at {:?}, stopping", MAX_WALK_DEPTH, dir);
tracing::warn!(
"walk_yaml: max depth {} reached at {:?}, stopping",
MAX_WALK_DEPTH,
dir
);
return;
}
let Ok(entries) = std::fs::read_dir(dir) else {
+4 -3
View File
@@ -197,9 +197,10 @@ fn spawn_npc(world: &mut World, profile: &types::NpcProfile, result: &mut SpawnR
// Register in EntityRegistry for StableId mapping
let stable_id = world.resource_mut::<EntityRegistry>().register(entity);
world
.entity_mut(entity)
.insert((StableEntityId(stable_id), ContentSlug(profile.canonical_id.clone())));
world.entity_mut(entity).insert((
StableEntityId(stable_id),
ContentSlug(profile.canonical_id.clone()),
));
result
.npc_ids
+1 -5
View File
@@ -214,11 +214,7 @@ mod tests {
id_first, id_second,
"Re-registration must assign a new StableId"
);
assert_eq!(
id_second,
StableId(1),
"Counter advances monotonically"
);
assert_eq!(id_second, StableId(1), "Counter advances monotonically");
assert_eq!(registry.len(), 1);
// New mapping is bidirectionally correct
+3 -1
View File
@@ -162,7 +162,9 @@ fn setup_proof_room(app: &mut App) {
use settled_reach_server::simulation::monologue::{
MonologueBuffer, MonologueState, SprintAnomalyQueue,
};
use settled_reach_server::simulation::movement::{PlayerCharacter, TilePosition, WalkabilityMap};
use settled_reach_server::simulation::movement::{
PlayerCharacter, TilePosition, WalkabilityMap,
};
use settled_reach_server::simulation::path_follow::MovementSpeed;
use settled_reach_server::simulation::stance::{MovementProfile, PlayerMoveCooldown};
use settled_reach_server::simulation::time::DayPhase;
+2 -4
View File
@@ -26,10 +26,8 @@ impl Plugin for PerceptionPlugin {
.add_systems(
Update,
(
anomaly::clear_anomaly_markers
.before(anomaly::detect_anomalies),
anomaly::detect_anomalies
.before(observation::emit_observation_events),
anomaly::clear_anomaly_markers.before(anomaly::detect_anomalies),
anomaly::detect_anomalies.before(observation::emit_observation_events),
cognitive_delay::process_cognitive_delay
.after(observation::emit_observation_events)
.before(crate::knowledge::events::process_knowledge_events),
+1 -1
View File
@@ -15,9 +15,9 @@ use crate::knowledge::{EntityRegistry, KnowledgeGraph, StableId};
use crate::perception::cognitive_delay::CognitiveDelay;
use crate::perception::query::{ActivePerceptionMode, VisibilityGeometry};
use crate::perception::vision_cone::Facing;
use crate::simulation::dialogue::DialogueResponseBuffer;
use crate::simulation::interaction::NearbyInteractionBuffer;
use crate::simulation::inventory::{CarriedBy, InventorySlot, ItemName};
use crate::simulation::dialogue::DialogueResponseBuffer;
use crate::simulation::monologue::{MonologueBuffer, SprintAnomalyQueue};
use crate::simulation::movement::{PlayerCharacter, TilePosition, WalkabilityMap};
use crate::simulation::stance::Stance;
+5 -1
View File
@@ -1948,7 +1948,11 @@ fn equidistant_npcs_produce_stable_snapshot_ordering() {
.map(|e| e.entity_id)
.collect();
assert_eq!(npc_ids.len(), 3, "all three equidistant NPCs should be visible");
assert_eq!(
npc_ids.len(),
3,
"all three equidistant NPCs should be visible"
);
// Entity IDs must be in strictly ascending order (Fix B sort guarantee)
for i in 1..npc_ids.len() {
+42 -20
View File
@@ -19,7 +19,9 @@ use bevy_ecs::prelude::*;
use rand::Rng;
use crate::bridge::types::{DialogueResponseEvent, RelationshipState};
use crate::content::line_pool::{AccessTier, IndexedDialogueLine, Mood, Situation, Topic, TrustTier};
use crate::content::line_pool::{
AccessTier, IndexedDialogueLine, Mood, Situation, Topic, TrustTier,
};
use crate::content::LinePoolIndexResource;
use crate::knowledge::{EntityRegistry, KnowledgeGraph};
use crate::simulation::movement::PlayerCharacter;
@@ -219,7 +221,11 @@ pub fn derive_situations(
/// - Topic match: +2 per matching topic
///
/// Returns 0 only for lines on cooldown (caller handles).
pub fn score_line(line: &IndexedDialogueLine, npc_mood: Option<Mood>, active_topics: &[Topic]) -> u32 {
pub fn score_line(
line: &IndexedDialogueLine,
npc_mood: Option<Mood>,
active_topics: &[Topic],
) -> u32 {
let mut score: u32 = 1; // Base score — no line is excluded by Layer 4
// Mood match
@@ -318,8 +324,14 @@ pub fn process_talk_interaction(
return;
};
let Ok((player_entity, observer_kg, talk_request, mut response_buffer, mut cooldown, active_dialogue_opt)) =
player_query.single_mut()
let Ok((
player_entity,
observer_kg,
talk_request,
mut response_buffer,
mut cooldown,
active_dialogue_opt,
)) = player_query.single_mut()
else {
return;
};
@@ -784,9 +796,14 @@ mod tests {
let mut match_count = 0;
for seed in 0..100 {
let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(seed);
if let Some(line) =
select_dialogue_line(&candidates, Some(Mood::Worried), &[], &cooldown, 0, &mut rng)
{
if let Some(line) = select_dialogue_line(
&candidates,
Some(Mood::Worried),
&[],
&cooldown,
0,
&mut rng,
) {
if line.id == "matched" {
match_count += 1;
}
@@ -869,9 +886,10 @@ mod tests {
role: "dock-worker".to_string(),
lines,
};
index
.dialogue
.insert(("the-terminal".to_string(), "dock-worker".to_string()), pool);
index.dialogue.insert(
("the-terminal".to_string(), "dock-worker".to_string()),
pool,
);
index
}
@@ -1009,10 +1027,11 @@ mod tests {
let mut seen_ids: Vec<String> = Vec::new();
for seed in 0..20 {
// Reset for each iteration
world.get_mut::<DialogueResponseBuffer>(player).unwrap().response = None;
world
.entity_mut(player)
.insert(TalkRequest { target: npc });
.get_mut::<DialogueResponseBuffer>(player)
.unwrap()
.response = None;
world.entity_mut(player).insert(TalkRequest { target: npc });
world.insert_resource(SimRng::new(seed));
let mut schedule = bevy_ecs::schedule::Schedule::default();
@@ -1020,7 +1039,11 @@ mod tests {
schedule.run(&mut world);
world.flush();
if let Some(resp) = &world.get::<DialogueResponseBuffer>(player).unwrap().response {
if let Some(resp) = &world
.get::<DialogueResponseBuffer>(player)
.unwrap()
.response
{
if !seen_ids.contains(&resp.line_id) {
seen_ids.push(resp.line_id.clone());
}
@@ -1046,9 +1069,7 @@ mod tests {
world.insert_resource(LinePoolIndexResource(index));
// NPC without DialogueProfile
let npc = world
.spawn((Npc, TilePosition::new(5, 5, 0)))
.id();
let npc = world.spawn((Npc, TilePosition::new(5, 5, 0))).id();
world.resource_mut::<EntityRegistry>().register(npc);
let player = world
@@ -1142,10 +1163,11 @@ mod tests {
);
// Second talk — same tick, line on cooldown
world.get_mut::<DialogueResponseBuffer>(player).unwrap().response = None;
world
.entity_mut(player)
.insert(TalkRequest { target: npc });
.get_mut::<DialogueResponseBuffer>(player)
.unwrap()
.response = None;
world.entity_mut(player).insert(TalkRequest { target: npc });
let mut schedule2 = bevy_ecs::schedule::Schedule::default();
schedule2.add_systems(process_talk_interaction);
+16 -17
View File
@@ -102,12 +102,7 @@ pub fn process_player_input(
for input in inputs {
// Discard all gameplay actions while paused (D-052, R2-OQ-01).
// Only Pause/Unpause are processed — everything else is discarded.
if paused
&& !matches!(
input.action,
PlayerAction::Pause | PlayerAction::Unpause
)
{
if paused && !matches!(input.action, PlayerAction::Pause | PlayerAction::Unpause) {
continue;
}
match input.action {
@@ -190,14 +185,20 @@ pub fn process_player_input(
handle_place(&mut commands, &registry, &player_query, target_entity_id);
}
Some("Talk") => {
handle_talk(&mut commands, &registry, &player_query, &all_positions, target_entity_id);
handle_talk(
&mut commands,
&registry,
&player_query,
&all_positions,
target_entity_id,
);
}
_ => {
tracing::info!(
"Interact: target={:?}, verb={:?} — logged only",
target_entity_id,
verb,
);
"Interact: target={:?}, verb={:?} — logged only",
target_entity_id,
verb,
);
}
},
PlayerAction::WalkAway => {
@@ -363,7 +364,9 @@ fn handle_talk(
// Server-side range check: reject Talk if target is beyond close range
if let Ok(target_pos) = all_positions.get(target_entity) {
let distance = player_pos.manhattan_distance(target_pos).unwrap_or(u32::MAX);
let distance = player_pos
.manhattan_distance(target_pos)
.unwrap_or(u32::MAX);
if distance > crate::simulation::interaction::CLOSE_RANGE {
tracing::info!(
target_id,
@@ -1312,11 +1315,7 @@ mod tests {
);
let mut query = world.query::<&Stance>();
let stance = query.single(&world).unwrap();
assert_eq!(
stance.0,
MovementStance::Walk,
"Stance unchanged in batch"
);
assert_eq!(stance.0, MovementStance::Walk, "Stance unchanged in batch");
assert_eq!(
world.resource::<SimulationTime>().tick_rate,
TickRate::Paused,
+19 -17
View File
@@ -39,18 +39,12 @@ pub(crate) const ANOMALY_DELAY_TICKS: u64 = 90;
/// Fire DURING cognitive delay (when grey blob appears). Future: move to
/// content pools with trigger="observe_anomaly" + character match.
const RECOGNITION_LINES: &[(&str, &str)] = &[
(
"recognition_01",
"Wait \u{2014} I know that walk.",
),
("recognition_01", "Wait \u{2014} I know that walk."),
(
"recognition_02",
"Those footsteps... I've heard that pattern before.",
),
(
"recognition_03",
"Something about that silhouette...",
),
("recognition_03", "Something about that silhouette..."),
];
/// Hardcoded v0.1 sprint anomaly "double-take" lines.
@@ -258,9 +252,9 @@ pub fn trigger_recognition_monologue(
let pending = cognitive_delay.pending_mut();
let target_idx = {
// First pass: anomalous + unfired
let anomaly_idx = pending.iter().position(|p| {
!p.monologue_fired && anomaly_markers.get(p.target).is_ok()
});
let anomaly_idx = pending
.iter()
.position(|p| !p.monologue_fired && anomaly_markers.get(p.target).is_ok());
if let Some(idx) = anomaly_idx {
Some(idx)
} else {
@@ -872,10 +866,10 @@ mod tests {
// trigger_recognition_monologue tests (#451, D-060)
// -----------------------------------------------------------------------
use crate::knowledge::types::StableId;
use crate::perception::cognitive_delay::{
CognitiveDelay, PendingRecognition, RecognitionTrigger, NORMAL_DELAY_TICKS,
};
use crate::knowledge::types::StableId;
fn setup_recognition_world() -> World {
let mut world = World::new();
@@ -957,7 +951,12 @@ mod tests {
// First tick: fires
schedule.run(&mut world);
assert!(
world.query::<&MonologueBuffer>().single(&world).unwrap().event.is_some(),
world
.query::<&MonologueBuffer>()
.single(&world)
.unwrap()
.event
.is_some(),
"first tick should fire"
);
@@ -967,7 +966,12 @@ mod tests {
// Second tick: should NOT fire (monologue_fired = true)
schedule.run(&mut world);
assert!(
world.query::<&MonologueBuffer>().single(&world).unwrap().event.is_none(),
world
.query::<&MonologueBuffer>()
.single(&world)
.unwrap()
.event
.is_none(),
"second tick should not fire (already fired for this recognition)"
);
}
@@ -1053,9 +1057,7 @@ mod tests {
let mut world = setup_recognition_world();
let normal_target = world.spawn_empty().id();
let anomalous_target = world
.spawn(crate::perception::anomaly::AnomalyMarker)
.id();
let anomalous_target = world.spawn(crate::perception::anomaly::AnomalyMarker).id();
let mut cd = CognitiveDelay::default();
// Normal entity added first
+4 -2
View File
@@ -917,12 +917,14 @@ mod tests {
// Entity with lower bits processes first and claims the target
assert_eq!(
pos_lower, target,
pos_lower,
target,
"entity with lower Entity::to_bits() ({}) should win the tile",
lower.to_bits()
);
assert_eq!(
pos_higher, higher_origin,
pos_higher,
higher_origin,
"entity with higher Entity::to_bits() ({}) should stay at origin",
higher.to_bits()
);
+8 -2
View File
@@ -86,7 +86,10 @@ fn input_roundtrip_over_tcp() {
match bridge.receive_inputs() {
Ok(inputs) if !inputs.is_empty() => break inputs,
Ok(_) => {
assert!(std::time::Instant::now() < deadline, "timed out waiting for inputs");
assert!(
std::time::Instant::now() < deadline,
"timed out waiting for inputs"
);
thread::sleep(std::time::Duration::from_millis(1));
}
Err(e) => panic!("failed to receive inputs: {}", e),
@@ -150,7 +153,10 @@ fn tcp_bridge_eof_returns_error() {
match bridge.receive_inputs() {
Ok(inputs) if inputs.is_empty() => {
// WouldBlock — client hasn't disconnected yet, retry
assert!(std::time::Instant::now() < deadline, "timed out waiting for EOF");
assert!(
std::time::Instant::now() < deadline,
"timed out waiting for EOF"
);
thread::sleep(std::time::Duration::from_millis(1));
}
Ok(inputs) => panic!("expected Disconnected error, got {} inputs", inputs.len()),
+5 -7
View File
@@ -16,8 +16,8 @@ use settled_reach_server::knowledge::registry::EntityRegistry;
use settled_reach_server::knowledge::{KnowledgeGraph, KnowledgePlugin};
use settled_reach_server::npc::relationships::{RelationshipEdge, RelationshipGraph};
use settled_reach_server::npc::{
Contentment, DailyRoutine, Npc, NpcPlugin, RelationshipKind, RoutineEntry,
ToleranceThreshold, Want, WantKind,
Contentment, DailyRoutine, Npc, NpcPlugin, RelationshipKind, RoutineEntry, ToleranceThreshold,
Want, WantKind,
};
use settled_reach_server::perception::cognitive_delay::CognitiveDelay;
use settled_reach_server::perception::vision_cone::Facing;
@@ -213,10 +213,7 @@ fn build_deterministic_app(seed: u64) -> App {
/// Run the simulation for a fixed number of ticks with predetermined inputs.
/// Returns serialized snapshots for each tick.
fn run_simulation(
seed: u64,
inputs: &[Vec<PlayerInput>],
) -> Vec<Vec<u8>> {
fn run_simulation(seed: u64, inputs: &[Vec<PlayerInput>]) -> Vec<Vec<u8>> {
let mut app = build_deterministic_app(seed);
let mut snapshots = Vec::with_capacity(inputs.len());
@@ -334,7 +331,8 @@ fn gauntlet_deterministic_replay() {
for (tick, (s1, s2)) in run1.iter().zip(run2.iter()).enumerate() {
assert_eq!(
s1, s2,
s1,
s2,
"snapshot at tick {} differs between runs ({} vs {} bytes)",
tick,
s1.len(),
+4 -4
View File
@@ -279,11 +279,11 @@ fn generate_msgpack_fixtures() {
// Tests that GDScript can decode full ObserverSnapshot structs when the tick
// field crosses encoding format boundaries.
let boundary_snapshots: [(u64, &str); 5] = [
(0, "snapshot_boundary_tick_0"), // pos fixint
(127, "snapshot_boundary_tick_127"), // pos fixint max
(32767, "snapshot_boundary_tick_32767"), // int16/uint16 asymmetry
(0, "snapshot_boundary_tick_0"), // pos fixint
(127, "snapshot_boundary_tick_127"), // pos fixint max
(32767, "snapshot_boundary_tick_32767"), // int16/uint16 asymmetry
(2147483647, "snapshot_boundary_tick_2b31m1"), // int32/uint32 asymmetry
(4294967296, "snapshot_boundary_tick_2b32"), // int64 minimum
(4294967296, "snapshot_boundary_tick_2b32"), // int64 minimum
];
for (tick, name) in &boundary_snapshots {
+44 -14
View File
@@ -139,8 +139,9 @@ fn all_fixtures_deserialize() {
if name.starts_with("snapshot_boundary") {
// Boundary snapshot fixtures (#472): tick may exceed PROTOCOL_VERSION check
rmp_serde::from_slice::<ObserverSnapshot>(&bytes)
.unwrap_or_else(|e| panic!("deserialize boundary snapshot fixture {}: {}", name, e));
rmp_serde::from_slice::<ObserverSnapshot>(&bytes).unwrap_or_else(|e| {
panic!("deserialize boundary snapshot fixture {}: {}", name, e)
});
} else if name.starts_with("snapshot") {
let snap = rmp_serde::from_slice::<ObserverSnapshot>(&bytes)
.unwrap_or_else(|e| panic!("deserialize snapshot fixture {}: {}", name, e));
@@ -694,19 +695,48 @@ fn nearby_interaction_contradicted_roundtrip() {
/// int 32 (-32769 to -2^31), int 64 (-2^31-1 to -2^63).
const BOUNDARY_VALUES: [i64; 41] = [
// Positive boundaries (25 values)
0, 1, 126, 127, // pos fixint
128, 129, 254, 255, // uint 8
256, 257, 32766, 32767, // int 16 / uint 16 asymmetry
32768, 32769, 65534, 65535, // uint 16
65536, 65537, 2147483646, 2147483647, // int 32 / uint 32 asymmetry
2147483648, 4294967294, 4294967295, // uint 32
4294967296, i64::MAX, // int 64
0,
1,
126,
127, // pos fixint
128,
129,
254,
255, // uint 8
256,
257,
32766,
32767, // int 16 / uint 16 asymmetry
32768,
32769,
65534,
65535, // uint 16
65536,
65537,
2147483646,
2147483647, // int 32 / uint 32 asymmetry
2147483648,
4294967294,
4294967295, // uint 32
4294967296,
i64::MAX, // int 64
// Negative boundaries (16 values)
-1, -31, -32, // neg fixint
-33, -34, -127, -128, // int 8
-129, -130, -32767, -32768, // int 16
-32769, -2147483647, -2147483648, // int 32
-2147483649, i64::MIN, // int 64
-1,
-31,
-32, // neg fixint
-33,
-34,
-127,
-128, // int 8
-129,
-130,
-32767,
-32768, // int 16
-32769,
-2147483647,
-2147483648, // int 32
-2147483649,
i64::MIN, // int 64
];
#[test]