Unreal Engine Integration Guide
This guide covers adding InventoryFramework to an Unreal Engine project using C# (via the .NET runtime bridge or a standalone service process).
Requirements
- Unreal Engine 5.x
- A running InventoryFramework server (see server-configuration.md)
- .NET 8 runtime accessible from the Unreal project (service process or plugin bridge)
Installation
dotnet add package InventoryFramework.UnrealAdapter
Quick start
using InventoryFramework.UnrealAdapter.Models;
using InventoryFramework.UnrealAdapter.Services;
var config = new UnrealInventoryConfiguration
{
ServerAddress = "https://your-server:5001",
ApiKey = "sk-game-your-key",
ActorId = "player-001",
DefaultSourceContainerCapacity = 30,
DefaultTargetContainerCapacity = 30
};
var facade = new UnrealInventoryFacade(config);
await facade.ConnectAsync();
await facade.CreateDefaultInventoryAsync();
Common operations
Grant items (admin)
var result = await facade.GrantItemsAsync(
containerId: facade.CurrentSourceContainerId,
itemDefinitionId: "wood",
quantity: 10);
Transfer between containers
var result = await facade.TransferItemsAsync(
sourceContainerId: facade.CurrentSourceContainerId,
sourceSlotIndex: 0,
targetContainerId: facade.CurrentTargetContainerId,
quantity: 5);
Quick-store (backpack to chest)
var result = await facade.QuickStoreToTargetContainerAsync(
sourceContainerId: facade.CurrentSourceContainerId,
targetContainerId: facade.CurrentTargetContainerId);
Lock / unlock a slot
Locked slots are skipped by quick-store and sort, useful for pinning a favourite item.
await facade.LockSlotAsync(
containerId: facade.CurrentSourceContainerId,
slotIndex: 2,
lockSlot: true);
Split a stack
var result = await facade.SplitStackAsync(
containerId: facade.CurrentSourceContainerId,
sourceSlotIndex: 0,
amount: 5);
Console.WriteLine($"Split into slot {result.DestinationSlotIndex}");
Drop items
var result = await facade.DropItemsAsync(
containerId: facade.CurrentSourceContainerId,
slotIndex: 0,
amount: 3);
if (result.Succeeded)
SpawnWorldPickup(result.DroppedItemDefinitionId, result.DroppedQuantity);
Sort container
// 0 = ByNameAscending, 1 = ByWeightDescending, 2 = ByTagThenName
await facade.SortContainerAsync(facade.CurrentSourceContainerId, sortMode: 0);
Crafting
var preview = await facade.PreviewCraftItemsAsync(
recipeId: "plank_recipe",
sourceContainerId: facade.CurrentSourceContainerId,
targetContainerId: facade.CurrentTargetContainerId,
requestedCraftCount: 2,
requiredStation: "workbench");
if (preview.CanCraftRequestedCount)
{
await facade.CraftItemsAsync(
recipeId: "plank_recipe",
sourceContainerId: facade.CurrentSourceContainerId,
targetContainerId: facade.CurrentTargetContainerId,
craftCount: 2,
allowPartial: false,
requiredStation: "workbench");
}
Reading the snapshot
var snapshot = await facade.RefreshAsync();
foreach (var container in snapshot.Containers)
{
foreach (var slot in container.Slots)
{
if (!slot.IsEmpty)
{
Console.WriteLine(
$"Slot {slot.Index}: {slot.ItemDefinitionId} x{slot.Quantity}" +
(slot.IsLocked ? " [LOCKED]" : "") +
(!string.IsNullOrEmpty(slot.Restriction) ? $" [restricted:{slot.Restriction}]" : ""));
}
}
}
Session Controller
For longer play sessions, UnrealInventorySessionController wraps the facade and maintains a session state object:
var controller = new UnrealInventorySessionController(facade);
await controller.StartSessionAsync();
// controller.State.Snapshot = current inventory
// controller.State.IsConnected = connection health
Error Handling
All operations return a result with Succeeded, ErrorCode, and ErrorMessage:
var result = await facade.GrantItemsAsync(containerId, "wood", 10);
if (!result.Succeeded)
Console.Error.WriteLine($"[{result.ErrorCode}] {result.ErrorMessage}");
Common error codes:
| Code | Meaning |
|---|---|
item_not_found | itemDefinitionId does not exist |
container_not_found | Container ID is not part of this inventory |
inventory_aggregate_not_found | Inventory does not exist |
container_full | No available capacity |
weight_limit_exceeded | Adding items would exceed the container weight limit |
split_stack_failed | Invalid split (empty slot, amount ≥ quantity, no free slot) |
drop_items_failed | Slot is empty |
sort_container_failed | Invalid sort mode |
unauthorized | API key is missing or invalid |