A variable is remembering
๐ง A variable is remembering
In chapter 1, your reader has a choice: tell the guard the truth, or lie to them. They lie. Three chapters later, the guard crosses their path again โ and should remember it.
Without memory, your graph can't do anything with that lie. It would have to duplicate the entire rest of the story: one "they lied" version and one "they told the truth" version, doubled, all the way to the end. Add a second memorable choice and you're up to four copies, a third and it's eight. ๐ฑ
A variable is exactly what avoids that: a place where your story writes something down, to read it again later. A sticky note the project keeps in its pocket for the whole playthrough. ๐
๐บ There's no math involved. A Celestory variable isn't an unknown to solve for: it's a label with a value written on it. HasLied = true. Points = 12. PlayerFirstName = Camille. You write to it whenever you want, you read it back whenever you want.
๐ช The Variables window
Two ways to open it:
- the project menu (the blue button top left) โ Variables;
- the shortcut
Cmd+Shift+V(Ctrl+Shift+Von Windows).
The window is titled "Project variables." That title isn't a vocabulary detail โ remember it, we come back to it below.
It's laid out in two columns: on the left, your list of variables (with a Search field above it); on the right, the sheet for whichever one you've selected. As long as you have none, the right-hand column simply shows "Add your first variable to add intelligence to your scenario."
โ Creating a variable
The Add variable button sits at the bottom of the left column. A small window asks for three things:
- Type of the variable (can not be changed) โ the dropdown in the table below. โ ๏ธ This is final: to change type, you have to delete and recreate.
- Of (can not be changed) โ this second dropdown appears only if you chose List: it asks what the list is made of.
- Name of the variable (can be changed) โ this one, yes, can be renamed at any time.
The confirm button refuses to activate and shows "This variable already exists" if the name is already taken. ๐
๐๏ธ The initial value
On the right-hand sheet, under the name, there's an Initial value field. This is the value the variable holds at the very start of the playthrough, before anything has touched it.
For seven types out of eight, Celestory creates this value on its own at creation time, with a neutral starting value: 0 for a Number, false for a Boolean, an empty (multi-line) text for a Text. All you have to do is fix it if it doesn't suit you.
๐บ Only the Background image type creates nothing automatically: its initial value stays empty until you fill it in yourself.
๐บ An empty initial value isn't an error, and produces no message: it produces emptiness, silently, everywhere you read the variable. Get in the habit of filling it in.
๐ The available variable types
Eight types, in the exact order of the dropdown:
Type | What it remembers | Example use |
|---|---|---|
Text | A string, on one line or several. | The player's first name, a typed answer, a long context for the AI. |
Boolean | True or false, nothing else. Starting value: | "Lied to the guard," "found the key," "has seen the tutorial." |
Number | A numeric value. Starting value: | Points, lives, money, attempt counter. |
Image | An image file. | The portrait the player chose. |
List | An ordered collection of a single type, asked for at creation: File, Text, Image, Number, Object, Boolean or Background image. | The inventory, the clues already found. |
Object | A set of key/value pairs, editable field by field or as raw JSON. | A full character sheet, an API response. |
File | A generic file, any format. | A document uploaded by the player. |
Background image | An image combined with a color, a position and a repeat setting. | The current scenery, which changes as the story progresses. |
๐บ The Boolean, File and List types don't offer a Clear button: their value can't be reset to "nothing," only replaced.
๐ฌ The running example: the guard remembers the lie
Four steps, start to finish.
1๏ธโฃ Create the variable
Cmd+Shift+V โ Add variable โ type Boolean โ name HasLied. Its initial value shows as false: at launch, nobody has lied yet. โ
2๏ธโฃ Write it in chapter 1
In the graph, right after the "I lie" branch of your Choice block, add an Assign block. It has three inputs:
inโ the wire arriving from the choice;variableโ which variable to write to;valueโ what to write into it.
On the variable input, open the picker and choose HasLied. ๐ The value input doesn't exist yet: it appears automatically as soon as you've picked the variable, and it takes on the right type by itself (a checkbox, here, since HasLied is a Boolean). Check it: true.
๐บ Close the window: if nothing is wired to variable or value, the block collapses on the graph into a compact HasLied = true pill, with only in and out. The variable and the value can then only be set in the editing window (double-click).
Wire the out output into the rest of the scene. There you go, the lie is recorded. ๐๏ธ
3๏ธโฃ Read it back in chapter 4
Where the guard crosses paths again, drop a Condition block. It has one condition input expecting a Boolean. Two outputs: true and false.
To bring HasLied to it, two strictly equivalent ways:
- The Variable block โ a small block that carries only the variable's name and a single output. Drop it, drag a wire from its output to the
conditioninput. - Directly on the point โ open the Condition block's editing window and, on the
conditionfield, use the Select a variable option. No wire, no extra block: the field points at the variable.
Either way, the read is live: Celestory fetches the value at the moment the player passes through, not the value it started with.
Wire true to "Well, well, the liarโฆ" and false to "Good evening, honest traveler." ๐ญ
๐บ The Condition block has its own article: โ๏ธ Setting up true/false conditions. It covers comparisons, combined tests and multiple branches. A variable with no condition is useless, and a condition with no variable is too: the two articles read one after the other.
4๏ธโฃ Check that it works
Launch the player and open its Variables panel. You'll see the full list there, with the value live, changing before your eyes as the Assign block runs. You can even force a value by hand there to test the chapter 4 branch without replaying chapter 1. ๐งช
๐ โ ๏ธ Why you'll never find the "Variable" block in search
This is the most confusing trap in this chapter, and it deserves its own callout.
Open the add-block menu, type variable: nothing. The Variable block is deliberately excluded from the block list and its search. ๐
It lives somewhere else: right at the bottom of the add-block menu, under a heading "Variables," where Celestory lists your variables by name. Clicking HasLied drops a Variable block already wired to HasLied. The search field does filter this section โ but by variable name, not block name: type HasLied, not variable.
๐บ Direct consequence: as long as you haven't declared a single variable, the section doesn't exist and the block is perfectly unfindable. This isn't a display bug: create the variable in the Variables window first, and the block will show up afterward.
๐บ Another route, handy once you know it: drag a wire out of an input and drop it into empty space. The autocomplete menu that opens offers, in addition to blocks, all your variables of the right type โ and drops the block already wired. โก
๐ โ ๏ธ Scope: there's only one bag, and it's shared
A critical, counter-intuitive point: a Celestory variable is global to the entire project.
Not to the module. Not to the graph. Not to the scene. There's only one list, flat, shared by the whole project โ which is exactly what the window's title says, "Project variables." The HasLied you write in the "Prologue" module is exactly the same one you read in the "Epilogue" module. A variable created from anywhere is immediately visible everywhere.
This is extremely useful โ it's what lets a story cross its modules without losing anything โ but it has three consequences worth knowing:
- ๐บ Names collide. Two collaborators who each create a
Counterin "their" part are, in reality, working on the same memory slot. Prefix them:Ch1_Counter,Combat_Counter. - ๐บ Deleting a variable hits the entire project. Celestory scans every graph, deletes every Variable block that pointed to it, and clears every field that referenced it. It's clean, it's thorough, and it's irreversible with one click (undo remains your safety net).
- ๐บ Renaming into a duplicate fails silently. If you type a name already held by another variable, the rename is simply ignored: no message, the old name stays. Check that the new name actually shows up.
๐ญ โ ๏ธ The "Context" trap in the sidebar
Expand a module in the left-hand sidebar: under each one sits an entry called Context (a speech-bubble icon).
The word strongly suggests "the variables of this module." It's not the case. This shortcut opens the exact same project Variables window, with no module filter whatsoever. Click "Context" under module A or under module B: you get the exact same list either way.
๐บ "Context" is nothing more than a shortcut to the Variables window. It's tucked under each module for convenient access, not because there's a context per module. There isn't one.
๐๏ธ Groups: folders, and nothing more
The Variables window offers an Add group button, and each group can contain subgroups. You can drag your variables into them, and fold or unfold the tree.
๐บ A group is purely cosmetic. It tidies up the display, full stop. It creates no partitioning whatsoever: a variable filed under the "Combat" folder stays readable and editable from any block in the project, exactly like the others. File things away for your own bearings, never to isolate them.
โ๏ธ The four blocks that write to a variable
Block | What it does | Types accepted |
|---|---|---|
Assign | Writes a value into a variable, replacing the old one. | Number, Text, Boolean, Image, List, Background image, File, Object. |
Multi Assign | The same thing, for several variables at once. A | The same. |
Increment | Adds an amount to the current value (1 by default). | Number only. |
Decrement | Subtracts an amount from the current value (1 by default). | Number only. |
๐บ Increment and Decrement are the right answer to "add a point": they read, compute and rewrite in a single block. Doing the same thing with an Assign would mean reading the variable, adding to it somewhere else, then reassigning it. ๐ฏ
๐บ The Variable block, for its part, only reads. It has no input, only an output. It never modifies anything.
๐ฌ Displaying a variable in a sentence
You don't need any complicated setup to write "You have 12 points." Just write, in the block's text field, You have {{Points}} points.: the double curly braces make a Points input appear on the block, which you wire to your variable.
This is a mechanism in its own right, with its own rules (no accents inside the braces, case matters, only ten blocks are concerned) โ it's all in the article ๐งฉ Injecting a variable into text: double curly braces. Don't leave this page without reading it if you want personalized text.
๐พ What survives from one play session to the next
A natural question: if the player closes the tab and comes back tomorrow, is HasLied still true?
Only if you planned for it. There is a game-save mechanism, but it's not automatic: it relies on two blocks.
- The Checkpoint block records, the moment the player passes through it, the entire state of the playthrough: the position in the graph, the current module, the call stackโฆ and the value of every variable. The whole thing is written into the player's browser, one save per project.
- The Load checkpoint block restores that state. It has a
no checkpoint foundoutput for the โ common โ case where the player is here for the first time.
๐บ Without a Checkpoint block in your graph, nothing is kept. On close, every variable goes back to its initial value.
๐บ A save is a snapshot, not a continuous recording: whatever happened after the last pass through a Checkpoint block is lost. Drop one at the end of every chapter.
๐บ It lives in the player's browser. Switch device, switch browser, or clear the site's data: the save is gone.
๐บ On the menu side, the Start button has a Reset the variables option. Turned on, it resets everything to the initial value when launching the module; turned off, it keeps the current state. That's exactly the difference between "New game" and "Continue." ๐ฎ
๐ฉน Two details that catch people off guard
๐บ The Variable block keeps its old name. Its label is copied the moment you drop it, and isn't refreshed if you rename the variable afterward. The link stays correct โ it really is the right variable being read โ but the graph shows a stale name. Replace the block to refresh the display.
๐บ An unwired variable doesn't complain. Whether the initial value is empty, a value point is left dangling, or an input is waiting for a wire that never arrives, Celestory says nothing: it uses emptiness and moves on. The player's Variables panel is your only reliable witness. ๐ฆ
โ Next step: your story can now remember โ all that's left is to see it for yourself. Head to Testing Your Project and Reading the Debugger, to run a playthrough and watch your variables change live, value by value. That's where you find out whether the sticky note was really written. ๐
Updated on: 23/09/2026
Thank you!
