Skip to content

ADR-023: Campaign Narrative Flow — Preamble Before, Interlude Optional After

Status: Accepted Date: 2026-04-10 Context: When a campaign chapter starts, players land directly on a scenario with a wall of text and choices — no atmosphere, no story setup. The CampaignInterlude typewriter component exists but only runs AFTER rounds. Players need a narrative entrance before each round (the "Brennan Lee Mulligan moment"). Additionally, after a round there's a results screen with voting/discussion, and players may want to leave rather than immediately continue — so the post-round interlude timing needs thought.

Decision

Preamble (Before the Round)

Each campaign chapter gets a full-screen narrative preamble before the scenario appears:

  • Uses the existing CampaignInterlude typewriter renderer
  • AI-generated from the chapter intro seed text, expanded into 4-8 narrative blocks (prose + optional dialogue)
  • Chapter 1 preambles are longer and more world-establishing; later chapters are shorter bridges
  • Ends with a "Begin" button that starts the actual scenario
  • Generated when the round starts (after ready-up resolves, before scenario loads)

Interlude (After the Round)

The post-round interlude becomes optional and deferred:

  • After the round completes, players see the normal results screen (sync scores, AI prediction, stand/change)
  • Results screen shows "Continue the Story" (as it does now) — this goes back to the campaign progress page
  • The interlude plays as the preamble of the NEXT chapter, not as a postlude of the current one
  • This means: preamble for Chapter 2 = bridge from Chapter 1's outcome + setup for Chapter 2

This simplifies the flow to one narrative moment per chapter (the preamble) rather than two (preamble + interlude). The preamble for Chapter N+1 naturally incorporates the outcome of Chapter N.

The Flow

Campaign page
  → "Start Round" (ready-up for multiplayer)
  → Preamble screen (typewriter, AI-generated from chapter intro + prior outcomes)
  → "Begin" button
  → Scenario (the sync game)
  → Results (scores, stand/change, discussion)
  → "Back to Campaign"
  → Campaign page (next chapter unlocked)

For Chapter 1, the preamble is pure world-building. For Chapters 2+, the preamble weaves in what happened last time.

Preamble Generation

The AI narrator receives: - The chapter's intro text (seed) - The campaign's narrative voice prompt (tone/style) - Prior chapter outcomes (from narrative_history) - Whether this is Chapter 1 (world-building mode) or a later chapter (bridge mode)

And generates NarrativeBlock[] with the same prose/dialogue format used by CampaignInterlude.

Rationale

  • One narrative moment is better than two. Bookending each round with a preamble AND interlude would slow the pace and feel repetitive. Players finish a round with the results buzz — let them sit with that. The story resumes when they're ready for the next chapter.
  • Preamble as bridge solves the "what happened last time" problem. The Chapter 3 preamble naturally says "After your decision to share the water supply, three weeks passed and..." — combining recap and setup.
  • Players control the pace. After results, they go back to the campaign page. They can read the arc timeline, check cohesion, or start the next chapter when ready. No forced narrative.
  • AI generation keeps it fresh. Same chapter, different playthrough, different preamble — because the outcomes differ.

Consequences

  • The interlude trigger (?interlude=true on campaign page) is replaced by preamble generation at round start
  • The preamble screen needs to exist between "ready-up resolves" and "scenario loads"
  • Chapter intros in the database remain as seeds — they don't need to be expanded since AI does the expansion
  • The narrative_history JSONB still accumulates entries, but they're written at preamble time (capturing prior chapter's outcome) rather than post-round

Key files: - src/app/(app)/campaigns/[id]/page.tsx — preamble screen state - src/components/campaign/CampaignInterlude.tsx — typewriter renderer (reused) - src/lib/ai/campaign-narrator.ts — needs a "preamble" mode - src/app/api/campaigns/[id]/preamble/route.ts — new API to generate preamble