Files
UE5-Modular-Game-Framework/docs/blueprints/05-saveload/35_SS_SaveManager.md

9.9 KiB

SS_SaveManager — GameInstance Subsystem

File: Content/Framework/Save/SS_SaveManager

C++ Status: Full ImplementationSource/PG_Framework/Public/Save/SS_SaveManager.h provides the complete save/load subsystem: slot manifest, save/load/delete, quick-save/load, checkpoint management, backup, FArchive binary serialization. Auto-created by UE's subsystem system when GI_GameFramework initializes — no BP child, no spawning needed. Access from any BP: Get Game Instance → Get Subsystem(SS_SaveManager). See docs/developer/cpp-integration-guide.md.


Purpose: The single authority for all serialisation and deserialisation of game state to disk. Supports multiple save slots, checkpoint saves, hard saves, auto-saves, and world object persistence.

Depends On: GI_GameFramework, I_Persistable Used By: BPC_CheckpointSystem, WBP_SaveLoadMenu, BPC_PlayerRespawnSystem


Enums

// E_SaveType — Categorizes the trigger that initiated a save
E_SaveType
{
  Checkpoint,    // Auto-triggered by crossing a checkpoint volume
  HardSave,      // Player-initiated manual save
  AutoSave,      // Periodic or event-triggered auto save
  DeathStateSave // Snapshot created when the player dies (for death loop continuity)
}

Structs

// S_SaveSlotInfo — Metadata entry for one save slot in the manifest
S_SaveSlotInfo
{
  SlotIndex:        Integer       // 0-based slot number
  DisplayName:      FText         // Player-chosen or auto-generated name
  Timestamp:        FDateTime     // UTC timestamp of last save
  ChapterTag:       GameplayTag   // Which chapter/level was active
  ThumbnailBytes:   Byte Array    // Compressed screenshot for UI preview
  PlaytimeSeconds:  Float         // Total playtime from GI_GameFramework
}

// S_WorldObjectState — Delta record for one persistent world actor
S_WorldObjectState
{
  ObjectTag:        GameplayTag   // Unique identifier matching the actor's tag
  bDestroyed:       Bool          // Was the actor destroyed?
  CustomData:       Map (Name  String)  // Generic key-value store for any component state
}

// S_PlayerSnapshot — Complete capture of player state at save time
S_PlayerSnapshot
{
  // Core vitals
  Health:             Float       // Current HP
  Stress:             Float       // Current stress level
  Stamina:            Float       // Current stamina pool

  // Transform
  Position:           Vector      // World location
  Rotation:           Rotator     // World rotation

  // Inventory
  InventoryData:      Array of S_InventorySlot  // From BPC_InventorySystem
  QuickSlotData:      Array of S_QuickSlotEntry // From BPC_InventoryQuickSlot
  EquipmentData:      Map (GameplayTag  S_EquipmentSlot)  // From BPC_EquipmentSystem

  // Narrative
  NarrativeFlags:     Map (GameplayTag  Bool)   // From BPC_NarrativeStateSystem
  NarrativeValues:    Map (GameplayTag  Float)

  // Metrics
  DeathCount:         Integer     // From BPC_PlayerMetricsTracker
  ItemsCollected:     Integer
  DistanceTravelled:  Float

  // Additional
  ActiveObjectiveTags:  Array of GameplayTag  // From BPC_ObjectiveSystem
  HidingState:          Bool                  // Was player hiding?
  CurrentHidingSpotTag: GameplayTag
  AltDeathSpaceEnterCount: Integer
}

Variables

Name Type Description
SlotManifest Array of S_SaveSlotInfo Cached metadata for all available save slots
ActiveSaveObject SaveGame Object Reference The currently loaded save data object in memory
bIsSaving Bool Prevents concurrent save operations
bIsLoading Bool Prevents concurrent load operations
SaveVersion Integer Current schema version for migration detection
WorldStateDelta Map (Name → S_WorldObjectState) Live delta of changed world objects since last save
PersistentActors Array of Actor Reference All registered I_Persistable actors in the current level

Functions / Events

Name Inputs Outputs Description
SaveToSlot SlotIndex: Int, SaveType: E_SaveType Bool Success Orchestrates full save: collects all state, writes SaveGame to disk, updates manifest
LoadFromSlot SlotIndex: Int Bool Success Reads SaveGame from disk, migrates if needed, distributes state to all systems
DeleteSlot SlotIndex: Int Removes save file and manifest entry
GetSlotManifest Array of S_SaveSlotInfo Returns all slot metadata for UI display
GetSaveFileSize SlotIndex: Int Int64 Bytes Returns the on-disk file size for the given slot
RegisterPersistableActor Actor: Actor Reference Adds an I_Persistable actor to the tracked list
UnregisterPersistableActor Actor: Actor Reference Removes an I_Persistable actor from the tracked list
CollectWorldState Iterates all registered I_Persistable actors and calls CollectState()
DistributeWorldState Iterates all registered I_Persistable actors and calls RestoreState()
CollectPlayerSnapshot S_PlayerSnapshot Gathers player state from all relevant components
DistributePlayerSnapshot Snapshot: S_PlayerSnapshot Restores player state to all relevant components
MigrateSaveVersion OldVersion: Int, Data: SaveGame Object SaveGame Object Upgrades old save schema to current version
SaveCheckpoint CheckpointTag: GameplayTag Saves checkpoint data to the active slot without prompting the player
SaveDeathState Saves a special death-state snapshot for death loop continuity
LoadDeathState Bool Success Loads the death-state snapshot
HasSaveData SlotIndex: Int Bool Returns whether a save file exists for the slot
GetActiveSaveSizeInfo FText Formatted string with playtime, chapter, timestamp for HUD

