INVENTORY SYSTEM
System Overview
Inventory is a component-based system designed for a multiplayer, multi-world game: items have to survive seamless travel between maps, replicate correctly to every client, and drive both equipment and UI without tightly coupling any of those layers together.
01 | Architecture
Component-Based Ownership
The inventory and quick-bar components live on the PlayerController, where gameplay Blueprints and the UI can reach them through one consistent owner. The PlayerState carries inventory state across travel.
02 | Item Fragments
Composable Item Definitions
Every item is a single ItemDefinition data composed of fragments, modular pieces that each describe one facet of the item. The workhorse is InventoryFragment_UserInterface, which carries the display name, tile image, and everything the inventory grid needs to render an item. Alongside it, Consumables, Key, and Drop fragments define how an item is used, whether it gates progression, and how it behaves when dropped back into the world.
The ItemDefinition also exposes the inventory policy for each item: MaxStackSize and AllowDuplicates. Whether an item stacks, how much, and whether the player can ever hold multiples is authored in the data. The collection abilities read these flags rather than hard-coding rules per item.
03 | World Pickups
Interactables & Collectables
World-side, the system is built on a small class chain: Interactable handles in-game interaction actors (including the world-travel actors), and WorldCollectable derives from it to implement the IPickupable interface, anything the player can take into inventory.
On the Blueprint side, WorldCollectable is the base class that handles Collection and fires GameplayCue notifies, with the cue tag exposed so each child picks its own feedback — Collectable_Health, Collectable_Key, and Collectable_Weapon each trigger their own GCNs without re-implementing any collection logic.
Collection itself runs through two gameplay abilities — Inventory_Item_Collect and Inventory_Weapon_Collect. New items are added to the inventory outright, while duplicates of stackable items increment the stack count instead. Collecting a weapon the player already owns converts the pickup into GiveAmmo for that weapon rather than a second copy.
04 | Loot Drops
Enemy Loot
Enemies feed the inventory loop from the other direction: when an enemy dies, it spawns a replicated loot pickup at the body. The current drop — AmmoPickup — replenishes ammo for every weapon in the player's inventory, keeping the combat loop fed during sustained fights.
The groundwork for authored loot is already in place: a LootDropDefinition struct will drive per-enemy and event-based drop tables — rarer drops from tougher enemies, guaranteed rewards at the end of a wave — as the encounter systems come online.
05 | World Travel
Seamless Travel Persistence
When the server begins seamless travel, the PlayerController captures the player's inventory into the PlayerState before the world tears down. After the new map loads and the controller possesses its pawn, the inventory is restored from that snapshot — so the player walks into the next mission carrying exactly what they left with.
Keeping capture and restore on the controller means the system works with GameFeature-driven worlds: each map's Experience spins up its own runtime systems, and the inventory rides through untouched.
06 | Equipment
Equip Slots & Quick Bar
Equipping an item grants its abilities and input bindings through the Gameplay Ability System, and unequipping cleanly removes them — the inventory never talks to input or animation directly.
07 | Interface
Inventory UI
The inventory screen is a CommonUI activatable widget pushed onto the game's layer stack, with slot states (empty, locked, populated) driven directly by visibility rather than animation playback — so slots always render the true inventory state.
Browsing is organized by tag-driven entry boxes: every item carries a category GameplayTag (Inventory.Item.Category.Consumable, Inventory.Item.Category.Collection), and each entry box filters its own category — a structure that extends to weapon classes (rifles, pistols, shotguns) as the arsenal grows. An InventoryDetails panel reads each item's UserInterface fragment and updates in real time as the player moves across item types.
Consumables get a fast path: hovering one auto-links a Consume action to a dedicated button, so replenishing health is a single press without ever leaving the screen — built on the hold-to-confirm support added to the custom button base class, covered on the UI & Front End page.
Widgets connect to inventory state through ViewModel (MVVM) bindings: ViewModels expose the item data each widget needs, and bound fields update reactively when the inventory changes. The UI never polls or reaches into gameplay code — slots, counts, and item details stay in sync automatically, and widget design stays decoupled from the systems underneath.
The item art is in-house too: tile images exist for every weapon and key, and the RFID keycard was modeled and textured from scratch in Blender and Substance Painter — baked down to a low-poly with packed textures, the same pipeline used for the game's weapon assets.
Input routing handles gamepad and keyboard seamlessly: bound actions surface in the action bar, Back unwinds the modal, and platform-aware input icons update live when the player switches devices. Custom UI sound feedback covers hover, select, equip, and close interactions.
In Development
Per-enemy loot drop tables (RCLootDropDefinition)
End-of-wave & event-based reward drops
Weapon holstering & melee equip flow
Weapon category tags — rifles, pistols, shotguns
Final health kit item art