Reference Devices compiles

conditional_button_device: Gated Interactions That Demand Payment

The `conditional_button_device` is a specialized button that checks an agent's inventory before it fires. Unlike a plain `button_device`, it refuses to activate unless the interacting player is carrying the required key items — making it the go-to device for treasure vaults, crafting benches, toll gates, and any mechanic where players must *earn* the right to press a button. Subscribe to `ActivatedEvent` when the player succeeds, or `NotEnoughItemsEvent` when they come up short, and drive your e

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

Overview

The conditional_button_device solves a classic game-design problem: how do you gate progress behind item collection without writing a custom inventory system? Drop the device into your island, configure one or more key item types in its properties panel, and the device handles the item check automatically. Your Verse code only needs to react to the outcome.

Reach for this device when you need:

  • A vault door that opens only when a player collects three key cards.
  • A crafting station that consumes resources before granting a reward.
  • A boss arena entrance that requires a specific weapon or artifact to enter.
  • A dynamic HUD hint that tells players how many items they still need.

The device exposes two events (ActivatedEvent, NotEnoughItemsEvent) and a rich set of methods for reading and writing item counts, interaction text, interaction time, and item scores — all of which you can drive from Verse at runtime.

API Reference

conditional_button_device

Used to create a specialized button which can only be activated when agents are carrying specific items.

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

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

Events (subscribe a handler to react):

Event Signature Description
ActivatedEvent ActivatedEvent<public>:listenable(agent) Signaled when this device is activated. Sends the agent that activated this device.
NotEnoughItemsEvent NotEnoughItemsEvent<public>:listenable(agent) Signaled when this device fails to activate because agent didn't have the required items. Sends the agent that attempted to activate the device.

Methods (call these to make the device act):

Method Signature Description
Enable Enable<public>():void Enables this device.
Disable Disable<public>():void Disables this device.
Activate Activate<public>(Agent:agent):void Activates this device. Agent is used as the instigator of the action.
Toggle Toggle<public>(Agent:agent):void Toggles the conditional button state. Agent is used as the instigator of the action.
SetInteractionText SetInteractionText<public>(Text:message):void Sets the text that appears when agents approach the device. Text is limited to 150 characters and will revert back to default if empty.
SetInteractionTime SetInteractionTime<public>(Time:float):void Sets the time (in seconds) that an interaction with this device should take to complete.
GetInteractionTime GetInteractionTime<public>()<transacts>:float Returns the time (in seconds) that an interaction with this device will take to complete.
SetItemCountRequired SetItemCountRequired<public>(KeyItemIndex:int, Count:int):void Sets the quantity of a specific key item type that needs to be collected in order to activate the switch. KeyItemIndex ranges from 0 to number of key item types - 1.
GetItemCountRequired GetItemCountRequired<public>(KeyItemIndex:int)<transacts>:int Returns the total quantity of a specific key item type that needs to be collected in order to activate the switch.
GetRemainingItemCountRequired GetRemainingItemCountRequired<public>(KeyItemIndex:int)<transacts>:int Returns the remaining quantity of a specific key item type that needs to be collected in order to activate the switch.
SetItemScore SetItemScore<public>(KeyItemIndex:int, Score:int):void Sets the score to be awarded for a key item. KeyItemIndex ranges from 0 to number of key item types - 1.
GetItemScore GetItemScore<public>(KeyItemIndex:int)<transacts>:int Returns the score to be awarded for a key item.
GetItemCount GetItemCount<public>(Agent:agent, KeyItemIndex:int):int Returns how many items an Agent has of the item stored at KeyItemIndex.
HasAllItems HasAllItems<public>(Agent:agent)<transacts><decides>:void Returns if the Agent has all of the items required to interact with this Device.
IsHoldingItem IsHoldingItem<public>(Agent:agent)<transacts><decides>:void Returns if the Agent is currently holding any of the items stored in the Device.
IsHoldingItem IsHoldingItem<public>(Agent:agent, KeyItemIndex:int)<transacts><decides>:void Returns if the Agent is currently holding the item stored at KeyItemIndex.

