NetRay 2.0 - Advanced Roblox Networking Library

NetRay 2.0 - Advanced Roblox Networking Library

Overview

NetRay is a powerful, optimized networking library for Roblox that significantly enhances RemoteEvents and RemoteFunctions with advanced features such as batched events, event prioritization, automatic compression, and circuit breaker protection.

Why Use NetRay?

Performance & Efficiency

NetRay improves memory usage and reduces network overhead by compressing data before transmission. It supports two types of compression:

  • Run-Length Encoding (RLE) ā€“ Ideal for repetitive data sequences.
  • Lempel-Ziv-Welch (LZW) ā€“ Great for general data compression.

By batching multiple events together and compressing payloads, NetRay reduces bandwidth consumption and improves game responsiveness. This leads to less lag and more efficient networking.

Key Features

  • Intuitive API: Designed to feel like standard Roblox RemoteEvents, making it easy to learn and use.
  • Promise-based Requests: Simplify asynchronous communication with a built-in Promise implementation.
  • Typed Events: Enforce type checking for event arguments using Luau types.
  • Automatic Compression: Optimize network traffic for large data payloads with automatic compression.
  • Circuit Breaker Pattern: Prevent cascading failures by temporarily disabling problematic events.
  • Event Prioritization: Prioritize critical events to ensure they are processed first.
  • Event Versioning: Maintain backward compatibility with versioned events.
  • Batched Events: Reduce network overhead by batching frequent small events.
  • Middleware Support: Add custom logic to event handling with middleware functions.
  • Comprehensive Metrics: Track network performance with detailed metrics and analytics.
  • Secure Events: Ensure secure event handling with server-side verification.
  • Documentation Generator: Automatically generate documentation for all registered events and request handlers.
  • Binary Encoding/Decoding: Automatically Encodes and decodes compressed data to save more bandwidth and ping

Screenshots & Results

NetRay reduces bandwidth usage significantly in high-frequency event scenarios. Below are results from testing, firing an event every 0.01 seconds with an 8 KB payload:

Roblox Default:


image

NetRay:
image

Links


Getting Started

Installation

To include NetRay in your project:

  1. Copy NetRay.lua into your game.
  2. Place it in ReplicatedStorage.
  3. Require the module in your scripts:
local NetRay = require(game:GetService("ReplicatedStorage").NetRay)

Usage

Server ā†’ Client Communication

Firing an Event to a Single Client

NetRay:FireClient("EventName", player, arg1, arg2)

Firing an Event to All Clients

NetRay:FireAllClients("EventName", arg1, arg2)

Firing an Event to a Group of Clients

NetRay:FireClients("EventName", {player1, player2}, arg1, arg2)

Example

NetRay:RegisterEvent("ShowNotification")
NetRay:FireClient("ShowNotification", player, "Hello, World!")

Customising and Registering a Event

NetRay:RegisterEvent("PlayerJoined", {
    rateLimit = 100, -- Events per minute
    throttleWait = 0.1, -- Minimum time between events
    priority = NetRay.Priority.HIGH, -- Event priority
    typeDefinitions = {"string", "number"}, -- Enforce argument types
    batchable = true -- Allow batching
})

Client ā†’ Server Communication

Sending an Event from Client to Server

NetRay:FireServer("EventName", arg1, arg2)

Example

-- Server
NetRay:RegisterEvent("PlayerJumped")
NetRay:RegisterRequestHandler("PlayerJumped", function(player, height)
    print(player.Name .. " jumped " .. height .. " studs!")
end)

-- Client
NetRay:FireServer("PlayerJumped", 10)

Request/Response (Advanced Networking)

Client Requesting Data from Server

NetRay:RequestFromServer("GetPlayerStats"):andThen(function(data)
    print("Received stats:", data)
end):catch(function(error)
    print("Request failed:", error)
end)

Server Handling the Request

NetRay:RegisterRequestHandler("GetPlayerStats", function(player)
    return {
        health = 100,
        level = 5
    }
end)

Batched Events (Optimizing Network Traffic)

NetRay can batch multiple events together to reduce the number of RemoteEvent calls.

Enabling Batching

NetRay:RegisterEvent("DamagePlayer", {batchable = true})
NetRay:FireServer("DamagePlayer", player, 10)

How it Works:

  • NetRay automatically batches small, frequent events.
  • Batches are processed at a set interval (default 0.2 seconds).
  • Compression is applied if the batch exceeds a threshold.

Security Features

Server-Side Validation

Preventing Exploits by Verifying Data:

NetRay:RegisterSecurityHandler("GiveGold", function(player, amount)
    return amount >= 0 and amount <= 1000
end)

Circuit Breaker Protection

NetRay automatically disables problematic events if they repeatedly fail.

if NetRay:_isCircuitOpen("PlayerJumped") then
    warn("Skipping event due to circuit breaker")
else
    NetRay:FireServer("PlayerJumped", 10)
end

Conclusion

NetRay provides a more efficient, secure, and scalable way to handle networking in Roblox games. It is ideal for reducing lag, securing communications, and optimizing data transfer.

NOTE

This is my first module, and I expect mistakes, errors, and issues. I would appreciate any feedback and improvements.

Original Idea: @ffrostfall
BridgeNet2

If you find any issues, please let me know!

Version List

Current Version: v2.0.2

NetRay v2.0.2

  • Fixed Multiple issues
  • Binary encoding enabled
  • improved module layout
  • Not backwards compatible

NetRay v2.0.1

  • Improved Binary Encoder/Decoder
  • Implemented Binary Encoder/Decoder during compression to save more bandwidth

NetRay v2.0.0

  • Original Module
12 Likes
  • why should i use this over alternatives (bytenet, zap, blink)
  • why no buffers

this has server checks right

