Reference Devices compiles

capture_area_device: Control Points, Flags, and Zone Logic

The `capture_area_device` is UEFN's Swiss Army knife for zone-based gameplay — it powers control points, flag drop-offs, proximity doors, and any mechanic that cares about *who is standing where*. Drop one in your level, wire it to Verse, and you get a full suite of events (agents entering, contesting, scoring, neutralizing) plus methods to resize the zone, pulse an objective marker, hand control to a team, or lock down capture entirely. This article walks you through the complete API with a rea

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

Overview

The capture_area_device defines a cylindrical volume on your island. At its simplest it fires AgentEntersEvent / AgentExitsEvent so you can use it as a fancy trigger zone — great for automatic doors, proximity traps, or safe-zone enforcement. Turn on Capture mode in the Details panel and it becomes a full control point: teams contest it, a progress bar fills, control changes hands, and AreaIsScoredEvent fires on every periodic tick while a team holds it.

Reach for it when you need:

  • A domination / king-of-the-hill control point
  • A flag delivery zone (pair with capture_item_spawner_device)
  • A proximity trigger that knows how many players are inside (GetAgentsInVolume)
  • A zone you can resize at runtime (SetRadius, SetHeight) or lock/unlock mid-game (DisallowCapture / AllowCapture)
  • An objective pulse that draws players to the zone (ActivateObjectivePulse)

API Reference

capture_area_device

Used to create a zone that can trigger effects once players enter it. Can be set up to be capturable by a team, to provide a score while held, or to require a specific item as a drop-off.

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

capture_area_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 this device area. Sends the agent that entered this device area.
AgentExitsEvent AgentExitsEvent<public>:listenable(agent) Signaled when an agent exits this device area. Sends the agent that exited this device area.
FirstAgentEntersEvent FirstAgentEntersEvent<public>:listenable(agent) Signaled when the first agent enters this device area. Sends the agent that entered this device area.
LastAgentExitsEvent LastAgentExitsEvent<public>:listenable(agent) Signaled when the last agent exits this device area. Sends the agent that exited this device area.
AreaIsContestedEvent AreaIsContestedEvent<public>:listenable(agent) Signaled when this device is contested. Sends the agent that is contesting this device.
AreaIsScoredEvent AreaIsScoredEvent<public>:listenable(agent) Signaled when this device is scored. Sends the agent that scored this device.
ControlChangeStartsEvent ControlChangeStartsEvent<public>:listenable(agent) Signaled when this device control change starts. Sends the agent that is triggering this device control change.
ControlChangeEvent ControlChangeEvent<public>:listenable(agent) Signaled when this device control changes. Sends the agent that triggered this device control change.
NeutralizeEvent NeutralizeEvent<public>:listenable(?agent) Signaled when this device enters the neutralized state. Sends the agent that was responsible for neutralizing the area (the player in the area at the time of neutralization, prioritized by the one who has been in the area the longest), if
ItemIsConsumedEvent ItemIsConsumedEvent<public>:listenable(agent) Signaled when an item is consumed by this device. Sends the agent that provided the item to this device.
ItemIsDeliveredEvent ItemIsDeliveredEvent<public>:listenable(agent) Signaled when an item is delivered to this device. Sends the agent that delivered the item to this device.

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.
ToggleEnabled ToggleEnabled<public>():void Toggles between Enable and Disable.
AllowCapture AllowCapture<public>():void Allows this device to be captured.
DisallowCapture DisallowCapture<public>():void Disallows this device from being captured.
ToggleCaptureAllowed ToggleCaptureAllowed<public>():void Toggles between AllowCapture and DisallowCapture.
GiveControl GiveControl<public>(Agent:agent):void Gives control of this device to the capturing agent's team.
Neutralize Neutralize<public>():void Clears control of this device for all teams.
ActivateObjectivePulse ActivateObjectivePulse<public>():void Activates the objective pulse for this device.
DeactivateObjectivePulse DeactivateObjectivePulse<public>():void Deactivates the objective pulse for this device.
SetHeight SetHeight<public>(Height:float):void Sets the Capture Height (in meters) of the capture area.
GetHeight GetHeight<public>()<reads>:float Returns the Capture Height (in meters) of the capture area.
SetRadius SetRadius<public>(Radius:float):void Sets the Capture Radius (in meters) of the capture area.
GetRadius GetRadius<public>()<reads>:float Returns the Capture Radius (in meters) of the capture area.
GetAgentsInVolume GetAgentsInVolume<public>()<reads>:[]agent Returns an array of agents that are currently occupying the Capture Area.
IsInArea IsInArea<public>(Agent:agent)<transacts><decides>:void Is true when Agent is in the Capture Area.

