Reference Devices compiles

map_controller_device: Custom Maps & Minimaps on Demand

Want a sneaky map that only the spy team can read, or a fog-of-war minimap that snaps into focus the moment a player grabs the objective? The map_controller_device lets your Verse code swap, size, and toggle map behavior per-agent or for the whole lobby. Here's how to drive it.

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

Overview

The map controller device changes the behavior of the full-screen map and the minimap. Each active controller sits on an agent's map controller stack; when several are active for the same player, the one with the highest Map Priority wins. The remaining ones stay queued, so when you Deactivate the top controller, the next-highest one takes over — and if the stack is empty, the island's default map behavior returns.

Reach for this device when you want the map to be context-sensitive: a captured region revealing a higher-resolution map view, an infiltration mode that hides the minimap from one team, or a boss arena that zooms the capture box out to show the whole battlefield. From Verse you can:

  • Activate / Deactivate the controller for one agent or everyone,
  • Enable / Disable the whole device (trigger + event response),
  • resize the capture area at runtime with SetCaptureBoxSize, and read it back with GetCaptureBoxSize.

Note there are no events on this device — it is a pure output device. You subscribe to triggers, mutators, or volumes elsewhere and call the map controller's methods in response.

API Reference

map_controller_device

Used to control the behavior of the map & minimap. Activation for a given agent can occur automatically via the device's Activate Automatically user option, by the agent entering and exiting the device's volume if using the Activate on Trigger user option, or via events from other devices or verse. When more than one map controller is activated for a given agent, the one with the highest

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

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

Methods (call these to make the device act):

Method Signature Description
Activate Activate<public>(Agent:agent):void Adds the map controller to the provided Agent's map controller stack. If multiple map controllers are active for an agent, the one with the highest Map Priority is used.
Activate Activate<public>():void Adds the map controller to all agents in the experience. If multiple map controllers are active for an agent, the one with the highest Map Priority is used.
Deactivate Deactivate<public>(Agent:agent):void Removes the map controller from the provided Agent's map controller stack. The next highest priority active map controller will be used, or if none exists, the default behavior will be restored.
Deactivate Deactivate<public>():void Removes the map controller from all agents in the experience. The next highest priority active map controller will be used, or if none exists, the default behavior will be restored.
Enable Enable<public>():void Enables the device. Enabling the device will allow it to be activated, both by incoming events, and by trigger if using Activate on Trigger.
Disable Disable<public>():void Disables the device. Disabling the device will deactivate it for all agents in the experience, turn off the trigger functionality, and prevent it from responding to events.
SetCaptureBoxSize SetCaptureBoxSize<public>(Size:float):void Sets the Capture Box Size (in meters). Capture Box Size refers to the length and width of the area used for both the map capture image as well as the activation trigger. Value is clamped between 25.0 and 2500.0 meters.
GetCaptureBoxSize GetCaptureBoxSize<public>()<transacts>:float Returns the Capture Box Size (in meters).

Walkthrough

Let's build an objective-zone map upgrade. The lobby starts on a default map. When a player steps on a trigger plate guarding the objective, we activate a special high-detail map controller just for that player and widen its capture box so they can see the surrounding battlefield. When they step off (a second trigger), we deactivate it and they drop back to the default map.

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

# Gives a player a custom, wide-area map when they enter the objective zone.
objective_map_manager := class(creative_device):

    # The custom map controller to push onto the player's stack.
    @editable
    ObjectiveMap : map_controller_device = map_controller_device{}

    # Trigger the player steps on to ENTER the objective zone.
    @editable
    EnterTrigger : trigger_device = trigger_device{}

    # Trigger the player steps on to LEAVE the objective zone.
    @editable
    ExitTrigger : trigger_device = trigger_device{}

    # How wide (meters) the capture box should be while in the zone.
    @editable
    ZoneCaptureSize : float = 500.0

    OnBegin<override>()<suspends> : void =
        # Make sure the controller can be activated by our calls.
        ObjectiveMap.Enable()
        # Resize the capture box up front so the custom map shows a wide area.
        ObjectiveMap.SetCaptureBoxSize(ZoneCaptureSize)
        # Wire trigger entry/exit to activation/deactivation per-agent.
        EnterTrigger.TriggeredEvent.Subscribe(OnEnterZone)
        ExitTrigger.TriggeredEvent.Subscribe(OnExitZone)

    # Called when a player steps on the entry plate.
    OnEnterZone(Agent : ?agent) : void =
        if (A := Agent?):
            # Push the custom map onto just this player's stack.
            ObjectiveMap.Activate(A)

    # Called when a player steps on the exit plate.
    OnExitZone(Agent : ?agent) : void =
        if (A := Agent?):
            # Pop the custom map; next-highest (or default) takes over.
            ObjectiveMap.Deactivate(A)

