VerseBuilderDocs

Docs/Game data/Inventories

Inventories

Slot-based per-player containers — backpack, hotbar, crafting grid. Persistent across sessions, stored as a single weak_map. Items are integer IDs + quantity.

Last updated 2026-06-15

What is this?

Each Inventory you declare is stored as a single per-player weak_map (not N×2 individual variables), persisted across disconnects. Every slot holds an ItemId:int and a Qty:int. It's the building block for any gameplay that manages items beyond Fortnite's native loadout.

Inventories are not UEFN Item Granter / Item Remover devices. Those hand or strip Fortnite items in the player's native loadout (atoms grant_item, remove_item); an Inventory tracks your game's items in your own slot storage.

When do I need it?

  • Backpack — a 20-slot grid of collected materials, potions, keys.
  • Hotbar — 5 quick-access slots a HUD widget renders.
  • Crafting grid — fixed slots that feed a recipe matcher.
  • Quest items — 1-slot “quest log” holding the current objective token.

Walkthrough: add a backpack

  1. Open Game Data → Inventories

    The empty state offers the 20-slot backpack pattern as a one-click starter.
  2. Name + slot count

    + Add Inventory. Name it backpack, slot count 20. The slot count is fixed — pick something that fits the UI. The ID also doubles as the HUD prefix for the slot widgets.
  3. Add items via rules

    In a rule: WHEN On Collectible Collected → DO Collect Item to Inventory (backpack, itemId). The Collect action checks for room first, then fills the first matching stack or empty slot; if there's no room it shows a “full” popup instead.
  4. Display on HUD

    In the HUD editor, the Widgets panel shows an Inventory grids section — one click drops a grid bound to backpack. Each slot binds to backpack_N_id / backpack_N_qty (also pickable in any Text/Bar widget's Linked Variable dropdown).

React to inventory state

Inventories are not write-only. Two conditions let rules branch on their contents, and two actions mutate them safely:

  • Inventory Has Item (inventory_has_item) — true when a given item ID is held in any slot.
  • Inventory Is Full (inventory_is_full) — true when no slot is free.
  • Collect Item to Inventory (inventory_collect) — add with a room check + feedback popups.
  • Buy Item (Safe) (inventory_buy) — atomic spend-currency + add-item (no money lost if the bag is full).
  • Reset Inventory Array (reset_inventory) — clear all slots (e.g. on respawn).

💡 Tip

Item IDs are integers. To show a readable name (e.g. “Sword” for ID 1), define an Item Dictionary and call its GetItemName(Id) via the Call Device Function action.

Common patterns

20-slot backpack

Default pattern. Per-player, persistent. Pairs with inventory_collect on collectible events and inventory_buy for shop purchases; gate the shop button with inventory_is_full.

Fixed hotbar

A 5-slot inventory pinned to the HUD. Often pre-filled on On Player Joined with starter items.

Quest log

Single-slot inventory holding the active quest token. Branch with inventory_has_item to check progress; pair with a tracker device.

Gotchas

⚠️ Watch out

Slot count is fixed at compile time. Resizing means changing the Game Data entry — there's no runtime way to grow an inventory mid-play. If you lower it after building a HUD grid, the now-out-of-range slot widgets show 0 (the composer warns you to re-insert the grid).

⚠️ Watch out

Persistent schema is forever. Like Variables, once your island ships with a persistent inventory, removing or renaming it can break old save data. Plan the schema before launch.

📌 Note

Items are integer IDs. Each slot stores an ItemId:int +Qty:int — there is no string ID. Map IDs to display names with an Item Dictionary, and reserve ID 0 for “empty slot”.

What gets generated?

One shared slot class, a persistable container, and a single per-player weak_map — plus index-based helpers inside the device:

# Shared slot type (ItemId is an int; 0 = empty)
inventory_slot := class<final><persistable>:
    ItemId:int = 0
    Qty:int = 0

# Container — class as weak_map value (extensible post-publish)
inventory_store := class<final><persistable>:
    Version:int = 0
    Slots:[]inventory_slot = array{}

# Per-player persistent storage — one weak_map per inventory
var Backpack : weak_map(player, inventory_store) = map{}

# Inside the device — index-based helpers (excerpt)
GetBackpackQty(Player:player, Index:int):int = ...
FindBackpackEmpty(Player:player):int = ...   # first empty slot, or -1 if full
AddItemToBackpack(Player:player, ItemId:int, Qty:int):void = ...

See also