Mastering Mutable State with Var and Set
Tutorial beginner compiles

Mastering Mutable State with Var and Set

Updated beginner Code verified

What you'll learn

You will learn the fundamental Verse syntax for mutable state and how to surface it on screen:

  1. Declaring a variable with var (which always requires an explicit type).
  2. Updating that variable with the set keyword (there is no ++ or +=).
  3. Displaying the changing value with the Player UI API — GetPlayerUI[], a text_block, and AddWidget.

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 = NewValueset X = X + 1, never X = X + 1 or X++.

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.

Comments

    Sign in to vote, comment, or suggest an edit. Sign in