Keeping and syncing state such as score for each network player

I’ve got a simple multiplayer FPS setup going, and I’d like to know what is best practice for keeping state about each player that can be synced to all the other players. Currently, stuff like health, ammo, anything related to an instance of a player is easy; the player object just has sync vars or whatever else as needed, and that works no problem. However, I want to store and sync some information that isn’t necessarily tied to an instance of a player object; for example, kill/death count, and player name, so that all players can see a scoreboard. If I used SyncVars on the player, all that would be lost once the player object got destroyed and replaced by a new one on respawn.

Initially, I thought about creating an Id for each player as they connected, or maybe just using the connection id. As soon as a player was created, I would send that id to them, and an RPC to other clients so that they could all have a synced up list of PlayerInfo objects that stored stuff like the player name, score, etc. However, since RPCs aren’t buffered and sent to future connections anymore, this doesn’t work, as only the very first client will receive the info about all the others. Client 0 would see themselves, as well as client 1, 2, and 3 connect, but client 2, for example, would only see themselves and client 3.

Another thing I’ve thought about trying, is using a player object that isn’t the actual player at all, but rather an object that holds all this sort of state and can spawn ‘physical’ players as needed. This doesn’t seem like an intended use of the player objects, though, so I’m worried I’ll run into issues down the line.

Finally, I’ve thought about trying to use Network Messages. In this case, it seems like I would need a sort of two-part approach. When a player connects, the server would send messages identifying each other player that already exists, then send a message to all the players to add the newest one, assigning it a new id based on connection or just some incrementing integer or something. Then, on a score update the server just needs to send a message to everyone with the id of the player whose score is being updated. As long as everyone has the correct id for each player, this should always work regardless of what state the actual player objects are in.

This last approach seems to me like the ‘right’ one for this, but I wanted to run it by the forums and see if anyone has tried something similar. Does this seem like a reasonable way to do it?

As a side note, one of the examples given in the documentation for Network Messages looks like it’s almost exactly what I want to do, except that it sends a “Score” message without actually sending anything about whose score it is.

I recently built a prototype for an FPS, and for this I just disabled player objects when they were “killed” rather than completely destroying them, allowing me to keep stats around and other things.

I thought about doing that as well, but in my case I’m going to be allowing the player to switch between different playable characters/teams/etc, so I want to be able to instantiate/remove/etc the player object without having to worry about it holding that kind of information.

I ended up going with the Network Messages option I thought of, and so far I think it’s a good way to go. The process, more or less, ended up being:

  • When a player connects (OnServerAddPlayer), Send the newly connected player messages containing the id (an int that is incremented every time a new player is added) and name of every other player that already exists, one message per player
  • Send that player another set of messages containing the id and kill/death count of each existing player, also one message per player
  • Create a new player info object, assign it the next id and a default name
  • Send to all clients a message containing the new id and name of the newly connected player
  • Send to the newly connected player only, a message containing their own id (so they know which of all the players that have been added they are)

When a player receives the “Here is your ID” message, it immediately sends back a message containing the id it just received, and the name that player wishes to set for themselves (configured before the player connected). The server receives that and then just sends it out to everyone. This includes the player that just sent it, so the code for receiving those messages is made to simply update the name if the id sent already exists.

1 Like