Event Dispatchers

Name Parameters Fired When
OnSaveComplete SlotIndex: Int, SaveType: E_SaveType Save operation finishes successfully
OnLoadComplete SlotIndex: Int Load operation finishes successfully
OnSaveFailed SlotIndex: Int, ErrorCode: Int Save fails (disk full, write error, etc.)
OnLoadFailed SlotIndex: Int, ErrorCode: Int Load fails (corrupt file, version mismatch, etc.)
OnWorldStateCollected ActorCount: Int After all I_Persistable actors collected state
OnWorldStateDistributed ActorCount: Int After all I_Persistable actors restored state
OnSaveVersionMigration OldVersion: Int, NewVersion: Int When a save file is migrated to a newer schema

Blueprint Flow Diagram

flowchart TD
    A[SaveToSlot called] --> B{bIsSaving?}
    B -->|Yes| C[Return False]
    B -->|No| D[Set bIsSaving = true]
    D --> E[CollectPlayerSnapshot]
    E --> F[CollectWorldState]
    F --> G[Write SaveGame to disk]
    G --> H[Update SlotManifest]
    H --> I[Set bIsSaving = false]
    I --> J[Broadcast OnSaveComplete]
    J --> K[Return True]

    L[LoadFromSlot called] --> M{bIsLoading?}
    M -->|Yes| N[Return False]
    M -->|No| O[Set bIsLoading = true]
    O --> P[Read SaveGame from disk]
    P --> Q{File valid?}
    Q -->|No| R[Broadcast OnLoadFailed]
    R --> S[Set bIsLoading = false]
    S --> T[Return False]
    Q -->|Yes| U[Check SaveVersion]
    U --> V{Needs migration?}
    V -->|Yes| W[MigrateSaveVersion]
    W --> X[DistributePlayerSnapshot]
    V -->|No| X
    X --> Y[DistributeWorldState]
    Y --> Z[Set bIsLoading = false]
    Z --> AA[Broadcast OnLoadComplete]
    AA --> AB[Return True]

Save File Structure

SaveGame Object (USaveGame-derived)
├── Header
│   ├── SaveVersion: Integer
│   └── SlotInfo: S_SaveSlotInfo
├── Player Snapshot
│   └── S_PlayerSnapshot
├── World State
│   └── WorldStateDelta: Map (Name → S_WorldObjectState)
└── Death State
    └── DeathStateData: S_PlayerSnapshot (optional, only in DeathStateSave)

Communication Matrix

Target System Method Why
All I_Persistable actors Interface call (CollectState, RestoreState) World object persistence
BPC_HealthSystem / Stress / Stamina Via S_PlayerSnapshot Restore player vitals
BPC_InventorySystem Via S_PlayerSnapshot Restore inventory state
BPC_NarrativeStateSystem Via S_PlayerSnapshot Restore narrative flags
BPC_PlayerMetricsTracker Via S_PlayerSnapshot Restore session metrics
BPC_ObjectiveSystem Via S_PlayerSnapshot Restore objective state
BPC_EquipmentSystem Via S_PlayerSnapshot Restore equipment state
BPC_InventoryQuickSlot Via S_PlayerSnapshot Restore quick slot layout
BPC_CheckpointSystem Dispatcher OnLoadComplete Notify checkpoint system to reset
WBP_SaveLoadMenu Dispatcher OnSaveComplete/OnLoadComplete UI refresh after operation
GI_GameFramework Direct (owned by) Access active slot index, update phase
BPC_DeathHandlingSystem Direct call SaveDeathState/LoadDeathState Death loop continuity

Reuse Notes

  • Add new fields to S_PlayerSnapshot per project without breaking existing saves (migration handles missing fields)
  • The WorldStateDelta map handles any I_Persistable actor generically — no per-actor serialisation code needed
  • Save file naming convention: SaveSlot_{SlotIndex}.sav
  • All disk I/O uses UE5's UGameplayStatics::SaveGameToSlot / LoadGameFromSlot
  • Register/unregister I_Persistable actors in BeginPlay / EndPlay of the actor
  • For multiplayer, the GM_CoreGameMode should be the Server-authorised caller of SaveToSlot / LoadFromSlot