Save Structures & Messaging

All save structs are plain USTRUCTs - data-in / data-out, no CrimsonSaveSystem dependency. Hand the snapshot to whatever save mechanism your project uses.

Save structures

cpp
/** Identifies a currency row robustly across reloads. */
struct FCrimsonInventoryCurrencyKey
{
FSoftObjectPath DataTablePath;
FName RowName;
};
/** Key-value record written by SaveState / LoadState (state fragments and constraints). */
struct FCrimsonInventoryStateData
{
FName Key;
TSubclassOf<UObject> FragmentClass;
int32 IntValue = 0;
float FloatValue = 0.f;
FString StringValue;
FGameplayTag TagValue;
TArray<uint8> BinaryValue;
};
/** One saved inventory entry - includes layout payload. */
struct FCrimsonInventorySaveEntry
{
TSubclassOf<UCrimsonInventoryItemDefinition> ItemDef;
int32 StackCount = 0;
int64 EntryId = 0;
int32 SlotIndex = -1;
FIntPoint GridPosition = FIntPoint(-1, -1);
ECrimsonItemRotation Rotation = ECrimsonItemRotation::None;
int32 LayoutGroupId = 0;
bool bLocked = false;
TMap<FGameplayTag, int32> StatTags;
TMap<FGameplayTag, float> FloatStatTags;
TArray<FCrimsonInventoryStateData> StateFragmentsData;
};
/** One saved runtime-attached constraint. */
struct FCrimsonInventoryConstraintSaveEntry
{
TSubclassOf<UCrimsonInventoryConstraint> ConstraintClass;
TArray<FCrimsonInventoryStateData> SerializedState;
};
/** Full inventory snapshot. Used by both the manager component and (nested) by the routing save. */
struct FCrimsonInventorySaveData
{
TObjectPtr<UCrimsonInventoryLayout> LayoutAsset = nullptr;
int64 NextEntryId = 1;
TArray<FCrimsonInventorySaveEntry> Items;
TArray<FCrimsonInventoryConstraintSaveEntry> ActiveConstraints;
TMap<FGameplayTag, int32> ConstraintTags;
TMap<FGameplayTag, float> ConstraintFloatTags;
TMap<FCrimsonInventoryCurrencyKey, int64> CurrencyAmounts;
};
/** UCrimsonContainerSubsystem snapshot. Key = container tag. */
struct FCrimsonContainerSaveData
{
TMap<FGameplayTag, FCrimsonContainerSaveEntry> Containers;
};
/** UCrimsonInventoryRoutingComponent snapshot - personal containers held on the PC. */
struct FCrimsonRoutingPersonalContainerSave
{
FGameplayTag ContainerTag;
FCrimsonInventorySaveData Inventory;
};
struct FCrimsonInventoryRoutingSaveData
{
TArray<FCrimsonRoutingPersonalContainerSave> PersonalContainers;
};
What goes where
Per-player inventories (player's own bag, equipped pawn, etc.) -> snapshot the manager component on the PlayerState / Pawn via GetSaveData() -> FCrimsonInventorySaveData.

Personal containers (PerPlayer chests) -> snapshot the PC's routing component via Routing->GetSaveData() -> FCrimsonInventoryRoutingSaveData.

Purely-virtual stashes (banks, guild vaults) -> snapshot UCrimsonContainerSubsystem via its GetSaveData() -> FCrimsonContainerSaveData.

Shared world chests (ACrimsonContainerActorBase with Scope = Shared) -> snapshot the actor's InventoryComponent directly with GetSaveData().

PerParty / PerDungeonInstance chests -> snapshot each ACrimsonInstancedInventoryActor from the instance subsystem's keys (GetAllInstanceKeys()); store keyed by FCrimsonContainerInstanceKey.

Message tags & payloads

TagPayload structWhen broadcast
TAG_Crimson_Inventory_Message_StackChangedFCrimsonInventoryChangeMessagePer-item when stack count changes (add, remove, quantity update)
TAG_Crimson_Inventory_Message_InventoryUpdatedFCrimsonInventory_Message_InventoryUpdatedAfter bulk mutations - UI should refresh
TAG_Crimson_Inventory_Message_ConstraintFailureMessageFCrimsonInventoryConstraintFailureMessageConstraint check failed (Client Reliable RPC)
TAG_Crimson_Inventory_Message_ConstraintChangedFCrimsonInventory_Message_ConstraintChangedCapacity changed (Client Reliable RPC)
TAG_Crimson_Inventory_Message_ItemDroppedFCrimsonInventory_Message_ItemDroppedServer: item removed via DropItemByEntry
TAG_Crimson_Inventory_Message_CurrencyDroppedFCrimsonInventory_Message_CurrencyDroppedServer: currency removed via DropCurrency
TAG_Crimson_Inventory_Message_CurrencyChangedFCrimsonInventoryCurrencyChangeMessageCurrency amount changed (Client Reliable RPC)
TAG_Crimson_Container_Message_ChangedFCrimsonContainerChangeMessageContainer contents changed via UCrimsonContainerSubsystem

For the UI <-> server routing layer, see the Routing Component page.