How-To: Save and Restore Equipment

Goal: persist what a character is wearing and put it back on load, using whatever save system your project already has.

Prerequisites
How-To: Get the Building Blocks, and a save path of your own - a USaveGame, a database write, anything.

1. Know what this plugin does and does not do

CrimsonEquipment depends on no save system. It gives you a plain struct and three calls; where the bytes go is entirely your project's business.

CallAuthorityWhat it does
Gather Save DataServer onlyReturns an FCrimsonEquipmentSaveData snapshot. Without authority it warns and returns an empty struct.
Restore From Save Data (Save Data)Server onlyForce-unequips everything, then re-equips the saved entries. If the ASC is not ready yet it caches the data instead - see step 4.
Try Flush Pending RestoreServer onlyApplies data that was cached because the ASC was not ready. Returns true when it restored.
Has Pending RestoreAnyWhether a restore is still waiting on the ASC.
Field of FCrimsonEquipmentSaveEntryTypeMeaning
Equipment DefinitionTSubclassOf<UCrimsonEquipmentDefinition>The definition class that was equipped.
Slot TagFGameplayTagThe slot it occupied.
Assigned Slot Indexint32The index within that slot.
Source Object PathFSoftObjectPathA path to the source object when it was a loadable asset. Empty otherwise.
Everything is SaveGame-flagged
Both structs are BlueprintType and every field carries the SaveGame flag, so they serialize through any archive that respects it - a USaveGame, a proxy archive, your own writer.
Verify
Equip two items on the server and call Gather Save Data: the returned array has two entries with the right definitions, slot tags and indices.

2. Gather and store

At your save point, on the server: Get Component By Class (Crimson Equipment Manager Component) -> Gather Save Data, then store the resulting struct on your SaveGame object as a variable of type Crimson Equipment Save Data.

The struct is Blueprint-readable, so you can also walk Equipped Items and write the fields into your own format if you prefer.

Verify
Save, then inspect the struct: one entry per equipped item whose source was an asset or absent.

3. Know which entries are skipped

Gather Save Data decides per entry by asking the source object whether it is an asset.

Source objectSaved?Who restores it
None (Equip Item was called with no source)Yes - definition, slot tag and index.Restore From Save Data re-equips it.
A loadable asset (a Data Asset, for instance)Yes, plus Source Object Path.Restore From Save Data loads the path and passes it back as the source.
A runtime object - an inventory item instance, sayNo. The entry is skipped entirely.The system that owns the item. It persists that the item was equipped and re-equips it on load.
This is why equipped inventory items vanish if nobody else saves them
Persisting a runtime-sourced entry here would restore the equip twice - once from equipment, once from the inventory that re-equips its own item - and leave a soft path pointing at an object that no longer exists. So the entry is dropped on purpose. If your items are runtime instances, the item system must record that they were equipped. See How-To: Bridge an Item System.
Verify
Equip one asset-sourced item and one runtime-sourced item, then Gather Save Data: the array has exactly one entry, the asset-sourced one.

4. Restore, and handle a late ASC

Restore From Save Data needs the ASC so it can grant the abilities. In a setup where the PlayerState owns the ASC, the pawn is often initialized first - so if the ASC is missing the component caches the data and waits rather than restoring gear with no abilities.

On load, on the server: Restore From Save Data with the struct you stored. Then, from wherever your project finishes initializing the Ability System Component, call Try Flush Pending Restore on the manager. Has Pending Restore tells you whether anything is still waiting.

Calling Try Flush Pending Restore when nothing is pending simply returns false, so it is safe to call unconditionally.

Restore wipes first, and is quieter than an equip
Restore From Save Data force-unequips everything currently equipped before re-adding the saved entries. The re-add goes straight into the equipment list, so on the server it does not run Can Equip Item, does not validate against the slot layout, and does not broadcast On Equipment Changed or the equipment messages. Clients still see the change through replication and their listeners still fire. If your own systems key off the server-side messages, tell them yourself after restoring.
Verify
Restore into a pawn whose ASC is not ready: LogCrimsonEquipment reports that the data was cached and Has Pending Restore is true. Call Try Flush Pending Restore once the ASC exists: it returns true, the gear appears, and the abilities are granted.

See also

  • How-To: Bridge an Item System
  • How-To: Keep Your Assets in a Cooked Build
  • Concept: Multiplayer