Reference Devices compiles

hero_chest_device: Loot Chests You Control

The `hero_chest_device` is an indestructible loot chest whose locked state, open state, and per-player access you can drive entirely from Verse. Whether you want a vault door that rewards a puzzle solver, a rank-gated chest that only VIPs can open, or a timed loot drop that pops open for everyone at once — this device is your tool.

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

Overview

The hero_chest_device represents an indestructible chest placed on your island. Out of the box it sits there looking pretty, but from Verse you can:

  • Lock and unlock it globally (LockForAll / UnlockForAll) or per-player (Lock / Unlock).
  • Force it open programmatically (Open) — perfect for cinematic reveals or puzzle rewards.
  • React when a player opens it via OpenEvent — great for tracking loot pickups, awarding bonus points, or triggering the next phase of your game.
  • Query its state at any time (IsOpen, IsLocked, IsLockedForAll) to branch your game logic.
  • Read its rank (GetRankAsString) to display flavour text or gate further logic.

Reach for hero_chest_device whenever you need a loot container whose availability is driven by game state rather than static placement settings.

API Reference

hero_chest_device

An indestructible chest that can be locked and unlocked.

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

hero_chest_device<public> := class<concrete><final>(creative_device_base, enableable):

Events (subscribe a handler to react):

Event Signature Description
OpenEvent OpenEvent<public>:listenable(?agent) Triggers whenever the chest is opened, returning the agent who opened it if applicable.

Methods (call these to make the device act):

Method Signature Description
Open Open<public>():void Open the chest.
IsOpen IsOpen<public>()<transacts><decides>:void Succeeds if the chest is currently open, fails if it's closed.
LockForAll LockForAll<public>():void Lock the chest for everyone, and set this chest's default state to Locked.
UnlockForAll UnlockForAll<public>():void Unlock the chest for everyone, and set this chest's default state to Unlocked.
IsLockedForAll IsLockedForAll<public>()<transacts><decides>:void Succeeds if the chest's default locked state is Locked. * The default locked state is initialized by the Start Locked user option and is overridden by LockForAll and UnlockForAll.
Lock Lock<public>(Agent:agent):void Lock the chest for Agent. Has no effect if the chest is open.
Unlock Unlock<public>(Agent:agent):void Unlock the chest for Agent. Has no effect if the chest is open.
IsLocked IsLocked<public>(Agent:agent)<transacts><decides>:void Succeeds if the chest is locked for Agent.
GetRankAsString GetRankAsString<public>():string Returns the chest rank as a string.

Walkthrough

Scenario: A puzzle room with a pressure plate. When a player steps on the plate the vault chest unlocks for that player only, plays a short delay, then pops open for everyone. A UI message announces the chest's rank. Any subsequent opener triggers a bonus-score event.

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

# Localized helper — message params require a <localizes> wrapper
RankMessage<localizes>(S : string) : message = "Chest Rank: {S}"
OpenedMessage<localizes>(S : string) : message = "A player just looted the {S} chest!"

vault_puzzle_device := class(creative_device):

    # The pressure plate players step on to earn access
    @editable
    Plate : trigger_device = trigger_device{}

    # The hero chest sitting behind the vault door
    @editable
    Chest : hero_chest_device = hero_chest_device{}

    # HUD message device to announce the rank
    @editable
    HUD : hud_message_device = hud_message_device{}

    OnBegin<override>()<suspends> : void =
        # Chest starts locked for everyone (set "Start Locked" = true in device options)
        # Subscribe to the plate so we know who solved the puzzle
        Plate.TriggeredEvent.Subscribe(OnPlateTriggered)
        # Subscribe to the chest so we can react whenever it is opened
        Chest.OpenEvent.Subscribe(OnChestOpened)

    # Called when any player steps on the pressure plate
    OnPlateTriggered(MaybeAgent : ?agent) : void =
        if (A := MaybeAgent?):
            # Unlock the chest only for the player who solved the puzzle
            Chest.Unlock(A)
            # Kick off the timed reveal as a concurrent task
            spawn { TimedReveal() }

    # After a short dramatic pause, open the chest for everyone
    TimedReveal()<suspends> : void =
        Sleep(2.0)
        # Announce the rank before popping it open
        RankStr := Chest.GetRankAsString()
        HUD.SetText(RankMessage(RankStr))
        # Open fires the OpenEvent, so OnChestOpened will also run
        Chest.Open()

    # Fires every time the chest is opened (including our forced Open above)
    OnChestOpened(MaybeAgent : ?agent) : void =
        RankStr := Chest.GetRankAsString()
        # Re-lock for everyone after it has been opened once
        Chest.LockForAll()

Line-by-line explanation

Lines What's happening
RankMessage<localizes> Verse message params must come from a <localizes> function — you cannot pass a raw string.
@editable fields Every device reference must be an @editable field; bare identifiers fail to compile.
Plate.TriggeredEvent.Subscribe(OnPlateTriggered) Hooks the plate's event to our handler at game start.
Chest.OpenEvent.Subscribe(OnChestOpened) Hooks the chest's open event — fires whether a player or our code opens it.
if (A := MaybeAgent?) TriggeredEvent delivers ?agent; we must unwrap it before calling Chest.Unlock(A).
Chest.Unlock(A) Unlocks only for the triggering player — everyone else still sees it locked.
spawn { TimedReveal() } Runs the suspending coroutine concurrently so the handler returns immediately.
Chest.GetRankAsString() Returns the rank (e.g. "S") as a plain string we can embed in a localized message.
Chest.Open() Forces the chest open regardless of lock state — also fires OpenEvent.
Chest.LockForAll() Re-locks globally after the reveal so it can't be looted again.