button_device

Used to create a button which can trigger other devices when an agent interacts with it.

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

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

Events (subscribe a handler to react):

Event Signature Description
InteractedWithEvent InteractedWithEvent<public>:listenable(agent) Signaled when an agent successfully interacts with the button for GetInteractionTime seconds. Sends the agent that interacted with the button.

Methods (call these to make the device act):

Method Signature Description
Enable Enable<public>():void Enables this device.
Disable Disable<public>():void Disables this device.
SetInteractionText SetInteractionText<public>(Text:message):void Sets the text that displays when an agent is close to this button and looks at it. Text is limited to 64 characters.
SetInteractionTime SetInteractionTime<public>(Time:float):void Sets the duration of the interaction required to activate this device (in seconds).
GetInteractionTime GetInteractionTime<public>()<transacts>:float Returns the duration of the interaction required to activate this device (in seconds).
SetMaxTriggerCount SetMaxTriggerCount<public>(MaxCount:int):void Sets the maximum amount of times this button can be interacted with before it will be disabled. * MaxCount must be between 0 and 10000. * 0 indicates no limit on trigger count.
GetMaxTriggerCount GetMaxTriggerCount<public>()<transacts>:int Returns the maximum amount of times this button can be interacted with before it will be disabled. * GetTriggerMaxCount will be between 0 and 10000. * 0 indicates no limit on trigger count.
GetTriggerCountRemaining GetTriggerCountRemaining<public>()<transacts>:int Returns the number of times that this button can still be interacted with before it will be disabled. Will return 0 if GetMaxTriggerCount is unlimited.

Walkthrough

Scenario: The Crystal Vault

Players roam the island collecting Crystal Shards (key item index 0). When they approach the vault door and interact with the conditional_button_device, one of two things happens:

  1. They have 3 shards → the vault unlocks, a barrier lowers, and they receive a score bonus.
  2. They don't have enough → a hint updates the button text to show exactly how many more shards they need.

Place a conditional_button_device and a barrier_device in the scene, wire them to the Verse device via @editable fields, and set Key Item 0 required count = 3 in the device's properties panel.

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

# Helper to build localized messages at runtime
VaultPrompt<localizes>(S : string) : message = "{S}"

crystal_vault_manager := class(creative_device):

    # The conditional button guarding the vault
    @editable
    VaultButton : conditional_button_device = conditional_button_device{}

    # The barrier that physically blocks the vault entrance
    @editable
    VaultBarrier : barrier_device = barrier_device{}

    # Called once when the game starts
    OnBegin<override>()<suspends> : void =
        # Personalise the interaction prompt and hold time
        VaultButton.SetInteractionText(VaultPrompt("Insert Crystal Shards"))
        VaultButton.SetInteractionTime(1.5)

        # Make sure the vault is sealed at the start
        VaultBarrier.Enable()

        # Subscribe to both outcomes
        VaultButton.ActivatedEvent.Subscribe(OnVaultUnlocked)
        VaultButton.NotEnoughItemsEvent.Subscribe(OnNotEnoughShards)

    # Fires when the player had all required items
    OnVaultUnlocked(Agent : agent) : void =
        # Lower the barrier — the vault is open!
        VaultBarrier.Disable()

        # Disable the button so it can't be used again
        VaultButton.Disable()

        # Award bonus score equal to the configured item score
        # (KeyItemIndex 0 is Crystal Shards)
        var Score : int = VaultButton.GetItemScore(0)

    # Fires when the player tried but didn't have enough shards
    OnNotEnoughShards(Agent : agent) : void =
        # Find out exactly how many more the player needs
        var Remaining : int = VaultButton.GetRemainingItemCountRequired(0)

        # Update the button text with a dynamic hint
        VaultButton.SetInteractionText(
            VaultPrompt("Need {Remaining} more Crystal Shards")
        )

