Add a deterministic authoring tool that turns a structured scenario markdown file into a validated scenario-data module: - tools/scenario-md.js: pure parseScenarioMarkdown + emitScenarioModule (frontmatter → meta; ## Timeline/## Clues/## Cast lists → the arrays; auto-slugged ids; validated via validateScenario before emit). - tools/md-to-scenario.mjs: CLI (npm run gen:scenario), file or stdout. - tools/example-scenario.md: documented format example. Parses a defined format, not freeform con prose. tools/ is dev-only and never bundled. tests/tools/scenario-md.test.js round-trips + validates. 187 tests pass; build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
37 lines
1.1 KiB
Markdown
37 lines
1.1 KiB
Markdown
---
|
|
id: example-md
|
|
title: EXAMPLE — Generated From Markdown
|
|
system: year-zero
|
|
players: 4
|
|
playMinutes: 210
|
|
slot: Fri · Slot 2
|
|
---
|
|
|
|
# Notes are ignored — only frontmatter and the sections below are parsed.
|
|
|
|
## Timeline
|
|
|
|
Beats are `[minutes-from-start] label`. Add `{hard}` for a hard trigger,
|
|
`| cut: …` for a cut hint, and `#id` to pin a stable id (else it is slugged).
|
|
|
|
- [0] The opening beat {hard} #a1-open
|
|
- [35] Parlor interview | cut: summarise the ledger; skip the tea ritual
|
|
- [120] The reveal {hard}
|
|
- [200] Ambiguous epilogue
|
|
|
|
## Clues
|
|
|
|
`{essential}` marks a clue the ending needs; `{act: …}` tags the act;
|
|
`| fallback: …` is how to deliver it if missed.
|
|
|
|
- The door-cam face that cannot exist {essential} {act: Act One} | fallback: the monologue cards
|
|
- The identical childhood, recited twice {essential}
|
|
- A colour detail {act: Act One}
|
|
|
|
## Cast
|
|
|
|
`NAME — one-line note`, optionally `| secret: …`, and `{pc}` for a player character.
|
|
|
|
- MARY FLETCHER — Innkeeper; saw the watchers | secret: she saw Crowe sew the pendant
|
|
- DANNY TATE — Stable boy, 14
|