[UE5] Implementing Save and Load with Save Game

Created: 2026-02-07Last updated: 2026-07-20

An illustrated guide to implementing save and load in Blueprint with UE's Save Game: the three steps of making, filling, and opening the box, a hands-on checkpoint respawn, why you must not save Actor references, and async saving.

You reach a checkpoint, get your gear sorted, and build up some gold. Then you stop Play and it's all gone. Next time you launch, you're back at the beginning.

Save Game solves this. It writes your game state out to a file and reads it back on the next launch, and you can implement it entirely in Blueprint. This article covers creating a Save Game class, a hands-on build where you save at a checkpoint and restore on respawn, and the pitfall every beginner hits: you can't save Actor references.

Packing the state of a game screen into a box and sliding it into a slot on a shelf

What You'll Learn

  • What Save Game really is: a box you carry things out in . Three steps: make it, fill it, open it
  • The complete node graphs for saving and loading in Blueprint
  • Hands-on: save at a checkpoint and restore when you die
  • Why you must not save Actor references , and what to save instead
  • Save during gameplay asynchronously

Sponsored

What Save Game Is: A Box You Carry Out

Every value in a running game lives in memory. The player's HP, their gold, all of it vanishes when you cut the power. To keep it as a file, you have to move just the values you want to keep into a separate container and write that out . That container is the Save Game.

It breaks into three steps.

StepWhat you doNodes used
MakePrepare a "type" that decides what gets saved(Create a Blueprint Class)
FillCopy current values into the box and write it to a slotCreate Save Game Object / Save Game to Slot
OpenPull the box out of the slot and put the values back into the gameLoad Game from Slot
Moving in-game values into a box and writing the box into a slot; loading retraces the same path in reverse

A slot is the name of the save file. Specify a string like "SaveSlot01" and a file is created under that name. Change the name and you get multiple save files.

Sponsored

Step 1: Create the Box Type

Right-click in the Content Browser and choose Blueprint Class . In the parent class dialog, type SaveGame into the "All Classes" search box and select SaveGame . It isn't in the row of common-class buttons, so you pick it from the search.

Name it BP_SaveGame . Open it and add the values you want to save as variables.

Variable nameTypePurpose
SavedHealthFloatHP
SavedGoldIntegerGold
SavedLocationVectorPlayer position
SavedItemIDsName (array)IDs of held items

Don't write any logic in this Blueprint. Use it purely as a container that lists values.

Note: keep the saved variables to a minimum. Anything you can recompute on load (max HP, item display names, total attack power from equipment) doesn't need saving. The more fields you save, the harder it becomes to keep save-file compatibility later.

Step 2: Fill It and Save

Saving goes in the order of "prepare the box", "move the values in", "write it out".

Blueprint node graph creating the box with Create Save Game Object, setting variables in order, and writing it out with Save Game to Slot
BP_PlayerCharacter (or GameInstance)
Custom Event: SaveGame
  → Create Save Game Object (Save Game Class: BP_SaveGame)
      Return Value → Promote to variable (name: SaveRef)
  → Set Saved Health (Target: SaveRef, Value: CurrentHealth)
  → Set Saved Gold (Target: SaveRef, Value: Gold)
  → Set Saved Location (Target: SaveRef, Value: GetActorLocation)
  → Save Game to Slot (Save Game Object: SaveRef, Slot Name: "SaveSlot01", User Index: 0)

Don't forget to select your BP_SaveGame in the Save Game Class pin of Create Save Game Object . Leave it empty and no box gets created.

Save Game to Slot returns a bool telling you whether it succeeded. Wire that return value into a Branch and you'll notice when a write fails.

Careful: Save Game to Slot blocks until the write finishes. For a small save of just numbers it's instantaneous, but calling it during gameplay can cause a brief hitch. The fix is covered in the bonus section.

Step 3: Open It and Restore

Loading is the reverse. But it takes two extra steps .

Blueprint node graph checking with Does Save Game Exist, then casting the Load Game from Slot result to BP_SaveGame before reading values
Custom Event: LoadGame
  → Does Save Game Exist (Slot Name: "SaveSlot01", User Index: 0)
      → Branch
          True →
            Load Game from Slot (Slot Name: "SaveSlot01", User Index: 0)
              Return Value → Cast To BP_SaveGame
                As BP Save Game →
                  Set Current Health (Value: Saved Health)
                  → Set Gold (Value: Saved Gold)
                  → Set Actor Location (New Location: Saved Location)
          False →
            Print String ("No save data found")

