AGameState, match data, and BeginPlay question

I’m making some classes that feel like they should belong as part of AGameState. E.g, data about which in-game factions love or hate which other factions. It’s really global data about the state of the game, which will have a default value when the game begins, and then update as the game progresses. I have some questions related to this:

  1. When a new game starts, I want to initialize this game state data from master data that feels like it should belong in AGameMode. However, if I do this in BeginPlay(), that will happen too often, won’t it? E.g, if the human saves the game to disk, then loads the game later, won’t BeginPlay() be called again? I wouldn’t want to re-initialize the gamestate data then; it should use the last data that was serialized in the save game. What I’m really after is something like BeginGame(), that will happen once and only once per game, not per game play session. I’m not sure about it, but it seems like BeginPlay would happen for each save/load cycle. What is the recommended way to do per-game initialization like this?

  2. I want to be able to edit the “game mode” type defaults in the editor, but AFAIK you can’t do so right now. E.g, if I add a new UPROPERTY(EditAnywhere) in AGameMode, it isn’t exposed in the editor. I can set the data up manually in C++ code, but then I’ll have to copy the data into the game state on match start. On top of that, if there are actors that hold pointers to this data, I’ll have to find them all and update their pointers to point to the AGameState data when the match starts, which seems awkward.

I feel like I am missing something important about how this is designed to work.

Hey they just did a stream on gameplay framework and design. :wink:
And you are correct as soon as the actor is spawned in world it calls BeginPlay()
You should probeboly look into how saving is done and how you load the data.
That way if saved data is beeing loaded you can use that and if not then use default values.

For 2 the game mode can be set in the editor, and in my opinion is the best way.
Go to: World Settings for your map and you can set it there, and Pawn/ Controller/ AI classes as well…
For new UPROPERTY`s you need to re-compile for them to show up in editor.
As long as they have the correct meta tags.

// Read Write rights in BP all the time.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Category, Sub Category")
// Only default write access in editor, not when game starts. 
UPROPERTY(EditDefaultsOnly, BlueprintReadReadOnly, Category = "Category, Sub Category")
// Only Read access in BP and can only be changed by code executing.
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Category, Sub Category")

Also the GameState and GameMode is available from any actor in the world.

GetWorld()->GetGameState(); // Game State
GetWorld()->GetAuthGameMode(); // Game Mode (only available on server).
GetWorld()->GetGameInstance(); // Game Instance Class

Hope this helps.

Thanks WCode! About #2, I know I can set the game mode itself in the editor, but if I added new UPROPERTY items to the AGameMode class, those didn’t appear in the editor when I tried, even after a recompile. I thought it wasn’t possible after reading this thread, where it seems like that was considered by Epic but rejected.

Am a bit unsure I understand what you are trying to do.
If you add a new member to the your Game Mode class and have the UPROPERTY macro above the member.
With the meta tags i mentioned above they should become visible once you have re-compiled.

Did you have a Blueprint or the Base Class set as Game Mode class?
You will need to make a BP of your new game mode class and edit property`s from there.

Its a known bug , after multiple hot reload you might need a restart of the editor for the properties to show up in the BP