Update 1.2
No longer possible for the client to make the server print error messages in live games
By stopping the client from making the server print error messages it stops exploiters from flooding the server and causing the server to slow down
No longer possible for the client to make the server print error messages in live games
By stopping the client from making the server print error messages it stops exploiters from flooding the server and causing the server to slow down
Hi what scripts have been changed? cause i converted the module for rojo and 5m after that u updated lol
Just the mainmodule
nothing else
thx, btw will u add a github in future,? i think is a better way to compare and verify updates/minor changes
I personally wont be but if anyone else wants to they can
there is one here: GitHub - mrchigurh/Suphi-Packet: Suphi Kaner Networking Module
but at this time its still on version 1.0
it has now been updated to 1.2
coudnāt we keep track of how Much Client sends Every couple of frames And if that exceeds the Limit as well we dont proccess events for Some time, that way if someone spams buffers that are just in range but still big enough to cause a lag it woud Trigger this and stop them From Firing any More Events? genuanly asking if this woud work
thatās kind of what Packet
already does
this is done per server heartbeat
the server heartbeat is 60 times a second
but a client can select a higher fps for example 120 and they would send 2 events in the same time the server does 1 heartbeat
the server will add up the size from both events and make sure the total of both events donāt pass the limit
in the main module you should fine
table.clear(playerBytes)
this is where we reset the amount of bytes a player has sent if you want to prolong this simple donāt clear the table as often
As someone who hasnāt really looked into or even considered optimising network efficiency before, this seems like a graceful way to handle this system in a considerate way Iāll find easy to implement!
Only question I have; I believe I remember seeing the word āfloatā being used somewhere, cant find it now, but are the āFā variants for number types the only ones that will properly function with floats/numbers with decimal values? I dont remember the video mentioning floats/shows them being used and the block comment guide for number types doesnt seem to clarify either.
yes the F variants are floating point numbers
for example F16
has enough precision to support integers up to 2048
after 2048
it will start to skip hole numbers but it will continue to go up to 65519.999...
then at 65520
it will become math.huge
its also possible to use the S and U as decimal values but in most cases you will want to use the F variants but just to show you that it is also possible with S and U here is a example
packet:Fire(0.123 * 1000) -- if you round this it will give better results
packet.OnClientEvent:Connect(function(number)
print(number / 1000)
end)
local thread = task.spawn(function()
while true do
coroutine.yield()
if cursor.Index > 0 then
if #cursor.Instances == 0 then
remoteEvent:FireServer(cursor:Truncate())
else
remoteEvent:FireServer(cursor:Truncate(), cursor.Instances)
end
cursor:Clear()
end
end
end)
RunService.Heartbeat:Connect(function() task.defer(thread) end)
should be
local thread = function()
while true do
coroutine.yield()
if cursor.Index > 0 then
if #cursor.Instances == 0 then
remoteEvent:FireServer(cursor:Truncate())
else
remoteEvent:FireServer(cursor:Truncate(), cursor.Instances)
end
cursor:Clear()
end
end
end
RunService.Heartbeat:Connect(function() task.defer(thread) end)
because ur calling task.spawn in task.defer, which calling twice thread this add some overhead.
additional change (inline):
if #cursor.Instances == 0 then
remoteEvent:FireServer(cursor:Truncate())
else
remoteEvent:FireServer(cursor:Truncate(), cursor.Instances)
end
to
remoteEvent:FireServer(cursor:Truncate(), #cursor.Instances > 0 and cursor.Instances)
No the first task.spawn is correct because it gets the function to the yield then inside the runservice we resume the yielded thread task.spawn() returns a thread not a function
its faster to resume a yielded thread vs making a new thread every time from a function
also the problem with your single line is that it will pass the value of false
when there are no instances and that would be a waste of data
you can slap an or nil
on that
also, i may be missing something but, what is the benefit of using a thread here? Would just calling the function not be more efficient?
deferring a thread is more efficient then deferring a function by about 2x
the reason we defer is so that if you are using single script architecture or global framework or for any reason you connect to a heartbeat event before packet does
your heartbeat event will run after packets heartbeat event
and if you do packet:Fire() inside that heartbeat event then it will add 0.01666ā¦ seconds of latency
so by deferring it makes sure that packet will run after all other heartbeat events in your game no matter the order they where connected in
so in short by deferring there wonāt be 0.01666ā¦ seconds of latency if you use packet:Fire() inside a heartbeat event
Itās an incredible module. It would be nice to see how it compares to other modules such as Wasp (1.0.9) Fastnet2 and Bridgenet2
Anyone is free to benchmark and post the results
Well as far as Iāve heard and read; Wasp, FastNet2 and BridgeNet2 arenāt really among the absolute best networking libraries.
I believe the only true competitors you have at the moment is ByteNet, Zap and Blink.
its very easy to see how many bytes each type uses by looking at the types modules
if you wanted to you could very easily make a CFrame type that only uses 6 bytes but I would not recommend doing that because the amount of data that is sent is not the only important thing packet comes with 12, 15 and 18 byte cframes
the 18 byte cframes has about the same precision as robloxs built in remote event cframes we could even make a 20 byte cframe that has more precision then remote event cframes but i decided not to include it but its very easy to make your own custom types if you watch the video we make 3 custom types in the video
if you would like to ask me about how each type works id be happy to explain how each type works and if you feel there is a more optimal way to send a type id be happy to listen
id also be happy for people to share there own custom types with the community to use
for example here is a 20 byte cframe that has better precision then remote events but is not included with the module
--!strict
-- Requires
local Cursor = require(script.Parent.Parent.Cursor)
return {
Read = function(cursor: Cursor.Cursor)
return CFrame.fromAxisAngle(
Vector3.new(cursor:ReadS2() / 32767, cursor:ReadS2() / 32767, cursor:ReadS2() / 32767),
cursor:ReadU2() / 20860.438391054722
) + Vector3.new(
cursor:ReadF4(),
cursor:ReadF4(),
cursor:ReadF4()
)
end,
Write = function(cursor: Cursor.Cursor, value: CFrame)
cursor:Allocate(20)
local axis, angle = value:ToAxisAngle()
cursor:WriteS2(axis.X * 32767 + 0.5)
cursor:WriteS2(axis.Y * 32767 + 0.5)
cursor:WriteS2(axis.Z * 32767 + 0.5)
cursor:WriteU2(angle * 20860.438391054722 + 0.5)
cursor:WriteF4(value.X)
cursor:WriteF4(value.Y)
cursor:WriteF4(value.Z)
end,
}
and here is a 17 byte version [Iām not sure how its precision compares to the built in 18byte version]
--!strict
-- Requires
local Cursor = require(script.Parent.Parent.Cursor)
return {
Read = function(cursor: Cursor.Cursor)
return CFrame.fromAxisAngle(
Vector3.new(cursor:ReadS1() / 127, cursor:ReadS1() / 127, cursor:ReadS1() / 127),
cursor:ReadU2() / 20860.438391054722
) + Vector3.new(
cursor:ReadF4(),
cursor:ReadF4(),
cursor:ReadF4()
)
end,
Write = function(cursor: Cursor.Cursor, value: CFrame)
cursor:Allocate(17)
local axis, angle = value:ToAxisAngle()
cursor:WriteS1(axis.X * 127 + 0.5)
cursor:WriteS1(axis.Y * 127 + 0.5)
cursor:WriteS1(axis.Z * 127 + 0.5)
cursor:WriteU2(angle * 20860.438391054722 + 0.5)
cursor:WriteF4(value.X)
cursor:WriteF4(value.Y)
cursor:WriteF4(value.Z)
end,
}
and here is a vector2 that only uses 4 bytes
--!strict
-- Requires
local Cursor = require(script.Parent.Parent.Cursor)
return {
Read = function(cursor: Cursor.Cursor)
return Vector2.new(cursor:ReadF2(), cursor:ReadF2())
end,
Write = function(cursor: Cursor.Cursor, value: Vector2)
cursor:Allocate(4)
cursor:WriteF2(value.X)
cursor:WriteF2(value.Y)
end,
}
and here is a vector2 that only uses 2 bytes
--!strict
-- Requires
local Cursor = require(script.Parent.Parent.Cursor)
return {
Read = function(cursor: Cursor.Cursor)
return Vector2.new(cursor:ReadS1(), cursor:ReadS1())
end,
Write = function(cursor: Cursor.Cursor, value: Vector2)
cursor:Allocate(2)
cursor:WriteS1(value.X)
cursor:WriteS1(value.Y)
end,
}
so to me just running a benchmark and testing each one does not really have any meaning
packet source code should be very easy for most scripters to understand and should give them the power to create any type they want i have included the types that i feel are best for general use but please donāt feel limited to the types that are included
i have never looked at zap or blink but if you notice there doing something better please tell me and ill implement the same type or if you like make the type and share it with us
lol when people ask this. youāre not forced to use anything here, and anybody who posts a resource here is not obligated whatsoever to convince you to use their resource over another. go use zap or blink
Iām not stating itās worse or that there are existing options, Iām asking why I should use it over said existing options and if there are any benefits over them that warrant a switch. Sorry if I sounded rude or something.
Has anyone done benchmarks of this in comparison with blink? The DDOS protection feature in this seems awesome.