Replace every occurrence of "Krenn" with "Van Maanen's Star" (or contextual variants like VMS for locale codes, Van Maanen for proper noun contexts). Covers CHANGELOG, briefings, workshop docs, sprint briefings, environmental text examples, templates, ticker content, and architecture docs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
11 KiB
title, description, type, status, workshop, agent, round, created
| title | description | type | status | workshop | agent | round | created |
|---|---|---|---|---|---|---|---|
| Workshop Brief | Workshop brief defining goals, participants, and scope for LLM voice pipeline design | workshop | archived | llm-voice-pipeline | 0 | 2026-03-07 |
LLM Voice Pipeline Workshop Brief
Goal: Decide the content generation architecture for NPC observable behaviors and dialogue — hand-authored pools, composable primitives, LLM re-voicing, or a hybrid. Produce a D-record and implementation plan.
Priority: HIGH — blocks scaling beyond the Sprint 25 spike. Current content model is O(roles x zones x cultures) hand-authored sentences.
Participants: Gestalt (systems design), Tyre (technical feasibility), Paula (narrative quality), Mellanie (content authoring), Ozzie (player experience), Miri (world consistency), Troblum (infrastructure/performance), Qatux (documenter), SI (tickets)
Source: Sprint 25 generator spike results, Q-057 (composable behavior generation), proposed-llm-voice.md (Gemini/Jeroen design session)
Context
What the spike proved
The Sprint 25 generator produces legible people in legible places. Five reviewers confirmed it "has shape." The mechanical foundation works:
- Zone contrast is real (rural vs industrial reads as different places)
- Trait-to-behavior correlation produces emergent character
- Want/State layer creates internal motives that leak through micro-tells
- Relationship-to-behavior pipeline makes social connections visible
The scaling wall
Copy team expanded behavior pools to ~50 lines per role during Sprint 25 (#630). In doing so, they surfaced Q-057: this doesn't scale. Each zone file is really culture x zone content — van-maanens-star-rural-zone.ron is not a reusable "rural template," it's Van Maanen's Star-flavored rural content. Adding a second culture or a third zone type means authoring from scratch.
The numbers: 4 roles x ~50 behaviors x N zones x M cultures = thousands of hand-authored lines before the game has meaningful variety. The copy team renamed files from generic (rural-zone-spec.ron) to location-specific (van-maanens-star-rural-zone.ron) to make this explicit.
Three options on the table
-
Hand-authored pools (current) — write complete sentences per culture x zone x role. High quality, doesn't scale. O(R x Z x C) content.
-
Composable primitives (Q-057) — decompose behaviors into role actions + culture modifiers + context tags, assemble at runtime. Scales better, but composition engine is complex and may produce mechanical-feeling output.
-
LLM re-voicing — write simple semantic lines per role (culture-neutral), use a small local LLM to "translate" them into character voice using injector clauses (personality, culture, mood). Scales to any culture with ~10-20 injector clauses per culture.
Shipping model: local inference, baked + lazy
The LLM ships with the game. Not as a dependency — as a bundled component. A lightweight Rust wrapper (not ollama, but similar in spirit — tightly coupled, single-purpose) loads a small model (2B-class) and runs inference locally. No network calls, no accounts, no cloud.
The design is progressive enhancement, not a toggle between two systems. Every behavior and dialogue line starts as a generic, culture-neutral base text — "tends crops in the field", "checks credentials at the gate." This base text serves triple duty:
- LLM seed prompt — the input the re-voicing model transforms into character-voiced output
- Fallback — what the player sees when pre-voicing hasn't finished yet
- LLM-off experience — the complete gameplay layer for players who disable AI-enhanced dialogue or run on minimal hardware
There is no separate authoring step for the fallback. The base text IS the fallback. The i18n analogy holds: en-base is always present, en-VMS-BOLD is the enhancement.
Content tiers: baked, pre-voiced, fallback
-
Baked — hub systems (Sova Transit District and other major locations) ship with pre-voiced content already generated and cached at build time. The player's first hours are fully voiced from disk. This is the quality floor and also the quality reference for runtime generation.
-
Pre-voiced — as the player moves through the world, the system anticipates where they're going and pre-generates voiced content in the background. Same pattern as lazy world generation: while the player does their thing in one zone, adjacent and likely-next zones get their content voiced. Prioritized queue: plot-critical NPCs first, then semi-unique, then ambient.
-
Base text (graceful fallback) — if the player moves faster than the queue (or hardware is slow, or LLM is off), they see the generic base line. Clean, functional, gameplay-complete — just not character-voiced. No jarring transition: base text is designed to read as neutral, not broken. The system catches up in the background and the next time the player returns, the voiced content is ready.
The "AI-Enhanced Dialogue" setting: OFF means base text everywhere (zero inference cost, runs on anything). ON means the pre-voicing pipeline is active. The game is complete either way.
What's new since the proposal
The spike added systems that the original LLM voice proposal didn't account for:
- Want/State layer — NPCs have internal motives. Can the LLM preserve the tell without making it obvious?
- Relationship behaviors — "talks past Rask without making eye contact." Can the LLM re-voice relationship-driven actions without losing the specific social information?
- Perception mechanic — players READ behaviors to infer hidden state. If the LLM varies the phrasing, does the same tell read differently to different players? Is that a feature or a bug?
- Determinism — same seed = same world. LLM output is non-deterministic. Pre-voicing and caching may solve this (generate once per seed, cache the result).
Key Questions to Resolve
Architecture
- Does the LLM re-voice observable behaviors (what you SEE), dialogue (what NPCs SAY), or both?
- How does re-voicing interact with the Want tell system? The tell is a carefully authored micro-behavior — does it get re-voiced or pass through untouched?
- How does determinism work? Generate once per seed and cache? Accept variance for flavor text but lock tells?
- What's the boundary between baked content and runtime generation? Which zones/NPCs ship pre-voiced?
Content Model
- What does the authoring workflow look like? Base text is already being written (the current behavior pools). Who writes injector clauses and culture modifiers? Copy team? Automated from culture RON?
- How does the base-text-to-voiced-text pipeline change the current RON format? Do we strip culture-specific vocabulary from base text (since the LLM adds it), or keep it as a quality floor?
- How do we quality-control LLM output? What catches lore breaks or leaked game state? Build-time validation pass on baked content? Runtime sampling?
- How do injector clauses map to the existing data model? Traits, culture profile, Want — which fields become injector inputs?
Technical Feasibility
- What 2B-class model can run on minimum-spec hardware (integrated GPU, 8GB RAM, shared with the game) with acceptable latency for background generation?
- What's the Rust inference wrapper? ggml/llama.cpp bindings, candle, burn? What's the binary size and startup cost?
- How does the pre-voicing queue integrate with the lazy world generation pipeline? Same thread pool, or separate?
- What's the cache format and invalidation strategy? (Seed changes = full regeneration? Culture mod = partial?)
Player Experience
- Base text is designed to be neutral, not broken — but is the quality gap between base and voiced noticeable enough to feel like a downgrade when pre-voicing hasn't finished? How do we minimize the seam?
- Does LLM variance help or hurt replayability? (Different phrasing per run vs recognizable patterns)
- How large is the baked cache for hub systems? Does it meaningfully impact install size?
- The lazy pre-voicing pattern mirrors lazy world generation — can we reuse the same priority/anticipation infrastructure?
Narrative & World Consistency
- Can injector clauses preserve culture-specific vocabulary (void-oaths, Van Maanen's Star speech register) reliably at 2B model size?
- How do we prevent the LLM from introducing lore-breaking content? (References to things that don't exist in the Settled Reach)
- Does re-voicing work across the 30/50/20 NPC tier model? Tier 3 ambient NPCs get re-voiced, Tier 1 hand-authored — where's the Tier 2 line?
Input Documents
| Document | What to read | Why |
|---|---|---|
docs/architecture/proposed-llm-voice.md |
Full proposal | The architecture being evaluated |
server/src/bin/generator_spike.rs |
gen_want, gen_want_tell, apply_relationship_behaviors | Systems re-voicing must preserve |
server/src/npc/blueprint.rs |
NpcBlueprint, NpcWant, CulturalMarkers | Data model re-voicing consumes |
content/global/van-maanens-star-rural-zone.ron |
Full file | Current hand-authored quality bar |
content/global/van-maanens-star-industrial-zone.ron |
Full file | Same, different zone for contrast |
content/global/culture-van-maanens-star.ron |
Speech patterns, exclamations | Culture voice injectors must preserve |
decisions/content.md |
D-121 (voice is culture-driven), D-122 (all NPCs generated), D-128 (culture implicit) | Content architecture constraints |
decisions/architecture.md |
D-010 (information boundaries), D-024 (NPC 10-axis model) | Architecture constraints |
decisions/questions-content.md |
Q-057 (composable behaviors), Q-012 (generation expansion) | Open questions this workshop should resolve |
decisions/scope.md |
D-117 (generator-first), D-115 (v0.2 proof-of-life) | Scope constraints — generator must work |
Expected Outputs
- D-record — the chosen content generation architecture (option 1, 2, 3, or hybrid), with rationale
- Resolution or refinement of Q-057 — composable behaviors: adopted, rejected, or subsumed by LLM approach
- Resolution or refinement of Q-012 — generation expansion method: now has a concrete candidate
- Tier boundary definition — which NPC tiers get which pipeline (hand-authored / re-voiced / both)
- Pre-voicing pipeline spec — baked zones, queue priority model, cache format, fallback behavior
- Inference wrapper requirements — model size ceiling, memory budget, Rust crate candidates
- Spike definition — concrete test: model candidates, test payloads from Sprint 25 output, success criteria
- Risk register — quality floor, hardware floor, lore contamination, cache size
Round Structure
Round 1: Inventory (divergent)
Each participant reads the input documents and the Sprint 25 spike output. Present:
- Your domain's take on the three options (hand-authored / composable / LLM re-voicing)
- Which option best serves your domain's concerns
- What breaks in your domain if we choose the wrong one
- One question you need answered before you can commit
Round 2: Proposals (convergent)
Based on Round 1 input, the lead synthesizes 2-3 concrete architecture proposals (may include hybrids). Each participant evaluates the proposals against their domain and flags blockers.
Round 3: Decision (commitment)
Narrow to one architecture. Resolve open questions. Produce the D-record. Define the spike. SI creates follow-up tickets.