Reference Devices compiles

creature_spawner_device: Waves of Fiends on Demand

Need a horde of fiends to pour out when players breach a vault, then vanish when the round ends? The Creature Spawner device is your monster faucet. In this article you'll wire it up in Verse — spawning at exact positions, reacting to kills, and cleaning up the battlefield on command.

Updated Examples verified on the live UEFN compiler

Overview

The Creature Spawner device spawns one or more waves of creatures (Fortnite "fiends" and other creature types) at configurable intervals. While most of its behavior is configured in the device's Details panel, Verse gives you precise, event-driven control: you can enable/disable the faucet, spawn a creature at an exact world position, listen for spawns and eliminations, wipe all spawned creatures, and even destroy the spawner itself.

Reach for this device when you want a survival arena, a horde-mode wave that starts when players step on a plate, a boss room that floods with enemies, or any scenario where creatures need to appear and be cleaned up under script control.

Key ideas you'll use:

  • SpawnAt(...) is <suspends> — it takes time to load the creature, so it must be called from an async context and returns a ?agent you unwrap.
  • SpawnedEvent and EliminatedEvent let you score kills, track counts, and chain logic.
  • GetSpawnLimit() tells you the device's configured cap so you don't spawn into a wall.

API Reference

creature_spawner_device

Used to spawn one or more waves of creatures of customizable types at selected time intervals.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).

creature_spawner_device<public> := class<concrete><final>(creative_device_base):

Events (subscribe a handler to react):

Event Signature Description
SpawnedEvent SpawnedEvent<public>:listenable(agent) Signaled when a creature is spawned. Sends the agent creature who was spawned.
EliminatedEvent EliminatedEvent<public>:listenable(device_ai_interaction_result) Signaled when a creature is eliminated. Source is the agent that has eliminated the creature. If the creature was eliminated by a non-agent then Source is 'false'. Target is the creature that was eliminated.

Methods (call these to make the device act):

Method Signature Description
SpawnAt SpawnAt<public>(Position:(/Verse.org/SpatialMath:)vector3, ?Rotation:?(/Verse.org/SpatialMath:)rotation Spawn a creature at the given position. When Rotation is not provided, it will default to the Device's rotation. Returns the agent spawned or false if the device has reached its maximum spawn count. This function is <suspends> because it
Enable Enable<public>():void Enables this device.
Disable Disable<public>():void Disables this device.
DestroySpawner DestroySpawner<public>():void Destroys this device.
EliminateCreatures EliminateCreatures<public>():void Eliminates all creatures spawned by this device.
GetSpawnLimit GetSpawnLimit<public>()<transacts>:int Returns the spawn limit of the device.

Walkthrough

Let's build a horde arena: when a player steps on a trigger plate, we enable the spawner, manually spawn an extra wave at a fixed position, count kills, and once the spawn limit's worth of creatures are eliminated we eliminate any stragglers and disable the device.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/SpatialMath }
using { /UnrealEngine.com/Temporary/Diagnostics }

horde_arena := class(creative_device):

    # Drag your Creature Spawner device here in the Details panel.
    @editable
    Spawner : creature_spawner_device = creature_spawner_device{}

    # The plate players step on to start the horde.
    @editable
    StartPlate : trigger_device = trigger_device{}

    # How many creatures have been eliminated this round.
    var Eliminated : int = 0

    OnBegin<override>()<suspends>:void =
        # React to spawns and kills.
        Spawner.SpawnedEvent.Subscribe(OnCreatureSpawned)
        Spawner.EliminatedEvent.Subscribe(OnCreatureEliminated)
        # Start the horde when a player steps on the plate.
        StartPlate.TriggeredEvent.Subscribe(OnPlateStepped)
        # Begin with the faucet off.
        Spawner.Disable()

    OnPlateStepped(Agent : ?agent):void =
        # Turn the faucet on so the device's own waves begin.
        Spawner.Enable()
        # Also drop one bonus creature right at the device, asynchronously.
        spawn { SpawnBonusWave() }

    SpawnBonusWave()<suspends>:void =
        Limit := Spawner.GetSpawnLimit()
        Print("Spawn limit is {Limit}")
        # SpawnAt suspends while the creature loads; it returns ?agent.
        MaybeCreature := Spawner.SpawnAt(vector3{ Forward := 0.0, Left := 0.0, Up := 200.0 })
        if (Creature := MaybeCreature?):
            Print("Bonus creature spawned!")

    OnCreatureSpawned(Creature : agent):void =
        Print("A creature joined the fight.")

    OnCreatureEliminated(Result : device_ai_interaction_result):void =
        set Eliminated = Eliminated + 1
        Print("Eliminated count: {Eliminated}")
        # Source is the agent that got the kill (false if non-agent).
        if (Killer := Result.Source?):
            Print("A player scored a kill.")
        # Once we've cleared a spawn-limit's worth, end the horde.
        if (Eliminated >= Spawner.GetSpawnLimit()):
            Spawner.EliminateCreatures()
            Spawner.Disable()
            Print("Horde cleared!")```

**Line by line:**
- `@editable Spawner : creature_spawner_device = creature_spawner_device{}`  the field that lets you bind a placed Creature Spawner in the Details panel. Without this `@editable` field, calling its methods fails with `Unknown identifier`.
- `Spawner.SpawnedEvent.Subscribe(OnCreatureSpawned)`  `SpawnedEvent` is `listenable(agent)`, so its handler receives a plain `agent` (already unwrapped).
- `Spawner.EliminatedEvent.Subscribe(OnCreatureEliminated)`  `EliminatedEvent` is `listenable(device_ai_interaction_result)`. The result carries `Source` (the killer, a `?agent`) and `Target` (the creature that died).
- `StartPlate.TriggeredEvent.Subscribe(OnPlateStepped)`  `TriggeredEvent` is `listenable(?agent)`, so its handler takes a `?agent`.
- `Spawner.Disable()` in `OnBegin` keeps creatures from spawning until the plate is stepped.
- `Spawner.Enable()` turns the device on so its configured waves begin.
- `spawn { SpawnBonusWave() }`  `SpawnAt` is `<suspends>`, and our trigger handler is a non-suspending method, so we launch the async work with `spawn`.
- `Spawner.GetSpawnLimit()` returns the device's configured maximum spawn count (`<transacts>`, no side effect).
- `MaybeCreature := Spawner.SpawnAt(...)` then `if (Creature := MaybeCreature?)` — `SpawnAt` returns `?agent`; unwrap it because it's `false` if the device hit its cap.
- `Spawner.EliminateCreatures()` wipes all creatures this device spawned when the round is over.

## Common patterns

### Pattern 1 — Spawn a creature at a precise location with a rotation

Use the `?Rotation` named option when you want the creature to face a specific direction instead of the device's rotation.

```verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/SpatialMath }
using { /UnrealEngine.com/Temporary/Diagnostics }