are these screenshots taken in studio

:coefficients: funny example

1 Like

Hello,

Itā€™s up to you if you prefer those, but unlike others, this module uses automatic compression to reduce memory usage when sending and receiving data, a simple and easy-to-use API, Binary Encoding that dynamically chooses the best uint size based on the value:

  • uint8 for small numbers.
  • uint16 for medium numbers.
  • uint32 for large numbers.

Netray doesnā€™t have a buffer system right now, but it has a batch event, compression a circuit breaker and other features you may find useful!

1 Like

Yes they are if you would like I can test it in Roblox as well although it shouldnā€™t affect it

Updated this, I will update the post as I improve the layout and features.

Features Planned:
Custom Binary encoder

How does the compression work?

BTW, you can edit your replies or quote a post to respond to multiple questions, you donā€™t need to make a new one every time

BTWBTW, the model is offsale.

1 Like

Right now, when you fire an event it will check if the data is above the threshold to compress if so it will choose either the pre-selected or defaults to auto where it chooses the historically more efficient method

it uses RLE and LZW compression methods

1 Like

Appreciate it, I must have forgotten to make it distributable.
the GitHub repo also has a download to it

1 Like

Iā€™d love a comparison against other alternatives like ByteNet and Blink.

1 Like

I am not that familiar with either but I can send some once I get it done

1 Like

Hey, is this how to use it?

Server

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local Modules = ReplicatedStorage.Modules

local NetRay = require(Modules.NetRay)
NetRay:Setup()
NetRay:RegisterEvent("UI")

Players.PlayerAdded:Connect(function(Player)
	local UI = script.UI:Clone()
	UI.Parent = Player.PlayerGui
	
	NetRay:FireClient("UI", Player, UI.Name)
end)

Client

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local NetRay = require(ReplicatedStorage.Modules.NetRay)
local TextRendererManager = require(ReplicatedStorage.Modules.TextRendererManager)

local Player = Players.LocalPlayer

local CFont = TextRendererManager.CFont

NetRay:Connect("UI", function(UIName: string)
	print(UIName)
	local UI = Player.PlayerGui:FindFirstChild(UIName)
	
	if UI then
		local Background = UI:FindFirstChild("Background")
		local TextFrame = Background:FindFirstChild("Text")

		local TextRender = TextRendererManager.new(TextFrame, `Hello, {Player.Name}!`, {
			Font = CFont.new("Robust", 40, "Regular", "Normal"),
			Color = Color3.fromRGB(255, 255, 255),
			XAlignment = Enum.TextXAlignment.Center,
			YAlignment = Enum.TextYAlignment.Center,
			LineSorting = true,
			WordSorting = true,
			Transparency = 1
		})

		task.wait(3)
		TextRender:Show(true)
	end
end)

Update: So basically I need to make my ServerScript to have task.wait(1) or else it will not Fireā€¦ How to fix it?

Players.PlayerAdded:Connect(function(Player)
	local UI = script.UI:Clone()
	UI.Parent = Player.PlayerGui
	
	task.wait(1)
	NetRay:FireClient("UI", Player, UI.Name)
end)
1 Like

this happens because your server script is firing the event before the client has the chance to connect with it. You need to ensure the client has loaded everything they need to before firing the event from the server. you can have the client fire an event to the server to signal theyā€™re ready

1 Like

Hello,

As voidage said

You are trying to fire to the client when the client and client scripts havenā€™t fully loaded and ran.
you can do as you have done by using a delay or you can wait until the player fully loads via

Player CharacterAdded:Wait()

this should yield until the player and character are fully loaded

Your use of the module seems to be good though!

1 Like

NetRay v2.0.1

  • Improved Binary Encoder/Decoder
  • Implemented Binary Encoder/Decoder during compression to save more bandwidth

The Github repo and Roblox model have been updated to reflect the update!

Edit:
Disabled Binary Encoding/Decoding temporarily

Hey! Awesome module. Thanks for mentioning BridgeNet2! Iā€™ve been using it in the past, but I moved on to Warp recently. However, I noticed that Warp has this annoying delay when requiring it and Iā€™m not sure how to fix it.

It may be an issue of mine, but I basically have the events in 1 moduleā€¦

local Events = {}

Events.Player = {
      LoadData = Warp.Client("LoadPlayerData")
}

...

But basically Warp has been archived and itā€™s unfortunate. So I was thinking if this module is possible to do this WITHOUT it delaying of some sort. Due to this I canā€™t require the said ā€˜Eventsā€™ module at the top of my code as it will literally yield until the event gets created or something (thatā€™s what Iā€™m assuming with Warp right now).

1 Like

Hello,

I am not exactly sure what you mean but there isnā€™t a delay.
as long as the server is setup and registers the event it should be alright

As long as this is done on the start of the server it should work fine

I am not sure why I am having trouble understanding the setup for this. I would appreciate assistance if possible. Using my current setup below, I want to change my client->server ā€œJumpEventā€ to use NetRay. I believe my disconnect is with the registering event first and how to use a :FireServer properly without any arguments as shown in your usage documentation.

Example of one of my events (Local script):

local jumpEvent = replicated_storage:WaitForChild("JumpEvent")
jumpEvent:FireServer()

Should it look like this? (This does not work for me on local script when trying to trigger the JumpEvent)

local NetRay = require(game:GetService("ReplicatedStorage").NetRay)
NetRay:RegisterEvent("JumpEvent")
NetRay:FireServer("JumpEvent")

I know I am clearly doing something wrong and being dense. Just need a little nudge :wink:

1 Like

Did you run setup and register the remote on the server?

Yes I did run the server setup. But I did not register the event on the server. So, do I need to register the event on the server and local script?

1 Like

I think I found an issue, I will try fix it soon and let you know