fix(simulation): Clippy cleanup and CI enforcement (#635)
Fix all Clippy warnings across the server codebase (2411 insertions, 1341 deletions). Raise type-complexity-threshold to 750 and too-many-arguments to 12 in .clippy.toml for idiomatic Bevy ECS system signatures. The server now passes `cargo clippy -- --deny warnings` cleanly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,17 +13,14 @@ use std::collections::BTreeMap;
|
||||
|
||||
use bevy_ecs::{schedule::Schedule, world::World};
|
||||
use settled_reach_server::{
|
||||
knowledge::{registry::EntityRegistry, types::StableId, StableEntityId},
|
||||
npc::ToleranceThreshold,
|
||||
simulation::triangle::{
|
||||
apply_resolve_triangle, tick_triangle_escalation, ResolveTriangleCommand,
|
||||
ResolveTriangleQueue, TemplateId, TriangleClassification, TriangleCrisisEventQueue,
|
||||
TriangleDef, TriangleId, TrianglePhase, TriangleState,
|
||||
},
|
||||
knowledge::{registry::EntityRegistry, types::StableId, StableEntityId},
|
||||
npc::ToleranceThreshold,
|
||||
simulation::{
|
||||
tier::ActiveSim,
|
||||
time::SimulationTime,
|
||||
},
|
||||
simulation::{tier::ActiveSim, time::SimulationTime},
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -43,9 +40,18 @@ fn make_escalation_world() -> World {
|
||||
fn spawn_npc_with_threshold(world: &mut World, stable_id_val: u64, threshold: i16) -> StableId {
|
||||
let sid = StableId(stable_id_val);
|
||||
let entity = world
|
||||
.spawn((ActiveSim, StableEntityId(sid), ToleranceThreshold { current_stress: 0, threshold }))
|
||||
.spawn((
|
||||
ActiveSim,
|
||||
StableEntityId(sid),
|
||||
ToleranceThreshold {
|
||||
current_stress: 0,
|
||||
threshold,
|
||||
},
|
||||
))
|
||||
.id();
|
||||
world.resource_mut::<EntityRegistry>().register_existing(entity, sid);
|
||||
world
|
||||
.resource_mut::<EntityRegistry>()
|
||||
.register_existing(entity, sid);
|
||||
sid
|
||||
}
|
||||
|
||||
@@ -190,7 +196,14 @@ fn d087_seed_dependent_escalation_timing() {
|
||||
assignments.insert(RoleId::new("r"), npc);
|
||||
|
||||
// Spawn as separate triangles.
|
||||
let slow = spawn_triangle(&mut world, 10, 0, 2, TrianglePhase::Simmering, assignments.clone());
|
||||
let slow = spawn_triangle(
|
||||
&mut world,
|
||||
10,
|
||||
0,
|
||||
2,
|
||||
TrianglePhase::Simmering,
|
||||
assignments.clone(),
|
||||
);
|
||||
let fast = spawn_triangle(&mut world, 20, 0, 8, TrianglePhase::Simmering, assignments);
|
||||
|
||||
let mut schedule = Schedule::default();
|
||||
@@ -202,8 +215,14 @@ fn d087_seed_dependent_escalation_timing() {
|
||||
}
|
||||
|
||||
// Both should be Active by 400 ticks.
|
||||
assert_eq!(world.get::<TriangleState>(slow).unwrap().phase, TrianglePhase::Active);
|
||||
assert_eq!(world.get::<TriangleState>(fast).unwrap().phase, TrianglePhase::Active);
|
||||
assert_eq!(
|
||||
world.get::<TriangleState>(slow).unwrap().phase,
|
||||
TrianglePhase::Active
|
||||
);
|
||||
assert_eq!(
|
||||
world.get::<TriangleState>(fast).unwrap().phase,
|
||||
TrianglePhase::Active
|
||||
);
|
||||
|
||||
// Fast triangle should have activated earlier (higher tension accumulated faster).
|
||||
let fast_tension = world.get::<TriangleState>(fast).unwrap().tension;
|
||||
@@ -220,7 +239,7 @@ fn crisis_event_trigger_npc_is_lowest_threshold() {
|
||||
let mut world = make_escalation_world();
|
||||
|
||||
let npc_high = spawn_npc_with_threshold(&mut world, 1, 50); // high tolerance
|
||||
let npc_low = spawn_npc_with_threshold(&mut world, 2, 10); // low tolerance — trigger
|
||||
let npc_low = spawn_npc_with_threshold(&mut world, 2, 10); // low tolerance — trigger
|
||||
|
||||
use settled_reach_server::simulation::triangle::RoleId;
|
||||
let mut assignments = BTreeMap::new();
|
||||
@@ -240,7 +259,10 @@ fn crisis_event_trigger_npc_is_lowest_threshold() {
|
||||
queue.events[0].trigger_npc, npc_low,
|
||||
"trigger NPC must be the one with the lowest threshold"
|
||||
);
|
||||
assert_eq!(queue.events[0].tick, 10, "crisis tick must match the game-minute");
|
||||
assert_eq!(
|
||||
queue.events[0].tick, 10,
|
||||
"crisis tick must match the game-minute"
|
||||
);
|
||||
}
|
||||
|
||||
/// No crisis event when tension hasn't exceeded the threshold.
|
||||
@@ -260,7 +282,10 @@ fn no_crisis_event_below_threshold() {
|
||||
run_at_tick(&mut world, &mut schedule, 10);
|
||||
|
||||
let queue = world.resource::<TriangleCrisisEventQueue>();
|
||||
assert!(queue.is_empty(), "no crisis event when tension (5) < threshold (100)");
|
||||
assert!(
|
||||
queue.is_empty(),
|
||||
"no crisis event when tension (5) < threshold (100)"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -281,28 +306,49 @@ fn active_triangle_continues_incrementing_no_new_event() {
|
||||
run_at_tick(&mut world, &mut schedule, 20);
|
||||
|
||||
let queue = world.resource::<TriangleCrisisEventQueue>();
|
||||
assert!(queue.is_empty(), "no crisis event for already-Active triangle");
|
||||
assert!(
|
||||
queue.is_empty(),
|
||||
"no crisis event for already-Active triangle"
|
||||
);
|
||||
}
|
||||
|
||||
/// Active triangle tension saturates at u8::MAX (255).
|
||||
#[test]
|
||||
fn active_triangle_tension_saturates_at_u8_max() {
|
||||
let mut world = make_escalation_world();
|
||||
spawn_triangle(&mut world, 1, 252, 10, TrianglePhase::Active, BTreeMap::new());
|
||||
spawn_triangle(
|
||||
&mut world,
|
||||
1,
|
||||
252,
|
||||
10,
|
||||
TrianglePhase::Active,
|
||||
BTreeMap::new(),
|
||||
);
|
||||
|
||||
let mut schedule = Schedule::default();
|
||||
schedule.add_systems(tick_triangle_escalation);
|
||||
run_at_tick(&mut world, &mut schedule, 10);
|
||||
|
||||
// First call: 252 + 10 = 262, saturates to 255
|
||||
let entity = world.query::<bevy_ecs::entity::Entity>().iter(&world).next().unwrap();
|
||||
let entity = world
|
||||
.query::<bevy_ecs::entity::Entity>()
|
||||
.iter(&world)
|
||||
.next()
|
||||
.unwrap();
|
||||
// Can't query TriangleState after mutable borrow; check via resource
|
||||
// (we verify by spawning directly and checking post-run)
|
||||
let _ = entity; // entity used to ensure spawn worked
|
||||
|
||||
// Re-run test cleanly
|
||||
let mut world2 = make_escalation_world();
|
||||
let e2 = spawn_triangle(&mut world2, 2, 254, 50, TrianglePhase::Active, BTreeMap::new());
|
||||
let e2 = spawn_triangle(
|
||||
&mut world2,
|
||||
2,
|
||||
254,
|
||||
50,
|
||||
TrianglePhase::Active,
|
||||
BTreeMap::new(),
|
||||
);
|
||||
let mut sched2 = Schedule::default();
|
||||
sched2.add_systems(tick_triangle_escalation);
|
||||
run_at_tick(&mut world2, &mut sched2, 10);
|
||||
@@ -349,7 +395,14 @@ fn d026_non_active_tier_triangle_not_escalated() {
|
||||
#[test]
|
||||
fn dormant_triangle_not_escalated() {
|
||||
let mut world = make_escalation_world();
|
||||
let entity = spawn_triangle(&mut world, 1, 0, 10, TrianglePhase::Dormant, BTreeMap::new());
|
||||
let entity = spawn_triangle(
|
||||
&mut world,
|
||||
1,
|
||||
0,
|
||||
10,
|
||||
TrianglePhase::Dormant,
|
||||
BTreeMap::new(),
|
||||
);
|
||||
|
||||
let mut schedule = Schedule::default();
|
||||
schedule.add_systems(tick_triangle_escalation);
|
||||
@@ -366,7 +419,14 @@ fn dormant_triangle_not_escalated() {
|
||||
#[test]
|
||||
fn resolved_triangle_not_escalated() {
|
||||
let mut world = make_escalation_world();
|
||||
let entity = spawn_triangle(&mut world, 1, 50, 5, TrianglePhase::Resolved, BTreeMap::new());
|
||||
let entity = spawn_triangle(
|
||||
&mut world,
|
||||
1,
|
||||
50,
|
||||
5,
|
||||
TrianglePhase::Resolved,
|
||||
BTreeMap::new(),
|
||||
);
|
||||
|
||||
let mut schedule = Schedule::default();
|
||||
schedule.add_systems(tick_triangle_escalation);
|
||||
@@ -401,14 +461,20 @@ fn resolve_command_sets_phase_to_resolved() {
|
||||
})
|
||||
.id();
|
||||
|
||||
world.resource_mut::<ResolveTriangleQueue>().push(ResolveTriangleCommand(TriangleId(100)));
|
||||
world
|
||||
.resource_mut::<ResolveTriangleQueue>()
|
||||
.push(ResolveTriangleCommand(TriangleId(100)));
|
||||
|
||||
let mut schedule = Schedule::default();
|
||||
schedule.add_systems(apply_resolve_triangle);
|
||||
schedule.run(&mut world);
|
||||
|
||||
let state = world.get::<TriangleState>(entity).unwrap();
|
||||
assert_eq!(state.phase, TrianglePhase::Resolved, "resolve command must set phase to Resolved");
|
||||
assert_eq!(
|
||||
state.phase,
|
||||
TrianglePhase::Resolved,
|
||||
"resolve command must set phase to Resolved"
|
||||
);
|
||||
assert_eq!(state.tension, 50, "tension must not change on resolve");
|
||||
}
|
||||
|
||||
@@ -455,7 +521,9 @@ fn d089_resolve_does_not_cascade() {
|
||||
.id();
|
||||
|
||||
// Resolve only triangle 100.
|
||||
world.resource_mut::<ResolveTriangleQueue>().push(ResolveTriangleCommand(TriangleId(100)));
|
||||
world
|
||||
.resource_mut::<ResolveTriangleQueue>()
|
||||
.push(ResolveTriangleCommand(TriangleId(100)));
|
||||
|
||||
let mut schedule = Schedule::default();
|
||||
schedule.add_systems(apply_resolve_triangle);
|
||||
@@ -498,9 +566,13 @@ fn resolve_twice_is_idempotent() {
|
||||
let mut schedule = Schedule::default();
|
||||
schedule.add_systems(apply_resolve_triangle);
|
||||
|
||||
world.resource_mut::<ResolveTriangleQueue>().push(ResolveTriangleCommand(TriangleId(100)));
|
||||
world
|
||||
.resource_mut::<ResolveTriangleQueue>()
|
||||
.push(ResolveTriangleCommand(TriangleId(100)));
|
||||
schedule.run(&mut world);
|
||||
world.resource_mut::<ResolveTriangleQueue>().push(ResolveTriangleCommand(TriangleId(100)));
|
||||
world
|
||||
.resource_mut::<ResolveTriangleQueue>()
|
||||
.push(ResolveTriangleCommand(TriangleId(100)));
|
||||
schedule.run(&mut world);
|
||||
|
||||
assert_eq!(
|
||||
@@ -526,7 +598,14 @@ fn crisis_events_accumulate_until_drained() {
|
||||
assignments.insert(RoleId::new("r"), npc);
|
||||
|
||||
// Two triangles that will both escalate.
|
||||
spawn_triangle(&mut world, 10, 0, 6, TrianglePhase::Simmering, assignments.clone());
|
||||
spawn_triangle(
|
||||
&mut world,
|
||||
10,
|
||||
0,
|
||||
6,
|
||||
TrianglePhase::Simmering,
|
||||
assignments.clone(),
|
||||
);
|
||||
spawn_triangle(&mut world, 20, 0, 6, TrianglePhase::Simmering, assignments);
|
||||
|
||||
let mut schedule = Schedule::default();
|
||||
@@ -578,16 +657,37 @@ fn d087_all_v01_conflict_types_produce_escalatable_states() {
|
||||
use settled_reach_server::simulation::triangle::{ConflictType, NpcAxis, RoleId};
|
||||
|
||||
let defs = [
|
||||
("kael-davan", "smuggler", "ring-contact", ConflictType::ResourceCompetition),
|
||||
("sera-venn", "detective", "commission-inspector", ConflictType::SecretExposure),
|
||||
(
|
||||
"kael-davan",
|
||||
"smuggler",
|
||||
"ring-contact",
|
||||
ConflictType::ResourceCompetition,
|
||||
),
|
||||
(
|
||||
"sera-venn",
|
||||
"detective",
|
||||
"commission-inspector",
|
||||
ConflictType::SecretExposure,
|
||||
),
|
||||
("naia", "kael-davan", "hael", ConflictType::LatentTension),
|
||||
("drin", "ring-system", "dock-supervisor", ConflictType::ResourceCompetition),
|
||||
("worried-partner", "ring-member", "neighbor", ConflictType::LatentTension),
|
||||
(
|
||||
"drin",
|
||||
"ring-system",
|
||||
"dock-supervisor",
|
||||
ConflictType::ResourceCompetition,
|
||||
),
|
||||
(
|
||||
"worried-partner",
|
||||
"ring-member",
|
||||
"neighbor",
|
||||
ConflictType::LatentTension,
|
||||
),
|
||||
];
|
||||
|
||||
for (r0, r1, r2, conflict) in &defs {
|
||||
let roles = [RoleId::new(r0), RoleId::new(r1), RoleId::new(r2)];
|
||||
let tid = settled_reach_server::simulation::triangle::TriangleId::from_seed_and_roles(42, &roles);
|
||||
let tid =
|
||||
settled_reach_server::simulation::triangle::TriangleId::from_seed_and_roles(42, &roles);
|
||||
let def = TriangleDef {
|
||||
triangle_id: tid,
|
||||
roles: roles.clone(),
|
||||
@@ -595,7 +695,11 @@ fn d087_all_v01_conflict_types_produce_escalatable_states() {
|
||||
interest_axes: [NpcAxis::Want, NpcAxis::Secret, NpcAxis::Relationships],
|
||||
relationship_constraints: vec![],
|
||||
};
|
||||
assert!(def.validate().is_ok(), "D-087 triangle must be valid: {:?}", def.validate());
|
||||
assert!(
|
||||
def.validate().is_ok(),
|
||||
"D-087 triangle must be valid: {:?}",
|
||||
def.validate()
|
||||
);
|
||||
|
||||
// Can construct a TriangleState from the def.
|
||||
let mut assignments = BTreeMap::new();
|
||||
|
||||
Reference in New Issue
Block a user