Learn / Guides /

Understanding branching complexity in visual novels

March 2026 6 min read Project Structure
Ren'Py Branching Story structure Visual maps

Every visual novel developer reaches a point where they can no longer hold the full story structure in their head. The script keeps growing, the menu choices multiply, and the question "does this choice actually matter?" stops having an obvious answer.

This isn't a writing problem. It's a structural visibility problem. Here's what's happening mathematically and what you can do about it.

Why simple scripts become hard to reason about

A visual novel script is a directed graph. Labels are nodes, jumps and calls are edges. When you write menu: with three options, you're creating three outgoing edges from one node — and those three paths may each branch further downstream.

At small scale this is easy to track mentally. Three labels, two choices, one merge point. You can sketch it on paper.

At medium scale — 50 labels, 20 choice points, 8 possible endings — paper sketches stop working. You're maintaining an implicit mental model of the graph, and that model degrades every time you write new content without looking at the whole structure.

Choice explosion: the numbers

The maximum number of distinct paths through a script grows exponentially with the number of branching choice points. For a simple binary-branching structure (every choice has exactly two options, no merging):

Choice pointsMaximum distinct pathsTestable manually?
532Easily
101,024With effort
1532,768No
201,048,576No

Most visual novels merge branches back together frequently — reducing the actual path count well below the theoretical maximum. But "merge at next chapter" is not the same as "all choices are equivalent." The paths between the choice and the merge point may contain different scenes, different assets, different variable states. Those intermediate paths each need to work correctly.

The consequence for testing You cannot test every path. That is true for almost any commercial visual novel. What you can do is verify the structure statically: confirm which labels exist, which ones are reachable, and which jumps point somewhere that doesn't exist.

What scripts look like as they grow

Early in a project, the flow is linear with occasional branches:

start └─ intro_scene └─ [ choice 1 ] ├─ path_a → chapter_2 └─ path_b → chapter_2

As the project grows, structure accumulates. New scenes are added between existing ones. Endings multiply. Variables start affecting which branches are reachable:

start └─ prologue └─ [ early choice ] ├─ route_a │ ├─ route_a_ch2 │ └─ [ mid choice ] │ ├─ route_a_good → chapter_3 │ └─ route_a_bad → chapter_3 └─ route_b ├─ route_b_ch2 └─ [ mid choice ] ├─ route_b_good → chapter_3 └─ route_b_bad → bad_end_1

Now add two more chapters, three more endings, variable-gated paths that only appear if a stat is above a threshold, and a hidden route added halfway through development — and you have a graph that no developer can keep accurate in memory.

Structural problems that only appear at scale

Dead labels

Labels that nothing jumps to. They were written, perhaps fully voiced and illustrated, but removed from the active story flow when the narrative changed. They still exist in the script file. They consume assets. They're invisible in a text editor.

Jump targets that don't exist

A jump ending_secret_route that was added before the label was created — and then the label creation was forgotten. The error only appears when a player reaches that exact point in the story.

# Added in chapter 5 refactor jump route_c_hidden_ending # The label was never written # This error waits for whoever reaches this path

Orphaned variable state

A variable is set in one branch and read in another, but the path that reads it can also be reached without ever setting it. The variable has its default value — which may produce a grammatically wrong dialogue line, a wrong character expression, or a silent logic error that accumulates through the rest of the game.

Why visual maps change what you can see

Reading a .rpy file is a linear experience. You see labels in the order they're written, not in the order a player experiences them. A jump at the bottom of a screen-length label sends execution somewhere that may be hundreds of lines away, across multiple files.

A visual map renders the same information as a graph — nodes for labels, edges for jumps and calls. On that map you can see, at a glance:

  • Which labels have no incoming edges (potential dead labels, or true entry points)
  • Which labels have no outgoing edges (endings, or labels that should have a jump but don't)
  • Where the story reconverges after branches
  • Which nodes have unusually many incoming edges (merge points that many paths pass through)
  • Whether the graph has connected components — isolated sub-graphs that can't be reached from the start

None of this is visible from a text editor. All of it is visible in seconds on a graph.

What changes at 100+ labels Below roughly 30 labels, most developers maintain an accurate mental model of their story structure. Above 100 labels, the mental model is almost always incomplete or incorrect in at least one respect. A visual map doesn't replace your understanding — it corrects the parts your memory has quietly dropped.

How BranchPy visualises story structure

BranchPy's flow visualiser reads every .rpy file in your project and generates an interactive node graph. Each label becomes a node. Each jump, call, and menu-generated branch becomes an edge. The graph is laid out automatically and is searchable by label name.

This doesn't require any changes to your scripts. You keep writing Ren'Py the way you always have.

Summary

  • Branching complexity grows exponentially with the number of choice points.
  • Manual testing can cover a small fraction of all possible paths in a mid-size project.
  • Structural problems — dead labels, missing jump targets, orphaned paths — are invisible in a text editor at scale.
  • A visual map of the story graph makes these problems immediately visible without running the game.
  • Understanding structure is a prerequisite for testing it effectively.
See your project's structure BranchPy generates an interactive flow graph from your Ren'Py scripts — labels, jumps, branches, and all. No configuration required.

See what BranchPy analyses →