The first is checking existence with Does Save Game Exist . On a first launch there is no save file, so without this you get "for some reason nothing happens".

Strictly speaking this check isn't mandatory. Load Game from Slot returns None on failure, so catching it with Is Valid achieves the same thing. But there are cases where the file exists yet is corrupt or the wrong type , so it's safest to also handle the failure branch of the Cast below.

The second is Cast To BP_SaveGame . Load Game from Slot returns the base Save Game type, which doesn't expose variables like SavedHealth . Cast it to your own class and the variables become readable (→ the Cast article).

"Saving works but loading returns nothing" is almost always this missing Cast.

Sponsored

Hands-On: Save at a Checkpoint and Restore

Let's assemble the pieces so far into something you can actually use. Action game checkpoints, roguelike per-floor saves, open-world hub saves. "Record when you pass a point, and send the player back there on death" is the same structure in every genre.

The end result

Touching a checkpoint saves the game, and even if you later die from a fall, you resume with the HP, gold, and position from when you touched it .

The full flow: touch a checkpoint to save, fall to your death, then respawn back into the saved state

Setup to follow along

Give BP_SaveGame three of the variables from step 1.

VariableTypeDefault value
SavedHealthFloat100.0
SavedGoldInteger0
SavedLocationVector(0, 0, 0)

Give BP_ThirdPersonCharacter the following.

VariableTypeDefault value
CurrentHealthFloat100.0
GoldInteger0
IsDeadBooleanfalse

Then create BP_Checkpoint (parented to Actor) and add a Box Collision component. In the details panel, confirm that Generate Overlap Events is on and that the Collision Preset is OverlapAllDynamic (a setting that responds to Pawns). Leave these at their defaults and touching it fires no event.

You also need three bits of groundwork to make this run.

What to prepareDetails
GameMode setupDefault Pawn Class must be BP_ThirdPersonCharacter
Level placementPlace one BP_Checkpoint
A way to gain goldFor testing, temporarily add an event on a key press (say the 1 key) that adds +100 to Gold

The checkpoint side

On BP_Checkpoint 's Box Collision, hook On Component Begin Overlap and, if the thing that touched it is the player, call the player's save routine.

