Variable

A variable is a typed mutation target: the persistent state that scenes, nodes, and events read and write. You declare variables in the editor’s Variables panel, then mutate them with Set Variable events and read them in expressions.

For conventions shared by all entity types, see Entities.

The Variable inspector, opened by selecting a variable on the Node Graph. The Data View’s Variables tab edits variables inline in the table row instead; the side inspector shown here appears only from a Node Graph selection.

Fields

ID

The renameable, expression-namespace identifier for the variable. You’ll type this in expressions like var_count >= 100 and pick from it in the editor’s variable picker. Renaming the ID updates expressions that mention the old name; it doesn’t break the variable’s binding to mutating events.

Convention: variable IDs are prefixed var_ (or skill_<id> for the auto-generated skill backers, see Skill).

Name

Optional human-readable label, edited inline in the Variables table row. The inspector header shows the ID, not the Name; the Name field only appears in the table. Free-form string, author-typed. This is the visible label the editor surfaces in place of the ID where a longer name reads better, and the runtime never reads it. Use it to give a variable a prose-style name that the ID convention won’t hold (var_brew_minutes → “Steep minutes”).

Type

One of bool, decimal, int, string, or list. Drives validation in the editor and coercion in expression evaluation:

  • bool: true / false. Coerced from “true” / “false” / numeric truthy in string contexts.
  • decimal: high-precision number for currency, scores, percentages.
  • int: whole number for counters, attribute scores, indices.
  • string: free-form text. Localized when the localized flag is on.
  • list: ordered list of strings. Supports append, remove, contains semantics in expressions and is the canonical inventory storage shape (an item id list rather than a per-item flag).

You can’t change Type after a variable has been authored against; mutations will reject coercions across incompatible types.

Default value

The starting value, in the variable’s own type. The editor renders the default-value control to match the Type: a checkbox for bool, a number field for decimal and int, a string field for string, an append-list control for list. The default applies at run start and at scene-scoped variable re-initialization (see Scope).

For string variables with the Localized flag on, Default value is the source-locale string; translators see it next to the Translator note and Max length advisories.

Meter

Optional display label. Any non-empty string opts this variable into the game’s meter/HUD UI: the game draws the variable as a progress bar (or whatever meter shape it renders), and the string is the label shown alongside it. The runtime never draws the meter itself; it just publishes the flagged variables to the game to consume. Leave empty for variables the game shouldn’t render as a meter.

Min

Optional numeric lower bound. Numeric variables only. Enter a plain number in the inspector’s field. The runtime clamps writes below this value up to the bound; reads pass through unchanged. Non-numeric values silently disable clamping. Leave empty for an unbounded variable.

Max

Optional numeric upper bound. Same shape and semantics as Min. Setting both Min and Max clamps every write into [min, max]. Leave empty for an unbounded variable.

Scope

One of world (default) or scene. World-scoped variables persist across the whole run; scene-scoped variables re-initialize to the Default Value whenever their owning scene activates. Use scene scope for state intrinsic to a single encounter (temporary counters, per-encounter flags) and world scope for everything that follows the player through the run.

Readonly

When true, the editor refuses to author a Set Variable event that targets this variable, and the runtime rejects mutation attempts at evaluation time. Use this for variables that should only be sourced from the game via External sync: flipping Readonly on locks them so a stray event can’t shadow the game’s value.

External sync

When true, the game owns this variable’s value. The project declares the variable here so expressions can reference it, but the value itself lives in the game and is fetched fresh on every read. Common pattern for state that already lives in the game’s data model (player health, current weapon, party composition). The Default value acts as a quiet fallback when the game hasn’t supplied a value yet (typically only in editor preview).

External sync is independent of Readonly. If you want game-owned variables to be unwriteable by events, flip both on. The combination is the canonical shape for read-only game stats.

External sync can’t be combined with Localized. The inspector disables the External sync checkbox when Localized is on: a translated string variable’s value comes from the translation table, and reading through to the game on every reference would overwrite the translation. Pick one or the other.

Localized

When true, the Default value is treated as a source-locale string subject to translation. Surfaces in the localization editor as a translatable entry. String variables only; toggling Localized on a non-string variable does nothing. Leave off for variables whose string values are meant as ids or runtime tokens rather than visible text.

Translator notes

Default value can carry a translator note (string-typed variables with Localized on): see Entities for more information.

When to reach for variables

A variable is the right shape when the runtime needs a piece of state that crosses node and scene boundaries: a counter, a flag, a string the player picked, an inventory list, a meter the UI shows. Reach for a variable any time you’d otherwise try to deduce state from Played(...) or Selected(...) after the fact; explicit state is cheaper to author and faster to evaluate. Reach for an event field or a literal in an expression instead when the value is local to one place and never read again.

The type drives the controls and the coercion. bool is your one-shot flag, int and decimal are your counters and scores (clamped by Min / Max bounds), string carries text and ids, list holds the inventory pattern (an id list rather than a per-item flag). Scope decides whether the value lives the whole run (world) or resets each time its owning scene activates (scene), and External sync plus Readonly is the pattern for game-sourced reads. Mutate from a set variable event, or for ICU-formatted strings, a set variable text event.

See also

  • Set variable: the event that mutates this Variable from inside a node.
  • Set Variable (Text): event for string-typed variables with ICU placeholders.
  • Skill: skill entities auto-generate skill_<id> backing variables that follow this same shape.
  • Expressions: identifier conventions and the typed-value coercion rules.
Docs last synced: 2026-07-08
Screenshot viewer