Overview
The real_time_clock_device is a creative device that bridges real-world UTC time and your island's gameplay logic. You configure a Target Time (and optionally a Duration offset) in the device's UEFN properties panel, then subscribe to its events in Verse to react when those moments arrive.
Use it when:
- You want a daily event (e.g., a boss spawns every day at 18:00 UTC).
- You need something to fire a set duration after a specific time.
- You want different behavior depending on whether the device is enabled before or after the target time has already passed.
Unlike a countdown timer that resets each round, the real-time clock anchors to the actual wall clock — so every player in every session experiences the event at the same real-world moment.
API Reference
real_time_clock_device
Used to trigger in game events based on real world time.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
real_time_clock_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
DurationElapsedEvent |
DurationElapsedEvent<public>:listenable(tuple()) |
Signaled when the optional second Duration time has been reached. |
TimeReachedEvent |
TimeReachedEvent<public>:listenable(tuple()) |
Signaled when the target time is reached. |
EnablingAfterTimeReachedEvent |
EnablingAfterTimeReachedEvent<public>:listenable(tuple()) |
Signaled when this device is enabled after the target time has been reached. |
EnablingBeforeTimeReachedEvent |
EnablingBeforeTimeReachedEvent<public>:listenable(tuple()) |
Signaled when this device is enabled before the target time has been reached. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
Walkthrough
Scenario: A "Daily Vault" door that unlocks at a specific UTC time each day. When the target time arrives (TimeReachedEvent), the vault door prop is revealed and a barrier device is disabled. A second clock fires DurationElapsedEvent to re-lock the vault after the duration window closes. If a player joins after the target time has already passed, EnablingAfterTimeReachedEvent handles that gracefully by keeping the vault open. If they join before the time, EnablingBeforeTimeReachedEvent confirms the vault is still locked.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
# Place this device in your level and wire up the @editable fields in UEFN.
daily_vault_manager := class(creative_device):
# The real_time_clock_device configured with your target UTC time.
# Set "Target Time" and optionally "Duration" in its UEFN properties.
@editable
VaultClock : real_time_clock_device = real_time_clock_device{}
# A barrier device that blocks the vault entrance while locked.
@editable
VaultBarrier : barrier_device = barrier_device{}
# A mutator zone or prop manager — here we use a second barrier
# to represent the "vault is open" state indicator.
@editable
VaultOpenIndicator : barrier_device = barrier_device{}
OnBegin<override>()<suspends> : void =
# Subscribe to all four events so we handle every arrival scenario.
VaultClock.TimeReachedEvent.Subscribe(OnVaultTimeReached)
VaultClock.DurationElapsedEvent.Subscribe(OnVaultDurationElapsed)
VaultClock.EnablingAfterTimeReachedEvent.Subscribe(OnEnabledAfterTime)
VaultClock.EnablingBeforeTimeReachedEvent.Subscribe(OnEnabledBeforeTime)
# Start the clock running.
VaultClock.Enable()
# Keep this coroutine alive so subscriptions remain active.
Sleep(Inf)
# Called at the exact moment the configured UTC time is reached.
OnVaultTimeReached(Args : tuple()) : void =
# Disable the barrier so players can enter the vault.
VaultBarrier.Disable()
# Show the open indicator.
VaultOpenIndicator.Enable()
# Called when the optional Duration window closes — re-lock the vault.
OnVaultDurationElapsed(Args : tuple()) : void =
VaultBarrier.Enable()
VaultOpenIndicator.Disable()
# Disable the clock until the next cycle if desired.
VaultClock.Disable()
# Player joined AFTER the target time — vault should already be open.
OnEnabledAfterTime(Args : tuple()) : void =
VaultBarrier.Disable()
VaultOpenIndicator.Enable()
# Player joined BEFORE the target time — vault stays locked.
OnEnabledBeforeTime(Args : tuple()) : void =
VaultBarrier.Enable()
VaultOpenIndicator.Disable()
Line-by-line explanation:
@editable VaultClock— Exposes thereal_time_clock_deviceto the UEFN details panel so you can drag your placed device into the slot. You must do this; you cannot call device methods on a bare identifier.VaultClock.TimeReachedEvent.Subscribe(OnVaultTimeReached)— RegistersOnVaultTimeReachedto fire the instant the UTC clock hits your configured target time.VaultClock.DurationElapsedEvent.Subscribe(OnVaultDurationElapsed)— Registers a handler for when the optional Duration offset elapses after the target time — perfect for closing a timed window.VaultClock.EnablingAfterTimeReachedEvent.Subscribe(OnEnabledAfterTime)— Handles the case whereEnable()is called (or the session starts) after the target time has already passed. Without this, late-joiners would see the wrong state.VaultClock.EnablingBeforeTimeReachedEvent.Subscribe(OnEnabledBeforeTime)— Confirms the vault is locked for players who arrive before the event.VaultClock.Enable()— Activates the device so it starts watching the clock. Without this call the device does nothing.Sleep(Inf)— KeepsOnBeginsuspended forever so subscriptions are never garbage-collected.- Event handlers take
(Args : tuple())— All four events on this device signallistenable(tuple()), so every handler receives an empty tuple. You don't need to unwrap an agent.
Common patterns
Pattern 1 — Toggle the clock on a trigger (Enable / Disable)
A player interacts with a lever to arm the daily clock, and a second interaction disarms it. This shows Enable and Disable called in response to player actions.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
clock_toggle_controller := class(creative_device):
@editable
DailyClock : real_time_clock_device = real_time_clock_device{}
# A button_device the player interacts with to arm the clock.
@editable
ArmButton : button_device = button_device{}
# A button_device the player interacts with to disarm the clock.
@editable
DisarmButton : button_device = button_device{}
# Tracks whether the clock is currently armed.
var ClockArmed : logic = false
OnBegin<override>()<suspends> : void =
ArmButton.InteractedWithEvent.Subscribe(OnArm)
DisarmButton.InteractedWithEvent.Subscribe(OnDisarm)
# Clock starts disabled — player must arm it.
DailyClock.Disable()
Sleep(Inf)
OnArm(Agent : ?agent) : void =
if (not ClockArmed?):
set ClockArmed = true
DailyClock.Enable()
OnDisarm(Agent : ?agent) : void =
if (ClockArmed?):
set ClockArmed = false
DailyClock.Disable()
Key point: button_device.InteractedWithEvent passes ?agent, so we receive (Agent : ?agent) — but here we only care that someone pressed it, so we ignore the value. Enable() and Disable() are plain void calls with no arguments.
Pattern 2 — Reward chest that fires on DurationElapsedEvent
The clock's target time marks when a daily reward window opens; DurationElapsedEvent marks when it closes. A item_granter_device hands out loot only during the window.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
daily_reward_controller := class(creative_device):
# Configure Target Time = reward window start, Duration = window length.
@editable
RewardClock : real_time_clock_device = real_time_clock_device{}
@editable
LootGranter : item_granter_device = item_granter_device{}
# A trigger_device players step on to claim the reward.
@editable
ClaimTrigger : trigger_device = trigger_device{}
var RewardWindowOpen : logic = false
OnBegin<override>()<suspends> : void =
RewardClock.TimeReachedEvent.Subscribe(OnWindowOpen)
RewardClock.DurationElapsedEvent.Subscribe(OnWindowClose)
RewardClock.EnablingAfterTimeReachedEvent.Subscribe(OnWindowOpen)
RewardClock.EnablingBeforeTimeReachedEvent.Subscribe(OnWindowClose)
ClaimTrigger.TriggeredEvent.Subscribe(OnPlayerClaims)
RewardClock.Enable()
Sleep(Inf)
OnWindowOpen(Args : tuple()) : void =
set RewardWindowOpen = true
ClaimTrigger.Enable()
OnWindowClose(Args : tuple()) : void =
set RewardWindowOpen = false
ClaimTrigger.Disable()
OnPlayerClaims(Agent : ?agent) : void =
if (RewardWindowOpen?):
if (A := Agent?):
LootGranter.GrantItem(A)
Key point: TriggeredEvent on a trigger_device passes ?agent, so we unwrap with if (A := Agent?) before calling LootGranter.GrantItem(A) which requires a concrete agent. The clock events pass tuple() so their handlers use (Args : tuple()).
Pattern 3 — Siren warning using EnablingBeforeTimeReachedEvent
When the session starts before the target time, play a warning sound and show a countdown UI hint. This pattern focuses purely on the two enabling events.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
clock_warning_system := class(creative_device):
@editable
EventClock : real_time_clock_device = real_time_clock_device{}
# An audio_player_device configured with a siren sound.
@editable
SirenAudio : audio_player_device = audio_player_device{}
# A conditional_button or HUD message device to show status.
@editable
StatusDisplay : hud_message_device = hud_message_device{}
OnBegin<override>()<suspends> : void =
EventClock.EnablingBeforeTimeReachedEvent.Subscribe(OnBeforeEvent)
EventClock.EnablingAfterTimeReachedEvent.Subscribe(OnAfterEvent)
EventClock.TimeReachedEvent.Subscribe(OnEventNow)
EventClock.Enable()
Sleep(Inf)
# Session started before the event — warn players it's coming.
OnBeforeEvent(Args : tuple()) : void =
SirenAudio.Play()
StatusDisplay.Show()
# Session started after the event already fired — hide the warning.
OnAfterEvent(Args : tuple()) : void =
SirenAudio.Stop()
StatusDisplay.Hide()
# The moment has arrived — trigger the real event logic.
OnEventNow(Args : tuple()) : void =
SirenAudio.Stop()
StatusDisplay.Hide()
# ... unlock doors, spawn boss, etc.
Key point: EnablingBeforeTimeReachedEvent and EnablingAfterTimeReachedEvent fire once at the moment Enable() is called (or the session begins with the device enabled), letting you set correct initial state without polling.
Gotchas
-
All four events pass
tuple(), not?agent. Unlike most device events (e.g.,trigger_device.TriggeredEvent), the real-time clock events carry no agent payload. Your handlers must be(Args : tuple()) : void. Trying to receive(?agent)will cause a compile error. -
Enable()must be called — the device does nothing by default. If you configure the device in UEFN but forgetVaultClock.Enable()in Verse, none of the events will ever fire. Always callEnable()inOnBegin(or whenever you're ready to start watching the clock). -
EnablingAfterTimeReachedEventandEnablingBeforeTimeReachedEventfire at enable-time, not at the target time. They tell you the state of the clock when the device is enabled. If you callDisable()and thenEnable()again after the target time,EnablingAfterTimeReachedEventwill fire again — use a guard variable (var ClockArmed : logic) if you only want to react once. -
The target time is UTC, not local time. Players in different time zones all experience the event simultaneously. Design your content around UTC and communicate times clearly to your audience.
-
DurationElapsedEventonly fires if you configure a Duration in the device's UEFN properties. If no Duration is set, this event never signals. Don't subscribe to it expecting it to fire without the property configured. -
Sleep(Inf)is required inOnBeginto keep subscriptions alive. IfOnBeginreturns, the coroutine ends and your subscriptions may be cleaned up. Always endOnBeginwithSleep(Inf)when your logic is entirely event-driven. -
You cannot construct
real_time_clock_device{}meaningfully in code. The device must be placed in the UEFN level and referenced via an@editablefield. The= real_time_clock_device{}in the field declaration is just a default placeholder — always drag your placed device into the slot in the details panel.