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 secondstrigger_device(StartTrigger) — pressure plate at the dock entrancetrigger_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.