Walkthrough

Scenario — Three-Point Domination

You have three capture areas (A, B, C) on a map. A Verse device manages all three:

  • When a point is first entered it pulses its objective marker so enemies know it's being contested.
  • When control changes it prints a message and removes the pulse.
  • When the last player leaves it neutralizes the point so neither team holds it passively.
  • A helper method lets a designer resize any point at runtime (e.g., shrink it during a final round).
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

# Localized message helper
PointCapturedMsg<localizes>(PointName : string) : message = "Point {PointName} has been captured!"
PointContestedMsg<localizes>(PointName : string) : message = "Point {PointName} is being contested!"
PointNeutralizedMsg<localizes>() : message = "A point has been neutralized!"

domination_manager := class(creative_device):

    # Wire these to your three placed Capture Area devices in the Details panel
    @editable
    CaptureAreaA : capture_area_device = capture_area_device{}

    @editable
    CaptureAreaB : capture_area_device = capture_area_device{}

    @editable
    CaptureAreaC : capture_area_device = capture_area_device{}

    # Called once at game start — subscribe to all relevant events
    OnBegin<override>()<suspends> : void =
        # Point A
        CaptureAreaA.FirstAgentEntersEvent.Subscribe(OnFirstEntersA)
        CaptureAreaA.ControlChangeEvent.Subscribe(OnControlChangedA)
        CaptureAreaA.LastAgentExitsEvent.Subscribe(OnLastExitsA)
        CaptureAreaA.AreaIsContestedEvent.Subscribe(OnContestedA)

        # Point B
        CaptureAreaB.FirstAgentEntersEvent.Subscribe(OnFirstEntersB)
        CaptureAreaB.ControlChangeEvent.Subscribe(OnControlChangedB)
        CaptureAreaB.LastAgentExitsEvent.Subscribe(OnLastExitsB)

        # Point C
        CaptureAreaC.FirstAgentEntersEvent.Subscribe(OnFirstEntersC)
        CaptureAreaC.ControlChangeEvent.Subscribe(OnControlChangedC)
        CaptureAreaC.LastAgentExitsEvent.Subscribe(OnLastExitsC)

        # Activate objective pulses at game start so players know where the points are
        CaptureAreaA.ActivateObjectivePulse()
        CaptureAreaB.ActivateObjectivePulse()
        CaptureAreaC.ActivateObjectivePulse()

    # ── Point A handlers ──────────────────────────────────────────────────────

    OnFirstEntersA(Agent : agent) : void =
        # Someone just walked in — pulse so enemies see it's being contested
        CaptureAreaA.ActivateObjectivePulse()

    OnControlChangedA(Agent : agent) : void =
        # A team now owns the point — stop pulsing, it's captured
        CaptureAreaA.DeactivateObjectivePulse()

    OnLastExitsA(Agent : agent) : void =
        # Nobody left inside — neutralize so it doesn't stay owned passively
        CaptureAreaA.Neutralize()
        CaptureAreaA.ActivateObjectivePulse()   # pulse again so players come back

    OnContestedA(Agent : agent) : void =
        # Optionally re-pulse when contested (enemy entered an owned point)
        CaptureAreaA.ActivateObjectivePulse()

    # ── Point B handlers ──────────────────────────────────────────────────────

    OnFirstEntersB(Agent : agent) : void =
        CaptureAreaB.ActivateObjectivePulse()

    OnControlChangedB(Agent : agent) : void =
        CaptureAreaB.DeactivateObjectivePulse()

    OnLastExitsB(Agent : agent) : void =
        CaptureAreaB.Neutralize()
        CaptureAreaB.ActivateObjectivePulse()

    # ── Point C handlers ──────────────────────────────────────────────────────

    OnFirstEntersC(Agent : agent) : void =
        CaptureAreaC.ActivateObjectivePulse()

    OnControlChangedC(Agent : agent) : void =
        CaptureAreaC.DeactivateObjectivePulse()

    OnLastExitsC(Agent : agent) : void =
        CaptureAreaC.Neutralize()
        CaptureAreaC.ActivateObjectivePulse()

    # ── Designer helper — call from another device or a timer ─────────────────
    # Shrinks all three points to create a tighter final-round zone
    ShrinkAllPoints() : void =
        CaptureAreaA.SetRadius(3.0)
        CaptureAreaA.SetHeight(2.0)
        CaptureAreaB.SetRadius(3.0)
        CaptureAreaB.SetHeight(2.0)
        CaptureAreaC.SetRadius(3.0)
        CaptureAreaC.SetHeight(2.0)

