Reference Devices compiles

scout_spire_device: Boss Encounters That React to Players

The Scout Spire is a boss-like environmental hazard that stalks players and unleashes a devastating laser attack. With its Verse API you can listen for the exact moment the Spire begins charging its laser — and the moment it fires — so your game can respond: warn players, trigger countermeasures, or despawn the Spire entirely when the right conditions are met.

Updated Examples verified on the live UEFN compiler
Watch the Knotscout_spire_device in ~90 seconds.

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 BeginChargeLaserEvent and EndChargeAndFireLaserEvent are listenable(tuple()). A tuple() payload means the event carries no data — your handler signature takes no parameters. This is different from events that pass an agent or ?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.

Device Settings & Options

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

Scout Spire Device settings and options panel in the UEFN editor — Activation Distance, Spawn at Game Start, Enabled at Game Start, Start with Shield
Scout Spire Device — User Options in the UEFN editor: Activation Distance, Spawn at Game Start, Enabled at Game Start, Start with Shield
⚙️ Settings on this device (4)

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

Activation Distance
Spawn at Game Start
Enabled at Game Start
Start with Shield

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