Skip to content

Save Game: Create / Save / Load Game to Slot

At a glance

Lives in: Blueprint API / SaveGame - Target: Gameplay Statics - Returns: Create Save Game Object returns a new SaveGame object; Save Game to Slot returns Boolean; Load Game from Slot returns a SaveGame object or None - Changes: writes or reads a platform save slot only when you call the save/load nodes - Can fail by: wrong class, wrong slot/user index, missing slot, disk/platform write failure, bad cast, or trying to persist live actor references - Official docs: Saving and Loading Your Game, Create Save Game Object, Save Game to Slot, and Load Game from Slot

The one-minute version

  • A SaveGame object is a data object you design. It is not the current world, not a checkpoint system by itself, and not automatic serialization of every actor.
  • Create a Blueprint subclass of SaveGame, add variables to it, create an object of that class, copy values into it, then call Save Game to Slot.
  • Loading is the reverse: load the object from the same slot/user index, cast it to your SaveGame class, then copy values back into the current world.
  • Use Does Save Game Exist before loading when a missing save slot is normal, such as a first launch or a new profile.
  • Save Game to Slot returns true or false. Treat false as "the save did not complete" and keep the player out of destructive follow-up actions.
  • Use the async save/load variants for autosaves, large saves, or moments where a hitch would be visible. Use the sync nodes for small menu saves while paused.
  • Do not design around storing live actor references. Store IDs, names, plain values, classes, transforms, and map names, then rebuild live references after the map loads.

What it actually is

USaveGame is a base object class meant to hold data that can be serialized to a platform save slot. In Blueprint, the normal setup is:

Content Browser
-> Add Blueprint Class
-> All Classes
-> SaveGame
-> name it BP_MySaveGame
-> add variables such as Coins, CurrentLevelName, PlayerTransform, DoorStates

The object is just memory until you save it:

Create Save Game Object
-> returns a new empty BP_MySaveGame object in memory
-> you set variables on it
-> Save Game to Slot writes that object to the chosen slot

Nothing in the current world is copied automatically. If the player has 12 coins on the Character and you never assign SaveObject.Coins = 12, the save object does not magically know about the Character's value.

The three-node workflow

For a first save button:

Save button clicked
-> Create Save Game Object (Save Game Class = BP_MySaveGame)
-> Cast To BP_MySaveGame
-> Set Coins = CurrentCoins
-> Set CurrentMap = current map name
-> Set PlayerTransform = player transform
-> Save Game to Slot
   Save Game Object = BP_MySaveGame object
   Slot Name = "Profile_0"
   User Index = 0
-> Branch on Return Value

For first launch/load:

Main menu Continue clicked
-> Does Save Game Exist (Slot Name = "Profile_0", User Index = 0)
-> Branch
   false: start a new game path
   true:
       Load Game from Slot
       Is Valid Return Value
       Cast To BP_MySaveGame
       read CurrentMap / Coins / PlayerTransform
       put runtime handoff values in Game Instance
       Open Level saved CurrentMap

Then in the loaded map:

PlayerController BeginPlay
-> Get Game Instance
-> read loaded save values needed for this map
-> move/spawn/initialize current pawn
-> update HUD

That last step matters. The SaveGame object is durable data. The current pawn, HUD, doors, enemies, and pickups are live world objects. Your Blueprint decides how saved data becomes live state.

The pins that matter

Save Game Class

This is the SaveGame subclass to create. It should be your BP_MySaveGame class, not a pawn, widget, actor, GameMode, or Game Instance class.

If the class is wrong, the object may be unusable for your save data, and a later cast to your expected class will fail.

Save Game Object

This is the object to write. You normally pass the object returned by Create Save Game Object or the object returned by Load Game from Slot after you update its variables.

Saving an old object saves that old object's current values. Saving a newly created object before setting variables saves defaults.

Slot Name

The slot name is your save-file key. Use a stable string such as:

Profile_0
Autosave
Checkpoint_CaveEntrance

Changing the string creates or reads a different slot. Most "my load is empty" bugs are really "save used one slot name, load used another."

User Index

User Index is a platform user number. Many single-player PC projects use 0. Epic's docs note that some platforms ignore it, but you should still pass the same value for save, existence check, and load.

Return values

Node Return value Meaning
Create Save Game Object New SaveGame object A blank object in memory; not written to disk yet.
Save Game to Slot true / false Whether the write succeeded.
Does Save Game Exist true / false Whether a slot exists for that slot/user pair.
Load Game from Slot SaveGame object or None Loaded data object if the read succeeded; None if it failed.

Always branch on save success when the next step matters. For example, do not delete an old checkpoint, show "saved," or travel away from an unsaved menu unless the save returned true.

What to store

Good beginner SaveGame variables:

Need Store this
Resume a map Map name or soft reference to the map.
Restore player position Transform, checkpoint ID, or spawn entrance ID.
Restore inventory Item IDs, counts, equipped item ID/class, ammo values.
Restore doors/pickups Durable IDs plus opened/collected booleans.
Restore settings Plain values such as volume, invert Y, subtitles.
Restore selected character Class reference or asset ID, not the old pawn object.

Poor SaveGame variables:

  • direct references to placed actors in a map;
  • references to the current pawn, controller, widget, or component;
  • values that change every frame but do not matter after load;
  • temporary combat state that should reset on death or map start;
  • huge object graphs "just in case";
  • secrets or anti-cheat-sensitive data that should not be trusted from a local save file.

