Reference Verse compiles

timer_device: Racing the Clock on the Pirate Cove

The `timer_device` is your island's countdown clock — it fires events when time runs out (success or failure), warns players when urgency mode kicks in, and lets you pause, resume, or force-complete the clock entirely from Verse. Drop one on your pirate cove dock, wire it to a trigger, and you have a fully scripted timed challenge in minutes.

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

Overview

The timer_device tracks elapsed or remaining time and broadcasts three key events your Verse code can react to: SuccessEvent (the player beat the clock), FailureEvent (time ran out), and StartUrgencyModeEvent (the clock is almost up — cue the dramatic music). You can also call methods like Start, Pause, Resume, Complete, and SetActiveDuration to control the clock entirely from code.

Reach for timer_device whenever your island needs:

  • A countdown before a vault door opens
  • A race across a pirate ship deck
  • A timed bomb-defusal challenge on a clifftop
  • Any "beat the clock" moment where you want to reward speed or punish slowness

The device works in both per-agent and global modes. Configure Is State Per Agent in the device settings to true if each player gets their own private timer; leave it false for a shared countdown everyone sees.

API Reference

timer_device

Provides a way to keep track of the time something has taken, either for scoreboard purposes, or to trigger actions. It can be configured in several ways, either acting as a countdown to an event that is triggered at the end, or as a stopwatch for an action that needs to be completed before a set time runs out.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).

timer_device<public> := class<concrete><final>(creative_device_base):

Events (subscribe a handler to react):

Event Signature Description
SuccessEvent SuccessEvent<public>:listenable(?agent) Signaled when the timer completes or ends with success. Sends the agent that activated the timer, if any.
FailureEvent FailureEvent<public>:listenable(?agent) Signaled when the timer completes or ends with failure. Sends the agent that activated the timer, if any.
StartUrgencyModeEvent StartUrgencyModeEvent<public>:listenable(?agent) Signaled when the timer enters Urgency Mode. Sends the agent that activated the timer, if any.

Methods (call these to make the device act):

Method Signature Description
Enable Enable<public>(Agent:agent):void Enables this device for Agent.
Enable Enable<public>():void Enables this device.
Disable Disable<public>(Agent:agent):void Disables this device for Agent. While disabled this device will not receive signals.
Disable Disable<public>():void Disables this device. While disabled this device will not receive signals.
ResetForAll ResetForAll<public>(Agent:agent):void Resets the timer back to its base time and stops it for all agents.
ResetForAll ResetForAll<public>():void Resets the timer back to its base time and stops it for all agents.
Start Start<public>(Agent:agent):void Starts the timer for Agent.
Start Start<public>():void Starts the timer.
Pause Pause<public>(Agent:agent):void Pauses the timer for Agent.
Pause Pause<public>():void Pauses the timer.
Resume Resume<public>(Agent:agent):void Resumes the timer for Agent.
Resume Resume<public>():void Resumes the timer.
Complete Complete<public>(Agent:agent):void Completes the timer for Agent.
Complete Complete<public>():void Completes the timer.
StartForAll StartForAll<public>(Agent:agent):void Starts the timer for all agents.
StartForAll StartForAll<public>():void Starts the timer for all agents.
PauseForAll PauseForAll<public>(Agent:agent):void Pauses the timer for all agents.
PauseForAll PauseForAll<public>():void Pauses the timer for all agents.
ResumeForAll ResumeForAll<public>(Agent:agent):void Resumes the timer for all agents.
ResumeForAll ResumeForAll<public>():void Resumes the timer for all agents.
CompleteForAll CompleteForAll<public>(Agent:agent):void Completes the timer for all agents.
CompleteForAll CompleteForAll<public>():void Completes the timer for all agents.
Save Save<public>(Agent:agent):void Saves this device's data for Agent.
Load Load<public>(Agent:agent):void Loads this device's saved data for Agent.
ClearPersistenceData ClearPersistenceData<public>(Agent:agent):void Clears this device's saved data for Agent.
ClearPersistenceDataForAll ClearPersistenceDataForAll<public>(Agent:agent):void Clears this device's saved data for all agents.
ClearPersistenceDataForAll ClearPersistenceDataForAll<public>():void Clears this device's saved data for all agents.
SetActiveDuration SetActiveDuration<public>(Time:float, Agent:agent):void Sets the remaining time (in seconds) on the timer, if active, on Agent.
SetActiveDuration SetActiveDuration<public>(Time:float):void Sets the remaining time (in seconds) on the timer, if active. Use this function if the timer is set to use the same time for all agent's.
GetActiveDuration GetActiveDuration<public>(Agent:agent)<transacts>:float Returns the remaining time (in seconds) on the timer for Agent.
GetActiveDuration GetActiveDuration<public>()<transacts>:float Returns the remaining time (in seconds) on the timer if it is set to be global.
SetLapTime SetLapTime<public>(Agent:agent):void Sets the lap time indicator for Agent.
SetLapTimeForAll SetLapTimeForAll<public>(Agent:agent):void Sets the lap time indicator for all agents.
SetLapTimeForAll SetLapTimeForAll<public>():void Sets the lap time indicator for all agents.
SetMaxDuration SetMaxDuration<public>(Time:float):void Sets the maximum duration of the timer (in seconds).
GetMaxDuration GetMaxDuration<public>()<transacts>:float Returns the maximum duration of the timer (in seconds).
IsStatePerAgent IsStatePerAgent<public>()<transacts><decides>:void Succeeds if this device is tracking timer state for each individual agent independently. Fails if state is being tracked globally for all agent's.

