Concept: Definitions, Instances and Entries

Three things carry equipment, and knowing which one holds what answers most questions about where to put your data.

The definition is a class, and it is shared

UCrimsonEquipmentDefinition is Const and Abstract. The plugin never instantiates it - it reads the class default object and moves on. That is why every API takes a TSubclassOf, and why a definition is immutable at runtime: a hundred characters wearing the same sword all read the same CDO.

So a definition describes the kind of gear: which slot it fills, what it grants, what it attaches. Nothing that varies between two copies of the same sword can live there.

The instance is the runtime object, one per equipped item

UCrimsonEquipmentInstance is created when the item is equipped and destroyed when it is unequipped. It is a replicated UObject whose outer is the pawn - a deliberate choice, because UE requires a replicated UObject to be outered to an actor. It holds three things: the definition it came from, the source object, and this machine's spawned actors.

SpawnedActors is per machine and not replicated. Every machine spawns its own cosmetic copies, so the server's list and a client's list contain different actors that look the same. Never send an actor from that list across the wire.

The entry is the slot assignment

FCrimsonAppliedEquipmentEntry is one row of the replicated FCrimsonEquipmentList. It holds the definition class, a pointer to the instance, the slot tag, the assigned index, and the ability-set handles. The handles are marked NotReplicated: grants exist only where the ASC has authority.

The entry, not the instance, is what carries a slot. That is why Swap Equipped Items and Move Equipped Item To Slot are cheap - they rewrite entry fields and mark them dirty, without touching abilities, actors or lifecycle hooks.

Where to put your data

The data is...It belongs on
The same for every copy of this gear (slot, grants, meshes, sockets)The definition.
Per equipped copy, and only meaningful while worn (a charge counter, a cooldown, a spawned effect handle)The instance, as a subclass.
Per item and meaningful whether or not it is worn (durability, rolled stats, a display name)Your source object - the item. The instance keeps a reference to it and nothing more.
Which slot this item is inNowhere of yours. The entry owns it; ask the manager or the bridge.

The source object is opaque on purpose

SourceObject is a bare UObject* that this plugin stores, replicates and hands back, and never inspects. That single decision is what keeps CrimsonEquipment free of any item-system dependency: your inventory item, a data asset, or nothing at all are all equally valid, and the plugin cannot develop an opinion about which.

The cost is that the plugin cannot help you with it either. It cannot tell whether the object still belongs to the player, cannot re-home an item it displaced, and skips it entirely when saving if it is a runtime object. Those are the item system's jobs.