twistedsignal/data
Persistent, replicated, reactive player data for Roblox
data
Persistent, replicated player data for Roblox with the same reactive contract as
twistedsignal/ui.
data is a fork of
leifstout/dataServiceTyped.
It keeps typed nested access, ProfileStore persistence, client replication,
array helpers, dictionary callbacks, and global profile messages. The public API
uses camelCase names.
Install
With pesde:
pesde add twistedsignal/data
The package currently targets pesde because twistedsignal/ui is released on
GitHub but is not yet available from the public Wally index. wally.toml stays
in the repository for compatibility with the upstream project and a later Wally
release.
Create the service
Call the package once from a shared module. The server gets player-indexed data and the client gets its local player's data.
local data = require(path.to.Data)({
template = {
coins = 0,
inventory = {} :: { string },
settings = { musicEnabled = true },
},
profileStoreIndex = "PlayerData",
})
return data
-- Server
local playerData = data.server:waitForData(player)
playerData.coins(function(previous)
return previous + 10
end)
playerData.inventory.insertArray("Sword")
-- Client
print(data.client.coins())
data.client.settings.musicEnabled(false)
Pass false as the second argument to a write, or the third argument to
insertArray, to make a server-only change.
Use it with ui
Every node is callable like ui.value() and participates in ui dependency
tracking. It also has an Rx Observable.
local ui = require(path.to.UI)
local labelText = ui.derive(function()
return `Coins: {data.client.coins()}`
end)
local stop = ui.bind(screenGui, {
Coins = { Text = labelText },
})
local subscription = data.client.coins.observable:Subscribe(function(coins)
print("coins changed", coins)
end)
Reading a parent node tracks nested writes too. This makes code such as
ui.derive(function() return #data.client.inventory() end) reactive when an
item is inserted or removed.
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).
Each callback registration returns a cleanup function.
The server service is available as data.server.service. Its methods include
waitForData, resetData, getProfile, asyncGetProfile,
addPlayerRemovingCallback, sendGlobalMessage, and addGlobalCallback.
Credits
The persistence and replication design comes from DataServiceTyped by Leif Stout. Reactive integration and the camelCase API are maintained by Twisted Signal. Licensed under MIT.