feat(simulation): add debug console server and LOS boundary wall margin

Debug and LOS tracks for Sprint 23 (#580, #584):

- DebugCommandKind enum with 10 variants (AdvanceTicks,
  SkipToContamination, TeleportToPosition, ForceContaminationActivate,
  InspectNpc, ListTriangles, ListPopulation, GetContaminationStatus,
  TeleportToLocation, ForceTriangleActivation)
- DebugResponsePayload on ObserverSnapshot, handle_debug_commands
  system gated by DebugEnabled resource
- PROTOCOL_VERSION bumped 17 → 18
- VisibilitySector::BoundaryWall variant — 1-tile wall margin beyond
  LOS boundary included in visible_tiles (not exploration/memory)
- compute_boundary_walls() pass in NaturalVision after FOV+cone

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-03 19:12:08 +01:00
co-authored by Claude Opus 4.6
parent 50f5d6c22e
commit c30197db0e
8 changed files with 666 additions and 1 deletions
+10
View File
@@ -2,6 +2,7 @@
// Timestamped player input events for deterministic simulation (D-010 principle 4)
// PlayerInput: semantic actions (MoveNorth, Interact, UsePerceptionMode, ToggleStance)
use crate::bridge::debug::DebugCommandBuffer;
use crate::bridge::types::{FacingDirection, ObjectType, PlayerAction, PlayerInput};
use crate::knowledge::{EntityRegistry, StableId};
use crate::perception::vision_cone::{facing_from_delta, Facing};
@@ -98,6 +99,7 @@ pub fn process_player_input(
reset_triggers: Query<&RoomResetTrigger>,
mut room_snapshots: Option<ResMut<RoomSnapshots>>,
mut save_load: Option<ResMut<SaveLoadPending>>,
mut debug_cmd_buffer: Option<ResMut<DebugCommandBuffer>>,
door_states: Query<&DoorState>,
object_types: Query<&ObjectType>,
) {
@@ -119,6 +121,7 @@ pub fn process_player_input(
| PlayerAction::TeleportToHub
| PlayerAction::SaveGame { .. }
| PlayerAction::LoadGame { .. }
| PlayerAction::DebugCommand(_)
)
{
continue;
@@ -364,6 +367,13 @@ pub fn process_player_input(
tracing::warn!("LoadGame received but SaveLoadPending resource not registered");
}
}
PlayerAction::DebugCommand(cmd) => {
if let Some(ref mut buf) = debug_cmd_buffer {
buf.push(cmd);
} else {
tracing::warn!("DebugCommand received but DebugCommandBuffer not registered");
}
}
}
}