How-To: Custom Fragments & Versioning
Goal: persist data that a SaveGame property can't hold - UObject references, GAS state, computed values - with a custom fragment, and evolve its schema safely as your game changes.
ICrimsonSaveableSystem and is registered (see Quick Start: Saveable Systems). You only need this when UPROPERTY(SaveGame) auto-serialization isn't enough.1. Subclass the fragment
Subclass UCrimsonSaveGameFragmentBase and add the fields you want to control by hand. A Blueprint subclass is a normal asset; a C++ subclass lives in your Public/ header.
UPROPERTY(SaveGame) fields regardless - a custom fragment is additive. GatherSaveData may return nullptr to rely entirely on auto-serialization, or return a fragment for the data auto-serialization can't reach. Both paths run together.2. Return it from GatherSaveData, read it in RestoreFromSaveData
.sav named after your GetFragmentName grows to include the custom data.3. Version the schema
Override GetCurrentVersion to declare your fragment's schema version, and increment it whenever you add, remove, or rename fields. Override UpgradeFromVersion to migrate data from an older save before RestoreFromSaveData runs.
UPROPERTY(SaveGame) field without an UpgradeFromVersion migration silently drops the old value on load. Increment the version and handle it explicitly.4. (Optional) Custom header fields
To show extra metadata in your save menu (chapter name, character portrait, difficulty), subclass UCrimsonSaveGameHeader, override OnHeaderUpdate to populate your fields, and set the subclass in Developer Settings under SaveGameHeaderClass.
See also
- Concept: The Fragment Model - how auto-serialization and custom fragments run together
- How-To: Save Player Progression - the player-state fragment applies this pattern
- API Reference -> Data types -
UCrimsonSaveGameFragmentBase/UCrimsonSaveGameHeaderfields