Reference Devices compiles

item_granter_device: Hand Players the Right Gear at the Right Time

Need a vault that hands out a sword, a vending machine that cycles weapons, or a round-start kit that arms everyone? The item_granter_device is your tool. This guide shows how to grant items, cycle through a set, and react to the granted event from Verse.

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

Overview

The item_granter_device delivers weapons and items into a player's hands. In the editor you fill its Item List with one or more entries (a shotgun, an assault rifle, a bandage), and from Verse you decide when and to whom they're granted.

Reach for it whenever the game needs to give something:

  • A button that grants a sword so the player can break a door.
  • A reward chest that hands out a random weapon each open.
  • A round-start loadout that arms every player at once.
  • A vending machine that cycles forward/back through a weapon menu.

The device exposes three families of behavior:

  1. GrantGrantItem, GrantItemToAll, GrantItemIndex push items to players.
  2. Cycle / selectCycleToNextItem, CycleToPreviousItem, CycleToRandomItem, SetNextItem, GetItemIndex move the "selected" item.
  3. Inventory bookkeepingGetItemGrantCountAtIndex, SetItemGrantCountAtIndex, RestockItems, ClearSaveData manage stock and counts.

And it tells you when a grant happened via ItemGrantedEvent and GrantItemWithCountEvent.

API Reference

item_granter_device

Used to grant items to agents. Items can either be dropped at the agent's location or added directly to their inventory.

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

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

Events (subscribe a handler to react):

Event Signature Description
ItemGrantedEvent ItemGrantedEvent<public>:listenable(agent) Signaled when an item is granted to an agent. Sends the agent that was granted the item.
GrantItemWithCountEvent GrantItemWithCountEvent<public>:listenable(tuple(agent, int)) Signaled when an item is granted to an agent. Sends the agent that was granted the item, as well as the number of items granted.

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.
ClearSaveData ClearSaveData<public>(Agent:agent):void Clears saved data for Agent, preventing them from receiving items while offline. This only works when Grant While Offline is set to Yes.
CycleToNextItem CycleToNextItem<public>(Agent:agent):void Cycles to the next item. If Grant on Cycle is set Agent will be granted the item.
CycleToPreviousItem CycleToPreviousItem<public>(Agent:agent):void Cycles to the previous item. If Grant on Cycle is set Agent will be granted the item.
CycleToRandomItem CycleToRandomItem<public>(Agent:agent):void Cycles to a random item. If Grant on Cycle is set Agent will be granted the item.
GrantItem GrantItem<public>(Agent:agent):void Grants an item to Agent.
GrantItemToAll GrantItemToAll<public>():void Grants an item without requiring an agent reference. This only works when Receiving Players is set to All or Team Index.
GrantItemIndex GrantItemIndex<public>(Agent:agent, ItemIndex:int):void Grants an item at a specific ItemIndex to an Agent. Index should be between 0 and the available item count - 1. If Value is out of bounds, which item is granted is determined by Cycle Behavior.
GrantItemIndex GrantItemIndex<public>(ItemIndex:int):void Grants an item at a specific ItemIndex to all players. Only functions when Receiving Players is set to All or Team Index. Index should be between 0 and the available item count - 1. If Value is out of bounds, which item is grant
GetItemIndex GetItemIndex<public>()<transacts>:int Returns the current Item Index that this device will grant when activated.
GetItemGrantCountAtIndex GetItemGrantCountAtIndex<public>(Index:int)<transacts>:int Returns the number of items this Item Granter will award for the item at the specified Index. This will return 0 if Index is invalid. If Cycle Behavior is Stop, Index is clamped to the number of items in the Item Granter. If *Cycl
SetItemGrantCountAtIndex SetItemGrantCountAtIndex<public>(ItemIndex:int, Count:int):void Sets the number of items this Item Granter will award for the item at the specified ItemIndex. Count must be greater than 0. If Cycle Behavior is Stop, ItemIndex is clamped to the number of items in the Item Granter. If *Cycle Beh
RestockItems RestockItems<public>():void Restocks this device back to its starting inventory count.
SetNextItem SetNextItem<public>(Index:int):void Sets the next item to be granted. * Index should be between 0 and the available item count - 1. * Calling SetNextItem with an invalid index will do nothing.

