Branching Story Example
An advanced campaign demonstrating diverging narrative paths, moral choices, and multiple endings. Every field below is one the app actually reads.
This page previously contradicted Campaign Structure. An earlier version used
episodeId+
name for episodes and a top-level
quests array with a
status field ("available"/"hidden") that doesn't exist anywhere in the real app. It's been rewritten to use
episodeNumber+
title and the real
questTemplates shape - quests aren't "hidden," they simply get accepted by a scene's
questActions whenever the DM reaches that branch.
Campaign Overview
The Cult of the Serpent
Level: 3-6
Duration: 5-8 sessions
Synopsis: A mysterious cult is growing in power. The party's choices determine whether they become heroes, villains, or something in between.
Features Demonstrated:
- Three distinct narrative branches
- Multiple endings (ally with cult, destroy cult, neutral path)
- Quest failure leading to alternative storylines
- Moral gray areas and consequences
- Faction reputation system
- Exclusive quest paths based on prior choices
Story Structure Diagram
Scene 1: Introduction
|
Scene 2: Quest Accept
|
Scene 3: First Contact
/ | \
/ | \
/ | \
Ally Path Neutral Path Destroy Path
(Scene 4a) (Scene 4b) (Scene 4c)
| | |
(Scene 5a) (Scene 5b) (Scene 5c)
| | |
Ending A Ending B Ending C
A Key Subtlety: Quest Matching Is Scoped to the Current Episode
Verified against processQuestActions(): when a choice's questActions fires, the app looks up the quest name in getEpisode(this.currentState.episodeNumber).questTemplates - the episode it currently thinks it's in at the moment the choice is clicked, which is before that click's scene transition takes effect (episode transitions are detected inside showScene(), which runs after quest actions are processed). Practically, this means: a quest template must be defined in the questTemplates of whichever episode is "current" when each of its accept/complete/fail actions fires - not just wherever the quest was first introduced. The example below defines Investigate the Cult plus all three follow-on quests in episode 1 (since all four are accepted or completed while episode 1 is still current), and duplicates each follow-on quest's definition into the branch episode that later completes or fails it.
Complete Campaign JSON (Key Scenes)
{
"id": "cult-of-serpent",
"name": "The Cult of the Serpent",
"description": "A morally complex campaign where the DM's choices shape the story's direction and outcome.",
"levelRange": { "min": 3, "max": 6 },
"episodes": [
{
"id": 1,
"episodeNumber": 1,
"title": "The Investigation",
"questTemplates": [
{
"name": "Investigate the Cult",
"type": "investigation",
"description": "Learn more about the mysterious cult operating near {nearestBurg}",
"rewards": { "xp": 150 }
},
{
"name": "Destroy the Cult",
"type": "combat",
"description": "Eliminate the cult threat permanently",
"rewards": { "xp": 400, "reputation": { "faction": "The Temple", "value": 25 } }
},
{
"name": "Join the Cult",
"type": "faction",
"description": "Embrace the serpent's wisdom and power",
"rewards": { "xp": 400, "reputation": { "faction": "The Cult", "value": 25 } }
},
{
"name": "Broker Peace",
"type": "diplomacy",
"description": "Find a middle ground between the cult and the town",
"rewards": { "xp": 500, "gold": 100 }
}
],
"scenes": [
{
"sceneId": "ep1-scene1",
"title": "Strange Happenings",
"readAloud": "<div class='read-aloud'><p>People in {nearestBurg} have been disappearing. Not kidnapped - they simply leave in the night, abandoning everything.</p><p>The town priest, Father Aldous, suspects a cult. 'They gather in {nearestDungeon:type=Ancient-Crypt},' he says. 'We must stop them before more souls are lost.'</p></div>",
"choices": [
{
"text": "Accept quest to investigate the cult",
"nextScene": "ep1-scene2",
"questActions": ["accept:Investigate the Cult"]
}
]
},
{
"sceneId": "ep1-scene2",
"title": "The Crypt",
"readAloud": "<div class='read-aloud'><p>You approach {nearestDungeon:type=Ancient-Crypt} at dusk. Hooded figures chant in an ancient language. At the center, a woman in crimson robes addresses the gathered crowd.</p><p>'We offer knowledge,' she calls out. 'The serpent teaches truth that your priests hide from you.'</p></div>",
"choices": [
{
"text": "Attack the cult immediately",
"nextScene": "ep1-scene3-attack"
},
{
"text": "Approach peacefully and listen to their teachings",
"nextScene": "ep1-scene3-listen"
},
{
"text": "Observe from hiding (Stealth check)",
"nextScene": "ep1-scene3-observe"
}
]
},
{
"sceneId": "ep1-scene3-attack",
"title": "The Destroy Path Begins",
"readAloud": "<div class='read-aloud'><p>You draw weapons and charge. The cultists scatter, but the woman in crimson stands her ground.</p><p>'So you choose violence,' she says sadly. 'Very well. You will learn nothing today but regret.'</p><p>You defeat them, but find no evidence of wrongdoing - just religious texts and personal belongings.</p></div>",
"dmNotes": {
"enemies": {
"cultists": { "count": 4, "hp": 9, "ac": 11 },
"high_priestess": { "count": 1, "hp": 58, "ac": 14 }
}
},
"choices": [
{
"text": "Continue hunting cult members",
"nextScene": "ep2-destroy-path",
"questActions": [
"complete:Investigate the Cult",
"accept:Destroy the Cult"
]
}
]
},
{
"sceneId": "ep1-scene3-listen",
"title": "The Ally Path Begins",
"readAloud": "<div class='read-aloud'><p>You step forward peacefully. The woman in crimson smiles.</p><p>'Welcome, seekers. I am Sister Vexis. We offer knowledge the temple hoards - healing arts, ancient wisdom, truths about the gods.'</p><p>'The temple calls us evil because we threaten their monopoly on divine power. But judge for yourself - have we harmed anyone?'</p></div>",
"choices": [
{
"text": "Join the cult and learn their ways",
"nextScene": "ep2-ally-path",
"questActions": [
"complete:Investigate the Cult",
"accept:Join the Cult"
]
},
{
"text": "Politely decline and return to report your findings",
"nextScene": "ep1-scene3-neutral"
}
]
},
{
"sceneId": "ep1-scene3-observe",
"title": "The Neutral Path Begins",
"readAloud": "<div class='read-aloud'><p>You watch from the shadows, gathering information. The cult teaches healing magic, philosophy, and meditation. No sacrifices, no dark rituals - just... learning.</p><p>However, you also notice their teachings contradict the temple's doctrine on several key points.</p></div>",
"choices": [
{
"text": "Report back to Father Aldous with your findings",
"nextScene": "ep1-scene3-neutral"
}
]
},
{
"sceneId": "ep1-scene3-neutral",
"title": "A Difficult Choice",
"readAloud": "<div class='read-aloud'><p>You return to Father Aldous with your report. He's furious.</p><p>'Heretics! They must be destroyed!' he demands. 'Will you help us, or do you side with blasphemers?'</p><p>But you're not sure the cult is truly evil. They seem to genuinely help people.</p></div>",
"choices": [
{
"text": "Help the temple destroy the cult",
"nextScene": "ep2-destroy-path",
"questActions": [
"complete:Investigate the Cult",
"accept:Destroy the Cult"
]
},
{
"text": "Refuse and try to broker peace between temple and cult",
"nextScene": "ep2-neutral-path",
"questActions": [
"complete:Investigate the Cult",
"accept:Broker Peace"
]
},
{
"text": "Side with the cult against the temple",
"nextScene": "ep2-ally-path",
"questActions": [
"complete:Investigate the Cult",
"accept:Join the Cult"
]
}
]
}
]
},
{
"id": 2,
"episodeNumber": 2,
"title": "The Purge",
"questTemplates": [
{
"name": "Destroy the Cult",
"type": "combat",
"description": "Eliminate the cult threat permanently",
"rewards": { "xp": 400, "reputation": { "faction": "The Temple", "value": 25 } }
}
],
"scenes": [
{
"sceneId": "ep2-destroy-path",
"title": "Hunting Heretics",
"readAloud": "<div class='read-aloud'><p>You've chosen to eliminate the cult. Father Aldous provides you with a list of known members in {nearestBurg}.</p><p>As you hunt them down, you notice many are just ordinary people - healers, teachers, farmers - who joined seeking knowledge. But orders are orders.</p></div>",
"choices": [
{
"text": "Finish the purge and report back",
"nextScene": "ep2-destroy-ending",
"questActions": ["complete:Destroy the Cult"]
}
]
},
{
"sceneId": "ep2-destroy-ending",
"title": "Ending: The Purge",
"readAloud": "<div class='read-aloud'><p>The cult is destroyed. {nearestBurg} returns to the temple's control.</p><p>Father Aldous thanks you, but the townsfolk look at you with fear. You killed healers, teachers, friends.</p><p>The temple's power is secure, but at what cost?</p><p><strong>Ending: Zealot's Path</strong></p></div>",
"choices": []
}
]
},
{
"id": 3,
"episodeNumber": 3,
"title": "The Serpent's Embrace",
"questTemplates": [
{
"name": "Join the Cult",
"type": "faction",
"description": "Embrace the serpent's wisdom and power",
"rewards": { "xp": 400, "reputation": { "faction": "The Cult", "value": 25 } }
}
],
"scenes": [
{
"sceneId": "ep2-ally-path",
"title": "Initiation",
"readAloud": "<div class='read-aloud'><p>Sister Vexis welcomes you into the cult. You learn their healing arts and ancient knowledge.</p><p>But the temple is preparing to attack. Father Aldous has declared the cult heretical and called for its destruction.</p><p>'We must defend ourselves,' Sister Vexis says. 'Will you stand with us?'</p></div>",
"choices": [
{
"text": "Defend the cult against the temple",
"nextScene": "ep2-ally-ending",
"questActions": ["complete:Join the Cult"]
}
]
},
{
"sceneId": "ep2-ally-ending",
"title": "Ending: New Order",
"readAloud": "<div class='read-aloud'><p>You defend the cult against the temple's forces. Father Aldous falls in battle.</p><p>The cult takes control of {nearestBurg}. Knowledge flows freely now, healing magic available to all.</p><p>But some whisper that you've simply replaced one dogma with another.</p><p><strong>Ending: Serpent's Champion</strong></p></div>",
"choices": []
}
]
},
{
"id": 4,
"episodeNumber": 4,
"title": "The Middle Path",
"questTemplates": [
{
"name": "Broker Peace",
"type": "diplomacy",
"description": "Find a middle ground between the cult and the town",
"rewards": { "xp": 500, "gold": 100 }
}
],
"scenes": [
{
"sceneId": "ep2-neutral-path",
"title": "Mediation",
"readAloud": "<div class='read-aloud'><p>You attempt to broker peace. Both sides reluctantly agree to meet.</p></div>",
"choices": [
{
"text": "DC 16 Persuasion - Success: Achieve lasting peace",
"nextScene": "ep2-neutral-success",
"questActions": ["complete:Broker Peace"]
},
{
"text": "DC 16 Persuasion - Failure: Negotiations break down",
"nextScene": "ep2-neutral-war",
"questActions": ["fail:Broker Peace"]
}
]
},
{
"sceneId": "ep2-neutral-success",
"title": "Ending: Balance Restored",
"readAloud": "<div class='read-aloud'><p>Through diplomacy, you achieve the impossible - the temple and cult agree to coexist.</p><p>{nearestBurg} benefits from both traditions. The temple maintains moral authority, while the cult provides healing and education.</p><p>Your name is spoken with reverence as the Peacemaker.</p><p><strong>Ending: Wisdom's Path</strong></p></div>",
"choices": []
},
{
"sceneId": "ep2-neutral-war",
"title": "Ending: Civil War",
"readAloud": "<div class='read-aloud'><p>Your mediation fails. War erupts between temple and cult.</p><p>{nearestBurg} tears itself apart. Both sides suffer devastating losses.</p><p>You leave the burning town behind, haunted by your failure to prevent the bloodshed.</p><p><strong>Ending: Ashes</strong></p></div>",
"choices": []
}
]
}
]
}
Why episode numbers 2, 3, 4 for three mutually-exclusive branches? getEpisode() finds the first episode object matching a given episodeNumber, so three different branch episodes can't all reuse episodeNumber: 2 - only the first one would ever be found. Since only one branch is ever visited per playthrough, non-sequential episode numbers across parallel branches are fine; they don't need to represent story chronology.
Key Features Explained
1. True Branching Structure
Unlike linear campaigns, this creates three completely different story paths:
- Destroy Path: Hunt and eliminate cultists
- Ally Path: Join the cult and fight the temple
- Neutral Path: Broker peace or fail trying
2. Four Different Endings
- Zealot's Path: Cult destroyed, temple victorious
- Serpent's Champion: Cult victorious, temple destroyed
- Wisdom's Path: Successful peace negotiation
- Ashes: Failed negotiation, civil war
3. Exclusive Quest Chains
Notice how each branch's accept: action fires alongside complete:Investigate the Cult, so only one of the three follow-on quests ever gets accepted per playthrough:
Initial: "Investigate the Cult" (accepted at ep1-scene1)
Then, depending on the choice at ep1-scene3-*:
→ "Destroy the Cult" (accepted if you attack)
→ "Join the Cult" (accepted if you ally)
→ "Broker Peace" (accepted if you observe/negotiate)
4. Moral Gray Area
No choice is clearly "good" or "evil":
- Destroy Path: Maintains order, but kills innocent people
- Ally Path: Spreads knowledge, but replaces one dogma with another
- Neutral Path: Seeks peace, but might fail catastrophically
Design Patterns
Pattern 1: Point of No Return
Scene 3 is the branching point. After this choice, paths never converge:
ep1-scene3-attack → Episode 2 "The Purge" → Ending A
ep1-scene3-listen → Episode 3 "The Serpent's Embrace" → Ending B
ep1-scene3-observe → Episode 4 "The Middle Path" → Ending C or D
Pattern 2: Cascading Consequences
Early choices affect later options:
- Attack in Scene 3 → Cannot join cult later
- Join cult in Scene 3 → Cannot negotiate peace
- Observe in Scene 3 → All paths remain open
Pattern 3: Failure Creates Story
Failed neutral path doesn't end campaign - it creates a unique "civil war" ending:
Persuasion Success → "Wisdom's Path" ending
Persuasion Failure → "Ashes" ending (still valid conclusion)
Customization Ideas
Add More Branch Points
Create sub-branches within each path:
{
"text": "Spare the cult children",
"nextScene": "ep2-destroy-merciful"
},
{
"text": "Show no mercy to anyone",
"nextScene": "ep2-destroy-ruthless"
}
Add Reconciliation Path
Allow players to switch paths mid-campaign:
Started Destroy Path → Discover temple corruption → Switch to Ally Path
Add Hidden Ending
Unlock secret ending if specific conditions met:
- Never killed anyone
- Discovered ancient prophecy
- United both factions against greater threat
Testing Branching Campaigns
Critical: Test every path from start to finish. Branching campaigns multiply testing requirements.
Path Testing Checklist
- ✓ Play through Destroy Path completely
- ✓ Play through Ally Path completely
- ✓ Play through Neutral Path with success
- ✓ Play through Neutral Path with failure
- ✓ Verify all quest transitions work correctly
- ✓ Ensure each ending provides satisfying closure
Best Practices for Branching
1. Clearly Signal Branch Points
Make it obvious when choices have major consequences:
✓ Good: "This choice will determine your allegiance"
✗ Bad: Hidden consequences players don't see coming
2. Make All Paths Equal Length
Don't punish players for choosing one path over another:
✓ Good: Destroy Path (5 scenes), Ally Path (5 scenes), Neutral Path (5 scenes)
✗ Bad: Destroy Path (8 scenes), Ally Path (2 scenes) - feels unbalanced
3. Ensure All Endings Are Satisfying
Even "bad" endings should feel complete:
✓ Good: Civil War ending shows consequences and aftermath
✗ Bad: "You failed. Campaign over." (no closure)
See Also