Files
settled-reach/docs/workshops/content-gap-analysis_v0_1/round2-gestalt.md
T
jpmschweitzerandClaude Opus 4.6 e96ec80d9c docs(workshops): archive v0.1 content gap analysis workshop
6 agents × 2 rounds examining 9 content layers. Produced D-032
through D-039, THE FRIEND NPC pattern, converged tag taxonomy,
and Sova Transit District setting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:27:31 +01:00

42 KiB

Round 2: Gestalt (Systems Design) - Synthesis

Workshop: v0.1 Content Gap Analysis Date: 2026-02-11 Scope: Mechanical convergence across all Round 1 outputs + Jeroen's Round 2 directives


0. Directives Acknowledged

Before I get into synthesis, let me confirm the constraints from Jeroen's Round 2 direction. These are locked. No further debate:

Directive Status Mechanical Implication
Separate monologue pools per character Confirmed, non-negotiable Two parallel content trees. character is a hard partition tag, not a filter.
Color = relationship to player Approved Entity color is a client-side derivation from RelationshipState component + knowledge state. Not an NPC property.
Audio included in v0.1 Confirmed 6-8 AI-generated files. Sound event system architecture must support this. Visual fallback for everything beyond those files.
One NPC per character = THE FRIEND Confirmed Two production-level NPCs. Full pipeline depth test. All systems exercised on these two.
Wiki structure for taxonomy Non-negotiable Miri handling. Tag taxonomy I define here must integrate with wiki structure.
Line pool format (YAML) Needs validation Mellanie and Paula must sign off. That's what this section does.

1. Converged Line Pool Format

Let me break down what this actually means mechanically. Three people proposed tag schemas in Round 1. Let me reconcile them.

Schema Comparison

