Overview
The round_settings_device sits at the heart of every round-based UEFN experience. Out of the box, Fortnite ends a round when its built-in conditions are met (last team standing, score limit, etc.). The round_settings_device lets you:
- React to round starts via
RoundBeginEvent— perfect for spawning enemies, starting timers, or resetting state. - Disable the default end conditions with
DisableEndRoundConditionsso your code is the sole arbiter of when a round finishes. - End the round immediately with
EndRound(Agent), declaring the agent's team the winner. - Gate matchmaking with
EnableMatchmaking/DisableMatchmaking/ToggleMatchmaking— useful for holding the lobby open or closed during setup phases. - Enable or disable the device entirely with
Enable/Disable.
Reach for this device whenever you need custom win conditions: a timed survival mode, a first-to-capture objective, or a scripted boss fight where the boss's defeat ends the round.
API Reference
round_settings_device
Used to customize gameplay for any round-based game. It generally defines what happens to the
agent's inventory and rewards in each round.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
round_settings_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
RoundBeginEvent |
RoundBeginEvent<public>:listenable(tuple()) |
Signaled when a game round starts. |
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. |
EnableMatchmaking |
EnableMatchmaking<public>():void |
Enables the ability for players to Matchmake into the Island. Only applies to published games that have matchmaking turned on in the Island settings |
DisableMatchmaking |
DisableMatchmaking<public>():void |
Disables the ability for players to Matchmake into the Island. Only applies to published games that have matchmaking turned on in the Island settings |
ToggleMatchmaking |
ToggleMatchmaking<public>():void |
Toggles between EnableMatchmaking and DisableMatchmaking. |
DisableEndRoundConditions |
DisableEndRoundConditions<public>():void |
Disables all end-round conditions. The round must be ended through calling EndRound or a creative event after this is called. |
EndRound |
EndRound<public>(Agent:agent):void |
Ends the round immediately with Agent's team set as the winner of the round. |
Walkthrough
Scenario: A timed survival arena. When the round begins, matchmaking is locked (no late joiners), a 60-second countdown starts, and the round ends when time runs out — the last surviving player wins. If only one player is alive before the timer expires, the round ends early and that player's team wins.
This example uses:
RoundBeginEvent— to kick off logic when the round startsDisableEndRoundConditions— so Fortnite doesn't end the round on its ownDisableMatchmaking— to lock the lobby once the round is liveEndRound(Agent)— to declare a winner
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Game }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
# Survival arena manager: locks matchmaking, runs a 60-second timer,
# and ends the round when time is up or only one player remains.
survival_arena_manager := class(creative_device):
# Wire this to your Round Settings device in the UEFN editor.
@editable
RoundSettings : round_settings_device = round_settings_device{}
# Wire this to a Class Designer or Player Spawner to get the active players.
# We'll use a trigger_device array as a stand-in for player tracking.
# In a real project you'd use GetPlayspace().GetPlayers().
@editable
RoundDurationSeconds : float = 60.0
# Called once when the island loads. Subscribe to RoundBeginEvent here.
OnBegin<override>()<suspends> : void =
# RoundBeginEvent fires a tuple() — handler signature must match.
RoundSettings.RoundBeginEvent.Subscribe(OnRoundBegin)
# Handler called every time a new round starts.
OnRoundBegin(Args : tuple()) : void =
# Spin up the round logic on its own async fiber so OnBegin returns fast.
spawn { RunRound() }
# Core round loop — runs concurrently once per round.
RunRound()<suspends> : void =
# 1. Disable built-in end conditions so we control when the round ends.
RoundSettings.DisableEndRoundConditions()
# 2. Lock matchmaking — no new players once the round is live.
RoundSettings.DisableMatchmaking()
# 3. Wait for the full round duration.
Sleep(RoundDurationSeconds)
# 4. Time's up — find any surviving player and declare them the winner.
# GetPlayspace().GetPlayers() returns all currently connected players.
Players := GetPlayspace().GetPlayers()
for (Player : Players):
# Cast to fort_character to check if they are still alive.
if (FortChar := Player.GetFortCharacter[]):
if (FortChar.IsActive[]):
# This player survived — their team wins the round.
RoundSettings.EndRound(Player)
# Re-enable matchmaking for the lobby phase.
RoundSettings.EnableMatchmaking()
return
# No survivors found — the round ends without a winner.
# (In a real game you might handle a draw differently.)
RoundSettings.EnableMatchmaking()
Line-by-line breakdown:
| Lines | What's happening |
|---|---|
@editable RoundSettings |
Exposes the device slot in the UEFN editor so you can wire in your placed Round Settings device. |
RoundSettings.RoundBeginEvent.Subscribe(OnRoundBegin) |
Registers OnRoundBegin to fire every time a new round starts — including round 2, 3, etc. |
OnRoundBegin(Args : tuple()) |
RoundBeginEvent is a listenable(tuple()), so the handler receives a tuple() argument. |
spawn { RunRound() } |
Launches the async round logic on a separate fiber so the subscribe handler returns immediately. |
DisableEndRoundConditions() |
Tells Fortnite: "Don't end this round automatically — I'll call EndRound when I'm ready." |
DisableMatchmaking() |
Prevents new players from joining mid-round. |
Sleep(RoundDurationSeconds) |
Suspends this fiber for 60 seconds (the round timer). |
EndRound(Player) |
Ends the round immediately, setting the surviving player's team as the winner. |
EnableMatchmaking() |
Re-opens the lobby for the next round's matchmaking phase. |
Common patterns
Pattern 1 — Toggle matchmaking with a button
A lobby manager device that opens or closes matchmaking when a host presses a button. Uses ToggleMatchmaking to flip state without tracking it yourself.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
# Lets a host button toggle matchmaking open/closed between rounds.
matchmaking_toggle_device := class(creative_device):
@editable
RoundSettings : round_settings_device = round_settings_device{}
# Wire this button_device to a prop only the host can reach.
@editable
HostButton : button_device = button_device{}
OnBegin<override>()<suspends> : void =
# Subscribe to the button's InteractedWithEvent.
# button_device fires listenable(?agent), so handler takes ?agent.
HostButton.InteractedWithEvent.Subscribe(OnHostPressed)
OnHostPressed(MaybeAgent : ?agent) : void =
# Each press flips matchmaking between enabled and disabled.
RoundSettings.ToggleMatchmaking()
Pattern 2 — Disable the device to freeze round settings mid-game
Sometimes you want to temporarily freeze the round settings device (e.g., during a cutscene or boss intro). Disable prevents the device from processing events; Enable restores it.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
# Freezes the round settings device during a 5-second boss intro cinematic,
# then re-enables it so normal round logic resumes.
boss_intro_manager := class(creative_device):
@editable
RoundSettings : round_settings_device = round_settings_device{}
@editable
BossTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
BossTrigger.TriggeredEvent.Subscribe(OnBossTriggered)
OnBossTriggered(MaybeAgent : ?agent) : void =
spawn { PlayBossIntro() }
PlayBossIntro()<suspends> : void =
# Disable round settings so no round-end conditions fire during the cinematic.
RoundSettings.Disable()
# Wait for the cinematic to finish (5 seconds).
Sleep(5.0)
# Re-enable so the round can proceed and end normally.
RoundSettings.Enable()
Pattern 3 — Instant round end when an objective is captured
A capture-point scenario: the first player to step on a trigger wins the round immediately. Uses DisableEndRoundConditions at round start and EndRound on capture.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
# Ends the round the moment any player steps on the capture-point trigger.
capture_point_manager := class(creative_device):
@editable
RoundSettings : round_settings_device = round_settings_device{}
# Place a trigger_device at the capture point in the level.
@editable
CapturePoint : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
RoundSettings.RoundBeginEvent.Subscribe(OnRoundBegin)
CapturePoint.TriggeredEvent.Subscribe(OnCapture)
OnRoundBegin(Args : tuple()) : void =
# Take over end-round logic — Fortnite won't end the round on its own.
RoundSettings.DisableEndRoundConditions()
# TriggeredEvent is listenable(?agent) — unwrap before calling EndRound.
OnCapture(MaybeAgent : ?agent) : void =
if (CaptureAgent := MaybeAgent?):
# The capturing player's team wins the round instantly.
RoundSettings.EndRound(CaptureAgent)
Gotchas
1. RoundBeginEvent is listenable(tuple()) — not listenable(?agent)
Unlike most device events, RoundBeginEvent carries no agent — it signals that a round started, not who caused it. Your handler must accept (Args : tuple()). Trying to write (Agent : ?agent) will cause a compile error.
2. Always call DisableEndRoundConditions before you expect to call EndRound yourself
If you skip DisableEndRoundConditions, Fortnite's built-in conditions (last team standing, score limit, etc.) can still fire and end the round before your Verse code does. Call it at the top of your round logic, ideally inside the OnRoundBegin handler or at the start of your async round fiber.
3. EndRound requires a live agent — not an optional
EndRound(Agent : agent) takes a concrete agent, not ?agent. Always unwrap optional agents first:
if (A := MaybeAgent?):
RoundSettings.EndRound(A)
Passing an unwrapped optional directly is a compile error.
4. Matchmaking methods only affect published islands
EnableMatchmaking, DisableMatchmaking, and ToggleMatchmaking have no effect in Play-in-Editor (PIE) or private playtests. They only matter for published islands with matchmaking enabled in Island Settings. Don't rely on them for local testing.
5. spawn your async round logic — don't block the subscribe handler
OnRoundBegin is a synchronous handler. If you Sleep or await inside it directly, you'll block the event system. Always launch long-running logic with spawn { MyAsyncFunction() } so the handler returns immediately.
6. Re-subscribe every round if needed
RoundBeginEvent.Subscribe in OnBegin registers a persistent listener that fires for every round — you don't need to re-subscribe. However, any spawned fiber from a previous round is independent; make sure you're not accumulating stale fibers across rounds by tracking and canceling them if necessary.