Reference Verse compiles

Count Matching: How Many Racers Passed?

Six dirtbikes are tearing through Codewood Grove and everyone wants to know the same thing: how many racers made it past checkpoint 3? Counting array elements that match a condition is the sum-an-array loop with one extra `if` — and it powers every racers-remaining, players-ready, and checkpoints-cleared counter on your island. Barnaby the bear walks you through the pattern, then bolts it onto a real trigger + HUD device you can drop straight into the Jungle Mod-Rally.

Updated Examples verified on the live UEFN compiler
Watch the Knottrigger_device in ~90 seconds.

Overview

The player_counter_device solves a classic party-game problem: "don't start until enough players are ready." Place it on a sun-bleached dock, a cove platform, or a clifftop arena, and it continuously compares the number of players standing inside its zone against a configurable Target Player Count. When the count is met it fires CountSucceedsEvent; if players leave and the count drops it fires CountFailsEvent. Individual arrivals and departures are reported through CountedEvent and RemovedEvent.

Reach for player_counter_device when you need:

  • A lobby gate that unlocks a mini-game only when the right number of players are present.
  • A "waiting area" that starts a countdown timer once enough crew members arrive.
  • Dynamic target adjustments mid-game (e.g., reduce the required count after a player disconnects).

API Reference

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

Walkthrough

Scenario — Dock Departure: Four players must stand on the wooden dock before the boat-launch cinematic plays and a timer starts. If players leave before the sequence finishes, the timer resets and the cinematic stops.

using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

# Place this device in your UEFN level alongside a player_counter_device,
# a cinematic_sequence_device, and a timer_device.
dock_departure_manager := class(creative_device):

    # Wire up in the UEFN Details panel
    @editable
    DockCounter : player_counter_device = player_counter_device{}

    @editable
    BoatLaunchCinematic : cinematic_sequence_device = cinematic_sequence_device{}

    @editable
    DepartureTimer : timer_device = timer_device{}

    # Called once when the island session begins
    OnBegin<override>()<suspends> : void =
        # Subscribe to all three counter events
        DockCounter.CountSucceedsEvent.Subscribe(OnCountSucceeds)
        DockCounter.CountFailsEvent.Subscribe(OnCountFails)
        DockCounter.CountedEvent.Subscribe(OnPlayerCounted)

    # Fires when the zone reaches (or exceeds) Target Player Count
    # CountSucceedsEvent sends tuple() — no payload to unwrap
    OnCountSucceeds(Ignored : tuple()) : void =
        # Enough players on the dock — play the boat-launch cinematic
        BoatLaunchCinematic.Play()
        # Start the departure countdown for everyone
        DepartureTimer.Start()

    # Fires when the zone drops below Target Player Count
    OnCountFails(Ignored : tuple()) : void =
        # Someone left — abort the launch sequence
        BoatLaunchCinematic.Stop()
        DepartureTimer.Reset()
        # Reset the counter's target back to its default (4 players)
        DockCounter.Reset()

    # Fires each time a single valid player enters the zone
    # CountedEvent sends the agent who just stepped in
    OnPlayerCounted(NewCrew : agent) : void =
        # Show the info panel so players can see Current vs Required count
        DockCounter.ShowInfoPanel()

Line-by-line breakdown:

Lines What's happening
@editable fields Lets you wire the three devices in the UEFN Details panel — required for any placed device reference.
OnBegin The only safe place to subscribe to events; runs once at session start.
CountSucceedsEvent.Subscribe(OnCountSucceeds) Registers OnCountSucceeds to be called whenever the zone headcount meets the target.
BoatLaunchCinematic.Play() Triggers the boat-launch level sequence for everyone.
DepartureTimer.Start() Kicks off the countdown — players now race against the clock.
OnCountFails Handles the "someone bailed" case: stops the cinematic, resets the timer, and resets the counter's target to its editor default.
OnPlayerCounted Receives the individual agent who just entered; calls ShowInfoPanel() so the HUD updates immediately.

