Multiplayer Date Storage

Hello, so I’ve been trying to come up with an idea to store data in a multiplayer/networked enviorment, for example ammo count, health, ect. I want to avoid storing sensitive data like that locally as anyone with cheat engine could just change the values and be able to give themselves an unfair advantage. My first taught was to store a players data in the player state, as suggested by various posts and documentaions, however I had trouble getting a working reference to player state associated with any particular character from within the character blueprint. To get around this I used the post login event in the game mode which gives me a controller reference for the connected player, I can then get the pawn reference and player state and directly set a variable in the pawn to the player state, this works perfectly, and since the server never connects but will be playing as the host I just do get player controller in the game mode with index 0 and do the same thing with that controller.

What I would like to know is, is there a better way of doing all of this or is this fine? If anyone has done anything similar then please let me know how you did it, thanks.

You can just store it on your ACharacter. It exists both locally and on the server. Then you can use RPC calls to set these variables on the server copy and have them replicated to the client.

Storing player information in the player state is a good approach, since player states for all players exist on all clients. Bear in mind though, since they do exist on all clients any replicated variables can be read (not written) by any client. So replicated variables in player states are good to make player information available to all clients, for example to display every player’s health on the HUD. They are bad for sensitive information (a hypothetical hacked client has access to them). What you can do for sensitive information that should only be available to the player itself is store it on the PlayerController, which only exists on the server and one player’s client.

Edit: If you work in C++ you can even make variables replicated to “owner only” (the player that owns an actor). Information about this: . This isn’t available yet in blueprint to the best of my knowledge.

This shouldn’t be an issue since Characters as subclass of Pawn have a direct reference to their associated PlayerState. What you may have encountered is that a PlayerState wasn’t initialized client-side yet, when a player joins a server it may take a fraction of a second before the player’s PlayerState is replicated over.

About modifying data as a hypothetical hacked client: know that UE does not let a client simply alter replicated variables. In fact, values are only replicated from server to client. If the client wants to change a variable’s value, he has to use an replicated function call (RPC) for it, which is like a request to the server: the server always has the option to deny the request or even kick the client if it is suspected of sending an invalid request in an attempt to cheat. If a client tries to change a replicated variable directly, it will only change its local value. This just causes this particular client to be out of sync with the server (and other clients), only ruining his own game experience. The only way a client can cheat by lying about values if you have unsafe RPCs prepared, say you have an RPC that lets the client instantly change the player’s position without checking for possible cheating.

Thank you for your reply, yes I can see how a hacked client could read all the variables, I also considered storing all data on the game mode and having clients ask the server to update values or ask to read specific values, but I think in this case I will store all data in player states as it will help me get access to any data I need for things like scoreboards, ect. If people at some point want to make a hack that reads enemy health it’s not the biggest deal, anyways thanks for the input.