Overview
The Player Checkpoint device (player_checkpoint_device) sets an agent's respawn point. When a player is registered to a checkpoint, dying sends them back to that checkpoint instead of the map's default spawn. Depending on the device's settings it can also clear the agent's inventory on register — handy for clean staged runs.
Reach for this device whenever you want progress to persist through death: a parkour course with mid-level save points, a dungeon crawl where each room banks your spot, or a boss arena that snaps survivors back to the entrance.
In Verse you get the full surface: subscribe to FirstActivationEvent / FirstActivationPerAgentEvent to react when players reach the checkpoint, call Register to set their respawn, Enable/Disable to gate the checkpoint, and GetRegisteredAgents / IsRegistered to query who has already saved.
API Reference
player_checkpoint_device
Used to set an
agent's spawn point when activated. This can also clear theagent's inventory.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
player_checkpoint_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
FirstActivationEvent |
FirstActivationEvent<public>:listenable(agent) |
Signaled when this device is first activated by any agent. Sends the agent that activated this device. |
FirstActivationPerAgentEvent |
FirstActivationPerAgentEvent<public>:listenable(agent) |
Signaled each time a new agent activates this device. Sends the agent that activated this device. |
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. |
Register |
Register<public>(Agent:agent):void |
Registers this checkpoint for Agent. This sets the respawn point and can clear Agent's inventory depending on this device's settings. Multiple agents can be registered to this device at one time. |
GetRegisteredAgents |
GetRegisteredAgents<public>()<reads>:[]agent |
Returns an array of agents that are currently registered to this checkpoint. |
IsRegistered |
IsRegistered<public>(Agent:agent)<transacts><decides>:void |
Succeeds when Agent is registered to this checkpoint. |
Walkthrough
Let's build a mid-level save point. We have a checkpoint device sitting at the end of the first room. When a player first crosses it, we register them (locking in their respawn), play an unlock sound, and award an accolade. We also keep a count of how many unique players have reached it so far.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# A mid-level save point that registers players and tracks who reached it.
checkpoint_manager := class(creative_device):
# The checkpoint that sets the respawn point.
@editable
Checkpoint : player_checkpoint_device = player_checkpoint_device{}
# Plays when the checkpoint is first activated by a player.
@editable
UnlockSound : audio_player_device = audio_player_device{}
# Awards XP to the player who reaches the save point.
@editable
Accolade : accolades_device = accolades_device{}
# Running count of unique players who have banked this checkpoint.
var PlayersReached : int = 0
OnBegin<override>()<suspends> : void =
# Fires only the first time ANY player activates the device.
Checkpoint.FirstActivationEvent.Subscribe(OnFirstEverActivation)
# Fires once per NEW player that activates the device.
Checkpoint.FirstActivationPerAgentEvent.Subscribe(OnNewPlayerActivation)
# Handler: the very first activation by anyone.
OnFirstEverActivation(Agent : agent) : void =
Print("Checkpoint came online for the first time!")
UnlockSound.Play(Agent)
# Handler: each new agent to reach the checkpoint.
OnNewPlayerActivation(Agent : agent) : void =
# Lock in this agent's respawn point (and clear inventory if the
# device is configured to do so).
Checkpoint.Register(Agent)
# Reward them.
Accolade.Award(Agent)
set PlayersReached += 1
Print("Players banked so far: {PlayersReached}")
Line by line:
@editable Checkpoint : player_checkpoint_device— the placed device. You MUST declare it as an editable field; callingCheckpoint.Register(...)only works because the device is bound in the editor.- In
OnBeginwe subscribe two handlers.FirstActivationEventfires exactly once — the very first time the device is touched by anyone.FirstActivationPerAgentEventfires once for each new player, which is what we want for per-player registration. - A
listenable(agent)hands the handler anagentdirectly (no?agentto unwrap here), soOnNewPlayerActivation(Agent : agent)is ready to use. Checkpoint.Register(Agent)is the heart of it — this sets the respawn point for that agent. Multiple agents can be registered at once.Accolade.Award(Agent)andUnlockSound.Play(Agent)give feedback, and we bump ourPlayersReachedcounter withset.
Common patterns
Gate the checkpoint until a switch is flipped (Enable / Disable).
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
gated_checkpoint := class(creative_device):
@editable
Checkpoint : player_checkpoint_device = player_checkpoint_device{}
# Flip this to open the save point.
@editable
UnlockSwitch : switch_device = switch_device{}
OnBegin<override>()<suspends> : void =
# Start with the checkpoint off so nobody banks early.
Checkpoint.Disable()
UnlockSwitch.TurnedOnEvent.Subscribe(OnSwitchOn)
OnSwitchOn(Agent : agent) : void =
# Now the checkpoint accepts activations.
Checkpoint.Enable()
Only let a player through a door if they've banked the checkpoint (IsRegistered).
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
registered_gate := class(creative_device):
@editable
Checkpoint : player_checkpoint_device = player_checkpoint_device{}
# Trigger at the exit door.
@editable
ExitTrigger : trigger_device = trigger_device{}
# Opens for players who saved.
@editable
ExitDoor : barrier_device = barrier_device{}
OnBegin<override>()<suspends> : void =
ExitTrigger.TriggeredEvent.Subscribe(OnExitTriggered)
OnExitTriggered(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# IsRegistered <decides> — succeeds only if banked.
if (Checkpoint.IsRegistered[Agent]):
ExitDoor.Disable() # drop the barrier so they can pass
Count everyone currently registered (GetRegisteredAgents).
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
checkpoint_census := class(creative_device):
@editable
Checkpoint : player_checkpoint_device = player_checkpoint_device{}
# Show how many players have saved when pressed.
@editable
CountButton : button_device = button_device{}
OnBegin<override>()<suspends> : void =
CountButton.InteractedWithEvent.Subscribe(OnCountPressed)
OnCountPressed(Agent : agent) : void =
Registered := Checkpoint.GetRegisteredAgents()
Print("Registered players: {Registered.Length}")
Gotchas
Registeris the call that actually sets the respawn. Reaching the checkpoint physically can fire the activation events, but in Verse you decide who is registered by callingRegister(Agent). Subscribe toFirstActivationPerAgentEventand register there if you want auto-registration on touch.FirstActivationEventfires once total;FirstActivationPerAgentEventfires once per new agent. Picking the wrong one is the classic bug — use the per-agent variant for anything you want to happen for every player.IsRegisteredis<decides>, so it's a failable expression — call it with square brackets inside anif:if (Checkpoint.IsRegistered[Agent]):. Using round parentheses won't compile.FirstActivationEventhands you anagent, not a?agent. No unwrap needed. But thetrigger_device.TriggeredEventislistenable(?agent), so there you DO needif (Agent := MaybeAgent?):— don't mix them up.- Clearing inventory is a device setting, not a parameter.
Registermay wipe the agent's items depending on the checkpoint's configured options in the editor — there's no Verse argument for it, so check the device settings if loot keeps disappearing. - Disable an enabled checkpoint to gate progress. A disabled checkpoint ignores activations; remember to
Enable()it again, or players silently never bank.