Variables and control flow
Declare typed variables, evaluate conditions, and distinguish session state from profile progression.
This chapter adds branch state to your first story. Declare variables before assigning them from Story; do not depend on undeclared temporary names.
1. Add a game catalog
Merge this field into prismatix.json. If the project already points to another catalog, edit that document instead of maintaining two different variable lists.
{
"gameCatalog": "Content/game.pxgame"
}For a new Content/game.pxgame, use this complete document. For an existing catalog, append the variables while preserving its gallery and unlockables:
{
"format": "PrismatiXGame",
"schemaRevision": 2,
"variables": [
{"name": "score", "type": "integer", "default": 0, "scope": "session"},
{"name": "visitedWindow", "type": "boolean", "default": false, "scope": "session"},
{"name": "route", "type": "string", "default": "none", "scope": "session"},
{"name": "volumeHint", "type": "number", "default": 0.5, "scope": "session"}
],
"gallery": [],
"unlockables": []
}integer stores integers, number supports fractional values, boolean stores true/false, and string stores text. Defaults must match their types. volumeHint is only a variable: a name that resembles an audio setting does not automatically change audio volume.
2. Record a choice in Story
At the beginning of the stars branch, add:
[set score=1]
[set visitedWindow=true]
[set route="stars"]At the beginning of the other branch, add:
[set score=0]
[set visitedWindow=false]
[set route="story"]Assign one variable per line. [set name=score value=1] is an alternative form. This is literal assignment, not a general expression evaluator: [set score=score+1] does not increment the value. Use ctx.variables.get/set from an extension for calculations.
3. Add a conditional ending
Before the shared ending, insert:
[if visitedWindow and score >= 1]
[id ending.window]
You remember the position of the evening's first star.
[else]
[id ending.book]
You remember the opening sentence of the story.
[endif]An else branch is optional, but every if needs its corresponding endif. Indentation can make nested conditions readable; it does not replace endif. If a speaker was active earlier, insert a blank line before narration so the ending does not accidentally become dialogue.
4. Operators and types
The condition parser accepts expressions such as:
[if (score + 2) >= 3 and not (route == "story")]
The condition is true.
[endif]
[if visitedWindow || score > 2]
At least one condition is true.
[endif]From lowest to highest, binary precedence is or / ||, and / &&, == / !=, < / <= / > / >=, + / -, and * / / / %. Unary operators are not / ! and negation. Use parentheses to make the intended grouping explicit.
Equality is ==, not JavaScript's ===; conditions are not an assignment location. Use numbers for arithmetic, booleans for boolean operations, and quoted strings for text comparisons. Because identifiers may contain -, write subtraction as score - 1, not the ambiguous-looking score-1. Avoid division by zero.
5. Session versus profile
Use session for the current story's state: the chosen route, dialogue decisions, and temporary flags. These belong to checkpoint, load, and rollback behavior.
Use profile for deliberately cross-session progression, such as unlocks. Do not put every variable in profile merely because you want saving to work; that confuses story rollback with permanent progression. Gallery and unlockable content also have catalog/progress APIs. Choose a clear owner for each value rather than keeping conflicting copies in several systems.
6. Validate and preserve compatibility
prismatix validate my-game
prismatix dev my-gameTest both branches and confirm they assign the state needed at the shared ending. Temporarily assign text to score and check the resulting type diagnostic. Fix undeclared variable references instead of treating them as new declarations.
After release, renaming a variable or changing its type is not simply a prose edit. Retain the previous game and isolated test saves, plan a versioned migration, and test them in the new Player. See Saves and compatibility.
Sources: Story compiler, Condition parser, Game contract.