Reference Devices compiles

crowd_volume_device: Spawn a Cheering Crowd on Demand

The `crowd_volume_device` fills a volume with a cheering NPC audience that reacts to your players — perfect for arenas, finish lines, or spectator stands. From Verse you can toggle the crowd on and off at exactly the right moment, and by pairing it with a `volume_device` you can detect when players step into the crowd zone and trigger crowd reactions dynamically.

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

Overview

The crowd_volume_device spawns an animated NPC crowd inside a defined area of your island. By default the crowd cheers and reacts to nearby players, adding atmosphere to arenas, race tracks, concert stages, or any competitive space.

From Verse you get two direct controls:

  • Enable() — activates the crowd so it appears and cheers.
  • Disable() — hides the crowd entirely.

Because the device has no built-in entry/exit events of its own, you pair it with a volume_device to detect when players enter or leave the crowd zone. The volume_device provides AgentEntersEvent, AgentExitsEvent, GetAgentsInVolume(), and IsInVolume() — giving you full situational awareness of who is standing in the crowd area.

Reach for this device when you want to:

  • Reveal a cheering crowd only after a player crosses a finish line.
  • Silence the crowd when the arena empties between rounds.
  • Gate crowd activation on how many players are currently inside the zone.

API Reference

crowd_volume_device

Spawns a crowd to cheer you on.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).

crowd_volume_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.

volume_device

Used to track when agents enter and exit a volume.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).

volume_device<public> := class<concrete><final>(creative_device_base):

Events (subscribe a handler to react):

Event Signature Description
AgentEntersEvent AgentEntersEvent<public>:listenable(agent) Signaled when an agent enters the device volume.
AgentExitsEvent AgentExitsEvent<public>:listenable(agent) Signaled when an agent exits the device volume.
PropEnterEvent PropEnterEvent<public>:listenable(creative_prop) Signaled when an creative_prop entered the device volume.
PropExitEvent PropExitEvent<public>:listenable(creative_prop) Signaled when an creative_prop exited the device volume.

Methods (call these to make the device act):

Method Signature Description
GetAgentsInVolume GetAgentsInVolume<public>()<reads>:[]agent Returns an array of agents that are currently occupying the volume.
IsInVolume IsInVolume<public>(Agent:agent)<transacts><decides>:void Succeeds when Agent is in the volume.

Walkthrough

Scenario: An arena has a crowd zone behind the starting gate. The crowd is silent at the start. When the first player steps into the arena volume, the crowd erupts. When the last player leaves, the crowd goes quiet again. A periodic check also prints how many players are currently in the zone.

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

# Localized helper so we can pass strings as `message` parameters if needed.
ArenaMessage<localizes>(S : string) : message = "{S}"

arena_crowd_manager := class(creative_device):

    # The crowd volume device placed in the editor — the NPC audience.
    @editable
    CrowdVolume : crowd_volume_device = crowd_volume_device{}

    # A volume_device placed over the same area — detects player presence.
    @editable
    ArenaVolume : volume_device = volume_device{}

    # Track how many players are currently inside.
    var PlayersInside : int = 0

    OnBegin<override>()<suspends> : void =
        # Start with the crowd disabled — silence before the action begins.
        CrowdVolume.Disable()

        # Subscribe to entry and exit events on the volume_device.
        ArenaVolume.AgentEntersEvent.Subscribe(OnPlayerEntered)
        ArenaVolume.AgentExitsEvent.Subscribe(OnPlayerExited)

        # Continuously monitor crowd zone population every 5 seconds.
        loop:
            Sleep(5.0)
            CheckArenaPopulation()

    # Called whenever an agent enters the arena volume.
    OnPlayerEntered(Agent : agent) : void =
        set PlayersInside = PlayersInside + 1
        if (PlayersInside = 1):
            # First player arrived — wake the crowd!
            CrowdVolume.Enable()

    # Called whenever an agent exits the arena volume.
    OnPlayerExited(Agent : agent) : void =
        if (PlayersInside > 0):
            set PlayersInside = PlayersInside - 1
        if (PlayersInside = 0):
            # Arena is empty — silence the crowd.
            CrowdVolume.Disable()

    # Periodic ground-truth check using GetAgentsInVolume.
    CheckArenaPopulation() : void =
        Agents := ArenaVolume.GetAgentsInVolume()
        # Sync our counter with reality in case events were missed.
        set PlayersInside = Agents.Length
        if (PlayersInside = 0):
            CrowdVolume.Disable()
        else:
            CrowdVolume.Enable()

