Reference Devices

effect_volume_device: Zones That Change the Rules When Players Step In

An effect volume is an invisible box you drop into your map that applies a gameplay rule — damage, mutation, skydiving — to anyone standing inside it. In Verse you can turn it on and off on cue, and pair it with a volume_device to know exactly who is inside. This article shows how to build a real lava pit that only burns while the round is hot.

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.

Overview

The effect_volume_device is the abstract base class for Fortnite's area-of-effect zone devices — the Damage Volume, Mutator Zone, and Skydive Volume. You place one in your map, configure what it does in the Details panel (deal damage, modify movement, force skydive, etc.), and then in Verse you control when it is active with two methods: Enable() and Disable().

Reach for it whenever a region of your map needs to change the rules of play: a lava pit that burns players, a low-gravity zone in a parkour challenge, a no-build bubble around the final circle, or a skydive launcher that only works during a mini-game phase.

The effect volume itself only knows how to switch on and off — it has no entry/exit events. To react to players crossing the boundary you pair it with a volume_device, a non-abstract tracker that fires AgentEntersEvent / AgentExitsEvent (and PropEnterEvent / PropExitEvent) and lets you query GetAgentsInVolume() or test IsInVolume(Agent). Place a volume_device over the same footprint as your effect volume and you get both the gameplay effect and the script hooks.

API Reference

effect_volume_device

Base class for types of volumes with special gameplay properties.

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

