How to load GameState data from a save file?

Hi, I was trying to save game state variables but found out that the game state gets constructed AFTER loading (loading happens before beginPlay) so its not loading with the rest of the actors. This seems to be by design as far as I know.

I tested loading again the gameState data from the GameState BeginPlay but somehow the data is not assigned. I am sure the data gets saved, seems to be a problem with restoring the data.

I followed TomLoomans guide for the save/Load structure.

What is the correct way of loading data? Is saving the GameState a bad practice?

EDIT:

Ended up loading like so in case anyone have the same problem:

// Here I saved the MapName and Options to use them later
void AMyGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
{
	Super::InitGame(MapName, Options, ErrorMessage);
	
	InitGameMapName = MapName;
	InitGameOptions = Options;

}


void AMyGameMode::PreInitializeComponents()
{

	Super::PreInitializeComponents();

	//Notify saveGame subsystem in case we want to load a saveGame
	const UGameInstance* GI = GetGameInstance();
	if (GI != nullptr) {
		USSaveGameSubsystem* SG = GI->GetSubsystem<USSaveGameSubsystem>();
		if (SG != nullptr && HasAuthority()) { SG->OnPreStartGame(InitGameMapName, InitGameOptions); }
	}

}

EDIT:

Game state name changes, not sure why but its not reliable to use the name as a loading identifier.

I found that the BeginPlay functions are all non-deterministic, but there is an event that is fired from UWorld when all of the BeginPlay functions have been fired, so I hook into that to load my stuff.

GetWorld()->OnWorldBeginPlay.AddUObject(this, &AYourCoolActor::InitLevel);

But the load should be done before BeginPlay, otherwise it may lead to incorrect initialization.

Still, its a useful trick for general initialization.

I guess that depends on what you are loading. “GameState variables” could mean anything. You weren’t clear on what you needed to set up.

If you want to set something up before the BeginPlay functions are called, there are many different functions that get called before that, including:

• GameInstance.InitializeForPlayInEditor
• GameInstance.Init
• GameInstance.StartPlayInEditorGameInstance
• GameInstance.OnStart
• GameModeBase.InitGame
• GameModeBase.PreInitializeComponents

These get called before GameModeBase.StartPlay which calls all the BeginPlay functions of the actors in the world.

2 Likes

Sorry I meant to load saved data from a file. Used InitGame, but since GameState is created after I had to load on GameMode::StartPlay() before Super::StartPlay().

It was the closest to InitGame that I could find but as you said PreInitializeComponents runs before so Its probably a more appropiate place for loading. Ended up loading like so in case anyone have the same problem:

// Here I saved the MapName and Options to use them later
void AMyGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
{
	Super::InitGame(MapName, Options, ErrorMessage);
	
	InitGameMapName = MapName;
	InitGameOptions = Options;

}


void AMyGameMode::PreInitializeComponents()
{

	Super::PreInitializeComponents();

	//Notify saveGame subsystem in case we want to load a saveGame
	const UGameInstance* GI = GetGameInstance();
	if (GI != nullptr) {
		USSaveGameSubsystem* SG = GI->GetSubsystem<USSaveGameSubsystem>();
		if (SG != nullptr && HasAuthority()) { SG->OnPreStartGame(InitGameMapName, InitGameOptions); }
	}
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.