Use multiple GameStates?

I know I can switch the GameStateClass in the GameMode but how do I create a new GameState for each map? I know that the GameState resets between maps but it does not recreate it (thus BeginPlay() and such do not fire on the second map and so on).

I have a project with multiple mini-games but the problem is that switching from one game to another sometimes requires a different GameState. Is this possible or am I doing it wrong?

// This code changes the GameStateClass prior to loading another level but my GameState is not being destroyed and recreated for some reason?
void AMyGameModeBase::SwitchGameState(TSubclassOf<AGameStateBase> newGameStateClass)
{
	if (newGameStateClass != nullptr)
	{
		GameStateClass = newGameStateClass;
	}
	else
	{
		LOG_NULL_ERROR("newGameStateClass")
	}
}

WorldSettings → GameModeOverride does not seem to work either.

Instead of creating a different game state you could create an enumeration. With this, you will be able to use the same game state and differentiate between the map rules within the same game state based on the enumeration.

What I use now:

if (UGameplayStatics::GetCurrentLevelName(GetWorld()) == BOARD_LEVEL_NAME) { /* do something */ }

However, this is a problem because sometimes my GameState needs to run code from its constructor but the constructor (and other methods like BeginPlay()) are only called once when the first level loads…

Also this if-checking (or enumerations or whatever) seems so dirty to me. I can’t believe that we are supposed to do it like this? Not to mention what happens when you combine 3D and 2D minigames and such and end up with a really huge and disgusting single GameState… Is this really the way to go?

I assumed that the GameState is destroyed when loading a new level (which would be handy since I could use this to create another one instead) and then recreated but apparently this is not the case. Mine remains the same between levels.

It’s weird that the GameModeOverride doesn’t work. I suspect an Unreal4 bug.

Anyway, you can use multiple GameStates like this (put in your C++ constructor of your GameMode):

if (UGameplayStatics::GetCurrentLevelName(GetWorld()) == BOARD_LEVEL_NAME)
{
	static ConstructorHelpers::FClassFinder<AC_CBGGameState> gameStateClass(TEXT(P_BP_CBG_GAME_STATE));
	if (gameStateClass.Class != nullptr)
	{
		GameStateClass = gameStateClass.Class;
	}
	else
	{
		LOG_ERROR_SAFELY("Unable to find GameState class.")
	}
}
else
{
	GameStateClass = AGameStateBase::StaticClass(); // Or whatever your default class is
}

I find this a bit stupid but okay it works and I can now use multiple GameStates as desired based on map name without resorting to large switch-statements and messy GameStates.

As for the reason why my GameState was not resetting between maps, I used the wrong node to open a map. I used “Load Level Instance” instead of “Open Level” by accident. I didn’t know that the GameState can persist between maps this way.