Please Help! How to Replicate Client Game Instance Variable to Server?

Hello everyone, hope you’re having a great day!

So, I have a game I am building that takes email password to login and once you login it checks your level which is stored on the database with your email password, this level is say noob, legend and elite. Now when a player logs in the level is stored in a variable at game instance and a new session is created when login button is pressed.

Game instance also has logic that sets it so that based on the level of the player he can enter specific areas so doors open or not, thus we set boolean of Area1 to be true and Area2 to be false. Now, this works with single player without server but when I do listen server the player doors open in front of the Area 1 at client but not on server thus the server collider collides with the client and doesn’t let him enter the Area 1 even with the doors open. How can I make it so that the server doors open for specific player.

I am using On Overlap Event to trigger opening doors.

I had been scratching my head on this for 3 days still no solution yet. Maybe the right way to do it is calling a Run On server event at the Game Instance, but I tried it and what happens is the default value of Area1 and Area2 is false so server only recognizes that doesn’t take in the variable from the client. I’m soo confused!

1 Like

The GameInstance on server is not the same as the GameInstance on client.
They might be of the same class, with same variables, but they do not share memory (=variables values).
Collision has to be handled on server-side, and should also be handled properly on client-sides for smoothness. Thus you have to synchronize (replicate) the variables you want. Using “Run on server” events is the right idea. But not in GameInstance.

GameInstance cannot replicate. Each machine has its own, local, gameinstance and you cannot use replicated variables or functions (RPCs) on them.
Furthermore, there is only one GameInstance on server, for all the players, so it wouldn’t be practical for your use-case. How would you handle if PlayerA and PlayerB can access different areas, but there’s only one game instance on server.

Your best place for this kind of variables is probably the PlayerState. Each player has a player state, on server, which replicates to every client. It’s the class where everybody knows about everybody, where you have variables like the “player name” and “score” so you can see everyone in a leaderboard (for example). As such it would make sense to also put the level/rank there.

So now let’s say you have custom playerstate class with this “Level” variable, and you need to populate it. That’s where a RunOnServer event can come into play.

This is roughly what happens when player joins a server :

  • PlayerA connects to server
  • PlayerStateA is created (on server)
  • All world information is replicated from server to PlayerA (including PlayerStateA)
  • PlayerStateA is created (on client) using replicated information

So what you can do is :

  • Wait for the player state to be created on client
  • Grab the Level from client’s GameInstance
  • Send it to server via RPC (Run on server event)
  • Set the value on server
  • Let the value replicate automatically to all clients

So, something like this (for a naive approach)

Then, whenever you need to test collision, grab the player state of the colliding player and check what you want.



Do note however that this approach is not really viable if your multiplayer needs to be somewhat secure. You cannot trust the client with whatever data (eg. level/rank) he sends to the server.

For proper security the server should retrieve player’s level directly from the database and assign it to the player state. No client-to-server RPC required here. However to implement it can be a bit tedious.
OSS (online subsystems) are supposedly designed to facilitate this sort of mechanism, where the player logs in via OSS, then connects to server via OSS, then server also gets player information via OSS, and all this is abstracted through interfaces which you can either implement or use plugins for. You might want to delve into this rabbit hole.

If not, you can also try to wrap up something yourself.
Clearly you already have a login server and a database.
What you can do is something like this :

  • When player logs in to retrieve his level, generate a token (on the login server), and store it to associate the token with this player. Send the token to the player

  • On the client, store the token (along with the level) in GameInstance

  • In the PlayerState graph above, instead of sending Level via RPC, send the token instead

  • On gameserver-side, contact the login server with the token, and retrieve the true player level

This way the player cannot cheat by simply sending “level=99” with a forged RPC.

Of course there are many more concerns when it comes to security/stability, which is why a fully fledged and tested OSS implementation is probably recommended, but at least I hope you get the main idea.

2 Likes

Thanks @Chatouille for this amazing guide, I’ll try this right away and I am very glad you’ve also provided info on how to do it securely which is also a concern for this project! Will get back to you if there are any problems I face while implementing. Thanks again!

Thanks a lot @Chatouille it is working exactly as I wanted! Although still not that secure but works for a prototype version atm

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.