(post deleted by author)
Hello, I’m getting this error on the server-side
And this is my setup on the server
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Modules = ReplicatedStorage.Modules
local BridgeNet = require(Modules.BridgeNet)
--
BridgeNet.Start({
default_send_rate = 60,
default_receive_rate = 60,
})
I think it is probably it’s creating the bridge before actually completing the task of initialization, you could fix this by adding a variable that tells you when the module is ready for production use
I will make sure to add an error message for this, and I’ve corrected the documentation. I apologize for the mistake on my end, but this is why it’s in alpha
It’s actually send_default_rate, and receive_default_rate.
0.3.3-alpha
Get it here.
- Better error handling / messages
- Removed unused function in ServerBridge/ClientBridge.
- Added .CreateUUID(), .PackUUID(), .UnpackUUID(). (ty Pyseph!)
- Added .DictionaryToTable(), which converts a dictionary into an alphabetically-ordered table.
- Switched .ChildAdded for the client’s serdeLayer to be in serdeLayer._start()
- Switched “Network” documentation to be “BridgeNet”- Network was a working title.
- Removed one_remote_event from config.
Edited for hotfix to .CreateIdentifier and connections.
If anyone has any suggestions / ideas for BridgeNet, please mention them here! I’ll see if it fits in with the goals of BridgeNet, and if possible I’ll add it in.
Hi ^
Lucky me to have stumbled upon this at the exact right time. I am trying to rotate character’s waist by sending a value from local script to server and then doing the rotation on the server itself. This works fine, but since I’m using remote events, with many clients it will lag like hell, so I want to use your module.
But since the documentation doesn’t provide some necessary information, I hope you can help me figure this out ^
Here’s how it works without BridgeNet
Client:
function updatewaist(dt)
local cameralookvectorY = workspace.CurrentCamera.CFrame.lookVector.Y
local radian = math.asin(cameralookvectorY)
if camMove.Value == true then
repEvent:FireServer(waist, c0*CFrame.fromEulerAnglesYXZ(radian,0,0))
end
end
runService.Heartbeat:Connect(updatewaist)
Server:
replicateEvent.OnServerEvent:Connect(function(sender, waist, rot)
waist.C0 = rot
end)
Now questions about implementing bridgenet into this.
-
It says in the documentation that BridgeNet.Start needs to be called only once for server and client. Does this mean that I need to call BridgeNet.Start only in one server script, and it will work for all the others? And also create it just once for each client, or just create it on the server, and I can use it on the client too without creating?
-
BridgeNet.CreateBridge(). It says that it creates either a client bridge, or a server bridge, depending on where it’s called. So for example in my case, do I need to just call CreateBridge() on client, and then use Fire() without creating anything on the server? So how would I connect to these bridge on the server.
If you could provide some simple example code of firing a remoteevent to server and then doing something on the server,it would be very helpful. And Thank You for very useful module! If not this I would’ve left my game unfinished, since what I’m trying to achieve is a very important aspect of it (Melee Combat System), and Roblox itself doesn’t provide many tools for ping optimization.
about the start command, i think we shouldnt use a table as an arg. because the table indexes for this module are case-sensitive and people might forget if the index name is this or this, so why not make it like this:
bridgeNet.Start(60, 60)
anyway im interested in this module, i always have wanted to optimize remote events so thanks!
This actually showcases a flaw with BridgeNet I’ll get on fixing when available.
As of right now there’s no way to tell when BridgeNet is started. This means you’re kinda forced to use single-script architecture which is something I encourage you to research, but I’m not going to assume everyone who uses BridgeNet will do this.
So, I think what I’m going to do is make functions such as CreateBridge yield until BridgeNet starts. However, it’s possible that it plays nicely without starting because starting BridgeNet connects to heartbeat and all that. I’m still going to make this functions yield until start because I don’t want completely unexpected behavior in my module
the code snippet you asked for:
Client
local Object = BridgeNet.CreateBridge("Test")
Object:Connect(function(arg1, arg2, arg3)
print(arg1)
end)
while task.wait(1) do
Object:Fire("Hello", "world")
end
Server
local Object = BridgeNet.CreateBridge("Test")
Object:Connect(function(plr, arg1, arg2)
print(plr, arg1)
end)
while task.wait(1) do
Object:FireTo(game.Players:GetPlayers()[1], "Received: Fire")
end
To answer your second question, the bridges are just connected by string, and you need to call CreateBridge separately on the client and the server. However, if you need to index a bridge that’s already created, you can do .FromBridge(). As of right now, this will return nil if it doesn’t exist, which means I could probably add in a .WaitForBridge() function to make this process easier.
I think one thing I could do is use symbols instead of text indexes, so it would be like
BridgeNet.Start({
[BridgeNet.DefaultReceive] = 60,
[BridgeNet.DefaultSend] = 60,
})
You’re right, plain text keys are easy to forget and get confused (it’s already happened!), but the reason I don’t want to use the order of arguments is because of how difficult it is to change. Say I want to remove the default send and receive options in a year, what happens then? Backwards compatibility breaks.
And thank you! Every bit of support means a lot to me.
An enum thing is also fine. Thank you for this! will there ever be roblox-ts support too?
Thank You!! One more follow up question.
Assuming I use 1 script architecture, I still need to use 1 server script and 1 client script. Do I need to call BridgeNet.Start both on Server and on Client, or just call it only on the server?
I have it planned for the future, but I wouldn’t count on it.