spawn_at_marker := class(creative_device):

    @editable
    Spawner : creature_spawner_device = creature_spawner_device{}

    # A prop marking where we want the creature to appear.
    @editable
    Marker : creative_prop = creative_prop{}

    OnBegin<override>()<suspends>:void =
        SpawnAtMarker()

    SpawnAtMarker()<suspends>:void =
        Where := Marker.GetGlobalTransform().Translation
        Facing := IdentityRotation()
        Maybe := Spawner.SpawnAt(Where, ?Rotation := Facing)
        if (Creature := Maybe?):
            Print("Creature spawned at the marker.")
        else:
            Print("Spawn failed — limit reached?")

Pattern 2 — Wipe the battlefield and shut down the spawner

A "safe room" panic button: clear every creature this spawner made, then permanently destroy the device.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

panic_button := class(creative_device):

    @editable
    Spawner : creature_spawner_device = creature_spawner_device{}

    @editable
    PanicButton : button_device = button_device{}

    OnBegin<override>()<suspends>:void =
        PanicButton.InteractedWithEvent.Subscribe(OnPanic)

    OnPanic(Agent : agent):void =
        # Remove all creatures this device spawned.
        Spawner.EliminateCreatures()
        # Then destroy the spawner so it never spawns again.
        Spawner.DestroySpawner()
        Print("Battlefield cleared and spawner destroyed.")

Pattern 3 — Score kills from EliminatedEvent

Give the player who eliminated a creature one point each, using the Source field of device_ai_interaction_result.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

kill_scoreboard := class(creative_device):

    @editable
    Spawner : creature_spawner_device = creature_spawner_device{}

    @editable
    ScoreManager : score_manager_device = score_manager_device{}

    OnBegin<override>()<suspends>:void =
        Spawner.Enable()
        Spawner.EliminatedEvent.Subscribe(OnEliminated)

    OnEliminated(Result : device_ai_interaction_result):void =
        # Source is the killer; false if a non-agent (e.g. a trap) made the kill.
        if (Killer := Result.Source?):
            ScoreManager.Activate(Killer)
            Print("Awarded a kill point.")

Gotchas

  • SpawnAt suspends. It's <suspends> because the creature has to load. You can only call it from an async context — inside OnBegin, another <suspends> function, or via spawn { ... }. Calling it directly from a non-suspending event handler won't compile.
  • SpawnAt returns ?agent, not agent. It yields false when the device has reached its spawn cap, so always unwrap with if (Creature := Maybe?): before using the result.
  • SpawnedEvent vs EliminatedEvent payloads differ. SpawnedEvent is listenable(agent) — its handler gets a ready-to-use agent. EliminatedEvent is listenable(device_ai_interaction_result) — you read .Source (a ?agent, the killer) and .Target (the creature). Don't write a handler expecting a bare agent for EliminatedEvent.
  • Source can be false. If a non-agent eliminated the creature (a vehicle, fall, or trap), Result.Source is false. Always unwrap before scoring so you don't crash trying to use a missing killer.
  • Disable() only stops the faucet; it doesn't remove existing creatures. If you want the field clear, call EliminateCreatures() as well.
  • DestroySpawner() is permanent. After destroying the device, further calls (including SpawnAt, Enable) target a device that no longer exists — design your flow so destruction is the last thing it does.
  • You must bind the device. The @editable field is required; a bare creature_spawner_device.SpawnAt(...) is an Unknown identifier error. Drag your placed spawner onto the field in the Details panel.

Device Settings & Options

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

Creature Spawner Device settings and options panel in the UEFN editor — Spawner Type, Creature Type, Number Of Creatures, Activation Range, Spawn Through Walls, Max Spawn Distance, Restore Player Shield on Elimination
Creature Spawner Device — User Options in the UEFN editor: Spawner Type, Creature Type, Number Of Creatures, Activation Range, Spawn Through Walls, Max Spawn Distance, Restore Player Shield on Elimination
⚙️ Settings on this device (7)

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

Spawner Type
Creature Type
Number Of Creatures
Activation Range
Spawn Through Walls
Max Spawn Distance
Restore Player Shield on Elimination

Guides & scripts that use creature_spawner_device

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

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