Line-by-line highlights:

Line / block What it does
@editable fields Lets you drag real placed devices into the slots in the UEFN Details panel. Without @editable you can't reference a placed device.
FirstAgentEntersEvent.Subscribe Fires once when the zone goes from empty → occupied. Perfect for "contest starts" logic.
LastAgentExitsEvent.Subscribe Fires once when the zone goes from occupied → empty. Ideal for auto-neutralize.
ControlChangeEvent.Subscribe Fires when ownership flips to a new team.
ActivateObjectivePulse() / DeactivateObjectivePulse() Toggles the glowing objective ring players see on-screen.
Neutralize() Clears team ownership so the point is up for grabs again.
SetRadius(3.0) / SetHeight(2.0) Resizes the cylinder at runtime — great for dynamic round phases.

Common patterns

Pattern 1 — Automatic Proximity Door

Use FirstAgentEntersEvent / LastAgentExitsEvent to open and close a door. The capture area sits in the doorway; no capture settings needed.

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

auto_door_device := class(creative_device):

    @editable
    DoorZone : capture_area_device = capture_area_device{}

    # A mutator zone or prop manipulator would be the real door;
    # here we use a second capture area as a stand-in for illustration.
    @editable
    InnerDoorZone : capture_area_device = capture_area_device{}

    OnBegin<override>()<suspends> : void =
        # Disable capture so this zone is purely a proximity sensor
        DoorZone.DisallowCapture()

        DoorZone.FirstAgentEntersEvent.Subscribe(OnSomeonePproaches)
        DoorZone.LastAgentExitsEvent.Subscribe(OnEveryoneLeaves)

    OnSomeonePproaches(Agent : agent) : void =
        # "Open" the door — enable the inner zone or trigger your door prop
        InnerDoorZone.Enable()

    OnEveryoneLeaves(Agent : agent) : void =
        # "Close" the door after the last person leaves
        InnerDoorZone.Disable()

Key calls: DisallowCapture() turns off the scoring system so the zone is a pure sensor. Enable() / Disable() on a second device acts as the door actuator.


Pattern 2 — Head-Count Gate (IsInArea + GetAgentsInVolume)

Only unlock a vault when three or more players are standing in the zone simultaneously — a co-op puzzle mechanic.

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

vault_gate_device := class(creative_device):

    @editable
    PressurePlate : capture_area_device = capture_area_device{}

    @editable
    VaultDoor : capture_area_device = capture_area_device{}

    # Minimum players required to open the vault
    RequiredPlayers : int = 3

    OnBegin<override>()<suspends> : void =
        PressurePlate.DisallowCapture()
        VaultDoor.Disable()   # vault starts locked

        # Check the count every time someone enters or exits
        PressurePlate.AgentEntersEvent.Subscribe(OnZoneChanged)
        PressurePlate.AgentExitsEvent.Subscribe(OnZoneChanged)

    OnZoneChanged(Agent : agent) : void =
        Agents := PressurePlate.GetAgentsInVolume()
        if (Agents.Length >= RequiredPlayers):
            VaultDoor.Enable()    # enough players — open the vault
        else:
            VaultDoor.Disable()   # too few — keep it locked

Key calls: GetAgentsInVolume() returns the live slice of agents inside right now. AgentEntersEvent and AgentExitsEvent (not just First/Last) fire for every individual, so the count is always fresh.


Pattern 3 — Neutralize Event + GiveControl (Flag Delivery)

