Reference Verse compiles

item_granter_device: Loot the Cove

The item_granter_device is your go-to tool whenever a player needs to receive an item — a weapon, a consumable, or a whole loadout — without picking it up off the ground. Drop a player onto a sun-drenched pirate cove, step on a pressure plate, and a flintlock pistol materialises in their hand: that's item_granter_device at work. In this article you'll learn every major method and event on the device, wired up through real Verse code that actually compiles.

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

Overview

The item_granter_device solves a very common island problem: how do I put a specific item into a player's inventory at a specific moment in code? Unlike an Item Spawner (which drops a pickup on the floor), the Item Granter pushes the item directly into the player's inventory — or drops it at their feet, depending on your On Grant Action setting in the device's User Options.

Reach for item_granter_device when you need to:

  • Hand a player a weapon the moment they enter an area (vault door, spawn pad, cove dock).
  • Rotate through a list of items — for example, giving a different weapon each time a player completes a lap.
  • Restock a limited-use granter after a round resets.
  • React to a grant event to update a score or trigger a cinematic.

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.

trigger_device

Used to relay events to other linked devices.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from trigger_base_device.

trigger_device<public> := class<concrete><final>(trigger_base_device):

Events (subscribe a handler to react):

Event Signature Description
TriggeredEvent TriggeredEvent<public>:listenable(?agent) Signaled when an agent triggers this device. Sends the agent that used this device. Returns false if no agent triggered the action (ex: it was triggered through code).

Methods (call these to make the device act):

Method Signature Description
Trigger Trigger<public>(Agent:agent):void Triggers this device with Agent being passed as the agent that triggered the action. Use an agent reference when this device is setup to require one (for instance, you want to trigger the device only with a particular agent.
Trigger Trigger<public>():void Triggers this device, causing it to activate its TriggeredEvent event.
Enable Enable<public>():void Enables this device.
Disable Disable<public>():void Disables this device.
SetMaxTriggerCount SetMaxTriggerCount<public>(MaxCount:int):void Sets the maximum amount of times this device can trigger. * 0 can be used to indicate no limit on trigger count. * MaxCount is clamped between [0,20].
GetMaxTriggerCount GetMaxTriggerCount<public>()<transacts>:int Gets the maximum amount of times this device can trigger. * 0 indicates no limit on trigger count.
GetTriggerCountRemaining GetTriggerCountRemaining<public>()<transacts>:int Returns the number of times that this device can still be triggered before hitting GetMaxTriggerCount. Returns 0 if GetMaxTriggerCount is unlimited.
SetResetDelay SetResetDelay<public>(Time:float):void Sets the time (in seconds) after triggering, before the device can be triggered again (if MaxTrigger count allows).
GetResetDelay GetResetDelay<public>()<transacts>:float Gets the time (in seconds) before the device can be triggered again (if MaxTrigger count allows).
SetTransmitDelay SetTransmitDelay<public>(Time:float):void Sets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered.
GetTransmitDelay GetTransmitDelay<public>()<transacts>:float Gets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered.

player

Full public surface, resolved verbatim from the live Epic digest (Verse.digest.verse). Inherited members are merged from agent.

player<native><public> := class<unique><persistent><module_scoped_var_weak_map_key><epic_internal>(agent):

vector3

3-dimensional vector with float components.

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

vector3<native><public> := struct<concrete><computes><persistable><uht_comparable>:

Walkthrough

Scenario — The Pirate Cove Armoury

Your island is a 2D cel-shaded pirate cove. A rickety dock juts out over turquoise water. When a player steps onto the Armoury Trigger (a trigger_device placed on the dock), they receive the weapon currently selected on the Cove Granter (item_granter_device). After granting, the granter automatically cycles to the next item in its list so the next visitor gets something different. A second trigger — the Restock Trigger — lets the island host restock the granter back to its starting counts at any time.

UEFN setup checklist before writing Verse:

  1. Place one trigger_device on the dock → name it ArmouryTrigger in the Outliner.
  2. Place one item_granter_device near the dock → name it CoveGranter. Add 3 weapons to its Item List (Index 0, 1, 2). Set Grant to Current Item.
  3. Place a second trigger_device somewhere only the host can reach → name it RestockTrigger.
  4. Place your Verse device and wire all three devices to it via @editable fields.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Fortnite.com/Playspaces }

