Script execution order, when to initialize an object in GameState that is used by Controllers and HUDs?

Hello,

I have a PlayerController for my Camera pawn. Within the controller I hook into Event:BeginPlay and the BeginPlay function bootstraps the PlayerController. One of the steps in this bootstrap process is to call my GameState.GetBuildingManager method that returns an Actor instance (Actor instance is used by my HUD buttons), but what’s actually being returned at this time is None/Null. (See my PlayerController below)

The arrow below is pointing to the method that is returning None/Null instead of my Actor. NOTE: I deliberately disconnected the return value of GetBuildingManager() from my call to Create Master HUD Widget for debugging reasons and forgot to reconnect it for the screenshot.

My GameState hooks into Event:BeginPlay too, as a way to bootstrap itself. It’s at this time when it spawns a new BuildingManager actor.

My overall question to get me unblocked is: At which point should I create the BuildingManager object in my GameState so it’s available to the PlayerControllers at Event:BeginPlay? Should I move the BuildingManager Actor initialization to GameState.ConstructionScript()?

I already discovered the event dispatching order for Event:BeginPlay is first triggered on PlayerControllers and then the GameState. At this point I only need to know what event or function will be called only once on the GameState and before PlayerControllers Event:BeginPlay.

The solution and answer to the question is below.

BeginPlay seems to be called on all Actors (including Game State) roughly at the same time. Meaning the likelihood for race conditions is very likely.

My solution was to implement a custom “event queue” in my Game State. This queue contained an array of PlayerControllers that were added to this array during the OnPostLogin event in the Game Mode (I overrode the OnPostLogin event).

After my GameState’s BeginPlay event is executed I iterate the array of PlayerControllers that have joined the server and I call an event on each one. The custom PlayerController event then replicates an event to the owning client to tell the client that the GameState is ready to be used (it’s BeginPlay event is done executing).

I implemented special checks so if a player joins the game after GameState’s BeginPlay event is called instead of adding the player controller to an internal array queue, I just call the event on the player controller immediately.