BP_Checkpoint
On Component Begin Overlap (Box)
  → Cast To BP_ThirdPersonCharacter (Object: Other Actor)
      As BP Third Person Character →
        Save Game (call the player's Custom Event)
        → Print String ("Checkpoint recorded")

The player side

Use the save and load events built in steps 2 and 3 as-is. Save the position with GetActorLocation and restore it with SetActorLocation .

Next, build "dying". This is the first place people get stuck: don't leave it to UE's built-in Kill Z . A Character that falls past Kill Z gets destroyed, so the restore logic you wrote on that Character never runs.

Instead, detect the fall yourself. Call OnDeath from Tick on BP_ThirdPersonCharacter , or from a Box Collision placed under the floor ( OnActorBeginOverlap ).

BP_ThirdPersonCharacter
Event Tick
  → Get Actor Location → Break Vector (Z)
  → Z < -500 AND IsDead == false
      → Branch True → Set IsDead (true) → OnDeath

In the restore routine, reset the falling velocity before loading. If you only restore the coordinates with SetActorLocation while downward velocity is still applied, you'll start falling again the instant you return.

Custom Event: OnDeath
  → Stop Movement Immediately (Target: Character Movement)
  → Load Game (the Custom Event from step 3)
  → Set IsDead (false)

Wire the Character Movement component into the Target of Stop Movement Immediately .

Note: this setup isn't a "respawn" that rebuilds the Character. It returns the same Character to the save point and restores its state . That's easier to work with in solo development, and your UI and camera references stay intact.

Verifying it

Press 1 to raise your gold to 300, touch the checkpoint, then walk off the edge of the floor. You've succeeded if your position snaps back to the checkpoint and your gold is still 300.

  • Gold drops back to 0 → a missing connection on Set Saved Gold when saving, or a missing Cast when loading
  • Position restores but you keep fallingStop Movement Immediately is missing
  • Nothing happens when you fallOnDeath isn't being called. Check you aren't relying on Kill Z, and check the Z threshold
  • Touching the checkpoint does nothing → the Box Collision's Generate Overlap Events or Collision Preset settings

One more thing: stop PIE, hit Play again, and run only the load . If the previous values come back, that confirms they live in a file and not just in memory. Testing within a single Play session can't confirm that.

Two things to take away.

  • Saving is just "copy the current values into the box": the checkpoint's only job is to send the signal, and the player decides what gets saved. With that split, adding save fields never requires touching the checkpoint
  • Restoring takes more than coordinates: velocity, input state, the animation that's playing. You need logic to stop the "momentum" that survives after you move the player back. Skip it and you get "I came back and immediately died again"

Once you're saving more than ten fields, grouping them with a Struct lets you add fields without adding nodes.

Sponsored

What You Must Not Save

Save Game variables will happily accept Actor references and component references. No error either. But any design that relies on that will break.

Left: a saved Actor reference comes back empty on load. Right: values like IDs and coordinates restore fine

A reference points at "the object itself", not at the data inside it. References can restore under the right conditions, such as Actors placed in the level from the start, but Actors spawned at runtime will not restore , and state like the referenced object's HP isn't saved along with it. In practice: it sometimes works, and you can't rely on it.

Don't saveSave this instead
A reference to the equipped weapon ActorThe weapon's ID ( Name or Integer )
Item Objects in the inventoryAn array of item IDs
An Actor reference to the current roomThe room's name, or the player's coordinates
A reference to a WidgetAn Enum representing the screen that was open

So the basic policy is save only values and rebuild from them on load . Restoring the real weapon from an ID requires a lookup from ID to object, so you combine this with a Data Table or Data Asset.

Bonus: Good to Know for Later

Prepare for the day an update saves more. Adding a variable to a SaveGame class is safe, but renaming or retyping loses the old save's value. Carrying a single SaveVersion handles it, and it's cheapest to add right now while you're creating the save class (→ Versioning Save Data).

  • Save asynchronously during gameplay: using Async Save Game to Slot instead of Save Game to Slot pushes the disk write into the background, which eases the hitch. But it doesn't remove the stall entirely . Marshalling the values still runs on the game thread, so with many saved fields there's still an impact. The Completed pin fires when it finishes, but it fires on both success and failure . Run Success through a Branch and only show "Game saved" when it's True
  • Where save files live: in the editor, ProjectFolder/Saved/SaveGames/SaveSlot01.sav ; in a packaged Windows build, %LOCALAPPDATA%/ProjectName/Saved/SaveGames/ (the location differs per platform). While testing, deleting this file recreates the "first launch" state
  • Where to call saving from: the logic you wrote on the player doesn't disappear, but traveling to another level rebuilds the Character, so the values held in its variables are lost . When it's just a level-to-level carry-over that doesn't warrant writing to a file, putting them in the Game Instance alone keeps them alive through the session (the mechanics are also covered in Subsystem/GameInstance)
  • Adding fields later: adding variables to BP_SaveGame still lets you read old save files (the new variables get their defaults). But renaming or deleting a variable loses its value. Name them as if you're deciding for good the first time
  • Save files can be edited: a .sav is an ordinary file in a place the player can reach. For an offline solo-developed game, that's not worth worrying about at first
// Defining the type in C++
UCLASS()
class MYPROJECT_API UMySaveGame : public USaveGame
{
    GENERATED_BODY()

public:
    UPROPERTY()
    float SavedHealth = 100.0f;

    UPROPERTY()
    int32 SavedGold = 0;

    UPROPERTY()
    FVector SavedLocation = FVector::ZeroVector;
};

Saving and loading use UGameplayStatics::SaveGameToSlot / LoadGameFromSlot , with AsyncSaveGameToSlot / AsyncLoadGameFromSlot for the async versions. A variable missing UPROPERTY() will not be saved. That's the most common C++ stumble here.

Note that UPROPERTY() alone is enough for saving (no SaveGame specifier required). If you also want to read and write the variable from Blueprint, add BlueprintReadWrite .

Summary

  • Save Game is a box you carry things out in . Three steps: make it (the class), fill it (Save to Slot), open it (Load from Slot)
  • Loading needs an existence check with Does Save Game Exist and a type conversion with Cast To . Missing values are almost always a missing Cast
  • Don't rely on references to Actors or objects. Save values like IDs and coordinates, and rebuild on load
  • When restoring, restore velocity, not just position . Forget it and you die again the moment you return
  • Use Async Save Game to Slot to reduce hitching when saving during gameplay. Completed fires on failure too, so branch on Success

In your game, when is the moment a player would hate to lose their progress? That's where your first checkpoint goes.