Story Script Syntax
Reference for .story script files. Each file is a plain-text sequence of
commands that the StoryInterpreter compiles into a
NodeGraph at runtime.
File Format
Story files are plain UTF-8 text files with the .story extension placed
in StreamingAssets/Stories/. Every non-blank line is one command.
Blank lines are ignored. Comments are preceded by a double slash //
and extend to the end of the line. Comments are ignored by the parser.
- Lines are split on
\rand\n; both Windows and Unix line endings are accepted. - The first token on each line (case-insensitive) is the command keyword.
- Arguments follow on the same line, separated by whitespace.
Inline Parameters
Character parameters [...]
A bracket token resolves a randomised character dialogue string at compile time.
| Parameter | Description |
|---|---|
| greeting | A random greeting line for the character. |
| thanks | A random thanks line for the character. |
| itemNeed | The name key of a random item the character needs. |
| reward | The name key of a random reward the character offers. |
The optional new prefix forces selection of a new, non-repeating line.
[mario greeting] [new mario thanks] say translated QUEST_NEED [mario itemNeed]
Variable parameters {...}
A brace token reads an integer variable from PlayerSave at compile time.
Supported in the set command value position.
set score to {previousScore} + 10
Control Flow Keywords
These keywords are not commands — they are structural delimiters handled directly by the parser.
| Keyword | Description |
|---|---|
| end | Closes a scope opened by on or other scope-creating commands. |
| endif | Closes a conditional block opened by if. |
| else | Begins the fallback branch of an if block. |
| elif | Shorthand for else if. Opens a new conditional branch if the previous one failed. Can be chained arbitrarily. |
if must be closed with exactly one
endif. Every on block must be closed with
end. Mismatched delimiters produce a warning and may generate
an incorrect graph. This will be fixed in a future update.
Comparison Operators
Used by if, when playtimes, and requirement.
Both symbolic and English forms are accepted where noted.
| Symbol | English equivalent | Meaning |
|---|---|---|
| = | is | Equal to |
| != | is not | Not equal to |
| < | is less than | Less than |
| > | is greater than | Greater than |
| >= | — | Greater than or equal to |
| <= | — | Less than or equal to |
Commands
say
Displays a dialogue popup to the player. Supports localisation keys, raw strings, and character parameter tokens. Optionally targets an NPC location first.
Literal message
Localised key
Character parameter
Targeted NPC interaction popup
say Hello there! say translated QUEST_INTRO say tr QUEST_NEED [mario itemNeed] say at villager translated NPC_GREETING say [mario greeting]
set
Sets a save variable to a value, optionally chaining arithmetic operations. Can also set the state of a world object.
Set save variable
Set object state
to keyword is optional in both forms
and exists only for readability.
set questProgress to 1
set score 100
set score to {score} + 10
set score to {score} * 2 - 5
set state of door to open
set state of trapdoor to index 2
if / elif / else / endif
Conditional branching. The body of the passing branch executes; all branches
rejoin at the endif line. Multiple elif branches
can be chained.
| Type qualifier | Checks |
|---|---|
| variable (default) | A named integer save variable. |
| item | The player's inventory count of an item. |
| played | Number of times a mini-game has been played. |
The type qualifier is optional. When omitted, a variable check is assumed and
the first token after if is treated as the variable name directly.
English operators (is, is not, is greater than,
is less than) are also accepted.
if questProgress = 0
say translated QUEST_NOT_STARTED
elif questProgress = 1
say translated QUEST_IN_PROGRESS
else
say translated QUEST_COMPLETE
endif
if variable score > 100
give player trophy x1
endif
if item appleItem >= 3
say translated ENOUGH_APPLES
endif
if test_var is greater than 5
say translated BIG_NUMBER
endif
when
Registers a game-world event trigger that starts a new execution branch when
the condition is met. Each when opens a new scope in the story
graph; subsequent commands until the next top-level scope belong to that branch.
Player talks to an NPC / object
Custom interaction (custom label & icon)
Player uses an item on a location
Player gains an item
Player arrives at a location
Mini-game play count condition
id — assigns a custom interaction identifier, useful for later removal with
remove interaction. Defaults to
titleKey_locationID or use_itemID_on_locationID.
when talk to villager
say translated NPC_GREETING
when talk at questgiver once
say translated QUEST_INTRO
when (EXAMINE icon_magnify) at ancientRuin id ruins_examine
say translated RUINS_DESCRIPTION
when use keyItem on lockedDoor once
say translated DOOR_UNLOCKED
when gain item apple 3
say translated GOT_APPLES
when arrive at marketSquare
say translated WELCOME_TO_MARKET
when playtimes fishingGame >= 5
say translated FISHING_VETERAN
give / take
Adds or removes an item from the player's inventory. The optional
animated flag plays the item fly-to-inventory animation.
The count can be written as
3, x3, or x 3.
Defaults to 1.When
animated is given, the optional objectID can specify
the world object the animation originates from.
give apple give player apple x3 give player apple 3 animated appleBush take apple x2 take player coin 10 animated
collect
Waits for the player to collect an item or pick up a specific world object, then adds the result to the inventory.
Collect an inventory item directly
Collect a physical world object, converting it to an item
collect item apple collect item coin x5 collect object woodenCrate as lumber collect object flowerBush as flower animated
item
Registers a quest item, assigning it a unique ID and a display name localisation key. Must be declared before any commands that reference the item.
itemID is the game-wide item type identifier.
nameLocaKey is the localisation key for the item's display name.
The keywords
as and called are optional separators.
item quest_apple as apple called ITEM_APPLE item quest_key questKey called ITEM_KEY
key
Locks an interaction on an object behind possession of a specific item. The interaction becomes available only when the player carries the key item.
key questKey opens lockedChest
play
Triggers an Animator state or trigger on a world object identified by its
IdTag.
play open of door play celebrate as villager play Jump trigger of player
effect
Spawns or plays a named visual/audio effect at the position of a world object.
effect sparkle at treasure effect explosion campfire
vehicle
Moves a named vehicle from one location waypoint to another.
from and to keywords are optional separators.
vehicle ferry from dockA to dockB vehicle cart harbourGate marketGate
checkpoint
Marks the current execution position as a checkpoint. If the player exits
the game or plays a minigame, the story resumes from the most recent checkpoint
when the main scene is reloaded.
Use clear to remove the active checkpoint.
clear removes the currently active checkpoint.
checkpoint checkpoint quest_start checkpoint clear
remove
Removes a previously registered interaction from a world object, preventing it from being triggered again.
remove item is not valid. Use
take to remove items from the player's inventory.
remove interaction ruins_examine
requirement
Adds a gate at the current point in the graph: execution continues only if
the named variable satisfies the condition. Used to guard event branches.
Defaults to > 0 if no operator or value is given.
requirement questProgress requirement variable questProgress > 0 requirement score >= 50
on / do
on declares a named reusable sub-graph (function). The body between
on and end becomes an isolated sub-graph.
do calls that sub-graph by name, inserting its nodes inline.
Declare a function
Call a function
on must be
closed with end, not endif.
on questComplete
give player trophy
set questProgress to 3
say translated QUEST_DONE
end
when talk to questgiver
requirement questProgress = 2
do questComplete
Full Example
A complete quest script demonstrating most features together.
// Register the quest item used throughout this quest item quest_apple as apple called ITEM_APPLE // Declare a reusable completion routine on completeQuest give player reward x1 animated rewardChest set questProgress to 2 say translated QUEST_COMPLETE end // Trigger when the player first talks to the villager when talk to villager once requirement questProgress = 0 say translated VILLAGER_INTRO say translated VILLAGER_NEED [villager itemNeed] set questProgress to 1 // Trigger when the player returns with the apple when talk to villager requirement questProgress = 1 if item apple >= 1 take apple do completeQuest else say translated VILLAGER_WAITING endif // Play a celebration effect when quest is done when talk to villager requirement questProgress = 2 say translated VILLAGER_THANKS effect confetti at villager // Activate the key-locked chest after the quest is complete when arrive at treasureRoom requirement questProgress >= 2 key quest_apple opens treasureChest checkpoint afterArrival