Line by line:

  • @editable ObjectiveMap : map_controller_device — the field that points at the placed map controller in the Outliner. Without this @editable field you cannot call its methods at all.
  • EnterTrigger / ExitTrigger are standard trigger_devices whose TriggeredEvent fires when a player overlaps them.
  • In OnBegin, ObjectiveMap.Enable() makes sure the device is allowed to be activated (a disabled controller ignores all calls).
  • ObjectiveMap.SetCaptureBoxSize(ZoneCaptureSize) sets the capture-box width to 500 m. Values are clamped between 25.0 and 2500.0.
  • TriggeredEvent.Subscribe(OnEnterZone) registers our handler. The handler signature is (Agent : ?agent) because the event hands an optional agent.
  • In OnEnterZone we unwrap with if (A := Agent?): then call ObjectiveMap.Activate(A) — the per-agent overload, so only that player's map changes.
  • OnExitZone calls ObjectiveMap.Deactivate(A) to pop the controller back off that player's stack.

Common patterns

Activate for the whole lobby (no agent)

Use the parameterless overloads when a game-wide event should change everyone's map at once — e.g. a storm phase that switches to a tactical overview map.

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

global_map_phase := class(creative_device):

    @editable
    TacticalMap : map_controller_device = map_controller_device{}

    # A button the host presses to start the tactical phase.
    @editable
    PhaseButton : button_device = button_device{}

    OnBegin<override>()<suspends> : void =
        TacticalMap.Enable()
        PhaseButton.InteractedWithEvent.Subscribe(OnPhaseStart)

    OnPhaseStart(Agent : agent) : void =
        # Push the tactical map onto EVERY agent's stack at once.
        TacticalMap.Activate()

Resize the capture box from a slider, then read it back

The capture box controls both the captured map image and the activation trigger size. Here we let a UI slider drive it and confirm the clamped value with GetCaptureBoxSize.

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

map_zoom_tuner := class(creative_device):

    @editable
    ZoomMap : map_controller_device = map_controller_device{}

    # Fires whenever the host commits a new zoom value.
    @editable
    ApplyButton : button_device = button_device{}

    # The desired size to apply (meters).
    @editable
    DesiredSize : float = 1200.0

    OnBegin<override>()<suspends> : void =
        ZoomMap.Enable()
        ApplyButton.InteractedWithEvent.Subscribe(OnApply)

    OnApply(Agent : agent) : void =
        ZoomMap.SetCaptureBoxSize(DesiredSize)
        # Read back the actually-applied (clamped) value.
        Current := ZoomMap.GetCaptureBoxSize()
        # Re-activate so the new capture box takes effect for everyone.
        ZoomMap.Activate()

Disable the device entirely to clear it for everyone

When a special mode ends, Disable() deactivates the controller for all agents in one call and stops it responding to triggers or events — cleaner than deactivating per-agent.

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

map_mode_cleanup := class(creative_device):

    @editable
    SpecialMap : map_controller_device = map_controller_device{}

    # Trigger fired when the special round ends.
    @editable
    RoundEndTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        SpecialMap.Enable()
        SpecialMap.Activate()
        RoundEndTrigger.TriggeredEvent.Subscribe(OnRoundEnd)

    OnRoundEnd(Agent : ?agent) : void =
        # Yank the special map off everyone and stop the device responding.
        SpecialMap.Disable()

Gotchas

  • Disabled means deaf. If the device is Disable()d, Activate calls are ignored. Always Enable() before (or in OnBegin) if you intend to drive it from Verse.
  • Priority decides the winner, not call order. Activating two controllers for the same agent does not stack visually — only the highest Map Priority shows. Set Map Priority in the Details panel; Verse cannot set it.
  • Deactivate pops, it doesn't reset. Deactivate(Agent) removes this controller from that agent's stack; the next-highest active controller (or default) takes over. It does not clear the whole stack — use Disable() to wipe it for everyone.
  • Capture box is clamped. SetCaptureBoxSize clamps to 25.02500.0 meters, so always read back with GetCaptureBoxSize() if you depend on the exact value. Note GetCaptureBoxSize <transacts> but returns a plain float — no [] failure brackets needed.
  • No int↔float auto-convert. SetCaptureBoxSize takes a float; pass 500.0, never 500.
  • There are no events on this device. Don't look for an ActivatedEvent. Subscribe to triggers, volumes, or buttons elsewhere and call the map controller's methods from those handlers.
  • Unwrap the optional agent. Trigger handlers receive (Agent : ?agent); always if (A := Agent?): before passing it to the per-agent Activate/Deactivate.

Device Settings & Options

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

Map Controller Device settings and options panel in the UEFN editor — Map Capture Box Size, Map Capture Box Height, Activate Automatically, Activate on Trigger, Map Priority
Map Controller Device — User Options in the UEFN editor: Map Capture Box Size, Map Capture Box Height, Activate Automatically, Activate on Trigger, Map Priority
⚙️ Settings on this device (5)

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

Map Capture Box Size
Map Capture Box Height
Activate Automatically
Activate on Trigger
Map Priority

Guides & scripts that use map_controller_device

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

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