Overview
The objective_device is a destructible device you place in the world to act as the goal of a round — think "destroy the enemy generator", "plant on the relic", or "protect the core". Unlike a plain prop, it ships with gameplay-ready behavior: it can be shown or hidden, marked invulnerable during a setup phase, decorated with a directional objective pulse that points players toward it, and it fires a DestroyedEvent telling you exactly which agent finished it off.
Reach for it when your mode has a literal target to defend or destroy. It inherits from healthful, damageable, and healable, so it has real health and can take damage from weapons — but the Verse surface you'll script against day-to-day is small and focused: Show, Hide, ActivateObjectivePulse, DeactivateObjectivePulse, Destroy, SetInvulnerable, and the DestroyedEvent.
API Reference
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 classic "destroy the enemy generator" round. The generator starts hidden and invulnerable during a short setup phase. When the round begins, we show it, make it damageable, and light an objective pulse for the attacking player so they can find it. When someone destroys it, we react to DestroyedEvent, clear their pulse, and announce the winner.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporal }
# A round built around one destructible generator.
generator_round := class(creative_device):
# The destructible objective placed in the level.
@editable
Generator : objective_device = objective_device{}
# A trigger that starts the round when a player steps on it.
@editable
StartPlate : trigger_device = trigger_device{}
# Localized message helper — message params need a localized value, not a raw string.
Banner<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
# Setup phase: the generator is present in the level but should be
# untouchable and invisible until the round formally starts.
Generator.Hide()
Generator.SetInvulnerable(true)
# React to the generator being destroyed for the rest of the match.
Generator.DestroyedEvent.Subscribe(OnGeneratorDestroyed)
# When a player steps on the start plate, begin the round.
StartPlate.TriggeredEvent.Subscribe(OnRoundStart)
# trigger_device hands us an ?agent — unwrap it before use.
OnRoundStart(Agent : ?agent) : void =
if (Player := Agent?):
# Reveal the objective and let weapons hurt it.
Generator.Show()
Generator.SetInvulnerable(false)
# Point an arrow from the player toward the generator.
Generator.ActivateObjectivePulse(Player)
# DestroyedEvent sends the agent that destroyed the device.
OnGeneratorDestroyed(Destroyer : agent) : void =
# The objective is gone — clean up the pulse for the destroyer.
Generator.DeactivateObjectivePulse(Destroyer)
Print("Generator destroyed — round over!")
Line by line:
@editable Generator : objective_device— you must declare the placed device as an@editablefield, then bind it to the level instance in the Details panel. Calling methods on a bareobjective_device{}literal would fail at runtime.Generator.Hide()+SetInvulnerable(true)— during setup the target is invisible and can't be damaged.SetInvulnerabletakes alogic(true/false), not an int.Generator.DestroyedEvent.Subscribe(OnGeneratorDestroyed)— subscribing inOnBeginwires the device event to a method at class scope.StartPlate.TriggeredEventis alistenable(?agent), so the handler receivesAgent : ?agent. We unwrap it withif (Player := Agent?):before using it.Show()/SetInvulnerable(false)flip the objective into its live state.ActivateObjectivePulse(Player)draws a directional beacon from the player's position toward the generator — great for guiding attackers.OnGeneratorDestroyed(Destroyer : agent)—DestroyedEventislistenable(agent), so the handler gets a plain (already-unwrapped)agent. We turn off that player's pulse since the target no longer exists.
Common patterns
Force-destroy the objective when a timer expires
Use Destroy(Agent) to end the objective programmatically — for example, an attacker fails to defend it and the timer kills it. Destroy works regardless of the device's health or visibility.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporal }
timed_demolition := class(creative_device):
@editable
Core : objective_device = objective_device{}
OnBegin<override>()<suspends> : void =
Core.Show()
Core.SetInvulnerable(true)
# Wait 30 seconds, then forcibly destroy the core.
Sleep(30.0)
# Destroy needs an agent — credit the first player on the island.
AllPlayers := GetPlayspace().GetPlayers()
if (FirstPlayer := AllPlayers[0]):
Core.Destroy(FirstPlayer)
Re-show and re-pulse the objective for every player at round start
Loop over all players to give each one a pulse pointing at the freshly revealed objective.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
multi_pulse_objective := class(creative_device):
@editable
Relic : objective_device = objective_device{}
OnBegin<override>()<suspends> : void =
Relic.Show()
Relic.SetInvulnerable(false)
for (Player : GetPlayspace().GetPlayers()):
# Each player gets their own beacon toward the relic.
Relic.ActivateObjectivePulse(Player)
Hide the objective when it's destroyed and stop the pulse
React to DestroyedEvent to tidy up the world — hide any leftover and deactivate the destroyer's pulse.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
cleanup_on_destroy := class(creative_device):
@editable
Target : objective_device = objective_device{}
OnBegin<override>()<suspends> : void =
Target.Show()
Target.DestroyedEvent.Subscribe(OnDestroyed)
OnDestroyed(Destroyer : agent) : void =
Target.DeactivateObjectivePulse(Destroyer)
Target.Hide()
Gotchas
SetInvulnerabletakes alogic, not an int. Passtrueorfalse—SetInvulnerable(1)will not compile. Verse never auto-converts between numeric and logic types.DestroyedEventgives you a plainagent, buttrigger_device.TriggeredEventgives you?agent. Don't try toAgent?-unwrap the destroyer fromDestroyedEvent— it's already anagent. Always check the event's actual signature.ActivateObjectivePulseis per-agent. The pulse is drawn at that specific agent's location. If you want every player to see a beacon, you must call it once per player, and callDeactivateObjectivePulsefor the same agent to clear it.Destroyignores health and visibility. It removes the objective item even if it's hidden or marked invulnerable — useful for ending rounds on a timer, but be sure you actually want it gone.Hide()only hides; it doesn't make the device invulnerable. A hidden objective can still be affected byDestroy. PairHide()withSetInvulnerable(true)for a true "inactive" state during setup.- Message params need a localized value. If you wire announcements through a HUD device, declare a helper like
Banner<localizes>(S:string):message = "{S}"— there is noStringToMessage. - Bind the
@editablefield in the Details panel. A declared-but-unboundobjective_device{}field points at nothing; yourShow/Hidecalls will silently do nothing in-game.