Reference Verse compiles

Default Parameters: Flexible Functions for Your Fortnite Island

Default parameters let you write one function that works in many situations — call it with all the arguments when you need precision, or leave some out and let sensible defaults do the work. On a cel-shaded pirate cove island, that means a single `WarnCrew` function can flash a full custom alert for the captain, or a quick two-second blip for a deckhand, without duplicating any logic. This article teaches default parameters through real `trigger_device` and `hud_message_device` calls so every ex

Updated Examples verified on the live UEFN compiler
Watch the Knottrigger_device in ~90 seconds.

Overview

Default parameters are a core Verse language feature — not a device — that make your functions flexible without exploding into a dozen near-identical versions. You declare a parameter with a leading ? (a named parameter) and give it an = value fallback. Callers can then omit that argument and get the default, or pass it explicitly by name (?Points := 5).

This matters the moment your island grows. Imagine a sunny cove with a score_manager_device that awards points. Most pickups give 1 point, but the golden chest on the clifftop gives 10, and a hidden tide-pool gem gives 3. Without defaults you'd write three functions or pass every argument every time. With defaults you write one AwardLoot helper: call AwardLoot(Player) for the common case, AwardLoot(Player, ?Bonus := 10) for the chest.

Key rules from the Verse language:

  • Named parameters use a leading ? in the declaration: MyFunc(?Points:int = 1).
  • A default value can even reference an earlier parameter: CreateRange(?Start:int, ?End:int = Start + 10).
  • Defaults can reference class fields, and subclasses can <override> those fields to change the default.
  • Verse does not auto-convert int to float, so a default typed float must be written 1.0, not 1.

Reach for default parameters whenever you have a function that is usually called the same way but occasionally needs a tweak.

API Reference

(API surface could not be resolved for this device.)

Walkthrough

Here's the cove scene: three trigger plates on the dock. Stepping on any plate awards score through a single shared score_manager_device. The common plate gives the default 1 point; the chest plate passes a bonus; the gem plate passes a named ?Points. All three call the same AwardLoot method thanks to default parameters.

The score_manager_device's Activate(Agent:agent) grants the currently configured score, and Increment(Agent:agent) bumps the next award by 1. We use Increment in a loop to raise the total, then Activate to grant it — all driven by our defaulted parameter.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }

cove_loot_device := class(creative_device):

    # The shared score device that grants points on the cove.
    @editable
    Scorer : score_manager_device = score_manager_device{}

    # Common beach-loot plate: awards the default amount.
    @editable
    CommonPlate : trigger_device = trigger_device{}

    # Clifftop golden chest: awards a big bonus.
    @editable
    ChestPlate : trigger_device = trigger_device{}

    # Tide-pool gem: awards a small named amount.
    @editable
    GemPlate : trigger_device = trigger_device{}

    # ONE function, called three ways. ?Points defaults to 1.
    AwardLoot(Player : agent, ?Points : int = 1) : void =
        # Bring the score device up to Points by incrementing.
        # (First Activate grants 1, so we Increment Points-1 extra times.)
        var Remaining : int = Points
        loop:
            if (Remaining <= 1):
                break
            Scorer.Increment(Player)
            set Remaining -= 1
        Scorer.Activate(Player)

    OnCommonStepped(Agent : ?agent) : void =
        if (Player := Agent?):
            AwardLoot(Player)                 # uses default 1

    OnChestStepped(Agent : ?agent) : void =
        if (Player := Agent?):
            AwardLoot(Player, ?Points := 10)  # named override

    OnGemStepped(Agent : ?agent) : void =
        if (Player := Agent?):
            AwardLoot(Player, ?Points := 3)   # named override

    OnBegin<override>()<suspends> : void =
        CommonPlate.TriggeredEvent.Subscribe(OnCommonStepped)
        ChestPlate.TriggeredEvent.Subscribe(OnChestStepped)
        GemPlate.TriggeredEvent.Subscribe(OnGemStepped)

Line by line:

  • The @editable fields let you drop the score device and three trigger plates into your level and wire them in the Details panel.
  • AwardLoot(Player : agent, ?Points : int = 1) — the star of the show. ?Points is a named parameter with a default of 1. Any caller who omits it gets 1.
  • Inside, we loop calling Scorer.Increment(Player) to raise the pending award, then Scorer.Activate(Player) to grant it to that agent. Increment and Activate are real score_manager_device methods with agent overloads.
  • Each On...Stepped handler receives (Agent : ?agent) from the TriggeredEvent. We unwrap it with if (Player := Agent?): before use.
  • OnCommonStepped calls AwardLoot(Player) — no ?Points, so the default 1 applies.
  • OnChestStepped and OnGemStepped pass ?Points := 10 and ?Points := 3 by name. Same function, three behaviors.
  • OnBegin subscribes every plate to its handler. This is where all wiring happens.

