Packet - Networking library

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

1 Like

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
3 Likes

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

1 Like

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.

4 Likes

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

2 Likes

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!

2 Likes

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

1 Like

Nice module; would love to see a future update where this is added too.

3 Likes

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

2 Likes

Thanks for sharing I have slightly modified the benchmark

Benchmark.rbxl (240.9 KB)

Network Data

Blink


Zap


ByteNet


Packet




Fire CPU times

image



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
image
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

3 Likes

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 :slight_smile:

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:
image

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:


image

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:
image

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! :slight_smile:

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 :pray: :face_holding_back_tears:

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

Now im no expert but uhm


is this supposed to happen? Shouldnt it simplify it as one call? Or does it add one per key (event)?
If it should work like this then just heart this message instead of replying to save everyone some effort lol

image
(here the same event is used 3 times at once)