Server to Client changes replication vs remote events race condition

Server Script:

Part.Transparency = 1
wait(10)
Part.Transparency = 0
Event:FireClient(Part)

Client Script:

Event.OnClientEvent:Connect(function(Part)
    print(Part.Transparency) -- Either 1 or 0
end)

Is a FireClient or a property change replication going to reach the client in the same order they were issued? Is this a race condition? Is the behavior consistent?

4 Likes

This is a great question! I believe events fire and go to the client in order, but I don’t know if the default server/client replicator follow the same rules.

According to the Task Scheduler page, these happen in the same step called Replication Receive Jobs: “Incoming property changes and event firings are applied.”

I can’t discern from this whether chronological order is maintained when changes to be replicated are sent to the client. Unfortunately, the network and client replicator pages don’t detail this either.

I think replicated data is sent across multiple packets depending on the amount of data. I don’t know if the engine needs to wait to receive a certain threshold of the data before making changes or not. Perhaps the client waits until it receives all of the replicated data for that frame. If it doesn’t, there could be a race condition.

Let’s assume it does wait for all replication changes that occurred. Now we need to consider whether the property change and remote event are guaranteed to be executed in the same frame. I believe they are because there isn’t a wait() or anything like that between them, but I could be wrong, so someone feel free to correct me on that. I couldn’t find any sources on this so I’m just providing my intuition.

Lastly, consider this, regardless of everything above: the replication changes are probably not applied simultaneously on the client. Even if they used multithreading or multiprocessing, they wouldn’t be applied at the same time. The only way they could get around this would be to wait for all the replicated changes in the same frame, possibly make the the received changes in a new data model to prevent asynchronous behavior, and then reference the new/modified data model with all the changes applied at the same time. This could serve as a “lock” for the replicated changes until all of the changes for that frame are applied.

Maybe the engine does all that, but I’m willing to venture a guess that it doesn’t at one of those steps. For practical purposes, definitely treat it as a race condition. Theoretically speaking, I would love to see if anyone else knows more about how the replicator works in depth.

Hope this helps!

4 Likes

@Icee444 has a pretty great explanation of what happens. I’m not to sure if it’s correct, but I have a theory. Keep in mind this is just a theory, I don’t actually know what happens.

I don’t think Roblox replicates everything at 60hz. I believe it’s something like 30hz (every 2 frames). So, I believe that Roblox internally stores what is going to be replicated in order (within the 2 frames) and sends that information to the client. The client then receives and executes the info in the order provided. If you change a property before firing the remote, I’m almost certain that it will print the value it’s set to.

2 Likes

This reminds me - I think some things are replicated at different rates. I thought I remember reading somewhere that physics for example replicates a lot faster than other things, but I don’t know what occurs in terms of remote events.

In practice, I agree that calling them so close together would make it almost always be the same in practice. In theory, I don’t know if most people know the answer. And if someone does, I hope they provide an answer and explanation to your question.

1 Like

I’m also struggling with a similar issue to this. I think that even if remote events are fired within the same frame, there’s a possibility that they wont be received on the same frame on the client. This is with the fact that there are many changes made in the datamodel between the two firings, even if the firings and those changes were all made within the same frame. I’ve observed this on my client, where it would receive the first event on one frame, 2 - 4 frames pass, then receive the next frame. I speculate that it’s those changes that caused the delay. Because those changes in the data model would have to go through the default server/client replicator.