CrimsonSaveSystemv1.0Free
Get it on Fab

Fragment-based saving where every system owns its own data. No plugin is ever aware of another's save file.

Free · Persistence · Unreal Engine 5

Every system saves itself. No monolithic save file, no cross-system coupling.

CrimsonSaveSystem is a fragment-based save system for multiplayer Unreal projects. Each saveable system writes its own independent fragment inside the slot: tag your UPROPERTY(SaveGame) fields, implement one interface, and the Save Manager handles slots, headers, world state, and per-player scoping. No system is ever aware of another's save data.

Why CrimsonSaveSystem

A decoupled persistence layer: each system owns its data and restores itself, with zero cross-system coupling.

Fragment-based architecture

Instead of one monolithic save file, every registered system writes its own independent fragment inside the save slot. Systems contribute their own data without knowing about each other, and no fragment ever reads another's; that is what keeps plugins decoupled.

Automatic serialization

Tag any field UPROPERTY(SaveGame) and the manager captures it automatically via the engine's proxy archive, no fragment subclass needed. For data that can't be auto-serialized (UObject refs, GAS state, computed values), subclass UCrimsonSaveGameFragmentBase and both paths run together.

Save Manager and a one-call menu API

One UGameInstanceSubsystem orchestrates new-game saves, rotating auto-saves and quick-saves, slot deletion, and a per-slot header with display name, date, play time and thumbnail. UCrimsonSaveFacade wraps the same actions as Blueprint nodes for a save/load menu; rotation limits and the storage provider live in Project Settings.

World state saves

Level actors opt in with ICrimsonSaveableActor; no registration call. Transform, the actor's and its components' SaveGame fields, hidden flag and velocities are captured automatically; runtime-spawned actors re-spawn on load, a destroyed placed actor leaves a tombstone, and SaveGame actor pointers re-resolve to live instances.

Three save scopes, one profile id

Each system declares a scope: World (per slot), Player (per player per slot) or Profile (outside any slot, so a character can travel between servers). Player and profile data are keyed by a stable profile GUID, and a client may only write its own profile.

Versioning & migration

Fragments are stamped with a schema version on every save. Override GetCurrentVersion() and UpgradeFromVersion() to migrate older saves before restore, so adding or renaming fields never silently drops a player's data.

A closer look

Make any system saveable in four steps

Enable the plugin, tag your fields UPROPERTY(SaveGame), implement ICrimsonSaveableSystem with a unique GetFragmentName(), and register with the Save Manager.

  • A player-owned system also returns Player from GetSaveScope() and its owner's id from GetProfileId()
  • Forward PostLogin and Logout from your game mode and per-player loading and flushing are handled for you

Decoupled by design

No fragment ever reads another fragment's data; each system restores itself from its own fragment only. The plugin knows nothing about the systems it saves. With CrimsonCore, the other Crimson plugins get ready-made save adapters; without it, implement the interface on your own systems.

  • You never call SaveGameToSlot directly; the CrimsonSaveSystem API is the single entry point
  • Where one system has to land before another, GetRestorePriority() orders delivery

Where the bytes land is a swappable class

The manager decides what to save; a UCrimsonSaveStorageProvider decides where the bytes go. The default routes through the engine's own ISaveGameSystem, which is correct on PC and console, platform-managed cloud sync included, with no code from you.

  • PlayStation, Switch, Xbox and Steam Auto-Cloud sync with no code from you
  • Point saves at a directory of your own with the shipped file provider
  • Subclass the provider for a service API such as Steam Cloud or EOS; that path is C++

Saves and loads are event-driven

OnSaveStarted / OnSaveComplete and OnLoadStarted / OnLoadComplete bracket every operation, so loading screens and a "don't close the game" banner have a clean signal to key off.

  • OnSaveError and OnLoadError fire once per failing fragment while the rest continues
  • A single corrupt fragment tells the player which system failed, not just that saving failed
  • IsSaveOrLoadInProgress() answers the same question on demand

Technical details

Engine
UE 5.8
Tested platforms
Windows
Blueprint-ready
Yes
C++ required
No
Network replicated
No
Dependencies
GameFeatures, ModularGameplay, CoreOnline, DeveloperSettings

Frequently asked questions

Do I need C++ to use it?
No. ICrimsonSaveableSystem, ICrimsonSaveableActor, the fragment base class, the Save Manager, the save facade and the lifecycle hooks are all Blueprint-accessible; enabling the plugin in Edit → Plugins is the whole install for a Blueprint project. The one C++-only surface is writing your own storage provider, because its functions can run on a background thread; choosing a shipped provider is a Project Settings dropdown.
How does saving work without a monolithic save file?
Each registered system writes its own independent fragment into the slot, alongside a header and one entry per saved world actor. Tag fields UPROPERTY(SaveGame) for automatic capture, or subclass UCrimsonSaveGameFragmentBase for data that can't be auto-serialized; both run together. No fragment ever reads another's, so systems stay fully decoupled, and how those fragments are physically stored is the storage provider's decision, not the save code's.
Does it work in multiplayer?
Yes: single player, listen server, dedicated server and splitscreen all run the same code. Whole-slot saves are server/standalone only (client calls are rejected and logged), fragments declare a World, Player or Profile scope, and per-player data is keyed by a stable profile GUID. One thing you must wire: a remote player's controller, of any APlayerController class, needs the profile-identity component (added with the Add Crimson Save Profile Identity game feature action) so the owning client can report who it is; until it does, the manager holds that player's fragments rather than guessing.
Does it depend on other Crimson plugins?
No. CrimsonSaveSystem is fully standalone and needs only engine plugins; any system becomes saveable through its interfaces. CrimsonCore, the free integration layer, adds ready-made save adapters for the other Crimson plugins (inventory, skill trees, ability state), a pre-wired game mode and player state, and a persistent-actor base. It needs every Crimson plugin installed, so the docs build the same loop without it.
Can I clear test saves without leaving the editor?
Yes. The plugin's editor module adds a Delete Save Game dropdown to the Level Editor play toolbar: delete one file, one folder or every file of a slot, each behind a confirmation. It hides during Play-In-Editor and can be switched off in Project Settings.
Where are saves stored, and do cloud saves work?
By default through the engine's ISaveGameSystem: Saved/SaveGames/ on PC, the platform's save container on console. Platforms that sync a container or a directory for you (PlayStation, Switch, Xbox, Steam Auto-Cloud) need no change at all. A service API (Steam Cloud, EOS, your own server) is a storage provider subclass rather than a fork of the save system, and a shipped file provider writes plain files under a directory you configure with {SavedDir} / {UserDir} / {Project} tokens.
Is it free?
Yes. CrimsonSaveSystem is free on Fab and standalone: slots, world actors, per-player scopes and pluggable storage are all included.

Add saving to your project today

CrimsonSaveSystem is free and takes four steps to adopt. Tag your fields, implement one interface, and every system saves and restores itself, independently.