toamig.com / Plugins / GearFlow Get on Fab

GearFlow

A fully modular inventory, equipment, and crafting system for Unreal Engine 5. Fragment-based item definitions, tag-driven gear slots, categorized inventory, timed crafting queues, and built-in save serialization, multiplayer-ready out of the box.

v0.1

Overview

GearFlow is a modular inventory, equipment, and crafting framework for Unreal Engine 5. Items are UGearItemDefinition data assets, a small set of flat fields (name, description, icon) plus an opt-in Fragments array. Each fragment owns one concern: stacking lives on UGearStackFragment, equipment slot data on UGearEquipmentFragment, purchase cost on UGearCostFragment, world pickup visuals on UGearPickupFragment, and inventory category on UGearCategoryFragment. An item carries only the fragments it needs.

Three storage components, Inventory, Equipment, and Wallet, extend a shared UGearStorageComponent base that owns the replicated slot array and the full Add/Remove/Query API. Crafting supports both immediate execution and a timed queue. A save library serializes and restores all three component types. A world-facing layer of pickup actors and loot tables covers every item-movement pattern without custom code. GAS is optional.

Fragment System

Item behaviour is composed via opt-in fragments. Shared, Instanced, and InstancedReplicated policies control how fragment data is owned and replicated. Lifecycle hooks fire on equip, unequip, create, and destroy.

Modular Components

Add only what each actor needs. A chest uses Inventory. A player adds Equipment. A shop NPC adds Wallet. Each component is self-contained and independently replicated.

Multiplayer Ready

FastArray replication with delta compression on all storage components. Server-authoritative. Works with Listen and Dedicated servers out of the box. InstancedReplicated fragments replicate per-instance state automatically.

Designer Friendly

All items, recipes, and loot tables are data assets. Designers create and iterate entirely in the Content Browser. Built-in gameplay tags cover equipment slots, item types, and currencies out of the box.

Transfer Model

All item movement, looting, buying, dropping, runs through UGearFunctionLibrary. One unified path, one set of delegates, no custom movement code required in your project.

Crafting System

Data-driven recipes with multi-output support. Instant crafting via UGearCraftingComponent or time-queued crafting via UGearTimedCraftingComponent. Custom validation rules for skill gates and positional grids.

Equipment Slots

Tag-driven named gear slots. UGearEquipmentFragment declares accepted slot types and an array of visual entries, each entry provides an actor class and optional socket override for multi-mesh weapon setups.

Save System

UGearSaveLibrary serializes inventory, equipment, and wallet state to structured save data types. Per-instance save hooks let custom fragments persist their own state alongside the slot data.

GearFlow does not require the Gameplay Ability System. The optional EquipmentRule and CraftingRule objects and custom fragment subclasses are natural GAS extension points, but GAS is entirely optional.

Getting Started

A working inventory is up and running in five steps. The fastest path requires no C++ beyond adding the module dependency.

1

Enable the plugin

In the Unreal Editor, open Edit → Plugins, search for GearFlow, and enable it. Restart the editor when prompted.

2

Add the module dependency

Open your project's Build.cs and add "GearFlow" to PublicDependencyModuleNames. This gives access to all GearFlow C++ headers in your module.

3

Create an Item Definition

Right-click in the Content Browser and select GearFlow → Item Definition. Open the asset and set DisplayName and Icon. Add fragments to the Fragments array as needed, for example, a UGearStackFragment to allow stacking, or a UGearEquipmentFragment to make the item equippable.

4

Add UGearInventoryComponent to your character

In your character Blueprint or C++, add a UGearInventoryComponent and set SlotCount to the number of inventory slots you want. No further setup is required, the component replicates automatically.

5

Add an item

Call AddItem(ItemDefinition, Count) on the component from the server. The item fills existing stacks first for stackable items, then creates new slots. Replication to clients is automatic.

Item Definition

UGearItemDefinition extends UPrimaryDataAsset and is the immutable template for an item type. It is never modified at runtime, all runtime state lives on the UGearItemInstance. A small set of flat fields is present on every item; all optional behaviour is added via the Fragments array.

PropertyTypeDescription
DisplayName FText Shown in inventory UI.
Description FText Tooltip or detail panel text.
Icon TSoftObjectPtr<UTexture2D> Inventory slot icon. Soft reference, loaded on demand, not held in memory when the item is not displayed.
Fragments TArray<UGearItemFragment*> Instanced fragment objects that attach optional behaviour to this item. Absence of a fragment means the item simply does not have that capability.
InstanceClass TSubclassOf<UGearItemInstance> Custom instance class override. Leave unset to use the default UGearItemInstance. Override when you need Blueprint-subclassed instances with per-item state (durability, enchantments).

