Reference Devices

timed_objective_device: Arm-the-Bomb Countdowns in Verse

The timed_objective_device is the heart of Attack/Defend bomb modes: one team arms a timer, the other races to defuse it before it completes. This article shows how to drive its real Verse API — Begin, Pause, Resume, Restart, Complete — and react to its lifecycle events to build a full bomb-site round.

Updated
The code on this reference page is provided as-is and did not pass the latest compile check — treat the examples as a starting point and verify in your project.
Watch the Knottimed_objective_device in ~90 seconds.

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 @editable fields 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, we Subscribe handlers to the device's real events. BeganEvent, EndedEvent, and CompletedEvent are listenable(agent), so each handler receives an Agent.
  • ArmButton.InteractedWithEvent hands us the pressing agent; we forward it to Bomb.Begin(Agent) so the device knows who armed it.
  • Bomb.End(Agent) stops an active timer — the defuse.
  • CompletedEvent only fires if the timer was never stopped. There we unwrap the agent with if (A := Agent?) because BombProp.Destroy takes a plain agent, then destroy the prop.
  • ActivateObjectivePulse / DeactivateObjectivePulse are 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 with if (A := Agent?): first.
  • CompletedEvent vs EndedEvent are different outcomes. EndedEvent means a player stopped the timer (defused); CompletedEvent means it ran to zero (or you called Complete). Don't subscribe to one expecting the other's behavior.
  • Complete fires CompletedEvent. If your CompletedEvent handler also calls Complete, 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 — pass true or false (Verse logic values). Destroy ignores invulnerability and visibility, so it always removes the prop.
  • Localized text: any message parameter (e.g. a custom prompt) needs a <localizes> function like MyText(S:string):message. There is no StringToMessage. Raw strings won't compile where a message is expected.
  • You must declare every placed device as an @editable field in the creative_device class and bind it in the Details panel. Calling Bomb.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.

Device Settings & Options

The timed_objective_device User Options panel in the UEFN editor — every setting you can tune.

Timed Objective Device settings and options panel in the UEFN editor — Time, Start Score, Stop Score, Completed Score
Timed Objective Device — User Options in the UEFN editor: Time, Start Score, Stop Score, Completed Score
⚙️ Settings on this device (4)

Setting names read from the panel above — may be partial; the screenshots are the source of truth.

Time
Start Score
Stop Score
Completed Score

Guides & scripts that use timed_objective_device

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

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