Populate cast[] (kind:'npc') for every Continuum scenario, transcribed
from the gm-utility NPC sources — normalising the two schemas (console
{id,name,ess,sec} and module {name,tag,secret}) into
{ id, name, kind, note, secret? }. 57 NPCs total. Pregens/PCs excluded
(separate character-sheet system).
No cast UI consumer yet — the design reserves scenario.cast for a future
cast dashboard, so this is a data-model port guarded by
tests/scenarios/cast.test.js (shape + unique ids). 131 tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
32 lines
3.3 KiB
JavaScript
32 lines
3.3 KiB
JavaScript
export default {
|
||
meta: { id: 'afterimage', title: 'AFTERIMAGE', system: 'year-zero', players: 4, playMinutes: 210, slot: 'Fri · Slot 2' },
|
||
timeline: [
|
||
{ id: 'a1-open', act: 1, label: 'The pier — the case lands', targetMin: 0, hardTrigger: true },
|
||
{ id: 'a1-parlor', act: 1, label: 'Parlor 88 interview', targetMin: 35, cutHint: 'Summarise the ledger; skip the tea ritual' },
|
||
{ id: 'a2-market', act: 2, label: 'The Market', targetMin: 90 },
|
||
{ id: 'a2-doorcam', act: 2, label: 'Door-cam reveal', targetMin: 120, hardTrigger: true, notes: 'The pivot — do not let this slip past 2:15' },
|
||
{ id: 'a3-pier', act: 3, label: 'Pier confrontation', targetMin: 175, hardTrigger: true },
|
||
{ id: 'epilogue', act: 4, label: 'Baseline / ambiguous end', targetMin: 200 },
|
||
],
|
||
clues: [
|
||
{ id: 'c1', label: 'The door-cam face that cannot exist (hand the still around as an object)', essential: true },
|
||
{ id: 'c2', label: 'The ledger: A-1 · A-2 · A-3 — and A-3’s file just reads “retired”', essential: true },
|
||
{ id: 'c3', label: 'The identical childhood, recited twice across the split', essential: true, fallback: 'the monologue cards ×2' },
|
||
{ id: 'c4', label: 'The spike was intimate — face to face, not an execution (Avis)', essential: true },
|
||
{ id: 'c5', label: 'Pier + dawn deadline known before 2:45', essential: true, fallback: 'both Act Two tracks carry it' },
|
||
{ id: 'c6', label: 'Whisper-9 is stolen Wallace property — why Corvin has legal cover', essential: true },
|
||
],
|
||
cast: [
|
||
{ id: 'cmdr-bryant', name: 'Cmdr. Bryant', kind: 'npc', note: 'RDU commander — ally, guarded', secret: 'If asked to expedite the IDENT CONFLICT desk review: “Can’t. Wallace liaison put a hold on all RDU record reviews tonight. Funny, that.”' },
|
||
{ id: 'dr-avis', name: 'Dr. Avis', kind: 'npc', note: 'Coroner — friendly' },
|
||
{ id: 'wren-unit-a-1', name: 'Wren (unit A-1)', kind: 'npc', note: 'The runner — flight, then fragile trust', secret: 'If she escapes: origami sparrow under the wiper — YOU WANT THE TRUTH. THE PIER. DAWN.' },
|
||
{ id: 'lark-unit-a-2', name: 'Lark (unit A-2)', kind: 'npc', note: 'The still one — cooperative, composed', secret: 'Under the grief: relief at being found out, without knowing for what.' },
|
||
{ id: 'aris-kade', name: 'Aris Kade', kind: 'npc', note: 'The original — 38, exhausted beyond fear', secret: 'Truth-ending lever: “Say something. One of you. They’re your witnesses too.”' },
|
||
{ id: 'corvin', name: 'Corvin', kind: 'npc', note: 'Wallace Asset Protection — a deadline in a good coat', secret: 'His warrant covers units and media ONLY — no paper on a human. A human homicide collapses his pretext. He will trade. Even his defeats are tidy.' },
|
||
{ id: 'ap-officers-2', name: 'AP Officers ×2', kind: 'npc', note: 'Follow the warrant, not the man' },
|
||
{ id: 'street-extras-improv', name: 'Street extras (improv)', kind: 'npc', note: 'Off-script encounters', secret: 'Fortune-teller line, aimed at a replicant PC: “Two birds with one song. The cage is open, officer. Whose hand closed it?”' },
|
||
{ id: 'auntie-bo', name: 'Auntie Bo', kind: 'npc', note: 'Night-market broth queen — stall 44', secret: 'Will never sell Wren out — a phone call ahead only means Wren is already spooked.' },
|
||
],
|
||
props: [],
|
||
};
|