Fragment access

FunctionDescription
FindFragment<T>() Template accessor returning the first fragment of type T, or nullptr. Use in C++.
FindFragmentByClass(Class) Blueprint-accessible equivalent. Pass the fragment class and cast the result.

Fragments

UGearItemFragment is the base class for all item fragments. Every fragment declares a policy that controls how the fragment is owned and replicated at runtime. Add your own fragment subclasses in Blueprint or C++ to attach custom per-item data without modifying the definition asset itself.

EGearFragmentPolicy

ValueDescription
Shared Fragment data is read directly from the definition asset. No per-instance copy is made. Use for read-only data that all instances share (e.g. display name overrides, category tags).
Instanced A copy of the fragment is made per instance, owned locally on the server. Use for mutable per-instance data that does not need to reach clients (server-only durability tracking).
InstancedReplicated A copy is made per instance and replicated to clients. Use for data that must be visible to clients, ability charges, enchantment level, or any state the UI reads.

Lifecycle hooks

Override these in your fragment subclass to react to item events. All hooks run server-side.

HookWhen it fires
OnCreated(Instance) After the item instance is created and the definition is assigned. Use for one-time initialization, roll random stats, set initial charges.
OnDestroyed(Instance) Before the instance is destroyed (item removed from all storage). Use to clean up side effects or grant replacement items.
OnEquipped(Instance, SlotTag) After the item is placed in a gear slot. Use to apply passive stat modifiers or grant abilities.
OnUnequipped(Instance, SlotTag) After the item is removed from a gear slot. Use to revoke any effects applied by OnEquipped.

Built-in fragment classes

ClassKey PropertyPurpose
UGearStackFragment MaxStackSize: int32 Makes the item stackable. Maximum units per slot. Absence means one unit per slot, each with its own instance.
UGearEquipmentFragment AcceptedSlotTypes: FGameplayTagContainer Makes the item equippable. Declares which slot tags accept this item. Also holds EquippedVisuals, an array of visual entries, each with an actor class and optional socket override for multi-mesh setups.
UGearCostFragment Cost: TMap<FGameplayTag, int32> Attaches a purchase price. Currency tag → amount pairs. Used by TransferItem when a wallet is provided, the transfer fails atomically if the wallet cannot cover all entries.
UGearPickupFragment PickupActorClass, WorldMesh Makes the item droppable. Specifies the pickup actor class (null uses the built-in static mesh pickup) and the mesh to display. Absence means the item cannot be dropped.
UGearCategoryFragment CategoryTag: FGameplayTag Tags the item with an inventory category. Matched against FGearInventoryCategory.ItemTypeFilter to route the item into the correct category slots when added to a categorized inventory.

Custom fragment example

C++
// Declare a replicated, per-instance durability fragment
UCLASS()
class UDurabilityFragment : public UGearItemFragment
{
    GENERATED_BODY()
public:
    UPROPERTY(EditDefaultsOnly)
    float MaxDurability = 100.f;

    UPROPERTY(Replicated)
    float CurrentDurability = 100.f;

    virtual EGearFragmentPolicy GetPolicy() const override
    { return EGearFragmentPolicy::InstancedReplicated; }

    virtual void OnCreated(UGearItemInstance* Instance) override
    { CurrentDurability = MaxDurability; }
};

Item Instance

UGearItemInstance is the runtime handle for an item occupying a slot. It holds a pointer to the immutable definition and the per-instance copies of any Instanced or InstancedReplicated fragments. Stackable items share one instance per slot; non-stackable items get one instance per unit so each can carry individual state. Instances are owned and replicated by the storage component, never construct one manually. Subclass in Blueprint or C++ via the definition's InstanceClass override.

