Overview
GetPlayers() is not a placed device — it's a method on the fort_playspace, the container that owns every player and object in your experience. Whenever your game logic needs to reach all the players at once — teleport the whole lobby to the arena, start each player's countdown, grant everyone the opening loadout — you call GetPlayers() to get the current roster as an array []player, then loop over it and drive your devices.
You reach the playspace from inside any creative_device with GetPlayspace(). From there:
GetPlayspace().GetPlayers()→[]player— everyone currently in the match.GetPlayspace().PlayerAddedEvent()→listenable(player)— fires when someone joins.
The key beginner insight: GetPlayers() gives you player values, but nearly every device method (teleport, timer, score) wants an agent. A player is an agent, so you can pass a player straight into methods like Teleporter.Teleport(Agent:agent). This article ties GetPlayers() together with real devices — a teleporter, a timer, and a score manager — so the roster actually does something.
API Reference
(API surface could not be resolved for this device.)
Walkthrough
The scene: players spawn on a sunny wooden dock. When the match starts, we want to sweep every player off the dock and into the cove arena via a teleporter_device, then start each player's timer_device counting down, and give everyone a starting point on the score_manager_device.
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Simulation }
match_starter := class(creative_device):
# Placed devices we drive across the whole roster.
@editable
ArenaTeleporter : teleporter_device = teleporter_device{}
@editable
RoundTimer : timer_device = timer_device{}
@editable
StartScore : score_manager_device = score_manager_device{}
OnBegin<override>()<suspends>:void =
# Grab EVERY player currently in the match from the playspace.
AllPlayers := GetPlayspace().GetPlayers()
# Do the opening routine for each one.
for (P : AllPlayers):
StartRoundForPlayer(P)
# Also handle anyone who joins late.
GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerJoined)
# A player IS an agent, so it passes straight into agent-typed methods.
StartRoundForPlayer(P : player):void =
# Sweep them from the dock into the cove arena.
ArenaTeleporter.Teleport(P)
# Kick off their personal countdown.
RoundTimer.Start(P)
# Hand them their opening point.
StartScore.Activate(P)
# Fires whenever a NEW player enters the playspace mid-match.
OnPlayerJoined(NewPlayer : player):void =
StartRoundForPlayer(NewPlayer)
Line by line:
- The three
@editablefields are the devices we placed in the level. You must declare them as fields on acreative_device— a bareTeleporter.Teleport(...)would fail with 'Unknown identifier'. GetPlayspace().GetPlayers()returns[]player— the live roster the instantOnBeginruns. We store it inAllPlayers.for (P : AllPlayers): StartRoundForPlayer(P)loops over every player and runs the same opening routine on each.- Inside
StartRoundForPlayer,Pis aplayer. Becauseplayeris a subtype ofagent, we pass it directly intoArenaTeleporter.Teleport(P),RoundTimer.Start(P), andStartScore.Activate(P)— all of which takeAgent:agent. PlayerAddedEvent().Subscribe(OnPlayerJoined)covers stragglers.GetPlayers()only captures who's present right now, so we subscribe to the join event to give latecomers the same treatment.
Common patterns
Pattern 1 — Count the roster to gate the round start. Use GetPlayers() just to check how many people are present before playing the opening cinematic.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
lobby_gate := class(creative_device):
@editable
OpeningCinematic : cinematic_sequence_device = cinematic_sequence_device{}
OnBegin<override>()<suspends>:void =
Roster := GetPlayspace().GetPlayers()
# Only roll the intro once at least 2 players are on the cove.
if (Roster.Length >= 2):
OpeningCinematic.Play()
Pattern 2 — Damage everyone who is standing outside a safe zone. Combine the roster with a damage volume's occupancy check: loop the roster, and for anyone NOT in the safe volume, ... here we just teleport out-of-zone players back to safety.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
shore_sweep := class(creative_device):
@editable
SafeVolume : damage_volume_device = damage_volume_device{}
@editable
SafeRift : teleporter_device = teleporter_device{}
OnBegin<override>()<suspends>:void =
for (P : GetPlayspace().GetPlayers()):
# If the player is NOT inside the safe volume, rift them back to it.
if (not SafeVolume.IsInVolume[P]):
SafeRift.Teleport(P)
Pattern 3 — Respawn the whole roster from a spawner. player_spawner_device.SpawnPlayer takes a player directly (no agent needed), which pairs perfectly with the []player roster.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
round_reset := class(creative_device):
@editable
Spawner : player_spawner_device = player_spawner_device{}
OnBegin<override>()<suspends>:void =
for (P : GetPlayspace().GetPlayers()):
Spawner.SpawnPlayer(P)
Gotchas
GetPlayers()is a snapshot, not a live list. It returns who is present the moment you call it. Players who join afterward won't be in that array — subscribe toGetPlayspace().PlayerAddedEvent()(payloadplayer) to catch them, as the walkthrough does.- It lives on the playspace, not a device. There is no
GetPlayers()on a placed device. Always go throughGetPlayspace().GetPlayers()from inside yourcreative_device. playervsagent.GetPlayers()returns[]player. Most device methods wantagent— butplayeris anagent, so passingPstraight in works. Watch the direction: you can't hand a bareagenttoSpawnPlayer(Player:player)without narrowing it first.IsInVolumeis a<decides>(failable) method. Call it with square brackets inside anif—if (SafeVolume.IsInVolume[P]):— not round parentheses.not SafeVolume.IsInVolume[P]reads 'the player is NOT in the volume'.- Empty roster. During editor sessions the roster can be empty; a
forover an empty array simply does nothing, so no crash — but guard withRoster.Length >= Nif your logic assumes a minimum count. cinematic_sequence_device.Play()with no agent only works when the device is set to Everyone in its details panel. If it's set per-agent, use thePlay(Agent:agent)overload inside your roster loop instead.