ByteNet | Advanced networking library w/ buffer serialization, strict Luau, absurd optimization, and rbxts support. | 0.4.3

0.4.3

Fixes

  • Fixed i16 allocating 8 bytes instead of 2.

Improvements

  • Significant optimization to optional types
  • Array serialization is roughly ~2x as efficient
  • All data type write functions now directly reference the buffer writer. This means all allocation calls are inlined, and there are roughly ~3x less function calls.
1 Like

ByteNet on roblox-ts

The roblox-ts version is under 0.4.3-tsprev1 to ensure everything is typed properly. When I am more confident in the typings I will upload the main 0.4.3 version.

You can see the typings here.

Im probably going to need your script, and it would be better to ask in the OSS server (but beware, they dont give you good string patterns for getting URLs)

@ffrostfall any chance this will be fixed in the future?
Thanks.

How I can send an Instance?
chars

How is this compared to: Security/Performance/Features

You shouldn’t worry with security if you have proper sanity checks on the server and aren’t sending sensitive information like damage (that shouldn’t be done on the client), but from the looks of it, ENet only acts as an exploit protection and still uses normal events

1 Like

Is there going to be a feature where a certain value can be two or more types? For example:

local packets = byteNet.defineNamespace("namespace", function()
	return {
		event = byteNet.definePacket({
			reliabilityType = "reliable",
			value = byteNet.array(byteNet.either(byteNet.uint8, byteNet.vec3, byteNet.cframe))
			--There could be more than one type that can be sent in the array
		})
	}
end)

You should never have that setup, you need to know whats getting passed.

Is it possible to use bytenet to purely send remote events? My approach was:

		--!native
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ByteNet = require(ReplicatedStorage.Packages.ByteNet)

return ByteNet.defineNamespace("messaging", function()
	return {
		ExposeChoice = ByteNet.definePacket({
			value = ByteNet.struct({
				ChoiceName = ByteNet.string,
			}),
		}),
		ExposeMessage = ByteNet.definePacket({
			value = ByteNet.struct({
				Message = ByteNet.string,
			}),
		}),
		CloseDialogue = ByteNet.definePacket({
			value = ByteNet.struct({
				_ = ByteNet.nothing,
			}),
		}),
		SwitchToChoice = ByteNet.definePacket({
			value = ByteNet.struct({
				_ = ByteNet.nothing,
			}),
		}),
		ChoiceChosen = ByteNet.definePacket({
			value = ByteNet.struct({
				UUID = ByteNet.string,
			}),
		}),
		FinishedMessage = ByteNet.definePacket({
			value = ByteNet.struct({
				_ = ByteNet.nothing,
			}),
		}),
		-- EnablePP = ByteNet.definePacket({
		-- 	value = ByteNet.struct({
		-- 		_ = ByteNet.nothing,
		-- 	}),
		-- }),
		-- DisablePP = ByteNet.definePacket({
		-- 	value = ByteNet.struct({
		-- 		_ = ByteNet.nothing,
		-- 	}),
		-- }),
	}
end)

is there a better approach than mines or is this fine?

So wait i’m so confused especially since those struct and other things were added,

i have been basically trying to send packets stuff that could sent data values like that for a tower defense game:

[12] = { -- enemy ID that was attacked by towers in the same frame
    53,                -- ID of the first tower that attacked
    57,                -- ID of the second tower that attacked
    12,                -- ID of the third tower that attacked
    38,                -- ID of the fourth tower that attacked
    {                  -- Additional data for a specific tower's attack (5th tower)
        98,            -- ID of the tower that attacked with more data
        {              -- other data, here IDs of enemies affected by explosion (secondary targets)
            38,
            85,
            97
        }
    }
     -- other towers that could have perhaps attacked that enemy
}
-- other attacked enemies during this frame

but i don’t really understand how can i put that under struct and etc
since well ofc it’s never gonna be the same

That’s not true. You don’t need to know (exactly) what’s being passed around. In fact, ByteNet already provides something similar to this with optionals.

Doesn’t matter if it’s provided, its bad practice to not know what’s being passed.

It’s not, and stuff like this has been in use for centuries now (e.g. tagged unions, std::variant), and I’d argue it does matter if it’s provided, because it shows the library author does not seem to think “it’s bad practice”.

Anyway, ByteNet specials are already dynamic by nature, so enums (or tagged unions, if you prefer) wouldn’t be that different from what’s already in ByteNet today, and I’d like to see you argue that maps are bad practice because “you don’t know what’s being passed around”.

Well, I tried this library and it seems insanely good compared with BridgeNet2 in terms of low receive stats, but I have a few questions:

  1. When sending 200 blank events per frame the ping stats go crazy due to the fact that the receive value is actually much lower than when using BridgeNet2. Is it possible to further optimize this module so that ping doesn’t kill the game? Will you actually work on the ping optimizations?

  2. Is there any functionality close to RemoteFunction:InvokeServer() ? Yes, this module does a great job of reducing the amount of receive close to 0, but there definitely needs to be something to invoke the server on the client.

It seems that this module is indeed one of the best network modules at the moment, but its functionality should definitely be increased, because now you can’t invoke server on the client, so you have to use other networking modules to do that, for example, BridgeNet2.

2 Likes

Yes! Would love to see this also work with remoteFunctions

there’s another thing that’s unfortunate and it’s that it doesn’t work well when placed inside an actor
it will bug out and only 1 person will have it work like normal
in multiplayer, it just won’t work

Would sending data every frame not cause memory leaks whether or not you are sending it through reliable or unreliable?

The reliable and unreliable event data queues get cleared after all the data is processed into a buffer and the cumulative buffer sent (every Heartbeat), so no, there won’t be any memory leaks.

oh ok I was asking because I was using it for a combat game and someone said that using bytenet for combat games causes data leaks