PropertyTypeDescription
Definition UGearItemDefinition* The definition this instance was created from. Replicated.
InstancedFragments TArray<UGearItemFragment*> Per-instance copies of fragments with Instanced or InstancedReplicated policy. Query through FindFragment rather than accessing this array directly.
FunctionReturnsDescription
GetDefinition() UGearItemDefinition* Inline getter for the definition.
IsStackable() bool True when the definition carries a UGearStackFragment.
FindFragment<T>() T* Searches instanced fragments first, then falls back to the definition's shared fragments. Use this in C++ to access fragment data from an instance.
FindFragmentByClass(Class) UGearItemFragment* Blueprint-accessible equivalent of FindFragment<T>.
OnInstanceCreated() Blueprint event Called once after Definition is assigned. Override to initialize per-instance state. Fragment OnCreated hooks fire before this.
GetInstanceSaveData(out TMap<FString,FString>) Blueprint event Return custom key/value pairs for save serialization. Called by UGearSaveLibrary::CaptureInventory.
SetInstanceSaveData(TMap<FString,FString>) Blueprint event Restore custom save data on load. Called by UGearSaveLibrary::RestoreInventory before OnInstanceCreated.

Storage Component

UGearStorageComponent is the abstract base shared by Inventory and Equipment. It owns the replicated slot array (FastArray via FGearContainerSlot) and exposes the full Add/Remove/Query/Move API. All mutating functions are server-authoritative, calling them on a client has no effect.

FGearContainerSlot

FieldTypeDescription
Instance UGearItemInstance* The item instance occupying this slot. nullptr if empty.
Count int32 Stack count for stackable items. Always 1 for non-stackable items.
bStackable bool Whether this slot allows stacking.
MaxStackSize int32 Maximum stack count for this slot.
SlotFilter FGameplayTag Tag filter for this slot. An empty tag accepts any item. Used by equipment slots to restrict item types.

Functions

FunctionDescription
AddItem(Definition, Count)Adds Count units; fills existing stacks first, then new slots. Returns the amount actually added. Server only.
AddItemInstance(Instance)Places a pre-created instance into the first available matching slot. Server only.
RemoveItem(Definition, Count)Removes Count units by item type. Returns false if insufficient. Server only.
RemoveItemInstance(Instance)Removes a specific instance. Server only.
SwapSlots(IndexA, IndexB)Swaps two slots within this component. Server only.
SwapSlotsBetween(IndexA, OtherComponent, IndexB)Swaps a slot in this component with a slot in another component. Server only.
SplitStack(SlotIndex, SplitCount)Splits a stack by moving SplitCount units to the next available empty slot. Server only.
ConsolidateStacks()Merges split stacks of the same item where possible, freeing slots. Server only.
MoveItem(SlotIndex, TargetComponent, TargetSlotIndex)Moves a slot to a specific slot in another (or the same) component. Server only.
GetItemCount(Definition)Returns total units of an item across all slots.
HasItem(Definition, Count)Returns true if at least Count units of the item are present.
CanAddItem(Definition, Count)Returns true if there is room to add Count units without losing any.
GetItemInstance(Definition)Returns the first instance of the given item type, or nullptr.
GetSlots()Returns all slots as an array snapshot. Safe to call on client.
FindAvailableSlotIndex(Definition)Returns the index of the first available slot for the item, or -1 if none.

Delegates

DelegateParametersDescription
OnSlotChanged SlotIndex, FGearContainerSlot Fires on any slot mutation, add, remove, or stack count change. Broadcasts on both server and client after replication. Bind here to keep UI in sync.
OnStorageFull Item, AmountNotAdded Fires when AddItem cannot place all units due to capacity. Use to show an inventory-full notification.

Inventory Component

UGearInventoryComponent extends UGearStorageComponent and acts as the player bag, chest, or loot container. Slots can be configured uniformly or split into named categories, each category owns a fixed slice of the slot array and accepts only items whose UGearCategoryFragment tag matches the category's ItemTypeFilter.

Properties

PropertyTypeDescription
SlotCount int32 Total number of slots when not using categories. Ignored if Categories is populated.
bDefaultStackable bool Default stacking behaviour applied to all slots unless overridden per-slot or per-category.
DefaultMaxStackSize int32 Default max stack count when bDefaultStackable is true.
SlotFilters TArray<FGameplayTag> Per-slot tag filters, index-matched to the slot array. Slots without an entry use an empty filter (accepts anything).
Categories TArray<FGearInventoryCategory> Defines named category groups. When populated, the inventory is divided into category-owned slot ranges instead of using SlotCount.

FGearInventoryCategory

Each entry in the Categories array defines a named slot group. The total inventory slot count is the sum of all category SlotCount values.

