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.

Prerequisites
Your system implements 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.

New Blueprint Class -> search `Crimson Save Game Fragment Base` -> add your own variables (e.g. `Item Ids`, `Item Counts`).
Auto-serialization still runs
The manager always captures your 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

On the saveable object: override **Gather Save Data** -> Construct your fragment, fill its fields, Return. Override **Restore From Save Data** -> cast the Fragment to your class and apply it.
Verify
Change some inventory, save, reload - the items come back. The fragment .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.

On the fragment Blueprint: override **Get Current Version** to return your schema number (e.g. `2`). Override **Upgrade From Version** and branch on the `Old Version` input to backfill new fields before restore runs.
Never rename a SaveGame field without an upgrade
The auto-serialization blob uses property names as keys. Renaming a 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.

New Blueprint Class -> `Crimson Save Game Header` -> add fields (e.g. `Current Chapter Name`, `Completion Percent`). Override **On Header Update** to populate them from your Game Instance. Then set the subclass in **Project Settings -> Crimson -> Crimson Save Game Manager -> `Save Game Header Class`**.

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 / UCrimsonSaveGameHeader fields