A variable's scope is where it lives: which parts of your game can use it, how long it keeps its value, and whether it's saved with the game. There are five places to keep a value.
| Scope | Set up in | Used by | Keeps its value | In a save |
|---|---|---|---|---|
| Project variables | Variables Manager | Every scene and chapter | Until the game closes | Yes |
| Character variables | Character Manager | Every scene and chapter | Until the game closes | Yes |
| Scene variables | The scene's root inspector | That scene, and Scene nodes that embed it | Until the game closes | No |
| Script members | The top of a scene script | That scene's script | Until the game closes | No |
| Game settings | Your scripts | Every scene | Between play sessions | Kept separately |
Project variables
Project variables are for things the whole game needs to know, like the player's name, their gold, or the choices they've made. Create them in the Variables Manager, where you also set their starting values. While the game runs they're kept in the Variable Store.
In a scene script:
const gold = Store.Get("gold", 0); // 0 if it isn't set yet
Store.Set("gold", gold + 10);
// Calls onGoldChanged whenever gold changes
Store.Register("gold", this.onGoldChanged, this);
In a chapter:
You have {$gold} gold.
{set($gold, $gold - 5)}
{if ($gold < 10)
You're nearly broke.
}
- Scripts and chapters use the same variables, so a change made in one is seen straight away by the other.
- To read a field of an object variable, use
Store.Get("player").hp. Changing a field directly, likeStore.Get("player").hp = 5, doesn't tell listeners. To notify them, set a new object withStore.Set("player", { ...Store.Get("player"), hp: 5 }). In a chapter,{set($player.hp, 5)}does this for you. - The store also holds
scene, the name of the current scene. Saves use it to know which scene to load. - When the game starts, every project variable has its starting value from the Variables Manager. Loading a save puts back the values from that save.
Character variables
Each character, and each of its variants, can have its own variables, set up in the Character Manager. Use them for things that belong to one character, like how much they trust the player.
In a scene script:
const alice = Assets.GetCharacter("alice");
alice.variables.trust += 1;
const smiling = Assets.GetVariant("alice", "smiling");
log(smiling.variables.voiceLine);
In a chapter, pick a character with character, then use $char for its variables and $variant for its variant's variables:
{character(alice, variant=smiling)}
Alice's trust is {$char.trust}.
{set($char.trust, $char.trust + 1)}
Bob's trust is {print($char(bob).trust, 0)}.
See Logic for every way to write these.
- Changes made by scripts and by chapters are both saved with the game.
Store.Registerdoesn't see changes to character variables.- A script can pick the character that
$charand$variantuse withStore.SetCharacterTarget("alice", "smiling").
Scene variables
Scene variables belong to one scene. Add them to the Scene Variables list in the scene's root inspector. They're most useful in sub-scenes, because each Scene node that embeds the scene can give them different values, such as a different name or picture for each character card.
In the scene's own script:
onStart() {
this.dom.title.textContent = this.vars.title;
this.vars.health -= 10;
},
From another scene's script:
const hud = SceneManager.GetScene("hud");
hud.vars.health = 100;
- Chapters can't read scene variables.
- A scene's variables start with the defaults from its inspector when its script first loads, then keep their values until the game closes. Leaving a scene and coming back doesn't reset them, so set them in
onEnter()if you want a fresh value on each visit. - A Scene node's values are applied each time the scene containing it is shown, before the sub-scene's
onEnter()runs. - They aren't saved with the game. Copy anything you need to keep into a project variable.
- In TypeScript,
this.varsonly accepts names from the list, so typos are caught (see Script Types).
Script members
Anything you declare at the top level of a scene script becomes a property of the scene, this.<name>. Use these for values only the script needs, like a timer or a count of tries.
retries: 0,
onStart() {
this.retries++;
},
From another scene's script, use SceneManager.GetScene("battle").retries.
They behave like scene variables. They start with the value you wrote when the script first loads, keep their value until the game closes, and aren't saved. Unlike scene variables, they can't be set from a Scene node, and the Debug View doesn't show them.
Game settings
Game settings are for options the player picks, like text speed or language. They're stored on the player's device, separately from save slots, so they stay the same between play sessions and don't change when a save is loaded.
const speed = SaveManager.GetGameSettings("textSpeed", 30); // 30 if never set
SaveManager.SetGameSettings("textSpeed", 45); // stored straight away
To change several settings at once, pass false as a third argument to SetGameSettings so it doesn't store each one, then call SaveManager.SaveGameSettings() at the end.
Chapters can't read game settings. If a chapter needs one, copy it into a project variable.
Audio volumes are stored on their own, with AudioManager.SaveSettings() and AudioManager.LoadSettings().
Loop variables in chapters
The variable in a chapter loop, like $item in {for ($item in $inventory) ...}, only exists in the chapter node it's in. It isn't added to your project variables. If it has the same name as a project variable, the loop's value is used for the rest of that node.
What a save contains
SaveManager.Save(slot) and autosaves keep:
- every project variable, including
scene; - every character's and variant's variables;
- the character and variant that
$charand$variantpoint at.
Scene variables, script members and game settings aren't saved.
Viewing and debugging
In the editor
| Scope | Where to see it |
|---|---|
| Project variables | The Variables Manager |
| Character variables | The Character Manager |
| Scene variables | The scene's root inspector for its defaults, and each Scene node's inspector for the values it sets |
These are the starting values. Changes made while the game runs don't change them.
The Chapter Node Preview works on a copy of the project variables, so a set while previewing doesn't change your project. Rewind and Replay undo the changes made in a node.
While the game runs
The Debug View is included in Play and in Dev builds. Open it with the Mammut button on the right edge of the game.
The Variables tab shows live values:
- Project variables: everything in the store.
@charactersholds every character's and variant's variables, and@targetis the character that chapters are using. These two can't be changed here. - Scene: name: the current scene's
vars. - Attached scene: name: the
varsof each sub-scene and attached scene.
You can change values while the game runs. Changing a project variable uses Store.Set, so anything listening reacts straight away. Changing a scene variable only sets the value.
The Saves tab lists the autosaves and save slots, and the variables stored in each one.
The Log tab shows every change to a project variable, as Store set: gold = 15. Changes chapters make to character variables show as Character set:. A {log($gold)} in a chapter prints there too.
Browser DevTools
When the game runs in a browser, you can read every scope from the DevTools console:
Store.Get("gold");
Assets.GetCharacter("alice").variables;
SceneManager.GetScene("hud").vars;
SceneManager.GetScene("battle").retries;
SaveManager.GetGameSettings("textSpeed");
Game settings and save slots are also listed under Application then Local Storage, as myGame_settings, myGame_slot_1 and so on.