Reference Verse

for: Looping Over Devices to Build a Sunny Cove Moment

The `for` expression is the workhorse that lets one line of Verse touch many things at once — every player who just spawned on the dock, every teleporter along the shore, every score you want to hand out. On a bright cel-shaded cove map, `for` is how you turn a single event into a whole beach coming to life.

Updated
The code on this reference page is provided as-is and did not pass the latest compile check — treat the examples as a starting point and verify in your project.
Watch the Knotfor in ~90 seconds.

Overview

for is not a device — it's a core Verse control-flow expression, and it is the single most useful tool for working with devices. Placed devices almost always come in groups (a row of teleporters along the shore, a handful of player spawners on the dock), and the players you serve arrive as arrays too. for lets you sweep across those collections and call a device method on each element.

Reach for for whenever you catch yourself thinking "...for every X, do Y": for every spawner, spawn a player; for every teleporter, activate the link; for every player in the damage volume, grant a point. It pairs naturally with Subscribe handlers — one event fires, and inside the handler a for loop fans that single signal out across many devices.

The shape is simple:

for (Item : SomeArray):
    Item.DoSomething()

You can also filter mid-loop with a <decides> (failable) expression: for (X : Array, X.IsReady[]): only runs the body for the elements that pass. That combination — iterate, filter, act on a real device — is what this article teaches on a sunny cove.

API Reference

(API surface could not be resolved for this device.)

Walkthrough

The moment: Players stand on a clifftop above a cel-shaded cove. When the round timer succeeds, we want to celebrate: sweep across a row of teleporter_devices and drop everyone onto the beach below, then hand each of them a point via a score_manager_device. One timer event, many devices — that's for.

using { /Fortnite.com/Devices }

# A clifftop-to-cove celebration: one timer success fans out across
# an array of teleporters and a score manager using `for`.
sunny_cove_finale := class(creative_device):

    # The round timer that fires SuccessEvent when the beach party begins.
    @editable
    RoundTimer : timer_device = timer_device{}

    # A row of teleporters placed along the clifftop edge.
    # In the Details panel you add each placed teleporter to this array.
    @editable
    BeachTeleporters : []teleporter_device = array{}

    # Hands out celebration points.
    @editable
    ScoreManager : score_manager_device = score_manager_device{}

    OnBegin<override>()<suspends>:void =
        # First: link every teleporter so players can return later.
        # `for` sweeps the whole placed array in one pass.
        for (Tele : BeachTeleporters):
            Tele.Enable()
            Tele.ActivateLinkToTarget()

        # When the timer succeeds, run our celebration handler.
        RoundTimer.SuccessEvent.Subscribe(OnTimerSuccess)

    # SuccessEvent is a listenable(?agent) — the handler receives an optional agent.
    OnTimerSuccess(MaybeAgent : ?agent) : void =
        # Unwrap the optional agent. If someone triggered the timer, teleport
        # exactly them; otherwise fall through to the whole array behaviour.
        if (Agent := MaybeAgent?):
            # Sweep every teleporter and send this agent to the cove,
            # then award them a point.
            for (Tele : BeachTeleporters):
                Tele.Activate(Agent)
            ScoreManager.Activate(Agent)```

**Line by line:**

- `@editable RoundTimer : timer_device = timer_device{}`  a bare `Device.Method()` fails with 'Unknown identifier', so every placed device must be an `@editable` field. This one holds the timer you drop in the level.
- `@editable BeachTeleporters : []teleporter_device = array{}`  the `[]` makes this an *array* of teleporters. In the Details panel you add each placed teleporter, and Verse sees them as one collection to loop over.
- In `OnBegin`, the first `for (Tele : BeachTeleporters):` walks each teleporter and calls `Enable()` and `ActivateLinkToTarget()` on it  two real teleporter methods, applied to every element with no repeated code.
- `RoundTimer.SuccessEvent.Subscribe(OnTimerSuccess)` wires the timer's success signal to our method. Subscription happens in `OnBegin`; the handler is a method at class scope.
- `OnTimerSuccess(MaybeAgent : ?agent)` matches the `listenable(?agent)` signature  the timer hands us an *optional* agent.
- `if (Agent := MaybeAgent?):` unwraps the option. Only inside this block do we have a real `agent`.
- The inner `for (Tele : BeachTeleporters): Tele.Activate(Agent)` fans the single success event out: every teleporter teleports the agent (they emerge at whichever cove destination is set), and `ScoreManager.Activate(Agent)` grants the celebration point.

## Common patterns

**Spawn everyone in from a row of spawners.** Loop the spawner array and call `Spawn`/`SpawnPlayer` on each  great for dropping a squad onto the dock at once.

```verse
dock_squad_spawner := class(creative_device):

    # Player spawn pads placed along the dock.
    @editable
    DockSpawners : []player_spawner_device = array{}

    OnBegin<override>()<suspends>:void =
        # Enable every spawner in one sweep.
        for (Pad : DockSpawners):
            Pad.Enable()

        # When any pad spawns someone, log it via the SpawnedEvent.
        for (Pad : DockSpawners):
            Pad.SpawnedEvent.Subscribe(OnSpawned)

    OnSpawned(Agent : agent) : void =
        # A fresh arrival on the dock — nothing else needed here,
        # but you could grant an item or teleport them onward.
        Agent.IsA[]  # harmless no-op placeholder guard

