A voiced choose-your-own-adventure, built as a story-first pipeline: everything downstream — dialogue audio, captions, the web app — is derived from one authored story graph.
Story → Web pipeline
Scenes, lines, choices, flags, checkpoints, endings — the canonical story graph, hand-authored.
edit context/storybook.json
Outputs story/Dialogue.luau and context/story-chapters.md.
python3 tools/story/build-story.py
Per-line mp3s from a local neural TTS toolchain (Kokoro) — one distinct voice per character, cast in voice-cast.json. Committed to audio/lines/ so voices work on a fresh clone with no setup.
python3 tools/voice-tools/scripts/generate-voice-lines.py --dialogue story/Dialogue.luau
Combines each scene's line clips into one mp3, with exact per-line timing offsets so captions stay in sync.
python3 tools/story/build-scene-audio.py
Bundles the story graph and stitched audio into web/story.json + web/audio/, consumed by the hand-written static app (index.html / app.js / style.css).
python3 tools/story/build-web.py
Parallel: Storyboard Art
Scene illustrations shown behind captions. Three phases, each separately invocable and safe to stop between.
/storyboard-plan breaks a scene's lines into frames — shot type, composition, mood — sized to the scene's actual length. Writes context/storyboard.json.
Drives ChatGPT per planned frame against a shared style/character anchor, downloads images, gated per-scene for review.
Approved frames get written into storybook.json's frames field, then the web app rebuilds and redeploys.
Converges at Step 5 — published frames flow into the same build-web.py package as the story and audio.