Line-by-line explanation

Lines What's happening
VaultPrompt<localizes> Verse requires message parameters to be localized values. This helper wraps a runtime string into the correct type.
SetInteractionText Overrides the default button label. Limited to 150 characters; passing an empty string reverts to the device default.
SetInteractionTime(1.5) Players must hold the interact key for 1.5 seconds — prevents accidental activation.
VaultBarrier.Enable() Ensures the barrier is up at game start regardless of its default state.
ActivatedEvent.Subscribe Registers OnVaultUnlocked as the success handler. The event sends the agent who activated the button.
NotEnoughItemsEvent.Subscribe Registers OnNotEnoughShards as the failure handler.
GetItemScore(0) Reads the score value configured for key item 0 in the device panel — useful for awarding points.
GetRemainingItemCountRequired(0) Returns how many more of item 0 the player still needs, enabling a precise HUD hint.

Common patterns

Pattern 1 — Runtime item count adjustment and hold-to-pay gate

Sometimes you want the vault to get harder as the game progresses. This snippet raises the required item count after the first activation and re-enables the button for the next wave.

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

ScalingGatePrompt<localizes>(S : string) : message = "{S}"

scaling_gate_device := class(creative_device):

    @editable
    Gate : conditional_button_device = conditional_button_device{}

    # Track how many times the gate has been opened
    var OpenCount : int = 0

    OnBegin<override>()<suspends> : void =
        # Start: require 2 tokens (KeyItemIndex 0)
        Gate.SetItemCountRequired(0, 2)
        Gate.SetInteractionText(ScalingGatePrompt("Pay 2 Tokens to pass"))
        Gate.ActivatedEvent.Subscribe(OnGateOpened)

    OnGateOpened(Agent : agent) : void =
        set OpenCount = OpenCount + 1

        # Each wave costs one more token, up to a cap of 10
        var CurrentRequired : int = Gate.GetItemCountRequired(0)
        var NewRequired : int = CurrentRequired + 1
        if (NewRequired <= 10):
            Gate.SetItemCountRequired(0, NewRequired)
            Gate.SetInteractionText(
                ScalingGatePrompt("Pay {NewRequired} Tokens to pass")
            )

        # Re-enable so the next player can try
        Gate.Enable()

Pattern 2 — Checking inventory before a programmatic activation

Sometimes you want to trigger the button from code (e.g., when a timer expires) but only if the player already has the goods. Use HasAllItems (a <decides> function) to guard the call.

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

TimedVaultPrompt<localizes>(S : string) : message = "{S}"

timed_vault_device := class(creative_device):

    @editable
    VaultButton : conditional_button_device = conditional_button_device{}

    @editable
    CountdownTimer : timer_device = timer_device{}

    OnBegin<override>()<suspends> : void =
        VaultButton.SetInteractionText(TimedVaultPrompt("Claim your reward"))
        CountdownTimer.SuccessEvent.Subscribe(OnTimerExpired)

    # When the countdown ends, try to force-activate for each eligible player
    OnTimerExpired(Agent : agent) : void =
        # HasAllItems<decides> — only activates if the agent has every required item
        if (VaultButton.HasAllItems[Agent]):
            VaultButton.Activate(Agent)

Pattern 3 — Holding-item HUD and per-item inventory inspection

This snippet subscribes to NotEnoughItemsEvent and uses IsHoldingItem plus GetItemCount to give the player a granular status message about which item they're missing.

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

StatusPrompt<localizes>(S : string) : message = "{S}"

