Reference Verse compiles

Cross-Folder Access: Wiring Devices Across Your Island

UEFN islands grow fast — your Verse files end up in nested folders, but your placed devices live in the scene. Cross-folder access is the pattern that lets any Verse script in any folder reach out and drive a trigger, flash a HUD message, or start a countdown timer, no matter where the `.verse` file lives. Master this and every device on your island becomes a puppet you can pull strings on from anywhere.

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

Overview

When your island grows beyond a single Verse file, you'll naturally split logic into folders — a Dock folder for fishing mechanics, a Cove folder for swimming challenges, a Clifftop folder for the lookout mini-game. The moment one folder needs to reference a type or device declared in another, you hit cross-folder access.

In UEFN, every Verse content folder compiles into its own module. By default, definitions inside that module are internal — invisible outside it. To share a definition across folders you must explicitly widen its access specifier to <public>. Once it's public, any other Verse file in the project can using its module path and reference it directly.

The player_reference_device is the perfect vehicle for this pattern: it holds a single agent reference that any other device on the island can query or react to via AgentUpdatedEvent, ActivatedEvent, and IsReferenced. Pair it with score_manager_device and you have a complete cross-folder reward pipeline — register the player at the dock, award points from the clifftop.

Reach for this pattern when:

  • A player registered in one mini-game zone needs to be recognised in another.
  • You want a central "current VIP player" reference that multiple devices react to.
  • You're splitting a large island into logical Verse modules and need controlled sharing.

API Reference

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

Walkthrough

Scenario: The Sunny Cove Treasure Hunt

A player dives into the cove and touches a treasure prop (trigger). A player_reference_device on the dock registers them as the active treasure-finder. Up on the clifftop, a separate Verse device listens to AgentUpdatedEvent on that same reference device and immediately awards bonus score via score_manager_device. The whole thing plays out under a cel-shaded noon sun with seagulls wheeling overhead.

# File: CoveTreasureManager.verse  (lives in the /Dock/ content folder)
# This device sits on the dock and owns the player_reference_device.
# It registers whoever touches the cove treasure chest.

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

cove_treasure_manager<public> := class(creative_device):

    # The trigger placed on the treasure chest prop in the cove
    @editable
    TreasureTrigger : trigger_device = trigger_device{}

    # The player_reference_device placed on the dock — holds the active finder
    @editable
    FinderReference : player_reference_device = player_reference_device{}

    # Score manager that awards the initial discovery bonus
    @editable
    DiscoveryScorer : score_manager_device = score_manager_device{}

    OnBegin<override>()<suspends> : void =
        # Subscribe to the treasure trigger — fires when a player steps on it
        TreasureTrigger.TriggeredEvent.Subscribe(OnTreasureFound)

        # Also listen for when the reference device confirms a new agent is stored
        FinderReference.AgentUpdatedEvent.Subscribe(OnFinderConfirmed)

    # Called when a player touches the treasure chest trigger
    OnTreasureFound(Agent : agent) : void =
        # Register this player as the active treasure-finder
        FinderReference.Register(Agent)

    # Called once player_reference_device confirms the new agent is stored
    OnFinderConfirmed(Agent : agent) : void =
        # Award the discovery score to the confirmed finder
        DiscoveryScorer.Activate(Agent)
        # Enable the scorer so it can be triggered again if needed
        DiscoveryScorer.Enable(Agent)

Line-by-line breakdown:

Line What it does
@editable TreasureTrigger Wires the in-editor trigger placed on the cove chest prop.
@editable FinderReference Wires the player_reference_device sitting on the dock.
@editable DiscoveryScorer Wires the score manager that gives the discovery bonus.
TreasureTrigger.TriggeredEvent.Subscribe(OnTreasureFound) Subscribes to the trigger's event — fires with the touching agent.
FinderReference.Register(Agent) Stores the agent inside the reference device, broadcasting AgentUpdatedEvent.
FinderReference.AgentUpdatedEvent.Subscribe(OnFinderConfirmed) Reacts to the reference device confirming the new agent.
DiscoveryScorer.Activate(Agent) Awards the configured point value to the confirmed finder.

Now the clifftop device, in a different folder, listens to the same player_reference_device:

# File: ClifftopLookout.verse  (lives in the /Clifftop/ content folder)
# This device is placed on the clifftop and reacts to the dock's reference device.
# It awards a bonus when the registered finder reaches the clifftop trigger.

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

clifftop_lookout<public> := class(creative_device):

    # The SAME player_reference_device wired in the editor — cross-folder access
    # via @editable: no module path needed, the editor resolves the reference.
    @editable
    FinderReference : player_reference_device = player_reference_device{}

    # Trigger at the top of the cliff — player must reach it to claim bonus
    @editable
    ClifftopTrigger : trigger_device = trigger_device{}

    # Score manager for the clifftop bonus
    @editable
    BonusScorer : score_manager_device = score_manager_device{}

    OnBegin<override>()<suspends> : void =
        ClifftopTrigger.TriggeredEvent.Subscribe(OnPlayerReachedClifftop)

    OnPlayerReachedClifftop(Agent : agent) : void =
        # Only award the bonus if this is the registered treasure-finder
        if (FinderReference.IsReferenced[Agent]):
            BonusScorer.Increment(Agent)   # bump the award up by 1
            BonusScorer.Activate(Agent)    # then fire it

