Mastering Mutable State with Var and Set
What you'll learn
You will learn the fundamental Verse syntax for mutable state and how to surface it on screen:
- Declaring a variable with
var(which always requires an explicit type). - Updating that variable with the
setkeyword (there is no++or+=). - Displaying the changing value with the Player UI API —
GetPlayerUI[], atext_block, andAddWidget.
How it works
In Verse, ordinary bindings made with := are immutable — they never change. When a value must change during play (score, health, ammo), you declare it as a var:
- Declaration:
var Name : Type = InitialValue— the type is mandatory. - Update:
set Name = NewValue—set X = X + 1, neverX = X + 1orX++.
A subtle gotcha: our button handler runs once per press, but a text_block you AddWidget is added once. If you re-created and re-added a widget on every press you'd stack duplicates on screen. The clean pattern is to build ONE text_block per player up front, keep a reference to it, and just call SetText on it each time the score changes.
Also note the failable APIs. GetPlayerUI[] returns a player_ui but fails if the player has no UI — the square brackets mean you must call it inside a failure context (if (UI := Player.GetPlayerUI[]):). Building display text uses string interpolation "Score: {CurrentScore}", never + concatenation.
Let's build it
This device tracks a score. On OnBegin it creates one score label for each player. Every button press increments the var with set and refreshes the label's text.
using { /Fortnite.com/Devices }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
my_score_device := class<concrete>(creative_device):
# 1. A mutable variable — 'var' REQUIRES an explicit type annotation.
var CurrentScore : int = 0
# Keep one reusable label so we don't stack widgets on every press.
var ScoreLabel : ?text_block = false
# Button we wire up in the editor.
@editable
ScoreButton : button_device = button_device{}
OnBegin<override>()<suspends>: void =
# Create one score label per player and add it to their UI once.
for (Player : GetPlayspace().GetPlayers()):
if (PlayerUI := GetPlayerUI[Player]):
Label := text_block{}
Label.SetText(StringToMessage("Score: 0"))
PlayerUI.AddWidget(Label)
# Store the widget reference for later updates.
set ScoreLabel = option{Label}
# Subscribe to the button press; button events use no () before .Subscribe.
ScoreButton.InteractedWithEvent.Subscribe(OnButtonPressed)
# Handler runs each time the button is interacted with.
OnButtonPressed(Agent : agent): void =
# 2. Update the mutable variable with 'set' (no ++ / += in Verse).
set CurrentScore = CurrentScore + 1
# 3. Refresh the on-screen label if it exists (option bind, not = nil).
if (Label := ScoreLabel?):
Label.SetText(StringToMessage("Score: {CurrentScore}"))
# Console verification via string interpolation (no string '+').
Print("Score updated to: {CurrentScore}")
StringToMessage<localizes>(Value : string): message = "{Value}"```
## Try it yourself
1. Place a **Button Device** and your **Verse Device** in the level.
2. In the Verse Device details, drag the Button into the **Score Button** slot.
3. Push your changes and Play. Click the button and watch the score climb both on screen and in the debug log.
4. Experiment: change `set CurrentScore = CurrentScore + 1` to `+ 10` and see the label jump by tens.
## Recap
* Use `var Name : Type = Value` to declare state that can change — the type is required.
* Use `set Name = NewValue` to update it; there is no `++`, `--`, or `+=`.
* `GetPlayerUI[]` is failable — bind it with `if (UI := Player.GetPlayerUI[]):`.
* Build ONE `text_block`, `AddWidget` it once, and call `SetText` on each update instead of re-adding widgets.
* Build display strings with interpolation `"Score: {X}"`, never `+` concatenation.
Check your understanding
Test yourself with an interactive quiz and track your progress + earn XP — free for members.
Turn this into a guided course
Add Declaring and updating mutable variables with var and set to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.
Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.