The quick path is to put every variable you can see into the SaveGame class. The concrete cost is that loading becomes a second, hidden version of your whole game state. Save durable facts and rebuild the live world from those facts.

Actor references are the trap

A live actor reference points at an object in a loaded world. Save files outlive that world. Even when a reference-shaped value appears to serialize in a test, it is usually the wrong design for beginner saves because the live actor may not exist when you load, may have a different generated instance name, or may belong to another map.

Use durable identity instead:

Bad save data:
    DoorReference = BP_Door_12 live actor

Better save data:
    DoorStates:
        DoorId = "Cave_Entrance_Door"
        bOpened = true

On map BeginPlay, each door can look up its own ID in the loaded data and apply the saved state. The save stores facts. The map rebuilds actors.

For player position, storing a transform can be fine:

Save:
    CurrentMap = "L_Cave"
    LastCheckpointId = "Entrance"
    SavedPlayerTransform = X/Y/Z + rotation

Load:
    Open Level L_Cave
    after map starts, move/spawn player at that checkpoint/transform

If collision matters, restore the player with the same care you would use for normal spawning or movement. Do not blindly place the character inside a wall.

Sync vs async

The synchronous nodes are simple:

Save Game to Slot
-> waits for the save attempt
-> returns true/false

They are fine for small saves from a pause menu, main menu, or checkpoint moment where a short hitch is acceptable.

The async variants are for smoother runtime behavior:

Async Save Game to Slot
-> starts the save
-> game can continue
-> completion callback gives Slot Name, User Index, and success boolean

Use async for autosaves, larger save objects, or saving during active gameplay. While an async save is in progress, avoid starting another write to the same slot unless your own save manager serializes those requests. "Last write wins" bugs are difficult to reason about when two systems save different versions of the object.

SaveGame vs Game Instance

These two are often used together, but they solve different lifetimes.

Need Use
Survive Open Level during the same running game Game Instance
Survive quitting and launching later SaveGame
Current map rules/default pawn GameMode
Current pawn health/movement/body state Pawn, Character, or a component
UI references and menu widgets PlayerController, HUD, or widgets

A clean pattern is:

Load save from disk
-> copy needed runtime values into Game Instance
-> Open Level saved map
-> destination map reads Game Instance and initializes live actors
-> when saving again, copy current live values back into SaveGame
-> Save Game to Slot

Game Instance is the handoff while the application is running. SaveGame is the disk record.

What the SaveGame flag does not do here

Blueprint variables can expose a SaveGame flag in some contexts, and C++ properties can be marked for save-game serialization. That flag matters for systems that deliberately serialize only save-marked properties.

Epic's Save Game to Slot Blueprint helper writes the SaveGame object's non-transient properties; its official page explicitly notes that the helper does not filter by the SaveGame property flag. For a Blueprint beginner, the practical rule is simpler:

Only values that are on the SaveGame object, and that you set to the values you
care about, are part of this save-object workflow.

Do not rely on a checkbox to pull data out of your Character, GameMode, or level actors. Copy the values.

When it fails (and what failure does)

Common causes:

  1. You loaded a missing slot. Load Game from Slot returns None; use Does Save Game Exist when absence is expected.
  2. Save and load use different slot names or user indexes. The data exists, but you are asking for another key.
  3. The loaded object is not your class. The cast fails because the slot was created with another SaveGame class or old data.
  4. You saved defaults. You created the object but did not copy current values into it before saving.
  5. The write failed. Disk/platform conditions, permissions, storage limits, or platform user state can make Save Game to Slot return false.
  6. You stored live object references. Loading gives you stale or unusable references instead of rebuildable state.
  7. You loaded before the destination world exists. Read durable data first, travel, then apply map-specific data after the new map starts.
  8. You changed the SaveGame class layout. Old saves may not contain new variables or may need version/default handling.

Failure does not run a special failed exec pin on the sync nodes. The graph continues with a return value. Branch on it, print the slot/user values, and guard loaded objects with Is Valid before casting.

The C++ twin

For the curious, the C++ version follows the same shape (our own example code):

void UTrainingSaveSubsystem::WriteSlot(const FString& SlotName, int32 Coins)
{
    UTrainingSaveGame* Save =
        Cast<UTrainingSaveGame>(UGameplayStatics::CreateSaveGameObject(
            UTrainingSaveGame::StaticClass()));

    if (!IsValid(Save))
    {
        return;
    }

    Save->Coins = Coins;
    Save->LastMapName = FName(TEXT("L_Cave"));

    const bool bSaved =
        UGameplayStatics::SaveGameToSlot(Save, SlotName, 0);

    if (!bSaved)
    {
        UE_LOG(LogTemp, Warning, TEXT("Save failed for slot %s"), *SlotName);
    }
}

Lookalikes - which one do I want?

Node or tool Use when Not the same as
Create Save Game Object You need a new in-memory object of your SaveGame class. Writing to disk.
Save Game to Slot You want to write the object to a platform save slot now. Automatically collecting world state.
Does Save Game Exist Missing save data is normal and you need to branch. Validating that the data inside is the right version/class.
Load Game from Slot You want to read saved data from a slot. Applying that data to live actors for you.
Async Save / Async Load Save/load should not hitch active gameplay. Simpler graph control flow.
Delete Game in Slot You intentionally remove a save slot. Resetting current runtime variables by itself.
Game Instance Runtime values must survive map travel. Data that survives quitting.
Open Level You want to load the saved map or travel after saving. Saving data.

Going deeper