fix(content): PR #64 round 2 — NPC ID, outcome gating, fact stubs

Fix npc:nils → npc:nils-davan canonical ID mismatch. Replace
auto-flag gates on ring_completes/ring_splinters with player-
action-gated fact conditions (unreachable outcomes). Add
ring_stalemate terminal exit for non-terminal ring_splinters.
Create ring.yaml with 10 fact stubs for content/global/knowledge/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 09:49:09 +01:00
co-authored by Claude Opus 4.6
parent c55474f46d
commit cc898d60c7
2 changed files with 146 additions and 8 deletions
+40 -8
View File
@@ -131,7 +131,7 @@ npc_requirements:
Handles physical drops. Not a speaking character — observable behavior only.
Can be the anonymous contact Kael meets.
binding: named
named_npc: "npc:nils"
named_npc: "npc:nils-davan"
is_optional: false
- role: institutional-watcher
@@ -580,9 +580,11 @@ outcomes:
flags_set:
- final_shipment_known # set by final_shipment_scheduled event
- timeline_accelerating # set by maret_increases_presence — Maret forced their hand
flags_not_set:
- kael_message_sent # If this is NOT set, Kael's cooperation went unnoticed
facts_not_known:
- "ring.cargo_discrepancy_pattern" # detective never found the basic pattern — no investigation
ticks_since_activation: 3600 # Module ran for ~60 minutes without full exposure
# kael_message_sent was previously gated here but auto-fires at tick ~1550,
# making this outcome permanently unreachable. Replaced with player-action fact gate.
effects:
- type: faction_reaction
faction: the-ring
@@ -611,14 +613,14 @@ outcomes:
faces an awkward return to normalcy. Both know the ring isn't gone — just quiet.
conditions:
facts_known:
- "ring.cargo_discrepancy_pattern"
- "ring.cargo_discrepancy_pattern" # detective found some evidence — ring responds
events_fired:
- kael_goes_cold # event ID — Kael's behavioral shift fired
flags_set:
- kael_missed_drop # set by drop_happens_without_kael — ring destabilized
flags_not_set:
- kael_message_sent
ticks_since_activation: 2400
# Mutually exclusive with ring_completes via facts_known/facts_not_known on
# ring.cargo_discrepancy_pattern. No auto-flag gate needed.
effects:
- type: npc_disposition
npc_role: ring-leader
@@ -632,8 +634,38 @@ outcomes:
reaction: suspicious
description: "The ring is alerted to exposure risk. Future operations will be more careful."
# 5. MODULE EXPIRY (quiet exit)
# Player never engaged. Module times out without drama.
# 5. INVESTIGATION STALLS (post-splinter exit)
# The ring splinters but the detective never breaks through to the pivot evidence.
# Explicit terminal exit for the non-terminal ring_splinters state.
- outcome_id: ring_stalemate
label: "Investigation Stalls"
is_terminal: true
description: >
The ring went dark after the splinter. The detective has the cargo discrepancy
on record — enough to flag, not enough to pursue. The case stays open but cold.
No arrests. No answers. Kael stays in the district, the only person who knows
the full shape of what happened, with no one left to tell it to.
The ring will reconstitute elsewhere. It always does.
conditions:
facts_known:
- "ring.cargo_discrepancy_pattern" # ring_splinters already fired (same gate)
facts_not_known:
- "ring.kael_unauthorized_corridor_access" # detective never reached the pivot evidence
flags_set:
- kael_missed_drop
- final_shipment_known # ring finished while investigation stalled
ticks_since_activation: 4500 # 2100 ticks after ring_splinters window — investigation ran cold
effects:
- type: faction_reaction
faction: lattice-commission
reaction: neutral
description: "The discrepancy flag stays in Maret's file. No follow-up action."
- type: npc_exit
npc_role: ring-leader
description: "Voss quietly transfers. No announcement, no incident report."
# 6. MODULE EXPIRY (quiet exit)
# Player never engaged at all. Module times out without drama.
# NOTE (Gestalt, Sprint 18): Condition uses facts_not_known, not flags_not_set.
# kael_behavior_changed fires automatically at tick 300 (time-triggered), making
# flags_not_set: [kael_behavior_changed] permanently false after tick 300.