My question is pretty simple to ask, but I cannot for the life of me find an answer.
When entering an OnRep for a replicated value, is that OnRep automatically scoped to that specific replication? i.e. My server sends an Enum to the player which is replicated. Inside of the OnRep for that Enum there is a switch to specify what to do on state changes. If the server were to send a second replication (or the client were to receive 2 replicated values back to back by a temporary slowdown in network) is it possible that the local value might change during the execution of the OnRep initiated from the first replication.
I’m running a dedicated server multiplayer game, and upon completing the load of the map and associated player loadouts the server sets an Enum on the gameState to BattleBegin, this pretty much just removes the loading screen from viewport. Then after a configured delay the server updates the Enum again to Deployment.
From time to time, one of the clients will receive both updates, whereas the other only logs the Deployment as being received/handled.
What is not making sense to me is how one of the clients is receiving the change, while the other is not, especially since the player does always receive the second update to Deployment.
Any ideas? Perhaps OnReps are scoped to specific updates but quick changes back to back be parsed as one single change? Though that wouldn’t quite explain why one client receives them separately and one receives only one.
Replicated variables only send the latest variable change so intermediate changes might never reach all clients.
In other words Replicated variables are lossy by design however you can rely on the variable eventually being updated unlike RPC’s.
Hey Garner, thank you for this. Don’t know if I skipped over it in my reading or was reading the wrong sources. I was looking at Replication too much like Reliable RPCs. i.e. upon the server finding that the client did not receive the change, it would attempt to re-send the same change, rather than the latest value.
Reliable RPC is often what people tend to use because it sounds “safe” however Reliable RPC’s have a lot more overhead than regular RPC’s and if not used correctly will cause clients to be disconnected.
These RPC’s also ONLY get sent when the Client has an open connection and will never be resent when the client does open the connection later.
Unreliable RPC’s are in normal condition just as good as Reliable but with a “safety valve” that can open when a connection gets flooded which is often what you want in order to avoid a disconnect.
And then you have replicated variables that should be the ONLY choice when dealing with state and not just an event that doesn’t matter a moment later.
So the 3 cases :
1 Reliable RPC’s: Used very rarely.
An example could be a Client-Server-Client handshake. Client has a certain feature enabled. The Client tells Server Yes/No. The Server acknowledges to the client.
2 Unreliable RPC: The standard choice of RPC for Client input or Server Sound or Effects that only matters if present at the time of the event.
3 Replicated variables: The standard workhorse of replication that should be used for every state change in the game.
So yeah what you are doing ain’t gonna work reliably because nothing guarantees BattleBegin ever happens on clients since you are changing to Deployment quickly after.
A quick solution to the bug would be to change your check for removing loading screen.
Enums are convertible to byte (which are small integers), so instead of doing this :
//OnRep_State
if (State == BattleBegin)
RemoveLoadingScreen()
You could do the following instead (maybe need to convert to byte type in blueprint) :
//OnRep_State
if (State >= BattleBegin)
RemoveLoadingScreen()
Now this should handle players joining late and even in the middle of the game if necessary.