This article is also available in:

Your first choice: the reader decides, the story branches

πŸ”€ Your first choice: the reader decides, the story branches


So far, your story has been a straight line: Start β†’ Dialogue, and that's it. The reader reads; they do nothing. In this article we add the one thing that turns a text into an interactive experience: a branch. One question, two buttons, two different continuations.


This is the Choice block. We start from here:


  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Start │───────▢│ Dialogue β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ out β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
in out β–Ά (into empty space)


…and we end up here:


                                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”Œβ”€β”€β”€β–Άβ”‚ Dialogue "left" β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ Start │──▢│ Dialogue β”‚β”€β”€β–Άβ”Œβ”€β”€β”€β”΄β”€β”€β”€β”€β”€β”
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ Choice β”‚
β”‚ β”‚
β”‚ left ▢───▢ (branch 1)
β”‚ right ▢───▢ (branch 2)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


πŸ”Ί This article was checked against the Creator's source code (packages/frontend/src/containers/), not copied from internal notes. Points, wires, triangles and circles aren't re-explained here: see the article Linking Two Blocks: the Wire, the Triangles and the Circles.




🧩 The Choice block, and its cousin


Two blocks do the same basic job, with an extra feature on the second one:


Block

Color

What it does

Choice

Light purple

Displays a list of buttons. The reader clicks one, and the story continues out the matching output.

Choice with dialogue

Turquoise

The same thing, but it shows a line of dialogue first, then the buttons. One block instead of two.


They share exactly the same options mechanism: everything below applies to both. Choice with dialogue simply has two extra fields (the dialogue line and its media content).


⚠️ Choice with dialogue belongs to the Chatbot template: you won't find it in a Visual Novel module. The Choice block, on the other hand, is common to every template.



πŸͺ„ What makes this block special: it builds itself


Here's the thing nobody guesses on the first try, and it explains everything else.


When you drop a Choice block onto the graph, it has no outputs at all. Zero. A Dialogue block arrives with its output already there; the Choice block arrives bare, with nothing but its input and its settings.


