A modular, network-replicated inventory/container system for Unreal Engine with fragment-based item composition and transaction-driven mutations.
Combee is a comprehensive inventory system plugin designed for multiplayer Unreal Engine projects. It provides a robust framework for managing items in containers with:
- Fragment-Based Composition: Build items from reusable, data-driven components
- Network Replication: Efficient FastArray-based delta serialization for multiplayer
- Transaction System: Client-server validated operations with rollback support
- Extensibility: Blueprint and C++ friendly architecture with preset implementations
Items implement ICombeeItemInterface and are composed of UCombeeFragment components:
// Example: A consumable health potion
UCombeeItem_UNIQUE
βββ UCombeeFragment_Ownership // Tracks container ownership
βββ UCombeeFragment_Stackable // Enables stacking
βββ UCombeeFragment_Usable // Defines use behavior- Item Types:
UCombeeItem_UNIQUE: Instanced items with unique state (weapons, equipment)UCombeeItem_SHARED: Singleton items using CDO (currencies, basic resources)UCombeeItem_LINK: Reference-based items pointing to external objects
UCombeeContainer is an ActorComponent that stores items in replicated cells:
UPROPERTY()
UCombeeContainer* Inventory; // Capacity: 20 slots
// Access cells
const FCombeeCell& Cell = Inventory->GetCell(5, bIsValid);
TScriptInterface<ICombeeItemInterface> Item = Cell.Item;
int32 Stack = Cell.StackCount;- Network Replication: Uses
FCombeeHive(FastArraySerializer) for efficient delta replication - Mutation Callbacks: Throttled delegates for UI updates (batched per-tick on server, immediate on a client)
- Compatibility Checks: Override
CheckItemCompatible()for slot restrictions
Operations are performed through validated transactions:
// Client requests a move operation
UCombeeTransactionSubsystem::Get(this)->RequestTransactionLatent(
PlayerController,
UCombeeTransaction_Move::StaticClass(),
FInstancedStruct::Make<FCombeeTransactionPayload_Move>({
.FromContainer = InventoryA,
.FromIndex = 2,
.TargetContainer = InventoryB,
.TargetIndex = 5
}),
Response // Out parameter
);- Authority Validation: Server executes and validates all transactions
- Hierarchical Execution: Transactions can spawn child transactions
- Bridge Pattern:
ACombeeBridgemanages transaction lifecycle per-controller
| Module | Purpose |
|---|---|
| Combee | Core system: Items, Fragments, Containers, FastArray replication |
| CombeeTransaction | Transaction system: Bridge, operations, subsystem |
| CombeePresets | Common implementations: Ownership, SubItems, Move/Swap/Merge |
| CombeeUse | Item usage system with coroutine support (requires UE5Coro) |
| CombeeSnapshot | Save/load system for containers and items |
| CombeeUI | UI integration helpers and fragments |
| CombeeEditor | Editor tooling and customizations |
// C++ Header
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UCombeeContainer> Inventory;
// Constructor
Inventory = CreateDefaultSubobject<UCombeeContainer>(TEXT("Inventory"));
Inventory->InitialCapacity = 20;
Inventory->HiveReplicateCondition = COND_OwnerOnly;- Create Blueprint class based on
UCombeeItem_UNIQUE - Add fragments in
Fragmentsarray (e.g.,UCombeeFragment_Ownership) - Configure fragment properties in Details panel
// Server-side instantiation
auto* Subsystem = UCombeeSubsystem::Get(*this);
auto Item = Subsystem->Instantiate<UMyItemClass>(InitParams);
// Assign to container
FCombeeCellMutationContext Context;
Context.TargetIndex = 0;
Context.UpcomingInstance = Item;
Context.UpcomingStackCount = 1;
Inventory->AssignCell(Context);// Blueprint example: Move item between containers
UCombeeTransactionSubsystem* TxSystem = UCombeeTransactionSubsystem::Get(WorldContext);
FCombeeTransactionPayload_Move Payload;
Payload.FromContainer = SourceContainer;
Payload.FromIndex = 3;
Payload.TargetContainer = TargetContainer;
Payload.TargetIndex = 7;
TxSystem->RequestTransactionLatent(
PlayerController,
UCombeeTransaction_Move::StaticClass(),
FInstancedStruct::Make(Payload),
Response
);ββββββββββββββββ ββββββββββββββββ
β Client β β Server β
β β β β
β Request TX βββββββRPCββββββββββ>β Validate β
β β β Execute β
β β β Mutate Hive β
β β β β
β Update UI β<ββββFastArrayβββββββ€ Replicate β
β β Delta Sync β β
ββββββββββββββββ ββββββββββββββββ
- Client: Sends transaction requests via
ACombeeBridge::Server_RequestTransaction - Server: Validates, executes, broadcasts delegates, marks FastArray dirty
- Replication:
FCombeeHiveefficiently replicates only changed cells - Client Callbacks:
ReceiveContainerMutationtriggered on replication
UCLASS()
class UMyCustomFragment : public UCombeeFragment
{
GENERATED_BODY()
// Runtime data (replicated)
UPROPERTY(Replicated)
FInstancedStruct Rna; // Use FFMyFragmentRna struct
virtual void OnInitialized_Implementation(const TScriptInterface<ICombeeItemInterface>& Item) override
{
// Setup logic
}
};UCLASS()
class UMyTransaction : public UCombeeTransaction
{
GENERATED_BODY()
virtual void OnExecute_Implementation() override
{
auto Payload = Payload.Get<FMyPayload>();
// Validate
if (!IsValid(Payload.TargetContainer))
{
MARK_TRANSACTION_FAILED_AND_RETURN(false);
}
// Execute logic
// ...
// Spawn child transaction if needed
ProcessTransaction<UCombeeTransaction_Move>(ChildPayload);
}
};// Create snapshot
auto* SnapshotSystem = UCombeeSnapshotSubsystem::Get(WorldContext);
FCombeeContainerSnapshot Snapshot = SnapshotSystem->CreateContainerSnapshot(Container);
// Save to disk (serialize Snapshot to JSON/Binary)
// ...
// Load and apply
SnapshotSystem->ApplyContainerSnapshot(Container, Snapshot);- Unreal Engine: 5.x+
- UE5Coro (Optional): Required for
CombeeUsemodule's coroutine-based usage system - Paper2D (Optional): Used for sprite-based UI fragments
Combee is designed with Blueprint scripting in mind:
- All core functions exposed with
BlueprintCallable/BlueprintPure - Events for lifecycle hooks:
OnInitialized,OnExecute, etc. - Custom events via delegates:
PreCellChange,PostCellChange,ReceiveContainerMutation - Latent transaction execution with automatic response handling
- FastArray Replication: Only changed cells replicate, reducing bandwidth
- Mutation Throttling: Server batches callbacks per-tick to reduce overhead
- Read-Write Locks:
FRWLockprotects concurrent cell access - Subobject Replication: Items use a registered subobject list for stable networking
Copyright 2019-Present tarnishablec. All Rights Reserved.
- Documentation: GitHub Wiki
- Issues: GitHub Issues
- Author: @tarnishablec
Built with β€οΈ for Unreal Engine multiplayer projects