Question about replication/fireallclients

This isn’t really documented anywhere by roblox, I wanted to know does replication and fireallclients work through option A or B?

A: FireAllClients/Replication from the server sends the data to each client individually one by one.

Kind of like this:

--How fireallclients works internally (theory)
for _, Player in game.Players:GetPlayers() do
RemoteEvent:FireClient(Player)
end

B: FireAllClients/Replication sends the data to all clients at the same time, instead of going one by one.

I was wondering because if it is option A, then couldn’t I make it so that replication occurs for each client all at the same time through parallel luau? So there will be less of a delay for clients to receive data?

4 Likes

I think it can generally be assumed that it’s done iteratively (one-by-one). It wouldn’t make sense to do it in parallel because the overhead will outweigh the speed benefit since there isn’t going to be a large amount of connected clients. If not, clients aren’t going to receive the packets all at the same time anyways because of latency.

1 Like

Of course there will always be latency because it will always take time to send data regardless. But I think there would be a decent speed benefit. If it’s all done one by one that’s much worse and I think this is the main reason Roblox games have a lot of ping related issues. (Apart from possibly bad networking or excessive replication)

Even at 5-10 players it can really benefit I’d say.

Also could you mind explaining what the overhead would be? Do you mean like scalability?

2 Likes

personally i think it would be option A because if we send the data to all clients at the same time with huge tables of data it would lag the game and roblox wants to minimize the amount of latency recieved

1 Like

There’s going to be overhead switching between serial and parallel, and vice versa - wasted execution time essentially. Parallel luau is only recommended when working with high volume calculation-intensive tasks because small tasks like iterating across 10 players, like in your example, will end up being slower in parallel than series because of the overhead. Slower and/or more expensive, personally, I’ve found when working in parallel that small tasks are about equal in speed to serial execution but end up being more expensive - but even so, you would be trading performance for something that is equal in speed as without.

I don’t even think that it is possible to replicate data in the exact same timestamp. There will always be some delay between each replication, since there is only one operation done per cpu clock tick. Im sure that for loops have very minimal delay and the time difference between each replication is negligent.

1 Like

All RemoteEvent methods (:FireClient(), :FireAllClients(), :FireServer()) cannot be ran in parallel. Attempting to do so will give a thread safety error:

image

The engine internally multithreads tasks, and as @Downrest also stated, remote methods aren’t parallel safe, meaning you can’t use them while in a parallel Luau execution phase.

According to documentation, replication happens at the end of the frame (after Heartbeat), they are sent all at once (with rate limits and bandwidth constraints).

Following this step, the engine sends property updates and events to the server or clients which are later received as part of the replication receive step.
From: https://create.roblox.com/docs/reference/engine/classes/RunService#Heartbeat

1 Like

Where exactly did you identify that replication happens all at once? From the url you linked all I’ve found is info about replication just being a process of the server.

Didn’t know that they weren’t parallel safe thank you

Replication happens at the end of the frame, unless limited by bandwidth, it gets sent out all at once.
“Following this step, the engine sends property updates and events to the server or clients which are later received as part of the replication receive step.

It just says they’re sent to the server/clients. Not exactly that they’re sent all at once. Could still be just an iteration.

I very much doubt it is all happening at the same time because luau was always single threaded up until 2-3 years ago where multi threading wax released. So before that there was no way to truly multi thread.

2 Likes

I might do some benchmarking later to see if that’s true. I’m not 100% sure if it takes quite a bit of compute time to switch from parallel to serial and vice versa but I’ll see.

Oh dang, good catch on the documentation. I’ve heard that Roblox automatically batches events into single packets, though it seems like there is still room for improvement (e.g. networking libraries).

For those reading, this is what the replication receive step looks like:

And about the batching thing, it makes sense. Roblox queues “exceeding RemoteEvents” when network bandwidth goes above 50 KB/s (soft limit) and only attempts to send them once there is available bandwidth, which probably implies that Roblox batches these RemoteEvents. I mean they’re already queued, might as well.

1 Like

Networking is implemented on the C/C++ side, not Luau.
Roblox uses RakNet, which uses UDP.

1 Like

Pretty sure there has always been worker threads though? Microprofiler has been a thing for a while, and when you look at old Roblox videos, you can see different threads:

Ah that makes sense, I am not too familiar with languages outside of luau lol.

So if info is being replicated to all clients all at once. How exactly does this mean replication is sometimes delayed for certain clients? Even when data size is very low?

1 Like

Network conditions!
Data can only get from A to B so quickly, meaning the further physically away they are, the longer it takes for them to receive the data. There is also possible packet loss, where packets fail to reach the destination for a multitude of reasons.

1 Like

Even if you send a packet to all clients at the same time, their ping will still be a deciding factor for when they would receive the packet.

That’s not truly multithreading though. Maybe it shouldn’t be called multithread actually.

Back then, everything ran on a single cpu core in luau. After parallel luau released, everything still by default ran on a single core. But developers were given the option to split work between multiple cores. This is known as “multithreading” although the name doesn’t really match to be honest.