Game Instance¶
Game Instance is the runtime object that survives changing maps. It is useful for run-wide state, but it is not a save file and not a place to store live level actors.
The one-minute version¶
- Game Instance is created for the running game and stays alive until that game instance shuts down. In normal standalone play, there is one. In Play-in-Editor with multiple sessions, each session gets its own.
- It survives
Open Level. GameMode, GameState, level actors, pawns, and widgets are usually recreated with the new map. - Create a Blueprint subclass of
GameInstance, then set it in Project Settings -> Maps & Modes -> Game Instance Class. - Use Get Game Instance, cast to your Blueprint Game Instance class, then read or write your variables.
- Store simple run-wide values here: selected character, current save slot, settings chosen in a main menu, collected count for a run, or services that coordinate map travel.
- Do not store direct references to level actors here across map changes. The actor belonged to the old world and can be destroyed when the level changes.
- Game Instance memory is not disk persistence. If the player quits the game, use SaveGame for data that must still exist next launch.
What it actually is¶
Game Instance is a high-level manager object for one running instance of the
game. It is a UObject, not an Actor, so it is not placed in a level and has
no transform, collision, mesh, or component tree.
The lifetime difference is the point:
flowchart LR
Start[Start game] --> GI[Game Instance]
GI --> MapA[Open Level: Map A]
MapA --> WorldA[World A actors<br/>GameMode, pawns, widgets]
MapA --> Travel[Open Level: Map B]
Travel --> MapB[World B actors<br/>new GameMode, new pawns]
GI --> MapB
MapB --> Quit[Quit game]
Quit --> End[Game Instance shuts down]
That means:
coin count in Character
-> Open Level
-> old Character destroyed
-> coin count resets unless copied somewhere else
coin count copied to Game Instance before travel
-> Open Level
-> new map can read it from the same Game Instance
Game Instance is not magic backup. You still decide when to write values into it and when to read them back out.
Creating one in Blueprint¶
The normal beginner setup:
Content Browser
-> Add Blueprint Class
-> All Classes
-> GameInstance
-> name it BP_MyGameInstance
Project Settings
-> Maps & Modes
-> Game Instance Class = BP_MyGameInstance
Then add variables to BP_MyGameInstance, such as:
CurrentSaveSlotName (String)
SelectedCharacterClass (Class Reference)
CoinsThisRun (Integer)
MasterVolume (Float)
LastCheckpointMapName (Name)
If you forget the Project Settings step, Get Game Instance still returns a
Game Instance object, but it is not your Blueprint subclass. The cast to
BP_MyGameInstance fails because the running object is the default class.
Getting it from Blueprint¶
The usual Blueprint access pattern is:
Get Game Instance
-> Cast To BP_MyGameInstance
-> Get or Set your variable
For example, before changing maps:
Player reaches exit
-> Get Game Instance
-> Cast To BP_MyGameInstance
-> Set LastCheckpointMapName = CurrentMapName
-> Set CoinsThisRun = CurrentCoins
-> Open Level NextMap
Then in the next map:
PlayerController BeginPlay
-> Get Game Instance
-> Cast To BP_MyGameInstance
-> Read CoinsThisRun
-> update HUD / initialize current run state
Guard the cast while debugging. If it fails, check the Maps & Modes Game Instance Class setting before rewriting your graph.
The C++ twin, for the curious (our own example code):
void ATrainingPlayerController::CacheRunStateBeforeTravel()
{
UTrainingGameInstance* TrainingGI = GetGameInstance<UTrainingGameInstance>();
if (!IsValid(TrainingGI))
{
return;
}
TrainingGI->CoinsThisRun = CurrentCoins;
TrainingGI->LastCheckpointMapName = CurrentCheckpointMap;
}
What belongs in Game Instance?¶
Good first-project Game Instance jobs:
- main-menu choices that affect the next map;
- selected character/class/loadout before spawning;
- current save slot name;
- options/settings values before they are applied or saved;
- run-level counters that should survive map travel;
- manager references that are not level actors, such as subsystem access or service-style objects;
- temporary travel data from one map to the next.
Poor first-project Game Instance jobs:
- direct references to doors, enemies, pickups, player pawns, widgets, or level cameras across map changes;
- per-frame movement or combat logic;
- current health if health belongs to the body that can die and respawn;
- every variable you cannot find a better owner for;
- data that must still exist after quitting the application unless you also copy it to SaveGame;
- multiplayer shared state that clients need to receive from the server.
The quick path is to make Game Instance a project-wide junk drawer. The concrete cost is that every Blueprint becomes able to mutate global state, and you stop being able to tell whether a value belongs to the current body, the current level, the current run, or the saved profile. Use it for data whose lifetime really is "this running game, across maps."
Runtime memory vs SaveGame¶
Game Instance survives map travel. It does not survive process shutdown.
| Need | Use |
|---|---|
Value survives Open Level during this play session |
Game Instance |
| Value survives quitting and launching later | SaveGame |
| Value belongs to the current map only | GameMode, GameState, level actors, or map-specific managers |
| Value belongs to the current pawn body | Pawn, Character, or component |
| Value belongs to the local player's UI/input path | PlayerController, HUD, widget, or Local Player subsystem |
A common pattern is:
Load game from disk
-> put selected runtime values into Game Instance
-> travel between maps using Game Instance as the run handoff
-> when player saves, copy durable values into SaveGame
-> Save Game to Slot
Do not store a live actor reference in SaveGame either. Store identifiers, plain values, map names, class references, or your own durable data, then rebuild live actor references when the map loads.
Why actor references go bad¶
Actors live in a world. When Open Level destroys the old world, actors from
that world can be destroyed too.
So this is fragile:
Game Instance variable:
CurrentDoorReference = BP_Door_12 from Map_A
Open Level Map_B
-> BP_Door_12 belonged to Map_A
-> reference is no longer useful
Use one of these instead:
| Need | Store this |
|---|---|
| Remember which door was opened | Door ID, map name, and opened state |
| Spawn selected character next map | Character class reference or asset ID |
| Return to checkpoint | Map name plus checkpoint ID or transform |
| Restore inventory | Item IDs/counts, not item actor references |
| Reconnect UI to player | Re-find current PlayerController/Pawn after the new map starts |
If you need to rebuild references after travel, do it from the new map's BeginPlay or PlayerController setup path, then validate with Is Valid.
Game Instance vs GameMode¶
The shortest rule:
GameMode = rules and defaults for this loaded map/session
GameInstance = run-wide manager/data that survives changing maps
Use GameMode for:
- default pawn/controller/HUD class choices;
- player start and respawn rules;
- win/loss rules for this map;
- match/session rules that are remade with the level.
Use Game Instance for:
- data passed from main menu to gameplay map;
- selected save slot;
- current run state that crosses level loads;
- systems whose lifetime should be the whole running game.
See GameMode & friends, single-player edition for the map-level framework split.
Common traps¶
- The cast fails. Project Settings is still using the default Game Instance class, or you cast to the wrong subclass.
- The value resets when quitting. Game Instance is runtime memory, not a SaveGame file.
- The value resets on Play-in-Editor restart. Starting a new play session creates a fresh Game Instance.
- An actor reference is invalid after Open Level. The actor belonged to the old world.
- A widget reference is stale. Widgets are usually recreated for the new map/player UI path; keep durable data, not the old widget object.
- Every Blueprint writes global values. Too many writers make bugs look random. Prefer clear setter functions or one manager path for important state.
- You used Game Instance for multiplayer shared state. It is not replicated; each running game/server/client has its own instance.
- You put current pawn state there too early. Health, movement mode, and animation state usually belong to the current pawn/component and are copied elsewhere only when the design requires it.
Lookalikes - which one do I want?¶
| Thing | Use when | Not the same as |
|---|---|---|
| Game Instance | Runtime data/managers should survive loading another map. | Disk save data or current map rules. |
| SaveGame | Data should survive quitting and launching later. | A live runtime manager. |
| GameMode | Current map's rules, default classes, spawn/restart decisions. | Cross-map storage. |
| GameState | Runtime state for the current game/session. | Persistent settings. |
| PlayerController | Local player's input/UI/camera/possession path. | Whole-application state. |
| Pawn / Character | Physical body state such as movement, health, collision, mesh. | A stable place for data after the body is destroyed. |
| Game Instance Subsystem | A code/system module should share Game Instance lifetime without stuffing everything into one class. | A beginner Blueprint variable bucket. |
| Level Blueprint | One-off scripting for this exact map. | Cross-map run state. |
Going deeper¶
- GameMode & friends, single-player edition - the per-map framework classes Game Instance outlives.
- Get Player Character / Pawn / Controller - rebuilding live player references after travel.
- Is Valid - guarding references that can be empty or stale.
- Create Widget + Add to Viewport - recreating UI with the current owning player instead of storing old widgets.
- Official docs: Gameplay Framework, UGameInstance, Get Game Instance, Project Settings: Maps & Modes, Open Level by Name, and Programming Subsystems.
- Engine source (requires engine access - we do not reproduce it here):
UGameInstance::Init,UGameInstance::Shutdown,UGameInstance::StartGameInstance,UGameInstance::OnWorldChanged, and related travel/lifetime hooks inEngine/Source/Runtime/Engine/Private/GameInstance.cpp; declarations inEngine/Source/Runtime/Engine/Classes/Engine/GameInstance.h.