Overview
The timed_objective_device powers any game where a countdown advances an objective: arming a bomb, holding a control point, capturing intel. A player starts the timer (Begin), defenders can stop it (End), and if nobody stops it in time it fires CompletedEvent — your cue to detonate explosives, award score, or end the round.
Reach for it whenever you need a timer tied to player interaction with teams, not just a passive countdown. (For a purely visual round timer with no objective semantics, the plain timer_device is simpler — but the timed_objective_device gives you Begin/End/Pause/Resume/Restart/Complete plus per-agent enable/disable.)
It pairs naturally with the objective_device, a destructible objective marker (the bomb itself) that you can Destroy, pulse toward, or make invulnerable. We use both together below.
API Reference
timed_objective_device
Configures game modes where players can start or stop timers to advance gameplay objectives, such as Attack/Defend Bomb objectives.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
timed_objective_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
BeganEvent |
BeganEvent<public>:listenable(agent) |
Signaled when the objective begins. Sends the agent that started the timer. |
EndedEvent |
EndedEvent<public>:listenable(agent) |
Signaled when the objective ends. Sends the agent that stopped the timer. |
PausedEvent |
PausedEvent<public>:listenable(agent) |
Signaled when the objective is paused. Sends the agent that paused the timer. |
ResumedEvent |
ResumedEvent<public>:listenable(agent) |
Signaled when the objective is resumed. Sends the agent that resumed the timer. |
RestartedEvent |
RestartedEvent<public>:listenable(agent) |
Signaled when the objective is restarted. Sends the agent that restarted the timer. |
CompletedEvent |
CompletedEvent<public>:listenable(agent) |
Signaled when the objective is completed. Sends the agent that started the timer or completed the timer by calling Complete. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>(Agent:agent):void |
Enables the objective for Agent. |
Disable |
Disable<public>(Agent:agent):void |
Disables the objective for Agent. |
Show |
Show<public>():void |
Makes this device visible. |
Hide |
Hide<public>():void |
Makes this device invisible. |
Begin |
Begin<public>(Agent:agent):void |
Starts the objective with Agent acting as the user the interacted this device. |
End |
End<public>(Agent:agent):void |
Ends the objective with Agent acting as the user the interacted this device. |
Pause |
Pause<public>(Agent:agent):void |
Pauses the objective with Agent acting as the user the interacted this device. |
Resume |
Resume<public>(Agent:agent):void |
Resumes the objective with Agent acting as the user the interacted this device. |
Restart |
Restart<public>(Agent:agent):void |
Restarts the objective with Agent acting as the user the interacted this device. |
Complete |
Complete<public>(Agent:agent):void |
Completes the objective with Agent acting as the user the interacted this device. |
objective_device
Provides a collection of destructible devices that you can select from to use as objectives in your game.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
objective_device<public> := class<concrete><final>(creative_device_base, healthful, damageable, healable):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
DestroyedEvent |
DestroyedEvent<public>:listenable(agent) |
Signaled when this device has been destroyed by an agent. Sends the agent that destroyed this device. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Show |
Show<public>():void |
Shows this device in the world. |
Hide |
Hide<public>():void |
Hides this device from the world. |
ActivateObjectivePulse |
ActivateObjectivePulse<public>(Agent:agent):void |
Activates an objective pulse at Agent's location pointing toward this device. |
DeactivateObjectivePulse |
DeactivateObjectivePulse<public>(Agent:agent):void |
Deactivates the objective pulse at Agent's location. |
Destroy |
Destroy<public>(Agent:agent):void |
Destroys the objective item. This is done regardless of the visibility or health of the item. |
SetInvulnerable |
SetInvulnerable<public>(Invulnerable:logic):void |
Sets the device either invulnerable or damageable |
Walkthrough
Let's build a single bomb site. An attacker interacts with a button to arm the bomb (Begin). A defender's defuse button ends the timer. If the timer runs out, CompletedEvent fires and we destroy the objective prop and pulse all players toward it for drama.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Playspaces }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporal }
bomb_site_manager := class(creative_device):
# The countdown objective that arms/disarms.
@editable
Bomb : timed_objective_device = timed_objective_device{}
# The destructible bomb prop the attackers are defending.
@editable
BombProp : objective_device = objective_device{}
# Attacker arms here.
@editable
ArmButton : button_device = button_device{}
# Defender defuses here.
@editable
DefuseButton : button_device = button_device{}
MyText<localizes>(S:string):message = "{S}"
OnBegin<override>()<suspends>:void =
# React to the objective's lifecycle.
Bomb.BeganEvent.Subscribe(OnArmed)
Bomb.EndedEvent.Subscribe(OnDefused)
Bomb.CompletedEvent.Subscribe(OnDetonated)
# Buttons drive Begin/End.
ArmButton.InteractedWithEvent.Subscribe(OnArmPressed)
DefuseButton.InteractedWithEvent.Subscribe(OnDefusePressed)
# Bomb starts intact and visible; defuse disabled until armed.
BombProp.SetInvulnerable(true)
BombProp.Show()
OnArmPressed(Agent:agent):void =
# Start the countdown, crediting the attacker who pressed.
Bomb.Begin(Agent)
OnDefusePressed(Agent:agent):void =
# End the countdown before it completes.
Bomb.End(Agent)
OnArmed(Agent:agent):void =
# Timer has begun: point everyone at the bomb.
for (Player : GetPlayspace().GetPlayers()):
BombProp.ActivateObjectivePulse(Player)
OnDefused(Agent:agent):void =
# Stopped in time — clear pulses, bomb survives.
for (Player : GetPlayspace().GetPlayers()):
BombProp.DeactivateObjectivePulse(Player)
OnDetonated(Agent:agent):void =
# Countdown reached zero — destroy the prop.
if (A := Agent?):
BombProp.Destroy(A)
Line by line:
- The four
@editablefields let you drop placed devices into the script in the Details panel — without these declared as class fields you cannot call their methods. - In
OnBegin, weSubscribehandlers to the device's real events.BeganEvent,EndedEvent, andCompletedEventarelistenable(agent), so each handler receives anAgent. ArmButton.InteractedWithEventhands us the pressing agent; we forward it toBomb.Begin(Agent)so the device knows who armed it.Bomb.End(Agent)stops an active timer — the defuse.CompletedEventonly fires if the timer was never stopped. There we unwrap the agent withif (A := Agent?)becauseBombProp.Destroytakes a plainagent, then destroy the prop.ActivateObjectivePulse/DeactivateObjectivePulseare objective_device methods that draw a directional pulse from each player toward the bomb — pure juice.
Common patterns
Pause and Resume during a cutscene
When a cinematic plays you usually want the countdown — and its ticking audio — to freeze, then resume after. Use Pause and Resume.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
cutscene_freeze := class(creative_device):
@editable
Bomb : timed_objective_device = timed_objective_device{}
# Player steps in this trigger to start the cutscene.
@editable
CutsceneTrigger : trigger_device = trigger_device{}
# And this one when the cutscene ends.
@editable
ResumeTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends>:void =
Bomb.PausedEvent.Subscribe(OnPaused)
Bomb.ResumedEvent.Subscribe(OnResumed)
CutsceneTrigger.TriggeredEvent.Subscribe(OnCutsceneStart)
ResumeTrigger.TriggeredEvent.Subscribe(OnCutsceneEnd)
OnCutsceneStart(Agent:?agent):void =
if (A := Agent?):
Bomb.Pause(A)
OnCutsceneEnd(Agent:?agent):void =
if (A := Agent?):
Bomb.Resume(A)
OnPaused(Agent:agent):void = {}
OnResumed(Agent:agent):void = {}
Note trigger_device.TriggeredEvent hands a ?agent (optional), so we unwrap with if (A := Agent?) before passing to Pause/Resume.
Restart and Complete from game logic
You can force the objective forward yourself. Restart resets the countdown to full; Complete instantly finishes it (firing CompletedEvent). Here a button restarts the round, and a sudden-death timer completes it.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
round_control := class(creative_device):
@editable
Bomb : timed_objective_device = timed_objective_device{}
@editable
RestartButton : button_device = button_device{}
@editable
SuddenDeathButton : button_device = button_device{}
OnBegin<override>()<suspends>:void =
Bomb.RestartedEvent.Subscribe(OnRestarted)
Bomb.CompletedEvent.Subscribe(OnCompleted)
RestartButton.InteractedWithEvent.Subscribe(OnRestartPressed)
SuddenDeathButton.InteractedWithEvent.Subscribe(OnSuddenDeath)
OnRestartPressed(Agent:agent):void =
Bomb.Restart(Agent)
OnSuddenDeath(Agent:agent):void =
# Skip the wait — finish the objective right now.
Bomb.Complete(Agent)
OnRestarted(Agent:agent):void = {}
OnCompleted(Agent:agent):void = {}
Enable per-team and hide the device
Enable/Disable are per-agent, and Show/Hide toggle the device's world visibility. Enable the objective only for the attacking team as they spawn.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Playspaces }
using { /Verse.org/Simulation }
attacker_enable := class(creative_device):
@editable
Bomb : timed_objective_device = timed_objective_device{}
OnBegin<override>()<suspends>:void =
# Hide the visual until the round is live.
Bomb.Hide()
# Enable the objective for every current participant.
for (Player : GetPlayspace().GetPlayers()):
Bomb.Enable(Player)
# Now reveal it.
Bomb.Show()
Gotchas
- Begin/End/Pause/Resume/Restart/Complete all take an
agent, not nothing. The device records who interacted (for scoring and team filters). If your event source only gives you?agent(like a trigger), unwrap it withif (A := Agent?):first. - CompletedEvent vs EndedEvent are different outcomes.
EndedEventmeans a player stopped the timer (defused);CompletedEventmeans it ran to zero (or you calledComplete). Don't subscribe to one expecting the other's behavior. CompletefiresCompletedEvent. If your CompletedEvent handler also callsComplete, you'll loop. Keep completion-triggering logic out of the completion handler.- objective_device.SetInvulnerable takes a
logic, not a bool literal you'd write elsewhere — passtrueorfalse(Verse logic values).Destroyignores invulnerability and visibility, so it always removes the prop. - Localized text: any
messageparameter (e.g. a custom prompt) needs a<localizes>function likeMyText(S:string):message. There is noStringToMessage. Raw strings won't compile where amessageis expected. - You must declare every placed device as an
@editablefield in thecreative_deviceclass and bind it in the Details panel. CallingBomb.Begin(...)on an unbound/undeclared device gives 'Unknown identifier' or a runtime no-op. GetPlayspace().GetPlayers()returns players, fine for pulses/enable loops, but the objective events still credit whichever agent interacted — track the instigator from the event, not the loop.