GameInstance and GameMode in Multiplayer Games

Let’s say I have project that uses a dedicated server and two clients that connect to the game. In this scenario one thing is still not clear to me.

When the user launches the game, it will open some level that usually is responsible for connecting to the server. Before connecting to the server, the client will have a whole set of the game framework classes locally correct? It must have a GameInstance, GameMode, GameState, Pawn, PlayerState, PlayerController etc.

When an instance of the server is created it will also open a level and it will have its own GameInstance, GameMode, GameState etc. Please correct me if I am wrong here. At this point the client should be able to access the local game mode without problems.

When a client connects to the server, it is no longer possible to access the GameMode in the client as per documentation of UGameplayStatics::GetGameMode.

So far so good. From my tests, the GameInstance doesn’t replicate, which means both server and client will have its own GameInstance’s instance correct? In this case, is it safe to store information in the server’s GameInstance if the server needs to load a new level?

Hi mcleary.

Once connected to a map on a dedicated server, the client will not have access to the GameMode or GameInstance.

You are right that the client will have a Game Instance and Game Mode along with other classes such as a Player Controller as they are connecting to the server. However, these classes get thrown away as soon as the client connects to the server.

As you have mentioned, this will leave clients not being able to access the GameMode or the GameInstance.

There is no real way to control when these classes get over-written so it’s best not to use them on the client at all unless the client is in a map that is not connected to the server (such as the main menu).

If you are looking at transferring information on the client between levels, you can use the Player State and the CopyProperties function providing you are using seamless travel. Another way is to use a local save object.

If you are looking at Game data inside the GameMode to be visible or accessible to the clients, then you can replicate this data using the GameState.

Basically, the PlayerState and the GameState are data classes that can be seen as “Facebook profiles” for the GameMode and PlayerController and can be accessible by any client or server as long as replication is set correctly.

Be careful with the GameInstance. The GameInstance should only handle logic and data specifically required for the application itself, so there isn’t any real reason why the client would need to access the GameInstance if the other objects are set correctly. Obviously though, there maybe some reasons depending on the application which you might want this data to be replicated in which case you should utilize the objects mentioned above to do this.

Hope this helps.

Alex

1 Like

Hi mcleary

I am glad you found my explanation useful. If it answered your original question, could you mark it as the answer to help other people find it. That would be great :slight_smile:

The GameMode is not accessible to the clients as it’s the main class responsible for handling player connections to the server and the player controllers’ registration process (OnPostLogin). Once the player controller is registered on the server, it sends this controller to the client and overnights the local controller. This is why the GameMode only exists on the server, because it may try to assign the player controller twice (server and client) which will throw everything out of whack.

Altering this class data on the client could cause heavy internal confusion and is not the way the GameMode is intended to be used.

The GameInstance CAN be used in the client, however, it is best practice not to, unless there are extra control parameters required for the game behavior on the clients (providing it will not affect any of the run time data being handled by the server).

As mentioned, this is why classes such as the player state and the game state are implemented.

Is there anything specific you are looking at achieving?

Thanks

Alex

Ahhh okay :slight_smile:

I hope my explanations helped.

One of the things that helped me to understand networking in Unreal was by dissecting the RoboRecall project released by epic.

Good luck

Alex

Hi Alex,

Thanks for the very detailed explanation. Everything makes sense, however, I would like to ask you about this sentence:

As you have mentioned, this will leave clients not being able to access the GameMode or the GameInstance

In a small test I made, while the clients can’t access the GameMode, since the function GetGameMode returns null, the GetGameInstance function still works and returns a valid object. However, the object is local to the client.

I’ve setup the ThirdPersonCharacter to increment a counter stored in the GameInstance. This graph is executed after connecting to the server. The U key works as expected, it prints Oh No since the GameMode is null. Now, the GameInstance works fine, and each client has it’s own instance, thus, they increment the counter locally.

That’s what’s still a little bit confusing to me, why forbid access to the GameMode but keep the GameInstance? As you said, there might be situations where this can be useful and I just haven’t encountered them yet.

PS: The “Facebook Profile” analogy is an excellent way to explain it.

Is there anything specific you are looking at achieving?
Not at the moment, just trying to get my head around the gameplay framework on a multiplayer environment.