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:
+124
-65
@@ -8,16 +8,14 @@
|
||||
|
||||
use bevy_ecs::prelude::*;
|
||||
|
||||
use crate::bridge::types::{
|
||||
DebugCommandKind, DebugEnabled, DebugResponsePayload, SnapshotBuffer,
|
||||
};
|
||||
use crate::simulation::triangle::TriangleState;
|
||||
use crate::bridge::types::{DebugCommandKind, DebugEnabled, DebugResponsePayload, SnapshotBuffer};
|
||||
use crate::knowledge::EntityRegistry;
|
||||
use crate::npc::Npc;
|
||||
use crate::simulation::conversation::NpcName;
|
||||
use crate::simulation::movement::{PlayerCharacter, TilePosition, WalkabilityMap};
|
||||
use crate::simulation::tier::ActiveSim;
|
||||
use crate::simulation::time::SimulationTime;
|
||||
use crate::simulation::triangle::TriangleState;
|
||||
use crate::storyteller::{ContaminationActive, ContaminationEventQueue, CONTAMINATION_DELAY_TICKS};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -67,10 +65,13 @@ pub fn handle_debug_commands(
|
||||
registry: Res<EntityRegistry>,
|
||||
mut player_query: Query<(Entity, &mut TilePosition), With<PlayerCharacter>>,
|
||||
triangles: Query<(Entity, &TriangleState), With<ActiveSim>>,
|
||||
npcs: Query<(Entity, &TilePosition, Option<&NpcName>), (With<Npc>, With<ActiveSim>, Without<PlayerCharacter>)>,
|
||||
npcs: Query<
|
||||
(Entity, &TilePosition, Option<&NpcName>),
|
||||
(With<Npc>, With<ActiveSim>, Without<PlayerCharacter>),
|
||||
>,
|
||||
) {
|
||||
// Gate: debug must be enabled
|
||||
let enabled = debug_enabled.as_ref().map_or(false, |d| d.0);
|
||||
let enabled = debug_enabled.as_ref().is_some_and(|d| d.0);
|
||||
let commands = cmd_buffer.drain();
|
||||
if commands.is_empty() {
|
||||
return;
|
||||
@@ -91,10 +92,7 @@ pub fn handle_debug_commands(
|
||||
time.tick = time.tick.saturating_add(n);
|
||||
DebugResponsePayload {
|
||||
command: format!("AdvanceTicks({})", n),
|
||||
text: format!(
|
||||
"Advanced {} ticks: {} -> {}",
|
||||
n, old_tick, time.tick
|
||||
),
|
||||
text: format!("Advanced {} ticks: {} -> {}", n, old_tick, time.tick),
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
@@ -145,7 +143,7 @@ pub fn handle_debug_commands(
|
||||
// Validate target is walkable (if WalkabilityMap available)
|
||||
let walkable = walkability
|
||||
.as_ref()
|
||||
.map_or(true, |wm| wm.can_move_to(&target));
|
||||
.is_none_or(|wm| wm.can_move_to(&target));
|
||||
if !walkable {
|
||||
DebugResponsePayload {
|
||||
command: format!("TeleportToPosition({}, {}, {})", x, y, z),
|
||||
@@ -181,42 +179,42 @@ pub fn handle_debug_commands(
|
||||
// center from tile_bounds). For now, report unimplemented.
|
||||
DebugResponsePayload {
|
||||
command: format!("TeleportToLocation({})", name),
|
||||
text: format!(
|
||||
"TeleportToLocation not yet implemented (needs location tile_bounds from ContentStore). Use TeleportToPosition instead."
|
||||
),
|
||||
text: "TeleportToLocation not yet implemented (needs location tile_bounds from ContentStore). Use TeleportToPosition instead.".to_string(),
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
DebugCommandKind::ForceContaminationActivate => {
|
||||
if contamination.is_none() {
|
||||
if let Some(ref mut cont) = contamination {
|
||||
if cont.0 {
|
||||
DebugResponsePayload {
|
||||
command: "ForceContaminationActivate".to_string(),
|
||||
text: "Contamination already active.".to_string(),
|
||||
success: true,
|
||||
}
|
||||
} else {
|
||||
cont.0 = true;
|
||||
// Also push an event so downstream systems react
|
||||
if let Some(ref mut queue) = contamination_queue {
|
||||
queue.push(crate::storyteller::ContaminationEvent {
|
||||
tick: time.tick,
|
||||
triangles_affected: 0, // no pressure delta applied — use SkipToContamination for that
|
||||
});
|
||||
}
|
||||
DebugResponsePayload {
|
||||
command: "ForceContaminationActivate".to_string(),
|
||||
text: format!(
|
||||
"Contamination force-activated at tick {}. Note: no tension delta applied (use SkipToContamination for full effect).",
|
||||
time.tick
|
||||
),
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DebugResponsePayload {
|
||||
command: "ForceContaminationActivate".to_string(),
|
||||
text: "Contamination system not available.".to_string(),
|
||||
success: false,
|
||||
}
|
||||
} else if contamination.as_ref().unwrap().0 {
|
||||
DebugResponsePayload {
|
||||
command: "ForceContaminationActivate".to_string(),
|
||||
text: "Contamination already active.".to_string(),
|
||||
success: true,
|
||||
}
|
||||
} else {
|
||||
contamination.as_mut().unwrap().0 = true;
|
||||
// Also push an event so downstream systems react
|
||||
if let Some(ref mut queue) = contamination_queue {
|
||||
queue.push(crate::storyteller::ContaminationEvent {
|
||||
tick: time.tick,
|
||||
triangles_affected: 0, // no pressure delta applied — use SkipToContamination for that
|
||||
});
|
||||
}
|
||||
DebugResponsePayload {
|
||||
command: "ForceContaminationActivate".to_string(),
|
||||
text: format!(
|
||||
"Contamination force-activated at tick {}. Note: no tension delta applied (use SkipToContamination for full effect).",
|
||||
time.tick
|
||||
),
|
||||
success: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
DebugCommandKind::ForceTriangleActivation(ref slug) => {
|
||||
@@ -244,7 +242,10 @@ pub fn handle_debug_commands(
|
||||
} else {
|
||||
DebugResponsePayload {
|
||||
command: format!("InspectNpc({})", wire_id),
|
||||
text: format!("Entity {} exists but is not an Active-tier NPC.", wire_id),
|
||||
text: format!(
|
||||
"Entity {} exists but is not an Active-tier NPC.",
|
||||
wire_id
|
||||
),
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
@@ -290,8 +291,12 @@ pub fn handle_debug_commands(
|
||||
lines.push(format!(
|
||||
" {} | sid={} | pos=({},{},{}) | {}",
|
||||
entity,
|
||||
stable.map(|s| s.0.to_string()).unwrap_or_else(|| "?".to_string()),
|
||||
pos.x, pos.y, pos.z,
|
||||
stable
|
||||
.map(|s| s.0.to_string())
|
||||
.unwrap_or_else(|| "?".to_string()),
|
||||
pos.x,
|
||||
pos.y,
|
||||
pos.z,
|
||||
name_str,
|
||||
));
|
||||
}
|
||||
@@ -366,12 +371,18 @@ mod tests {
|
||||
fn advance_ticks_updates_simulation_time() {
|
||||
let (mut world, mut schedule) = setup_debug_world();
|
||||
world.resource_mut::<SimulationTime>().tick = 100;
|
||||
world.resource_mut::<DebugCommandBuffer>().push(DebugCommandKind::AdvanceTicks(50));
|
||||
world
|
||||
.resource_mut::<DebugCommandBuffer>()
|
||||
.push(DebugCommandKind::AdvanceTicks(50));
|
||||
|
||||
schedule.run(&mut world);
|
||||
|
||||
assert_eq!(world.resource::<SimulationTime>().tick, 150);
|
||||
let resp = world.resource::<SnapshotBuffer>().pending_debug_response.as_ref().unwrap();
|
||||
let resp = world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
assert!(resp.success);
|
||||
assert!(resp.text.contains("150"));
|
||||
}
|
||||
@@ -380,21 +391,30 @@ mod tests {
|
||||
fn skip_to_contamination_sets_tick() {
|
||||
let (mut world, mut schedule) = setup_debug_world();
|
||||
world.resource_mut::<SimulationTime>().tick = 10;
|
||||
world.resource_mut::<DebugCommandBuffer>().push(DebugCommandKind::SkipToContamination);
|
||||
world
|
||||
.resource_mut::<DebugCommandBuffer>()
|
||||
.push(DebugCommandKind::SkipToContamination);
|
||||
|
||||
schedule.run(&mut world);
|
||||
|
||||
assert_eq!(world.resource::<SimulationTime>().tick, CONTAMINATION_DELAY_TICKS);
|
||||
let resp = world.resource::<SnapshotBuffer>().pending_debug_response.as_ref().unwrap();
|
||||
assert_eq!(
|
||||
world.resource::<SimulationTime>().tick,
|
||||
CONTAMINATION_DELAY_TICKS
|
||||
);
|
||||
let resp = world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
assert!(resp.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn teleport_moves_player() {
|
||||
let (mut world, mut schedule) = setup_debug_world();
|
||||
world.resource_mut::<DebugCommandBuffer>().push(
|
||||
DebugCommandKind::TeleportToPosition { x: 50, y: 60, z: 1 },
|
||||
);
|
||||
world
|
||||
.resource_mut::<DebugCommandBuffer>()
|
||||
.push(DebugCommandKind::TeleportToPosition { x: 50, y: 60, z: 1 });
|
||||
|
||||
schedule.run(&mut world);
|
||||
|
||||
@@ -402,7 +422,11 @@ mod tests {
|
||||
let pos = q.single(&world).unwrap();
|
||||
assert_eq!((pos.x, pos.y, pos.z), (50, 60, 1));
|
||||
|
||||
let resp = world.resource::<SnapshotBuffer>().pending_debug_response.as_ref().unwrap();
|
||||
let resp = world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
assert!(resp.success);
|
||||
}
|
||||
|
||||
@@ -411,12 +435,18 @@ mod tests {
|
||||
let (mut world, mut schedule) = setup_debug_world();
|
||||
assert!(!world.resource::<ContaminationActive>().0);
|
||||
|
||||
world.resource_mut::<DebugCommandBuffer>().push(DebugCommandKind::ForceContaminationActivate);
|
||||
world
|
||||
.resource_mut::<DebugCommandBuffer>()
|
||||
.push(DebugCommandKind::ForceContaminationActivate);
|
||||
schedule.run(&mut world);
|
||||
|
||||
assert!(world.resource::<ContaminationActive>().0);
|
||||
assert!(!world.resource::<ContaminationEventQueue>().is_empty());
|
||||
let resp = world.resource::<SnapshotBuffer>().pending_debug_response.as_ref().unwrap();
|
||||
let resp = world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
assert!(resp.success);
|
||||
}
|
||||
|
||||
@@ -424,11 +454,17 @@ mod tests {
|
||||
fn debug_disabled_rejects_commands() {
|
||||
let (mut world, mut schedule) = setup_debug_world();
|
||||
world.insert_resource(DebugEnabled(false));
|
||||
world.resource_mut::<DebugCommandBuffer>().push(DebugCommandKind::GetContaminationStatus);
|
||||
world
|
||||
.resource_mut::<DebugCommandBuffer>()
|
||||
.push(DebugCommandKind::GetContaminationStatus);
|
||||
|
||||
schedule.run(&mut world);
|
||||
|
||||
let resp = world.resource::<SnapshotBuffer>().pending_debug_response.as_ref().unwrap();
|
||||
let resp = world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
assert!(!resp.success);
|
||||
assert!(resp.text.contains("disabled"));
|
||||
}
|
||||
@@ -437,21 +473,30 @@ mod tests {
|
||||
fn get_contamination_status_reports_state() {
|
||||
let (mut world, mut schedule) = setup_debug_world();
|
||||
world.resource_mut::<SimulationTime>().tick = 42;
|
||||
world.resource_mut::<DebugCommandBuffer>().push(DebugCommandKind::GetContaminationStatus);
|
||||
world
|
||||
.resource_mut::<DebugCommandBuffer>()
|
||||
.push(DebugCommandKind::GetContaminationStatus);
|
||||
|
||||
schedule.run(&mut world);
|
||||
|
||||
let resp = world.resource::<SnapshotBuffer>().pending_debug_response.as_ref().unwrap();
|
||||
let resp = world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
assert!(resp.success);
|
||||
assert!(resp.text.contains("false")); // not yet active
|
||||
assert!(resp.text.contains("42")); // current tick
|
||||
assert!(resp.text.contains("42")); // current tick
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_commands_produces_no_response() {
|
||||
let (mut world, mut schedule) = setup_debug_world();
|
||||
schedule.run(&mut world);
|
||||
assert!(world.resource::<SnapshotBuffer>().pending_debug_response.is_none());
|
||||
assert!(world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -461,17 +506,25 @@ mod tests {
|
||||
map.set_walkable(&TilePosition::new(5, 5, 0), false);
|
||||
world.insert_resource(map);
|
||||
|
||||
world.resource_mut::<DebugCommandBuffer>().push(
|
||||
DebugCommandKind::TeleportToPosition { x: 5, y: 5, z: 0 },
|
||||
);
|
||||
world
|
||||
.resource_mut::<DebugCommandBuffer>()
|
||||
.push(DebugCommandKind::TeleportToPosition { x: 5, y: 5, z: 0 });
|
||||
schedule.run(&mut world);
|
||||
|
||||
// Player should NOT have moved
|
||||
let mut q = world.query_filtered::<&TilePosition, With<PlayerCharacter>>();
|
||||
let pos = q.single(&world).unwrap();
|
||||
assert_eq!((pos.x, pos.y, pos.z), (10, 20, 0), "player must not teleport to unwalkable tile");
|
||||
assert_eq!(
|
||||
(pos.x, pos.y, pos.z),
|
||||
(10, 20, 0),
|
||||
"player must not teleport to unwalkable tile"
|
||||
);
|
||||
|
||||
let resp = world.resource::<SnapshotBuffer>().pending_debug_response.as_ref().unwrap();
|
||||
let resp = world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
assert!(!resp.success);
|
||||
assert!(resp.text.contains("not walkable"));
|
||||
}
|
||||
@@ -482,7 +535,9 @@ mod tests {
|
||||
// Set tick past the delay but contamination not yet active
|
||||
world.resource_mut::<SimulationTime>().tick = CONTAMINATION_DELAY_TICKS + 100;
|
||||
|
||||
world.resource_mut::<DebugCommandBuffer>().push(DebugCommandKind::SkipToContamination);
|
||||
world
|
||||
.resource_mut::<DebugCommandBuffer>()
|
||||
.push(DebugCommandKind::SkipToContamination);
|
||||
schedule.run(&mut world);
|
||||
|
||||
// Tick should NOT have changed (no rewind)
|
||||
@@ -492,7 +547,11 @@ mod tests {
|
||||
"tick must not rewind"
|
||||
);
|
||||
|
||||
let resp = world.resource::<SnapshotBuffer>().pending_debug_response.as_ref().unwrap();
|
||||
let resp = world
|
||||
.resource::<SnapshotBuffer>()
|
||||
.pending_debug_response
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
assert!(!resp.success);
|
||||
assert!(resp.text.contains("already past"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user