Line-by-line explanation:

Lines What's happening
@editable CrowdVolume References the placed crowd_volume_device — required to call Enable/Disable.
@editable ArenaVolume References the placed volume_device — provides all entry/exit events and query methods.
CrowdVolume.Disable() in OnBegin Ensures the crowd is hidden at game start.
AgentEntersEvent.Subscribe(OnPlayerEntered) Wires the entry event to our handler.
AgentExitsEvent.Subscribe(OnPlayerExited) Wires the exit event to our handler.
loop + Sleep(5.0) Runs CheckArenaPopulation every 5 seconds as a safety net.
OnPlayerEntered Increments the counter; enables the crowd when the first player arrives.
OnPlayerExited Decrements the counter; disables the crowd when the last player leaves.
GetAgentsInVolume() Returns the live array of agents — used to reconcile the counter with ground truth.

Common patterns

Pattern 1 — Spotlight check: is a specific player in the crowd zone?

Use IsInVolume (a failable expression) to check whether a particular agent is standing in the zone right now.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

crowd_spotlight_check := class(creative_device):

    @editable
    CrowdVolume : crowd_volume_device = crowd_volume_device{}

    @editable
    ArenaVolume : volume_device = volume_device{}

    # A button players press to check if they are "in the spotlight".
    @editable
    CheckButton : button_device = button_device{}

    OnBegin<override>()<suspends> : void =
        CrowdVolume.Enable()
        CheckButton.InteractedWithEvent.Subscribe(OnButtonPressed)
        # Keep the coroutine alive.
        loop:
            Sleep(9999.0)

    OnButtonPressed(Agent : agent) : void =
        # IsInVolume<decides> — wrap in `if` to handle the failable call.
        if (ArenaVolume.IsInVolume[Agent]):
            # Player IS in the crowd zone — crowd reacts.
            CrowdVolume.Disable()
            # Brief pause, then re-enable for a "wave" effect.
            # (Spawn a concurrent task so we don't block the handler.)
            spawn { CrowdWaveEffect() }

    CrowdWaveEffect()<suspends> : void =
        Sleep(1.5)
        CrowdVolume.Enable()

Key point: IsInVolume has the <decides> effect — it is a failable expression and must be called inside an if (or another failure context). Calling it bare will not compile.


Pattern 2 — Round-based crowd toggle (Enable/Disable on a timer)

Simple round structure: crowd cheers during the round, goes quiet during the break.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

round_crowd_controller := class(creative_device):

    @editable
    CrowdVolume : crowd_volume_device = crowd_volume_device{}

    # Duration of each active round in seconds.
    @editable
    RoundDuration : float = 60.0

    # Duration of the break between rounds in seconds.
    @editable
    BreakDuration : float = 15.0

    OnBegin<override>()<suspends> : void =
        # Crowd starts disabled — silence before round 1.
        CrowdVolume.Disable()
        Sleep(3.0)  # Brief countdown pause.

        loop:
            # --- Active round: crowd cheers ---
            CrowdVolume.Enable()
            Sleep(RoundDuration)

            # --- Break: crowd goes quiet ---
            CrowdVolume.Disable()
            Sleep(BreakDuration)

Key point: Enable() and Disable() are plain void calls with no effects — safe to call anywhere, including inside a loop.


Pattern 3 — React to props entering the crowd zone