Its outputs are born from what you write inside it. Every line you type into the choices field grows:


  • one output (a triangle on the right of the block: it's a flow output), carrying the exact text of the line;
  • one input carrying that same text (more on this below β€” it's for styling).


Write "left" and an output named "left" appears. Delete the line and the output disappears. Correct "left" to "toward the clearing" and the output is renamed β€” and the wire already plugged into it stays put. That's by design: the output is attached to the text line itself, not to its label.


πŸ”Ί There is no maximum. Two options, five, twenty: nothing in the code caps the list. Past five or six the block just gets very tall on the canvas, and your buttons very numerous on screen.



πŸ› οΈ Step by step


We'll assume your graph already has a Start block wired to a Dialogue, as at the end of the previous article. The Dialogue says something like "The path splits in two."


1. Drop the Choice block


Right-click an empty area of the canvas, a little to the right of your Dialogue. The block browser opens, with a Search… field at the top.


Type choice, then click Choice in the list.


πŸ’‘ A faster trick, which also skips step 3: drag a wire out of your Dialogue's output and drop it into empty space. Celestory then opens a list containing only the blocks compatible with that point, and creates the block already connected.


2. Open its editing window


Double-click the Choice block. Its window opens, with these fields:


  • in β€” the input, which currently reads "The block … isn't connected to any other block."
  • choices β€” a list, empty, with a οΌ‹ Text button.
  • timer β€” a number, set to 0.


3. Wire the Dialogue to the Choice


If you didn't use the step 1 trick: on the canvas, drag a wire from the Dialogue's output to the Choice block's input.


4. Write the first option


In the Choice window, click οΌ‹ Text under the choices field. An input line appears. Type:


Take the left path


Look at the block on the canvas: an output has just appeared, named Take the left path.


5. Write the second option


Click οΌ‹ Text again and type:


Take the right path


πŸ’‘ Faster still: with the cursor still in an option's field, press Enter β€” a new line is inserted right below it, and the cursor jumps there. You can write all five of your options in a row without ever touching the mouse.


Your block now has two outputs. That's a branch: one input, two outputs.


6. Reorder or delete (optional)


Each line has a drag handle on the left (to change the order the buttons are shown in) and a cross on the right (to delete it).


⚠️ Deleting a line also deletes its output and the wire that was plugged into it, with no confirmation asked. A Cmd+Z / Ctrl+Z undoes the whole thing.


7. Build the first branch


Right-click on empty space β†’ Dialogue. Write the continuation of the left path in it: "The clearing opens up in front of you."


Then drag a wire from the Choice block's Take the left path output to this new Dialogue's input.


8. Build the second branch


Do it again: a second Dialogue ("The path disappears under the trees."), wired to the Take the right path output.


9. Test it


Click Play current module: the Play test window opens. You see the intro line, then two buttons. Click one, you read its continuation; restart the test, click the other, you read the other continuation.


You've just written your first branching story. πŸŽ‰



πŸ—ΊοΈ Where we are


                                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”Œβ”€β”€β”€β–Άβ”‚ Dialogue β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ "The clearing opens up" β”‚
β”‚ Start │──▢│ Dialogue β”‚β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ "The path splits β”‚β”‚
β”‚ in two" β”‚β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚ β”‚
β–Ό β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Choice β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Take the left path β–Άβ”˜
β”‚ Take the right path ▢┐
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
└─▢│ Dialogue β”‚
β”‚ "The path disappears..." β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜



πŸ”— Making the two branches meet again


Two paths that diverge forever is rarely what you want: most of the time, both trails lead to the same village, and the story continues as one.


Good news: there's nothing special to do. A Stream input accepts several wires; just wire the output of the "clearing" Dialogue and the output of the "undergrowth" Dialogue to the input of the same third block.


   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” "clearing"      ┐
β”‚ Choice ▢───▢ Dialogue ─────
β”‚ β”‚ β”œβ”€β”€β–Ά β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ▢───▢ Dialogue β”€β”€β”€β”€β”˜ β”‚ Dialogue "The village"β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ "undergrowth" β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


⚠️ The reverse rule, though, is strict: a Stream output only accepts a single wire. Several wires can arrive at the same input; only one can leave a given output. If the Creator refuses your wire, it's almost always this.


πŸ”Ί If the crossing wires become hard to read, double-click on a wire: Celestory inserts a Connector block, a plain relay that does nothing but pass the flow through. That's visual housekeeping, not logic.


And if you want the branches to stay separate all the way to the end: don't join them. When a branch ends on a block whose output goes nowhere, the story simply stops there. That's an ending, not an error.



πŸ”‡ The trap: the option you forget to wire


This is the classic failure of this block, and it says nothing at all.


If an option does have its output, but that output isn't wired to any block, then at play time the button isn't displayed at all. Not greyed out, not struck through, not accompanied by a message: simply absent from the list.


You wrote three options, wired only two of them, you test, and you see two buttons. Nothing, anywhere, tells you the third one exists: the graph validates, no red cross appears on the block, no warning is raised.


The extreme case is even more confusing: if no option is wired, the reader sees an empty choice area and the story stops dead, waiting for a click that can never happen.


Symptom

Cause

What to do

A written option doesn't show up in the game

Its output goes nowhere

Wire that output to a block

The choice area is empty, the story is frozen

No output is wired

Wire at least one output

An option has vanished from the block, along with its wire

The line was deleted from the choices list

Cmd+Z / Ctrl+Z, or retype the line and redo the wire


πŸ”Ί The reflex that avoids all three: count the output triangles, count the wires leaving them β€” the two numbers must match before you test.



πŸ’¬ "Connect an Alter Choice block to make it dynamic"


Opening the Choice block's window, you may have noticed that below the options list, each option reappears a second time, as a separate field, with this message:


Connect an Alter Choice block to make it dynamic.


This is not an error, and there is nothing for you to do. It's simply the empty-state message of an optional field: next to each option, Celestory reserves a socket for plugging in an Alter Choice block. As long as nothing is plugged in, the field shows this invitation. An option with no Alter Choice works perfectly fine.


The Alter Choice block is used to make an option variable from one playthrough to another. It offers four behaviors:


Type

Effect on the option

Disable

The button stays visible but becomes unclickable (with its own style).

Remove

The button disappears completely from the list.

Rename

The button shows a different text.

Change style

The button gets a different text style and border.


This is how you write "the door is locked until you have the key": an Open the door option wired to an Alter Choice block of type Disable, whose condition depends on a variable.


⚠️ Careful not to confuse the two kinds of disappearance: Remove via Alter Choice is a button deliberately hidden, based on a condition you control. A button missing because its output isn't wired to anything is an oversight. On screen, the two are strictly identical.



⏱️ The timer: one more output, optional


The Choice block's timer field is 0 by default, meaning "no time limit."


Set it to a number of seconds, and an extra output appears on the block: time out. If the reader hasn't clicked anything before the countdown ends, the story continues through that output. A progress bar is shown above the buttons during the countdown.


Reset the timer to 0 and the time out output disappears β€” along with the wire that was plugged into it, exactly like a deleted option.



πŸ“Œ What to remember


  • A Choice block arrives with no outputs at all: its outputs are born from the lines you write in the choices field.
  • One line = one button on screen = one output to wire. No maximum.
  • Renaming an option keeps its wire; deleting it destroys its wire.
  • A Stream output only accepts a single wire, but an input accepts several: that's how two branches meet again.
  • An option whose output goes nowhere doesn't appear in the game, with no warning whatsoever.
  • The message "Connect an Alter Choice block" is an optional invitation, not an error.



β†’ Next step: your story branches now, but it doesn't remember anything β€” at the next fork, it will have forgotten which path the reader took. Head to A Variable Is Remembering. 🧠

Updated on: 23/09/2026

Was this article helpful?

Share your feedback

Cancel

Thank you!