Overview
The end_game_device is the device that actually ends the round or the match. On its own it does nothing — it sits in the level waiting for your Verse script (or its own configured win conditions) to tell it "we're done here." Reach for it whenever your game has a custom win condition that Fortnite's built-in round settings can't express on their own: reaching a specific location, surviving a scripted event, disarming a bomb, capturing an objective, or any other bespoke trigger you build in Verse.
In the device's own User Options you configure things like Winning Team (e.g. Activating Team) and What to End (End Round vs End Game). Verse's job is simply to call the right method at the right moment:
Enable()/Disable()— turn the device's ability to end the game on or off, so you can arm or disarm your win condition dynamically.Activate(Agent)— actually ends the round/game right now, usingAgent's team to decide who won (when the device is set to Activating Team).
Everything else — cinematics, scoreboards, victory screens — is handled by Fortnite's built-in match flow once you call Activate. Your job is just to detect the win condition and call it with the correct player.
API Reference
end_game_device
Used to configure rules that can end the current round or game.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
end_game_device<public> := class<concrete><final>(creative_device_base):
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. |
Activate |
Activate<public>(Agent:agent):void |
Ends the round/game. Uses Agent's team to determine if the round/game ends when Activating Team is enabled. |
Walkthrough
Let's build a Vault Heist mode: two teams race to reach a vault plate. To keep things fair, the vault is sealed with an alarm timer — nobody can win in the first 30 seconds while the vault door is still locked down. Once the alarm timer expires, the first team to step on the vault plate wins the whole match.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
vault_heist_device := class(creative_device):
# The End Game device placed in the level, configured with
# Winning Team = Activating Team, and What to End = End Game.
@editable
EndGame : end_game_device = end_game_device{}
# A trigger placed on the vault floor plate.
@editable
VaultPlate : trigger_device = trigger_device{}
# How long the vault stays sealed before it can be won.
@editable
AlarmTimeSeconds : float = 30.0
OnBegin<override>()<suspends>:void =
# Lock down the win condition immediately so nobody can
# sneak an early Activate call before the alarm timer runs out.
EndGame.Disable()
# Listen for any player stepping on the vault plate.
VaultPlate.TriggeredEvent.Subscribe(OnVaultReached)
# Wait out the alarm, then arm the End Game device.
Sleep(AlarmTimeSeconds)
EndGame.Enable()
OnVaultReached(MaybeAgent:?agent):void =
if (Agent := MaybeAgent?):
# Only actually ends the game if EndGame is currently Enabled.
# Agent's team becomes the winning team (Winning Team = Activating Team).
EndGame.Activate(Agent)```
Line by line:
- `EndGame : end_game_device = end_game_device{}` — the required pattern for referencing a placed device: declare an `@editable` field of the device's type. Without this, calling `EndGame.Activate(...)` would fail with 'Unknown identifier'.
- `VaultPlate : trigger_device` — a second placed device, the floor plate players stand on to trigger the win.
- `OnBegin<override>()<suspends>:void` — all setup happens here. It's marked `<suspends>` because we're going to `Sleep` inside it.
- `EndGame.Disable()` — called immediately so the vault can't be won during the alarm countdown, even if a player is somehow already standing on the plate.
- `VaultPlate.TriggeredEvent.Subscribe(OnVaultReached)` — wires the plate's event to our handler. This must happen in `OnBegin`, not at class scope.
- `Sleep(AlarmTimeSeconds)` — suspends this function for 30 seconds without blocking anything else in the game.
- `EndGame.Enable()` — re-arms the win condition once the alarm timer is up.
- `OnVaultReached(Agent:agent):void` — the event handler. It receives the `agent` who triggered the plate directly (no optional to unwrap here since `TriggeredEvent` always has a real player attached).
- `EndGame.Activate(Agent)` — the actual match-ending call. If the device is still `Disable`d, this call is ignored; once `Enable`d, it immediately ends the match with `Agent`'s team as the winner.
## Common patterns
**1. Arm and disarm the win condition on a timer.** Use `Disable`/`Enable` to prevent an accidental early win, then arm it once your game's setup phase is complete.
```verse
using { /Fortnite.com/Devices }
arm_end_game_device := class(creative_device):
@editable
EndGame : end_game_device = end_game_device{}
OnBegin<override>()<suspends>:void =
# No one can end the game during the opening 15-second setup phase.
EndGame.Disable()
Sleep(15.0)
EndGame.Enable()
2. End the match when a flag/objective is captured. Subscribe to a trigger device and forward the capturing player straight into Activate.
using { /Fortnite.com/Devices }
capture_flag_device := class(creative_device):
@editable
EndGame : end_game_device = end_game_device{}
@editable
FlagPlate : trigger_device = trigger_device{}
OnBegin<override>()<suspends>:void =
FlagPlate.TriggeredEvent.Subscribe(OnFlagCaptured)
OnFlagCaptured(Agent:agent):void =
EndGame.Activate(Agent)
3. Let a player end the match on demand. A button can serve as a "call the game" lever — useful for a surrender button, a manual referee override, or a boss-room switch that only unlocks after the boss dies.
using { /Fortnite.com/Devices }
surrender_button_device := class(creative_device):
@editable
EndGame : end_game_device = end_game_device{}
@editable
SurrenderButton : button_device = button_device{}
OnBegin<override>()<suspends>:void =
SurrenderButton.InteractedWithEvent.Subscribe(OnSurrender)
OnSurrender(Agent:agent):void =
EndGame.Activate(Agent)
Gotchas
Activateonly means something if the device isEnabled. If you never callDisable, the device starts enabled by default in most setups — but if your logic assumes it's locked, callDisable()explicitly at the start ofOnBeginrather than relying on assumptions about initial state.Winning Teammust be set to Activating Team in the device's User Options forAgent's team to actually decide the winner. If it's set to a fixed team instead,Activate'sAgentargument is effectively ignored for that purpose — the device will still end the round/game, but the pre-configured team wins.Activateends things immediately — there's no confirmation step, animation delay, or way to cancel it once called. Do any "are you sure" or victory-cinematic logic before you callActivate, not after.- Double-triggering is possible. If two players can trigger your win condition in the same frame (e.g. both step on adjacent plates), you may call
Activatetwice. This is usually harmless since the match ends on the first call, but don't build logic that assumes exactly-once semantics without guarding it. - Remember the
@editablefield rule.EndGame.Activate(Agent)will fail to compile with 'Unknown identifier' ifEndGameisn't declared as an@editablefield of typeend_game_deviceon your device class — you cannot call a placed device directly by name. - Event agents aren't always optional. Some device events (like
TriggeredEventused above) hand you a plainagent, not a?agent, because the player triggering them is guaranteed. Don't reflexively addif (A := Agent?):unwrapping where the signature doesn't call for it — check the actual event type first. What to End(Round vs Game) is a separate device setting, not something Verse controls. Make sure it's configured correctly in the editor for the scope of match you actually want to end.