CrimsonSaveSystem

CrimsonSaveSystem is a fragment-based save system built for multiplayer projects. Instead of one monolithic save file, each saveable system writes its own fragment - a small, independent blob stored under the save slot. Systems register themselves and contribute their own data without knowing about each other, and actors placed in your levels persist automatically.

Using with other Crimson plugins
This plugin works alone: any system becomes saveable by implementing its interfaces, with no other Crimson plugin involved. When you own the other Crimson plugins, CrimsonCore contains the full-suite save wiring in Source/CrimsonCore/{Public,Private}/SaveIntegration/: UCrimsonCorePlayerSaveComponent (the base for per-system save adapters such as UCrimsonInventorySaveComponent and UCrimsonSkillTreeSaveComponent) and ACrimsonPersistentActor. To wire it yourself, see CrimsonCommon -> Concept: Connecting Crimson Plugins; for what CrimsonCore installs, see CrimsonCore -> Concept: The Integration Layer.

What's included

SystemKey typesPurpose
Fragment saves (systems)ICrimsonSaveableSystem, UCrimsonSaveGameManagerSubsystemPersist data-owning systems - inventory, progression, settings - as independent .sav fragments.
World-state saves (actors)ICrimsonSaveableActor, UCrimsonSaveWorldManagerSubsystemPersist actors placed or spawned in a level (doors, chests, levers) automatically, with no registration.
Slots, metadata & menu APIUCrimsonSaveGameHeader, ECrimsonSaveSlotType, UCrimsonSaveFacadePer-slot header - display name, date, play time, thumbnail - plus UCrimsonSaveFacade, a one-call Blueprint library for building save/load menus.
Multiplayer scopingUCrimsonSaveProfileIdentityGlobal vs per-player fragments; dedicated-server, listen-server, and single-player ready.
Pluggable storageUCrimsonSaveStorageProvider, UCrimsonPlatformSaveStorageProviderDecides where save bytes go. Defaults to the engine's ISaveGameSystem - correct on PC and console. Swap the class to retarget a directory or a cloud backend.
Editor toolsFCrimsonSaveGameDeleteUtility, UCrimsonSaveSystemEditorSettings, UCrimsonSaveCleanupStaticsA Delete Save Game play-toolbar dropdown that groups save files by slot, and an orphaned-world-row cleaner. See How-To: Delete Save Files in the Editor.
Turnkey layer (CrimsonCore)ACrimsonPersistentActor, ACrimsonPlayerStateOptional ready-made GameMode / PlayerState wiring and a persistent-actor base.

Plugin dependencies

TypeNameNotes
CrimsonNoneThis plugin is fully standalone.
Crimson (not a dependency)CrimsonCore (CrimsonCore - requires all Crimson plugins)For orientation only: a free turnkey layer built on top of this plugin. See How-To: Turnkey Save Setup with CrimsonCore.
Engine pluginGameFeatures, ModularGameplayEnabled by the .uplugin; needed by the save-identity game feature action.
EngineCore, CoreUObject, EngineCore types, USaveGame, UGameInstance, subsystems, FInstancedStruct payloads.
EngineGameFeatures, ModularGameplayUGameFeatureAction base and UGameFrameworkComponentManager requests for Add Crimson Save Profile Identity.
EngineCoreOnlineResolving UniqueNetId for per-player save keys.
EngineSlate, SlateCoreUsed internally by the runtime module (e.g. save-thumbnail capture).
EngineDeveloperSettingsThe Project Settings page (UCrimsonSaveGameManagerDeveloperSettings).
Engine (editor module)UnrealEd, ToolMenus, Slate, SlateCore, ApplicationCore, AssetRegistry, AssetTools, ContentBrowserData, Kismet, DeveloperSettingsCrimsonSaveSystemEditor: the Delete Save Game toolbar, save cleanup, content-browser entries, and UCrimsonSaveSystemEditorSettings.
Which path do I choose?
- A data-owning system (inventory, progression, settings)? Follow Quick Start: Saveable Systems.
- An actor placed or spawned in a level (door, chest, lever)? Follow Quick Start: World Actors.
- Want a working save menu with almost no wiring? Use the turnkey layer - see How-To: Turnkey Save Setup with CrimsonCore.
- Need saves somewhere other than the default location, or on a cloud backend? See How-To: Change Where Saves Are Stored.
Cardinal rules
1. The simplest path is UPROPERTY(SaveGame) auto-serialization - no getters/setters, no custom fragment. Reach for a custom fragment only for data a SaveGame property can't hold (UObject references, GAS state, computed values).
2. Never call UGameplayStatics::SaveGameToSlot directly - use the CrimsonSaveSystem API exclusively. Where those bytes physically land is the storage provider's job, not yours; see Concept: Where Saves Are Stored.
3. Never make one fragment depend on another fragment's data. Each system restores itself from its own fragment only.