Walkthrough

Let's build a reward terminal. A trigger (the terminal the player interacts with) grants the player whatever item is currently selected, then immediately cycles to the next item so repeated uses hand out a rotating loadout. We also subscribe to ItemGrantedEvent so we can flash a HUD message, and to GrantItemWithCountEvent so we can read how many were given.

reward_terminal := class(creative_device):

    # The granter you placed and filled with an Item List.
    @editable
    Granter : item_granter_device = item_granter_device{}

    # The trigger the player steps on / interacts with.
    @editable
    UseTrigger : trigger_device = trigger_device{}

    # Optional HUD feedback.
    @editable
    FeedbackHUD : hud_message_device = hud_message_device{}

    # Localized text helper — message params need a localized value, not a raw string.
    Msg<localizes>(S : string) : message = "{S}"

    OnBegin<override>()<suspends> : void =
        # React when the player triggers the terminal.
        UseTrigger.TriggeredEvent.Subscribe(OnUsed)
        # React when ANY item is granted by this device.
        Granter.ItemGrantedEvent.Subscribe(OnItemGranted)
        # React with the count of items granted.
        Granter.GrantItemWithCountEvent.Subscribe(OnItemGrantedWithCount)

    # TriggeredEvent hands us a ?agent — unwrap before using it.
    OnUsed(Agent : ?agent) : void =
        if (Player := Agent?):
            # Grant the currently selected item to this player.
            Granter.GrantItem(Player)
            # Then advance the selection so the next use gives the next item.
            Granter.CycleToNextItem(Player)

    # ItemGrantedEvent gives us the agent directly (listenable(agent)).
    OnItemGranted(Agent : agent) : void =
        # Read which index is now selected after the grant.
        CurrentIndex := Granter.GetItemIndex()
        FeedbackHUD.Show(Agent, Msg("Item granted! Next item index: {CurrentIndex}"))

    # GrantItemWithCountEvent gives us a tuple(agent, int).
    OnItemGrantedWithCount(Payload : tuple(agent, int)) : void =
        Agent := Payload(0)
        Count := Payload(1)
        FeedbackHUD.Show(Agent, Msg("You received {Count} item(s)."))

