← Back to list

Refactoring My Multiplayer Inventory System (Before It Became a Nightmare)

Let me tell you a story.

Indie Indian · 2026-05-24 03:16 · 2 claps · 2.4 min read
#game-development #software-architecture #unreal-engine-5 #indie-game-development #game-design
Open on Medium ↗
Wiki topics: 💻 · Programming 🎮 · Gaming 🏛️ · Architecture

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)
  • Pocket
  • 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