Thank You!! One more follow up question.
Assuming I use 1 script architecture, I still need to use 1 server script and 1 client script. Do I need to call BridgeNet.Start both on Server and on Client, or just call it only on the server?
You do need to call it on both the server and client.
apologize for bad formatting, on mobile lol
0.4.3-alpha
Get it here.
- Connections now spawn a thread, making them yield-safe and error-proof.
- Added .WaitForBridge()
- Added Roact’s Symbol class- not used for now, will be used for .Start configuration in the future.
- .CreateBridge() now has the same functionality of .FromBridge()
- Server now checks for the BridgeObject to exist before trying to run connections. If it doesn’t exist, nothing happens.
Friendly reminder, you should be using the latest version of BridgeNet at all times. Not doing so can cause issues with your game / result in errors and buggy behavior. For example, before this update, any error in connections would halt the whole process and prevent other connections on the object from running. It was also not yield-safe. This is fixed now.
I don’t know how you achieved this, but this is amazing. I’m doing the same thing I explained above, firing bridge event from client, and on the server changing waist rotation.
I wanted to test the difference myself, so first I fired 100 remote events without using bridge. My ping was 3k+.
Then I implemented bridge and did the absolute same thing. Literally nothing in the code is changed, except instead of remote events I am using Bridge Events. Firing 100 in a single frame. This is the result:
To clarify, even on an empty baseplate I have 100 ping because I live far from the servers, so firing 100 Bridge Events every frame has basically same toll on performance as an empty baseplate.
TLDR: Magnificent module providing incredible network optimization.
I definitely recommend everyone using this module, as it will allow you to implement much more things in your game without causing massive lags.
@ffrostfall I recommend you create a way to donate to this module voluntarily, I would gladly donate.
1 question: “CreateBridge() now has the same functionality of .FromBridge()”
If I understand correctly, this means that if a bridge is already created, it will get the already created bridge, instead of creating a new one with same string, right? Or should I implement my own logic for that?
Thank you so so much for the feedback! Appreciate the praise a lot, however I do have a tip for you- instead of sending it constantly per heartbeat/whatever, you can cache the value to detect if it’s the same. That way you’re not firing it constantly.
If you’re firing anything else like a string to say “this is rotation”, do it with BridgeNet.CreateIdentifier
. It was made specifically to compress strings, and it’ll further optimize your networking.
As per your question, yes. If you create a BridgeObject with .CreateBridge and one already exists, it’ll return that.
This is because it doesn’t make sense to have multiple objects for a single remote. You do not need to implement your own object.
1.4.3-beta
Get it here.
- Removed .FromBridge, use .WaitForBridge or .CreateBridge (createbridge returns the existing bridge object if it exists)
- Configuration object now uses symbols instead of regular strings
- Added global custom logging support. UNSTABLE, DONT USE IN PRODUCTION
- Changed some loops to use ipairs instead of pairs
- Used table.clear instead of tbl = {} for better efficiency
- Fixed Disconnect
- General optimizations (thank you @Baileyeatspizza)
- Fixed ClientBridge breaking if the client’s bridge was created before the server created the bridge (thank you evanchan0819)
- Fixed client-to-server communication only sending the first argument
Upcoming features
- roblox-ts port
- Re-adding middleware
- Re-adding rate limiting
- Runtime typechecking for RemoteEvents
Just a thought, I’ve got no idea how this works but could you make sending the data from the server parallel? It could probably speed it up on the server.
I’m not sure how I’d do that. It’s a single table that produces a single table
Server to client seems to be working for me, client to server doesn’t seem to be working for me. Is this a bug or am I doing something wrong?
Server
local MineBlock = BridgeNet.CreateBridge("MineBlock")
BridgeNet.Start({
[BridgeNet.DefaultReceive] = 60,
[BridgeNet.DefaultSend] = 60,
})
MineBlock:Connect(function(Player, Block)
print('fired')
end)
Client
local MineBlock = BridgeNet.CreateBridge("MineBlock")
local UserInputService = game:GetService("UserInputService")
BridgeNet.Start({
[BridgeNet.DefaultReceive] = 60,
[BridgeNet.DefaultSend] = 60,
})
UserInputService.InputBegan:Connect(function(Input, GameProcessed)
if GameProcessed then return; end
if Input.UserInputType == Enum.UserInputType.MouseButton1 or Input.UserInputType == Enum.UserInputType.Touch then
local Target = RbxMouse:GetTarget()
if Target.Instance then
MineBlock:Fire(Target.Instance)
end
end
end)
No errors whatsoever, I have print lines in my actual code for debugging and they all print fine. Is there something I missed?
I tried testing but it doesn’t work for me nor print anything on the server.
Server:
local BridgeNet = require(game.ReplicatedStorage.BridgeNet)
local Remote1 = BridgeNet.CreateBridge("RemoteEvent1")
BridgeNet.Start({
[BridgeNet.DefaultReceive] = 60,
[BridgeNet.DefaultSend] = 60,
})
Remote1:Connect(function(Player, ...)
print(Player, ...)
end)
Client:
local BridgeNet = require(game.ReplicatedStorage.BridgeNet)
local Remote1 = BridgeNet.CreateBridge("RemoteEvent1")
script.Parent.MouseButton1Click:Connect(function()
Remote1:Fire("Hello", "this is a test.")
end)
You need to start it on the client too