Overview
The player_spawner_device is a placeable Creative device that defines a spawn location on your island. Out of the box it works like any spawn pad, but its real power comes from Verse: you can enable or disable individual spawners at runtime (perfect for locking spawn zones until a round starts), force-spawn a specific player at a chosen location (great for checkpoints or respawn mechanics), and react when any player spawns from it via SpawnedEvent (useful for granting loadouts, starting timers, or logging analytics).
Reach for player_spawner_device when:
- You need team-specific spawn zones that swap between rounds.
- You want to teleport a player to a safe respawn point after an event.
- You need to know the exact moment a player enters the arena so you can hand them gear.
API Reference
player_spawner_device
Used to spawn an
agenton an island. Use multipleplayer_spawner_devices to spawn multipleagents.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
player_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 an agent is spawned from this device. Sends the agent that spawned. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
SpawnPlayer |
SpawnPlayer<public>(Player:player):void |
Spawn Player from this device. Uses the device's ShouldRespawnAlivePlayers setting to control behavior when called on an alive player. If the device is not a valid spawn for that player, they will respawn from a valid spawn device, or f |
Walkthrough
Scenario: A wave-survival arena. The arena has two spawn pads — a "safe" lobby spawner and an "arena" spawner. Players wait in the lobby, then when the round begins the lobby spawner is disabled, the arena spawner is enabled, and every player is force-spawned into the fight. When a player spawns in the arena, they're greeted with a log (and you can extend this to grant items).
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Place this Verse device in your level.
# In the Details panel, assign LobbySpawner and ArenaSpawner
# to the two player_spawner_device instances you placed.
wave_spawn_manager := class(creative_device):
# Assign the lobby spawn pad in the Details panel.
@editable
LobbySpawner : player_spawner_device = player_spawner_device{}
# Assign the arena spawn pad in the Details panel.
@editable
ArenaSpawner : player_spawner_device = player_spawner_device{}
# How long (seconds) players wait in the lobby before the round starts.
@editable
LobbyWaitSeconds : float = 10.0
# Called when the game starts.
OnBegin<override>()<suspends> : void =
# Start: lobby is open, arena is closed.
LobbySpawner.Enable()
ArenaSpawner.Disable()
# Subscribe to ArenaSpawner so we know when each player enters the fight.
ArenaSpawner.SpawnedEvent.Subscribe(OnArenaSpawn)
# Wait for the lobby countdown, then launch the round.
Sleep(LobbyWaitSeconds)
StartRound()
# Flips spawn zones and moves all players into the arena.
StartRound() : void =
# Close the lobby so no one spawns back there.
LobbySpawner.Disable()
# Open the arena.
ArenaSpawner.Enable()
# Force every current player to spawn at the arena spawner.
for (Player : GetPlayspace().GetPlayers()):
ArenaSpawner.SpawnPlayer(Player)
# Fires each time a player spawns from ArenaSpawner.
# SpawnedEvent sends an `agent`, not a `player`, so no unwrap needed here
# — but we cast to player if we need player-specific APIs.
OnArenaSpawn(SpawnedAgent : agent) : void =
# Cast agent -> player to access player-only APIs if needed.
if (P := player[SpawnedAgent]):
# Extend here: grant a weapon, start a timer, etc.
# For now we just confirm the spawn happened.
Print("Player entered the arena!")
Line-by-line breakdown:
| Lines | What's happening |
|---|---|
@editable fields |
Wire up the two placed spawn pads in the UEFN Details panel — without this the Verse code can't reach them. |
LobbySpawner.Enable() / ArenaSpawner.Disable() |
Sets the initial state: lobby open, arena locked. |
ArenaSpawner.SpawnedEvent.Subscribe(OnArenaSpawn) |
Registers a handler so we react every time someone spawns from the arena pad. |
Sleep(LobbyWaitSeconds) |
Suspends the coroutine for the lobby countdown — OnBegin is <suspends> so this is safe. |
LobbySpawner.Disable() / ArenaSpawner.Enable() |
Swaps the active zone when the round starts. |
ArenaSpawner.SpawnPlayer(Player) |
Force-moves each player to the arena spawner, regardless of where they currently are. |
OnArenaSpawn |
Handler receives the agent from SpawnedEvent; cast to player with player[SpawnedAgent] for player-specific work. |
Common patterns
Pattern 1 — Checkpoint respawn (SpawnPlayer)
A player touches a checkpoint trigger and from that point on they respawn at that checkpoint's dedicated spawner.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Place this device in the level and wire up the fields in the Details panel.
checkpoint_respawn := class(creative_device):
# The trigger a player walks through to activate the checkpoint.
@editable
CheckpointTrigger : trigger_device = trigger_device{}
# The spawn pad associated with this checkpoint.
@editable
CheckpointSpawner : player_spawner_device = player_spawner_device{}
OnBegin<override>()<suspends> : void =
# Enable the spawner so it's valid when needed.
CheckpointSpawner.Enable()
# Listen for a player hitting the checkpoint trigger.
CheckpointTrigger.TriggeredEvent.Subscribe(OnCheckpointReached)
# trigger_device sends ?agent — unwrap before use.
OnCheckpointReached(MaybeAgent : ?agent) : void =
if (A := MaybeAgent?):
if (P := player[A]):
# Immediately respawn the player at this checkpoint.
# If ShouldRespawnAlivePlayers is false in device settings,
# this will only take effect on their next death.
CheckpointSpawner.SpawnPlayer(P)
Print("Checkpoint saved!")
Pattern 2 — Timed spawn zone rotation (Enable / Disable)
Two spawn zones alternate every 30 seconds — useful for a king-of-the-hill variant where the safe spawn area shifts.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
rotating_spawn_zones := class(creative_device):
@editable
ZoneA : player_spawner_device = player_spawner_device{}
@editable
ZoneB : player_spawner_device = player_spawner_device{}
# Seconds each zone stays active before swapping.
@editable
SwapInterval : float = 30.0
OnBegin<override>()<suspends> : void =
# Zone A starts active, Zone B starts locked.
ZoneA.Enable()
ZoneB.Disable()
# Rotate forever (or until the game ends).
loop:
Sleep(SwapInterval)
ZoneA.Disable()
ZoneB.Enable()
Print("Spawns moved to Zone B")
Sleep(SwapInterval)
ZoneB.Disable()
ZoneA.Enable()
Print("Spawns moved to Zone A")
Pattern 3 — Loadout granter on spawn (SpawnedEvent)
Every time a player spawns from the arena pad, grant them a starting item via an item_granter_device. This pattern shows reacting to SpawnedEvent to drive downstream devices.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
loadout_on_spawn := class(creative_device):
@editable
ArenaSpawner : player_spawner_device = player_spawner_device{}
# An item_granter_device placed in the level, configured with the
# starting weapon in its Details panel.
@editable
WeaponGranter : item_granter_device = item_granter_device{}
OnBegin<override>()<suspends> : void =
ArenaSpawner.Enable()
# Subscribe: every spawn from this pad triggers a loadout grant.
ArenaSpawner.SpawnedEvent.Subscribe(OnPlayerSpawned)
# SpawnedEvent delivers an `agent` directly (not ?agent).
OnPlayerSpawned(SpawnedAgent : agent) : void =
# item_granter_device.GrantItem takes an agent — no cast needed.
WeaponGranter.GrantItem(SpawnedAgent)
Print("Loadout granted to spawning player")
Gotchas
1. Always declare devices as @editable fields
You cannot write player_spawner_device{}.Enable() inline — that creates a disconnected default instance with no placed counterpart. Every device you want to control must be an @editable field wired up in the UEFN Details panel.
2. SpawnedEvent sends agent, not ?agent
SpawnedEvent is typed listenable(agent) — your handler signature must be (SpawnedAgent : agent) : void, not (MaybeAgent : ?agent). Contrast this with trigger_device.TriggeredEvent which sends ?agent and requires an unwrap (if (A := MaybeAgent?):).
3. SpawnPlayer and the ShouldRespawnAlivePlayers setting
If the device's ShouldRespawnAlivePlayers option is false (the default), calling SpawnPlayer on a currently-alive player does nothing until they next die. Set it to true in the device's Details panel if you need to teleport living players immediately.
4. Disabled spawners are skipped, not errored
If SpawnPlayer is called on a disabled spawner (or one that isn't valid for that player's team), the engine silently falls back to another valid spawner. It won't crash your script, but the player may not end up where you expected — always Enable() the target spawner before calling SpawnPlayer.
5. Sleep requires a <suspends> context
The rotation pattern uses Sleep inside loop — this only works because OnBegin is declared <suspends>. If you call Sleep from a plain event handler (not <suspends>), the code won't compile. Spawn your long-running logic as a spawn { MyAsyncFunction() } call if you need async behavior outside OnBegin.