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

Guides & scripts that use hero_chest_device

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

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 →