Concept: Multiplayer

Every part of the plugin assumes a dedicated server with several clients. This page states the mechanisms so you can reason about what a client sees and when.

Ownership

An item instance has exactly one owner at a time: the manager that holds its entry, or the pickup actor that holds its FCrimsonPickupInstance. Moving an item between inventories (TransferEntryTo) re-outers the instance; it is never duplicated. The manager's bReplicateUsingRegisteredSubObjectList is on and every instance, state fragment, constraint, and currency handler is registered with AddReplicatedSubObject - there is no legacy ReplicateSubobjects path.

What replicates

DataMechanismCondition
EntriesFCrimsonInventoryList (FFastArraySerializer)Everyone who sees the owner.
Item instances, state fragmentsRegistered subobjectsWith the entry.
Capacity tags (current and max)FCrimsonInventoryTagStackContainer / FCrimsonInventoryFloatTagStackContainer FastArrays with OnRep_ConstraintValues, which sweeps and announces OnConstraintValueChangedCOND_Dynamic, resolved per send in PreReplication: owner-only when the owning actor has a net owning player (a player's own inventory), everyone who sees the owner when it does not (a world container).
LayoutAsset, ActiveConstraints (and each constraint's rule properties), RegisteredCurrencyDataTables, CurrenciesStandard replicated properties and subobjectsEveryone who sees the owner.
Layout runtime state, groups, occupancyNot replicated - rebuilt locally from entries-
Pickup contentsFCrimsonInventoryPickup with OnRep_PickupInventory; instances as registered subobjectsEveryone who sees the pickup.
Scoped container instancesACrimsonInstancedInventoryActor::IsNetRelevantFor limits to viewersViewers only.

One broadcast per mutation

Every server mutator ends in FinalizeServerMutation: it marks the FastArray dirty, rebuilds the layout runtime, broadcasts InventoryUpdated once, and calls FlushNetDormancy + ForceNetUpdate on the owner. Containers stay DORM_Awake (a dormant-all chest dropped changes for remote clients); the flush matters for projects that make their own inventory owners dormant. Clients rebuild the layout runtime in the FastArray callbacks and OnRep_InventoryList (always before the message broadcast), so a batch that adds three entries produces three StackChanged messages and one InventoryUpdated.

Where things run

ActionServerOwning clientOther clients
Add / remove / move / dropMutatesSees it by replication; gets OperationResult if it askedSees it by replication if relevant
PreviewPlacementAuthoritative checkSame code on replicated data - identical answer-
Constraint evaluationAuthoritativePreview only (rule properties replicate for this)-
EquipHost mutates; manager sets the Equipped flag from the host's messageSees the flagSees the flag
Save / loadGetSaveData / ApplySaveData--

Routed request lifecycle

  1. Client calls a routing function (MoveItem).
  2. Server_MoveItem_Validate rejects null targets and nonsensical counts before the body runs.
  3. Server_MoveItem checks CanAccessInventory, then calls MoveItemByEntry.
  4. FinalizeServerMutation replicates the change; Client_NotifyOperationResult reports the outcome to the caller.
Do not call manager mutators on clients
They are BlueprintAuthorityOnly and log a warning. A client that appears to 'work' in a listen-server PIE window is the server. Always test with Play As Client.