Overview
In many languages you write continue; to jump straight to the next iteration of a loop. Verse has no continue statement. Instead, Verse loops (for, loop) skip work using the language's failure model: if the guard at the top of the loop body fails, the rest of that iteration is abandoned and the loop moves on to the next element.
Think of a bright clifftop finish line. When the round ends you sweep through every player on the island. Some are on the winning team, some aren't. You want to teleport ONLY the winners to the victory cove, award them points, and skip everyone else — without stopping the loop. That 'skip this one, keep going' behavior is exactly what a failable guard inside a for gives you.
The two everyday shapes are:
for (X : Collection, Guard[X]) { ... }— the filter is baked into theforheader. Elements that failGuard[X]are silently skipped. This is the closest thing tocontinue.for (X : Collection) { if (Guard[X]) { DoWork(X) } }— the guard is anifinside the body. Wheniffails, the body after it is skipped and the loop continues to the next element.
Because there's no device called continue-skip-iteration, the code here uses real placed devices — teleporter_device, score_manager_device, and timer_device — as the work you selectively run per iteration.
API Reference
(API surface could not be resolved for this device.)
Walkthrough
Scenario: the round timer completes on a sunny clifftop. We loop over every player. For each player we check a condition; players who pass get teleported to the victory cove and awarded points, players who fail are skipped — but the loop keeps running for the rest.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Simulation }
using { /Fortnite.com/Characters }
# Sweeps all players when the round timer finishes.
# Winners are teleported + scored; everyone else is SKIPPED.
victory_sweep := class(creative_device):
# Placed devices we drive per iteration.
@editable
RoundTimer : timer_device = timer_device{}
@editable
VictoryTeleporter : teleporter_device = teleporter_device{}
@editable
WinnerScore : score_manager_device = score_manager_device{}
OnBegin<override>()<suspends>:void =
# When the timer succeeds, run our sweep.
RoundTimer.SuccessEvent.Subscribe(OnRoundOver)
RoundTimer.Start()
# SuccessEvent hands us a ?agent (may be empty).
OnRoundOver(MaybeAgent : ?agent):void =
# Grab every player currently in the match.
AllPlayers := GetPlayspace().GetPlayers()
# Loop over all of them. The guard in the body decides
# whether this iteration does work or is skipped.
for (P : AllPlayers):
# 'continue/skip': if this fails, the rest of the
# body is abandoned and we move to the next player.
if (IsWinner[P]):
# This player qualified -> do the real work.
VictoryTeleporter.Teleport(P)
WinnerScore.Activate(P)
# Failable predicate: succeeds only for players we want to reward.
# Replace this with your real win condition.
IsWinner(P : player)<transacts><decides>:void =
# Example gate: the player must be a valid, fortnite character.
FC := P.GetFortCharacter[]
FC.IsActive[]```
Line by line:
- The three `@editable` fields are the placed devices. You drop a Timer, Teleporter and Score Manager on the island and assign them in the Details panel.
- `OnBegin` subscribes `OnRoundOver` to the timer's `SuccessEvent` and starts the timer with `RoundTimer.Start()`.
- `SuccessEvent` is a `listenable(?agent)`, so the handler signature is `(MaybeAgent : ?agent)`. We don't need that agent here, so we ignore it.
- `GetPlayspace().GetPlayers()` returns the array we iterate.
- The `for (P : AllPlayers)` walks every player. Inside, `if (IsWinner[P])` is the **skip gate**: when `IsWinner[P]` fails, everything after the `if` is skipped for THAT player and the loop simply proceeds to the next one — that's the Verse version of `continue`.
- Winners get `Teleport(P)` and `Activate(P)` (the agent overload that awards points to that specific player).
- `IsWinner` uses `<decides>` (it can fail). The `[]` call syntax runs it in a failure context. Swap the body for your real win check.
## Common patterns
### 1. Skip in the `for` header (the tightest 'continue')
Instead of an inner `if`, bake the filter into the `for` itself. Any player failing `HasCharacter[P]` is skipped before the body ever runs. Here we increment a score bump for each qualifying player.
```verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /Verse.org/Simulation }
header_filter_scorer := class(creative_device):
@editable
Score : score_manager_device = score_manager_device{}
OnBegin<override>()<suspends>:void =
AllPlayers := GetPlayspace().GetPlayers()
# Filter clause in the header: non-matching players are skipped.
for (P : AllPlayers, HasCharacter[P]):
# Only reached for players that passed the filter.
Score.Increment(P)
Score.Activate(P)
HasCharacter(P : player)<transacts><decides>:void =
FC := P.GetFortCharacter[]
FC.IsActive[]
2. Skip missing array elements while looping devices
When looping an array of optional teleporters, use the inner if to skip empty slots and keep going. Only valid destinations get activated.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
teleport_all_valid := class(creative_device):
# A row of teleporters along the dock; some slots may be empty.
@editable
Teleporters : []teleporter_device = array{}
@editable
StartRift : teleporter_device = teleporter_device{}
OnBegin<override>()<suspends>:void =
StartRift.EnterEvent.Subscribe(OnEnter)
OnEnter(Entrant : agent):void =
for (T : Teleporters):
# Enable each teleporter; if any op fails we skip it.
T.Enable()
T.ActivateLinkToTarget()
3. Countdown loop that skips ticks until a condition holds
A loop with Sleep is a common async pattern. Each pass we check a guard; when it fails we skip the body work and let the loop Sleep again — effectively 'continue to next tick'.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
pulse_timer := class(creative_device):
@editable
Beacon : timer_device = timer_device{}
var Beats : int = 0
OnBegin<override>()<suspends>:void =
loop:
Sleep(1.0)
set Beats += 1
# Skip the reset work unless we've hit 5 beats.
if (Beats >= 5):
Beacon.Reset()
set Beats = 0
# (If the if fails, we skip straight to the next loop pass.)
Gotchas
- There is no
continuekeyword. Reaching forcontinue/breakfrom another language will not compile. Use a failableifguard (skip) orbreakis likewise absent — restructure with guards instead. forheader filters short-circuit before the body.for (P : Ps, Guard[P])never runs the body for failing elements — this is usually clearer than an innerifwhen you're just filtering.?agentevents must be unwrapped.timer_device.SuccessEventislistenable(?agent); the handler receives?agent. If you need the actual agent, unwrap withif (A := MaybeAgent?):before using it.<decides>predicates use[], not(). CallIsWinner[P]inside a failure context (anif, or aforfilter clause). Calling it with()will not compile.- Agent vs. no-agent device overloads.
Score.Activate(P)awards to a specific player;Score.Activate()uses the device's default. Pick the overload that matches whether your device's Activating Team is set to a specific team. - Int/float don't auto-convert. In the countdown pattern,
BeatsisintandSleeptakes afloatliteral (1.0). Don't mix them.