FieldTypeDescription
CategoryTag FGameplayTag Unique identifier for this category. Used as the key in GetSlotsByCategory.
DisplayName FText UI display name for this category tab or section.
Icon TSoftObjectPtr<UTexture2D> Icon for this category's UI tab.
SlotCount int32 Number of slots in this category's range.
ItemTypeFilter FGameplayTag Matched against the item's UGearCategoryFragment.CategoryTag. Only matching items can enter this category's slots.
bAcceptsUncategorized bool When true, items without a UGearCategoryFragment can spill into this category. Useful as a catch-all "Misc" category.
bDefaultStackable bool Stacking behaviour applied to all slots in this category, overriding the component-level default.
DefaultMaxStackSize int32 Max stack size for slots in this category.

Category functions

FunctionDescription
GetSlotsByCategory(CategoryTag)Returns the slot indices belonging to the given category. Use to drive per-category UI panels.
ResizeInventory(NewSlotCount)Resizes the total slot count at runtime. New slots are empty; items are not moved. Existing items beyond NewSlotCount overflow via the OnStorageFull delegate path. Server only.
ResizeCategory(CategoryTag, NewSlotCount)Resizes a single category's slot range at runtime. Server only.

Equipment Component

UGearEquipmentComponent extends UGearStorageComponent and manages named gear slots, one item per slot, identified by Gameplay Tag. Only items carrying a UGearEquipmentFragment can be equipped; the fragment's AcceptedSlotTypes must overlap with the target slot tag. When an item is equipped, the component iterates the fragment's EquippedVisuals array and spawns each visual actor server-side, attaching it to the specified socket on VisualAttachTarget. All visual actors replicate to clients. Unequipping destroys them.

Properties

PropertyTypeDescription
EquipmentSlotDefinitions TArray<FGameplayTag> The set of valid slot tags recognized by this component (e.g. GearFlow.Slot.MainHand). Only listed tags can receive items.
VisualAttachTarget USceneComponent* Component to attach visual actors to, typically the character's skeletal mesh.
SlotAttachSockets TMap<FGameplayTag, FName> Maps slot tag to socket name on VisualAttachTarget. If a slot has no entry, visuals attach at the component root.
EquipmentRule UGearEquipmentRule* Optional custom validation object. Default validation is tag matching only. Subclass UGearEquipmentRule and override ValidateEquip() to add level requirements, class restrictions, or other conditions.

Functions

FunctionDescription
EquipItem(Definition, SlotTag)Creates a new instance from the definition and equips it to the slot. Unequips the current occupant first if needed. Server only.
UnequipSlot(SlotTag)Removes the item from the slot. Does not destroy the instance. Server only.
UnequipItem(Definition)Finds and unequips the first slot holding this item type. Server only.
GetItemInSlot(SlotTag)Returns the UGearItemDefinition* in that slot, or nullptr if empty.
GetItemInstanceInSlot(SlotTag)Returns the UGearItemInstance* in that slot, or nullptr.
IsSlotOccupied(SlotTag)Returns true if the slot has an item.

Delegates

DelegateParametersDescription
OnItemEquipped SlotTag, Instance Fires after equip replication reaches clients. Safe to use for UI and VFX responses.
OnItemUnequipped SlotTag, OldInstance Fires after unequip replication reaches clients.
OnVisualSpawned SlotTag, SpawnedActor Fires on the server when a visual actor is spawned for a slot. Use to call setup functions on the visual actor before clients receive it.
GearFlow ships built-in tags for common slots: GearFlow.Slot.MainHand, GearFlow.Slot.OffHand, GearFlow.Slot.Head, GearFlow.Slot.Chest, GearFlow.Slot.Legs, GearFlow.Slot.Feet, GearFlow.Slot.Hands, GearFlow.Slot.Ring, GearFlow.Slot.Neck, GearFlow.Slot.Back. Define your own in your project's gameplay tags for custom slots.

Wallet Component

UGearWalletComponent is a tag-keyed currency store with FastArray replication. Any number of currency types are supported, each identified by a Gameplay Tag. Multi-currency cost checks and atomic payment are first-class, CanAfford and PayCost operate on a whole cost map, making vendor transactions and recipe costs a single call. GearFlow ships built-in currency tags: GearFlow.Currency.Gold, GearFlow.Currency.Silver, and GearFlow.Currency.Premium.

