Overview
When you write Verse for UEFN, the very first lines of every file look like this:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
Each using line imports a module — a named, path-addressed bundle of code owned by someone (Fortnite.com, Verse.org, or you). Without the right using, the names you need (trigger_device, timer_device, Subscribe) don't exist in your scope and the compiler reports 'Unknown identifier'. That is the #1 beginner error, and it's always a missing using.
Modules solve a real game problem: code organization and reuse. Say your pirate cove has three devices that all need to "reward the player who reached the treasure" the same way. Instead of copy-pasting that logic three times, you put it in one module and using it from each device. Reach for modules when:
- You need a symbol from Epic's libraries (devices, math, UI) — you
usingtheir module. - You want to share helper functions/types between your own scripts — you author your own module.
This article teaches both: importing the standard modules to make a trigger_device start a timer_device, then factoring shared helpers into your own module.
API Reference
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. |
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. |
Walkthrough
The scene: A sunny cel-shaded cove. A wooden pressure plate sits at the end of the dock. When a pirate steps on it, a treasure countdown begins — they have to reach the glowing chest on the clifftop before the timer runs out. We use two devices from /Fortnite.com/Devices: a trigger_device (the plate) and a timer_device (the countdown).
Notice the using block at the very top — those lines are the whole point of this article. /Fortnite.com/Devices gives us trigger_device and timer_device; /Verse.org/Simulation gives us creative_device and Subscribe.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
# This whole file lives inside the modules imported above.
cove_treasure_run := class(creative_device):
# @editable fields let you drag the placed devices in from the Outliner.
@editable
StartPlate : trigger_device = trigger_device{}
@editable
TreasureTimer : timer_device = timer_device{}
OnBegin<override>()<suspends>:void =
# Only let the run start once per life so pirates can't spam it.
StartPlate.SetMaxTriggerCount(1)
# A short cooldown before it can fire again if we ever reset.
StartPlate.SetResetDelay(2.0)
# Wire the plate's event to our handler method.
StartPlate.TriggeredEvent.Subscribe(OnPlateStepped)
# React to the timer finishing well or badly.
TreasureTimer.SuccessEvent.Subscribe(OnTreasureReached)
TreasureTimer.FailureEvent.Subscribe(OnTimeUp)
# Enable both devices so they respond.
StartPlate.Enable()
TreasureTimer.Enable()
# TriggeredEvent hands us (Agent : ?agent) — an OPTIONAL agent.
OnPlateStepped(Agent : ?agent):void =
if (Pirate := Agent?):
# Start the countdown just for the pirate who stepped on the plate.
TreasureTimer.Start(Pirate)
OnTreasureReached(Agent : ?agent):void =
if (Pirate := Agent?):
# They made it! Give the plate back to the next player.
StartPlate.Enable()
OnTimeUp(Agent : ?agent):void =
if (Pirate := Agent?):
# Ran out of time — reset the timer for everyone.
TreasureTimer.ResetForAll()
Line by line:
- The two
usinglines are the module imports. Delete/Fortnite.com/Devicesandtrigger_devicebecomes an unknown identifier — the module is where that type is defined. class(creative_device)— your script must be a creative_device to hold@editabledevice fields and runOnBegin.SetMaxTriggerCount(1)andSetResetDelay(2.0)— realtrigger_devicemethods configuring how often the plate fires.TriggeredEvent.Subscribe(OnPlateStepped)—Subscribecomes from the simulation module; it connects the device's event to a method.OnPlateStepped(Agent : ?agent)— alistenable(?agent)always hands an optional agent.if (Pirate := Agent?)unwraps it safely.TreasureTimer.Start(Pirate)— starts the countdown for just that pirate.- The timer's
SuccessEvent/FailureEventdrive win/lose reactions.
Common patterns
Pattern 1 — Authoring your OWN module to share a helper
Here the file declares a module named cove_helpers and then usings it in the same file. The helper starts a timer for a pirate — logic you could reuse across many devices. This is exactly how you factor shared code out.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
# Our own module — a named bundle of shared code we can import elsewhere.
cove_helpers := module:
# A shared helper any device can call.
BeginRunFor<public>(Timer : timer_device, Pirate : agent):void =
Timer.Enable(Pirate)
Timer.Start(Pirate)
# Import our module so its functions are in scope.
using { cove_helpers }
lagoon_starter := class(creative_device):
@editable
Plate : trigger_device = trigger_device{}
@editable
RunTimer : timer_device = timer_device{}
OnBegin<override>()<suspends>:void =
Plate.TriggeredEvent.Subscribe(OnStep)
OnStep(Agent : ?agent):void =
if (Pirate := Agent?):
# Call the shared helper from our module.
BeginRunFor(RunTimer, Pirate)
Pattern 2 — Timer control for everyone (module methods for all agents)
When a captain rings the ship's bell (a trigger), the whole crew's shared countdown starts. This uses the *ForAll overloads and shows a trigger with no reset limit.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
ship_bell := class(creative_device):
@editable
Bell : trigger_device = trigger_device{}
@editable
CrewTimer : timer_device = timer_device{}
OnBegin<override>()<suspends>:void =
# 0 = no trigger limit; the bell can ring all match.
Bell.SetMaxTriggerCount(0)
Bell.TriggeredEvent.Subscribe(OnBellRung)
CrewTimer.SuccessEvent.Subscribe(OnCrewFinished)
OnBellRung(Agent : ?agent):void =
# Start (and reset) the shared countdown for the entire crew.
CrewTimer.ResetForAll()
CrewTimer.StartForAll()
OnCrewFinished(Agent : ?agent):void =
# Pause the timer for everyone once the objective is met.
CrewTimer.PauseForAll()
Pattern 3 — Reading timer state and adjusting duration
A lookout trigger checks how much time remains and, on a fresh start, sets a fixed active duration for that pirate. Shows GetActiveDuration/SetActiveDuration and a code-driven Trigger().
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
lookout_post := class(creative_device):
@editable
Lookout : trigger_device = trigger_device{}
@editable
DiveTimer : timer_device = timer_device{}
OnBegin<override>()<suspends>:void =
Lookout.TriggeredEvent.Subscribe(OnSpotted)
DiveTimer.StartUrgencyModeEvent.Subscribe(OnUrgency)
OnSpotted(Agent : ?agent):void =
if (Pirate := Agent?):
# Give this pirate a 30-second dive window, then start.
DiveTimer.SetActiveDuration(30.0, Pirate)
DiveTimer.Start(Pirate)
OnUrgency(Agent : ?agent):void =
# Time is almost up — fire the trigger from code (no agent needed).
Lookout.Trigger()
Gotchas
- 'Unknown identifier' almost always means a missing
using. Iftimer_deviceorSubscribearen't recognized, addusing { /Fortnite.com/Devices }andusing { /Verse.org/Simulation }. The module is where the name is defined. usinggoes at the top, before definitions. Verse is explicit — it will not auto-import anything for you.- Optional agents must be unwrapped.
TriggeredEvent,SuccessEvent,FailureEvent, andStartUrgencyModeEventare alllistenable(?agent). Always doif (Pirate := Agent?):before using the pirate. @editabledevice fields are required to call a placed device. A bareTimer.Start()at file scope fails — the device must be a field inside yourclass(creative_device)and assigned in the Outliner.Start()vsStart(Agent)vsStartForAll()are different overloads. Per-agent timers only affect one pirate; use theForAllversions for the whole lobby.- Your own module's members need
<public>to be usable outside it. In Pattern 1,BeginRunFor<public>is callable afterusing { cove_helpers }; drop<public>and it stays hidden. - No
int↔floatauto-convert.SetActiveDurationandSetResetDelaytakefloat— write30.0, not30. - A
messageparam needs localized text, e.g.MyText<localizes>(S:string):message = "{S}"— there is noStringToMessage. (None of these device methods take a message, but keep it in mind when you add HUD text.)