Skip to main content

Matter

tip

Check out the adapted version of the Matter Example game to see how it's used in a real game.

See all of YetAnotherNet's example projects in the repository.

Being initially made for the Matter ECS, YetAnotherNet provides a simple function for scheduling your Routes to run on your Matter Loop.

Firstly, create a routes.luau ModuleScript in ReplicatedStorage to strictly declare your Routes.

shared/routes.luau
local YetAnotherNet = require("@shared/routes")

local Route = YetAnotherNet.Route
type Route<U...> = YetAnotherNet.Route<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: Route<EntityPayload> = Route.new(defaultConfiguration)

-- Signal that the Player has loaded
local PlayerLoaded: Route<boolean> = Route.new(defaultConfiguration)

return {
MatterReplication = MatterReplication,
PlayerLoaded = PlayerLoaded,
}

And now in the same script where you create your Matter Loop, you can run the YetAnotherNet.start(Loop, { Route }) function to schedule your Routes to run on Matter's Middleware.

init.server.luau / init.client.luau
local RunService = game:GetService("RunService")

local Matter = require("@packages/Matter")
local World = Matter.World
local Loop = Matter.Loop

local YetAnotherNet = require("@packages/YetAnotherNet")
local routes = require("@shared/routes")

local world = World.new()
local loop = Loop.new(world)

-- Schedules your Routes
YetAnotherNet.start(loop, routes)

local systems = {}
for _, child in script.systems:GetChildren() do
if child:IsA("ModuleScript") then
table.insert(systems, require(child))
end
end

loop:scheduleSystems(systems) -- Schedule systems after running ``YetAnotherNet.start()``

-- Begin the loop and make sure the ``Event`` key in your Routes configuration are added here
loop:begin({
default = RunService.Heartbeat
})

Finally, in a Matter System we can use our routes.luau ModuleScript to access our Routes and use them within our Systems.

systems/exampleSystem.luau
local routes = require("@shared/routes")
local PlayerLoaded = routes.PlayerLoaded

local function exampleSystem(world)
-- Query through every networking call that frame on the Server
for i, player, ...data in PlayerLoaded:query() do
-- Do something
end

-- Query through every networking call that frame on the Client
for i, _, ...data in PlayerLoaded:query() do
-- Do something
end

-- Send data from the Client to the Server
PlayerLoaded:send(...data)

-- Send data to a Client from the Server
PlayerLoaded:send(...data):to(Player)
end