Overview
An array is a container that stores elements of the same type — []player, []team, []agent, []button_device, and so on. You get the number of elements in an array by accessing its Length member. For example, array{10, 20, 30}.Length returns 3, and Players.Length tells you how many players are currently in that list.
Length is not a device method — it is a built-in member available on every array in Verse. That makes it the workhorse of counting-based gameplay:
- Round gating — start a match only when
Players.Length >= 2. - Team balancing — compare
TeamA.LengthandTeamB.Lengthto decide where the next player goes. - Collection puzzles — unlock a vault when the collected-keys array reaches a target
Length. - Elimination win conditions — end the round when a team's living-players array
Lengthhits0.
Reach for Length whenever your game logic depends on "how many of these do I have right now?". It pairs naturally with the Teams API (GetTeams, GetAgents, GetPlayers) which hand you arrays you can immediately count.
Length returns an int. Remember Verse does not auto-convert int to float, so if you need a float count you must convert explicitly.
API Reference
(API surface could not be resolved for this device.)
Walkthrough
Let's build a round-start gate. We have a game where players must gather at a lobby. A round should only begin once at least 2 players are present. We read the playspace's player list, count it with .Length, and when we have enough, we unlock a vault door (an barrier_device) and show a message.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Teams }
using { /Fortnite.com/Playspaces }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
round_gate := class(creative_device):
# The vault door players unlock once enough of them have joined.
@editable
VaultDoor : barrier_device = barrier_device{}
# A HUD message device to announce the count.
@editable
Announcer : hud_message_device = hud_message_device{}
# How many players we need before the round can begin.
@editable
RequiredPlayers : int = 2
# Localized-message helper: a message param needs a localized value, not a raw string.
CountMessage<localizes>(Have:int, Need:int):message = "Players ready: {Have} / {Need}"
OnBegin<override>()<suspends>:void =
# Start with the door blocking the way in.
VaultDoor.Enable()
# Re-check the count whenever a player spawns into the world.
Playspace := GetPlayspace()
Playspace.PlayerAddedEvent().Subscribe(OnPlayerAdded)
# Also check once at startup in case players are already here.
CheckRoundReady()
# Event handler: fired when a new player joins the playspace.
OnPlayerAdded(InPlayer:player):void =
CheckRoundReady()
# The core counting logic.
CheckRoundReady():void =
Players := GetPlayspace().GetPlayers()
# .Length gives us the current player count as an int.
Count := Players.Length
Announcer.SetText(CountMessage(Count, RequiredPlayers))
Announcer.Show()
if (Count >= RequiredPlayers):
# Enough players — drop the barrier so the round can begin.
VaultDoor.Disable()
Line by line:
- The
@editablefields (VaultDoor,Announcer,RequiredPlayers) let you wire real placed devices and a tunable number in the UEFN details panel. A barebarrier_device{}reference only works because you assign the actual device in the editor. CountMessage<localizes>(...)builds amessage— the typeSetTextexpects. There is noStringToMessage; the<localizes>function is how you produce localized text with interpolated{Have}values.- In
OnBegin,VaultDoor.Enable()turns the barrier ON so it blocks movement. GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded)wires a handler that runs each time someone joins. Subscribing lives inOnBegin; the handlerOnPlayerAddedis a method at class scope.CheckRoundReady()callsGetPlayers()which returns a[]player.Players.Lengthcounts them. We compare thatintagainstRequiredPlayers.- When the count reaches the threshold we
Disable()the barrier, opening the way in.
Common patterns
Team balancing — send the next player to the smaller team
Compare the Length of each team's agent array and route a joining player to whichever side has fewer members.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Teams }
using { /Fortnite.com/Playspaces }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
team_balancer := class(creative_device):
OnBegin<override>()<suspends>:void =
Playspace := GetPlayspace()
Playspace.PlayerAddedEvent().Subscribe(OnPlayerAdded)
OnPlayerAdded(InPlayer:player):void =
TeamCollection := GetPlayspace().GetTeamCollection()
Teams := TeamCollection.GetTeams()
# Need at least two teams to balance between.
if (TeamA := Teams[0], TeamB := Teams[1]):
if:
AgentsA := TeamCollection.GetAgents[TeamA]
AgentsB := TeamCollection.GetAgents[TeamB]
then:
# Whichever team's agent array is shorter gets the new player.
if (AgentsA.Length <= AgentsB.Length):
if (TeamCollection.AddToTeam[InPlayer, TeamA]) {}
else:
if (TeamCollection.AddToTeam[InPlayer, TeamB]) {}
GetTeams() returns []team and GetAgents[Team] returns []agent; comparing their .Length values tells you which side is lighter before AddToTeam places the player.
Elimination win condition — end when a team is empty
Count a team's remaining agents after each elimination; when Length reaches 0, the round is over.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Teams }
using { /Fortnite.com/Playspaces }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
last_team_standing := class(creative_device):
@editable
EndGameDevice : end_game_device = end_game_device{}
OnBegin<override>()<suspends>:void =
for (P : GetPlayspace().GetPlayers()):
if (FC := P.GetFortCharacter[]):
FC.EliminatedEvent().Subscribe(OnEliminated)
OnEliminated(Result:elimination_result):void =
TeamCollection := GetPlayspace().GetTeamCollection()
for (Team : TeamCollection.GetTeams()):
if (Agents := TeamCollection.GetAgents[Team]):
# A team with 0 living agents has lost the round.
if (Agents.Length = 0):
EndGameDevice.Activate(Result.EliminatingCharacter)
Here .Length = 0 is the pattern for "is this collection empty?" — a clean win check without manually tracking each elimination.
Collection puzzle — unlock a vault at a target count
Store collected items in a var array, set it as items arrive, and compare Length against the goal.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
key_collector := class(creative_device):
@editable
KeyButtons : []button_device = array{}
@editable
Vault : barrier_device = barrier_device{}
# Which key indices have been pressed so far.
var CollectedKeys : []int = array{}
OnBegin<override>()<suspends>:void =
Vault.Enable()
for (Index -> Button : KeyButtons):
Button.InteractedWithEvent.Subscribe(OnKeyPressed)
OnKeyPressed(Agent:agent):void =
# Add one key to the collection.
set CollectedKeys = CollectedKeys + array{CollectedKeys.Length}
# When we have collected every key, open the vault.
if (CollectedKeys.Length >= KeyButtons.Length):
Vault.Disable()
Both the collected array and the source array are counted with .Length, and the puzzle is solved when the two counts match.
Gotchas
Lengthis anint, and Verse never auto-converts tofloat. If you needCount / 2.0, first convert withIntToFloat(Count)(orCount * 1.0won't work — use the explicit cast). Comparing twointlengths, as in all the examples above, is fine.- Empty check.
MyArray.Length = 0is the idiomatic "is it empty?" test. It does not fail — it evaluates totrue/falseinside anif. - Indexing still fails,
Lengthdoes not.Players[0]is a failable expression (it fails if the array is empty), so it must live in a failure context.Players.Lengthalways succeeds and returns a plainint— you can read it anywhere. messageparams need localized values. Devices likehud_message_device.SetTexttake amessage, not astring. Build one with a<localizes>helper (e.g.CountMessage(Count, Need)), never a raw"..."string. There is noStringToMessage.- Bracket vs. paren calls.
GetAgents,GetTeam, andAddToTeamare<decides>(failable) — call them with square brackets inside anif(TeamCollection.GetAgents[Team]).GetTeams()andGetPlayers()are not failable — call them with parentheses. Mixing these up is a common compile error before you ever get to.Length. - Snapshot, not live binding.
Players.Lengthis the count at the moment you read the array. If players join or leave, you must re-readGetPlayers()(as the walkthrough does onPlayerAddedEvent) to get a fresh count.