Branching Story

Overview

The BranchingStoryGraph component is the runtime hub for branching narratives. It lives on a scene GameObject so it can reference scene assets directly, manage trigger colliders, and dispatch story events without the indirection of ScriptableObjects.

The component keeps the authoritative state of the current branch, visited nodes, active flags, and branch-specific object visibility while exposing events for external systems such as UI, save systems, and analytics. Flags are scoped into timeline-local, traveler, and global layers so that branch rewinds restore only what should change while preserving cross-branch knowledge.

Branching story graphs are the backbone of celebrated narrative adventures, including:

  • Detroit: Become Human, where cascading quick-time choices lead to entirely different investigation timelines and endings.

  • Mass Effect, whose squad loyalty arcs and climactic decisions ripple across sequels.

  • The Witcher 3, which locks and unlocks political resolutions based on how Geralt resolves regional questlines.

  • Life is Strange, whose Time-Rewind mechanic mirrors Crystal Save's TimeMachine integrations for decision do-overs.

  • Steins;Gate, a visual novel whose divergent "world lines" highlight how flag-driven branching reveals alternate truths.

These experiences use branching structures to deliver meaningful agency, showcase alternate perspectives, and encourage replays—all goals the Crystal Save tooling enables when authoring your own content.

Core Data Model

Each story point is represented by a StoryNode that stores editor placement, presentation data, optional audio/video payloads, and flag/branch metadata directly on the component. Supporting records such as NodeConnection, GroupData, FlagCondition, and FlagAction keep the graph structure and rule logic together with each graph instance.

Node Types at a Glance

The graph ships with a wide catalog of node types so designers can mix triggers, branching logic, and multimedia beats without coding. All types are editable in-scene and can fire custom UnityEvents when activated or completed.

Node type
Purpose

Start

Entry point that usually plays intro narration or establishes default flags before advancing.

Trigger

Spatial or scripted trigger that can auto-create colliders, highlight objects, and gate progress; configurable activation modes (enter/stay/exit/manual).

Decision

Presents a decision point, often paired with Choice nodes for branching UI or dialogue.

Choice

Represents a selectable option from a decision; can spawn or switch TimeMachine branches when picked.

Ending

Marks a terminal outcome and can drive ending-specific UI or analytics flows.

FlagCheck / SetFlag

Branches logic based on accumulated flags or mutates scopes when milestones are hit.

BranchCheck

Allows narrative beats that only fire on specific TimeMachine branches (e.g., reveal content after a revisit).

Action

Executes designer-authored UnityEvents and immediately advances the graph, ideal for glue logic between systems.

CreateBranch

Issues a new branch in the TimeMachine timeline, capturing metadata such as branch name and description for visualizers.

Wait

Pauses progression for a fixed duration, frame count, or random interval, supporting pacing and timed reveals.

BranchVisibility

Shows or hides branches in UI visualizers to control spoiler exposure or guide the player.

Event

Parallel listener that reacts to flag changes, branch switches, node arrivals, or inputs, optionally limited to one fire per playthrough.

VideoPlayer / AudioPlayer

Inline cinematic nodes that manage playback, skipping input, and auto-advance behaviour for rich media moments.

InstructionList / Conditions / GC2Event

If GC2 is installed: Hooks into Game Creator 2 instruction lists, condition checks, and events so GC2 content slots directly into the flow.

Game Creator 2 smart detection

Crystal Save automatically scans your project for Game Creator 2 assemblies and toggles the appropriate scripting defines when they are present, so Branching Story Graph features light up without any manual setup. When GC2 is available the Branching Story Graph editor reveals dedicated add-node menu entries for Instruction Lists, Conditions, and GC2 Events, matching the extra node types shown in the catalog above.

If a project without GC2 loads a graph that references those nodes, the runtime gracefully warns the team and auto-advances to keep the story playable, ensuring the same scene can ship with or without the GC2 toolchain installed.

Editor Workflow

All authoring flows through the Story Graph Editor window (Tools/Crystal Save/Time Crystal/Story Graph Editor or through the BranchStoryGraph component, see screenshot above). The editor mirrors Unity tools like Animator by editing the selected scene component, tracks the last edited graph, and keeps the view synchronized across play/edit mode transitions.

Runtime Management with StoryGraphManager

StoryGraphManager is the default implementation of IStoryGraphManager. It binds a single BranchingStoryGraph, wires up UI references (decision panels, branch visualizer, ending overlay), and handles cursor state for narrative overlays.

Inside the Crystal Save Settings, the "Configuration Preset" dropdown lists all TimeMachine presets and describes their intended mechanics. The Branching Story preset is explicitly positioned for choice-driven narratives like Life is Strange or Steins;Gate, with accumulative branch copies so prior timelines remain explorable.

Extending via IStoryGraphManager

Custom teams can replace the default manager by implementing IStoryGraphManager. The interface exposes branch queries, rewind control, cursor overrides, and a branch-changed event so alternative UIs or gameplay systems stay compatible with the graph component.

When creating a custom manager, follow the same lifecycle as the reference implementation: connect to BranchingStoryGraph events, forward branch creation to GameObjectTimeMachine, and maintain GraphBranchData so rewinds reconstruct flags, used nodes, visited nodes, and visibility states exactly as the player left them. You can then plug in your own decision UI, voiceover systems, or analytics without modifying the core graph or editor tooling.

Last updated