Files
nightclub-arcadia/NightclubArcadia/Assets/Dialogue/Scenes/SC101.yarn
T
lennartandClaude Opus 5 f1fadf7909 add a writer-facing content pipeline under writing/
Dialogue was already plain text, so the gap was never the .yarn files. It was
that the character material a writing session needs was either missing or stored
somewhere a writer could not comfortably work.

Three things were wrong. The writing handbook was not in the repo and was cited
by SC101.yarn as though it were. The best voice material — register, verbal tics,
success/failure/passive samples — was a \n-escaped string inside a JSON field.
The named NPCs had no sheets at all, existing only as their Yarn lines.

writing/ now holds the dialogue-facing layer, at the repo root so it gets no
.meta files and is not a Unity asset:

  STYLE.md          register, the five tone moves, the ban list, branching
                    shapes, the Wrong Truth rule, flag families, candidate rules
  YARN-PRIMER.md    the one page of syntax needed to write a scene
  GLOSSARY.md       in-world and project vocabulary
  voices/           the eleven skill voices, one readable sheet each
  characters/       Bartender, Chevalier Cassian Thal, Bradford Kane
  scenes/           SC-101's brief: intent, beats, checks, constraints
  lore/             the three identity readings and the rules that bind them

STYLE.md is a digest of the Mystery Writing Handbook in the Obsidian vault, with
pointers rather than copies. The vault stays the authoring home for design work,
and Ground Truth — the solution document — deliberately stays out of this repo.

The voice sheets are generated from skill_bible.json but are the source of truth
for the prose. tools/writing/sync_voices.py folds edits back; voicelib.py
guarantees notes -> dict -> notes is identity for all eleven, so --to-json on
unchanged sheets is byte-identical. VoiceSheetSyncTests fails the build on drift
in either direction, and was verified to fail on real drift rather than merely
to pass.

SC101.yarn's header is trimmed from prose rationale to the six rules that bind
while editing that file, with the reasoning moved to the scene brief.

EditMode 42/42. YarnCheck compiles 9 files / 35 nodes.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-25 20:23:42 +02:00

73 lines
3.5 KiB
Plaintext

// SC-101 — The Card at the Desk. Opening candidate hooks.
//
// Brief, beats, checks and the reasoning behind every rule below:
// writing/scenes/sc101-the-card-at-the-desk.md
//
// Rules that bind while editing THIS file — all six are deliberate, none is a
// leftover. The brief says why; this is the short form so you do not have to
// leave the file to avoid breaking it.
//
// 1. Scene files stay thin: set the stage, <<detour>> into hook nodes, return.
// 2. Evidence balance — one object / testimony / document / intuition per
// candidate. Never stack types. See Assets/Candidates/candidates.json.
// 3. Beat order is fixed: STANDING ORDER -> HOUSE POUR -> FACEWORK ->
// CONFLUENCE. Never <<if>>-guard a hook on another hook having fired, on any
// $self_lean_*, or on skill_rank(...).
// 4. Passive pattern for a clue-bearing hook: one voice, from the candidate's
// attached pair; the line is that voice's argument, never a report; exactly
// one $self_lean_* write, with $found_<clue_id> set alongside it.
// 5. Four voice introductions, against the handbook cap of three. Deliberate,
// SC-101 only — one voice per pair. Do not correct it down, do not copy it.
// 6. The body stays neutral: no lean, no candidate attachment outside the hooks.
title: Start
position: -17,-276
---
<<jump SC101_Desk>>
===
title: SC101_Desk
position: -19,-36
---
<<set $seen_sc_101 = true>>
<<set $visited_desk = true>>
Narrator: The mahogany doors are too heavy for the hinges someone recently, badly, tightened — you feel the extra half-second of resistance before either side gives. Beyond them: a hall built for four hundred people politely disagreeing about tariffs, hosting perhaps sixty, none of whom look like they've read the programme.
Narrator: Someone left a card with your name on it at the registration desk three hours before you decided to come. You don't remember deciding.
<<detour SC101_Hook_Inheritor>>
<<detour SC101_Hook_Neutral>>
<<detour SC101_Hook_Journalist>>
<<detour SC101_Hook_MadeAsset>>
Narrator: You're drawn toward a seat — toward a waiting conversation you didn't agree to have yet.
<<enter_environment>>
===
title: SC101_Hook_MadeAsset
position: -40,567
---
CONFLUENCE: One: the seating chart's alphabetical. Two: one gap in it, held open past the start time. Three, and three is the one, {$player_name}: whoever printed this knew you'd be late to your own arrival. Which means somebody in this room has already met you, {$player_name}, and you're the only one who doesn't know it.
<<set $found_made_asset_intuition = true>>
<<set $self_lean_made_asset += 1>>
===
title: SC101_Hook_Journalist
position: -299,452
---
FACEWORK: His hands gave it away before his face did — a flinch toward you, checked, turned into reaching for a drink that wasn't there. That's not a stranger's hands. What did you do to earn that flinch?
<<set $found_journalist_intuition = true>>
<<set $self_lean_journalist += 1>>
===
title: SC101_Hook_Inheritor
position: 335,366
---
STANDING ORDER: You are standing in a doorway, {$player_name_full}. That's the whole of what's certain. Build outward from there — a person who starts anywhere else is a person coming apart in public.
<<set $found_inheritor_intuition = true>>
<<set $self_lean_inheritor += 1>>
===
title: SC101_Hook_Neutral
position: 87,310
---
HOUSE POUR: Cigar smoke, spilled aperitif, and under it — cold, sharp — the ammonia bite of a floor mopped in a hurry, love. Someone's trying to make this room smell like money. It smells like panic with good cologne on top.
===