Summary
This page will summarize the previous guides and create a basic project setup for replecs.
-
Create your world and require replecs. This is to avoid creating a world before requiring replecs.
Directorysrc
Directoryshared
- world.lua
local jecs = require("@pkg/jecs")require("@pkg/replecs")return jecs.world()
-
Create a
Replicator
in shared and re-export theclient
andserver
entries:Directorysrc
Directoryclient
- replicator.lua
Directoryserver
- replicator.lua
Directoryshared
- replicator.lua
- world.lua
local replecs = require("@pkg/replecs")local world = require("@shared/world")return replecs.create(world)local replicator = require("@shared/replicator")return replicator.serverlocal replicator = require("@shared/replicator")return replicator.client
-
Create your components and mark them as shared:
Directorysrc
Directoryclient
- replicator.lua
Directoryserver
- replicator.lua
Directoryshared
- components.lua
- replicator.lua
- world.lua
local jecs = require("@pkg/jecs")local replecs = require("@pkg/replecs")local world = require("@shared/world")local components = {position = world:component(),velocity = world:component(),player = world:component(),health = world:component(),alive = world:tag(),}for name, component in components doworld:add(component, replecs.shared)world:set(component, jecs.Name, name)end
-
Initialize replicators and get the full state of the world:
Directorysrc
Directoryclient
- replicator.lua
- init.client.lua
Directoryserver
- replicator.lua
- init.server.lua
Directoryshared
- components.lua
- replicator.lua
- world.lua
local replicator = require("@server/replicator")local remotes_server = require("@shared/remotes").serverreplicator:init()remotes_server.receive_full:set_callback(function(player)replicator:mark_player_ready(player)return replicator:get_full(player)end)local replicator = require("@client/replicator")local remotes_client = require("@shared/remotes").clientreplicator:init()local buf, variants = remotes_client.receive_full:invoke_server()replicator:apply_full(buf, variants) -
Create systems to send updates and unreliable values:
Directorysrc
Directoryclient
Directorysystems
- replecs-client.lua
- replicator.lua
Directoryserver
Directorysystems
- replecs-server.lua
- replicator.lua
Directoryshared
Directoryutils
- collect.lua
- interval.lua
- components.lua
- replicator.lua
- world.lua
local replicator = require("@server/replicator")local interval = require("@utils/interval")local updates_interval = interval(1 / 20)local unreliables_interval = interval(1 / 30)function replecs_server()if updates_interval() thenfor player, buf, variants in replicator:collect_updates() doremotes_server.send_updates:fire(player, buf, variants)endendif unreliables_interval() thenfor player, buf, variants in replicator:collect_unreliable() doremotes_server.send_unreliables:fire(player, buf, variants)endendendreturn replecs_serverlocal replicator = require("@client/replicator")local collect = require("@utils/collect")local updates = collect(remotes_client.send_updates)local unreliables = collect(remotes_client.send_unreliables)function replecs_client()for buf, variants in updates doreplicator:apply_updates(buf, variants)endfor buf, variants in unreliables doreplicator:apply_unreliable(buf, variants)endendreturn replecs_clientlocal function collect(event)local storage = {}local mt = {}local iter = function()local n = #storagereturn function()if n <= 0 thenmt.__iter = nilreturn nilendn -= 1return n + 1, unpack(table.remove(storage, 1) :: any)endendif type(event) == "function" thenevent(function(...)table.insert(storage, { ... })mt.__iter = iterend)elseevent:Connect(function(...)table.insert(storage, { ... })mt.__iter = iterend)endsetmetatable(storage, mt)return (storage :: any) :: () -> (number, ...any)endreturn collectlocal function interval(s: number)local pin: number = nil :: anylocal function throttle()if not pin thenpin = os.clock()endlocal elapsed = os.clock() - pin > sif elapsed thenpin = os.clock()endreturn elapsedendreturn throttleendreturn interval