# Localised message helper — item_granter_device.GrantItem takes an agent, not a string,
# but we use this for any future UI work.
GrantedMessage<localizes>(S : string) : message = "{S}"

# cove_armoury_device — wires the dock trigger to the item granter.
# Place this Verse device on your island and assign the three @editable fields
# in the UEFN details panel.
cove_armoury_device := class(creative_device):

    # The trigger on the dock that players step on.
    @editable ArmouryTrigger : trigger_device = trigger_device{}

    # The item granter loaded with pirate weapons.
    @editable CoveGranter : item_granter_device = item_granter_device{}

    # A second trigger the host activates to restock the granter.
    @editable RestockTrigger : trigger_device = trigger_device{}

    # Called once when the game starts.
    OnBegin<override>()<suspends> : void =
        # Subscribe to the dock trigger — fires when a player steps on it.
        ArmouryTrigger.TriggeredEvent.Subscribe(OnDockTriggered)

        # Subscribe to the restock trigger.
        RestockTrigger.TriggeredEvent.Subscribe(OnRestockTriggered)

        # Subscribe to the granter's ItemGrantedEvent so we know when a grant succeeds.
        CoveGranter.ItemGrantedEvent.Subscribe(OnItemGranted)

    # Handler: a player stepped onto the dock.
    # TriggeredEvent sends ?agent, so we must unwrap it.
    OnDockTriggered(MaybeAgent : ?agent) : void =
        if (Agent := MaybeAgent?):
            # Grant the currently selected item to this player.
            CoveGranter.GrantItem(Agent)

            # Cycle to the next weapon so the next visitor gets something different.
            CoveGranter.CycleToNextItem(Agent)

    # Handler: the granter confirmed an item was granted.
    # ItemGrantedEvent sends a plain agent (not optional).
    OnItemGranted(Agent : agent) : void =
        # Log the current item index for debugging — useful during playtesting.
        CurrentIndex := CoveGranter.GetItemIndex()
        # (In a real game you might update a HUD or award XP here.)
        # Note: Verse does not support `_` as an identifier; unused locals are safe to leave.

    # Handler: the host triggered the restock plate.
    OnRestockTriggered(MaybeAgent : ?agent) : void =
        # RestockItems needs no agent — it resets all item counts on the granter.
        CoveGranter.RestockItems()```

### Line-by-line explanation

| Lines | What's happening |
|---|---|
| `@editable ArmouryTrigger` | Exposes the trigger to the UEFN details panel so you can wire up the placed device. Without `@editable` the field is just a default-constructed stub that does nothing. |
| `ArmouryTrigger.TriggeredEvent.Subscribe(OnDockTriggered)` | Registers `OnDockTriggered` as the callback. Every time a player steps on the trigger, Verse calls this method. |
| `OnDockTriggered(MaybeAgent : ?agent)` | `TriggeredEvent` is `listenable(?agent)` — the agent is **optional**. You *must* unwrap it with `if (Agent := MaybeAgent?):` before passing it to `GrantItem`. |
| `CoveGranter.GrantItem(Agent)` | The core call — pushes the current item into the player's inventory. |
| `CoveGranter.CycleToNextItem(Agent)` | Advances the internal index so the next player gets the next weapon in the list. |
| `CoveGranter.ItemGrantedEvent.Subscribe(OnItemGranted)` | `ItemGrantedEvent` is `listenable(agent)`  **not** optional. The handler receives a plain `agent`. |
| `CoveGranter.GetItemIndex()` | Returns the current index as an `int`. Marked `<transacts>` so it's safe to call anywhere. |
| `CoveGranter.RestockItems()` | Resets item counts to their starting values — no agent needed. |

## Common patterns

### Pattern 1 — Grant a specific item by index to every player at round start

You want every pirate on the cove to start with the same weapon (index 0 — the cutlass). Use `GrantItemIndex` with the overload that takes no agent, which broadcasts to all players when **Receiving Players** is set to *All* in the device options.

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

cove_round_start_device := class(creative_device):

    @editable StartGranter : item_granter_device = item_granter_device{}

    OnBegin<override>()<suspends> : void =
        # Wait a moment for all players to spawn before granting.
        Sleep(1.0)
        # Grant item at index 0 (the cutlass) to ALL players at once.
        # Requires 'Receiving Players = All' in the device User Options.
        StartGranter.GrantItemIndex(0)

Pattern 2 — Dynamic grant count: give more ammo to solo players

Before granting, check how many players are alive and boost the ammo count for solo players using SetItemGrantCountAtIndex and GetItemGrantCountAtIndex.

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

cove_solo_bonus_device := class(creative_device):

    @editable SoloGranter : item_granter_device = item_granter_device{}
    @editable BonusTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        BonusTrigger.TriggeredEvent.Subscribe(OnBonusTrigger)

    OnBonusTrigger(MaybeAgent : ?agent) : void =
        if (Agent := MaybeAgent?):
            # Read the current grant count for index 0.
            CurrentCount := SoloGranter.GetItemGrantCountAtIndex(0)

            # If only one player is on the island, double the ammo grant.
            Playspace := GetPlayspace()
            Players := Playspace.GetPlayers()
            if (Players.Length = 1):
                SoloGranter.SetItemGrantCountAtIndex(0, CurrentCount * 2)

            SoloGranter.GrantItem(Agent)

            # Reset count to original after granting.
            SoloGranter.SetItemGrantCountAtIndex(0, CurrentCount)

Pattern 3 — React to GrantItemWithCountEvent for a loot-log

GrantItemWithCountEvent fires with both the agent and the count of items granted — useful for a loot log or achievement tracker. This pattern also shows CycleToRandomItem for a surprise-loot crate on the pirate ship.

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

cove_loot_crate_device := class(creative_device):

    @editable LootGranter : item_granter_device = item_granter_device{}
    @editable CrateTrigger : trigger_device = trigger_device{}

    # Tracks total items granted this session.
    var TotalGranted : int = 0

    OnBegin<override>()<suspends> : void =
        CrateTrigger.TriggeredEvent.Subscribe(OnCrateOpened)
        # GrantItemWithCountEvent sends tuple(agent, int) — count of items granted.
        LootGranter.GrantItemWithCountEvent.Subscribe(OnGrantWithCount)

    OnCrateOpened(MaybeAgent : ?agent) : void =
        if (Agent := MaybeAgent?):
            # Pick a random weapon from the granter's list before granting.
            LootGranter.CycleToRandomItem(Agent)
            LootGranter.GrantItem(Agent)

    # Handler receives a tuple: (agent, int)
    OnGrantWithCount(Payload : tuple(agent, int)) : void =
        (GrantedAgent, Count) := Payload
        set TotalGranted += Count
        # TotalGranted now reflects the running total across all players.
        _ = GrantedAgent  # suppress unused-variable warning

Gotchas

1. TriggeredEvent sends ?agent — always unwrap

trigger_device.TriggeredEvent is listenable(?agent). If you write OnTriggered(Agent : agent) the code will not compile. Always declare the parameter as MaybeAgent : ?agent and unwrap: if (A := MaybeAgent?):. ItemGrantedEvent, by contrast, sends a plain agent — no unwrap needed.

2. GrantItemToAll and GrantItemIndex(ItemIndex:int) require a device setting

The no-agent overloads (GrantItemToAll, GrantItemIndex(int)) only work when the device's Receiving Players option is set to All or Team Index in the UEFN details panel. Calling them with Specific Player selected silently does nothing.

3. CycleToNextItem does NOT grant by default

Calling CycleToNextItem(Agent) only advances the index. If you want the player to receive the item on cycle, enable Grant on Cycle in the device User Options. Otherwise, follow the cycle call with an explicit GrantItem(Agent) call as shown in the Walkthrough.

4. SetItemGrantCountAtIndex requires Count > 0

Passing 0 or a negative number to SetItemGrantCountAtIndex is silently ignored. Always guard with a check before calling.

5. @editable is mandatory for placed devices

Declaring MyGranter : item_granter_device = item_granter_device{} without @editable gives you a default-constructed stub — it exists in code but is not the device you placed on the map. Every device you want to control must be @editable and assigned in the UEFN details panel.

6. message vs string

If you ever pass text to a device method that expects a message (e.g., a HUD device), you cannot pass a raw string literal. Declare a localised helper: MyText<localizes>(S:string):message = "{S}" and call MyText("Hello").

7. GetItemIndex is <transacts> — call it freely

GetItemIndex() is marked <transacts>, meaning it can fail and roll back in theory, but in practice it always succeeds. You can call it inside any expression context without wrapping in if.

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 →