Replaces the hardcoded seed=0 with the seed received in StartupMessage,
threading it through SimulationPlugin -> EconomyPlugin / SimRng. Integration
test fixtures updated for the new SimulationPlugin { seed } signature.
- Widen EventPort tick methods from u32 to u64 (prevents overflow)
- Add is_identity() guard on hot-path String allocation in modifiers
- Replace Vec::remove(0) with VecDeque::pop_front() in price history
- Add .after(tick_economy_simulation) ordering for debug commands
- Fix stale PROTOCOL_VERSION assertion (20 → 21) in serialization test
- Add D-181 Phase 2 visibility scope comment on serve_econ_state_query
- Eliminate double lookup in rebuild_signals via single-pass extraction
- Track economy seed TODO with backlog ticket reference
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
System S-057 assigned to real star GJ 35 (Van Maanen's Star, DG white
dwarf at 13.9 ly). Renamed across all content, server code, docs,
decisions, wiki lore, and config files. 224 files updated.
Co-Authored-By: Claude Opus 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>
ContentType::Factual bypasses LLM for fact-bearing lines (numbers,
denials). Observer enrichment systems rewrite dialogue/conversation
text with voiced versions before snapshot assembly. Friendly and
RoutineDeviation tells get concrete surface-pattern examples.
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>
- 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>
- 7 archetype→monologue regression tests (smuggler/detective pool partitioning)
- 3 tell escalation unit tests (RoutineDeviation insertion + expiry)
- 6 news ticker tests (pool loading, SimRng rotation, zone gating)
- 3 live integration tests against real server binary (Layer 3)
- Update existing tests for current_ticker field and protocol v19
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add live server lifecycle to tests/run-visual (start/stop server per
scenario, parse LISTENING:{port}). Add MessagePack snapshot replay to
visual_capture.gd via Protocol.decode_snapshot() — exercises the full
client pipeline from wire bytes to rendered fog. Three replay scenarios
(hub_spawn, fog_theater, hub_after_movement) plus one live scenario
(fog_live_hub). Add gen_gauntlet_fixtures.rs to produce .msgpack fixtures
from the Gauntlet test world. Add max_diff_pct threshold to visual-diff.
Makefile: add fixtures-gauntlet target, fix build-client double-import,
preserve .godot cache in clean.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add debug_response: None to all ObserverSnapshot constructors in
integration tests
- Bump PROTOCOL_VERSION assertion 17 → 18 in serialization tests
- Regenerate golden proof_room_tick_10.json (BoundaryWall tiles)
- Regenerate client msgpack fixtures for new snapshot fields
- Fix debug.rs resource optionality (Option<ResMut> for
ContaminationActive/EventQueue)
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>
The constant was supposed to represent 30 game-minutes but the formula
was wrong (30 × 10 tps × 60s = 1800). Correct derivation: 30 minutes ×
TICKS_PER_GAME_MINUTE (10) = 300. Now uses the canonical constant
directly. Also fixes stale assertion message in integration test.
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>
Timer-based storyteller system fires after 1800 ticks (30 game-min).
Sets ContaminationActive resource, applies tension delta to all
ActiveFork triangles, and emits ContaminationEvent for downstream
monologue/behavioral hooks. Q-017 fallback constants in place.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Production startup now spawns 23 Sova NPCs with EntanglementTag
(Flat/Intrigue) based on triangle_membership. Three-phase spawn:
entity creation, cross-reference resolution, and authored triangle
instantiation. Five triangles (3 ActiveFork, 2 PassiveTension per
D-087) with deterministic IDs via FNV-1a hashing.
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>
Implements the StartupMessage protocol: client generates world_seed in
SessionManager.new_game(), sends it after handshake, server uses it to
seed SimRng and sample EntanglementConfig.
EntanglementConfig samples flat ∈ [25,35]%, intrigue ∈ [15,25]%, mundane
as remainder (D-029). Same seed produces identical config (D-010
determinism). Different seeds produce distinct configs in ≥90% of pairs.
Protocol flow: HandshakeMessage (server→client) → StartupMessage with
world_seed (client→server) → SimRng initialization → tick loop.
10 Rust tests (determinism, variation, bounds, sum invariant).
9 GDScript test stubs + 2 encode tests for client-side pipeline.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the peripheral sector (100° half-angle, reduced range) and blind
spot classification. The server now sends only tiles within the 120°
forward cone; the client renders previously-explored tiles behind the
player with a light fog overlay instead.
This eliminates complexity in both the cone classifier and the snapshot
protocol while preserving the core information asymmetry — you still
can't see behind you, and the monologue system (D-016) still bridges
the perceptual gap.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. CRITICAL: spawn_template_npcs now inserts NpcVisionState, NpcMemory,
PlayerAwareness on template-spawned NPCs — matches spawn_npc() pattern
from PR #66. Without these, template NPCs were invisible to vision and
awareness systems.
2. WARNING: generate_intra_template_triangles now calls validate_triangle_def
before generating TriangleState — mirrors cross-template path. Updates
test TriangleDefs and logistics-hub.yaml to pass all three quality checks
(conflict viability, relationship coherence, interest divergence).
3. WARNING: state_hash in compute_observer_snapshot now uses FNV-1a instead
of DefaultHasher — consistent with D-010 principle 4 and the pattern in
TemplateId/TriangleId. Updates golden file for new hash value.
4. WARNING: TriangleCrisisEventWire.role_assignments now filtered against
observer KnowledgeGraph — unknown NPCs redacted from wire event per
D-010 principle 2 (information boundaries).
5. WARNING: ActiveTemplateInstances::insert now despawns previous instance
entities before overwriting — prevents orphaned ECS entities.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add FullTemplateDef integration tests: round-trip YAML serialization,
space spec validation, routine schedule, sightline zones, dialogue pool
refs, cross-template link specs, and logistics-hub template fixture.
Tests cover the full social site template document structure per D-023,
D-024, D-025, D-028.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Protocol v17: add state_hash (desync detection) and sim_errors
(structured error reporting) to ObserverSnapshot. Add SimError,
SimErrorKind, SimErrorBuffer types. Wrap main loop app.update() in
catch_unwind — on panic, send a final SimError snapshot before exit.
Report recoverable deserialization errors to client via SimErrorBuffer.
Compute per-tick state hash from player position + NPC count + tick.
Update all test fixtures and golden files for protocol v17.
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>
- Add ValidationError enum with three failure modes: ConflictViability
(missing Want axis), RelationshipCoherence (empty constraints),
InterestDivergence (duplicate interest axes)
- Add validate_triangle_def() pure function enforcing all three checks
in priority order (per D-087)
- Add generate_cross_template_triangles() function that combines NPC
pools from two templates, validates each TriangleDef before processing,
and assigns ownership to template_a
- 10 integration tests in tests/triangle_validation.rs covering all
validation failure modes, ordering guarantees, cross-template span,
invalid def skipping, determinism, and intra-template isolation
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>
Updates all client-side msgpack test fixtures and server test
harnesses to include the new triangle_crisis_events field added
in protocol v16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements #163 (RoleSchema), #164 (SpaceSpec), #165 (TemplateOwnership
+ TemplateReferenceMap), #106 (TriangleDef), #107 (intra-template
triangle generation), and #250 (triangle escalation system) as the
foundational Tier 2 template system per D-025.
New content/template module with YAML-deserializable schema types,
ECS components for ownership/triangle state, escalation system
running on game-minute boundaries, and TriangleCrisisEvent emission.
Sample YAML templates at server/data/templates/.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- gen_fixtures.rs: version comments now say PROTOCOL_VERSION instead
of hardcoded 14, so they stay correct across bumps
- run-ipc-benchmark: remove --iterations flag that was parsed but
never forwarded to the Rust test (compile-time constant governs)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
#556: HANDSHAKING state in sim_bridge.gd — decodes first framed message
as HandshakeMessage, validates vs Protocol.PROTOCOL_VERSION, 5s timeout,
handshake_complete/handshake_failed signals.
#342: IPC benchmark now reads and validates HandshakeMessage before
starting the timing loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed duplicate examine_result from ObserverSnapshot (old ExamineResultEvent
superseded by ExamineResultWire). Fixed serde_default test version assertion.
Regenerated golden file and all fixture .msgpack files. 1070 Rust tests passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Five new .msgpack fixtures: snapshot_minimal, snapshot_full,
player_input_move, player_input_interact, malformed. Rust generator in
gen_fixtures.rs, 7 Rust validation tests in serialization.rs, GDScript
cross-language test in test_ipc_fixtures.gd (22 assertions).
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>
Regenerated MsgPack fixtures for protocol v14 (examine_result and
character_pressure fields). Updated golden test, serialization
assertions, and cross-language fixture generator.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add three new ObserverSnapshot fields for client Sprint 18 tickets:
poi_list (Vec<PoiWire>) for minimap #151, examine_result
(Option<ExamineResultWire>) for #174, player_knowledge
(Option<PlayerKnowledgeWire>) for journal #264. POI list populated
live from KG-discovered PointOfInterest components. KG dump
serializes entity/fact knowledge with confidence, source, and state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Version field round-trip, mismatch detection, serde_default migration
pattern, all TellCategory and VerbKind variant coverage.
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>