When a flag carrier delivers an item, immediately give control to their team and then neutralize after a delay — simulating a timed capture in a CTF variant.

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

ctf_delivery_zone := class(creative_device):

    @editable
    DeliveryZone : capture_area_device = capture_area_device{}

    OnBegin<override>()<suspends> : void =
        DeliveryZone.ItemIsDeliveredEvent.Subscribe(OnFlagDelivered)
        DeliveryZone.NeutralizeEvent.Subscribe(OnZoneNeutralized)

    OnFlagDelivered(Agent : agent) : void =
        # Hand control to the delivering agent's team immediately
        DeliveryZone.GiveControl(Agent)
        # Wait 10 seconds, then reset the zone for the next round
        Sleep(10.0)
        DeliveryZone.Neutralize()

    # NeutralizeEvent sends ?agent — must unwrap the option
    OnZoneNeutralized(MaybeAgent : ?agent) : void =
        if (A := MaybeAgent?):
            # A specific agent triggered the neutralize
            DeliveryZone.ActivateObjectivePulse()
        else:
            # Neutralized programmatically (no agent responsible)
            DeliveryZone.ActivateObjectivePulse()

Key calls: ItemIsDeliveredEvent fires when a player drops a tracked item (flag) into the zone. GiveControl(Agent) skips the capture progress bar and instantly awards the point. NeutralizeEvent sends ?agent — always unwrap with if (A := MaybeAgent?).

Gotchas

1. NeutralizeEvent sends ?agent, not agent

Every other event on this device sends a plain agent. NeutralizeEvent sends ?agent (optional) because the neutralize can be triggered programmatically with no player involved. Always unwrap:

OnNeutralized(MaybeAgent : ?agent) : void =
    if (A := MaybeAgent?):
        # use A as a real agent

Forgetting this causes a type mismatch compile error.

2. @editable is mandatory for placed devices

You cannot write MyArea := capture_area_device{} and expect it to refer to the device you placed in the level. That creates a new, unplaced instance. Every device you want to control from Verse must be declared as an @editable field and then dragged into the slot in the UEFN Details panel.

3. DisallowCapture() before using as a pure sensor

If you use a capture area purely as a proximity trigger (door, head-count gate, etc.) and leave Capture enabled in the Details panel, the zone will still run its scoring logic, fire ControlChangeEvent, and potentially award score. Call DisallowCapture() in OnBegin to suppress all of that.

4. IsInArea has <transacts><decides> effects

IsInArea is a failable expression — it only succeeds if the agent is inside. You must call it inside an if (or another decision context):

# Correct
if (DeliveryZone.IsInArea[SomeAgent]):
    # agent is confirmed inside

Calling it outside a decision context is a compile error.

5. SetRadius / SetHeight take float, not int

Verse does not auto-convert integers to floats. Write SetRadius(5.0) not SetRadius(5) — the latter is a type error.

6. Objective pulse state is not automatically reset

ActivateObjectivePulse() and DeactivateObjectivePulse() are fire-and-forget toggles. If you Disable() the device and then Enable() it again, the pulse state is whatever you last set it to. Re-activate or deactivate explicitly after re-enabling.

7. GiveControl bypasses the capture progress bar

This is intentional for scripted scenarios (flag delivery, designer-triggered events), but if you call it mid-contest the progress bar will snap immediately. Pair it with ControlChangeStartsEvent if you need to animate a transition in your UI.

Device Settings & Options

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

Capture Area Device settings and options panel in the UEFN editor — Accent Color, Capture Radius, Visible During Game, Item Filter, Item Delivery Score, Periodic Scoring, Score on Taking Control, Count as Objective, Show In Objective HUD, Item List
Capture Area Device — User Options in the UEFN editor: Accent Color, Capture Radius, Visible During Game, Item Filter, Item Delivery Score, Periodic Scoring, Score on Taking Control, Count as Objective, Show In Objective HUD, Item List
⚙️ Settings on this device (10)

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

Accent Color
Capture Radius
Visible During Game
Item Filter
Item Delivery Score
Periodic Scoring
Score on Taking Control
Count as Objective
Show In Objective HUD
Item List

Guides & scripts that use capture_area_device

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

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