player

Full public surface, resolved verbatim from the live Epic digest (Verse.digest.verse). Inherited members are merged from agent.

player<native><public> := class<unique><persistent><module_scoped_var_weak_map_key><epic_internal>(agent):

trigger_device

Used to relay events to other linked devices.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from trigger_base_device.

trigger_device<public> := class<concrete><final>(trigger_base_device):

Events (subscribe a handler to react):

Event Signature Description
TriggeredEvent TriggeredEvent<public>:listenable(?agent) Signaled when an agent triggers this device. Sends the agent that used this device. Returns false if no agent triggered the action (ex: it was triggered through code).

Methods (call these to make the device act):

Method Signature Description
Trigger Trigger<public>(Agent:agent):void Triggers this device with Agent being passed as the agent that triggered the action. Use an agent reference when this device is setup to require one (for instance, you want to trigger the device only with a particular agent.
Trigger Trigger<public>():void Triggers this device, causing it to activate its TriggeredEvent event.
Enable Enable<public>():void Enables this device.
Disable Disable<public>():void Disables this device.
SetMaxTriggerCount SetMaxTriggerCount<public>(MaxCount:int):void Sets the maximum amount of times this device can trigger. * 0 can be used to indicate no limit on trigger count. * MaxCount is clamped between [0,20].
GetMaxTriggerCount GetMaxTriggerCount<public>()<transacts>:int Gets the maximum amount of times this device can trigger. * 0 indicates no limit on trigger count.
GetTriggerCountRemaining GetTriggerCountRemaining<public>()<transacts>:int Returns the number of times that this device can still be triggered before hitting GetMaxTriggerCount. Returns 0 if GetMaxTriggerCount is unlimited.
SetResetDelay SetResetDelay<public>(Time:float):void Sets the time (in seconds) after triggering, before the device can be triggered again (if MaxTrigger count allows).
GetResetDelay GetResetDelay<public>()<transacts>:float Gets the time (in seconds) before the device can be triggered again (if MaxTrigger count allows).
SetTransmitDelay SetTransmitDelay<public>(Time:float):void Sets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered.
GetTransmitDelay GetTransmitDelay<public>()<transacts>:float Gets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered.

Walkthrough

Scenario: A sun-drenched pirate cove. Players sprint across a rickety dock to reach a treasure chest. When they step on a pressure plate at the dock entrance, the countdown starts. If they reach the chest trigger at the far end before time runs out, they win. If the clock hits zero first, they fail. When urgency mode fires (the last few seconds), we shorten the remaining time slightly to ramp up pressure — a classic game-feel trick.

Place these devices in your UEFN level:

  • timer_device — configured as a 30-second countdown, urgency mode at 10 seconds
  • trigger_device (StartTrigger) — pressure plate at the dock entrance
  • trigger_device (ChestTrigger) — invisible trigger at the treasure chest
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

# Pirate Cove Dock Race — complete timed challenge example
dock_race_manager := class(creative_device):

    # Wire these in the UEFN Details panel
    @editable
    DockTimer : timer_device = timer_device{}

    @editable
    StartTrigger : trigger_device = trigger_device{}

    @editable
    ChestTrigger : trigger_device = trigger_device{}

    # Called when the island starts
    OnBegin<override>()<suspends> : void =
        # Subscribe to the pressure plate at the dock entrance
        StartTrigger.TriggeredEvent.Subscribe(OnDockEntered)

        # Subscribe to the treasure chest trigger
        ChestTrigger.TriggeredEvent.Subscribe(OnChestReached)

        # Subscribe to timer outcomes
        DockTimer.SuccessEvent.Subscribe(OnTimerSuccess)
        DockTimer.FailureEvent.Subscribe(OnTimerFailure)
        DockTimer.StartUrgencyModeEvent.Subscribe(OnUrgencyMode)

    # Player stepped onto the dock — start the race clock
    OnDockEntered(Agent : ?agent) : void =
        if (A := Agent?):
            DockTimer.Start(A)   # start per-agent timer for this racer
        else:
            DockTimer.Start()    # fallback: start global timer

    # Player reached the treasure chest — force a success
    OnChestReached(Agent : ?agent) : void =
        if (A := Agent?):
            DockTimer.Complete(A)   # marks success for this agent
        else:
            DockTimer.Complete()    # global complete

    # Timer fired SuccessEvent — player beat the clock!
    OnTimerSuccess(Agent : ?agent) : void =
        # In a real island you'd grant loot, open a vault door, etc.
        # The timer device itself handles the HUD celebration.
        if (A := Agent?):
            DockTimer.ResetForAll(A)   # reset so the next racer gets a fresh clock

    # Timer fired FailureEvent — time ran out
    OnTimerFailure(Agent : ?agent) : void =
        # Reset the timer so the player can try again
        DockTimer.ResetForAll()

    # Urgency mode fired — crank up the pressure!
    # We shave 2 seconds off the remaining time to punish dawdling.
    OnUrgencyMode(Agent : ?agent) : void =
        if (A := Agent?):
            # GetActiveDuration returns the current remaining seconds
            CurrentTime : float = DockTimer.GetActiveDuration(A)
            NewTime : float = CurrentTime - 2.0
            if (NewTime > 0.0):
                DockTimer.SetActiveDuration(NewTime, A)

Line-by-line breakdown:

Lines What's happening
@editable fields Declare every device as an editable field so UEFN can wire the placed actor to your code. Without this, the identifier is unknown at compile time.
OnBegin Subscribe all event handlers here. OnBegin is the island's entry point and runs with <suspends> so async work is legal.
StartTrigger.TriggeredEvent.Subscribe(OnDockEntered) Hooks the pressure plate. When a player steps on it, OnDockEntered fires.
DockTimer.Start(A) Starts the countdown for the specific agent who stepped on the plate.
DockTimer.Complete(A) Forces the timer to fire SuccessEvent immediately — the player reached the chest.
OnTimerSuccess / OnTimerFailure React to the timer's natural end. Both receive ?agent — always unwrap with if (A := Agent?):.
GetActiveDuration + SetActiveDuration Read and write the live remaining time in seconds. Used here to shave 2 seconds off during urgency mode.
DockTimer.ResetForAll() Snaps the timer back to its configured base duration and stops it, ready for the next attempt.

Common patterns

Pattern 1 — Global pause and resume (cinematic cutscene mid-race)

You want to pause the race clock while a cinematic plays, then resume it seamlessly.

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

cutscene_pause_manager := class(creative_device):

    @editable
    RaceTimer : timer_device = timer_device{}

    @editable
    CutsceneTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        CutsceneTrigger.TriggeredEvent.Subscribe(OnCutsceneStart)

    OnCutsceneStart(Agent : ?agent) : void =
        # Freeze the clock for ALL players while the cutscene plays
        RaceTimer.PauseForAll()

        # Simulate the cutscene duration (5 seconds)
        Sleep(5.0)

        # Resume the clock for everyone once the cutscene ends
        RaceTimer.ResumeForAll()

Key calls: PauseForAll() and ResumeForAll() — both operate on every agent simultaneously, ideal for shared-world events like cinematics or round transitions.


Pattern 2 — Urgency mode as a difficulty signal

When urgency mode fires, disable a shortcut trigger so players can't cheese the last stretch.

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

shortcut_lockout_manager := class(creative_device):

    @editable
    CoveTimer : timer_device = timer_device{}

    @editable
    ShortcutTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        CoveTimer.StartUrgencyModeEvent.Subscribe(OnUrgency)
        # Start the global timer immediately at island start
        CoveTimer.Start()

    OnUrgency(Agent : ?agent) : void =
        # Lock the shortcut path once urgency mode fires
        ShortcutTrigger.Disable()
        # Give the shortcut trigger a fresh reset delay for next round
        ShortcutTrigger.SetResetDelay(30.0)

Key calls: CoveTimer.Start() (global start), StartUrgencyModeEvent.Subscribe, ShortcutTrigger.Disable(), ShortcutTrigger.SetResetDelay().


Pattern 3 — Force-complete the timer for all players at once

A lagoon boss is defeated — everyone wins simultaneously regardless of their individual timers.

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

boss_defeat_manager := class(creative_device):

    @editable
    LagoonTimer : timer_device = timer_device{}

    @editable
    BossDefeatedTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        LagoonTimer.StartForAll()   # everyone's clock ticks from island start
        BossDefeatedTrigger.TriggeredEvent.Subscribe(OnBossDefeated)

    OnBossDefeated(Agent : ?agent) : void =
        # Instantly fire SuccessEvent for every player on the island
        LagoonTimer.CompleteForAll()

Key calls: StartForAll() and CompleteForAll() — broadcast timer control to every agent in one call.

Gotchas

1. Always unwrap ?agent before using it

SuccessEvent, FailureEvent, and StartUrgencyModeEvent all send ?agent (an optional agent), not a bare agent. You must unwrap it:

# CORRECT
OnTimerSuccess(Agent : ?agent) : void =
    if (A := Agent?):
        DockTimer.Complete(A)

# WRONG — compile error, ?agent ≠ agent
OnTimerSuccess(Agent : ?agent) : void =
    DockTimer.Complete(Agent)   # type mismatch!

2. @editable is mandatory for placed devices

If you write DockTimer.Start() without declaring DockTimer as an @editable field in a class(creative_device), Verse reports Unknown identifier. Every device reference must be an editable field wired in the UEFN Details panel.

3. SetActiveDuration only works while the timer is running

Calling SetActiveDuration on a stopped or paused timer has no effect. Always call it after Start or Resume.

4. Per-agent vs. global methods

Methods like Start(Agent:agent) and Start() are different overloads. If your timer is configured as Is State Per Agent = true, always pass the agent — calling the global overload may not affect individual players as expected.

5. ResetForAll stops the timer

ResetForAll() snaps the clock back to its base duration and stops it. If you want players to immediately race again, call StartForAll() right after.

6. message parameters need localization wrappers

If you ever pass text to a device that expects a message type (e.g. HUD labels), you cannot pass a raw string. Declare a localizer:

MyLabel<localizes>(S : string) : message = "{S}"
# then pass: MyLabel("Dock Race")

There is no StringToMessage function in Verse.

Guides & scripts that use timer_device

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

Build your own lesson with timer_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 →