Overview
The lock_device is the Verse-controllable handle for any UEFN asset that has a door attached (vault doors, gates, cell doors, and more). It does two related-but-separate things:
- Lock state — whether a player is allowed to interact with the door (
Lock,Unlock,ToggleLocked). - Open state — whether the door is physically open or shut right now (
Open,Close,ToggleOpened).
Reach for it whenever the game decides — not the player — when a door should move. Classic uses: a vault that opens when the team captures a zone, a cell that unlocks when a boss is defeated, a gate that closes behind the player after they cross a checkpoint. Every method takes an agent — the instigator of the action — so Fortnite can attribute the open/close to a player for stats, audio, and effects.
The key thing to internalize: lock ≠ closed. A door can be unlocked but still shut (the player must walk up and open it), or locked but open (frozen wide while it's locked). Your code controls both axes independently.
API Reference
lock_device
Used to customize the state and accessibility of doors.
lock_deviceonly works with assets that have a door attached.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
lock_device<public> := class<concrete><final>(creative_device_base):
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Lock |
Lock<public>(Agent:agent):void |
Locks the door. Agent is the instigator of the action. |
Unlock |
Unlock<public>(Agent:agent):void |
Unlocks the door. Agent is the instigator of the action. |
ToggleLocked |
ToggleLocked<public>(Agent:agent):void |
Toggles between Lock and Unlock. Agent is the instigator of the action. |
Open |
Open<public>(Agent:agent):void |
Opens the door. Agent is the instigator of the action. |
Close |
Close<public>(Agent:agent):void |
Closes the door. Agent is the instigator of the action. |
ToggleOpened |
ToggleOpened<public>(Agent:agent):void |
Toggles between Open and Close. Agent is the instigator of the action. |
Walkthrough
Let's build a vault that auto-opens when a player steps on a pressure plate, then locks itself shut again after a few seconds so the next player has to earn it too.
We use a trigger_device (the pressure plate) and a lock_device (the vault door). When the plate fires, we unlock the vault, swing it open, wait 5 seconds, then close and re-lock it.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Log channel so we can watch what the vault is doing in the Output Log.
vault_log := class(log_channel){}
vault_controller := class(creative_device):
Logger:log = log{Channel := vault_log}
# The pressure plate the player steps on.
@editable
Plate:trigger_device = trigger_device{}
# The vault door we open and close. Must be an asset with a door attached.
@editable
Vault:lock_device = lock_device{}
OnBegin<override>()<suspends>:void =
# When the plate fires, run OnPlateStepped with the instigating agent.
Plate.TriggeredEvent.Subscribe(OnPlateStepped)
# TriggeredEvent hands us a ?agent — it may or may not have an instigator.
OnPlateStepped(MaybeAgent:?agent):void =
if (Agent := MaybeAgent?):
Logger.Print("Plate stepped — opening vault")
# Run the open/close sequence as a coroutine so the 5s wait
# doesn't block other events.
spawn{ RunVaultSequence(Agent) }
RunVaultSequence(Agent:agent)<suspends>:void =
# Allow interaction and physically swing the door open.
Vault.Unlock(Agent)
Vault.Open(Agent)
# Hold it open for 5 seconds.
Sleep(5.0)
# Shut it and lock it back down for the next player.
Vault.Close(Agent)
Vault.Lock(Agent)
Logger.Print("Vault re-secured")
Line by line:
vault_log := class(log_channel){}declares a log channel.Logger.Printmessages are prefixed with the channel name in the Output Log — great for debugging which step ran.- The two
@editablefields,PlateandVault, are the bridge to the placed devices. After building Verse, you drag your actual Trigger and Lock devices into these slots in the device's Details panel. Without the@editablefield you cannot call the device's methods — a barelock_device{}literal would do nothing. OnBeginsubscribesOnPlateSteppedto the plate'sTriggeredEvent. Subscribing inOnBeginis the standard wiring spot.TriggeredEventis alistenable(?agent), so our handler receives a?agent. We unwrap it withif (Agent := MaybeAgent?):before using it.- We
spawnthe sequence so theSleep(5.0)runs concurrently — the device stays responsive to other plate steps instead of freezing. - Inside
RunVaultSequencewe call the reallock_devicemethods in order:UnlockthenOpen, wait, thenClosethenLock. Each takes the instigatingAgent.
Common patterns
Toggle a gate open/closed each time a button is pressed
ToggleOpened flips the door between open and closed — perfect for a switch that acts like a light switch for a gate.
using { /Fortnite.com/Devices }
gate_toggle := class(creative_device):
@editable
GateButton:button_device = button_device{}
@editable
Gate:lock_device = lock_device{}
OnBegin<override>()<suspends>:void =
GateButton.InteractedWithEvent.Subscribe(OnButtonPressed)
OnButtonPressed(Agent:agent):void =
# Flip the door: if it's open, close it; if closed, open it.
Gate.ToggleOpened(Agent)
Unlock a vault when the input trigger fires
Use Unlock on its own when you only want to grant access — the player still walks up and opens the door themselves.
using { /Fortnite.com/Devices }
vault_unlocker := class(creative_device):
@editable
FireInput:input_trigger_device = input_trigger_device{}
@editable
Vault:lock_device = lock_device{}
OnBegin<override>()<suspends>:void =
FireInput.PressedEvent.Subscribe(OnInputPressed)
OnInputPressed(Agent:agent):void =
# Just remove the lock; leave the door shut so the player opens it.
Vault.Unlock(Agent)
Slam a door shut and lock it when a player enters a danger zone
Close and Lock together trap the player — a great escape-room beat. We drive it from a volume_device.
using { /Fortnite.com/Devices }
trap_room := class(creative_device):
@editable
DangerZone:volume_device = volume_device{}
@editable
ExitDoor:lock_device = lock_device{}
OnBegin<override>()<suspends>:void =
DangerZone.AgentEntersEvent.Subscribe(OnEntered)
OnEntered(Agent:agent):void =
# Trap them: close the door and lock it so they can't reopen it.
ExitDoor.Close(Agent)
ExitDoor.Lock(Agent)
Gotchas
- The asset MUST have a door.
lock_deviceonly works with assets that have a door attached. If you point it at a plain wall or prop, the methods silently do nothing. - Lock state and open state are independent.
Lockdoes not close the door, andClosedoes not lock it. To fully secure a vault you must call bothCloseandLock. To fully open it for a player you typically call bothUnlockandOpen. - Every method needs an
agent. There is no parameterlessOpen()onlock_device— you must pass the instigator. When the event hands you a?agent(liketrigger_device.TriggeredEvent), unwrap it withif (Agent := MaybeAgent?):before calling. You cannot pass an unwrapped optional directly. - No int/float auto-conversion. When you
Sleep, pass a float literal likeSleep(5.0), notSleep(5). - Don't block on
Sleepin a plain handler. Event handler methods likeOnPlateSteppedare not<suspends>. If you need to wait,spawna<suspends>coroutine (as in the walkthrough) instead of trying toSleepinline. ToggleOpenedvsToggleLocked. It's easy to confuse them —ToggleOpenedflips the physical door,ToggleLockedflips whether players may interact. Pick the one matching the axis you want to change.