Scoped the vertical slice: 16 EntityKnowledge keys, v0.1 mechanical NPC mapping, YAML content format, 7-verb interaction model, server- authoritative pause, 38 tickets created across copy/server/client/ci. 20 decisions (D-042 through D-061). 8 agents, 2 rounds + closing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
16 KiB
v0.1 Content Scoping Workshop — Summary
Date: 2026-02-12 Called by: Jeroen Participants: Gestalt (Systems Design), Paula (Narrative), Tyre (Architecture), Mellanie (Copywriter), Stig (UI), Dudley (Server), SI (Project Manager), Qatux (Documenter) Rounds: 2 + closing round (lead resolutions) Purpose: Scope and prioritize content work for v0.1 vertical slice. Apply Wiki Review long-term strategy (300-world generator model) to the hand-authored Sova Transit District proof. Key constraint: v0.1 proves the interaction model. All structures must be generator-compatible for the 300-world future.
Source files:
docs/workshops/v01-content-scoping/round1-tracking.mddocs/workshops/v01-content-scoping/round2-tracking.mddocs/workshops/v01-content-scoping/si-ticket-changes.mddocs/workshops/v01-content-scoping/v01-content-scoping-workshop-brief.md- Round 1 responses:
round1-gestalt.mdthroughround1-si.md - Round 2 responses:
round2-gestalt.mdthroughround2-si.md
1. Workshop Overview
Round 1 — 7 responses across 6 topics (wiki fixes, NPC architecture, content directory, interaction model, scope boundary, tickets). Produced 17 consensus items, 5 disagreements, 7 wiki gaps, 7 decisions ready to formalize, 26 surviving tickets + 7 new proposals.
Round 2 — Lead issued 4 decisions resolving the major disagreements (NPC mapping, content format, interaction model, pause behavior). 7 responses addressed remaining convergence work. Gestalt changed 6 of 10 NPC mapping positions to Paula's reads. Tyre and Dudley independently produced structurally identical ObserverSnapshot v3 definitions. Mellanie delivered canonical PC voice registers and the Kael Davan content pack template.
Closing round — Lead resolved 3 remaining questions: Q-012 (16 EntityKnowledge keys), Q-013 (server-authoritative pause, NEW-12 killed), Q-016 (verbs[] rename confirmed). Established process rule: no ticket merges across domain teams.
2. Decisions Made (D-042 through D-061)
From Round 1 Consensus (7)
| ID | Decision |
|---|---|
| D-042 | Drin promoted from Tier 3 to Tier 2. |
| D-043 | THE NOBODY mechanic deferred to v0.2; hidden pattern+motivation data ships in v0.1 content files. |
| D-044 | v0.1 interaction model: 7 interactions (Move, Look, Monologue, Examine Object, Examine NPC, Talk, Overhear). |
| D-045 | v0.1 scope IN additions: News ticker, PC-as-NPC, Time progression, Relationship state transitions. |
| D-046 | v0.1 scope OUT additions: Inventory, Stealth, Combat, Player-facing save/load, Lattice modification. |
| D-047 | v0.1 triangles: 3 active forks (T1, T2, T4), 2 passive tensions (T3, T5). |
| D-048 | Client receives all text from server via state updates; client does not load or evaluate content files. |
From Round 2 + Closing (13)
| ID | Decision |
|---|---|
| D-049 | YAML is the content file format for v0.1. RON converter available as optional build-time tool. Server loads YAML directly; RON cache is a future production optimization. |
| D-050 | Gestalt's NPC pattern/motivation mapping is canonical for v0.1. Paula's emotional/narrative layer becomes v0.2 annotations. Version-toggle approach. |
| D-051 | v0.1 ships single context-sensitive action; multi-verb architecture modeled underneath. Server computes N available verbs per entity. v0.1 client shows priority-0 only. v0.2 client reads full list — no server changes. |
| D-052 | 3-state pause: Normal (100%), Overlay (50%), Paused (0%). Server-authoritative — client is a dumb renderer. Client sends pause IPC command; reads sim_speed from ObserverSnapshot. |
| D-053 | Self-contained triangle forks for v0.1. No cross-triangle cascade. v0.2 adds storyteller-managed cascade. |
| D-054 | ObserverSnapshot v3 protocol. Extends v2 with: sim_speed, nearby_interactions, active_dialogue, monologue, overheard, knowledge_updates, examine_result, ticker_headlines. Backward compatible via serde defaults. |
| D-055 | 16 EntityKnowledge keys. 4 new generic role-perspective keys. trust_read merged into trust_level. secret_held renamed to leverage_held (expanded value space). secret_confidence → leverage_confidence. social_debt and loyalty_conflict deferred to v0.2. |
| D-056 | PC voice registers defined. Smuggler: feeling-first, fragments, concrete/physical. Detective: analysis-first, complete sentences, institutional vocabulary. |
| D-057 | Content directory: content/ with schema/, global/, districts/ top-level split. JSON Schema validation at build time. Dialogue by location+role. Monologue partitioned by character. |
| D-058 | THE FRIEND content pack template: Kael Davan. 91 lines across 5 arc phases. Becomes template for all subsequent packs. |
| D-059 | Monologue display: 160 char max, 2-line max, 4-6s display, 2s cooldown, queue depth 1, 9-level priority ordering. |
| D-060 | actions[] renamed to verbs[] across all surfaces (server, client, YAML, wiki, decisions). |
| D-061 | No ticket merges across domain teams. Shared epics fine; each team gets own ticket with own definition of done. |
3. EntityKnowledge — 16 Keys
Architecture: All keys are observer-to-target. Interpretation lives in content (monologue pools, voice registers, archetype briefs), not schema. Same key, same enum, different meaning per archetype.
12 Existing Keys
| # | Key | Category |
|---|---|---|
| 1 | name |
Identity |
| 2 | role |
Identity |
| 3 | faction |
Identity |
| 4 | species |
Identity |
| 5 | location |
Spatial |
| 6 | routine_pattern |
Behavioral |
| 7 | trust_level |
Relational (absorbs trust_read) |
| 8 | leverage_held |
Relational (renamed from secret_held; expanded: secrets, debts, promises, obligations, compromising positions) |
| 9 | leverage_confidence |
Relational (renamed from secret_confidence) |
| 10 | relationship_state |
Relational |
| 11 | behavior_flags |
Behavioral (tracks tells + contradictions) |
| 12 | known_associates |
Social |
4 New Role-Perspective Keys
| # | Key | Values | What It Stores |
|---|---|---|---|
| 13 | risk_assessment |
none / low / moderate / high / critical | How this NPC threatens observer's position |
| 14 | loyalty_assessment |
solid / dependable / uncertain / wavering / hostile | How predictably this NPC serves observer's interests |
| 15 | position_integrity |
solid / thin / cracking / blown / N/A | Status of active deception involving this NPC |
| 16 | moral_weight |
innocent / peripheral / complicit / compromised / willing | Observer's subjective moral assessment |
Deferred to v0.2: social_debt (no favor economy in 30-min session), loyalty_conflict (inferable from behavior_flags + loyalty_assessment).
Not added: tell_observed, contradiction_flagged — tracked in existing behavior_flags.
4. NPC Mapping
v0.1 Canonical (Gestalt's Mechanical Mapping)
| # | Name | Tier | Pattern | Motivation |
|---|---|---|---|---|
| 1 | Kael Davan | T1 | FRIEND | OPERATOR |
| 2 | Sera Venn | T1 | FRIEND | WITNESS |
| 3 | Naia Tamm | T1* | MIRROR | CIVILIAN |
| 4 | Voss | T2 | SYSTEM | OPERATOR |
| 5 | Lera Sessik | T2 | ANCHOR | OPERATOR |
| 6 | Torek Lintar | T2 | CATALYST | CIVILIAN |
| 7 | Devra | T2 | THRESHOLD | HANDLER |
| 8 | Maret Korr | T2 | WITNESS | SKEPTIC |
| 9 | Resha | T2 | CATALYST | CIVILIAN |
| 10 | Drin | T2 | SYSTEM | TURNCOAT |
| 11 | Renn | T2 | THRESHOLD | OPERATOR |
| 12 | Pell | T2 | CATALYST | TURNCOAT |
| 13 | Harek | T2 | ANCHOR | HANDLER |
| 14 | Sess | T3 | ANCHOR | CIVILIAN |
| 15 | Olin | T3 | CATALYST | CIVILIAN |
| 16 | Sabel | T3 | GHOST | OPERATOR |
| 17 | Tav | T3 | SYSTEM | CIVILIAN |
Off-stage: Nils Davan — GHOST + HANDLER
Distribution: 8 of 9 patterns present (REMNANT correctly absent; NOBODY deferred). All 6 motivations present. CIVILIAN at 6/17 (35%) matches D-029 noise floor (~30%).
v0.2 Emotional Layer (Paula's Annotations)
Paula annotated all 10 disagreement NPCs with emotional/narrative depth descriptions specifying what content each v0.2 motivation/pattern unlocks (~30-50 lines per NPC). The version-toggle approach: same NPCs, same schema, deeper analytical lens.
Resolution Process
Gestalt changed 6 of 10 Round 1 disagreement positions to Paula's reads (Maret pattern+motivation, Resha motivation, Harek pattern, Drin pattern, Sabel pattern, Olin motivation). Gestalt held on 3 (Voss motivation, Devra motivation, Sess pattern). Tav was a design-choice change (NOBODY deferred = SYSTEM+CIVILIAN instead).
5. Content Architecture
Format
YAML for all content files (D-049). RON converter in tooling/ as optional build-time optimization. Server loads YAML directly via serde_yaml. JSON Schema validation at authoring and build time.
Directory Structure
content/
content.yaml # manifest
_schema/ # JSON Schema files
_meta/ # infrastructure
global/
facts.yaml
factions.yaml
enums/ # situations, topics, moods, triggers, access-tiers, activities
knowledge/
entity-attributes.yaml
regions/
districts/
sova-transit/
district.yaml
npcs/ # per-NPC YAML (tier-conditional fields)
locations/
triangles/ # 5 triangle definitions
lines/
dialogue/ # by location + role (not NPC)
monologue/ # partitioned by character
routines/
templates/
Canonical ID format: {system}.{station}.{district}.{type}.{slug}
Validation Pipeline (3-tier)
- Authoring time: IDE with JSON Schema autocomplete
- Build time:
make validate-content— JSON Schema + cross-reference validation - Load time: serde_yaml deserialization + semantic validation (StableId assignment, relationship wiring)
Schemas Defined
npc-profile.schema.json— tier-conditional fields, pattern/motivation enums, axes, tells, access tiers, trust levels, friend_arc, triangle membershipdialogue-pool.schema.json— tagged per D-028/D-035, role+location based, access/trust/situation gating, knowledge_grantsmonologue-pool.schema.json— character-partitioned (D-032), trigger+prerequisite (AND-only)+priority+cooldown, 160 char max
6. Interaction Model
7 Verbs (D-044)
Move, Look, Monologue, Examine Object, Examine NPC, Talk, Overhear.
Architecture
- Server computes N available verbs per entity every tick via
verbs[]field (D-060 rename fromactions[]) - Priority-sorted: context determines which verb surfaces as
[E]prompt - Post-contradiction: Examine can rise above Talk (detective investigating flagged NPC)
verbs[]embedded in ObserverSnapshot vianearby_interactions, not separate message
v0.1 Client
Single context-sensitive action. [E] Talk / [E] Examine. One keybind. InteractPrimary PlayerAction variant sends priority-0 verb.
v0.2 Extension
[E] Talk [F] Observe — horizontal label row. InteractWith PlayerAction variant. Client reads full verbs[] list. No server changes needed.
Convergence
Tyre (AvailableActions/ActionOption), Dudley (EntityInteractions/AvailableAction), and Stig (InteractionOptions) independently produced structurally identical designs. Naming unification deferred to implementation (Q-015).
7. Pause System
3 States (D-052)
| State | Speed | Trigger |
|---|---|---|
| Normal | 100% (1.0) | Default |
| Overlay | 50% (0.5) | Knowledge panel, dialogue |
| Paused | 0% (0.0) | Spacebar (always) |
Authority
Server-authoritative. Tick rate is a server simulation concern. Client is a dumb renderer — renders ObserverSnapshots at whatever rate the server sends them. Client sends pause IPC command to server. Client reads sim_speed from ObserverSnapshot for visual feedback.
Spacebar from any state goes to Paused. Spacebar from Paused resumes to pre-pause state. Multiple overlays don't stack below 50% in v0.1.
NEW-12 (client pause state machine) killed — client doesn't manage time. Stig's PauseManager reduced to sending IPC commands and reading sim_speed.
8. Scope Boundary
IN (v0.1)
- WASD movement + collision
- Context-sensitive interaction (7 verbs, single-action prompt)
- Monologue system (tagged triggers, FactId prerequisites, AND-only)
- Knowledge graph (player learns facts, relationships change)
- 2 playable characters (smuggler, detective)
- THE FRIEND arc (Kael for smuggler, Sera for detective)
- 5 triangles: 3 active forks (T1, T2, T4), 2 passive tensions (T3, T5)
- 6 wow moments (D-039)
- 3 social sites (Terminal, Last Shift, Maintenance Corridors)
- NPC routines (schedule-based movement)
- News ticker (world-space at bar)
- PC-as-NPC (other character exists as NPC)
- Time progression (DayPhase)
- Relationship state transitions (Friendly → PersonOfInterest)
- Self-contained triangle forks (no cross-triangle cascade)
- ~695 authored content items (~200 monologue + ~350 dialogue + ~50 environmental + ~20 ticker + ~50 UI + ~25 PC-as-NPC)
OUT (v0.1)
- THE NOBODY / dynamic tier promotion (data ships, mechanic deferred)
- Archetype transitions
- Multiple FRIEND candidates per character
- Secondary contraband variation
- Gate network / multi-world
- Content generation / randomization
- Modding support (mod-compatible conventions ship; overlay implementation doesn't)
- Inventory system (evidence is knowledge, not physical items)
- Stealth mechanics (social stealth, not mechanical)
- Combat system
- Player-facing save/load (session-based 30-minute slice)
- Lattice modification/upgrade
- Cross-triangle cascade (storyteller-managed, v0.2)
social_debt/loyalty_conflictEntityKnowledge keys
9. Ticket Summary
Counts
| Category | Count | Teams |
|---|---|---|
| Wiki fixes (A-series) | 8 | copy |
| Style guides & specs (B-series) | 5 | copy |
| Content directory & schema (C-series) | 10 | copy (1), server (8), ci (1) |
| Design specs (D-series) | 2 | server (1), copy (1) |
| Workshop tickets (NEW 1-7) | 7 | copy |
| Lead decision tickets (NEW 8-14, excl. killed NEW-12) | 6 | server (4), client (2) |
| Total new tickets | 38 | copy (21), server (13), client (2), ci (1) |
| Existing ticket updates | 10 | — |
Sprint 3 Allocation
Copy team (15 tickets):
- P0: #261 (Dual Lens Guide — critical path root, blocks 9 tickets), C1 (content dir design), A1 (canonical names), A2 (Naia Tamm rename), A7 (smuggler attributes)
- P1: B2 (MIRROR spec), B4 (smuggler voice + moral arc), NEW-1 (NPC mapping), NEW-5 (wow moment checklist), A10 (Nils stub), A11 (Triangle 1 fix)
- P2: B3 (PC-as-NPC spec), A8 (shortcode fix), NEW-2 (Drin expansion), NEW-7 (interaction verb spec)
Server team (6 additions to existing 10):
- C2 (directory skeleton), C3 (schemas), C9 (validate-content CLI), NEW-9 (proximity + InteractionOptions), #326-P1 (loader skeleton), NEW-11 (tick rate scaling)
Client team (1 addition):
- NEW-10 (extensible interaction prompt)
Critical Paths
Chain 1 — Content Authoring:
#261 → B4 → A6 (Sprint 4) → NEW-4 (Sprint 4) → content packs (Sprint 5)
Chain 2 — Content Architecture: C1 → C2+C3 (Sprint 3) → C4-C8+NEW-3 (Sprint 4) → #326-P2 (Sprint 4)
Chain 3 — Interaction Pipeline: NEW-7 (soft) → NEW-9 (server) → NEW-10 (client)
#261 (Dual Lens Authoring Guide) is the single biggest blocker. Blocks 9 downstream tickets across the entire content pipeline. Recommended: Paula as owner, 5-day time-box.
Key Existing Ticket Updates
- #368: Close (wiki delivered)
- #369: Repurpose as parent epic
- #326: Split into Phase 1 (Sprint 3, skeleton) + Phase 2 (Sprint 4, real content)
- #86: Update ECS component list to workshop output
- #88: Add #237 (A* pathfinding) dependency
10. Open Items Carried Forward
| ID | Item | Owner | Priority |
|---|---|---|---|
| Q-014 | 3 NPC surnames awaiting Miri validation: Drin Vassar, Sess Torin, Tav Lenn | Miri | Low |
| Q-015 | Interaction struct naming: AvailableActions (Tyre) vs EntityInteractions (Dudley). Trivial — resolved at implementation time. |
Tyre/Dudley | Low |
| Q-017 | 695 authored items validated as scope input but not independently verified by other agents. | SI/Mellanie | Low (informational) |
None of these block Sprint 3 work.
Compiled by Qatux. Workshop produced 20 decisions (D-042 through D-061), 38 new tickets + 10 updates, canonical NPC mapping for 17 NPCs, 16-key EntityKnowledge spec, full content architecture, and Sprint 3-5 roadmap. 3 minor open items carried forward. #261 is the critical path root.