← Back to the game
The Friday Night Elsewhere · build process

The Friday Night Elsewhere

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

  1. 1
    Write the Story source

    Scenes, lines, choices, flags, checkpoints, endings — the canonical story graph, hand-authored.

    edit context/storybook.json
  2. 2
    Validate & Build derived
    • every path reaches an ending
    • no orphans or cycles
    • flag logic sound
    • 2–3 choices per decision
    • per-path runtime report

    Outputs story/Dialogue.luau and context/story-chapters.md.

    python3 tools/story/build-story.py
  3. 3
    Generate Voice Lines derived, committed

    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
  4. 4
    Stitch Scene Audio derived

    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
  5. 5
    Package for Web derived

    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.

Phase A · Plan
Shot list

/storyboard-plan breaks a scene's lines into frames — shot type, composition, mood — sized to the scene's actual length. Writes context/storyboard.json.

Phase B · Render
Generate frames

Drives ChatGPT per planned frame against a shared style/character anchor, downloads images, gated per-scene for review.

Phase C · Publish
Wire & rebuild

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.