Line by line:

  • @editable Granter : item_granter_device — you MUST declare the placed device as an editable field, then link it in the Details panel. Calling Granter.GrantItem(...) only works because Granter is a real field.
  • Msg<localizes>(S : string) : message — HUD's Show takes a message (localized text). There is no StringToMessage; this helper wraps a string into a message.
  • In OnBegin we Subscribe three handlers. Subscriptions belong in OnBegin; the handlers themselves are methods at class scope.
  • OnUsed(Agent : ?agent)TriggeredEvent is listenable(?agent), so the parameter is an optional agent. if (Player := Agent?): unwraps it.
  • Granter.GrantItem(Player) grants the selected item; Granter.CycleToNextItem(Player) advances the selection for next time.
  • OnItemGranted(Agent : agent)ItemGrantedEvent is listenable(agent), so the agent arrives already unwrapped. GetItemIndex() returns the current index (it <transacts>, so it's safe to call inline).
  • OnItemGrantedWithCount(Payload : tuple(agent, int)) — read tuple elements with Payload(0) and Payload(1).

Common patterns

Arm everyone at round start with GrantItemToAll

When Receiving Players is set to All (or Team Index), you can grant without an agent reference. Great for round-start loadouts.

round_start_loadout := class(creative_device):

    @editable
    LoadoutGranter : item_granter_device = item_granter_device{}

    # A trigger that fires when the round begins.
    @editable
    RoundStartTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        RoundStartTrigger.TriggeredEvent.Subscribe(OnRoundStart)

    OnRoundStart(Agent : ?agent) : void =
        # No agent needed — grants to all receiving players at once.
        LoadoutGranter.GrantItemToAll()

A vending machine that cycles and grants a specific index

Use CycleToRandomItem for a loot-box feel, or GrantItemIndex to hand out an exact slot.

loot_vending := class(creative_device):

    @editable
    Granter : item_granter_device = item_granter_device{}

    @editable
    RandomButton : button_device = button_device{}

    @editable
    BandageButton : button_device = button_device{}

    OnBegin<override>()<suspends> : void =
        RandomButton.InteractedWithEvent.Subscribe(OnRandom)
        BandageButton.InteractedWithEvent.Subscribe(OnBandage)

    OnRandom(Agent : agent) : void =
        # Pick a random item, then grant whatever is now selected.
        Granter.CycleToRandomItem(Agent)
        Granter.GrantItem(Agent)

    OnBandage(Agent : agent) : void =
        # Always grant the item at index 3 (e.g. a bandage) to this player.
        Granter.GrantItemIndex(Agent, 3)

Restock and adjust grant counts

Granters have a finite starting inventory. Refill it with RestockItems, and tune how many of an item each grant awards with SetItemGrantCountAtIndex / GetItemGrantCountAtIndex.

ammo_resupply := class(creative_device):

    @editable
    AmmoGranter : item_granter_device = item_granter_device{}

    @editable
    ResupplyTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        # Set item 0 to hand out 30 per grant.
        AmmoGranter.SetItemGrantCountAtIndex(0, 30)
        ResupplyTrigger.TriggeredEvent.Subscribe(OnResupply)

    OnResupply(Agent : ?agent) : void =
        if (Player := Agent?):
            # Refill the device to its starting stock.
            AmmoGranter.RestockItems()
            # Read back the configured count (returns 0 if index is invalid).
            CountForSlot0 := AmmoGranter.GetItemGrantCountAtIndex(0)
            # Pre-select item 0 so the next GrantItem uses it.
            AmmoGranter.SetNextItem(0)
            AmmoGranter.GrantItem(Player)

Gotchas

  • Bare device calls fail. item_granter_device.GrantItem(...) is an "Unknown identifier" error. You must declare an @editable field, place + link the device, then call Field.GrantItem(...).
  • GrantItemToAll and the agent-less GrantItemIndex(ItemIndex) need the right setting. They only work when Receiving Players is All or Team Index. With Selected you must pass an agent.
  • Two events, two shapes. ItemGrantedEvent is listenable(agent) — the handler gets (Agent : agent), already unwrapped. GrantItemWithCountEvent is listenable(tuple(agent, int)) — read it with Payload(0) / Payload(1). Don't try to unwrap the agent event with Agent?; it isn't optional.
  • Trigger events ARE optional. TriggeredEvent hands you ?agent, so always if (P := Agent?): before using it.
  • Index bounds matter. GrantItemIndex and SetNextItem expect 0 to (item count − 1). An out-of-range index for GrantItemIndex falls back to your Cycle Behavior; SetNextItem with an invalid index simply does nothing. GetItemGrantCountAtIndex returns 0 for an invalid index.
  • Counts must be positive. SetItemGrantCountAtIndex requires Count > 0.
  • HUD/message params are localized. A message can't take a raw string — wrap it with a <localizes> helper like Msg(...). There is no StringToMessage.
  • ClearSaveData only matters with offline grants. It clears a player's saved pending items and is a no-op unless Grant While Offline is Yes.

Device Settings & Options

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

Item Granter Device settings and options panel in the UEFN editor — On-Grant Action, Grant, Give Extra Ammo, Item List
Item Granter Device — User Options in the UEFN editor: On-Grant Action, Grant, Give Extra Ammo, Item List
⚙️ Settings on this device (4)

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

On-Grant Action
Grant
Give Extra Ammo
Item List

Guides & scripts that use item_granter_device

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

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