Tag Gestalt R1 Mellanie R1 Paula R1 (implied) Converged
id {template}_{type}_{###} {template}-{role}-{situation}-{##} Not specified Keep Gestalt format — machine-parseable, stable
text string string string Keep
role / speaker role (enum per template) speaker (enum per template) Implied by NPC profile role — the template role, not the NPC name. NPC assignment is runtime.
character N/A (on monologue only) character (smuggler/detective/any) Implied character — but ONLY on monologue lines. Dialogue lines are character-agnostic; the access tier handles filtering.
access list<enum> single enum Per-line, hard filter list<enum> — a line can be eligible for multiple access tiers
trust enum (surface/real/secret) enum (same) Three disclosure tiers, progressive Aligned. No change.
situation list<enum> list<enum> Relationship history + context list<enum> — see converged situation taxonomy below
topic list<enum> single enum Mood + topic for Layer 4 list<enum> — lines can cover multiple topics
mood list<enum> single enum Mood for weighted selection list<enum>
location N/A (implicit from file) enum N/A Drop from line-level. Location is implicit from the file's directory. Adding it per-line is redundant and an error source.
type N/A (implicit from file) type (dialogue/monologue/env/ticker) N/A Drop from line-level. Content type is implicit from file name (dialogue.yaml vs monologue.yaml).
tags list<string> freeform N/A N/A Keep — escape hatch for author intent that doesn't fit taxonomy
dual_lens map (per-character notes) N/A Critical for authoring Keep — authoring-only, not consumed by engine
notes string N/A N/A Keep — authoring-only
trigger On monologue only N/A N/A Keep for monologue — the observation event that fires the line
prerequisite On monologue only N/A N/A Keep for monologue — knowledge state gate

Converged Tag Taxonomy — FINAL (pending Mellanie/Paula sign-off)

Structural tags (required on every dialogue line):

Tag Type Values Maps to D-028 Layer
id string {template}_{d|m|e}_{###} N/A (indexing)
text string The authored line N/A (content)
role enum Template-defined roles N/A (speaker assignment)
access list<enum> public, insider, authority, peer, hostile Layer 1 (hard filter)
trust enum surface, real, secret Layer 3 (hard filter)
situation list<enum> See taxonomy below Layer 2 (context filter)

Selection tags (recommended, fallback to defaults if empty):

Tag Type Values Maps to D-028 Layer Default
topic list<enum> See taxonomy below Layer 4 (weighted selection) [general]
mood list<enum> See taxonomy below Layer 4 (weighted selection) [neutral]
tags list<string> Freeform N/A (author use) []

Authoring-only tags (not consumed by engine):

Tag Type Purpose
dual_lens map Per-character interpretation notes
notes string Author intent, dependencies, context

Monologue-specific tags (in addition to above):

Tag Type Values Purpose
character enum smuggler, detective Hard partition. Separate pools per Jeroen's directive.
trigger enum See trigger taxonomy below Observation event that fires this line
prerequisite map or null Knowledge state conditions Gate: line only eligible if character knows X

Alignment with Paula's Four Layers

This is the critical validation. Does the converged schema express all four D-028 layers?

D-028 Layer How It's Expressed Tag(s) Filter Type
Layer 1: Access tier access tag on every line. Engine checks player character's current access tier at the NPC's social site. access Hard filter. Line invisible if access doesn't match.
Layer 2: Relationship history situation tag + engine-tracked interaction state. Engine maintains per-NPC counters (interaction_count, last_interaction_time, notable_events). These counters activate/deactivate situation eligibility. first_meeting is true once. repeated_visit activates after 3+ visits. greeted_before is tracked by engine, not tagged per-line. situation + engine state Context filter. Narrows eligible pool based on relationship progression.
Layer 3: Trust-gated gossip trust tag on every line. Engine tracks trust progression per NPC (starts at surface, can reach real/secret through repeated positive interactions). trust Hard filter. Line invisible if current trust level is below line's trust tier.
Layer 4: Unprompted disclosure topic + mood tags. Engine selects from eligible lines (post-Layer 1/2/3 filtering) weighted by match between NPC's current mood state and line's mood tag, and between NPC's current concern topics and line's topic tag. topic + mood + engine state Weighted selection. Soft ranking, not hard filter. Neutral mood always available as fallback.

Verdict: The converged schema fully expresses all four layers. Layers 1 and 3 are hard filters (binary tag match). Layer 2 is engine-state-to-situation mapping. Layer 4 is weighted selection across two tag dimensions.

Paula's concern about greeted_before:true — this is NOT a per-line tag. It's engine state. The engine tracks whether these characters have met before and activates the first_meeting or repeated_visit situation accordingly. The content author doesn't tag individual lines with interaction history — they tag situations, and the engine decides which situations are active.

Key Changes from My Round 1 Proposal

  1. Dropped location from line-level tags — location is directory-level. This removes a redundancy Mellanie flagged.
  2. Dropped type from line-level tags — content type is file-level. This reduces Mellanie's 8 tags to 6 structural + 2 selection = 8 total, but 2 fewer per-line.
  3. Added character as monologue-only hard partition — confirms Jeroen's directive mechanically.
  4. Clarified that access is list, not single — a line can be eligible for both insider and peer.
  5. Made topic and mood list types — a line can cover multiple topics and be appropriate for multiple moods.

Situation Taxonomy v0.1 (Converged)

Merged from my Round 1 list + Mellanie's proposal:

Situation Description Activation
greeting First interaction this game-day Engine: no interaction logged today
first_meeting Characters have never interacted Engine: interaction_count == 0
routine Normal daily activity Engine: NPC in scheduled routine state
morning / afternoon / evening / night Day phase (D-031) Engine: current SimulationTime phase
repeated_visit Player has visited this NPC 3+ times Engine: interaction_count >= 3
interrogation Player is asking pointed questions Engine: dialogue topic escalation detected
witnessed_secret Player has observed something they shouldn't Engine: KnowledgeInventory contains secret-tagged fact about this NPC
idle NPC is between scheduled activities Engine: NPC routine state = idle
working NPC is performing job routine Engine: NPC routine state = job
social NPC is in social activity (bar, break) Engine: NPC routine state = social
confrontation Triangle tension has escalated Engine: triangle pressure threshold exceeded
post_event Responding to a recent simulation event Engine: event log contains recent entry for this NPC
absence_noticed An expected NPC is missing Engine: NPC not in expected location during expected time

13 situations for v0.1. Mellanie's gossip and observed_anomaly situations are covered by social + topic filtering and post_event respectively. I'm not adding them as separate situations because they're better expressed as topic + mood combinations.

Topic Taxonomy v0.1

Topic Description
work Job-related: tasks, schedules, complaints
social Relationships, personal life, family
cargo Freight, manifests, shipments — setting-specific
money Finances, costs, spending
rumors Gossip, hearsay, speculation
identity Who someone is, where they're from, what they do
deflection Avoiding a topic, changing subject
complaint Grievances, frustrations
general Weather, food, neutral small talk

9 topics for v0.1. Mellanie's crime topic is deliberately excluded — NPCs don't think of what they do as "crime." It's cargo or money from their perspective. The dual-lens interpretation is what makes those topics crime-adjacent for the detective.

Mood Taxonomy v0.1

Mood Description
neutral Default state. Calm, unremarkable.
happy Positive, upbeat, satisfied
tired Low energy, going through motions
annoyed Irritated, short-tempered
nervous Anxious, fidgety, checking surroundings
defensive Guarded, deflecting, walls up
friendly Warm, open, welcoming
cautious Careful, measuring words

8 moods for v0.1. Mellanie's tense, relaxed, and suspicious map to nervous, happy/neutral, and cautious respectively. I'm consolidating to prevent near-duplicate moods that make authoring harder without adding selection granularity.

Monologue Trigger Taxonomy v0.1

Unchanged from Round 1. 9 triggers:

Trigger Description
enter_location Player enters a new area
observe_npc Player sees NPC doing something notable
hear_sound Sound event from fog edge
observe_anomaly NPC deviates from known routine
post_conversation After dialogue ends
discover_evidence Player examines an informational object
witness_interaction Player sees two NPCs interacting
time_idle Player hasn't acted for a while
return_visit Player returns to a previously visited area

2. Mellanie's Tag Proposal vs. Mine — Convergence

Mellanie proposed 8 tags. I proposed a more granular set. Here's where we landed:

Mellanie's Tag My Tag Resolution
character character (monologue only) Aligned. Monologue-only, hard partition. Not on dialogue lines.
access access Aligned. I upgraded to list<enum>; she had single. List is correct.
trust trust Aligned. Identical.
location (directory-level) Dropped from per-line. Directory structure handles this. Mellanie agreed provisional format is fine.
situation situation Aligned. Her values are a subset of mine. Using the full 13-situation taxonomy.
mood mood Aligned. Consolidated to 8 moods.
topic topic Aligned. Expanded to 9 topics.
type (file-level) Dropped from per-line. File naming convention handles this.

Net result: 6 per-line structural tags + 3 per-line selection/freeform tags = 9 tags per dialogue line. For monologue lines: +3 monologue-specific tags = 12 tags per monologue line.

Mellanie's "tag smoke test" request is smart. Before she writes 165 lines for the workplace, she writes 20, tags them, and I validate the filtering behavior. This should happen as the first line previewer test case.


3. THE FRIEND: Production-Level NPC Specification

Okay, let me map this to mechanics. Jeroen says THE FRIEND is a production-level complex NPC — one per character, full pipeline depth test. Ozzie defined the emotional design in Round 1. Let me define what "production-level" means for the ECS and content pipeline.

What "Production-Level" Means Mechanically

THE FRIEND exercises every system we're building. It's the NPC that proves the pipeline works end-to-end:

System What THE FRIEND Tests Minimum Requirement
10-axis model (D-024) All 10 axes populated with meaningful values that change during play Axes must shift in response to simulation events
Access tiers (D-028 L1) THE FRIEND has different access tiers per character Smuggler: insider+peer. Detective: varies (starts public, can reach peer)
Relationship history (D-028 L2) Interaction count tracked, situation progression works first_meeting -> greeting -> repeated_visit must trigger different lines
Trust progression (D-028 L3) Trust level advances through positive interactions Surface -> Real progression visible in dialogue depth change
Unprompted disclosure (D-028 L4) THE FRIEND volunteers information when mood + topic align At least 3 unprompted lines that fire based on NPC mood state
Tell system Observable behavioral markers for internal state All 5 tell categories must be demonstrable on THE FRIEND
Routine system Predictable daily schedule with deviations Morning/afternoon/evening locations defined. At least 1 deviation event
Triangle membership Belongs to at least 1 triangle Triangle pressure must affect THE FRIEND's behavior observably
Contradiction arc (Ozzie) Discoverable through observation, not dialogue The contradiction must emerge from routine deviation + tell, then be confirmed/complicated by dialogue
Monologue integration Player character comments on THE FRIEND specifically Named monologue lines referencing THE FRIEND's behavior, not generic role observations
Dual-lens divergence Same NPC, fundamentally different relationship per character THE FRIEND is a different person emotionally to the smuggler vs. detective

THE FRIEND: ECS Component Profile

Each FRIEND NPC needs these components at minimum:

Entity: THE_FRIEND_smuggler / THE_FRIEND_detective

Components:
  - NpcIdentity { name, role, home_template, reference_templates[] }
  - Want { current_want, intensity, blocked_by }
  - Secret { content, known_by[], exposure_risk }
  - Relationships[3] { target_entity, valence, trust_level, interaction_count, last_interaction }
  - ToleranceThreshold { current_value, max_value, triggers[] }
  - DailyRoutine { schedule: Map<DayPhase, Location>, deviations[] }
  - InformationInventory { known_facts[], rumors[], secrets_held[] }
  - Contentment { value, trend, causes[] }
  - PersonalityTraits { trait_a, trait_b, trait_c }
  - TellState { active_tells: Map<TellCategory, Intensity> }
  - SkillSet { skills[], combat_trained: bool }
  - AccessTierMap { Map<Entity, AccessTier> }  // per-observer access
  - TriangleMembership { triangle_ids[], role_in_triangle: Map<TriangleId, Role> }
  - MoodState { current_mood, trend, causes[] }

THE FRIEND: Content Requirements

Per FRIEND NPC, Mellanie needs to author:

Content Type Volume Notes
Dialogue lines (all access tiers) 25-35 lines Must cover public, insider, peer, hostile. More lines than any other NPC.
Trust-gated dialogue (surface/real/secret) 15-20 lines Including at least 3 secret-tier lines that reveal the contradiction
Unprompted disclosure lines 5-8 lines Mood-triggered, topic-relevant. THE FRIEND initiates conversation.
Monologue lines (smuggler reacting to FRIEND) 10-15 lines Named references. "There goes Kael." Not "That dock worker."
Monologue lines (detective reacting to FRIEND) 10-15 lines Different framing. Analytical, not personal.
Tell observation monologue 5-8 lines per character "Kael's tapping his foot again." / "Subject displays stress indicators."
Contradiction discovery monologue 3-5 lines per character The moment the player realizes THE FRIEND isn't what they seemed

Total per FRIEND: ~70-100 authored lines (including both character perspectives). This is roughly half the content budget of an entire template's dialogue pool — for one NPC. That's the cost of production-level. It's worth it because this NPC carries D-027 success criterion #3.

THE FRIEND: Mapping to Paula's NPCs

Looking at Paula's Round 1 relationship web:

Character THE FRIEND candidate Why
Smuggler NPC-B (Logistics Worker 1 / Kael Davan) Smuggler's closest colleague. Ring member. Works together daily. Trust + shared risk = deepest pre-existing bond. Contradiction: Kael is reliable to the smuggler, but is cracking under pressure / making mistakes / possibly considering turning.
Detective NPC-D (Dock Inspector) or NPC-G (Security Officer) The detective needs a contact who becomes a relationship. NPC-D has the gambling debt (exploitable, sympathetic). NPC-G has institutional proximity (a peer the detective trusts professionally). Recommendation: NPC-D — the gambling debt creates the contradiction (seems corrupt, might just be desperate) and connects to Triangle B (Card Game Debt).

Paula should confirm these assignments in her Round 2. The FRIEND NPCs are the first profiles she should write at Tier 1 depth.


4. Missing Tickets for Systems/Mechanical Work

I've cross-referenced all Round 1 outputs against the existing ticket pool. Here are the systems tickets that should exist but don't (or need upgrading):

New Tickets Needed

Title Type Priority Rationale Depends On
Dialogue selection pipeline implementation Feature Critical The 4-layer filtering engine: access -> situation -> trust -> weighted(mood, topic). This is the core runtime system that makes content playable. Nothing in the existing tickets covers the actual selection algorithm. Line pool format (this document), NPC component architecture
Monologue trigger system Feature Critical Engine component that fires monologue events based on observation triggers (enter_location, observe_npc, etc.). Must select from character-specific pool, apply prerequisite gates, track variety (no repeats). Perception system (#124), Character knowledge state
NPC mood state machine Feature High NPCs need a mood component that changes based on simulation events (triangle pressure, time of day, recent interactions). Mood drives Layer 4 selection + tell system. 10-axis NPC components
Trust progression system Feature High Engine tracks trust level per player-NPC pair. Progresses through surface -> real -> secret based on interaction quality and frequency. Must be observable (player can sense trust improving). Relationship tracking, dialogue system
Interaction tracking component Feature High Per-NPC-pair counter: interaction_count, last_interaction_time, notable_events log. Drives Layer 2 situation activation. NPC component architecture
Tell state derivation system Feature Medium System that reads NPC axis values (Secret + Tolerance = nervous, Contentment low = frustrated, etc.) and outputs observable tell states consumed by monologue trigger system. 10-axis NPC components, monologue trigger system
Sound event system architecture Feature High Event emitter for sound occurrences. Emits typed events (footsteps, voices, machinery, alarm) with position, intensity, and range. Client renders as audio file OR visual indicator + monologue, depending on available assets. Perception system (#124)
YAML content loader Feature High Rust system that parses content YAML files into indexed, queryable line pools at startup. Must support hot-reload for previewer/authoring workflow. Line pool format (this document)
Line variety tracker Feature Medium Prevents the same line from firing repeatedly. Tracks recently-used line IDs per NPC per session. Selects from eligible pool excluding recent history. Dialogue selection pipeline
Knowledge state component Feature High Per-character component tracking known facts, tagged by source, confidence, and emotional weight. Gates monologue prerequisites and informs situation activation. Paula's KnowledgeInventory proposal. NPC component architecture
Observation event generator Feature Critical System that detects observable NPC behaviors (routine deviation, interaction between NPCs, absence from expected location) and generates events consumed by monologue trigger system. This is the bridge between simulation and player perception. NPC routine system, perception system
Tag taxonomy wiki page Documentation High The converged taxonomy from this document, formatted for the wiki structure Miri is building. Reference document for all content authors. This document, Miri's wiki structure
THE FRIEND: Smuggler's NPC profile Story Critical Full Tier 1 profile for the smuggler's FRIEND (NPC-B / Kael Davan). All 10 axes, voice paragraph, triangle positions, contradiction arc. Dual Lens Guide (#261)
THE FRIEND: Detective's NPC profile Story Critical Full Tier 1 profile for the detective's FRIEND (NPC-D / Dock Inspector). Same depth. Dual Lens Guide (#261)

Existing Tickets That Need Scope Updates

Ticket Current Scope Needed Addition
#90 (Tell system) Unclear Scope to 5 tell categories (nervous, angry, friendly, guarded, routine deviation). Text-via-monologue as v0.1 renderer, not visual animation.
#124 (Sound system) Unclear Must include sound event emitter architecture supporting both audio playback AND visual indicator fallback. See Section 6 below.
#193 (Line previewer) "Authoring tool" Concrete MVP scope defined. See Section 7 below.
#168 (Tag taxonomy) "Agreement needed" This document IS the agreement. Ticket should be updated to reference this converged taxonomy.

5. How Mechanical Systems Support Content Needs

Let me map every content need from Round 1 to a mechanical system. This is the crosswalk that ensures nothing falls through the cracks.

Content Need -> System Mapping

Content Need (from Round 1) Required System Status Gap?
Dialogue lines filtered by access tier Dialogue selection pipeline (Layer 1) Not built YES - needs ticket
Dialogue changes based on relationship history Interaction tracking + situation activation (Layer 2) Not built YES - needs ticket
Trust-gated disclosure Trust progression system (Layer 3) Not built YES - needs ticket
NPCs volunteer information based on mood NPC mood state machine + weighted selection (Layer 4) Not built YES - needs ticket
Monologue fires on observation events Observation event generator + monologue trigger system Not built YES - needs ticket
Separate monologue per character Character-partitioned content pools Not built Covered by YAML loader + character tag
Tells observable through monologue Tell state derivation + monologue integration Not built YES - needs ticket
NPC routine creates observable patterns NPC routine system (D-024 Daily routine axis) Partially ticketed Needs scope for deviations and absence detection
Dual-lens interpretation of same event Per-character monologue pools + knowledge prerequisites Not built Covered by monologue trigger system + prerequisite field
Mirror moments on replay Same trigger, different character pool Architectural Covered by design — separate pools keyed to same triggers
Flat NPCs don't feel flat Routine system + 1 memorable trait + role voice pool Not built Personality trait modifier in dialogue selection
THE FRIEND contradiction arc Triangle pressure + tell escalation + routine deviation Not built Composition of several systems (triangle, tell, routine)
Environmental text readable in world Environmental text rendering in Godot client Not built Needs client-side ticket
News ticker / Meridian feed Ticker content system + time-based rotation Not built Needs ticket for both content + rendering
Audio atmosphere (6-8 files) Sound event system + audio playback Not built YES - see Section 6
Diegetic tutorial via monologue Opening hook monologue + trigger on first-time events Not built Covered by monologue trigger system + first_meeting / first-visit gates

Summary: 17 content needs, 0 fully built, 12 need new tickets, 5 covered by existing ticket scope updates.

The critical path for systems is:

NPC Component Architecture (10 axes)
  |
  +-> NPC Routine System
  |     |
  |     +-> Observation Event Generator
  |           |
  |           +-> Monologue Trigger System
  |
  +-> NPC Mood State Machine
  |     |
  |     +-> Tell State Derivation
  |
  +-> Interaction Tracking
  |     |
  |     +-> Trust Progression
  |
  +-> YAML Content Loader
        |
        +-> Dialogue Selection Pipeline (4 layers)
              |
              +-> Line Variety Tracker

Everything fans out from the NPC component architecture. That's Sprint 1 server work. The YAML loader and dialogue pipeline can be developed in parallel once the component schema is stable.


6. Audio Event System: Minimal Architecture

Jeroen confirmed audio in v0.1: 6-8 AI-generated files. Ozzie's minimum viable list from Round 1:

  1. Station ambient loop (1 file)
  2. Location variants: workplace, bar, corridors (3 files)
  3. Footsteps — walk/run (2 files)
  4. Monologue appearance chime (1 file)
  5. (Optional) UI interaction sound (1 file)

That's 7-8 files. Here's the minimal architecture that supports them while remaining extensible:

Sound Event System Architecture

[Simulation Server]
  SoundEventEmitter
    - emits: SoundEvent { type, position, intensity, range_category }
    - types: Footstep, Voice, Machinery, Alert, Ambient
    - range_category: Close, Medium, Long (D-018)
    |
    v
[ObserverSnapshot]
  sound_events: Vec<SoundEvent>  // only events within perception range
    |
    v
[Godot Client]
  SoundRenderer
    - receives SoundEvents from snapshot
    - looks up audio asset for event type
    - if asset exists: play audio (with distance attenuation + stereo panning)
    - if asset missing: render visual indicator + fire monologue trigger
    |
    +-> AudioAssetRegistry
    |     Maps SoundEvent.type -> audio file path (or null)
    |     v0.1 registry:
    |       Footstep -> footstep_walk.ogg, footstep_run.ogg
    |       Ambient(workplace) -> ambient_workplace.ogg
    |       Ambient(bar) -> ambient_bar.ogg
    |       Ambient(corridor) -> ambient_corridor.ogg
    |       Alert(monologue) -> monologue_chime.ogg
    |       * -> null (visual fallback)
    |
    +-> VisualSoundIndicator
    |     Renders fog-edge ripple/pulse for events without audio
    |     Color-coded per Araminta's spec:
    |       neutral (#c8d0e0), voices (#e8c547), danger (#d45d5d)
    |
    +-> AmbientManager
          Manages location-based ambient loops
          Crossfades between ambient tracks on location transition
          The span gate hum (Miri's suggestion) is the base layer

Key Design Principles

  1. Events first, assets second. The simulation always emits sound events. The client decides how to render them. Zero audio files = everything renders as visual + monologue. 8 files = partial audio with visual fallback for the rest. Full audio suite = rich soundscape. The architecture doesn't change.

  2. The ambient manager is separate from event-driven sounds. Ambient loops play continuously based on location. Sound events are discrete occurrences (footsteps, voices, alerts). These are two different subsystems that share the audio output.

  3. Monologue chime is a UI sound, not a simulation sound. It's triggered by the client when monologue text appears, not by the simulation. It doesn't go through the SoundEvent system.

  4. Distance attenuation is simple for v0.1. Close range = full volume. Medium range = 50% volume + slight muffle. Long range = no direct audio (insert notification only). Three tiers, not continuous falloff.

What This Requires from Implementation

  • Server side: SoundEventEmitter system that checks entity actions each tick and emits typed events. Perception filter includes events within hearing range in ObserverSnapshot.sound_events.
  • Client side: SoundRenderer node in Godot that processes snapshot sound events. AudioAssetRegistry as a simple dictionary. VisualSoundIndicator for fog-edge rendering. AmbientManager for location loops.
  • Asset pipeline: 7-8 .ogg files, generated or sourced. Integrated into Godot project's audio resources.

This is a small architecture for a large capability surface. It handles v0.1's 8 files and scales to hundreds without structural changes.


7. Line Previewer (#193): Concrete MVP Scope

The line previewer was flagged by me, Mellanie, and Ozzie in Round 1 as critical. Let me scope the MVP concretely.

What the Previewer Does

The previewer answers one question: "Given this NPC state and this player state, what line fires?"

It's the authoring equivalent of a compiler — it tells the content author whether their tags produce the intended behavior before the line is integrated into the game.

MVP Feature Set

Feature Description Priority
Load YAML Parse a content YAML file (dialogue or monologue) into indexed pool Must have
Set filter context CLI arguments or interactive prompts for: access tier, trust level, active situations, NPC mood, topic filter, character (for monologue) Must have
Show matching lines Display all lines that pass the 4-layer filter with the given context Must have
Show selected line Apply weighted selection to show which single line would fire Must have
Explain selection Show WHY each line was included/excluded (which filter passed/failed) Must have
Sequence mode Play N lines in order simulating a walk-through (Ozzie's "preview sequence" request) Should have
Coverage report Show which access/trust/situation combinations have zero eligible lines (dead conversation detection) Should have
Hot reload Watch YAML file for changes, re-run filter on save Nice to have
Batch validation Run all YAML files through a consistency checker (missing required tags, invalid enum values, duplicate IDs) Should have

Implementation

Language: Rust. The previewer should use the same YAML parser and selection logic that the game server will use. This means the previewer IS a test harness for the dialogue pipeline — if the previewer selects correctly, the game will select correctly.

Interface: CLI. No GUI needed. Terminal output with color-coded pass/fail on filters.

# Show what the detective hears from a dock_worker at insider access, surface trust,
# morning routine, neutral mood
$ cargo run --bin previewer -- \
    --file content/templates/logistics-hub/dialogue.yaml \
    --role dock_worker \
    --access authority \
    --trust surface \
    --situation greeting,morning,routine \
    --mood neutral \
    --verbose

[PASS] access=authority  [PASS] trust=surface  [PASS] situation=greeting
  -> lh_d_002: "You're new around here? Or just... visiting?"
     topic=[social, identity]  mood=[cautious, neutral]  weight=0.85

[PASS] access=authority  [PASS] trust=surface  [FAIL] situation=first_meeting (requires interaction_count==0)
  -> lh_d_005: "Morning. Can I help you with something?"
     (excluded: situation mismatch)

Selected: lh_d_002 (weight: 0.85, variety_penalty: 0.0)

Sequence Mode (Ozzie's Request)

$ cargo run --bin previewer -- \
    --file content/templates/bar/monologue.yaml \
    --character smuggler \
    --sequence enter_bar \
    --mood neutral

[Sequence: enter_bar — smuggler]
1. (enter_location) "The Last Shift. Lera's already got my usual poured."
2. (observe_npc) "Kael's at the corner booth. He looks rough tonight."
3. (observe_npc) "Drin's telling the same story again. Third time this week."
4. (time_idle) "Should probably check in with Kael. He doesn't usually drink alone."

This gives Mellanie and Ozzie a way to "feel" the content flow without running the full game. It's the emotional smoke test.

Effort Estimate

The previewer shares 80% of its code with the dialogue pipeline implementation. Building it first means the pipeline is already tested when it's integrated into the server. The unique work is the CLI interface, the verbose explain mode, and the sequence playback — maybe 2-3 days of Dudley/Tyre's time on top of the pipeline work they'd do anyway.

Recommendation: Build the previewer AS the first implementation of the dialogue pipeline. Don't build them separately. The previewer is the pipeline running in standalone mode with verbose output.


8. Cross-Agent Synthesis: Convergence Map

Here's where every Round 1 contributor's proposals landed after synthesis:

Fully Aligned (no further discussion needed)

Topic Status Contributors Aligned
Separate monologue pools per character Locked (Jeroen directive) All
Color = relationship to player Locked (Jeroen directive) Araminta (proposed), Gestalt (endorsed)
YAML as authoring format Aligned Gestalt (proposed), Mellanie (accepted with conditions)
5 tell categories for v0.1 Aligned Gestalt (proposed), Araminta (visual notes), Ozzie (emotional validation)
Diegetic tutorial via monologue Aligned Gestalt (mechanical), Mellanie (content), Paula (narrative)
30/50/20 entanglement ratio Aligned (D-029 confirmed) All
Monologue is v0.1 tell renderer Aligned Gestalt, Araminta, Mellanie

Converged in This Document

Topic Resolution Key Decision
Tag taxonomy Converged 8-tag system (6 structural + 2 selection + freeform) See Section 1
Situation taxonomy 13 situations from Gestalt + Mellanie merge See Section 1
Access tier model list<enum> with 5 values Gestalt's model, Paula's content, aligned
Line pool file structure Directory = template/location, file = content type Dropped per-line location and type tags
THE FRIEND mechanical spec Full pipeline depth test with ~70-100 authored lines per NPC See Section 3
Audio architecture Event-driven with asset registry + visual fallback See Section 6
Line previewer MVP Rust CLI sharing pipeline code, 7 must-have features See Section 7

Needs Round 2 Confirmation from Others

Topic Who Needs to Confirm What I Need
Converged tag taxonomy Mellanie Can you author with 6+3 tags per line? Is the mood/topic consolidation workable?
Converged tag taxonomy Paula Does the Layer 2 approach (engine-state-to-situation mapping, not per-line relationship tags) satisfy your 4-layer requirements?
THE FRIEND NPC assignments Paula Confirm NPC-B (Kael) for smuggler, NPC-D for detective. Or propose alternatives.
Miri's setting tags Miri Your proposed lattice_tier, shift_phase, district_familiarity, institutional_context — these should be engine-state context, not per-line tags. The engine knows the player is a newcomer; it activates first_meeting situations. Do you agree?
Spatial layout timing Araminta Your spatial layouts are needed before or in parallel with content packs. Confirmed? Can they be done independently of content?
Audio asset creation Ozzie 7-8 AI-generated files. Who generates them? What's the quality bar? Do we need a ticket for audio asset generation?

9. Emergent Interactions: Where Systems Collide

This is my favorite part. Let me map the places where independently designed systems will interact to produce emergent gameplay — the stuff nobody scripted.

Interaction Map

System A System B Emergent Result
NPC Routine + Observation Events Player sees NPC in unexpected place at unexpected time Monologue fires: "That's not where they usually go." Player decides to follow or ignore. Neither designer planned the specific moment.
Trust Progression + Triangle Pressure NPC's trust in player increases while triangle pressure increases NPC discloses something they shouldn't under pressure. The disclosure is selected by the dialogue pipeline combining high trust + high stress mood. Not scripted — emergent from system state.
Access Tier Shift + Monologue Dual-Lens Player's access tier changes at a social site (e.g., detective becomes a bar regular) New dialogue lines become available AND the monologue reflects the shift ("They're starting to warm up to me"). The player FEELS the social change through two channels simultaneously.
Sound Events + Fog of Perception + Monologue Player hears voices through a wall they can't see past Sound event at fog edge -> visual indicator -> monologue interprets ("Sounds like an argument. Can't make out the words.") Player decides to move closer or not. The three systems produce a decision point.
THE FRIEND Contradiction + Tell System + Monologue THE FRIEND's tell state escalates (nervous) while their dialogue stays friendly The player gets conflicting signals: dialogue says "everything's fine," monologue says "they keep checking the door." The player must decide which signal to trust. Asymmetric information within a single NPC.
NPC Mood + Time Phase + Unprompted Disclosure An NPC's mood worsens over the course of a day; by evening at the bar, they're drunk and frustrated Layer 4 selects from mood: [annoyed, tired] + trust: real pool. The NPC says something they wouldn't have said that morning. Time + mood + alcohol = emergent information leak.

This is why systems-first design works. None of these moments are scripted events. They're collisions between independently designed systems operating on shared state. The content authors write the individual lines; the systems decide when and how those lines combine. The result is stories the designers didn't anticipate.


10. Open Questions for Round 3 / Sprint Planning

Question Owner Context
Does the 4x generation expansion apply to THE FRIEND's custom lines? Or are all 70-100 hand-authored? Mellanie + Gestalt Generation expansion on high-specificity NPC lines risks losing the hand-crafted voice. Recommend: no expansion on FRIEND lines. Every line hand-authored.
Who creates the 7-8 audio files? Ozzie + Justine AI-generated is confirmed, but the pipeline needs defining. Which AI tool? What format? Who evaluates quality?
Should the line previewer be a sprint deliverable or a tooling side-project? Tyre + Dudley I recommend sprint deliverable — it's the dialogue pipeline in standalone mode. Building it IS building the pipeline.
How does the knowledge prerequisite system handle "partial knowledge"? Gestalt + Paula A monologue line gated on knows: smuggling_operation — does the player need to know the full operation, or just that something suspicious is happening? Need a knowledge hierarchy: suspects < knows_of < knows_details.
Triangle pressure threshold — what triggers escalation? Gestalt + Paula Triangles need a numeric pressure value that increases based on events. When it crosses a threshold, confrontation situation activates. Need to define the events that increase pressure.

Gestalt out. The taxonomy is converged. The FRIEND is specified. The audio architecture is minimal and extensible. The previewer is scoped. Now we need Mellanie and Paula to validate the tag schema, and Dudley to start building the NPC component architecture. The systems are ready to support the content. Let's build.