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>
Points auto-memory to ~/Projects/settled-reach/.memory so all
worktrees share a single memory root outside the git tree.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prerequisite for #646 (AI-Enhanced Dialogue toggle). Updated server
and client briefings with dependency chain and integration notes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
13 tickets across server (5), copy (6), client (1), planning (1).
Sprint goal: ship voice pipeline to production via observer integration,
remove v0.1 dead weight, stabilize codebase. #648 cancelled as duplicate
of #658.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Spike 2 amendments: stdio IPC (not HTTP, Gemma 2 T&C compliance),
tell differentiation results (3/5 at 2B capacity), double-prompt
technique, ContentType::Factual for LLM bypass, all negative
injectors moved from universal RULES to per-culture voice_persona.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Critical fixes:
- Pause mechanism: workers now hold requests during pause instead of
dropping them. Queue and worker pool share the same AtomicBool flag
via VoiceQueue::paused_flag(). Submit() rejects while paused.
- Seed type: sr-voice accepts u64 seeds over IPC (explicit u32 truncation
for llama.cpp sampler, documented).
Warning fixes:
- HashMap → BTreeMap in cache.rs and worker.rs (D-010 determinism mandate).
Added Ord derives to CacheKey, ContentType, TellCategory.
- VoicePipe::generate() watchdog kills child after 120s timeout to prevent
indefinite blocking on read_line.
- VoiceCacheStore Drop impl calls save_all() on shutdown.
- trait-modifiers.ron: fixed 3 wrong trait names (Impulsive→Compassionate,
Methodical→Incurious, Stubborn→Ruthless) to match PersonalityTrait enum.
Suggestion fixes:
- Worker spawn: log error + reduce pool instead of panic on thread failure.
- on_battery(): added macOS detection via pmset.
- Epistemic markers: lowercased constants, removed redundant to_lowercase().
- cache.rs: documented non-atomic write tradeoff.
- queue.rs: reprioritize() bypasses pause check (it runs during pause).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10 trait modifiers targeting distinct speech dimensions (delivery force,
word selection, sentence shape, framing, cadence, volume, texture,
position) so they stack without conflict. Used by prompt_builder.rs
to modify NPC speech style based on personality traits.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gemma 2 T&C compliance: exposed HTTP ports allow mods or external code
to reach the model, complicating license enforcement. Switch to piped
stdin/stdout (JSONL protocol) so the model is only reachable through
the game server's internal queue.
- worker.rs: VoicePipe owns Child + piped stdin/stdout, VoiceProcessConfig
replaces port-based config, workers spawn their own sr-voice child
- hardware.rs: remove VoiceInstanceManager (port/process lifecycle),
replace with evaluate_scaling() free function + HardwareProbe::voice_config()
- sr-voice: add --stdio flag to serve command, new stdio.rs JSONL mode
- Remove ureq dependency from server crate (no longer needed)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add lookup.rs with voiced_behavior() — ready to wire into a behavior-serving
system once one exists (Q-058). Tell behaviors always passthrough (never
re-voiced). Cache miss returns base text (graceful degradation).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MessagePack voice cache with per-zone persistence and version invalidation.
Priority work queue with crossbeam bounded channel, backpressure, pause/resume,
and zone-change reprioritization. Inference worker pool with empty output guard
and graceful degradation to base text.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Tell-variant caching: 6→length-gated (short=neutral only, medium=3,
long=6). 2B model produces identical output across tell states on
short lines — confirmed across two test rounds.
- Composition-engine occasional injections: oath vocabulary, faith
expressions etc. controlled by prompt generator frequency, not model.
Systemic pattern for any culture marker that should appear occasionally.
- NI-1/NI-5 culture-gated: religious language and Earth-origin markers
are per-culture injector constraints, not universal bans. Cultural
heritage from colonization history is intentional. Earth is not lost.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reference document from Gemini design sparring session covering
re-voicing compliance and implementation considerations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Between rounds: mandatory AskUserQuestion checkpoint before next round launches
- Wrap-up: user explicitly controls team dismissal
- Hard requirements before close: D-records filed, discussion captured, tickets created
- User reviews workshop-outcomes.md before finalization
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Workshop to decide content generation architecture: hand-authored pools,
composable primitives, or LLM re-voicing with progressive enhancement.
Includes proposed-llm-voice.md (Gemini/Jeroen design session) and
Gemini project review (GEMINI-SCAN.md).
Key design: base text serves triple duty — LLM prompt seed, graceful
fallback, and LLM-off experience. Baked content for hubs, lazy
pre-voicing for exploration, same pattern as world generation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Open question for decomposing hand-authored behavior pools into
composable primitives (role actions + culture modifiers + context tags).
Part of Sprint 25 PoC spike. Server ticket #633, copy ticket #634.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Four generator spike improvements in one pass:
- #628: Fix name pool first-pick bias. build_name_pool now derives a
zone+culture-specific ChaCha20 RNG via FNV-1a mixing of (seed,
zone_type, culture_id), isolating name ordering from main RNG
consumption. Different zone types with the same seed now produce
different first names.
- #629: Behavior dedup within a zone run. build_behavior_pools
pre-shuffles each role's behavior list; gen_behaviors draws without
replacement. Falls back to random repeat with warning when pool
exhausts.
- #631: Relationship-to-behavior pipeline. Third generation pass
(~50% chance) replaces primary behavior with relationship-revealing
action — rivals talk past each other, friends drift together,
subordinates defer.
- #632: Want/State layer. NpcWant enum (Neutral/Bored/Alert/Suspicious/
AvoidingSomeone/LookingForInfo) biased by traits and role. Fourth
generation pass produces observable tells that leak internal state
through behavior. AvoidingSomeone resolves against negative-valence
relationships for named targets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Name pool fixes:
- Remove "Korr" from given_names (duplicate with family_names), replace with "Tork"
- Replace "Narek" with "Sorek" (real-world Armenian name, IP concern)
- Replace soft "-ael" endings (Vael→Vrek, Rael→Rask) to match naming rules
- Update comment: "no soft endings" → "hard endings preferred"
- Add 2 family names (Tollek, Dass) to balance pool ratio (now 40/18)
Voice fixes:
- Replace "same drill" (not an exclamation) with "cold vacuum"
- Rewrite 3 trader behaviors as observable stage directions
- Add 2 foreman off-duty behaviors (person beneath the role)
- Add break room behaviors to dock_worker, technician, foreman
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove "Narek" from family_names (duplicate with given_names), replace with "Morek"
- Rewrite rural farmer behaviors to be location-agnostic (no sky/weather assumptions)
- Add heritage root overlay comments (D-104/D-105) to both zone specs
- Add insert/lattice tech behavior to industrial technician role
- Rewrite 2 security behaviors with Krenn cultural texture (D-121)
- Replace generic exclamations with Krenn-specific oaths ("void's sake", "same drill")
- Replace soft greeting "you okay?" with "all in one piece?"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Insert A1b retrospective step between sprint close and version bump.
Covers: what shipped, what didn't, what we learned, process notes.
Process improvements are optional — only proposed when something was
actually broken.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zone specs need a location_context field (surface/station/vessel) so
the generator can filter environment-specific behaviors. Raised during
PR #88 review — rural zone had sky/weather references that only make
sense on a planet surface.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zone identity specs for the generator spike proof-of-life:
- rural-zone-spec.ron: 4 roles, 3 social sites, density 2, economic 3
- industrial-zone-spec.ron: 4 roles, 3 social sites, density 6, economic 7
Krenn culture profile:
- culture-krenn.ron: 40 given names, 16 family names, speech patterns,
cultural values (Bold/Honest/Curious/Social favored)
All three files validate against the Rust structs from #611 and produce
visibly differentiated output from the generator spike.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add generator-spike binary producing NPC rosters from hardcoded zone and
culture stubs. Deterministic via SimRng, supports rural and industrial
zone types with Krenn culture. Phase 2 (RON file loading) wired via
--from-files flag, awaiting copy team deliverables (#609, #610).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Define ZoneSpec, CultureProfile, and NpcBlueprint structs with serde/RON
deserialization. Ship example RON files as schema contract for the copy
team (#609, #610). Add validate-ron CLI for copy team to lint their files
without compiling the server.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
RON is Rust-native and struct-aware — the Rust structs ARE the schema.
Includes RON validator CLI for the copy team to lint their files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
D-records from Where's the Fun workshop across architecture, content,
and scope domains. Updated open questions for v0.2 pivot.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
server.md: four warnings from Troblum — generate_npc() requires a live
bevy World (stub routine generation in Phase 1), cultural text assembly
is a new code path not a one-liner, DayPhase alias collision in
generator.rs, schema negotiation takes rounds.
joint.md: confidence 15% note at top. Intra-zone variance test added
(rural seed 42 vs rural seed 43 — coherence within type, variance
across seeds). Pass conditions restructured into three explicit
comparisons: cross-type, intra-type, culture.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dependency chain inverted: #611 (NpcBlueprint structs) now goes first
and defines the schema contract. Copy team (#609, #610) fills YAML to
match Tyre's structs rather than the other way around.
#613 (NPC generation pipeline) cancelled and absorbed into #612 — the
NPC pipeline is the print loop at the end of the generator binary, not
a separate ticket.
Ticket descriptions loosened: strip over-specified acceptance criteria,
replace with intent + scope boundaries. Phoneme generation explicitly
out of scope for #610 (name lists are sufficient). #612 gains a phased
approach note (Phase 1: hardcoded stubs, Phase 2: real YAML) so server
can build in parallel with copy.
Briefings updated to reflect inverted chain, two-ticket server sprint,
and exploratory framing: this sprint discovers the right spec, it does
not implement a known one.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- protocol.gd: replace capitalize() with explicit match for archetype
string mapping, push_error on unknown input with Detective fallback
- main.gd: clear _known_triangle_ids in _teleport_transition() alongside
_known_recognition_ids so chime re-fires after room change
- news_ticker.gd: defer get_minimum_size() via call_deferred to run
after layout pass, fixing first-frame scroll distance
- 3 new tests: unknown archetype fallback, triangle dedup per-id,
independent triangle ID firing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>