Yes I don’t know why it didn’t pick that up but when I specifically set the value to be 256,256,256 in that test file the spike occurred. I am now noticing that it does spike in the test place, I must of not been waiting long enough before
i set the position to 256, 256, 256 and watched for over a minute and it never spiked
this version only sends 256, 256, 256
KingBobPacketTest.rbxl (73.7 KB)
EDIT*
I just watched it for another 5 minuets and still no spike the highest it goes to is ~5.4KB/s
I think yours is getting batched together in someway due to the hash. Sorry for not mentioning it but my hash is set to be the index instead of random and changing that does seem to increase it up to 7-9kb
ok when I set hash to the index it started doing it now I have to find out why its doing it
if you use a Vector3F32
then the problem goes away
but if you use a Vector3F24
or Vector3S16
then the problem exists but I still don’t understand why
and the Hash has to be the index and the vector3 has to be higher then 255 super strange
Could it be due to some sort of mismatch between the UInt8? as 255 is the limit for that
I just tested this with ByteNet and it has the same phenomenon when sending U8 + S16 + S16 + S16
or U8 + U16 + U16 + U16
KingBobByteNetTest.rbxl (71.8 KB)
this will also go up to ~8KB/s
I think it has to do with how Roblox sends buffers but I don’t know what triggers it to happen
so this shows that this is not a problem with any networking library but with how Roblox replicates buffers
we can see the same thing here without using any library
this sends about ~8KB/s
local remoteEvent = game.ReplicatedStorage.RemoteEvent
local amount = 255
local step = 8
local length = amount * step
local b = buffer.create(length)
for offset = 0, length - 1, step do
buffer.writeu8(b, offset + 0, 0)
buffer.writeu8(b, offset + 1, offset / step)
buffer.writeu16(b, offset + 2, 0)
buffer.writeu16(b, offset + 4, 0)
buffer.writeu16(b, offset + 6, 256)
end
while true do
task.wait(1 / 10)
remoteEvent:FireAllClients(b)
end
but this will send about ~21KB/s
local remoteEvent = game.ReplicatedStorage.RemoteEvent
local amount = 255
local step = 8
local length = amount * step
local b = buffer.create(length)
math.randomseed(123456)
for offset = 0, length - 1, step do
buffer.writeu8(b, offset + 0, math.random(0, 255))
buffer.writeu8(b, offset + 1, math.random(0, 255))
buffer.writeu16(b, offset + 2, math.random(0, 65535))
buffer.writeu16(b, offset + 4, math.random(0, 65535))
buffer.writeu16(b, offset + 6, math.random(0, 65535))
end
while true do
task.wait(1 / 10)
remoteEvent:FireAllClients(b)
end
and if we send the buffer as a string it will also use ~21KB/s
local remoteEvent = game.ReplicatedStorage.RemoteEvent
local amount = 255
local step = 8
local length = amount * step
local b = buffer.create(length)
for offset = 0, length - 1, step do
buffer.writeu8(b, offset + 0, 0)
buffer.writeu8(b, offset + 1, 0)
buffer.writeu16(b, offset + 2, 0)
buffer.writeu16(b, offset + 4, 0)
buffer.writeu16(b, offset + 6, 0)
end
b = buffer.tostring(b)
while true do
task.wait(1 / 10)
remoteEvent:FireAllClients(b)
end
so to me this is saying that Roblox is doing some extra optimizations to buffers that can reduce the amount of data they send
Q: does this mean we should not use buffers:
A: no buffers have some magic that causes them to use less data then expected if we use another type we would lose the magic
Q: does it means benchmarking networking libraries that use buffers can be effected by the numbers sent
A: yes we need to be carful when benchmarking buffers because the numbers we send can effect if Roblox's magic takes effect or not
Q: does this mean that the packet profiler plugin is incorrect when measuring buffers
A: yes it does not take the magic into consideration it will show you the worst case scenario
Q: does this mean that a NumberU8
always uses less data then a NumberF64
A: No based on the numbers sent some types might trigger Roblox's magic to take effect and some types might prevent it
Q: how should I benchmark networking libraries that use buffers
A: I don't fully understand what makes Roblox's magic work but sending random numbers that use the full range of the type seams to prevent the magic from working
-- benchmark example that bypasses Roblox's magic
local packet = Packet("Name", Packet.NumberU8, Packet.NumberU16, Packet.NumberF16)
math.randomseed(123456)
for index = 1, 1000 do
packet:Fire(math.random(0, 255), math.random(0, 65535), math.random() * 65520)
end
what features does this have over a CLI such as zap, and are there benchmarks to show the difference in bandwidth? also i believe the quote unquote “ddos protection” is a standard across most libraries and clis
I don’t know iv never used zap or inspected its source
the quote unquote ddos protection doesnt exist in any other buffer library like bytenet, zap, etc ATM. exploiters can spam a very large buffer to both of those libraries and crash the server near instantly.
Is there a maximum length for the number of characters in strings that you can send? I am having weird behaviour when sending a long string to the client from the server where it cuts off portions of the string.
Yes by default there is a limit of 255 character but its very easy to change this limit I even go over how to change the limit in the video at 28:26
https://youtu.be/WoIElUdj64A?t=1706
Great module. Though I’m wondering, is it possible to use Packet for parameters in :Response()
that can either be a dictionary or nil? If I were to use types instead of Packet’s, it would be something like:
type MyTable = {
Apples: number
}
type Test = MyTable?
Just wanted to clarify if this is possible, other than that it’s a really great module!
At this current time this is not supported but in the future the Any
type might support tables but it wont be the most efficent way to send data sending a empty table would be more efficent
Nice module; would love to see a future update where this is added too.
Hello,
I have added Packet & NetRay into benchmark. please test it in your environment.
Benchmark.rbxl (244.3 KB)
versions:
bytenet: 0.4.3
zap: 0.6.19
blink: 0.17.0
packet: 1.2
netray: 1.0.0
note:
- i have to remove buffer size validation in packet module so the benchmark can be run for the packet module.
- i tried to remove client throttles in netray module but seems like still does.
- the bytenet im using is 0.4.3, which is not the latest version, but feel free if you like to update it to 1.0.0 (latest)
- my benchmark result may got different with yours…
result:
- packet doesnt beating the other library (blink & zap) in bandwidth and fps mode, but it beat bytenet, netray & roblox.
- netray fails at every benches & mode… insane lags & studio crashes everywhere. data not sending.
- blink & zap is the wins here…, but overall seems like blink is slightly better than zap(?).
reference result (outdated data):
benchmark made by @.nezuo
Thanks for sharing I have slightly modified the benchmark
Benchmark.rbxl (240.9 KB)
Network Data
Blink
Zap
ByteNet
Packet
Fire CPU times
Summery
When comparing basic types Numbers
Booleans
Arrays
and Structs
, all network libraries perform the same around 5KB/s for array of booleans
and around 32KB/s for array of structs with numbers
When comparing CPU usage Blink
performs the best and Packet
performs the worse this is a area where Packet
could improve while it would be impossible to match Blink
due to there functions being pre generated for each individual packet there should still be room for improvements
Warnings
if you set your FPS to be higher then 60 Blink
will not fire a event every frame like the others causing it to batch more events then the other network libraries
you can comment out Elapsed
if you want to make Blink
work like the other libraries and fire a event every frame i did not do this in the screenshots above but I did limit my FPS to 60
Woah this is awesome. The in-depth video guide was really nice as well. I for one had no idea what bytes are and how/when they were sent (yikes, average 6 month dev moment).
But as they say, the real treasure are the friends we made along the way. Through this post / module I also stumbled over your other projects which are also just as insanely awesome. Personally, I’ll get the mesh editor plugin as well. Thanks for publishing all of these things for free
Personally my favorite part about this module is that the syntax is just like that of regular remote events. Clearly an advantage over alternative modules for me as a beginner.
You’re a legend
Hey guys, I’m trying to implement Packet with parallel luau but there seems to be an issue when assigning the server script to an actor and calling the Packet Module that I created (HelpProblem module). This one:
When calling the HelpProblem module in an actor it seems to create another RemoteEvent. Now this will work if there is only 1 actor which might seem fine but when I added another actor that does the same thing and tried to run it I get this message:

