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>
- line_pool.rs: add trace! when active_situations is empty (Layer 2
will silently filter all lines — important for content debugging)
- knowledge_grant.rs: document serde(untagged) ambiguity hazard; add
KnowledgeGrant::validate() for load-time field validation
- monologue.rs: annotate trigger_monologue as schedule ordering anchor;
fix stale "periodic trigger cooldown tracking" doc reference in
trigger_event_monologue (COOLDOWN_TICKS removed in #655)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Per-player settings via rusqlite (bundled, zero runtime dep). Server
owns the settings DB; client sends ChangeSettings commands over IPC.
Extensible key-value with typed columns (String/Int/Float/Bool).
Protocol bumped to v20 with settings_response in ObserverSnapshot.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete the hand-authored YAML content pipeline (server/src/content/) superseded
by the v0.2 generator-first approach (D-122, D-128). Runtime ECS types that were
co-located with content loading have been extracted to dedicated simulation modules:
- simulation/triangle.rs: TriangleState, TriangleCrisisEventQueue, tick/resolve systems
- simulation/line_pool.rs: LinePoolIndex, AccessTier, TrustTier, Mood, LinePoolIndexResource
- simulation/knowledge_grant.rs: KnowledgeGrant, Prerequisites
Monologue systems (trigger_monologue, trigger_recognition_monologue,
trigger_event_monologue) now use hardcoded fallback lines only; the
ContentStoreResource branch and select_pool_line function are removed.
Deleted: content/{loader,types,line_pool,hot_reload,spawn,instantiation,entanglement,mod}.rs
Deleted: tests/{content_loading,content_runtime,content_scaling,template_instantiation,template_schema}.rs
Deleted: bin/line_preview.rs (v0.1 tool)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updated docstrings in sqlite_connector, qdrant_connector,
decisions_sync, schema.sql, and two doc comments in generator.rs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Ticker rotation: document sliding-window semantics (vs modulus-aligned)
- Ticker zone ID: add warning about Gauntlet vs production zone ID mismatch
- Proof-room movement profile: respect archetype instead of hardcoding smuggler
- Storyteller tie-break: use exact f32 equality (inputs are discrete integers)
- Observer: .map().flatten() → .and_then() (clippy strict)
- Content loader: remove dangling doc comment before section header
- Tests: replace assert!(false, ...) with TODO comments in ignored tests
- Tests: add frame limiter note on 302-update loop in tell expiry test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add character_archetype to StartupMessage with serde default (Detective)
- Bump PROTOCOL_VERSION to 19
- Add escalate_tells_on_activation() and expire_routine_deviations() systems
- RoutineDeviation inserted on triangle NPCs with 300-tick TTL
- Add TickerPool resource with deterministic SimRng rotation (200 ticks)
- Emit current_ticker in ObserverSnapshot when player is in bar zone
- Load ticker YAML from district content directories
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Storyteller chain for Sprint 23 (#570, #571, #572, #579):
- EngagementRecord component: per-NPC observation_time_ticks,
conversation_count, monologue_trigger_count — incremented by
perception, dialogue, and monologue systems
- MovementHistoryBuffer resource: ring buffer of player positions
over last 3000 ticks with npcs_copresent_in_window() query
- Lifecycle rules: single activation per session, no concurrency,
no cooldown, terminal resolution constants
- activation_pass() system: gate check, proximity query, engagement
scoring, unentangled-NPC routing, module selection, emits
TriangleActivatedEvent on 10-tick cadence after contamination
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Spatial chain for Sprint 23 (#576, #577, #578):
- TileKind enum (Floor/Wall/Void/Restricted) on WalkabilityMap with
set_tile_kind/tile_kind API, backward-compatible with existing
is_walkable/set_walkable
- Location YAML tile format: tiles as string arrays (F/W/V/R chars),
load_location_tiles() stamps tile data onto WalkabilityMap from
ContentStore on production startup
- Chunk streaming system: ChunkLoadRadius + ChunkStreamingCadence
resources, loads/unloads chunks around player position on cadence.
v0.1 radius covers full district (no streaming stutter)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Register StorytellerPlugin in main() and dump_schedule_graph() so
contamination system runs in production (critical, rounds 2+3)
- Add doc comment to z_bands_connected clarifying band indices vs
absolute z-levels (D-110)
- Add TODO on hardcoded modifications: vec![] in save_to_file
- Init ContaminationActive in minimal_world() test helper
- Replace ChaCha20Rng with SimRng in fuzzy_map tests (D-010)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three save/load bugs fixed:
- ContaminationActive not persisted in SaveStateV1 — caused double-fire
of contamination pressure on reload after tick 300.
- Loaded triangle entities missing ActiveSim marker — made them
invisible to escalation and contamination systems after any load.
- Existing triangle entities not despawned before load — created
duplicates, doubling tension escalation per tick.
Also: HashSet → BTreeSet for D-010 compliance, defensive event queue
reset on load, and three regression tests for triangle roundtrip.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
50-seed randomized testing against 4 structural invariants:
walkable connectivity (BFS), entity bounds, door adjacency,
and minimum tile count floor. Includes generator module for
test-scoped procedural map creation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New test_world room with two zones (Terminal/Corridor) separated by
a door. Adds ZoneCrossEventQueue resource and detect_zone_crossings
system to fire events when the player crosses zone boundaries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DLC entry point for future player construction system. Adds
Modification struct, ModificationType enum, and Modifications
component. Wired into SaveStateV1 with #[serde(default)] for
forward-compatible save format.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Follow-up to b6a9b78: register TerminalInteractedQueue resource and
door/terminal interaction systems in SimulationPlugin; add door state
save/load in save_io (open doors round-trip through SaveStateV1);
make WalkabilityMap param optional in process_door_interaction so
plugin-only tests work without a loaded map; fix information_boundaries
test missing open_doors field.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add DoorState component tracking is_open and blocking_tile; add
DoorInteractRequest per-player component consumed by new
process_door_interaction system (toggles walkability each use)
- Add TerminalInteracted event, TerminalInteractedQueue resource,
TerminalInteractRequest component, and process_terminal_interaction
system (emits event on Use verb)
- Add ExamineText(String) component for authored object examine text;
extend process_examine_interaction with object examine path:
uses ExamineText if present, falls back to generic string if absent
- Fix: add Without<ObjectType> filter to npc_query in
process_examine_interaction — previously any entity with TilePosition
was mis-routed through the NPC text generator
- Add SaveStateV1.open_doors: Vec<StableId> with #[serde(default)]
for backward-compatible serialization
- Add "Open"/"Close" → DoorInteractRequest and "Use" →
TerminalInteractRequest dispatch in process_player_input
- 10 integration tests in tests/environmental_interaction.rs covering
all acceptance criteria: door toggle (both directions), open-to-close,
invalid target, readable examine (with/without ExamineText), out-of-range,
terminal event emission, request cleanup, and save state round-trip
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Triangle phase and tension were silently lost on save/load. Now
serialized as triangle_states vec in SaveStateV1, sorted by
triangle_id for determinism (D-010). Dedicated triangle entities
are respawned on load.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Registers tick_triangle_escalation and apply_resolve_triangle systems
in SimulationPlugin. Adds TriangleCrisisEventWire to ObserverSnapshot
(protocol v16) for future client rendering of triangle crises (#250,
D-087). Observer emits empty vec by default; escalation system will
populate when triangles reach Active phase.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds TemplateOwnership to NpcSaveState and TemplateReferenceMap to
SaveStateV1 so cross-template links survive save/load and tier
eviction (D-025, D-026). Both fields use serde(default) for backward
compatibility with existing saves.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Protocol handshake (#555): HandshakeMessage as first IPC frame,
HandshakeState resource, forward-compatible input handling.
State serialization (#96): serialize_npc_to_frozen/deserialize with
full D-024 axis coverage (10 new optional fields on NpcSaveState).
Scope tags (#98): ScopeTagKind enum, ScopePinned marker, automatic
assignment from KnowledgeGraph and RelationshipGraph.
Timestamp eviction (#97): LastInteractionTick, SimSpacePressure,
BinaryHeap LRU eviction respecting ScopePinned entities.
Save/load (#553): save_to_file/load_from_file via MessagePack,
SaveGame/LoadGame IPC commands, SaveLoadResultWire on snapshot.
Test infrastructure (#200): Layer 3 integration test entry point,
three-layer architecture documented per D-030.
Information boundary tests (#272): 4 negative tests proving no
passive KG leakage, LOS fog holds, tier boundary holds, save
isolation per NPC.
1063 tests passing, 0 failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Background tier state machines (#95), NPC vision (#115), player-
awareness behavior (#244), skill system & combat flag (#91), social
propagation (#249), examine mechanic (#242), character pressure
framework (#248), save state data model (#256), tell state wiring
(#337). Protocol version bumped 13→14 for examine_result and
character_pressure snapshot fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- monologue.rs: tracing::warn on unrecognized trigger in fallback arm
- disclosure.rs: borrow-sequencing comment, first() simplification note
- trait_modifiers.rs: delegate parse_confidence to KnowledgeConfidence::try_from
- npc_knowledge_transfer.rs: fix misleading "draw randomly" comment,
document one-directional transfer behavior
- graph.rs: document intentional no-retrigger after contradiction
- dialogue.rs: explain entity grant guardrail asymmetry (D-079)
- knowledge/mod.rs: document one-tick monologue lag from system ordering
- poi_discovery.rs: document D-079 carve-out for direct KG write
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
tell_state reads KG for other-entity relationship state (MVP boundary
per D-082). Contradiction monologue fires with pre-resolved entity names,
shifts ToldBy source to PersonOfInterest. Full THE FRIEND arc event chain.
Implements D-082 step 1, D-083 event chain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
transfer_npc_knowledge system runs after conversations with trust-gated
fact exchange, confidence capping at KnowsOf, ToldBy source construction.
POI data model with PointOfInterest component and proximity-based discovery
via KnowledgeGranted events. Implements D-080. Closes Q-024.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tyre #1: Extract run_dialogue_pipeline() shared helper — eliminates ~60
lines of duplication between process_talk_interaction and
process_dialogue_response (L1-L4 pipeline).
Hoshe #1: process_dialogue_response now updates ActiveDialogue with
current tick on follow-up selection — prevents stale started_tick.
Tyre #4: process_dialogue_response now updates InteractionMemory on
follow-up — multi-turn conversations are visible in history.
Hoshe #6 / Tyre #6: handle_dialogue_response adds server-side range
check (CLOSE_RANGE), matching Talk/Confront pattern (D-010 info
boundary).
Hoshe #2: Weighted selection fallback replaced with unreachable!() —
score_line always returns >= 1, so the fallback was dead code.
Hoshe #3: assert!(false, ...) → panic!() in serialization.rs (clippy).
Hoshe #4: SetFacing and TeleportToHub added to roundtrip test.
Hoshe #5: setup_dialogue_response_world inlined (trivial pass-through).
Tyre #2: Doc comment on DialogueCooldownTracker explains per-player-global
design choice (line IDs are NPC-scoped per D-035, no collision risk).
Tyre #3: CONFRONTATION_LINES comment updated with TODO for D-028/D-035
migration.
Tyre #5: DialogueResponse fixture added for cross-language GDScript
testing (input_dialogue_response.msgpack).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move dialogue system registrations from BridgePlugin to NpcPlugin (#538):
game logic that depends on NPC-layer resources now registers where it
belongs. BridgePlugin retains only wire protocol concerns.
Implement DialogueResponse verb handler (#539): new process_dialogue_response
system runs the full D-028 four-layer pipeline to select follow-up lines
when the player picks a dialogue option. Clears ActiveDialogue when no
candidates remain. Fix latent schedule ambiguity — emit_observation_events
now has explicit .before(advance_tick) constraint.
Verify trust-gated gossip pipeline (#171): confirmed process_talk_interaction
correctly passes KnowledgeConfidence through relationship_to_trust() per
D-075. Added integration tests for Secret-tier access (Friendly+KnowsDetails)
and Surface-only fallback (Friendly+Suspects).
Wire DialogueCooldownTracker into selection (#338): added regression test
confirming no line_id repeats within the 600-tick cooldown window across
10 consecutive Talk interactions.
Closes#538, #539, #171, #338
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix protocol version comment (12 → 13) in ObserverSnapshot doc
- Widen Want intensity range from 3..=9 to 1..=10 to match spec and test
- Replace duplicated pool selection in trigger_recognition_monologue with
call to select_pool_line helper (~50 lines removed)
- Document NaiveSpatialIndex migration cost for grid/quadtree swap
- Remove misleading Default derive from TellCategory (Nervous is not a
sensible default for neutral NPCs)
- Add caller invariant doc on generate_npc (no TilePosition spawned)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Register all new systems in NpcPlugin and SimulationPlugin with correct
ordering constraints. Protocol bumped to v13: tell_state on VisibleEntity,
follow_state and PostConversationQueue on ObserverSnapshot, Follow verb
on VerbKind. Observer snapshot populates tell state from DerivedTellState
and follow state from FollowTarget. System ordering: tolerance after
mood, deviation after activity, tell after mood+deviation, follow after
visibility geometry, event monologue after conversations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add observe_npc, hear_sound, observe_anomaly, witness_interaction, and
post_conversation triggers to monologue system. trigger_event_monologue
system fires after sound collection, NPC conversations, and walk-away.
Context tags (location, situation, character_state) populated for D-035
content pool matching. COOLDOWN_TICKS=300 anti-spam guard respected.
witness_interaction fires after overheard NPC-to-NPC conversation per
D-078. Voice sounds and ambient sounds correctly excluded from
hear_sound trigger.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Follow verb on interaction dispatcher. FollowTarget component tracks
target entity, proximity ticks, and LOS-lost ticks. update_follow_state
system: observation events fire at double frequency while following,
NPC suspicion increases via stress when player within 2 tiles for 60+
ticks (configurable). Follow ends on LOS lost timeout, suspicion
threshold crossed, or player issues different action. FollowStateWire
emitted in ObserverSnapshot for client HUD.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Define SpatialIndex trait with entities_in_range, entities_at, and
update methods. NaiveSpatialIndex uses Vec backend with Manhattan
distance. sync_spatial_index system auto-updates from Changed<TilePosition>.
Registered as Bevy resource. Trait abstraction allows grid/quadtree
replacement later without touching callers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server-side infrastructure for information asymmetry in dialogue.
NPCs display role labels (Worker, Supervisor, Patron) instead of
real names until the player explicitly learns them via KG lookup.
NpcColorIndex (stable_id % 8) persists across name reveal.
ConversationEvent and DialogueResponseEvent carry display names +
color indices on the wire with serde(default) for compat.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keep all new variants from both branches: Greeting (copy), FirstMeeting
and RepeatedVisit (server). Combine Mood doc comments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Additional integration tests for conversation cooldown application, distance
termination with both NPCs receiving cooldown, and edge cases in the NPC-to-NPC
conversation pipeline.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
InteractionMemory component tracks interaction_count, last_interaction_tick,
and notable_events per NPC. Drives D-028 Layer 2 situation activation:
first_meeting (count==0) and repeated_visit (count>=3). warm_active in mood
system now derives from InteractionMemory within a 300-tick window.
Trust progression wired into dialogue systems: talk completion (+1),
walk-away (-1), confrontation (-2) emit TrustEvents consumed by update_trust.
InteractionEvent (WalkAway, Confrontation) recorded in notable_events for
fast per-pair access.
Adds FirstMeeting and RepeatedVisit Situation variants. 18 unit tests in
interaction.rs. All arithmetic integer-only (D-010 determinism). No HashMap.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements server-authoritative per-word occlusion for NPC conversations.
ConversationEventBuffer drains into ObserverSnapshot each tick so the client
receives only words audible from the player's position. Updates test fixtures
to include the new conversation_events and conversation_ended fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add 3 zone enrichment tests to observer pipeline (tile inside zone,
tile outside zone, absent ZoneMap resource). Fix misleading Decay
Observatory doc comment that claimed Direct start when test starts at
KnowsDetails. Add production population TBD note on ZoneMap.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server-tracked zone_id on VisibleTile for D-073 zone crossfade and
D-059 deep fog temperature tint. ZoneMap resource backed by BTreeMap,
observer enrichment in snapshot assembly. Backwards-compatible: v10
payloads deserialize with zone_id: None.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
validate_movement now inserts SoundEventEmitter with Footstep events on
every successful move. Intensity scales by stance: Sprint 0.8, Walk 0.5,
Careful 0.3, Crouch 0.15. Range is Close (3 tiles) for all stances.
This completes the sound event pipeline end-to-end: movement produces
events → collect_sound_events drains to queue → observer snapshot
includes audible events → client bridge receives them.
Addresses Tyre critical review item #1 on PR #42.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Sound producers: document empty v0.1 pipeline explicitly (critical)
2. Routine tests: add ActiveSim to 3 tests that passed trivially
3. Rename _observer_pos → observer_pos (used at line 191)
4. Add FactionOnly positive test case (matching faction_id)
5. Fix stale doc comment "Current: 9" → 10 in ObserverSnapshot
6. Remove orphaned SimulationTier/LastInteraction/ScopeTag types
7. Add tracing::warn on FactionOnly non-numeric parse failure
8. Document Medium-range occlusion gap as TODO in audible_at
9. Insert SoundEventQueue in observer test setup_world
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>