State, Variables, and Items
When writing interactive narratives, the most important thing is:
Your story must “remember” what has already happened.
For example:
- Whether the player has obtained a key
- How much money the player has
- What the player’s current health is
- Whether the player has met a certain character
These are collectively called: state.
Two Types of Common State
NovaMark currently recommends dividing state into two categories:
1. @var — Internal Logic Variables
Best for:
- Flow control
- Internal flags
- Values not necessarily shown directly to players
For example:
@var met_spirit = false
@var chapter_index = 1
@var courage = 102. @item — Player-Facing State Items
Best for:
- Traditional inventory items
- Currency
- Public attributes
- State data that GUI wants to display directly
For example:
@item money
name: "Money"
description: "Currency available to the player."
default_value: 100
@endOr:
@item hp
name: "Health"
description: "The character's current health."
default_value: 100
@endWhy Split Into @var and @item
Because not all state should be exposed directly to players.
Examples Better Suited for @var
@var met_spirit = false
@var hidden_route_open = falseThese values are more like:
- Internal story switches
- System memories
- Branch conditions
Examples Better Suited for @item
@item money
name: "Money"
default_value: 20
@end
@item sanity
name: "Sanity"
default_value: 100
@endThese values are more like:
- Resources visible to players
- Entries the HUD wants to display
- Data the GUI can use for status panels
How to Define Variables
@var hp = 100
@var gold = 50
@var player_name = "沈砚"
@var met_spirit = falseThis means:
hpis a numberplayer_nameis a stringmet_spiritis a boolean
How to Modify Variables
@set hp = hp - 10
@set gold = gold + 20
@set met_spirit = true@set supports expressions, and now also uses set-or-create semantics: if the variable on the left side does not exist yet, it will be created in the current scope.
For example:
@set hp = 100
@set gold = hp + 20However, variables read on the right side must still already exist.
@set hp = gold + 20 // still an error if gold is undefinedIf you want to make it explicit that a piece of state is declared ahead of time, you can still use @var.
How to Give and Take Items/State Items
@give money 10
@take money 2Now @give and @take also support expressions:
@take money 1 + 1
@give money random(1, 10)
@take money count + 1This means creators can write more naturally:
- Fixed values
- Variables
- Function results
- Arithmetic expressions
Without always needing a temporary variable.
How to Check State
NovaMark’s most commonly used state functions include:
has_item("magic_stone")
item_count("money")
has_flag("met_spirit")
has_ending("true_end")These typically appear in:
ifstatements@checkblocks- Conditional choices
For example:
if item_count("money") >= 50
> You have enough money.
endifWhy Runtime State Matters for Clients
In NovaMark’s design, scripts don’t directly manage HUDs.
So the recommended approach is:
- Scripts maintain state
- Clients read state and decide how to display it
For example, a client can use runtime state to:
- Display
moneyin a status bar - Show
hpas a health bar - Render
sanityas a number or icon
This is why @item is now suitable for “player-facing state items.”
What’s Next
Now you know how to store and modify state.
The natural next questions are:
- How do you branch into different storylines based on state?
- How do you write a clear success/failure check?
Next page: