How does a Client determine when PlayerStates are Replicated?

Hi all,

I’m looking to store information in a custom PlayerState regarding the other players (their score, if they have finished a race or not, etc.). When a client joins an in-progress session they can iterate through the GameState::PlayerArray and retrieve all of this information and use it to set their client state to match the already in progress state, great!

However, the information in PlayerState is not replicated immediately upon a client connecting. This means there’s a period of time when the PlayerArray is empty or has stale information and if you try to match the in-progress state you will become out of sync with the other clients/server. You can use the “Delay” node in BeginPlay and wait a arbitrary amount of time but this feels hacky and prone to hard to catch bugs.

Is there a way to know when the GameState’s PlayerArray has successfully replicated the initial state of the world? There doesn’t seem to be any sort of OnRepNotify implementations for PlayerArray so I don’t see a way for the client to know when it has the PlayerArray from the server.

A solution in either C++ or Blueprints is fine, or a common design pattern that everyone uses would also be great!

You can try every tick or with a timer until you succeed. Still hacky and dirty, but less error prone.

Right, I understand that you don’t know when replication will happen until it’s replicated. However, the PlayerArray class doesn’t have any RepNotify for when it is updated (ie: clients are added or removed). It’s not entirely clear how the PlayerArray is replicated as it’s not even marked for replication, which makes me think there’s other code adding/removing from the PlayerArray and the objects are sync’d outside of that. I guess you could broadcast an event when they’re added or removed in the C++ code, but it’s unclear if they will have had their properties updated when they’re first added to the array even.

A less-hacky workaround I’ve come to is that the PlayerState classes use their OnRepNotify for specific properties to tell the GameState that they have changed. Then the GameState broadcasts this via an Event Dispatcher to anyone listening. This means it calls the event multiple times, but should at least cover when a new PlayerState is added + replicated, and when properties are updated.

It does not however, cover the case of a player being removed from the PlayerArray. :frowning:

It is very difficult to know when replication will happen, especially in this context. Realistically, I have never relied on when anything will replicate. Even RepNotify doesn’t have a determined time when it will call, it’ll just have an event when it does.

If you really need to know, you can always have the client call a server function requesting any information you need and then have the server call back down to the client with that information. But again, there is no way to determine when or how long this will take to happen, as it will probably be different for every client.