Common patterns

Pattern 1 — Dynamically lower the required count mid-game

If a player disconnects, use DecrementTargetCount() so the remaining crew aren't stuck waiting forever.

using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

dynamic_target_manager := class(creative_device):

    @editable
    DockCounter : player_counter_device = player_counter_device{}

    OnBegin<override>()<suspends> : void =
        # When a player is removed from the count (left the zone or disconnected)
        DockCounter.RemovedEvent.Subscribe(OnPlayerRemoved)

    # RemovedEvent sends the agent who is no longer counted
    OnPlayerRemoved(LeavingPlayer : agent) : void =
        # Lower the bar by 1 so the remaining players can still succeed
        DockCounter.DecrementTargetCount()
        # Refresh the HUD so everyone sees the new requirement
        DockCounter.ShowInfoPanel()

Pattern 2 — Broadcast to all currently counted players at once

Use TransmitForAllCounted() to re-fire CountedEvent for every agent already in the zone — handy for late-join initialization.

using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

late_join_initializer := class(creative_device):

    @editable
    DockCounter : player_counter_device = player_counter_device{}

    @editable
    ScoreManager : score_manager_device = score_manager_device{}

    OnBegin<override>()<suspends> : void =
        DockCounter.CountedEvent.Subscribe(OnPlayerCounted)
        # After a short wait, ping all already-counted players
        # so they receive their starting bonus too
        Sleep(5.0)
        DockCounter.TransmitForAllCounted()

    OnPlayerCounted(Player : agent) : void =
        # Award a "you made it to the dock" bonus point
        ScoreManager.Activate(Player)

Pattern 3 — Raise the required count for a harder challenge

Use SetTargetCount() to change the target on the fly — for example, scale difficulty with the number of players who joined the session.

using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

scalable_challenge_manager := class(creative_device):

    @editable
    DockCounter : player_counter_device = player_counter_device{}

    @editable
    BoatLaunchCinematic : cinematic_sequence_device = cinematic_sequence_device{}

    OnBegin<override>()<suspends> : void =
        DockCounter.CountSucceedsEvent.Subscribe(OnCountSucceeds)
        # Example: require ALL 8 players for the grand finale
        DockCounter.SetTargetCount(8)
        DockCounter.ShowInfoPanel()

    OnCountSucceeds(Ignored : tuple()) : void =
        # Full crew on deck — fire the grand finale cinematic
        BoatLaunchCinematic.Play()

Gotchas

CountSucceedsEvent and CountFailsEvent send tuple(), not agent. Their handlers must accept (Ignored : tuple()). A common mistake is writing (A : agent) — that won't compile.

CountedEvent and RemovedEvent send a plain agent, not ?agent. No optional unwrap needed here. Just use the value directly: OnPlayerCounted(NewCrew : agent).

Reset() restores the editor-configured target, not zero. If you called SetTargetCount(8) at runtime and then call Reset(), the target snaps back to whatever you set in the UEFN Details panel — not 8. Store your runtime target in a var if you need to restore it.

DecrementTargetCount() can push the target below 1. Guard against this if players keep leaving: check your game logic before calling it repeatedly, or you may end up with a target of 0 or negative, which immediately triggers CountSucceedsEvent.

ShowInfoPanel() is a one-shot display call. It shows the panel at that moment; it does not keep it permanently visible. Call it again whenever the count changes if you want the HUD to stay current.

The device must be enabled to count players. If you disabled it earlier in your flow (e.g., between rounds), call Enable() before expecting any count events to fire.

@editable is mandatory for all placed device references. You cannot write player_counter_device{} and expect it to reference the one you placed on the island. Every device used in Verse must be declared as an @editable field and wired in the Details panel.

Guides & scripts that use trigger_device

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

Build your own lesson with trigger_device

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 →