Key cross-folder insight: Both cove_treasure_manager and clifftop_lookout hold an @editable field typed player_reference_device. In the UEFN editor you drag the same placed device actor into both fields. The Verse compiler never needs to import one Verse file from another — the editor's property panel is the bridge. This is the canonical cross-folder access pattern for devices.

Common patterns

Pattern 1 — Clearing the reference when the round resets

When a new round starts, clear the stored agent so stale data doesn't persist.

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

round_reset_manager<public> := class(creative_device):

    @editable
    FinderReference : player_reference_device = player_reference_device{}

    @editable
    DiscoveryScorer : score_manager_device = score_manager_device{}

    @editable
    RoundEndTrigger : trigger_device = trigger_device{}

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

    OnRoundEnd(Agent : agent) : void =
        # Wipe the stored agent — next round starts fresh
        FinderReference.Clear()
        # Reset the scorer so its trigger count goes back to zero
        DiscoveryScorer.Reset()

Pattern 2 — Reacting to a failed registration attempt

If the reference device already holds a different player and can't accept a new one, AgentUpdateFailsEvent fires. Use it to give feedback.

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

registration_guard<public> := class(creative_device):

    @editable
    FinderReference : player_reference_device = player_reference_device{}

    # A score manager configured to DEDUCT points (set to negative in editor)
    @editable
    PenaltyScorer : score_manager_device = score_manager_device{}

    @editable
    CoveTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        CoveTrigger.TriggeredEvent.Subscribe(OnAttemptRegister)
        # Subscribe to the failure event — fires if the slot is already taken
        FinderReference.AgentUpdateFailsEvent.Subscribe(OnRegistrationFailed)

    OnAttemptRegister(Agent : agent) : void =
        FinderReference.Register(Agent)

    OnRegistrationFailed(Agent : agent) : void =
        # The agent tried to register but the slot was occupied — apply penalty
        PenaltyScorer.Activate(Agent)

Pattern 3 — Enabling and disabling the scorer per-agent

Some score manager settings are per-agent. Use the agent overloads to gate scoring to only the registered finder.

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

dock_score_gate<public> := class(creative_device):

    @editable
    FinderReference : player_reference_device = player_reference_device{}

    @editable
    DockScorer : score_manager_device = score_manager_device{}

    @editable
    DockTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        # When a new finder is registered, enable scoring only for them
        FinderReference.AgentUpdatedEvent.Subscribe(OnNewFinder)
        DockTrigger.TriggeredEvent.Subscribe(OnDockReached)

    OnNewFinder(Agent : agent) : void =
        # Enable the scorer specifically for the new finder
        DockScorer.Enable(Agent)

    OnDockReached(Agent : agent) : void =
        if (FinderReference.IsReferenced[Agent]):
            # Increment first, then activate for a boosted payout
            DockScorer.Increment(Agent)
            DockScorer.Activate(Agent)
        else:
            # Not the registered finder — disable scoring for this agent
            DockScorer.Disable(Agent)

Gotchas

1. @editable is the cross-folder bridge — not using

You do not write using { /MyProject/Dock/cove_treasure_manager } in the clifftop file to share a device reference. The Verse module system doesn't work that way for placed devices. Instead, both Verse classes expose the same player_reference_device as an @editable field and you drag the same actor into both slots in the UEFN Details panel. The editor resolves the shared reference at runtime.

2. IsReferenced is a deciding expression

FinderReference.IsReferenced[Agent] uses square brackets and can only appear inside an if (or another failable context). Writing FinderReference.IsReferenced(Agent) with parentheses will not compile.

3. AgentUpdatedEvent vs AgentReplacedEvent

  • AgentUpdatedEvent fires whenever the stored agent changes (including the first registration).
  • AgentReplacedEvent fires only when an existing agent is replaced by a new one. If you only want to react to the very first registration, subscribe to AgentUpdatedEvent and check IsReferenced inside the handler.

4. score_manager_device.Reset() has two overloads

Calling DiscoveryScorer.Reset() (no argument) resets the device globally. Calling DiscoveryScorer.Reset(Agent) resets it only for that agent. Use the agent overload when you want per-player resets between rounds without affecting other players' state.

5. Enable/Disable are also overloaded

Both score_manager_device.Enable() and Enable(Agent:agent) exist. The agent overload gates the device for a specific player only — useful when you want the scorer active for the registered finder but inactive for everyone else on the island.

6. Forgetting <public> on shared classes

If you define a helper class in one folder and try to reference it from another, the compiler reports Unknown identifier. Add <public> to the class declaration: my_helper<public> := class(creative_device):. Without it the definition is internal to its module and invisible elsewhere.

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 →