Overview
The scout_spire_device is a self-contained boss encounter device. Place it in your level and it will autonomously track nearby players, charge a laser, and fire. What makes it powerful for Verse creators is its event surface: you can subscribe to the charge phase and the fire phase separately, letting you build warning systems, damage multipliers, cinematic reactions, or escape sequences around the Spire's attack cycle.
Reach for this device when you want:
- A persistent environmental threat that players must avoid or defeat.
- A dramatic moment where you warn players a laser is incoming (charge event) and then react after it fires (fire event).
- The ability to remove the Spire from the scene programmatically — for example, after a boss-kill condition is met — using
Despawn.
The Scout Spire inherits from has_spire_functionality, which gives it additional methods like Reset, Spawn, Destroy, SetTarget, and state-query functions (IsDestroyed, IsEnabled, IsSpawned). This article focuses on the three API members unique to scout_spire_device itself: BeginChargeLaserEvent, EndChargeAndFireLaserEvent, and Despawn.
API Reference
scout_spire_device
A boss-like environmental encounter that will attack players with different abilities
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
scout_spire_device<public> := class<concrete><final>(creative_device_base, has_spire_functionality):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
BeginChargeLaserEvent |
BeginChargeLaserEvent<public>:listenable(tuple()) |
Triggers when the Spire begins its laser attack |
EndChargeAndFireLaserEvent |
EndChargeAndFireLaserEvent<public>:listenable(tuple()) |
Triggers when the Spire shoots its laser attack. Triggers once, even if it shoots at multiple targets |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Despawn |
Despawn<public>():void |
Hides the spire immediately without playing any vfx * Does nothing if the Spire is already destroyed or despawned. |
Walkthrough
Scenario: Laser Warning System with Auto-Despawn
You have a gauntlet room. A Scout Spire guards the exit. When it starts charging its laser, a warning announcement plays and a countdown begins. When it fires, the game logs the shot. After the Spire fires three times, it despawns — the gauntlet is cleared and players can advance.
This example subscribes to both laser events and calls Despawn after the third shot.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Attach this Verse device to your level.
# Wire SpireDevice to your placed scout_spire_device in the Details panel.
spire_gauntlet_manager := class(creative_device):
# Reference to the Scout Spire placed in the level
@editable
SpireDevice : scout_spire_device = scout_spire_device{}
# How many laser shots before the Spire despawns
ShotsToSurvive : int = 3
# Mutable shot counter
var ShotsFired : int = 0
# Called when the island starts
OnBegin<override>()<suspends> : void =
# Subscribe to the charge-start event
SpireDevice.BeginChargeLaserEvent.Subscribe(OnLaserChargeBegin)
# Subscribe to the fire event
SpireDevice.EndChargeAndFireLaserEvent.Subscribe(OnLaserFired)
Print("Gauntlet started — survive {ShotsToSurvive} laser blasts!")
# Handler: Spire just started charging its laser
# BeginChargeLaserEvent is listenable(tuple()), so the handler takes no arguments
OnLaserChargeBegin() : void =
Print("⚡ WARNING: Spire is charging its laser — take cover!")
# Handler: Spire just fired its laser
OnLaserFired() : void =
set ShotsFired = ShotsFired + 1
Print("💥 Laser fired! Shot {ShotsFired} of {ShotsToSurvive}.")
if (ShotsFired >= ShotsToSurvive):
Print("Gauntlet cleared! Despawning the Spire...")
# Hides the Spire immediately — no VFX, instant removal
SpireDevice.Despawn()
Line-by-line breakdown:
| Lines | What's happening |
|---|---|
@editable SpireDevice |
Exposes the Spire reference in the UEFN Details panel so you can wire it to your placed device. |
OnBegin |
The island entry point. We subscribe both handlers here before any gameplay begins. |
BeginChargeLaserEvent.Subscribe(OnLaserChargeBegin) |
Registers our warning handler. Every time the Spire starts a charge, OnLaserChargeBegin runs. |
EndChargeAndFireLaserEvent.Subscribe(OnLaserFired) |
Registers our shot-counter handler. Fires once per attack cycle even if the Spire targets multiple players. |
set ShotsFired = ShotsFired + 1 |
Mutates the counter. Verse requires set to write to a var. |
SpireDevice.Despawn() |
Instantly hides the Spire. Safe to call even if already despawned — it's a no-op in that case. |
Important: Both
BeginChargeLaserEventandEndChargeAndFireLaserEventarelistenable(tuple()). Atuple()payload means the event carries no data — your handler signature takes no parameters. This is different from events that pass anagentor?agent.
Common patterns
Pattern 1 — Charge-phase countdown timer (BeginChargeLaserEvent)
When the Spire starts charging, spawn a timed async task that counts down so players know exactly how long they have to dodge.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
spire_charge_timer := class(creative_device):
@editable
SpireDevice : scout_spire_device = scout_spire_device{}
OnBegin<override>()<suspends> : void =
SpireDevice.BeginChargeLaserEvent.Subscribe(OnChargeStarted)
OnChargeStarted() : void =
# Spawn an async countdown so the main event loop isn't blocked
spawn { RunChargeCountdown() }
RunChargeCountdown()<suspends> : void =
Print("Laser charging — 3...")
Sleep(1.0)
Print("Laser charging — 2...")
Sleep(1.0)
Print("Laser charging — 1... DODGE!")
Sleep(1.0)
Key point: OnChargeStarted is a synchronous handler (no <suspends>), so we use spawn { RunChargeCountdown() } to run the countdown concurrently without blocking the event system.
Pattern 2 — Instant Despawn on a trigger (Despawn)
A button or trigger in your level lets a game-master remove the Spire mid-match — useful for playtesting or a "mercy" mechanic.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
spire_removal_controller := class(creative_device):
@editable
SpireDevice : scout_spire_device = scout_spire_device{}
# A trigger_device placed in the level — stepping on it removes the Spire
@editable
RemovalTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# trigger_device.TriggeredEvent passes ?agent
RemovalTrigger.TriggeredEvent.Subscribe(OnRemovalTriggered)
OnRemovalTriggered(Agent : ?agent) : void =
# Unwrap the optional agent before using it
if (A := Agent?):
Print("Agent triggered Spire removal.")
# Despawn is safe to call regardless — no-op if already gone
SpireDevice.Despawn()
Print("Scout Spire despawned.")
Key point: trigger_device.TriggeredEvent passes ?agent (an optional agent), so we unwrap with if (A := Agent?). Despawn() itself needs no agent — it always acts on the Spire unconditionally.
Pattern 3 — React differently to charge vs. fire (both events)
Track the full attack cycle: enable a shield prop during the charge phase, then disable it after the shot lands.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
spire_shield_sync := class(creative_device):
@editable
SpireDevice : scout_spire_device = scout_spire_device{}
# A conditional button or barrier device you use as a "shield" prop
@editable
ShieldBarrier : barrier_device = barrier_device{}
OnBegin<override>()<suspends> : void =
SpireDevice.BeginChargeLaserEvent.Subscribe(OnChargeBegin)
SpireDevice.EndChargeAndFireLaserEvent.Subscribe(OnLaserFired)
# Raise the shield the moment the Spire starts charging
OnChargeBegin() : void =
ShieldBarrier.Enable()
Print("Shield UP — laser incoming!")
# Lower the shield after the shot — danger has passed
OnLaserFired() : void =
ShieldBarrier.Disable()
Print("Shield DOWN — laser discharged.")
Key point: EndChargeAndFireLaserEvent fires once per attack cycle, even when the Spire targets multiple players simultaneously. Don't assume it fires once per player hit.
Gotchas
1. Both laser events are listenable(tuple()) — handlers take NO parameters
Unlike many Fortnite device events that pass an agent or ?agent, both BeginChargeLaserEvent and EndChargeAndFireLaserEvent carry a tuple() payload — meaning no data at all. Your handler must have the signature MyHandler() : void. Adding a parameter will cause a compile error.
# ✅ Correct
OnLaserFired() : void = ...
# ❌ Wrong — tuple() carries no agent
OnLaserFired(Agent : agent) : void = ...
2. Despawn is NOT the same as Destroy
Despawn() hides the Spire without VFX and without triggering DestroyEvent. If you want the Spire to die with its death animation and fire DestroyEvent, call Destroy() instead (inherited from has_spire_functionality). Use Despawn for silent removal (e.g., end-of-round cleanup); use Destroy for in-game death.
3. Despawn is a no-op if already despawned or destroyed
Calling Despawn() on a Spire that is already hidden or destroyed does nothing — it won't throw an error. This makes it safe to call defensively, but don't rely on it as a state check. Use IsSpawned<override>() (a <decides> function from has_spire_functionality) if you need to branch on state.
# Safe state check before acting
if (SpireDevice.IsSpawned[]):
SpireDevice.Despawn()
4. EndChargeAndFireLaserEvent fires ONCE per attack, not once per target
The Spire can attack multiple players simultaneously, but EndChargeAndFireLaserEvent still fires exactly once per attack cycle. Do not use it to count per-player hits — it is an attack-cycle event, not a hit event.
5. You MUST declare the device as an @editable field
You cannot instantiate scout_spire_device{} and call methods on it meaningfully at runtime — the device must be placed in the UEFN level and wired via the Details panel. The @editable declaration is what creates that wire. A bare scout_spire_device{}.Despawn() will compile but will act on a dummy instance, not your placed device.