Order in which components load, communication between components.

Can someone please explain to me the order in which things are initialized? I did some research and what I concluded was the below initialization order. But please correct me if I’m wrong.

Note: I’m using Unreal Engine 5.4 with blueprints, dedicated server Netmode = RunAsClient. With only 1 client right now.

My current understanding as to the Order in which things are initialized:

  • GameMode (server)
  • GameState (server)
  • PlayerController (server + client)
  • PlayerState (server + client)
  • Pawn (server + client)
  • HUD (client)
  • GameState (client)

Note: It seems like the GameState on the server spawns first, then when the client connects the gamestate on the client spawns later?

So in my game, I’m needing to access things form various places, so I make reference pointers where needed. For example: from the BP_GameState, I need to access my BP_PlayerController so I stored a variable reference. And from the GameMode I need to access BP_GameState, so i stored a variable reference. From my BP_PlayerPawn I needed to access BP_PlayerController, so I stored a variable reference.

There were some interesting initialization orders, so in some cases I had to make some event dispatchers to go back and set reference variables when that BP was finally initialized.


This is the issue I ran into today. My server spawned a BP_GameState, which is great, but I need access to my BP_PlayerController and it’s currently null. So maybe that means the player hasn’t connected to the server yet?? So I’ll need an event dispatcher to go back and update the variable once the player connects?

So my question really is. What is the order in which things actually load? And how do you guys keep communication between components open? Am I going about it correctly by storing reference variables? And am I correct in sometimes I have to make event dispatchers to backtrack and update a reference variable when something finally initializes? Or is this hacky hocus pocus and there’s a much better way?


My project maps and modes in case this is helpful.

Bonus question: If my server stores a variable reference pointer to a blueprint (that is replicated) in my GameState (also replicated), is it safe to assume that the variable reference pointer will still work on both the client and server? Or do the client and server need separate reference variables?

Thank you!

I did not investigated multiplayer for that, however in singleplayer i think GameInstance is first.
You can also make game systems (in C++) and they load around same time as GameInstance (but i am not really sure if i loaded them manually from game instance, or they load self).

For my game i made simple solution:

  • on begin play added usual get all actors, check if reference is valid, if it is store it in variable.
  • then on event tick same stuff if its valid stop checking, and store valid reference. This way every reference to blueprints i needed was valid after some time. This beats that silly delay 0.2 sec.

Yeah I never ran into this issue when my prototype was running in Standalone… But now that i’m client/server, it’s confusing as hell.

Yeah I will not use a hardcoded delay. That’s just dumb. But I have thought about a ghetto chain of loops that wait for things to initialize, then set up reference variables everywhere lol. But that seems ghetto too.

This should be the correct order, perhaps without a couple things possibly not listed that might start somewhere in-between

ServerClient:

  • GameInstance ( Server )
  • Level ( Server )
  • GameMode ( Server)
  • GameState ( Server+Client )
  • Character ( Server+Client )
  • PlayerController ( Server+Client )
  • PlayerState ( Server+Client )
  • HUD ( Client )

This Link to the Network Compendium might very well have this informatioon in there somewhere as well, haven’t quite explored the whole thing yet

unfortunately it is different between standalone and editor so we need to test in standalone frequently.

you can have a loop check if references are valid
ie if invalid call itself until valid which breaks the loop

i use a different way though, eventually your probably want load system/screens. you can use this to check if your refs are loaded but i have a ClickToStart mechanic where by the time the player clicks everything will be loaded. the good thing is it works for multiplayer too, because once all players have clicked your know they are loaded/ready

1 Like

Just get logging plugin (it makes log pretty). And make in C++ print to log function that also prints to some log file.

In every blueprint you want check print to log, that it initialized. With time stamp. Helped me a lot looking what starts after what. Also there were differences in order between editor, standalone, and coked/packed version.

Oh i call this problem (jokingly) chicken and egg. :slight_smile:

