twistedsignal/replication
Typed reactive server-to-client replication for Roblox
replication
Typed, reactive replication for Roblox. The server owns shared in-memory state, changes replicate to every connected client, and clients that join later fetch the latest server state. Nothing is saved after the server closes.
This package follows the behavior of ReplicationTyped, itself based on
dataServiceTyped. It retains
the camelCase API and integration with
twistedsignal/ui.
Install
pesde add twistedsignal/replication
Create a replica
Give each replica a unique name and an initial template:
local replication = require(path.to.Replication)
local gameState = replication("gameState", {
round = 1,
status = "waiting",
playersAlive = {} :: { string },
})
return gameState
On the server, use .server:
gameState.server.round(function(round)
return round + 1
end)
gameState.server.status("playing")
gameState.server.playersAlive.insertArray("Builderman")
On the client, use .client:
print(gameState.client.round())
gameState.client.status.changed(function(status)
print("status", status)
end)
Server changes go to all current clients. When a client initializes the replica, it requests a snapshot of its current state from the server, so it receives changes made before that player joined.
Private values
Pass false as shouldReplicate to change server state without sending it to
clients:
gameState.server.secret("server only", false)
The package remembers that path and removes it from snapshots sent to late joiners. Array methods accept the same option:
gameState.server.queue.insertArray(item, nil, false)
gameState.server.queue.removeArray(1, false)
Value API
All values support reads, writes, updater functions, .observable, and
changed(callback).
Array values add:
insertArray(item, position?, shouldReplicate?)removeArray(position?, shouldReplicate?)onArrayInserted(callback)onArrayRemoved(callback)
Dictionary values add onKeyAdded(callback) and onKeyRemoved(callback).
Callback registration returns a cleanup function.
Every value participates in twistedsignal/ui dependency tracking:
local labelText = ui.derive(function()
return `Round {gameState.client.round()}`
end)
Credits
Based on twistedsignal/data, ReplicationTyped, and dataServiceTyped.
Licensed under MIT.