FunctionDescription
AddCurrency(CurrencyTag, Amount)Adds Amount to the given currency. Server only.
RemoveCurrency(CurrencyTag, Amount)Removes Amount. Returns false if insufficient. Server only.
HasCurrency(CurrencyTag, Amount)Returns true if at least Amount is present for that tag.
GetCurrency(CurrencyTag)Returns current balance, or 0 if the tag has never been added.
CanAfford(TMap<FGameplayTag,int32>)Returns true if all entries in the cost map can be met simultaneously.
PayCost(TMap<FGameplayTag,int32>)Deducts all entries atomically. Returns false and applies no change if any single entry is insufficient. Server only.
GetCurrencies()Returns all currency entries as a snapshot array.
ClearAllCurrencies()Removes all currencies. Server only.
DelegateParametersDescription
OnCurrencyChanged CurrencyTag, NewAmount Fires on client after replication. Use to refresh currency UI without polling.

Crafting Component

GearFlow provides two crafting components. UGearCraftingComponent executes recipes immediately, ingredients are consumed and outputs are delivered in the same frame. UGearTimedCraftingComponent extends it with a queued model: each craft takes CraftingTime seconds, multiple crafts can be queued up to MaxQueueSize, and progress is queryable at any time. Both components can be placed on a player character or a workbench actor, the caller supplies the source and output storage, so the component is agnostic about where items come from and go.

UGearCraftingComponent

Property / FunctionDescription
AvailableRecipesThe set of recipes this component knows. Replicated to the owner only.
CraftingRuleOptional validation object. Subclass UGearCraftingRule and override ValidateRecipe() for skill gates, positional grids, or other conditions.
Craft(Recipe, SourceStorage, OutputStorage)Validates via CanCraft, removes ingredients from SourceStorage, and delivers outputs to OutputStorage. Server only.
CanCraft(Recipe, SourceStorage)Returns true if all ingredients can be satisfied without consuming anything.
GetAvailableRecipes()Returns all known recipes.
GetCraftableRecipes(SourceStorage)Returns the subset of known recipes that pass CanCraft.
AddRecipe(Recipe)Adds a recipe at runtime, use for discovery systems. Replicated to owner.
RemoveRecipe(Recipe)Removes a known recipe. Replicated to owner.
DelegateDescription
OnCraftingCompleted(Recipe)Fires on the server after a successful craft.
OnCraftingFailed(Recipe)Fires when CanCraft returns false. Use to communicate the specific failure reason.

UGearTimedCraftingComponent

Drop-in replacement for UGearCraftingComponent. Adds a time-based crafting queue. The CraftingTime field on each recipe asset controls how long each craft takes.

Property / FunctionDescription
MaxQueueSizeMaximum number of crafts that can be queued simultaneously. Additional StartCraft calls are rejected if the queue is full.
StartCraft(Recipe, SourceStorage, OutputStorage)Validates and enqueues the craft. Ingredients are consumed immediately on enqueue. Server only.
CancelCraft(QueueIndex)Removes the craft at the given queue position. Ingredients are refunded to SourceStorage if they can fit. Server only.
GetCraftingProgress()Returns 0.0–1.0 progress of the currently active craft. Safe to call on client.
GetCraftingQueue()Returns the current queue as an array of recipe references. Safe to call on client.
DelegateDescription
OnCraftingStarted(Recipe)Fires when a queued craft begins its timer.
OnCraftingProgress(Recipe, Progress)Fires periodically while a craft is in progress. Use to drive a crafting progress bar.
OnCraftingCancelled(Recipe)Fires when a craft is cancelled via CancelCraft.
OnCraftingQueueChanged()Fires whenever the queue is modified, enqueue, dequeue, or cancel. Use to refresh the queue UI.
C++
// Start a timed craft on the server
TimedCraftingComp->StartCraft(SwordRecipe, PlayerInventory, PlayerInventory);

// Bind progress for UI (safe on client after replication)
TimedCraftingComp->OnCraftingProgress.AddDynamic(this, &AMyHUD::OnCraftProgress);

// Poll progress directly if needed
float Progress = TimedCraftingComp->GetCraftingProgress();

Recipes

A UGearCraftingRecipeDataAsset declares what is consumed, what is produced, and how long it takes. Items are referenced by direct UGearItemDefinition pointer, not by tag, so renaming or moving assets never breaks recipe references. Multiple outputs allow byproduct modelling (e.g. smelting ore yields ingots and slag).

PropertyTypeDescription
Inputs TArray<FGearCraftingIngredient> Required items. Each entry holds a definition reference and a required quantity.
Outputs TArray<FGearCraftingOutput> Produced items. Each entry holds a definition reference and a quantity to add. Multiple entries enable byproduct drops.
CraftingTime float Duration in seconds for UGearTimedCraftingComponent. Ignored by the instant UGearCraftingComponent.
Custom validation logic lives in UGearCraftingRule, subclass it and override ValidateRecipe() to return false under any custom condition. Assign the instance to UGearCraftingComponent.CraftingRule. The rule is checked by both CanCraft and Craft.

Loot Tables

UGearLootTableDataAsset is a weighted pool for procedural inventory population. Define a set of entries each with a weight and quantity range, then call UGearFunctionLibrary::PopulateFromLootTable to roll the table and add results directly to a storage component, useful for chest contents, enemy drops, and random shop stock.

PropertyTypeDescription
Entries TArray<FGearLootEntry> Each entry holds: Item (UGearItemDefinition*), Weight (float), MinQuantity (int32), MaxQuantity (int32). Higher weight increases the chance of selection on each roll.
RollCount int32 Number of independent rolls performed when the table is evaluated. The same entry can be selected multiple times.

World Pickups

AGearPickupActor is the world-space item representation. The actor class and world mesh are configured per item via UGearPickupFragment. The built-in AGearStaticMeshPickupActor loads and applies the fragment's mesh asynchronously; subclass AGearPickupActor for custom visuals or interaction. Spawn pickups via UGearFunctionLibrary::DropItem, pre-placed pickups call InitializePickup at BeginPlay.

Properties

PropertyTypeDescription
ItemInstance UGearItemInstance* The item this pickup represents. Replicated so clients can display the correct icon before picking up.
Quantity int32 Units of the item this pickup contains.
bAutoPickup bool When true, automatically calls Pickup when a UGearStorageComponent overlaps the sphere.
PickupRadius float Radius of the overlap sphere used for auto-pickup detection.
LifetimeMode EGearPickupLifetime Persistent never expires. Timed destroys after LifetimeDuration seconds. ProjectDefined delegates expiry to your project code.
LifetimeDuration float Seconds before the pickup expires when LifetimeMode is Timed.

Functions

FunctionDescription
InitializePickup(Definition, Count)Creates a new instance from the definition. Use for fresh drops with no prior instance state.
InitializePickupFromInstance(Instance, Count)Uses a pre-created instance, preserves per-instance state (durability, enchantments) when dropping equipped items.
Pickup(Instigator)Adds the item to the first UGearStorageComponent found on the Instigator actor. Destroys the pickup actor on success.
OnVisualSetup()Blueprint-overridable event called after ItemInstance is set. Override to configure custom visuals or VFX on the pickup actor.

Delegates

DelegateParametersDescription
OnPickedUp PickupActor, Instigator Fires when the item is successfully added to the instigator's storage. Use to play pickup SFX or show a notification.
OnLifetimeExpired PickupActor Fires when the Timed lifetime elapses before pickup. Use to play a despawn effect.

Item Transfer

UGearFunctionLibrary is the static utility layer for all cross-component item movement and world population. Every transfer pattern in GearFlow, looting a chest, buying from a vendor, dropping an item, populating a loot chest, runs through one of these functions. The unified model means OnSlotChanged delegates fire normally on both endpoints.

C++
// Loot a chest into player inventory
UGearFunctionLibrary::TransferItem(ChestInventory, PlayerInventory, Item, Count);

// Buy from vendor (deducts Cost from wallet atomically)
UGearFunctionLibrary::TransferItem(VendorInventory, PlayerInventory, Item, 1, PlayerWallet);

// Drop item to world at a given transform
UGearFunctionLibrary::DropItem(WorldContext, PlayerInventory, Item, 1, DropTransform);

// Populate a chest from a loot table
UGearFunctionLibrary::PopulateFromLootTable(ChestInventory, LootTable);
FunctionDescription
TransferItem(From, To, Item, Count, Wallet) Moves Count units from From to To. If Wallet is provided and the item carries a UGearCostFragment, deducts the cost map first, the entire transfer fails atomically if the wallet cannot cover all currencies. Server only.
PopulateFromLootTable(Storage, LootTable) Rolls the loot table and adds results to Storage. Returns the number of items actually added (may be less than RollCount if the storage is nearly full).
DropItem(WorldContext, Storage, Item, Count, Transform) Removes the item from Storage and spawns a pickup actor at Transform. The actor class is determined by the item's UGearPickupFragment. Returns nullptr if the item has no pickup fragment. Server only.
DropItemInstance(WorldContext, Storage, Instance, Transform) Drops a specific instance, preserves per-instance state (durability, enchantments) on the spawned pickup actor. Server only.

