Refactoring My Multiplayer Inventory System (Before It Became a Nightmare)
Let me tell you a story.
Refactoring My Multiplayer Inventory System (Before It Became a Nightmare)

Let me tell you a story.
I was slowly progressing with my game development until I reached a point where I needed to reinforce the survival gameplay loop.
So I started working on a very simple crafting system: the player interacts with a fireplace, adds items as input, and receives a crafted item as output.
Simple enough… right?
Well, somewhere in the middle of implementing it, I realized something:
My inventory system was going to become a nightmare to maintain.
So instead of continuing to stack features on top of bad foundations, I decided to refactor the entire inventory architecture before things got worse.
The Problem
At that moment, I already had an InventoryWidget responsible for:
- holding all inventory slots
- handling UI updates
- managing drag & drop behavior
- …
Current inventory sections:
- Equipment Slots
- Primary Slots (Sling / Rifle)
- Secondary Slots (Holster / Handgun)
- Vest
- Backpack
- Vicinity
And that’s where the problem started.
Too many slot sections. Too much UI logic. Too much responsibility inside a single widget.

The Refactor
To make things more scalable and easier to maintain, I created a dedicated widget for each inventory section:
UInventorySectionSlotsWidget
Now every section (Pocket, Primary, Backpack, etc.) manages its own UI behavior independently.
Meanwhile, the UInventoryComponentActor still owns and manages the actual inventory data.
To organize the inventory state, I introduced a struct that stores items by slot group:
USTRUCT(BlueprintType)
struct FInventorySlots
{
GENERATED_BODY()
UPROPERTY()
TArray<FInventoryItem> Pocket;
UPROPERTY()
TArray<FInventoryItem> Primary;
UPROPERTY()
TArray<FInventoryItem> Secondary;
TArray<FInventoryItem>& GetList(ESlotGroup SearchGroup)
{
switch (SearchGroup)
{
case ESlotGroup::PRIMARY:
return Primary;
case ESlotGroup::SECONDARY:
return Secondary;
default:
return Pocket;
}
}
};
Replication
Since this is a multiplayer survival game, everything is server authoritative.
The inventory struct gets replicated whenever it changes:
UPROPERTY(ReplicatedUsing = OnRep_Items)
FInventorySlots InventoryItems;
Then OnRep_Items broadcasts updates to the base UI widget, which updates each inventory section independently.
void UInventoryComponentActor::OnRep_Items()
{
OnInventoryChanged.Broadcast();
}
#### UserWidget -> UInventoryWidget
void UInventoryWidget::InitInventory(UInventoryComponentActor* InInventory)
{
Inventory = InInventory;
...
if (Inventory)
{
Inventory->OnInventoryChanged.AddDynamic(this, &UInventoryWidget::OnInventoryUpdated);
OnInventoryUpdated(); // Initial refresh
}
...
}
void UInventoryWidget::OnInventoryUpdated()
{
auto PocketItems = Inventory->GetPocketItems();
auto PrimaryItems = Inventory->GetPrimaryItems();
auto SecondaryItems = Inventory->GetSecondaryItems();
if (PocketItems.Num() > 0)
{
PocketSectionWidget->UpdateSlots(PocketItems);
SlingSectionWidget->UpdateSlots(PrimaryItems);
HolsterSectionWidget->UpdateSlots(SecondaryItems);
}
}

Current Progress
This system is still a work in progress, but it already feels much cleaner and easier to scale.
Currently implemented:
- Pickable items that go directly into pockets
- Drag & drop support
- Item dropping
- Item swapping
- Items that restore hunger and thirst through the inventory
A Design Decision I’m Still Thinking About
Originally, my idea was:
- Players must find a sling before equipping rifles in quick slot
1 - Players must find a holster before equipping handguns in quick slot
2
I liked the realism and progression behind it.
But now I’m wondering if this creates unnecessary friction for players.
Maybe a simpler draggable hotbar system would feel better.
Still experimenting and trying to find the right balance between realism and usability.
메타데이터
- post_id
- 600db111f59d
- slug
- refactoring-my-multiplayer-inventory-system-before-it-became-a-nightmare-600db111f59d
- url
- https://medium.com/@indieindian.gamelab/refactoring-my-multiplayer-inventory-system-before-it-became-a-nightmare-600db111f59d
- canonical_url
- https://medium.com/@indieindian.gamelab/refactoring-my-multiplayer-inventory-system-before-it-became-a-nightmare-600db111f59d
- author_url
- https://medium.com/@indieindian.gamelab
- status
- ok
- fetched_at
- 2026-06-09 14:34:10