CrimsonInventory

Layout-agnostic inventory system. Topology (flat slots, 2D grid, weight-ordered list, bag-of-bags, ...) is selected by assigning a UCrimsonInventoryLayout data asset. Caps and rules live in a runtime-mutable UCrimsonInventoryConstraint array on the component. Items are described by UCrimsonInventoryItemDefinition assets composed of UCrimsonInventoryItemFragment extensions; live items are UCrimsonInventoryItemInstance replicated subobjects of UCrimsonInventoryManagerComponent.

Also included: per-component currency, async pickup nodes with partial-success handling, ACrimsonContainerActorBase for world chests with four ownership scopes (Shared / PerPlayer / PerParty / PerDungeonInstance), UCrimsonContainerSubsystem for purely-virtual stashes (banks/account vaults), and a crafting station base class. UI <-> server routing is centralized in UCrimsonInventoryRoutingComponent on the PlayerController - projects no longer write Server_ RPCs for inventory operations.

Design decisions

Layout = topology only. Layouts never store caps or rules. A flat layout with weight, a grid layout with typed cells, a weight layout with per-type item count caps - all of these are configurations of the same component, composed from the constraint stack at runtime.

Constraints are first-class and runtime-mutable. Add a constraint when the player equips a bag, remove it when unequipping. Bumping the slot cap by +10 and weight cap by +50 when picking up a Backpack item is a two-line operation: ModifyIntConstraintValue(Slots, +10) and ModifyFloatConstraintValue(Weight, +50). Both replicate automatically.

Stable EntryId. Every entry has a server-assigned int64 EntryId that stays stable across FastArray reorders. UI binding, RPCs, and layout caches all key off EntryId, not slot index.

No CrimsonSaveSystem dependency. Save data is exposed as plain structs: FCrimsonInventorySaveData (layout asset, items, runtime constraints, tag-stack caps, currencies) and FCrimsonContainerSaveData. Wire these into whatever save system the game project uses.

No CrimsonInteraction or CrimsonEquipment dependency. World containers and crafting stations implement ICrimsonInteractableTarget from CrimsonCommon. Equipment integration uses ICrimsonAbilitySystemOwner from CrimsonCommon.

Plugin dependencies

TypeName
Crimson pluginCrimsonCommon
Engine modulesCore, CoreUObject, Engine, GameplayTags, GameplayAbilities, NetCore, CrimsonCommon, DeveloperSettings, UMG, IrisCore (private)

Key types

CategoryTypeRole
CoreUCrimsonInventoryManagerComponentActor component: layout, constraint stack, items, currencies. All mutations authority-only.
CoreUCrimsonInventoryItemDefinitionImmutable data asset describing an item type
CoreUCrimsonInventoryItemInstanceReplicated live item; int/float tag stacks + state fragments
CoreFCrimsonInventoryEntryOne slot: instance + stack + EntryId + slot/grid/rotation/group + locked
LayoutUCrimsonInventoryLayoutAbstract DataAsset base. Topology only - no caps.
LayoutUCrimsonInventoryLayout_FlatSlotIndexed slot list (MMO/RPG)
LayoutUCrimsonInventoryLayout_Grid2D Tetris with optional rotation (Diablo/Tarkov/PoE)
LayoutUCrimsonInventoryLayout_WeightAppend-only list with float-tag weight cap (Skyrim/Fallout)
LayoutFCrimsonItemFootprint{Dimensions, Weight, SlotCost, bAllowRotation} consumed by layouts
ConstraintsUCrimsonInventoryConstraintAbstract base: CanAcceptItem, CanAcceptAt, CalculateMaxAllowedQuantity, OnItemAdded, OnItemRemoved, SaveState/LoadState
ConstraintsUCrimsonInventoryConstraint_SlotSlot-count cap; reads Slots tag stack
ConstraintsUCrimsonInventoryConstraint_IntTagTag-keyed integer cap
ConstraintsUCrimsonInventoryConstraint_FloatTagTag-keyed float cap (weight); reads Footprint Weight
ConstraintsUCrimsonInventoryConstraint_TypeFilterAllow/block items by ItemType tags
ConstraintsUCrimsonInventoryConstraint_GridCellRulePer-cell allow/block for grid layouts (gem sockets, potion belt)
ConstraintsUCrimsonInventoryConstraint_StackLimitAggregate cap across all matching items
ConstraintsUCrimsonInventoryConstraint_CustomRuleBlueprint extension base for arbitrary rules
FragmentsUCrimsonInventoryItemFragment_FootprintGeometric footprint read by layouts
FragmentsUCrimsonInventoryItemFragment_DataStackable / unique / max stack size
FragmentsUCrimsonInventoryItemFragment_VisualsIcon, slot widget, pickup actor class
FragmentsUCrimsonInventoryItemFragment_GrantCurrencyOn pickup, convert directly to currency
FragmentsUCrimsonInventoryItemFragment_ConstraintPer-item attached constraints (in addition to component stack)
FragmentsUCrimsonInventoryStateFragmentBase for per-instance mutable state (Durability, Lifetime)
ContainersACrimsonContainerActorBaseReplicating world chest wrapping a manager component; ICrimsonInteractableTarget
ContainersUCrimsonContainerSubsystemGame-instance subsystem for purely-virtual stashes (banks)
ContainersICrimsonPickupableInterface for actors holding FCrimsonInventoryPickup
ContainersACrimsonPickupActorBaseBase for dropped-item world actors
CraftingACrimsonCraftingStationBaseInteractable world actor that coordinates ingredient consumption
CraftingUCrimsonCraftingRecipe / UCrimsonCraftingRecipeBookRecipe data
CurrencyUCrimsonInventoryCurrency / UCrimsonBasicCurrencyReplicated currency handlers
AsyncUCrimsonInventoryAsync_AttemptAddItem / _AttemptPickupBP async nodes with partial-success paths
RoutingUCrimsonInventoryRoutingComponentAttach to PlayerController. Owns Server_ RPCs for move/split/drop/lock/transfer/open. Virtual access control, per-player containers, party / dungeon-instance scope resolvers.