The second actor always returns this error for some reason and I think the reason is because of the duplicate RemoteEvents that is being created? Not too sure.
I want to mention that I called task.synchronise() when calling the HelpProblem module in the server script so it shouldn’t be able to fire the packet module while in parallel (and I think firing events in parallel is illegal in Roblox so it wouldn’t work anyways).
The duplicate RemoteEvents only appears when it is inside an actor and creates a new one for every new actor that calls the Packet Module (HelpProblem module) so when I have multiple scripts that calls the HelpProblem module outside the actors it only uses 1 which is expected:
Then in test 2 I tried creating a module script (CallAtOnePlace module) so that the scripts in the actors can access one point instead of calling them in each actor individually but it also didn’t work:
In theory all these should create one RemoteEvent only since its still running serially on the main thread, but instead it create’s multiple RemoteEvent’s.
Right now my current solution is to just create another RemoteEvent in ReplicatedStorage and directly sending it to the client.
I’m not sure if there is a way to get around this using Packet but please let me know! Thanks for reading!
Here is the Place file if you want to test:
HelpProblem.rbxl (73.8 KB)
I want to mention that I commented out task.wait() in one of the Actors to show the error, but enabling/uncommenting it should work the same, I did this because it spams the output a little bit and to make it easier to see the error.
Also I apologise for the many edits, I initially created this post on mobile then moved to PC to finish it along with the errors in the post
Thanks for reporting this problem ill try to add actor support in the next update but it could be problematic because each actor wont be able to share the same buffer and so it wont be able to batch events from each actor together