Net v0.5.0
Net v0.5.0
Net v0.5.0 is here with some big changes and improvements. This version introduces a new concept called Routes, adds complete Strict-typing and Auto-completion to the library, and introduces some new features.
Routes
Routes completely replace Identifiers, which are now internally handled by Net. You can create a Route the same way you used to create your single Net object, except this time you're encouraged to create as many as you need instead of one. The concept of Identifiers are completely abstracted away and all you need to do is create Routes for name-spacing.
Routes can be Reliable or Unreliable. Reliable events are never dropped and are always in order per frame. Unreliable events might be dropped on bad connections, but they are always received in order per frame.
You can also strictly type Routes to get auto-completion and type-checking when Sending and Querying packets.
local Net = require("Net.luau")
type Net<U...> = Net.Net<U...>
local PlayerLoaded: Net<boolean> = Net.new({
Channel = "Reliable"
})In this example, we create a new Route that will send a boolean over the Reliable Channel. It's identical to how you would create a Net object in previous versions, it is however encouraged to store them in an routes.luau Module like how you would with Identifiers.
You will need to migrate your existing Net code to use Routes. The Introduction to Net is fully updated, it's a great resource to learn how to use Routes.
Strict-typing + Auto-completion
This version was made with the goal to introduce full Strict-typing and Auto-completion into Net for a better developer experience.
You can Strictly type and get full Auto-completion for your Routes by adding a type annotation to it when creating it. The type can be any number of any types that you want and it will work for type-checking and auto-completion.
For example,
local Net = require("Net.luau")
type Net<U...> = Net.Net<U...>
local defaultConfiguration = {
Channel = "Reliable",
Event = "default",
}
-- Payload for replicating Entities
type EntityPayload = {
[string]: { -- EntityId
[string]: { -- Component name
data: ComponentInstance<T>
}
}
}
-- Replicate Matter Components
local MatterReplication: Net<EntityPayload> = Net.new(defaultConfiguration)
-- Signal that the Player has loaded
local PlayerLoaded: Net<boolean> = Net.new(defaultConfiguration)
return {
MatterReplication = MatterReplication,
PlayerLoaded = PlayerLoaded,
}In this example, we create two Routes that are strictly typed. In our first one, we annotate it with the EntityPayload type which will type-check our MatterReplication Route when we send Matter Entities and Components over our Net. In the second one, we provide a boolean to signal when the Player has loaded to the server.
You're not limited on what you can annotate here, you can specify multiple types like Net<number, boolean, string, any> and it will work.
Type-checking and Auto-completion work when using Route:send() or Route:query() in the arguments and returned values. Type-checking will not work during runtime, you'll have to do your own checks in your code to ensure the correct type of data was sent over the Net, we are working on a feature to allow you to do this easily in the future called Middle-ware.
Unreliable Routes
This release also contains support for the all new UnreliableRemoteEvents. These new UnreliableRemoteEvents allow for you to send unreliable data across Net, for more information see the DevForum Post.
You can create an Unreliable Route using the Configuration,
local Net = require("Net.luau")
type Net<U...> = Net.Net<U...>
local ExampleRoute: Net<any> = Net.new({
Channel = "Unreliable"
})Hooks
Net had always provided a utility function for integrating itself into your Matter ECS, Net:start(). While this was helpful to some, Net lacked proper support for other code structures. While there was the ability to use net._bridge:step() it was only a workaround for proper support.
Introducing.... Hooks! Hooks are a new way to integrate your Routes' scheduling into your code. These hooks will allow you to properly run scheduling on any event, making it accessible and versatile to any setup you may have. Hooks are simply functions, a function which you can call in accordance to any event.
To make a hook, you can use the new Net.createHook({ Route }) function and passing in a table of your Routes, after you call this function it will return another function that you can use anywhere to step your Routes' scheduling.
local RunService = game:GetService("RunService")
local Net = require("Net.luau")
local routes = require("routes.luau")
local hook = Net.createHook(routes)
RunService.Heartbeat:Connect(hook)In addition to this, the net:start(loop) method has been replaced with a similar Net.start(loop, { Route } function that internally behaves similarly to the Net.createHook({ Route }) function, except it does not return a function because that's all handled for you!