Scoped the vertical slice: 16 EntityKnowledge keys, v0.1 mechanical NPC mapping, YAML content format, 7-verb interaction model, server- authoritative pause, 38 tickets created across copy/server/client/ci. 20 decisions (D-042 through D-061). 8 agents, 2 rounds + closing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
28 KiB
Round 2 — Gestalt (Systems Design)
cracks knuckles
Four resolution tasks. Let me be honest about each.
Task 1: Canonical NPC Mapping (Definitive)
The lead confirmed my mechanical mapping wins for v0.1. Paula's emotional/narrative reads become v0.2 annotations. But "winning" doesn't mean refusing to learn from the disagreements. I reviewed all 10 and changed my mind on 6 of them.
Changes from Round 1 (Where Paula Was Right)
Let me be transparent about what I got wrong and why:
| NPC | My R1 | Paula's R1 | Final R2 | Who Was Right | Why I Changed |
|---|---|---|---|---|---|
| Maret (pattern) | SYSTEM | WITNESS | WITNESS | Paula | Maret's v0.1 function is defined by what she SAW, not her institutional role. The player (both characters) approaches Maret because she carries information. SYSTEM describes her job; WITNESS describes her story function. |
| Maret (motivation) | WITNESS | SKEPTIC | SKEPTIC | Paula | If pattern is WITNESS and motivation is WITNESS, there's no compositional tension. WITNESS+SKEPTIC = "she saw something AND she doubts" — the doubt makes her dangerous because she might ACT. Data-driven doubt IS skepticism. |
| Resha (motivation) | SKEPTIC | CIVILIAN | CIVILIAN | Paula | CATALYST+SKEPTIC implies deliberate questioning. CATALYST+CIVILIAN = "innocent disruption" — Resha doesn't INTEND to cause problems. The accidental quality makes the disruption more realistic and more dangerous (you can't negotiate with curiosity). |
| Harek (pattern) | GHOST | ANCHOR | ANCHOR | Paula | Harek is PHYSICALLY PRESENT. GHOST means absent power; Harek is at the bar playing cards. His leverage on Drin is indirect, but HE isn't absent. Paula's read: Harek embodies complacent contentment whose comfort accidentally creates a tool for others. The "unconscious lever" is more interesting than "invisible puppeteer." |
| Drin (pattern) | REMNANT | SYSTEM | SYSTEM | Paula | Paula nailed this: "The dock inspector IS the inspection system. His compromise means the system itself is corrupted." REMNANT requires historical depth a 40-year-old station doesn't have. Drin doesn't remember centuries of tradition — he remembers 5 years ago. That's not REMNANT-scale. SYSTEM+TURNCOAT = institutional rot. |
| Sabel (pattern) | THRESHOLD | GHOST | GHOST | Paula | Sabel is off-station with 1-2 brief visits. The player doesn't interact with Sabel enough for THRESHOLD mechanics (getting past a gatekeeper). The player learns about Sabel through others' references. That's GHOST — absent power shaping events through supply chain influence. |
| Olin (motivation) | SKEPTIC (dual) | CIVILIAN | CIVILIAN | Paula | Dropped dual designation. At Tier 3, Olin has 10-15 lines. Not enough content for SKEPTIC function. CIVILIAN is the safe tag — if Olin gets promoted to T2 in v0.2, the hidden motivation can be revealed. 1 pattern + 1 motivation per NPC, no exceptions. |
What I Kept (Where My Mechanical Read Holds)
| NPC | Disagreement | My R1 | Final R2 | Why I'm Keeping It |
|---|---|---|---|---|
| Voss (motivation) | OPERATOR vs HANDLER | OPERATOR | OPERATOR | Voss RUNS the schedule. That's operating, not handling. HANDLER implies top-down pressure — Devra and Harek do that. Voss is middle management: competent, procedural, operating the machinery. The schedule IS his operation. |
| Devra (motivation) | HANDLER vs OPERATOR | HANDLER | HANDLER | Devra conveys Nils's strategy, manages external contacts, delivers escalation demands. That's pressure from above. She doesn't run day-to-day operations (Kael, Renn, Voss do). She manages the people who run things. |
| Sess (pattern) | ANCHOR vs NOBODY | ANCHOR | ANCHOR | NOBODY is deferred to v0.2. Tagging Sess as NOBODY means the tag does nothing in v0.1. ANCHOR at T3 = contentment as atmospheric texture. The bartender who sees everything and says nothing because his life is fine. v0.2 note: Sess could be retagged NOBODY if dynamic tier promotion activates. |
The Definitive v0.1 NPC Mapping
| # | Name | Tier | Pattern | Motivation | Composition Read |
|---|---|---|---|---|---|
| 1 | Kael Davan | T1 | FRIEND | OPERATOR | Trust anchor running ring cargo. Identity betrayal: "I was your friend AND your co-conspirator." |
| 2 | Sera Venn | T1 | FRIEND | WITNESS | Trust anchor carrying unreported evidence. Concealment betrayal: "I was your friend AND I was hiding evidence." |
| 3 | Naia Tamm | T1* | MIRROR | CIVILIAN | Honest transparency, no secrets, uninvolved. "The one person not lying — surrounded by liars." |
| 4 | Voss | T2 | SYSTEM | OPERATOR | Institutional authority operating the schedule that enables smuggling. Corrupted machinery: "The system works — for the wrong people." |
| 5 | Lera Sessik | T2 | ANCHOR | OPERATOR | Contentment embodied, running a bar on willful ignorance. Profitable blindness: "Is this enough? Yes — if I don't look." |
| 6 | Torek Lintar | T2 | CATALYST | CIVILIAN | Spending disrupts equilibrium. Uninvolved, just living visibly. Accidental signal: "He doesn't know he's a liability." |
| 7 | Devra | T2 | THRESHOLD | HANDLER | Ring gatekeeper, manages operations from above. Obstacle with authority: "You go through her or you don't go." |
| 8 | Maret Korr | T2 | WITNESS | SKEPTIC | Accidentally observed discrepancies, doubts the numbers. Dangerous knowledge: "She saw something and she can't stop questioning it." |
| 9 | Resha | T2 | CATALYST | CIVILIAN | New hire forcing defensiveness with innocent questions. Accidental disruption: "She just asked. Everyone flinched." |
| 10 | Drin | T2 | SYSTEM | TURNCOAT | Inspector whose compromise corrupts the institution. Loyalty shifting under coercion. Institutional rot: "The inspection system is broken because the inspector is broken." |
| 11 | Renn | T2 | THRESHOLD | OPERATOR | Courier controlling cargo flow. Physical gatekeeper: "Renn moves the product. Trace Renn, find the route." |
| 12 | Pell | T2 | CATALYST | TURNCOAT | Wavering member forcing potential crisis. Maximum instability: "When Pell breaks, everything moves." |
| 13 | Harek | T2 | ANCHOR | HANDLER | Complacent contentment whose comfort creates a tool. Unconscious lever: "Harek doesn't know his card games built a weapon." |
| 14 | Sess | T3 | ANCHOR | CIVILIAN | Quiet contentment behind the bar. Social wallpaper: "Sees everything, says nothing — because nothing's wrong with HIS life." |
| 15 | Olin | T3 | CATALYST | CIVILIAN | New arrival forcing evaluation. Ambiguous intent: "Friend or threat? The question IS the disruption." |
| 16 | Sabel | T3 | GHOST | OPERATOR | Off-station absent power running the supply chain. Distant machinery: "Sabel shapes events from elsewhere." |
| 17 | Tav | T3 | SYSTEM | CIVILIAN | Ring lookout following procedure. Lowest rung: "Tav watches the door. That's the whole job." |
Off-stage:
| NPC | Pattern | Motivation | Notes |
|---|---|---|---|
| Nils Davan | GHOST | HANDLER | Absent authority applying pressure through intermediaries. |
Pattern Distribution (Final)
| Pattern | Count | NPCs | Coverage |
|---|---|---|---|
| FRIEND | 2 | Kael, Sera | Full (D-034 production level) |
| MIRROR | 1 | Naia Tamm | Full (T1 emotional depth) |
| ANCHOR | 3 | Lera, Harek, Sess | Full + sketch. Three versions of "is this enough?" |
| SYSTEM | 3 | Voss, Drin, Tav | Full + sketch. Institutional machinery (legit + criminal) |
| CATALYST | 3 | Torek, Resha, Pell | Full. Three disruption modes (accidental, innocent, deliberate) |
| THRESHOLD | 2 | Devra, Renn | Full. Access gatekeepers (organizational + physical) |
| WITNESS | 1 | Maret | Full. Data-driven information carrier |
| GHOST | 1+1 | Sabel (+Nils off-stage) | Light. Absent power through supply/authority |
| REMNANT | 0 | — | Correctly absent. 40-year station lacks historical depth. |
| NOBODY | 0 | — | Deferred to v0.2. Data ships (hidden fields in content). |
8 of 9 patterns present. All 6 motivations present.
Motivation Distribution (Final)
| Motivation | Count | NPCs |
|---|---|---|
| OPERATOR | 5 | Kael, Voss, Lera, Renn, Sabel |
| CIVILIAN | 6 | Naia Tamm, Torek, Resha, Olin, Sess, Tav |
| HANDLER | 2+1 | Devra, Harek (+Nils off-stage) |
| WITNESS | 1 | Sera |
| TURNCOAT | 2 | Drin, Pell |
| SKEPTIC | 1 | Maret |
CIVILIAN at 6/17 (35%) — matches D-029's noise floor requirement (~30% flat). OPERATOR at 5 reflects a logistics hub where everyone is RUNNING something. All 6 motivations represented.
Why This Mapping Creates Interesting Decisions
ANCHOR saturation (3): Three different answers to "is this enough?" Lera: "Yes, if I don't look." Harek: "Yes, absolutely — pass me the cards." Sess: "Yes, and I'd rather you didn't disturb it." This isn't redundancy — it's the thematic floor the investigation disrupts. The player walks through contentment before contamination touches it.
SYSTEM × TURNCOAT (Drin): The most mechanically productive composition in the set. The institution IS the character AND the character is betraying the institution. For the detective: crack the inspector, crack the system. For the smuggler: keep the inspector quiet, keep the system working for you. Same NPC, inverted interactions. That's the dual-lens proof.
CATALYST diversity (3 types): Torek disrupts through SPENDING (accidental, financial signal). Resha disrupts through ASKING (innocent, social signal). Pell disrupts through WAVERING (deliberate, operational signal). Three types of disruption, three types of player assessment. The smuggler reads them as threats with different urgency levels. The detective reads them as leads with different reliability levels.
Task 2: Generic Key Architecture (The Bloat Question)
The lead asks: "If the original EntityKnowledge set was incomplete for the smuggler, are we doing this again for the administrator or the corporate tycoon?"
The answer is no — if we design the keys correctly now.
The Problem with Per-Archetype Keys
My Round 1 proposal: 4 smuggler-specific keys (exposure_risk, loyalty_assessment, cover_integrity, moral_weight). If we repeat this for 8 archetypes:
8 archetypes × 4 unique keys = 32 archetype-specific keys
+ 14 shared keys
= 46 total keys (unsustainable)
Administrator needs bureaucratic_leverage, regulatory_compliance...
Merchant needs market_position, asset_vulnerability...
Every archetype spawns its own vocabulary. That's schema bloat AND content bloat (every NPC profile must have 46 fields).
The Solution: 4 Generic Perspective Keys
Look at what my 4 smuggler keys actually represent at the ABSTRACT level:
| Smuggler Key | Abstract Question |
|---|---|
exposure_risk |
"How does this NPC threaten MY operational position?" |
loyalty_assessment |
"How reliably will this NPC act in MY interest?" |
cover_integrity |
"How well is the relevant deception holding?" |
moral_weight |
"How morally culpable is this NPC in MY judgment?" |
These questions are UNIVERSAL. Every archetype asks them — just with different words:
| Abstract Question | Smuggler | Detective | Administrator | Merchant |
|---|---|---|---|---|
| "How does this NPC threaten my position?" | "Will they expose the ring?" | "Will they obstruct my investigation?" | "Will they expose my corruption?" | "Will they undercut my deal?" |
| "How reliably will this NPC serve my interests?" | "Can I count on them in operations?" | "Will they testify/cooperate?" | "Will they vote with me?" | "Will they honor the contract?" |
| "How well is the deception holding?" | "Is their cover solid?" | "Is my informant still believable?" | "Does the public still buy it?" | "Does the competitor still trust me?" |
| "How culpable is this NPC?" | "How deep in the ring?" | "How guilty?" | "How corrupt?" | "How honest?" |
Same 4 questions. Same 4 keys. 8 archetypes.
Proposed Generic Keys
| Key Name | Value Enum | What It Stores |
|---|---|---|
threat_to_position |
"none", "low", "moderate", "high", "critical" |
Observer's assessment of how this NPC threatens the observer's operational security, institutional standing, or strategic position. |
reliability |
"solid", "dependable", "uncertain", "wavering", "hostile" |
Observer's assessment of how predictably this NPC will serve the observer's interests. |
facade_status |
"solid", "thin", "cracking", "blown", "N/A" |
Status of any active deception involving this NPC (their cover, the observer's cover, a shared front). N/A if no deception in play. |
moral_standing |
"innocent", "peripheral", "complicit", "compromised", "willing" |
Observer's subjective moral assessment of this NPC within the observer's ethical framework. |
How Interpretation Works
The key stores GENERIC data. The monologue system provides CHARACTER-SPECIFIC interpretation through D-032's hard partition (separate pools per character).
Same NPC, same keys, different character pools:
# Smuggler monologue about Maret
- id: hub_m_031
text: "Maret's been checking manifests again. She's going to notice something she can't un-notice."
character: smuggler
trigger: observe_npc
prerequisite:
target.known_attributes.threat_to_position: "high"
target.known_attributes.name: "Maret Korr"
# Detective monologue about Maret
- id: hub_m_032
text: "Korr looks worried. She processes manifests — if the numbers are off, she'd know."
character: detective
trigger: observe_npc
prerequisite:
target.known_attributes.threat_to_position: "high"
target.known_attributes.name: "Maret Korr"
Same key (threat_to_position: "high"), same NPC — but the smuggler reads it as "she's a risk to the operation" while the detective reads it as "she's a potential witness at risk." The interpretation lives in the monologue text, not in the key schema.
Why This Scales to 8 Archetypes Without Bloat
| Archetype | threat_to_position means... | reliability means... | facade_status means... | moral_standing means... |
|---|---|---|---|---|
| Smuggler | Exposure risk to the ring | Operational loyalty | Cover integrity | Innocent vs. complicit |
| Detective | Obstruction to investigation | Cooperation likelihood | Informant/cover status | Guilt level |
| Administrator | Political liability | Voting alignment | Public image coherence | Corruption level |
| Merchant | Competitive threat | Contract reliability | Deal integrity | Business ethics |
| Newcomer | Social danger | Friendliness | Acceptance facade | Community trustworthiness |
| Operator | Operations disruption | Team dependability | Mission cover | Professional ethics |
| Exile | Personal danger | Alliance reliability | Identity concealment | Threat vs. ally |
| Fixer | Client risk | Job reliability | Operation facade | How dirty |
Total EntityKnowledge keys: 18. 14 shared + 4 generic perspective. Works for all 8 archetypes. No additional keys needed at v1.0.
Value Enum Design
The enums are deliberately archetype-neutral:
-
"solid"/"dependable"/"uncertain"/"wavering"/"hostile"— these words work in ANY context. A smuggler reads "wavering" as "might turn on us." A detective reads "wavering" as "might cooperate if pressured." Same word, different operational meaning. -
"innocent"/"peripheral"/"complicit"/"compromised"/"willing"— these work for any moral framework. A smuggler uses them to track guilt distance from the ring. An administrator uses them to track corruption distance from a scandal. The progression is the same.
How Content Authors Use This
NPC profiles get a SINGLE set of character-perspective attributes, not per-archetype sections:
# In kael-davan.yaml, perspective section
perspectives:
smuggler:
threat_to_position: "low" # Kael is reliable (pre-contradiction)
reliability: "solid" # Trusted colleague
facade_status: "solid" # Cover holds (pre-contradiction)
moral_standing: "willing" # Fully committed ring member
detective:
threat_to_position: "moderate" # Kael handles cargo on suspicious shifts
reliability: "uncertain" # Unknown cooperativeness
facade_status: "solid" # Appears to be a normal dock worker
moral_standing: "complicit" # Connected to discrepancies (if known)
Content authors populate perspective values per character in the NPC YAML. The server loads these as initial known_attributes values for each character's knowledge graph. Values update through gameplay (Kael's facade_status shifts from "solid" to "cracking" when tells accumulate).
Addressing Paula's 8-Key Proposal
Paula proposed all 8 smuggler attributes as new keys. My generic architecture maps her proposal:
| Paula's Key | Maps To | Notes |
|---|---|---|
trust_read |
trust_level (existing) |
Same key, context-dependent interpretation. Already works. |
exposure_risk |
threat_to_position (generic) |
Renamed for archetype-neutrality. |
loyalty_assessment |
reliability (generic) |
Renamed. |
leverage_held |
secret_held (existing) |
Leverage IS secret knowledge. Same storage. |
social_debt |
Deferred to v0.2 | 30-minute session doesn't develop favor economy. |
moral_weight |
moral_standing (generic) |
Renamed. |
cover_integrity |
facade_status (generic) |
Renamed. |
loyalty_conflict |
Deferred to v0.2 | Inferable from behavior_flags + reliability. |
Result: 2 existing keys reused + 4 generic keys created + 2 deferred. Total schema: 18 keys. Works for 8 archetypes.
Task 3: Self-Contained Triangle Forks (Confirmed)
I agree with Tyre's recommendation: self-contained forks for v0.1, no cross-triangle cascade.
But "self-contained" needs a precise definition, because there's a trap:
The Shared-NPC Problem
Voss appears in BOTH Triangle 1 (Hub Power) and Triangle 2 (Worried Knowledge). If the smuggler escalates in Triangle 1, Voss gets more anxious. That anxiety is part of Voss's ENTITY STATE — it's stored in behavior_flags, routine_pattern, etc. If Triangle 2's fork reads Voss's entity state, then Triangle 1's decision HAS cascaded into Triangle 2.
Is that a cross-triangle cascade? Technically yes. Should we prevent it? No — that would require NPCs to have separate states per triangle, which is absurd.
What "Self-Contained" Actually Means
Self-contained forks = independent decision state machines, shared NPC state.
| Allowed (v0.1) | Not Allowed (v0.2+) |
|---|---|
| Each triangle has its own fork with its own trigger, decision, and outcome | Triangle 1's OUTCOME directly gates Triangle 2's FORK (if T1 escalates, T2 fork changes) |
| NPCs carry behavioral state across triangles (Voss's anxiety is visible everywhere) | Triangle forks modify other triangles' state machines (T1 pushes T2 from state A to state B) |
| Players OBSERVE cross-triangle effects through NPC behavior | Fork resolution in one triangle REQUIRES resolution of another |
| Monologue can reference NPC state from any source | The storyteller sequences forks based on other forks' outcomes |
In implementation:
Triangle 1 Fork:
trigger: Devra delivers Nils's escalation demand
decision: smuggler chooses escalate/stabilize/mediate
outcome: modifies Voss.behavior_flags, Kael.behavior_flags
DOES NOT: modify Triangle 2's fork state
Triangle 2 Fork:
trigger: detective notices Maret's manifest re-checking pattern
decision: detective approaches Maret or pressures Drin
outcome: modifies Maret.trust_level, Drin.cover_integrity
DOES NOT: depend on Triangle 1's resolution
Shared state visible to both:
Voss.behavior_flags may contain "nervous" from T1 AND "overworked" from T2
The player sees ALL of Voss's behavioral state regardless of which triangle produced it
Cross-triangle OBSERVATION is emergent — it's systems interacting, not scripted cascade
Why this is right for v0.1:
-
Testing scope: Self-contained forks can be tested independently. Each triangle fork is a unit test. Cross-triangle cascade requires integration tests across all 5 triangles.
-
Content scope: Each fork needs its own decision content (dialogue, monologue, consequences). 3 active forks × 3 choices each = 9 content branches. Adding cascade dependencies multiplies this combinatorially.
-
The emergent observation IS the payoff: The player noticing that Voss is anxious in BOTH the hub (Triangle 1) and during manifest processing (Triangle 2) is an emergent connection. They're doing investigation — connecting dots across contexts. That's MORE interesting than scripted cascade, and it comes for free from shared NPC state.
-
v0.2 cascade path: If we want Triangle 1's escalation to gate Triangle 2's timing in v0.2, the architecture supports it. The fork state machines are independent now; adding dependencies later is an additive change, not a rewrite.
Triangle Fork Summary (Final)
| Triangle | Fork Type | Decision | Self-Contained? |
|---|---|---|---|
| T1: Hub Power | Active | Smuggler: escalate/stabilize/mediate | YES — modifies Voss+Kael state, no T2 gate |
| T2: Worried Knowledge | Active | Detective: approach Maret / pressure Drin / wait | YES — modifies Maret+Drin state, no T1 gate |
| T3: Bar Tensions | Passive | No fork — ambiguity is permanent | N/A |
| T4: Worried Partner | Active | Both PCs: FRIEND contradiction paths A/B/C | YES — modifies Kael/Sera state, no other triangle gate |
| T5: Informant Question | Passive | No fork — tension observable, resolution post-session | N/A |
Task 4: Knowledge Panel Pause — Sim Speed Architecture
Lead decision: 50% sim speed when panel is open. Spacebar always pauses from anywhere.
Why 50% Is Correct (Not 10%, Not Full Pause)
Stig proposed 10%. Lead overruled to 50%. Here's the mechanical reasoning:
| Speed | Effect | Problem |
|---|---|---|
| 100% (no slow) | World runs at full speed while you read the knowledge panel | NPCs walk away while you're cross-referencing. Punishes information gathering. |
| 50% (lead's choice) | World runs at half speed | You can SEE NPCs moving slowly while you think. Creates tension: "Do I keep reading or close and follow?" That's an INTERESTING DECISION. |
| 10% (Stig's proposal) | World barely moves | No tension. Functionally equivalent to pause. If you're going to pause, just pause. 10% is a nothing-state. |
| 0% (full pause) | World stops | No tension. The knowledge panel becomes a reference tool, not a strategic moment. Removes the feeling of time pressure that makes investigation feel real. |
50% creates a micro-decision every time you open the panel: "Is the information worth the time?" That's asymmetric information AS MECHANIC — even the player's attention is a scarce resource.
Sim Speed State Machine
Two independent toggles, multiplicative:
effective_speed = if pause_override { 0.0 } else { base_speed × ui_modifier }
| Toggle | Controls | Values |
|---|---|---|
ui_modifier |
Whether a UI overlay is open | 1.0 (no overlay) or 0.5 (knowledge panel open) |
pause_override |
Spacebar | false (not paused) or true (paused) |
State combinations:
| State | ui_modifier | pause_override | Effective Speed | Player Experience |
|---|---|---|---|---|
| Normal play | 1.0 | false | 100% | Full speed. NPCs move, routines advance. |
| Panel open | 0.5 | false | 50% | Slow motion. NPCs drift. Time passes. Tension. |
| Paused (from normal) | 1.0 | true | 0% | Full stop. World frozen. Read, think, plan. |
| Paused (from panel) | 0.5 | true | 0% | Full stop. Panel still visible. No time pressure. |
Key behaviors:
- Spacebar always pauses. From any state. No exceptions. This is accessibility AND good design.
- Spacebar resumes to previous state. If you paused from panel-open (50%), unpausing returns to 50%, not 100%. If you paused from normal play, unpausing returns to 100%.
- Tab toggles panel. Opening panel sets
ui_modifier = 0.5. Closing panel setsui_modifier = 1.0. Independent of pause state. - Dialogue: also 50%. When dialogue is active (Talk interaction), the same
ui_modifier = 0.5applies. NPCs who aren't in the conversation continue moving at half speed. This means other events can happen WHILE you're talking — the world doesn't freeze for your conversation. That's immersive sim design.
v0.2 Extension
The multiplicative model is composable. Future UI states can define their own modifiers:
| UI State | Modifier | Combined |
|---|---|---|
| Knowledge panel | 0.5 | 0.5 |
| Dialogue | 0.5 | 0.5 |
| Panel + Dialogue? | 0.5 × 0.5 = 0.25 | 25% (both open simultaneously) |
| Cutscene | 0.0 | Full freeze (storyteller controls) |
For v0.1, only panel and dialogue use 0.5. The system supports future states without redesign.
Implementation Note for Dudley
The server tick rate doesn't change. The CLIENT requests a sim speed modifier. The server processes ticks at variable intervals:
- Normal: 1 tick per 50ms (20 ticks/sec)
- 50%: 1 tick per 100ms (10 ticks/sec)
- Paused: 0 ticks (server queues but doesn't process)
The server's tick processing is deterministic regardless of interval. Changing the interval changes PACING, not LOGIC. All systems (NPC routines, monologue triggers, tell accumulation) operate on tick count, not wall-clock time. A 50% slowdown means the same events happen — they just take twice as long in wall-clock time.
Cross-Reference: Addressing Tracking Doc Items
A few items from Qatux's tracking that directly involve my assignments:
A-17: Self-contained triangle forks
Confirmed. See Task 3. Independent decision state machines, shared NPC state. Tyre was right.
D-04: Examine vs Talk
Lead decided: conceptually separate, v0.1 ships single action. I accept this. My 7-interaction model stands as the DESIGN TARGET. v0.1 implements it as context-sensitive single action (server knows about multiple actions per entity, client surfaces the best one). v0.2 adds multi-verb UI. The architecture must support both — that's Tyre and Dudley's task.
D-05: Knowledge Panel Pause
Resolved. See Task 4. 50% sim speed, spacebar override to full pause. Multiplicative model.
A-10: Dialogue files by location + role
I validate this. It aligns with D-035 (role-based, not NPC-based line assignment) and the generator model (templates define roles, NPCs fill roles). The file organization should be:
districts/sova-transit/dialogue/
hub-dock-worker.yaml # Role: dock worker, Location: hub
hub-supervisor.yaml # Role: supervisor, Location: hub
bar-owner.yaml # Role: bar owner, Location: bar
bar-regular.yaml # Role: bar regular, Location: bar
...
NPCs are assigned to roles at content load time. A line tagged role: dock_worker + access: insider fires for Kael (if smuggler has insider access to Kael) regardless of which NPC fills the dock_worker role. This is generator-compatible.
Summary of Changes from Round 1
| Item | Round 1 | Round 2 | Change Reason |
|---|---|---|---|
| Maret pattern | SYSTEM | WITNESS | Story function > job description |
| Maret motivation | WITNESS | SKEPTIC | Compositional tension (WITNESS+SKEPTIC > WITNESS+WITNESS) |
| Resha motivation | SKEPTIC | CIVILIAN | Innocent disruption > deliberate questioning |
| Harek pattern | GHOST | ANCHOR | Present contentment > absent power |
| Drin pattern | REMNANT | SYSTEM | Institutional role > nostalgia (station too young for REMNANT) |
| Sabel pattern | THRESHOLD | GHOST | Absent influence > present gatekeeper |
| Olin motivation | SKEPTIC (dual) | CIVILIAN | Dropped dual designation. 1 per NPC. |
| Smuggler keys | 4 smuggler-specific | 4 generic perspective | threat_to_position, reliability, facade_status, moral_standing — works for all 8 archetypes |
| EntityKnowledge total | 18 (14+4) | 18 (14+4) | Same count, generic names |
| Triangle forks | Self-contained (tentative) | Self-contained (confirmed) | Independent state machines, shared NPC state |
| Panel pause | Not addressed | 50% sim speed, spacebar override | Multiplicative toggle model |