Common patterns

1. A default that references an earlier parameter

Default values can be computed from parameters declared before them. Here a player_reference_device registers a player, and a helper decides how many bonus points to grant based on a Base amount — with ?Bonus defaulting to Base * 2.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

range_bonus_device := class(creative_device):

    @editable
    Scorer : score_manager_device = score_manager_device{}

    @editable
    Reference : player_reference_device = player_reference_device{}

    @editable
    StartPlate : trigger_device = trigger_device{}

    # ?Bonus defaults to Base * 2 — a later default using an earlier param.
    GrantScaled(Player : agent, Base : int, ?Bonus : int = Base * 2) : void =
        Reference.Register(Player)
        var Total : int = Base + Bonus
        loop:
            if (Total <= 1):
                break
            Scorer.Increment(Player)
            set Total -= 1
        Scorer.Activate(Player)

    OnStepped(Agent : ?agent) : void =
        if (Player := Agent?):
            # Base 5, Bonus defaults to 10 -> total 15.
            GrantScaled(Player, 5)

    OnBegin<override>()<suspends> : void =
        StartPlate.TriggeredEvent.Subscribe(OnStepped)

2. Toggling a device with a defaulted flag

A single helper enables or disables the score device. ?On defaults to true, so the common "turn it on" call is short, while a shutdown call passes ?On := false.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

toggle_scorer_device := class(creative_device):

    @editable
    Scorer : score_manager_device = score_manager_device{}

    @editable
    OpenGate : trigger_device = trigger_device{}

    @editable
    CloseGate : trigger_device = trigger_device{}

    # ?On defaults to true: SetScoring(Player) enables, SetScoring(Player, ?On := false) disables.
    SetScoring(Player : agent, ?On : logic = true) : void =
        if (On?):
            Scorer.Enable(Player)
        else:
            Scorer.Disable(Player)

    OnOpen(Agent : ?agent) : void =
        if (Player := Agent?):
            SetScoring(Player)               # default true -> Enable

    OnClose(Agent : ?agent) : void =
        if (Player := Agent?):
            SetScoring(Player, ?On := false) # -> Disable

    OnBegin<override>()<suspends> : void =
        OpenGate.TriggeredEvent.Subscribe(OnOpen)
        CloseGate.TriggeredEvent.Subscribe(OnClose)

3. A class-field default overridden by a subclass

Defaults can pull from a class field, and a subclass can <override> that field to change the default behavior — clifftop "hard mode" awards more per pickup.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

cove_rules_device := class(creative_device):

    @editable
    Scorer : score_manager_device = score_manager_device{}

    @editable
    Plate : trigger_device = trigger_device{}

    # Field used as the default award amount.
    DefaultAward : int = 1

    Award(Player : agent, ?Points : int = DefaultAward) : void =
        var Left : int = Points
        loop:
            if (Left <= 1):
                break
            Scorer.Increment(Player)
            set Left -= 1
        Scorer.Activate(Player)

    OnStepped(Agent : ?agent) : void =
        if (Player := Agent?):
            Award(Player)   # uses DefaultAward

    OnBegin<override>()<suspends> : void =
        Plate.TriggeredEvent.Subscribe(OnStepped)

Gotchas

  • The ? is required, in both places. Default parameters are named parameters — declare them with a leading ? (?Points : int = 1) and pass them with the same ? (AwardLoot(Player, ?Points := 10)). Forgetting the ? on the call gives an 'Unknown identifier' or argument-count error.
  • No int↔float auto-convert in defaults. If a parameter is float, its default must be written with a decimal: ?Speed : float = 1.0, never = 1. Mixing types won't compile.
  • Order matters for referencing earlier params. ?End : int = Start + 10 only works because Start is declared before End. You can't reference a parameter that comes later.
  • Named-parameter call syntax uses :=, not =. Inside a call you write ?Points := 10 (assignment-style), matching Verse's named-argument syntax.
  • Unwrap the event agent first. TriggeredEvent handlers receive (Agent : ?agent). Always do if (Player := Agent?): before passing it to a function like Scorer.Activate(Player) — the option must be opened.
  • Defaults live with the function, not the device. Default parameters are a language feature; the score_manager_device and player_reference_device methods themselves have fixed signatures. Your defaults only affect your helper functions that wrap those calls.

Guides & scripts that use trigger_device

Step-by-step tutorials that put this object to work.

Build your own lesson with trigger_device

Generate a personalized, step-by-step lesson plan built around this object — grounded in this exact reference and our compile-verified knowledge base.

Build a lesson →