Reward every player currently standing in a cove damage volume. GetAgentsInVolume() returns an array; for walks it and hands each occupant a point.

cove_zone_rewarder := class(creative_device):

    # A shallow-water volume in the cove.
    @editable
    CoveVolume : damage_volume_device = damage_volume_device{}

    # Awards points to occupants.
    @editable
    ScoreManager : score_manager_device = score_manager_device{}

    # A timer whose success tells us to sweep the zone.
    @editable
    ScoreTimer : timer_device = timer_device{}

    OnBegin<override>()<suspends>:void =
        ScoreTimer.SuccessEvent.Subscribe(OnTick)

    OnTick(MaybeAgent : ?agent) : void =
        # Grab everyone standing in the cove right now and reward them all.
        for (Occupant : CoveVolume.GetAgentsInVolume()):
            ScoreManager.Activate(Occupant)

Filter while you loop. A for can carry a <decides> guard so the body only runs for elements that pass. Here we only re-link teleporters that are actually enabled, using the reference device's IsReferenced check as a per-agent filter.

referenced_teleporter_linker := class(creative_device):

    # Teleporters lining the shore.
    @editable
    ShoreTeleporters : []teleporter_device = array{}

    # Tracks the currently referenced hero player.
    @editable
    HeroRef : player_reference_device = player_reference_device{}

    OnBegin<override>()<suspends>:void =
        HeroRef.ActivatedEvent.Subscribe(OnHeroActivated)

    OnHeroActivated(Agent : agent) : void =
        # Only act if this agent is the one the reference device tracks.
        if (HeroRef.IsReferenced[Agent]):
            # Sweep every shore teleporter and send the hero across.
            for (Tele : ShoreTeleporters):
                Tele.Activate(Agent)

Gotchas

  • A bare device call won't compile. You cannot loop over a device you never declared. Every device — even inside a for — must first exist as an @editable field on the creative_device class. An empty []teleporter_device = array{} field is populated in the Details panel.
  • ?agent events must be unwrapped before you loop. timer_device.SuccessEvent is listenable(?agent). The handler gets a ?agent, not an agent — you must if (Agent := MaybeAgent?): before passing it to Tele.Activate(Agent). Skipping the unwrap is a type error.
  • agent events give you an agent directly. player_spawner_device.SpawnedEvent and teleporter_device.EnterEvent are listenable(agent), so their handlers take a plain agent — no ? unwrap. Don't confuse the two shapes.
  • A for over an empty array simply does nothing. If your Details-panel array is empty, the loop body never runs — no error, no effect. If your beach stays quiet, check that the array actually contains placed devices.
  • <decides> filters inside for must be failable calls. Methods like IsReferenced[Agent] and IsInVolume[Agent] use square brackets and can fail; use them as loop guards or inside if, never as plain () statements.
  • No int/float mixing. If you ever compute a delay or count inside a loop, remember Verse never auto-converts — keep your counters int and your times float explicitly.

Guides & scripts that use for

Step-by-step tutorials that put this object to work.

Build your own lesson with for

Generate a personalized, step-by-step lesson plan built around this object — grounded in this exact reference and our compile-verified knowledge base.

Build a lesson →