Common patterns

Pattern 1 — Global timed loot drop (UnlockForAll + IsLockedForAll)

Unlock the chest for everyone at the 60-second mark, then re-lock it 30 seconds later if nobody opened it.

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

timed_loot_drop_device := class(creative_device):

    @editable
    Chest : hero_chest_device = hero_chest_device{}

    OnBegin<override>()<suspends> : void =
        # Wait 60 seconds into the match
        Sleep(60.0)
        Chest.UnlockForAll()
        # Give players 30 seconds to grab it
        Sleep(30.0)
        # Only re-lock if nobody opened it yet
        if (Chest.IsOpen[]):
            # Chest is already open — nothing to do
        else:
            # Chest is still closed; re-lock so latecomers can't grab it
            if (not Chest.IsLockedForAll[]):
                Chest.LockForAll()

Note: IsOpen and IsLockedForAll are <decides> functions — call them inside an if expression. They do not return bool.


Pattern 2 — Per-player VIP gate (Lock / Unlock / IsLocked)

Only players on a VIP list (signalled by a separate button device) can open the chest. Everyone else finds it locked.

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

vip_chest_device := class(creative_device):

    @editable
    Chest : hero_chest_device = hero_chest_device{}

    # A button only VIPs can reach (placed behind a barrier, etc.)
    @editable
    VIPButton : button_device = button_device{}

    OnBegin<override>()<suspends> : void =
        # Start locked for everyone (also set Start Locked = true in device options)
        Chest.LockForAll()
        VIPButton.InteractedWithEvent.Subscribe(OnVIPButtonPressed)

    OnVIPButtonPressed(MaybeAgent : ?agent) : void =
        if (A := MaybeAgent?):
            # Check whether this agent is still locked before unlocking
            if (Chest.IsLocked[A]):
                Chest.Unlock(A)

Pattern 3 — React to an open event and display rank (OpenEvent + GetRankAsString)

Every time the chest is opened, broadcast the rank to a HUD message so spectators can see what tier of loot dropped.

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

RankBroadcast<localizes>(R : string) : message = "Loot Rank {R} chest opened!"

rank_announcer_device := class(creative_device):

    @editable
    Chest : hero_chest_device = hero_chest_device{}

    @editable
    HUD : hud_message_device = hud_message_device{}

    OnBegin<override>()<suspends> : void =
        Chest.OpenEvent.Subscribe(OnChestOpened)

    OnChestOpened(MaybeAgent : ?agent) : void =
        Rank := Chest.GetRankAsString()
        HUD.SetText(RankBroadcast(Rank))
        # Optionally show the message to the specific opener
        if (A := MaybeAgent?):
            HUD.Show(A)

Gotchas

1. IsOpen, IsLocked, IsLockedForAll are <decides> — use them in if

These methods do not return a bool. They succeed or fail. Always call them as the condition of an if:

# CORRECT
if (Chest.IsOpen[]):
    ...

# WRONG — does not compile
Result := Chest.IsOpen()  # IsOpen has no return value and requires a decision context

2. Lock(Agent) and Unlock(Agent) have no effect on an already-open chest

If Chest.Open() has already been called (or a player opened it), calling Lock(Agent) silently does nothing. Check IsOpen[] first if you need to guard against this.

3. OpenEvent fires for both player opens and programmatic Open() calls

Don't assume MaybeAgent? will always succeed — when your code calls Chest.Open() directly, the agent payload is false (no agent). Always unwrap with if (A := MaybeAgent?).

4. message params require <localizes> — no raw strings

hud_message_device.SetText takes a message, not a string. You cannot pass GetRankAsString() directly. Wrap it:

RankMsg<localizes>(S : string) : message = "Rank: {S}"
HUD.SetText(RankMsg(Chest.GetRankAsString()))

5. LockForAll sets the default state — it persists across resets

Calling LockForAll() changes the chest's default locked state, meaning a subsequent Reset() will restore it to locked. If you want a chest that resets to unlocked, call UnlockForAll() before or after resetting.

6. Every device reference must be an @editable field

You cannot write hero_chest_device{}.Open() inline. Declare the chest as an @editable field in your class(creative_device) and wire it up in the UEFN Details panel.

Device Settings & Options

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

Hero Chest Device settings and options panel in the UEFN editor — Rank, Start Locked, Enabled at Game Start, Interact Text, Use Default Locked Label, Locked Label, Locked Sublabel, Locked Description
Hero Chest Device — User Options in the UEFN editor: Rank, Start Locked, Enabled at Game Start, Interact Text, Use Default Locked Label, Locked Label, Locked Sublabel, Locked Description
⚙️ Settings on this device (8)

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

Rank
Start Locked
Enabled at Game Start
Interact Text
Use Default Locked Label
Locked Label
Locked Sublabel
Locked Description

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