Overview
There is no single magic "team score" device in Verse — team scoring is a pattern you build. You keep the running totals in your own Verse variables, you detect scoring events with a trigger_device (a player steps on a treasure plate, dunks a coconut, captures a flag), and you broadcast the current standings to players with a hud_message_device.
Reach for this pattern whenever you want a scoreboard that reacts to gameplay: a tug-of-war on the dock, a coconut-toss on the shore, two pirate crews racing to loot the cove. The trigger_device gives you a clean TriggeredEvent that hands you the scoring agent, and the hud_message_device gives you Show(...) / SetText(...) / SetDisplayTime(...) to paint the totals on-screen.
In this article we'll build a two-crew cove scoreboard: step on the Red plate or the Blue plate, that crew scores, and a HUD banner updates for everyone. We rely on which team the scoring agent belongs to via the playspace team collection.
API Reference
team
Full public surface, resolved verbatim from the live Epic digest (Verse.digest.verse).
team<native><public> := class<unique><epic_internal>:
player
Full public surface, resolved verbatim from the live Epic digest (Verse.digest.verse). Inherited members are merged from agent.
player<native><public> := class<unique><persistent><module_scoped_var_weak_map_key><epic_internal>(agent):
hud_message_device
Used to show custom HUD messages to one or more
agents.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
hud_message_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
ShowMessageEvent |
ShowMessageEvent<public>:listenable(agent) |
Called when a Message has been Shown on-screen. Returns an Agent if it was Shown on a specified Agent's screen. |
HideMessageEvent |
HideMessageEvent<public>:listenable(agent) |
Called when a Message has been Hidden on-screen. Returns an Agent if it was Hidden from a specified Agent's screen. |
ClearAllMessagesEvent |
ClearAllMessagesEvent<public>:listenable(agent) |
Called when all queued Messages from all players that are affected by this HUD Message Device have been cleared. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Show |
Show<public>(Agent:agent):void |
Shows the currently set HUD Message on Agents screen. Will replace any previously active message. Use this when the device is setup to target specific agents. |
Show |
Show<public>():void |
Shows the currently set Message HUD message on screen. Will replace any previously active message. |
Hide |
Hide<public>():void |
Hides the HUD message. |
Hide |
Hide<public>(Agent:agent):void |
Hides the currently set HUD Message on Agents screen. Use this when the device is setup to target specific agents. |
Show |
Show<public>(Agent:agent, Message:message, ?DisplayTime:float |
Displays a Custom message to a specific Agent that you define.Setting DisplayTime to 0.0 will display the HUD message persistently.If not defined, or less than 0.0 the message will show for the time set on the device. |
Show |
Show<public>(Message:message, ?DisplayTime:float |
Displays a Custom message that you define for all PlayersSetting DisplayTime to 0.0 will display the HUD message persistently.If not defined, or less than 0.0 the message will show for the time set on the device. |
SetDisplayTime |
SetDisplayTime<public>(Time:float):void |
Sets the time (in seconds) the HUD message will be displayed. 0.0 will display the HUD message persistently. |
GetDisplayTime |
GetDisplayTime<public>()<transacts>:float |
Returns the time (in seconds) for which the HUD message will be displayed. 0.0 means the message is displayed persistently. |
SetText |
SetText<public>(Text:message):void |
Sets the Message to be displayed when the HUD message is activated. Text is clamped to 150 characters. |
ClearAllMessages |
ClearAllMessages<public>():void |
Clears all queued Messages from all players that are affected by this HUD Message Device. |
trigger_device
Used to relay events to other linked devices.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from trigger_base_device.
trigger_device<public> := class<concrete><final>(trigger_base_device):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
TriggeredEvent |
TriggeredEvent<public>:listenable(?agent) |
Signaled when an agent triggers this device. Sends the agent that used this device. Returns false if no agent triggered the action (ex: it was triggered through code). |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Trigger |
Trigger<public>(Agent:agent):void |
Triggers this device with Agent being passed as the agent that triggered the action. Use an agent reference when this device is setup to require one (for instance, you want to trigger the device only with a particular agent. |
Trigger |
Trigger<public>():void |
Triggers this device, causing it to activate its TriggeredEvent event. |
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
SetMaxTriggerCount |
SetMaxTriggerCount<public>(MaxCount:int):void |
Sets the maximum amount of times this device can trigger. * 0 can be used to indicate no limit on trigger count. * MaxCount is clamped between [0,20]. |
GetMaxTriggerCount |
GetMaxTriggerCount<public>()<transacts>:int |
Gets the maximum amount of times this device can trigger. * 0 indicates no limit on trigger count. |
GetTriggerCountRemaining |
GetTriggerCountRemaining<public>()<transacts>:int |
Returns the number of times that this device can still be triggered before hitting GetMaxTriggerCount. Returns 0 if GetMaxTriggerCount is unlimited. |
SetResetDelay |
SetResetDelay<public>(Time:float):void |
Sets the time (in seconds) after triggering, before the device can be triggered again (if MaxTrigger count allows). |
GetResetDelay |
GetResetDelay<public>()<transacts>:float |
Gets the time (in seconds) before the device can be triggered again (if MaxTrigger count allows). |
SetTransmitDelay |
SetTransmitDelay<public>(Time:float):void |
Sets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered. |
GetTransmitDelay |
GetTransmitDelay<public>()<transacts>:float |
Gets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered. |
Walkthrough
Our cove has two treasure plates (each a trigger_device) and one hud_message_device bolted to the mast. When a pirate steps on their crew's plate, we bump that crew's score and refresh the banner.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Teams }
using { /Fortnite.com/Playspaces }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
# Live scoreboard for a two-crew treasure race on the cove.
cove_scoreboard := class(creative_device):
# The plate the Red crew stomps to score.
@editable
RedPlate : trigger_device = trigger_device{}
# The plate the Blue crew stomps to score.
@editable
BluePlate : trigger_device = trigger_device{}
# The HUD banner bolted to the mast.
@editable
Scoreboard : hud_message_device = hud_message_device{}
# Our own running totals — THIS is the "team score tracking".
var RedScore : int = 0
var BlueScore : int = 0
# Helper to turn a plain string into a localized message.
Banner<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
# Keep the banner up permanently and subscribe both plates.
Scoreboard.SetDisplayTime(0.0)
RedPlate.TriggeredEvent.Subscribe(OnRedScored)
BluePlate.TriggeredEvent.Subscribe(OnBlueScored)
RefreshBoard()
# Red plate stomped: add a point for Red, refresh.
OnRedScored(MaybeAgent : ?agent) : void =
set RedScore = RedScore + 1
RefreshBoard()
# Blue plate stomped: add a point for Blue, refresh.
OnBlueScored(MaybeAgent : ?agent) : void =
set BlueScore = BlueScore + 1
RefreshBoard()
# Paint the current standings on every player's screen.
RefreshBoard() : void =
Scoreboard.SetText(Banner("RED {RedScore} - BLUE {BlueScore}"))
Scoreboard.Show()
Line by line:
- The three
@editablefields are the placed devices — you drag your two plates and one HUD device onto them in the UEFN Details panel. Without declaring them as fields you cannot call their methods. var RedScore/var BlueScoreARE the team score tracker. Verse variables hold the state; the devices only react to and display it.Banner<localizes>(...)is the required trick to build amessagefrom astring. Every method that takes amessage(likeSetText) needs this — there is noStringToMessage.- In
OnBegin,SetDisplayTime(0.0)makes the banner persistent (0.0 = never auto-hide). Then weSubscribeeach plate'sTriggeredEventto its handler. TriggeredEventislistenable(?agent), so each handler receivesMaybeAgent : ?agent. We don't need the agent to score here, but we keep the exact signature.RefreshBoardcallsSetTextwith the freshly-formatted score, thenShow()pushes it to everyone's HUD, replacing the previous banner.
Common patterns
Award only when the RIGHT crew triggers the plate
Instead of one plate per team, use one shared plate and check which team the scoring agent belongs to via the playspace team collection.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Teams }
using { /Fortnite.com/Playspaces }
using { /Verse.org/Simulation }
cove_team_plate := class(creative_device):
@editable
TreasurePlate : trigger_device = trigger_device{}
@editable
Scoreboard : hud_message_device = hud_message_device{}
var TeamZeroScore : int = 0
Banner<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
TreasurePlate.TriggeredEvent.Subscribe(OnLooted)
OnLooted(MaybeAgent : ?agent) : void =
if (Scorer := MaybeAgent?):
TeamCollection := GetPlayspace().GetTeamCollection()
if (Team := TeamCollection.GetTeam[Scorer]):
# Award a point to "team 0" only, as an example.
if (FirstTeam := TeamCollection.GetTeams()[0], Team = FirstTeam):
set TeamZeroScore = TeamZeroScore + 1
Scoreboard.SetDisplayTime(3.0)
Scoreboard.Show(Scorer, Banner("Team 0 loot: {TeamZeroScore}"))
Here Show(Agent, Message, ?DisplayTime) targets a single scorer's screen, so only the pirate who triggered it sees their crew's tally.
Limit how many times a plate can score, then close it off
Use SetMaxTriggerCount so a plate can only be looted a fixed number of times, and check how many remain with GetTriggerCountRemaining. When it's empty, Disable it.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
limited_treasure := class(creative_device):
@editable
TreasurePlate : trigger_device = trigger_device{}
@editable
Scoreboard : hud_message_device = hud_message_device{}
Banner<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
# This chest can only be looted 5 times.
TreasurePlate.SetMaxTriggerCount(5)
TreasurePlate.TriggeredEvent.Subscribe(OnLooted)
OnLooted(MaybeAgent : ?agent) : void =
Remaining := TreasurePlate.GetTriggerCountRemaining()
Scoreboard.SetDisplayTime(2.0)
Scoreboard.Show(Banner("Loot left in cove: {Remaining}"))
if (Remaining <= 0):
TreasurePlate.Disable()
Scoreboard.Show(Banner("The cove is plundered!"))
Reset the board with ClearAllMessages
When a round ends, wipe every queued banner off all screens with ClearAllMessages and trigger a fresh round-start signal in code.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
round_reset := class(creative_device):
@editable
Scoreboard : hud_message_device = hud_message_device{}
@editable
RoundStart : trigger_device = trigger_device{}
Banner<localizes>(S : string) : message = "{S}"
OnBegin<override>()<suspends> : void =
RoundStart.TriggeredEvent.Subscribe(OnNewRound)
# Kick off the first round from code (no agent needed).
RoundStart.Trigger()
OnNewRound(MaybeAgent : ?agent) : void =
# Clear old scoreboard banners, then show the new-round title.
Scoreboard.ClearAllMessages()
Scoreboard.SetDisplayTime(4.0)
Scoreboard.Show(Banner("New round! Grab the treasure!"))
Gotchas
- You store the score, not the device. There is no
team.GetScore()in this surface. Team scoring is your ownvartotals plus a trigger to detect events and a HUD device to display them. Keep the numbers in Verse. message, notstring.SetTextandShow(..., Message, ...)take amessage. Declare aBanner<localizes>(S:string):message = "{S}"helper and passBanner("...").StringToMessagedoes not exist.- Unwrap
?agent.TriggeredEventislistenable(?agent). The handler getsMaybeAgent : ?agent; you mustif (Scorer := MaybeAgent?):before using it. A pure-codeTrigger()sends no agent, soMaybeAgent?will fail — that's expected. DisplayTimevalues matter.SetDisplayTime(0.0)makes the banner persistent. A negative time falls back to the device's configured time. Set it beforeShow().- int vs float.
SetDisplayTimeandSetResetDelaytakefloat(3.0, not3). Your scores areint. Verse never auto-converts between them. Show()replaces, it doesn't stack. EachShow()call replaces the currently active message on that screen. To wipe queued messages entirely, useClearAllMessages().- Enable/Disable gate scoring. A
Disable()d trigger fires nothing — handy for closing a plundered chest, but remember toEnable()it again on the next round.