Save System

UGearSaveLibrary provides static capture and restore functions for all three storage components. Capture functions extract the current component state into a structured save data type that you write to your project's save game object. Restore functions rebuild the component from that saved state, including per-instance custom data via the GetInstanceSaveData / SetInstanceSaveData hooks on UGearItemInstance.

UGearSaveLibrary functions

FunctionSave data typeDescription
CaptureInventory(Component, out SaveData) FGearInventorySaveData Serializes the inventory to an array of slot saves, each with slot index, item ID, count, and custom instance data.
RestoreInventory(Component, SaveData) FGearInventorySaveData Rebuilds each slot from the saved state. Calls SetInstanceSaveData on each instance before OnInstanceCreated.
CaptureEquipment(Component, out SaveData) FGearEquipmentSaveData Serializes equipped items keyed by slot tag, including custom instance data.
RestoreEquipment(Component, SaveData) FGearEquipmentSaveData Re-equips saved items into their recorded slots and restores instance data.
CaptureWallet(Component, out SaveData) FGearWalletSaveData Serializes currency tag + amount pairs.
RestoreWallet(Component, SaveData) FGearWalletSaveData Restores all currency balances from saved entries.
C++
// On save, in your SaveGame object population
UGearSaveLibrary::CaptureInventory(InventoryComp, MySaveGame->InventoryData);
UGearSaveLibrary::CaptureEquipment(EquipmentComp, MySaveGame->EquipmentData);
UGearSaveLibrary::CaptureWallet(WalletComp, MySaveGame->WalletData);

// On load, after the SaveGame object is read back
UGearSaveLibrary::RestoreInventory(InventoryComp, MySaveGame->InventoryData);
UGearSaveLibrary::RestoreEquipment(EquipmentComp, MySaveGame->EquipmentData);
UGearSaveLibrary::RestoreWallet(WalletComp, MySaveGame->WalletData);

Debug Tools

GearFlow registers a UGearCheatExtension (a UCheatManagerExtension subclass) automatically at module startup. The cheat commands are available in any build that has the CheatManager enabled, no manual setup required.

CommandDescription
GearGive <ItemName> [Count] Adds the named item to the local player's first UGearInventoryComponent. Count defaults to 1.
GearClear Clears all items from the local player's inventory.
GearPrintInventory Logs all occupied inventory slots to the output log and on-screen debug area.
GearGiveCurrency <Tag> <Amount> Adds the specified amount of the given currency tag to the local player's wallet.
Misconfiguration errors, such as equipping an item with no UGearEquipmentFragment, or calling mutating functions from a client, produce on-screen debug messages in non-Shipping builds via the GEARFLOW_LOG_WARNING and GEARFLOW_LOG_ERROR macros.

Replication

All three storage components, Inventory, Equipment, and Wallet, use FastArray replication with delta compression. Only changed slot entries are transmitted per frame; a 100-slot inventory that receives one item sends roughly 20–30 bytes, not a full snapshot. The model is server-authoritative: all mutating functions must originate on the server, client-side calls are silently ignored. The recommended pattern is: client sends a Server RPC → server validates and mutates → FastArray replicates the delta → delegates fire on client with the new state.

Delta Compression

FastArray sends only the slot entries that changed since the last ACK. Full snapshots are never retransmitted after the initial connection sync.

Server Authoritative

Inventory state lives on the server. Clients receive replicated copies. No client can forge an item grant or craft result.

Visual Replication

Equipment visual actors are spawned server-side and replicated to all clients, so every player sees the correct visuals without extra RPC code. Multi-mesh items spawn all visual actors simultaneously.

InstancedReplicated Fragments

Fragment data with the InstancedReplicated policy is replicated per instance via the storage component's FastArray, so per-item state (charges, durability) reaches clients automatically.

Delegates on Client

OnSlotChanged, OnItemEquipped, and OnCurrencyChanged all fire on the client after replication, making UI bindings straightforward with no polling.

Timed Crafting Queue

The crafting queue and progress are replicated to the owning client. OnCraftingProgress fires on the client during the craft timer, enabling live progress bar updates without additional RPCs.