Files
settled-reach/wiki/authoring/monologue-guide.md
T
jpmschweitzerandClaude Opus 4.7 25eb8bd096 content(wiki): purge v0.1 Sova/Van Maanen residue (#865)
Spring-cleaning accumulated v0.1 vertical-slice residue across the
wiki. Scope per Jeroen's pre-decisions on 2026-04-21:

- Delete outright: wiki/star-systems/GJ-35/sova/ subtree (5 files +
  2 dirs) — v0.1 Station Sova / Transit District content.
- Strip example blocks in authoring guides and _templates/ that
  cited dropped v0.1 NPCs (Kael Davan, Sera Venn, Nils Davan, Devra,
  Torek, Renn, Pell, Tav, Lera Sessik, Sabel). Replaced with short
  "v0.1 examples removed — D-122" notes pointing authors to the
  active NPC roster.
- Rewrite canonical-lore references file-by-file: faction pages,
  technology pages, contraband pages, concepts pages, corp pages
  that cited v0.1 names/places. Preserve institutional/structural
  content, drop specific-name citations.
- Commission name drift: replace "Concord Commission" and "Assembly
  Commission" with "the Lattice Commission" (D-193) throughout.
- Van Maanen's Star cultural references: the canonical in-game name
  is Vuurkloof. "Van Maanen's Star" is retained only as an
  astronomical designation (glossary + GJ-35 Calibration Note).
  All cultural/system references converted to Vuurkloof across
  culture-authoring-guide, cultural-generation-guide, founder-gates,
  and star-system adjacent-system descriptions.
- Strip `v0.1` from faction/triangle frontmatter tags (8 files).
- wiki/triangles/hub-power.md and wiki/factions/the-ring.md:
  rewritten using role-name exemplars (Ring Coordinator / Shift
  Supervisor / THE FRIEND) instead of named v0.1 NPCs. Triangle
  pattern preserved as a structural reference.

Also applies drive-by Commission drift fixes and minor cross-ref
updates to canonical corps (gate-corporation, mastroianni-vehicle-group,
stalownia-kowalski, prometheus-labs, ferreira-monteiro, vins-de-grand-vide,
and 13 others).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:26:45 +02:00

30 KiB

title, description, slug, category, status, created, updated, tags, decision_refs, cross_refs
title description slug category status created updated tags decision_refs cross_refs
Monologue Authoring Guide How to write tagged monologue and dialogue content — tag taxonomy, prerequisite format, situation overlap rules, and voice discipline monologue-guide authoring-guide canonical 2026-02-12 2026-02-13
D-032
D-035

Monologue and Dialogue Authoring Guide

How to write tagged monologue and dialogue content for The Settled Reach. Read the knowledge system docs first — this guide assumes you know what a FactId is and how RelationshipState works.

Prerequisites:

Canonical sources: D-028 (dialogue architecture), D-032 (separate monologue pools), D-035 (tag taxonomy)


Location Shortcodes

Location shortcodes are defined per district. Used in line IDs ({shortcode}_{type}_{###}) and file naming. Author per-district shortcode tables in the district wiki entry.

Shortcode Location Type Notes
terminal Primary workplace (logistics hub, factory floor, etc.) Assign per district
bar Social venue (bar, canteen, commons) Assign per district
corridor Service / restricted spaces Assign per district

File naming convention: {shortcode}-{character}.yaml (e.g., terminal-smuggler.yaml, bar-detective.yaml)

Line ID format: {shortcode}_{d|m|e}_{###} where d=dialogue, m=monologue, e=environmental


Situation Overlap Rules

A line can have multiple situations in its situation list. These rules define valid combinations.

Mutually exclusive (never co-occur):

  • arrival and shift_end — you can't be both arriving and leaving
  • alone and social — by definition
  • emergency and routine — emergency overrides routine
  • confrontation and social — confrontation replaces social context

Common valid overlaps:

  • shift_start + routine — beginning-of-shift routine observations
  • bar_evening + social — social interaction at the bar
  • observation + any non-exclusive situation — observation layers on top of context
  • investigation + observation — investigating by watching

Default if empty: routine (engine assumes routine context)


Mood Exclusivity Rules

A line can have multiple moods, but some combinations are contradictory.

Mutually exclusive (never co-occur):

  • fond and suspicious — these are opposing orientations toward someone
  • comfortable and worried — opposing emotional states
  • relieved and concerned — resolved vs. unresolved tension

Common valid overlaps:

  • analytical + any mood — analytical is a cognitive mode that coexists with emotion
  • conflicted + fond or concerned — conflicted implies mixed feelings
  • worried + suspicious — worry about someone's behavior shading into suspicion

Default if empty: comfortable (engine assumes neutral emotional baseline)


Core Principle

Internal monologue is hard-partitioned by playable character (D-032). The smuggler and detective have completely separate monologue pools. No shared lines. Same trigger, different pool. This is how mirror moments work without either pool knowing about the other.

Dialogue lines are shared — NPCs say the same words regardless of who's listening. The access tier system filters which lines each character can hear at runtime.


D-035 Tag Taxonomy Reference

Every line carries structural tags, selection tags, and (for monologue) character-specific tags. Here's the full schema.

Structural Tags (required on every dialogue line)

Tag Type Purpose
id string {location}_{d|m|e}_{###} — stable, machine-parseable
text string The authored line
role enum Template-defined role, not NPC name (NPC assignment is runtime)
access list<enum> Hard filter: public, insider, authority, peer, hostile
trust enum Hard filter: surface, real, secret
situation list<enum> Context filter (13 situations)
Tag Type Purpose
topic list<enum> Weighted selection (9 topics)
mood list<enum> Weighted selection (8 moods)
tags list<string> Freeform escape hatch for author intent

Monologue-Specific Tags (added to structural + selection)

Tag Type Purpose
character enum smuggler or detective — hard partition (D-032)
trigger enum What fires this line (9 types — see next section)
prerequisite map or null Knowledge state gate

Authoring-Only Tags (not consumed by engine)

Tag Type Purpose
dual_lens map Per-character notes on how the line reads differently
notes string Author intent, context for future editors

Enum Values

situation (13): arrival, shift_start, shift_end, shift_transition, bar_evening, night_shift, investigation, confrontation, social, alone, emergency, routine, observation

topic (9): colleague, routine, cargo, money, trust, danger, institution, personal, investigation

Note: no crime or smuggling topic. NPCs think of it as cargo or money. The detective uses investigation.

mood (8): fond, comfortable, worried, suspicious, analytical, conflicted, concerned, relieved


Monologue Trigger Types (9)

The trigger tag determines WHEN a monologue line fires. Each type maps to a game event.

1. enter_location

Fires when the player enters a named area.

- id: terminal_m_010
  text: "Morning shift. Recycled air and cargo lubricant. Home sweet home."
  character: smuggler
  trigger: enter_location
  situation: [arrival]
  mood: [comfortable]
  prerequisite: null
- id: terminal_m_011
  text: "Logistics hub. Standard prefab, heavy foot traffic. Let's see what the shift change tells me."
  character: detective
  trigger: enter_location
  situation: [arrival]
  mood: [analytical]
  prerequisite: null

Mirror moment: Same entry, different register. Smuggler sees home; detective sees a crime scene.

Use for first impressions, atmosphere, returning-to-familiar-ground observations. Keep short — the player is moving.


2. observe_npc

Fires when a known entity enters the player's line of sight.

- id: terminal_m_020
  text: "{THE FRIEND}'s here. Good — I was starting to worry."
  character: smuggler
  trigger: observe_npc
  mood: [fond]
  prerequisite:
    relationship_state: Friendly
    subject: {friend_npc_slug}
- id: terminal_m_021
  text: "Dock worker from the case file. {Surname}, {initial}. Unremarkable on paper."
  character: detective
  trigger: observe_npc
  mood: [analytical]
  prerequisite:
    fact: investigation.manifest_discrepancy
    confidence: Suspects

Use for identification, behavioral observations, emotional reactions. The prerequisite controls which version fires — same NPC, different line depending on knowledge.


3. hear_sound

Fires on audio events — ambient, diegetic, or anomalous.

- id: bar_m_030
  text: "Raised voices from the back room. That's not a routine call."
  character: smuggler
  trigger: hear_sound
  mood: [concerned]
  prerequisite:
    fact: contraband.ring_exists
    confidence: KnowsDetails
- id: bar_m_031
  text: "Arguing behind that door. The bartender didn't flinch. Either she's used to it or she knows what it is."
  character: detective
  trigger: hear_sound
  mood: [suspicious]
  prerequisite: null

Audio triggers fire less frequently than visual ones. Make them count.


4. observe_anomaly

Fires when the player observes something that contradicts expected state — a container in the wrong place, an NPC where they shouldn't be, a door that should be locked.

- id: terminal_m_040
  text: "{THE FRIEND}'s checking their lattice again. Third time in ten minutes. That's not normal."
  character: smuggler
  trigger: observe_anomaly
  mood: [worried]
  prerequisite:
    relationship_state: Friendly
    subject: {friend_npc_slug}
- id: terminal_m_041
  text: "Dock worker {Surname} — lattice activity spiked. Expecting a message? Or checking for surveillance?"
  character: detective
  trigger: observe_anomaly
  mood: [analytical]
  prerequisite:
    known_attributes:
      subject: {friend_npc_slug}
      key: behavior_flags
      value_contains: lattice_checking

This is the detective's bread and butter: the gap between expected and observed.


5. post_conversation

Fires after a dialogue exchange ends. Internal reaction to what just happened.

- id: bar_m_050
  text: "{THE FRIEND}'s good to have around. Knows the district, knows the people. Reliable."
  character: detective
  trigger: post_conversation
  mood: [fond]
  prerequisite:
    relationship_state: Friendly
    subject: {friend_npc_slug}
- id: bar_m_051
  text: "Not lying. But not telling me everything. {THE FRIEND}, what do you know?"
  character: detective
  trigger: post_conversation
  mood: [conflicted]
  prerequisite:
    relationship_state: PersonOfInterest
    subject: {friend_npc_slug}

This is where character voice shines — the detective analyzes, the smuggler worries about people.


6. discover_evidence

Fires when the player finds physical evidence — a document, object, or data point.

- id: terminal_m_060
  text: "Container 4471. Manifest says 240 kilos. That crate is closer to 310."
  character: detective
  trigger: discover_evidence
  mood: [analytical]
  prerequisite:
    fact: investigation.manifest_discrepancy
    confidence: Suspects
- id: terminal_m_061
  text: "4471's still in temp. Routed there during transition. Standard. Nothing to worry about."
  character: smuggler
  trigger: discover_evidence
  mood: [relieved]
  prerequisite:
    fact: contraband.ring_exists
    confidence: KnowsDetails

Brief, observational. The fact system handles what the player now knows — the monologue handles what they feel about it.


7. witness_interaction

Fires when the player observes two NPCs interacting.

- id: bar_m_070
  text: "{THE FRIEND}'s headed out. Smart — {NPC} gets loud after three drinks. Nobody wants to deal with that."
  character: smuggler
  trigger: witness_interaction
  mood: [comfortable]
  prerequisite: null
- id: bar_m_071
  text: "That's twice now. {THE FRIEND} leaves when {NPC} arrives. Coincidence? Filing it."
  character: detective
  trigger: witness_interaction
  mood: [analytical]
  prerequisite:
    known_attributes:
      subject: {friend_npc_slug}
      key: behavior_flags
      value_contains: avoidance_pattern

Mirror moment: Same event. Smuggler has the innocent explanation. Detective has the investigative read. On replay: "Wait — WAS it just the noise?"


8. time_idle

Fires after inactivity — the player is standing still, watching, waiting. The character's mind wanders.

- id: corr_m_080
  text: "Quiet tonight. Good. Nobody using the south access."
  character: smuggler
  trigger: time_idle
  mood: [relieved]
  prerequisite:
    fact: location.restricted_corridor
    confidence: KnowsDetails
- id: corr_m_081
  text: "This corridor should see foot traffic during shift change. It's empty. Why?"
  character: detective
  trigger: time_idle
  mood: [suspicious]
  prerequisite:
    fact: location.restricted_corridor
    confidence: Suspects

Idle lines reveal what the character cares about when nothing demands attention. The smuggler thinks about the operation; the detective thinks about the case.


9. return_visit

Fires when the player returns to a location they've visited before. Distinct from enter_location — gates on prior visit history.

- id: bar_m_090
  text: "Back at the bar. Same seats, same faces. {THE FRIEND}'s in the corner booth. Good."
  character: detective
  trigger: return_visit
  mood: [comfortable]
  prerequisite:
    relationship_state: Friendly
    subject: {friend_npc_slug}
- id: bar_m_091
  text: "Back again. Same booth. ...Let's see if {THE FRIEND} leaves when {NPC} shows up."
  character: detective
  trigger: return_visit
  mood: [suspicious]
  prerequisite:
    known_attributes:
      subject: {friend_npc_slug}
      key: behavior_flags
      value_contains: avoidance_pattern

Return visits build investigation momentum. This is where the detective's pattern recognition fires.


YAML Prerequisite Format

Prerequisites gate monologue lines on knowledge state. A line only fires if the player's knowledge meets the conditions.

No prerequisite (always eligible)

prerequisite: null

Still filtered by trigger type, character, and location. Use for baseline observations that don't depend on knowledge.

Gating on FactId + confidence

prerequisite:
  fact: contraband.ring_exists
  confidence: KnowsOf

Fires only if the active character knows the named fact at the specified confidence or higher. Confidence levels ordered: Suspects < KnowsOf < KnowsDetails < Direct.

Use exact FactId strings from the Fact Catalog"contraband.ring_exists" not "Ring Exists". The 24 canonical FactIds are the only valid values.

Gating on RelationshipState

prerequisite:
  relationship_state: PersonOfInterest
  subject: {npc_slug}

Fires only if the active character's relationship with the named entity is the specified state. States: Unknown, Known, Friendly, PersonOfInterest, Hostile.

Gating on EntityKnowledge attributes

Exact match:

prerequisite:
  known_attributes:
    subject: {npc_slug}
    key: contradiction_flagged
    value: meeting_unknown_contact

Fires if the active character's EntityKnowledge for the target has the exact key-value pair.

Partial match (for comma-separated fields like behavior_flags):

prerequisite:
  known_attributes:
    subject: {npc_slug}
    key: behavior_flags
    value_contains: lattice_checking

Matches if behavior_flags contains lattice_checking anywhere in the comma-separated list.

Compound prerequisites

Combine conditions with all (AND) or any (OR):

prerequisite:
  all:
    - fact: contraband.ring_exists
      confidence: KnowsDetails
    - relationship_state: Friendly
      subject: {friend_npc_slug}
    - known_attributes:
        subject: {friend_npc_slug}
        key: behavior_flags
        value_contains: lattice_checking

All three must be true. Swap all for any for OR logic.

Keep compound prerequisites to 2-3 conditions. If you need more, the line is too narrowly targeted — split it.

Character-specific gating

The character tag on monologue lines is already a hard partition. You don't need to gate on character inside prerequisite. But some facts are character-specific in practice:

# Detective-only fact — smuggler never reaches this
prerequisite:
  fact: investigation.evidence_collected
  confidence: KnowsOf
# Both characters can reach this, but from different starting points
prerequisite:
  fact: contraband.ring_exists
  confidence: KnowsOf
  # Smuggler starts here. Detective earns it through investigation.

Access Tier Mapping

The access tag on dialogue lines determines who can hear what. Access is derived from RelationshipState plus character type (smuggler/detective).

RelationshipState to dialogue access

access tag Unknown Known Friendly PersonOfInterest Hostile
public yes yes yes yes yes
peer -- yes yes -- --
insider -- -- yes -- --
authority detective detective -- detective --
hostile -- -- -- -- yes

Key rules:

  • public: Anyone can hear it. Greetings, small talk, general information.
  • peer: Requires Known or Friendly. Coworker talk, casual gossip. Locks out at PersonOfInterest — when trust breaks, peers stop sharing.
  • insider: Requires Friendly only. Ring operations talk, close confidences. The content that vanishes when THE FRIEND turns amber.
  • authority: Detective-only, works at Unknown, Known, and PersonOfInterest. Institutional leverage. Doesn't work on Friendly (too personal) or Hostile (they've stopped cooperating).
  • hostile: Only at Hostile. Threats, demands, final warnings.

What this means for THE FRIEND

When THE FRIEND (smuggler's) transitions from Friendly to PersonOfInterest:

  • insider lines disappear. Ring talk stops. Trust-gated confidences lock.
  • peer lines disappear. Casual warmth dries up. THE FRIEND becomes guarded.
  • public lines remain. THE FRIEND still greets the smuggler — but the warmth is gone.

When THE FRIEND (detective's) transitions from Friendly to PersonOfInterest:

  • insider lines disappear. Institutional background sharing stops.
  • peer lines disappear. Bar conversation becomes stilted.
  • authority lines unlock for the detective. Pressing questions become available.

This is the mechanical expression of the emotional arc. The content doesn't change — the filter changes. Lines that existed before are now locked. That absence IS the narrative.

Trust sublayers

Within each access tier, trust further filters content:

trust What it gates
surface Safe topics, social norms, what anyone would say
real Honest opinions, unguarded speech, actual feelings
secret Dangerous knowledge, confessions, things that create leverage

Trust is orthogonal to access. A peer + surface line is casual coworker talk. A peer + real line is a coworker dropping the mask. A peer + secret line is a coworker confessing something risky.

Per-NPC access mapping

v0.1 named-NPC access table removed — cited NPCs no longer in v0.2 pipeline (D-122). Author per-district access mapping tables against the active NPC roster. Pattern for the standard cast:

NPC Role Smuggler Access Detective Access
THE FRIEND (smuggler's) insider, peer publicauthority (after flagging)
THE FRIEND (detective's) public (Commission, wary) peerauthority (post-contradiction)
Supervisor insider (colleague) authority
Bar owner insider (bar regular) publicpeer (repeat visits)
MIRROR NPC peer (through FRIEND) publicpeer (through FRIEND B)
Ring-adjacent NPC insider or peer public
Hub scheduler insider (hub colleague) authority
Compromised inspector insider (hub colleague) authority

Tell Observation Format

Tells are behavioral signals that update EntityKnowledge.known_attributes. When observed, two things happen: the attribute updates in the knowledge graph, and a monologue line fires.

Structure

A tell observation monologue line should:

  1. Name the behavior — what the player sees
  2. Interpret through character lens — what it means to THIS character
  3. Map to an attribute — note in notes which known_attributes key updates
- id: terminal_m_100
  text: "{THE FRIEND} keeps checking their lattice. Waiting for something."
  character: smuggler
  trigger: observe_anomaly
  mood: [concerned]
  topic: [colleague]
  prerequisite:
    relationship_state: Friendly
    subject: {friend_npc_slug}
  notes: "First tell. Updates behavior_flags: lattice_checking. Smuggler notices but doesn't flag yet."
- id: terminal_m_101
  text: "Dock worker {Surname} — lattice activity spiked. Three pings in two minutes. Expecting a message? Or checking for surveillance?"
  character: detective
  trigger: observe_anomaly
  mood: [analytical]
  topic: [investigation]
  prerequisite:
    relationship_state: Known
    subject: {friend_npc_slug}
  notes: "Same tell, different read. Updates behavior_flags: lattice_checking."

Tell progression

Tells accumulate. Write them as a sequence, each gated on increasing knowledge:

Tell 1 — first observation (no prior flags):

prerequisite:
  relationship_state: Friendly
  subject: {friend_npc_slug}
  # No behavior_flags gate — this IS the first observation

Tell 2 — pattern forming (first flag set):

prerequisite:
  known_attributes:
    subject: {friend_npc_slug}
    key: behavior_flags
    value_contains: lattice_checking
  # Requires tell 1 to have fired and set the attribute

Tell 3 — conclusion (multiple flags):

prerequisite:
  all:
    - known_attributes:
        subject: {friend_npc_slug}
        key: behavior_flags
        value_contains: lattice_checking
    - known_attributes:
        subject: {friend_npc_slug}
        key: behavior_flags
        value_contains: evasive

Each tell should feel like a natural observation, not a checklist. The player doesn't know they're accumulating evidence.

Canonical tell attributes

Attribute key What it captures Example values
behavior_flags Comma-separated observations "nervous,lattice_checking", "avoidance_pattern,evasive"
tell_observed Specific personal tell "looks_left_when_lying", "leaves_when_torek_arrives"
contradiction_flagged THE FRIEND arc trigger "meeting_unknown_contact", "avoidance_inconsistency"
secret_held What observer believes target hides "ring membership", "unreported evidence"
secret_confidence Certainty level "suspected", "likely", "confirmed"

THE FRIEND tell arcs

Tell arcs are authored per district against the active NPC roster — v0.1 named examples removed (D-122). The pattern structure:

THE FRIEND A (smuggler observes):

Phase Tell Behavior flag Line tone
First crack Increased lattice checking lattice_checking Concern: "Distracted today."
Pattern Shortened conversations, evasive distracted,evasive Worry: "Been quiet lately."
Contradiction Unauthorized spatial presence contradiction_flagged: meeting_unknown_contact Alarm: "That wasn't anyone from our rotation."
Confirmation Personal tell fires under pressure tell_observed: {specific_tell} Hurt: "That tell. I know that tell. They're lying to me."

THE FRIEND B (detective observes):

Phase Tell Behavior flag Line tone
First departure Leaves when ring-adjacent NPC arrives (once) avoidance_pattern (begins) Barely noticed: "Headed out. Long day."
Second departure Different excuse, same trigger avoidance_pattern (accumulating) Noted: "Left again. Tired lately."
Third departure Pattern confirmed contradiction_flagged: avoidance_inconsistency Analytical: "Three times. Three excuses. That's data."
Deflection Controlled redirect when asked tell_observed: controlled_deflection Conflicted: "Not lying. But not telling me everything."

Voice Discipline: Writing for Dual-Lens

Every NPC line must work for both character perspectives. Same words, different meaning.

The rule

Monologue pools are separate (D-032). But dialogue is shared — the NPC says the same thing to both characters. The access tier filters which lines each character can hear, but public and peer lines reach both. When an NPC speaks, the words must land differently depending on who's listening.

How to write dual-lens lines

Step 1: Write the line. Concrete, in the speaker's voice. The NPC doesn't know who's listening.

- id: hub_d_044
  role: dock_worker
  text: "Container 4471 sat in temp storage overnight. Scheduling backed up again."
  access: [public, peer]
  trust: surface
  situation: [shift_start]

Step 2: Check both readings. Document the split.

  dual_lens:
    smuggler: "Operational context — part of the ring pipeline. 'Backed up' is cover language."
    detective: "Anomaly — overnight exceeds standard procedure. Flag for investigation."

Step 3: Verify neither reading breaks. If it only works for one character, use a different access tier or rely on character-specific monologue to recontextualize.

Dual-lens patterns

Innocuous surface / operational subtext:

"{Supervisor} adjusted the night shift again. Two workers short."

  • Smuggler: coverage gap for tonight's run
  • Detective: scheduling irregularity worth tracking

Social warmth / threat assessment:

"{THE FRIEND} left early. Headache, they said."

  • Detective: pattern forming — third time when {NPC} is here
  • Smuggler: Commission person leaving, less oversight

Emotional resonance / clinical data:

"{THE FRIEND}'s been quiet lately. Not like them."

  • Smuggler: concern for a friend
  • Detective: behavioral change in a subject

Casual disclosure / institutional intelligence:

"I ran the usual calibration checks today."

  • Detective: routine work, mundane
  • Smuggler: Commission is still active in the district

What to avoid

  • One-character lines in shared pools. If only the smuggler gets it, it needs insider access, not public.
  • Telegraphing. "I'm definitely not doing anything illegal" — nobody talks like that.
  • Breaking NPC voice for the lens. The NPC doesn't know who's listening. They talk like themselves.
  • Over-explaining. If you need a paragraph of dual_lens notes to explain the split, the line isn't doing its job. The best dual-lens lines work on surface for one character and subtext for the other.

Concrete Examples: Full Tagged Pools

v0.1 named-NPC pool examples removed — cited NPCs no longer in v0.2 pipeline (D-122). Author per-district pools against the active NPC roster using the tag schema and trigger types documented above.

Structure reference (three pools per district):

content/{district}/
  {terminal-slug}/
    monologue-smuggler.yaml   # Smuggler's FRIEND arc + operational lines
    monologue-detective.yaml  # Detective's investigation lines
    dialogue.yaml             # Shared NPC dialogue (access-tier filtered at runtime)
  {bar-slug}/
    monologue-smuggler.yaml
    monologue-detective.yaml
    dialogue.yaml
  {corridor-slug}/
    monologue-smuggler.yaml   # Route operational + THE CONTRADICTION scene
    monologue-detective.yaml
    dialogue.yaml

Required content per location per character:

  • Arrival / enter_location (2-3 lines, baseline + investigation variant)
  • THE FRIEND arc phases 1-5 (smuggler: Phase 1-5 for FRIEND A; detective: Phase 1-5 for FRIEND B)
  • Operational / investigative observations (3-5 lines per location)
  • Return visit variants (1-2 lines per location)
  • Atmospheric time_idle lines (1-2 per location)

File Naming and Directory Structure

Content is organized by location and character. Location is implicit from directory — don't duplicate it in per-line tags.

content/
  terminal/
    monologue-smuggler.yaml
    monologue-detective.yaml
    dialogue.yaml
  bar/
    monologue-smuggler.yaml
    monologue-detective.yaml
    dialogue.yaml
  corridor/
    monologue-smuggler.yaml
    monologue-detective.yaml
    dialogue.yaml

Monologue files are hard-partitioned by character (D-032). One file per character per location. Dialogue files are shared — access-tier filtering happens at runtime.

ID Convention

{location}_{type}_{###}

  • location: terminal, bar, corridor (or hub, corr as shorthand)
  • type: m (monologue), d (dialogue), e (environmental)
  • number: Sequential per file, starting at 001

Authoring Checklist

Before submitting a line:

  1. Who is speaking? Monologue: which character? Dialogue: which role?
  2. What do they know? Does the prerequisite reference a real FactId, RelationshipState, or attribute key from the catalogs?
  3. What triggers it? One of 9 types. Does the trigger match the game moment?
  4. Dual-lens check. If dialogue, does it read differently for smuggler vs detective? Document in dual_lens.
  5. Brevity. Monologue competes with gameplay. If it's longer than one breath, cut it.
  6. Voice. Does it sound like the character? The detective analyzes. The smuggler worries about people. NPCs talk like themselves, not like game designers.
  7. Show don't tell. "The lock's been forced" not "Someone has broken into this room."
  8. Access tier. Is the line available to the right people? Does PersonOfInterest correctly lock out trust content?

Cross-References:

If this guide contradicts a decision file, the decision file wins.