effect_volume_device<public> := class<abstract><epic_internal>(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: A "floor is lava" arena. A Damage Volume (an effect_volume_device) sits over the lava pit and burns anyone inside, but only while the lava is active. A volume_device is placed over the same pit so we can announce who fell in and count survivors. The lava starts disabled, switches on after a warm-up, and we narrate entries/exits the whole time.

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

# A 'floor is lava' controller built on the effect volume + a tracking volume.
lava_pit_game := class(creative_device):

    # The Damage Volume placed over the lava pit. effect_volume_device gives us Enable/Disable.
    @editable
    LavaDamage : effect_volume_device = effect_volume_device{}

    # A volume_device covering the SAME footprint, so we can detect entries/exits.
    @editable
    LavaTracker : volume_device = volume_device{}

    OnBegin<override>()<suspends>:void =
        # Lava is harmless during the warm-up: turn the damage effect off to start.
        LavaDamage.Disable()

        # React when players cross the boundary of the tracking volume.
        LavaTracker.AgentEntersEvent.Subscribe(OnEnteredLava)
        LavaTracker.AgentExitsEvent.Subscribe(OnLeftLava)

        # Warm-up window, then the lava goes live.
        Print("Get to high ground! Lava activates in 5 seconds...")
        Sleep(5.0)
        LavaDamage.Enable()
        Print("The lava is HOT! Stay off the floor!")

        # Anyone already standing in the pit when it heats up is in trouble.
        BurningAgents := LavaTracker.GetAgentsInVolume()
        Print("Players caught in the lava on activation: {BurningAgents.Length}")

    # Handler for AgentEntersEvent — fires with the agent that crossed in.
    OnEnteredLava(Agent : agent):void =
        Print("An agent stepped into the lava pit!")

    # Handler for AgentExitsEvent — fires with the agent that crossed out.
    OnLeftLava(Agent : agent):void =
        # IsInVolume<decides> lets us confirm state; here we just confirm they left.
        if (not LavaTracker.IsInVolume[Agent]):
            Print("An agent escaped the lava pit. Safe... for now.")

Line by line:

  • @editable LavaDamage : effect_volume_device — the field that binds to the Damage Volume you dropped in the level. You MUST declare devices as editable fields; calling a bare effect_volume_device.Enable() would fail with Unknown identifier.
  • @editable LavaTracker : volume_device — a second device over the same area. effect_volume_device has no entry events, so the tracker is what gives us AgentEntersEvent/AgentExitsEvent.
  • LavaDamage.Disable() in OnBegin — start the round with the damage effect OFF so the warm-up is safe.
  • LavaTracker.AgentEntersEvent.Subscribe(OnEnteredLava) — subscribe a class method as the handler. The event is listenable(agent), so the handler receives an agent.
  • Sleep(5.0)OnBegin is <suspends>, so we can await a real-time delay before enabling the effect.
  • LavaDamage.Enable() — flips the volume on; from now on standing inside deals the damage configured in the Details panel.
  • LavaTracker.GetAgentsInVolume() — returns []agent; we read its .Length to count who got caught.
  • OnLeftLava uses IsInVolume[Agent] — a <decides> query, called with square brackets, that succeeds when the agent is inside. We negate it with not ...[] to confirm they're now out.

Common patterns

Toggle the effect from a player count threshold

Enable a Mutator Zone only once enough players have gathered inside it, using GetAgentsInVolume() to count.

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

arena_gate := class(creative_device):

    @editable
    MutatorEffect : effect_volume_device = effect_volume_device{}

    @editable
    Tracker : volume_device = volume_device{}

    OnBegin<override>()<suspends>:void =
        MutatorEffect.Disable()
        Tracker.AgentEntersEvent.Subscribe(OnAgentEntered)

    OnAgentEntered(Agent : agent):void =
        Count := Tracker.GetAgentsInVolume().Length
        Print("Players in the staging zone: {Count}")
        if (Count >= 3):
            # Enough players gathered — turn on the zone's gameplay effect.
            MutatorEffect.Enable()
            Print("Mutator zone ACTIVE — the rules have changed!")

React to a thrown prop entering the zone

A volume_device also tracks props. Disable a Damage Volume when a special prop is tossed in (e.g. an extinguisher prop dropped into the fire).

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

fire_zone := class(creative_device):

    @editable
    FireDamage : effect_volume_device = effect_volume_device{}

    @editable
    Tracker : volume_device = volume_device{}

    OnBegin<override>()<suspends>:void =
        FireDamage.Enable()
        Tracker.PropEnterEvent.Subscribe(OnPropEntered)
        Tracker.PropExitEvent.Subscribe(OnPropExited)

    OnPropEntered(Prop : creative_prop):void =
        # Extinguisher prop landed in the fire — put it out.
        FireDamage.Disable()
        Print("A prop landed in the fire zone — damage disabled.")

    OnPropExited(Prop : creative_prop):void =
        # Prop removed — relight the fire.
        FireDamage.Enable()
        Print("Prop left the zone — fire reignited.")

Check membership on demand with IsInVolume

Use IsInVolume[Agent] from any other logic — here a periodic safety check that re-enables a Skydive Volume if it ever empties.

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

skydive_loop := class(creative_device):

    @editable
    SkydiveEffect : effect_volume_device = effect_volume_device{}

    @editable
    Tracker : volume_device = volume_device{}

    @editable
    TestPlayerSpawn : player_spawner_device = player_spawner_device{}

    OnBegin<override>()<suspends>:void =
        SkydiveEffect.Enable()
        loop:
            Sleep(2.0)
            Agents := Tracker.GetAgentsInVolume()
            for (A : Agents):
                # IsInVolume<decides> — square brackets, succeeds when inside.
                if (Tracker.IsInVolume[A]):
                    Print("An agent is still in the skydive volume.")

Gotchas

  • The effect volume has NO entry/exit events. effect_volume_device only exposes Enable() and Disable(). If you need to know who entered, place a separate volume_device over the same area and subscribe to its AgentEntersEvent/AgentExitsEvent.
  • effect_volume_device is abstract. You never place a literal "effect volume" — you place a concrete child (Damage Volume, Mutator Zone, Skydive Volume) and bind it to an effect_volume_device-typed @editable field. What the volume actually does is configured in the Details panel, not in Verse.
  • IsInVolume is <decides>, call it with square brackets. Write if (Tracker.IsInVolume[Agent]):, not (...). Using parentheses or treating it like a bool returns a compile error. To test the negative, wrap it: if (not Tracker.IsInVolume[Agent]):.
  • listenable(agent) handlers already receive an agent. The signature here hands you a plain agent (not ?agent), so no Agent? unwrap is needed — but if you store it and later need the player, you still must validate with if (Player := Agent.GetFortCharacter[]...) style queries.
  • Enable/Disable do not move players. Disabling a Damage Volume stops new damage ticks but doesn't heal anyone; enabling a Skydive Volume only affects agents currently inside or who enter afterward. Combine with GetAgentsInVolume() if you need to act on whoever is caught at the moment of the toggle.
  • Sleep/loops require <suspends>. The warm-up and polling examples only work inside OnBegin<override>()<suspends>. You cannot Sleep inside a plain event handler method.

Device Settings & Options

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

Effect Volume Device settings and options panel in the UEFN editor — Zone Visible During Game, Base Visible During Game, Zone Width, Zone Depth, Zone Height
Effect Volume Device — User Options in the UEFN editor: Zone Visible During Game, Base Visible During Game, Zone Width, Zone Depth, Zone Height
⚙️ Settings on this device (5)

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

Zone Visible During Game
Base Visible During Game
Zone Width
Zone Depth
Zone Height

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