Long-term content strategy workshop: 300-world generator model, cultural ingredients menu, three-system NPC architecture (9 patterns x 6 motivations), Sacred/Profane/Middle Kingdom framework. 9 agents across 4 rounds plus lead interview establishing the production path from hand-authored Sova to generated 300 worlds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
27 KiB
Round 1 — Gestalt (Systems Design)
cracks knuckles
Alright. Four topics, all load-bearing. Let me break down what each one actually means mechanically.
Topic 1: Triangle Analysis — Do They Create Interesting Decisions?
I'm going to evaluate all 5 triangles on three axes: player agency (does the player choose?), information asymmetry (do the two characters see different things?), and system interaction (does this triangle exercise multiple game systems?).
Evaluation Table
| Triangle | Player Agency (Smuggler) | Player Agency (Detective) | Info Asymmetry | Systems Exercised | Verdict |
|---|---|---|---|---|---|
| T1: Hub Power (Voss-Kael-Nils) | Low — observe/mediate, mostly reactive | Low — sees Voss's anxiety, one thread | Medium — smuggler knows hierarchy, detective sees stress | Schedule, authority dynamics | Weakest |
| T2: Worried Knowledge (Maret-Drin-Voss) | Medium — manage risks (two aware NPCs) | High — two witness paths (cooperative vs turned) | High — smuggler knows who's compromised, detective doesn't | Investigation, tells, knowledge gating | Strong |
| T3: Bar Tensions (Lera-Torek-Olin) | Medium — address Torek's visibility, assess Olin | Medium — financial tell + ambiguous newcomer | High — spending could be ring OR mundane, player doesn't know | Financial observation, ambiguity, social site dynamics | Strong (uniquely mundane) |
| T4: Worried Partner (Hael-Kael-Sera) | High — lie to Hael, protect Kael, emotional cost | High — Hael as leverage, Sera's concealment | Maximum — both FRIEND NPCs are nodes | Relationships, tells, FRIEND arc, emotional weight | Essential |
| T5: Informant Question (Pell-Renn-Drin) | High — handle Pell (support/report/calm) | Medium-High — indirect benefits from ring fracture | High — smuggler sees internal threat, detective sees external symptoms | Cross-template propagation, ring stability | Strong |
Detailed Analysis
T1 (Hub Power) is the weakest triangle. Here's why:
-
Nils is off-stage. One vertex of the triangle is never physically present in v0.1. This means the smuggler can never mediate a Voss-Nils confrontation in real-time. The tension is narrated/implied, not observed and acted upon.
-
The smuggler's role is "caught between" — but what do they DO? The wiki says Kael "wants everyone to calm down." That's a passive stance, not a decision point. Where's the moment where the smuggler must choose Voss OR Nils, and face consequences?
-
The detective's interaction is one-directional. Detective sees Voss's anxiety, which is an investigation thread — but it's a data point, not a decision. "Voss seems nervous" leads to "investigate why" but doesn't fork into meaningfully different paths.
Proposal to strengthen T1: Give the smuggler a concrete decision moment. Example: Nils sends word (through Devra or Renn) demanding higher volume on the next run. Voss refuses to adjust the schedule. The smuggler must choose:
- Side with Nils (schedule the extra volume anyway) → Voss resents it, becomes less cooperative, might become a liability
- Side with Voss (tell Nils's messenger it's too risky) → Nils pushes back through other channels, smuggler's loyalty is questioned
- Try to split the difference (partial run, creative routing) → both sides grudgingly accept, but the operation is messier, increasing detective observation chances
This gives the smuggler a concrete fork with cascading consequences. The detective still sees the RESULTS of whichever choice was made (schedule anomalies, Voss's mood, operational messiness).
T3 (Bar Tensions) is critically important BECAUSE it's mundane. Per D-029, ~50% of NPCs should be in mundane triangles. T3 is the only triangle that might genuinely be disconnected from the ring. Torek's money could be from:
- The ring (entangled)
- A side hustle (mundane)
- An inheritance (flat)
- Gambling winnings from Harek's card games (mundane but connected to Harek's pressure on Drin)
This ambiguity is load-bearing. If the detective investigates Torek's spending and it turns out to be mundane, that's a RED HERRING — and red herrings are essential for investigation gameplay. The detective needs noise to make the signal meaningful. The smuggler player who KNOWS whether Torek is ring-connected has a different experience from the detective player who doesn't.
My concern: Is the ambiguity determined per-seed (randomizer decides at game start whether Torek is ring-connected) or is it authored (always one answer)? If always one answer, replay value drops. If per-seed, this becomes an excellent replayability vector.
Recommendation: Make Torek's ring connection randomizable. This is exactly the kind of variable the storyteller should control — it doesn't change the NPC profile structure, just one flag.
T4 (Worried Partner) and T5 (Informant Question) are both excellent. No notes on these — they produce rich, multi-system decisions for both characters. T4 is the emotional masterpiece; T5 is the operational thriller.
Redundancy Check
Are any triangles mechanically redundant? No — but T2 and T5 share a "potential informant" theme through different lenses:
| T2 (Worried Knowledge) | T5 (Informant Question) | |
|---|---|---|
| Key NPC | Maret (civilian who noticed) | Pell (ring member who's wavering) |
| Threat type | External observer | Internal defector |
| Smuggler decision | Manage an outsider who knows too much | Handle a member who might flip |
| Detective approach | Turn a cooperative witness | Receive an informant |
| System overlap | Both exercise "people who might talk" | Different mechanics — observation vs. loyalty |
They share Drin as a node, but Drin serves different functions: in T2 he's a compromised inspector, in T5 he's a potential recipient of information. These are mechanically distinct enough to justify both triangles.
Summary
- Keep all 5. None are redundant.
- Strengthen T1 with a concrete smuggler decision moment (Nils vs. Voss volume escalation).
- Make T3's ambiguity randomizable per seed (Torek's ring connection as storyteller variable).
- Consider making Nils partially present — even one short visit or comm call in v0.1 would make T1 dramatically more functional.
Topic 2: Mechanical Constraints for the Style Guide
Every NPC profile feeds into engine systems. If a field is missing or wrong, the system breaks silently. Here's what the style guide MUST mandate.
Hard Mechanical Requirements (Engine Will Break Without These)
| Constraint | Reason | System That Reads It | Applies To |
|---|---|---|---|
| Routine must specify hourly location presence | Schedule system generates NPC movement from this | ScheduleSystem → NPC position per tick |
All tiers |
| Routine must reference canonical location slugs | Locations are addressed by slug in the engine | LocationRegistry |
All tiers |
Every NPC must have a faction value from the canonical set |
Access tier logic reads this for dialogue filtering | AccessTierResolver |
All tiers |
Every NPC must have a role value |
Default descriptor when name unknown; access tier calculation | EntityKnowledge.known_attributes["role"] |
All tiers |
| Every NPC with a secret must map it to a FactId | Secrets must be discoverable through the knowledge system | FactId catalog lookup, KnowledgeConfidence gating |
Tier 1-2 |
Every tell must map to a behavior_flags value |
Tell system reads comma-separated flags | EntityKnowledge.known_attributes["behavior_flags"] |
Tier 1-2 |
Contradiction must specify contradiction_flagged value |
THE FRIEND arc trigger reads this exact attribute | EntityKnowledge.known_attributes["contradiction_flagged"] |
Tier 1 (FRIEND) |
| Relationships must reference NPCs that exist in the roster | Knowledge graph population uses these for cross-entity links | EntityKnowledge entries generated from relationships |
Tier 1-2 |
| Dual-lens notes required for all triangle members | Content authors need guidance for dual-lens dialogue writing | Monologue/dialogue authoring pipeline | Tier 1-2 in triangles |
| Bridge NPCs must have routine entries for EACH social site | NPCs that span sites must physically appear in both | ScheduleSystem multi-location routing |
Bridge NPCs |
Soft Mechanical Requirements (Won't Break Engine, But Content Quality Suffers)
| Constraint | Reason | Applies To |
|---|---|---|
| Personality traits should use established vocabulary | Trait modifiers in dialogue need consistent inputs | Tier 1-2 |
| Voice samples should cover at least 2 moods | Content authors need voice reference for dialogue writing | Tier 1-2 |
| Information Inventory must distinguish "knows" from "doesn't know" | Starting knowledge graph needs explicit boundaries | Tier 1-2 |
| Tolerance threshold must name specific triggers | Storyteller evaluates NPC tolerance against events | Tier 1-2 |
| Contentment should use the high/moderate/low vocabulary | D-024 thematic axis needs consistent scaling | Tier 1-2 |
| Skill set must include combat tag (yes/no) | CombatCapability ECS component gated by this tag | All tiers |
Proposed Format for Routine (Engine-Readable)
The current wiki uses prose for routines. The engine needs structured data. I propose the style guide require a structured routine block alongside the prose:
routine:
schedule:
- time: "06:00-06:30"
location: terminal # canonical location slug
activity: shift_startup
- time: "06:30-10:30"
location: terminal
activity: work_freight
- time: "10:30-11:00"
location: terminal_breakroom
activity: social_lunch
- time: "11:00-14:00"
location: terminal
activity: work_freight
- time: "14:30-16:00"
location: bar
activity: social_offshift
- time: "16:00-22:00"
location: residential
activity: home
deviations:
- trigger: ring_operation
replaces: "22:00-home"
location: corridor_b7
frequency: "1-2x per week"
This means: the wiki prose routine is for humans, but a YAML routine block is what gets translated to engine data. The style guide should define both.
Proposed Validation Checklist (Per-Tier)
Tier 3 (minimum viable NPC):
- Name, role, faction
- Routine with at least 2 time-location entries
- 1
behavior_flagsvalue (even "baseline") - Combat tag (yes/no)
- Function note (why this NPC exists)
Tier 2 (working profile):
- All Tier 3 requirements
- All 10 axes populated
- Secret mapped to FactId (if applicable)
- At least 1 tell with
behavior_flagsmapping - Dual-lens notes (if in a triangle)
- Relationships reference existing roster NPCs
- Voice sample (2-3 lines, at least 2 moods)
Tier 1 (FRIEND):
- All Tier 2 requirements
- Contradiction arc (3+ phases)
contradiction_flaggedvalue specified- Tell progression (minimum 3 stages)
- Dual-lens notes for BOTH characters
- Voice sample covering all moods in contradiction arc
- Content requirements met (70-100 authored lines)
Topic 5: Content Scoping — Per-District vs. Global
Let me break down what this actually means mechanically. Every content file lands in one of three buckets.
The Three Buckets
Bucket 1: Global Definitions (same everywhere, loaded once)
These are vocabulary and schema — they define WHAT things can exist, not WHERE they exist.
| Content Type | Example | Why Global |
|---|---|---|
| FactId catalog (definitions) | contraband.ring_exists definition structure |
FactIds are a vocabulary — same naming convention everywhere |
| Faction definitions | "The Lattice Commission is..." | Faction identity doesn't change per district |
| Technology descriptions | "Neural lattice is a brain-computer interface..." | Technology is tech everywhere |
| Contraband type definitions | "Lattice components are aftermarket neural mods..." | What a thing IS doesn't change by location |
| Tag taxonomy enums | Situations, topics, moods, triggers | Engine schema — universal |
| Relationship state definitions | Unknown/Known/Friendly/PoI/Hostile | State machine is global |
| Entity attribute schema | The 14 canonical keys | Data model is global |
| Access tier definitions | public/peer/insider/authority/hostile | Dialogue filtering rules are global |
Bucket 2: Per-District Content (unique to each setting)
These are the authored meat — they vary entirely by location and can't be shared.
| Content Type | Example | Why Per-District |
|---|---|---|
| NPC profiles | Kael Davan lives in Sova Transit | NPCs are physically located somewhere |
| NPC routines | Kael's schedule references specific locations | Locations are district-specific |
| Triangle definitions | Hub Power triangle among Sova NPCs | Triangles are relationships between local NPCs |
| Location descriptions | "The Terminal is a logistics hub..." | Physical spaces are unique |
| Monologue pools | Lines reference specific NPCs and locations | Content is hyper-local |
| Dialogue pools | Lines written for specific template roles | Roles are template-specific |
| Contraband instances | "The ring moves lattice components through Sova" | What's being smuggled HERE |
| District-specific FactIds | location.corridor_b7_restricted |
Only meaningful in this district |
Bucket 3: Global Definition, Per-District Instantiation
This is the tricky bucket. These things have a global identity but local presence.
| Content Type | Global Part | Per-District Part | Example |
|---|---|---|---|
| Factions | Definition, goals, ideology | Presence, strength, local leader, local agenda | Commission exists globally; Sera is the local presence |
| Contraband types | Definition, legality, market dynamics | What's actually flowing through THIS district, volume, routes | Lattice components defined globally; Sova's ring is local |
| FactId confidence states | Definition of confidence levels | Starting knowledge per NPC per district | contraband.ring_exists is a global FactId; the smuggler starts at KnowsDetails in Sova |
| Relationship templates | State machine, transition rules | Actual NPC-to-NPC and NPC-to-PC relationships | RelationshipState::Friendly is global; Kael-to-smuggler is local |
| Regional cultural flavor | Naming pattern template | Specific names, aesthetic markers, language echoes | "Compact, consonant-heavy" is Krenn System's cultural profile |
Proposed Content Directory Structure
content/
_global/
schema/
fact-ids.yaml # FactId definitions (vocabulary)
entity-attributes.yaml # 14 canonical keys
tags.yaml # situations, topics, moods, triggers
relationship-states.yaml # state machine definition
access-tiers.yaml # dialogue filtering rules
factions/
concord-assembly.yaml # faction description + goals
lattice-commission.yaml
syndics.yaml
guardians-of-autonomy.yaml
veil-institute.yaml
the-unbound.yaml
technology/
neural-lattice.yaml
meridian.yaml
span-gates.yaml
founder-gates.yaml
clone-transfer.yaml
severance-tech.yaml
contraband/
lattice-components.yaml # type definition
medical-grade.yaml
severance-equipment.yaml
regions/
krenn-system.yaml # regional style guide (naming, culture)
districts/
sova-transit/
district.yaml # district metadata, location list, faction presence
npcs/
kael-davan.yaml # full NPC profile (all axes)
sera-venn.yaml
voss.yaml
...
triangles/
hub-power.yaml # triangle definition (references NPC slugs)
worried-knowledge.yaml
bar-tensions.yaml
worried-partner.yaml
informant-question.yaml
locations/
terminal.yaml # location description + spatial data
bar.yaml
corridor-b7.yaml
facts/
local-facts.yaml # district-specific FactId instances + starting confidences
dialogue/
terminal.yaml # shared dialogue lines (both characters hear these)
bar.yaml
corridor.yaml
monologue/
terminal-smuggler.yaml # per-character per-location (D-032)
terminal-detective.yaml
bar-smuggler.yaml
bar-detective.yaml
corridor-smuggler.yaml
corridor-detective.yaml
factions.yaml # local faction presence + strength + local NPCs
Mod Overlay Principle
A mod adds a district:
mods/
new-bar-district/
mod.yaml # mod metadata, dependencies, load order
content/
districts/
new-bar-district/ # mirrors structure above
district.yaml
npcs/...
triangles/...
...
Override rules:
- District content: additive (new districts don't replace existing ones)
- Global content: override by key (mod provides
factions/new-faction.yaml→ added to faction list; mod providesfactions/lattice-commission.yaml→ overrides the global definition) - NPC replacement: mod specifies
replaces: kael-davanin NPC YAML → replaces that NPC in the roster
Key constraint for Tyre: Global schema files (_global/schema/) should be versioned. A mod that targets schema_version: 1 should still load on schema_version: 2 if the changes are additive. Breaking schema changes require mod updates.
Topic 6: PC-as-NPC — Mechanical Specification
This is the most interesting systems question. Let me map exactly what happens when an NPC is "upgraded" to a player character.
The Upgrade Process
Game Start
├─ Player selects archetype (smuggler / detective)
├─ System selects NPC matching archetype from district pool
├─ NPC profile → PC brief (data transfer + transformation)
├─ NPC removed from roster (they're now the player)
├─ All other NPCs' knowledge about this entity adjusted
└─ Game begins at PC's routine starting position
Data Transfer Table
| NPC Axis | What Transfers | How It's Used as PC Data | Transform Required? |
|---|---|---|---|
| Name | Directly | PC identity, how NPCs address you | No |
| Age | Directly | Cosmetic, some dialogue gating | No |
| Role | Directly | PC occupation, access tier baseline | No |
| Cultural Group | Directly | Naming conventions, environmental text familiarity | No |
| Lattice Tier | Directly | Perception mode availability (D-017) | No |
| Employer | Directly | Legitimate cover, schedule justification | No |
| Want | Transforms → Starting Objectives | PC's objectives screen, monologue motivation | Yes — prose → objective entries |
| Secret | Transforms → Player Burden | PC knows their own secret; it becomes what they must manage | Yes — inverted (NPC hides FROM observer; PC hides FROM world) |
| Relationships 1-3 | Transforms → Starting Social Network | Starting RelationshipState entries + EntityKnowledge for all known NPCs |
Yes — relationship data → knowledge graph entries |
| Tolerance | Transforms → Stress/Consequence System | Defines what pushes the PC toward failure states | Yes — NPC threshold → player consequence thresholds |
| Routine | Transforms → Default Schedule (overrideable) | PC's expected schedule; deviations are observable to NPCs | Yes — rigid schedule → soft expectation with deviation tracking |
| Information Inventory | Transforms → Starting Knowledge Graph | All starting FactId confidences + EntityKnowledge entries |
Yes — prose → structured knowledge data |
| Contentment | Directly | Starting thematic position, monologue tone baseline | No |
| Personality | Transforms → Monologue Voice | Which monologue pool, word choice, analytical vs emotional | Yes — traits → voice selection parameters |
| Tell System | Inverted | OTHER NPCs can observe the PC's tells when the PC lies/evades | Yes — "observe this tell" → "NPCs detect this behavior" |
| Skills | Directly | PC capabilities, combat tag, functional permissions | No |
What's Generated at Upgrade Time
These don't exist in the NPC profile — they're computed from the profile data:
| Generated Data | Source | Purpose |
|---|---|---|
Starting EntityKnowledge entries |
Information Inventory + Relationships | Populate the PC's knowledge graph for every NPC they know |
Starting FactId confidences |
Information Inventory | What facts the PC already knows at what confidence level |
Starting RelationshipState per NPC |
Relationships + role + faction | Unknown/Known/Friendly for each NPC based on prior relationship |
Starting known_attributes per NPC |
Information Inventory | Name, role, faction, routine_pattern, behavior_flags (baseline) for known NPCs |
| Reverse knowledge entries | All NPCs who know this NPC | Other NPCs' EntityKnowledge about the PC — what do THEY know about YOU? |
| Starting position | Routine + game start time | Where the PC physically spawns |
| Monologue pool activation | Archetype selection | Which character: tag pool is active |
| Starting inventory/equipment | Skills + role + archetype | Functional items derived from occupation |
The Critical Insight: Reverse Knowledge
When an NPC becomes a PC, every OTHER NPC's knowledge about that entity matters:
Example — Kael becomes the smuggler PC:
- Voss knows Kael as "dock worker, reliable, part of the arrangement" → Voss has
EntityKnowledgewithfaction: "ring member",trust_level: "reliable",relationship_type: "subordinate" - Hael knows Kael as "my partner, acting strange lately" → Hael has
EntityKnowledgewithrelationship_type: "partner",behavior_flags: "evasive,late_nights",trust_level: "uncertain" - Sera knows Kael as "Hael's partner, flagged in compliance check" → Sera has
EntityKnowledgewithsecret_held: "manifest discrepancies",secret_confidence: "confirmed"
This means the NPC profile's Relationships section is read bidirectionally. When writing an NPC profile that might be upgraded to a PC, the author must specify not just "who does this NPC know" but implicitly "what does each related NPC know about THIS NPC."
What the NPC Profile Doesn't Have (PC-Only Data)
| PC-Only Data | Where It Comes From |
|---|---|
| Monologue lines | Separate content files, not NPC profile |
| Starting objective text | Derived from Want + archetype-specific framing |
| Tutorial integration hooks | Archetype-specific, not NPC-specific |
| Equipment/inventory | Derived from skills + role, archetype defaults |
| Player agency permissions | Archetype-specific (smuggler can access ring locations, detective can use authority access) |
| Perception mode configuration | Lattice tier + equipment, archetype defaults |
Style Guide Implications
For NPCs that are candidates for PC upgrade (any archetype-matching NPC), the profile MUST additionally specify:
-
Starting FactId confidence table — explicit list of which facts at what confidence level:
starting_knowledge: facts: - id: contraband.ring_exists confidence: KnowsDetails - id: contraband.lattice_components confidence: KnowsDetails - id: location.corridor_b7_restricted confidence: KnowsDetails - id: world.shift_schedule confidence: KnowsDetails - id: relationship.ring_membership confidence: KnowsDetails # knows the ring, knows members - id: investigation.manifest_discrepancy confidence: null # doesn't know about this -
Starting RelationshipState table — explicit per-NPC:
starting_relationships: - npc: voss state: Known attributes: name: "Voss" role: "shift supervisor" trust_level: "reliable" faction: "civilian" # smuggler doesn't think of Voss as ring - npc: kael_davan # N/A if this NPC IS Kael state: Friendly ... -
Reverse knowledge entries — what each related NPC knows about THIS character:
known_by: - npc: voss attributes: name: "Kael Davan" role: "dock worker" faction: "ring member" # Voss knows trust_level: "reliable" - npc: hael attributes: name: "Kael" role: "dock worker" faction: "civilian" # Hael doesn't know about ring behavior_flags: "evasive,late_nights"
Randomizer Integration
For the randomizer to generate PC-viable NPCs:
-
Archetype templates define the minimum requirements:
archetype: smuggler requires: faction_access: [ring] minimum_relationships: 3 minimum_facts_at_KnowsDetails: 4 social_sites: [hub, ring] # must have presence in these combat_tag: false # smugglers aren't fighters (v0.1) -
NPC generation creates the full 10-axis profile per D-024
-
PC viability check confirms the NPC meets archetype requirements
-
Upgrade executes the transfer/transform/generate pipeline above
What the PC-as-NPC Spec Resolves
This spec answers several open questions:
- "Where does starting knowledge come from?" → Information Inventory axis, translated to FactId confidences + EntityKnowledge entries
- "How do NPCs already know the player?" → Reverse knowledge entries from the NPC profile's Relationships, read bidirectionally
- "What changes between playthroughs?" → Different NPC selected → different name, relationships, starting knowledge, position. Same systems, different starting state.
- "Does the player have a routine?" → Yes, inherited from NPC. Deviation from routine is observable to NPCs — this creates a soft constraint that grounds the PC in the world.
Cross-Cutting Observations
A few things connect across all four topics:
-
The NPC profile is the master document. Triangles, dialogue prerequisites, knowledge graph population, and PC upgrade all read from it. The style guide isn't just a writing guide — it's a data specification.
-
Routine is the most mechanically overloaded axis. The schedule system, tell deviation detection, NPC-observing-PC system, and location presence all read from it. It needs the most precise specification.
-
Information Inventory is the second-most critical. It's the seed for the entire knowledge graph — both for NPCs and for PC upgrade. If it's vague, the engine can't populate starting states.
-
Triangles need decision moments, not just tension descriptions. The wiki describes tensions beautifully. What it doesn't specify is the FORK — the moment where the player must choose, and can't have both outcomes. T1 is weakest here. The style guide should require that each triangle specifies at least one concrete decision moment per playable character.
-
The boundary between global and local content is also the boundary between what modders can freely add vs. what they must integrate with. Districts are self-contained additions. Global content changes require understanding system-wide consequences. The content directory structure should make this boundary obvious.