Okay you bring up a good point. I haven’t even yet implemented a GameInstance yet. I should probably do that while I work on this topic! Because it seems very relevant. The internet says that GameInstance is not replicated. The server can have its own GameInstance and the client can have its own GameInstance.

So in my POC, I found that my Server’s PlayerController hits BeginPlay before my Client’s GameState, and really before anything client happens at all. Does that mean there’s an inconsistency or that I’m doing something wrong or does it mean that there is just more than one way to skin a cat? Maybe what I’m doing isn’t wrong just different somehow.

Also there were differences in order between editor, standalone, and coked/packed version.

Deal lord don’t scare me. LOL. I passionately hate that sort of thing. But that’s life sometimes.

Okay with this scare tactic in mind, I think I’ll seriously consider the ghetto loop approach. Maybe I’ll even make a function out of it. A function that Gets the reference, returns it if it’s valid and if not waits until it is valid. I could see that having bad side effects though, or just slowing load time.

Or maybe, this is one of those times that I should just as F it and just call GetPlayerController → Cast to BP_PlayerController in a lot of places to save me a headache. I know casting all the time is slower, but this could avoid some headaches. I just hate knowingly doing things inefficiently. And it won’t work everywhere, Because in the case when it’s just not ready yet I’ll still need one of the other above solution ideas.

Think of Game Instance as basically the program itself

The way that the CastTo node works it only loads it once, so you could call it in a loop and it would only load it the once, and return valid every other time as its already loaded

Same thing if Function A uses CastTo
Then Function B uses CastTo, Function B will not have to load it, but will return valid

What do i mean by that? if it’s already in memory you don’t end up with multiple copies

Still doesn’t help of course if your trying to access something that doesn’t exist yet tho

If the Actor is replicated, it will be the same yes, Replication works such that everything present in the level is loaded by all clients including ServerClient if doing a listen server

The Server then has the one true version after that and any changes made that replicate are then sent over to the client

Ex All clients spawn Characters with 100 health… Game starts, Client A takes some damage(20), All other clients get this info… so when accessing their copy it’ll have the same 80 Health

Network Compendium

There’s certain things that are better to be done in the PlayerState or Controller, etc rather than the Character and vice versa ( Essentially Loading in the correct order ) ( This is another part of why Multiplayer is “Hard” )

When you run in Editor it all sorta runs on one thread, there is a setting in there somewhere for “launch server in background” or something like that that you could try and use to make your results between PIE and Standalone be the same

If Standalone Vs PIE is not what you meant and Standalone Vs Listen Server is..
Then all your observing is the Server now has it’s own set of Objects

Ex

Server:
-Game Instance
-GameMode
-Controllers

Client:
-Game Instance
-Controller

Notice how the server has more stuff to load up, so while when you played Standalone it went

-Game Instance
-Game Mode
-Controller

as your essentially playing as Server, or in other words you have it all under one thread
vs Listen would be “Two Threads”

Standalone and Packaged should be the same with the exception of performance

To say it in the blender guys voice, This is not Optimal

Not sure exactly what you may be trying to do but there’s usually a better way Than Hard Referencing everything and Linking/Chaining it all together

Ex You load the Character but the Character has a reference to GameMode Which has A reference to Some Hud Which has a reference to some Object, Well now every time you load Character you load all that other stuff as well ( or will do soonly if it’s on Begin play )

This can get out of control rather fast.. one of your goals as a Dev is to try and minimize these References in order to use less Memory

Rather Than “Wait until it’s loaded” approaches, It’s best Where possible to use an event dispatcher or Interface

Tho if that’s not possible you don’t want your

If your gonna do this, i suggest using the later so if it Always fails it’ll at least give up eventually and not just be a loop that forever runs in the background


Sources and Tons more detail:

From Epic themselves
-Myth Busting ( Common Misconceptions )
-Blueprint Communication ( Why And Where BPs should pass data )
-BPs In-Depth

UnOffical but solid:
-Network Compendium ( Everything Multiplayer )

The Server Will exist and likely finish all of it’s stuff before a client ever joins