inventory_inspector_device := class(creative_device):

    @editable
    CraftingStation : conditional_button_device = conditional_button_device{}

    OnBegin<override>()<suspends> : void =
        CraftingStation.SetInteractionText(StatusPrompt("Craft Item"))
        CraftingStation.NotEnoughItemsEvent.Subscribe(OnCraftFailed)
        CraftingStation.ActivatedEvent.Subscribe(OnCraftSuccess)

    OnCraftFailed(Agent : agent) : void =
        # Check item slot 0 (e.g., Wood) and item slot 1 (e.g., Metal)
        var WoodCount : int = CraftingStation.GetItemCount(Agent, 0)
        var MetalCount : int = CraftingStation.GetItemCount(Agent, 1)
        var WoodNeeded : int = CraftingStation.GetItemCountRequired(0)
        var MetalNeeded : int = CraftingStation.GetItemCountRequired(1)

        # Is the player at least holding the right item type?
        if (CraftingStation.IsHoldingItem[Agent, 0]):
            # They have some wood but not enough
            CraftingStation.SetInteractionText(
                StatusPrompt("Wood: {WoodCount}/{WoodNeeded} — need more!")
            )
        else:
            CraftingStation.SetInteractionText(
                StatusPrompt("You have no Wood at all!")
            )

    OnCraftSuccess(Agent : agent) : void =
        # Re-enable after a short delay for the next craft
        CraftingStation.Disable()
        CraftingStation.Enable()

Gotchas

1. SetInteractionText requires a message, not a raw string

Verse's message type is a localized value — you cannot pass a plain string literal or a string variable directly. Always declare a <localizes> helper:

MyLabel<localizes>(S : string) : message = "{S}"
// then:
Button.SetInteractionText(MyLabel("Open Vault"))

There is no StringToMessage function. Forgetting this causes a compile error.

2. HasAllItems and IsHoldingItem are <decides> functions

These are failable expressions. You must call them inside an if (or another failure context) — calling them as plain statements will not compile:

// CORRECT
if (Button.HasAllItems[Agent]):
    Button.Activate(Agent)

// WRONG  compile error
Button.HasAllItems(Agent)  // missing [] and failure context

3. KeyItemIndex is zero-based and must match the panel configuration

KeyItemIndex runs from 0 to (number of configured key item types − 1). If you call GetItemCount(Agent, 2) but only two key items are configured in the properties panel (indices 0 and 1), the result is undefined. Always keep your Verse index calls in sync with the device panel.

4. int and float do not auto-convert

SetInteractionTime takes a float. Passing an integer literal like 2 will cause a type error. Write 2.0 explicitly:

Button.SetInteractionTime(2.0)  // correct
Button.SetInteractionTime(2)    // compile error

5. NotEnoughItemsEvent fires on every failed attempt

If you update SetInteractionText inside OnNotEnoughShards, be aware it fires every time the player tries and fails — which is usually what you want for a live counter, but can cause rapid repeated calls if the player spam-interacts. Consider debouncing with a var flag if needed.

6. Disabling vs. using Toggle

Disable() makes the button completely non-interactive. Toggle(Agent) flips the button's internal active state (as if the player had activated it) — it does not simply enable/disable the widget. Use Disable()/Enable() for access control and Toggle(Agent) when you want to programmatically simulate an activation cycle.

Device Settings & Options

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

Conditional Button Device settings and options panel in the UEFN editor — Allow Interaction, Interact Time, Color Type, Direct Color, Display Main Icon, Use Alt Display lcon, Alt Display lcon, Key Items Required, Consume Key Items, All Key Items Required at Once, Key Item 1, Key Item 2, Key Item 3
Conditional Button Device — User Options in the UEFN editor: Allow Interaction, Interact Time, Color Type, Direct Color, Display Main Icon, Use Alt Display lcon, Alt Display lcon, Key Items Required, Consume Key Items, All Key Items Required at Once, Key Item 1, Key Item 2, Key Item 3
⚙️ Settings on this device (13)

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

Allow Interaction
Interact Time
Color Type
Direct Color
Display Main Icon
Use Alt Display lcon
Alt Display lcon
Key Items Required
Consume Key Items
All Key Items Required at Once
Key Item 1
Key Item 2
Key Item 3

Guides & scripts that use conditional_button_device

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

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