Overview
The Player Reference device (player_reference_device) solves a common island-design problem: how do I write Verse code that cares about one particular player? Whether you need to spotlight the current race leader, grant a bounty target special effects, or check if the agent who just stepped on a plate is the designated VIP, this device gives you the answer.
Key capabilities:
IsReferenced(Agent)— a failable (<decides>) check: succeeds only whenAgentis the player currently stored in the device.GetStatValue()— returns the integer stat the device is configured to track (kills, score, etc.).Activate()— programmatically fires the device (useful for chaining logic).- Events —
ActivatedEvent,AgentUpdatedEvent,AgentReplacedEvent,AgentUpdateFailsEventlet you react whenever the stored reference changes.
Reach for this device whenever your game needs a named player slot that Verse code can interrogate or subscribe to.
API Reference
(API surface could not be resolved for this device.)
Walkthrough
Scenario — Bounty Board: A trigger plate marks whoever steps on it as the "Bounty Target." Every other player is notified. A second trigger checks whether the agent who steps on it is the bounty target and, if so, activates the device to signal a bounty-claimed event.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Fortnite.com/Playspaces }
# Localized helper so we can pass message-typed params
bounty_msg<localizes>(S : string) : message = "{S}"
bounty_board_device := class(creative_device):
# Drop this Player Reference device into the level and wire it here
@editable
BountySlot : player_reference_device = player_reference_device{}
# Trigger plate that SETS the bounty target (step on it to become the target)
@editable
SetBountyPlate : trigger_device = trigger_device{}
# Trigger plate that CLAIMS the bounty (only works for the current target)
@editable
ClaimBountyPlate : trigger_device = trigger_device{}
# Called when the bounty reference slot is updated
OnBountyUpdated(NewTarget : agent) : void =
Print("Bounty target updated!")
# Called when someone steps on the Set-Bounty plate
OnSetBountyTriggered(Instigator : ?agent) : void =
if (A := Instigator?):
# Activate the device so it stores this agent as the reference
BountySlot.Activate()
Print("New bounty target designated.")
# Called when someone steps on the Claim-Bounty plate
OnClaimBountyTriggered(Instigator : ?agent) : void =
if (A := Instigator?):
# IsReferenced<decides> — only succeeds if A is the stored bounty target
if (BountySlot.IsReferenced[A]):
Print("Bounty claimed! Activating reward sequence.")
BountySlot.Activate() # signal downstream devices
else:
Print("Not the bounty target — keep hunting.")
OnBegin<override>()<suspends> : void =
# Subscribe to plate triggers
SetBountyPlate.TriggeredEvent.Subscribe(OnSetBountyTriggered)
ClaimBountyPlate.TriggeredEvent.Subscribe(OnClaimBountyTriggered)
# Subscribe to reference-slot events
BountySlot.AgentUpdatedEvent.Subscribe(OnBountyUpdated)
BountySlot.AgentReplacedEvent.Subscribe(OnBountyUpdated)
# Keep the device alive for the whole session
loop:
Sleep(60.0)
Line-by-line highlights:
BountySlot.IsReferenced[A]— the square-bracket call syntax is required for<decides>functions inside anifexpression. It fails (branches toelse) whenAis not the stored player.BountySlot.Activate()— tells the device to fire itsActivatedEventand push its stored agent downstream to any wired devices.AgentUpdatedEvent.Subscribe(OnBountyUpdated)— fires whenever the slot's stored agent changes to a new agent.AgentReplacedEvent.Subscribe(OnBountyUpdated)— fires when the stored agent is replaced by a different one; subscribing to both covers all update paths.- The
loop { Sleep(60.0) }keepsOnBeginsuspended so subscriptions stay alive for the entire session.
Common patterns
Pattern 1 — Read the tracked stat and display it
Use GetStatValue() to pull the integer stat the device is configured to track (e.g., eliminations) and act on it — here, granting a bonus when the target reaches 5 kills.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
stat_reward_device := class(creative_device):
@editable
BountySlot : player_reference_device = player_reference_device{}
@editable
RewardGranter : item_granter_device = item_granter_device{}
# Poll the stat every 5 seconds and reward at threshold
OnBegin<override>()<suspends> : void =
loop:
Sleep(5.0)
CurrentKills := BountySlot.GetStatValue()
Print("Bounty target kill count: {CurrentKills}")
if (CurrentKills >= 5):
# Grant the stored agent a bonus item
if (StoredAgent := BountySlot.ActivatedEvent):
# Activate fires ActivatedEvent with the stored agent
BountySlot.Activate()
Print("Threshold reached — granting bonus item.")
RewardGranter.GrantItem()
Note:
GetStatValue()returns the raw integer configured in the device's properties panel (Stat Type, Stat Source). Make sure the panel is set to the stat you actually want to track.
Pattern 2 — React to reference-slot events
Subscribe to ActivatedEvent to run logic the moment the device fires — for example, teleporting the stored agent to a boss arena.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
boss_arena_device := class(creative_device):
@editable
BountySlot : player_reference_device = player_reference_device{}
@editable
ArenaTelepad : teleporter_device = teleporter_device{}
# Fires when the device is activated (stores the agent at that moment)
OnBountyActivated(StoredAgent : agent) : void =
# Teleport the designated agent into the boss arena
ArenaTelepad.Teleport(StoredAgent)
Print("Bounty target teleported to boss arena!")
OnBegin<override>()<suspends> : void =
BountySlot.ActivatedEvent.Subscribe(OnBountyActivated)
loop:
Sleep(30.0)
Pattern 3 — Guard any action behind IsReferenced
Use IsReferenced as a gate so that only the designated player can open a vault door.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
vault_guard_device := class(creative_device):
@editable
VIPSlot : player_reference_device = player_reference_device{}
@editable
VaultButton : button_device = button_device{}
@editable
VaultDoor : mutator_zone_device = mutator_zone_device{}
OnButtonPressed(Instigator : agent) : void =
# Only the VIP stored in VIPSlot may open the vault
if (VIPSlot.IsReferenced[Instigator]):
VaultDoor.Enable()
Print("VIP opened the vault!")
else:
Print("Access denied — you are not the VIP.")
OnBegin<override>()<suspends> : void =
VaultButton.InteractedWithEvent.Subscribe(OnButtonPressed)
loop:
Sleep(60.0)
Gotchas
-
IsReferencedis<decides>— use square brackets insideif. Call it asif (VIPSlot.IsReferenced[Agent]):, notVIPSlot.IsReferenced(Agent). The parenthesis form won't compile inside a conditional context because the failure mode is unhandled. -
The device must be
@editableon aclass(creative_device). Declaringvar Slot := player_reference_device{}as a local variable and calling methods on it does nothing — the device must be placed in the level and referenced via an@editablefield so the runtime wires it to the actual placed instance. -
Activate()stores the triggering agent, not a Verse-chosen one. You cannot pass an agent directly toActivate(). The device captures whoever triggered it via its in-editor wiring or the last player to interact with a wired input device. If you need to designate a specific agent from Verse, wire a trigger or button to the device in the editor and fire that trigger from code instead. -
GetStatValue()reflects the panel configuration. If the device's Stat Type is set to "None" in the properties panel,GetStatValue()always returns0. Double-check the panel before debugging why your stat logic never fires. -
Subscribe to both
AgentUpdatedEventandAgentReplacedEventfor full coverage.AgentUpdatedEventfires when the slot was empty and gets a new agent.AgentReplacedEventfires when one agent is swapped for another. Missing either means your handler silently skips some update paths. -
No
int↔floatauto-conversion.GetStatValue()returnsint. If you compare it to a float literal or pass it to a function expectingfloat, you must cast explicitly (e.g.,Float(CurrentKills)).