The volume_device also fires PropEnterEvent when a creative_prop enters the volume — useful for physics objects or moving set pieces rolling into the crowd area.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

crowd_prop_reactor := class(creative_device):

    @editable
    CrowdVolume : crowd_volume_device = crowd_volume_device{}

    @editable
    ArenaVolume : volume_device = volume_device{}

    OnBegin<override>()<suspends> : void =
        CrowdVolume.Disable()
        ArenaVolume.PropEnterEvent.Subscribe(OnPropEntered)
        ArenaVolume.PropExitEvent.Subscribe(OnPropExited)
        loop:
            Sleep(9999.0)

    # A prop (e.g. a rolling boulder) entered the crowd zone — crowd reacts!
    OnPropEntered(Prop : creative_prop) : void =
        CrowdVolume.Enable()

    # Prop left — crowd calms down.
    OnPropExited(Prop : creative_prop) : void =
        CrowdVolume.Disable()

Key point: PropEnterEvent and PropExitEvent hand the handler a creative_prop value directly — no unwrapping needed (unlike ?agent optionals on some other devices).

Gotchas

1. crowd_volume_device has NO entry/exit events — always pair with volume_device

The crowd_volume_device only exposes Enable() and Disable(). It cannot tell you when players enter or leave. You must place a separate volume_device over the same area and subscribe to its events for any presence-based logic.

2. IsInVolume is failable — always call it inside if

IsInVolume carries the <decides> effect, meaning it can fail (when the agent is NOT in the volume). You must call it inside a failure context:

# CORRECT
if (ArenaVolume.IsInVolume[Agent]):
    CrowdVolume.Enable()

# WRONG — will not compile
ArenaVolume.IsInVolume(Agent)  # missing failure context

Note the bracket syntax IsInVolume[Agent] when used inside if — this is the standard Verse failable-call pattern.

3. AgentEntersEvent / AgentExitsEvent hand a plain agent, not ?agent

Unlike some other devices that signal ?agent (optional), volume_device events deliver a concrete agent. No if (A := Agent?) unwrap is needed in your handler signature.

4. Enable() and Disable() are idempotent but not stateful in Verse

Calling Enable() on an already-enabled crowd (or Disable() on an already-disabled one) is safe and will not throw. However, Verse has no built-in way to query the current enabled state of the device — track it yourself with a var boolean if your logic needs to know.

5. Keep your coroutine alive

If your OnBegin body returns (falls off the end), all subscriptions are still active but any loop-based logic stops. If you only subscribe to events and do nothing else, add loop: Sleep(9999.0) at the end of OnBegin to keep the device coroutine running indefinitely.

6. GetAgentsInVolume() returns a snapshot, not a live collection

The array returned by GetAgentsInVolume() is a point-in-time snapshot. Cache it to a local variable and iterate — do not assume it stays up to date as players move.

Device Settings & Options

The crowd_volume_device User Options panel in the UEFN editor — every setting you can tune.

Crowd Volume Device settings and options panel in the UEFN editor — Crowd Density, Character Alignment, Zone Width, Zone Depth, Zone Height, Enabled During Phase
Crowd Volume Device — User Options (1 of 2) in the UEFN editor: Crowd Density, Character Alignment, Zone Width, Zone Depth, Zone Height, Enabled During Phase
Crowd Volume Device settings and options panel in the UEFN editor — Crowd Density, Character Alignment, Zone Width, Zone Depth, Zone Height, Enabled During Phase
Crowd Volume Device — User Options (2 of 2) in the UEFN editor: Crowd Density, Character Alignment, Zone Width, Zone Depth, Zone Height, Enabled During Phase
⚙️ Settings on this device (6)

Setting names read from the panel above — may be partial; the screenshots are the source of truth.

Crowd Density
Character Alignment
Zone Width
Zone Depth
Zone Height
Enabled During Phase

Build your own lesson with crowd_volume_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 →