Documentation menu

Variables

Description: The shared state that dialogues, quests, and the game can read and write.

Variables example

A variable is a named piece of state that lives for the whole game — not scoped to one graph, one conversation, or one entity. JarlIsDead, Gold, QuestPhase: flags, counters, and small state machines that any part of your narrative can check or react to.

A variable has a default value — what a new game starts with — and, optionally, a description for your own reference. It can hold text, a number, a whole number, a true/false flag, an enumeration (below), or a reference to an entity — and any of those as a list or set, for things like "everyone the player has met."

Namespacing and conventions

Variables are always globally accessible, but as a convention underscores are used to namespace them. A common pattern is: <QuestName>_<VariableName> or <Topic>_<SubTopic>_<VariableName>

Note that namespacing helps with source control -- each namespace gets its own file, which helps limit the number of files changed when a variable is added or modified. Another benefit of namespacing is the editor will color distinct namespaces differently, which makes visual scanning easier.

Types

Variables match common programming language types: boolean, string, integer, and number.

Lists/sets

Variables can also represent a list or a set of a primitive type. (A list and a set are identical, other than that sets automatically deduplicate values whereas lists allow for duplicates.) Note that the lists/sets have a subtype, which is a primitive type or an enumeration. This is expressed with generics/templating syntax that may be familiar to programmers: list<string> reads "list of strings" and set<number> reads as "set of numbers".

Lists can be useful for reducing the number of variables needed in a project. For instance, if you need to keep track of places the player has been, you could create individual variables like PlayerVisitedTown, PlayerVisitedIn, etc., but it may be more efficient to instead have a single variable called VisitedLocations.

Option sets

Sometimes a value should only ever be one of a fixed set of options — a quest phase, a mood, a faction — rather than open text that's one typo away from silently breaking a condition. An option set (an enumeration in the data model) is that fixed list, defined once and then used to type any variable, or entity field, that should be restricted to it. Option sets covers how they work.

Entity References

Variables can also be an entity_reference. The underlying type is a string, but it hints to Narratyr that that the value is the id of an entity defined within narratyr such as a character, item or location.

The shared state between game, dialogue, and quest

A variable isn't scoped to whichever graph happens to read it. It's the shared memory between three things that all need to agree on where the story stands: your game, your dialogue graphs, and your quest graphs. Any of the three can read a variable to decide what happens next, and any of the three can write to it to record that something happened — there's no single owner.

  • A dialogue's Instruction Node can set a flag that a quest gates on later.
  • A quest completing can set a flag that a dialogue line reacts to, in a conversation that has no direct connection to that quest at all.
  • Your game can set a variable directly from code — reflecting something Narratyr doesn't model itself, like inventory or position — and any condition or line reads it exactly as if it were authored narrative state.

Because the connection is just a shared name rather than a direct call from one graph into another, dialogues and quests can react to each other without knowing about each other: a quest doesn't need to know which dialogue set HasMetSandra, only that the variable exists.

Variables are the main channel, but not the only one. An instruction can also call a function your game exposes — for a one-off action like granting an item or playing a cutscene, rather than state that needs to persist.

Narratyr's engine runtimes also allow for easy save/restore of variable state, simplifying save game creation.

Who owns the value

Some variables are best thought of as belonging to Narratyr — narrative state the runtime tracks entirely on its own, like JarlIsDead. Others belong to your game — values your engine already tracks, like health or position, that Narratyr just reads and writes into rather than duplicating. Both look identical from inside a condition or instruction: only the variable's name matters, so a quest gate can read your game's own stats without you re-authoring them as separate state.

Conditions and instructions

Graphs react to variables in two ways, using the same small expression language wherever either appears:

  • Conditions — a Gate waits on one, a Hub branches on one per output, and a choice's hide/disable toggle can carry one. Each is something that evaluates to true or false against the current values of one or more variables, e.g. Gold >= 10 && !HasMap.
  • Instructions — an Instruction Node runs one or more statements that change variables: setting a flag, incrementing a counter, adding an item to a list. JarlIsDead := true and Gold += 5 are both instructions.

A variable is referenced by name rather than copied into each place that uses it, so defining one once and reading it from many independent conditions across many graphs keeps all of them in agreement. Change what QuestPhase means, or which value marks a quest won, and every place that reads it sees the same thing — even though each condition was written separately.

Next

Expressions covers the syntax of the conditions and instructions above in full. Dialogues and Quests cover the graphs that read and write this state, and Text directives covers showing a variable's value — or branching on it — directly in player-facing text.