Start typing to search packages!
dataservicev2
By @kartzrbx
Roblox
Mirrored from WallyThis version ships no README. Showing the README from v2.1.4, mirrored from wally.
DataServiceV2
High-performance Roblox data service with automatic server/client replication, embedded ProfileStore persistence, typed path tokens, QuickNet transport, and Janitor-based connection lifecycle management.
Instalação
wally.toml:
[dependencies]
DataServiceV2 = "kartzrbx/dataservicev2@2.0.6"
wally install
Uso
Exemplo completo (Server + Client)
Use este exemplo como base de produção.
ServerScriptService/DataBootstrap.server.lua
const Players = game:GetService("Players")
const ReplicatedStorage = game:GetService("ReplicatedStorage")
const DataService = require(ReplicatedStorage.Packages.DataServiceV2).Server
const TEMPLATE = {
Currencies = {
Coins = 0,
Gems = 0,
},
Inventory = {},
Stats = {
Level = 1,
XP = 0,
},
}
DataService:Init({
Template = TEMPLATE,
StoreName = "PlayerDataV2",
StrictPaths = true,
AutoCreateMissingTables = false,
})
Players.PlayerAdded:Connect(function(player)
const data = DataService:WaitFor(player)
if not data then
return
end
-- Path token (recomendado)
data:Update(data.Currencies.Coins, function(current)
return (current or 0) + 100
end)
data:Update(data.Stats.XP, function(current)
return (current or 0) + 25
end)
data:GetChangedSignal(data.Currencies.Coins):Connect(function(newValue, oldValue)
print(("[Server] %s Coins: %s -> %s"):format(player.Name, tostring(oldValue), tostring(newValue)))
end)
-- Compatibilidade legada (continua suportado)
data:Set({ "Currencies", "Gems" }, 10)
end)
Players.PlayerRemoving:Connect(function(player)
const stats = DataService:GetBufferStats(player)
if stats then
print(("[Server] Buffer %s | bytes=%d messages=%d"):format(player.Name, stats.Bytes, stats.Messages))
end
end)
StarterPlayerScripts/DataClient.client.lua
const ReplicatedStorage = game:GetService("ReplicatedStorage")
const DataService = require(ReplicatedStorage.Packages.DataServiceV2).Client
const data = DataService:Init()
print("[Client] Coins initial:", data:Get(data.Currencies.Coins))
data:GetChangedSignal(data.Currencies.Coins):Connect(function(newValue, oldValue)
print(("[Client] Coins changed: %s -> %s"):format(tostring(oldValue), tostring(newValue)))
end)
data:GetChangedSignal(data.Stats.XP):Connect(function(newValue)
print("[Client] XP changed:", newValue)
end)
task.spawn(function()
while task.wait(10) do
const buffer = DataService:GetBufferStats()
if buffer then
print(("[Client] Buffer | bytes=%d messages=%d utilization=%.2f"):format(
buffer.Bytes or 0,
buffer.Messages or 0,
buffer.LastUtilization or 0
))
end
end
end)
Why DataServiceV2 is Powerful
- Built for scale: QuickNet-based replication reduces CPU and bandwidth overhead compared to plain RemoteEvent flows.
- Safer writes: strict path validation prevents silent corruption caused by invalid dynamic paths.
- Developer speed: chainable path tokens (
data.Currencies.Coins) improve readability and reduce human error. - Full compatibility: legacy array paths keep working, so migration can be incremental.
- Operational visibility: built-in buffer utilization stats help inspect replication pressure in real time.
- Lifecycle safety: Janitor cleanup prevents connection leaks in both server and client runtime.
Servidor
local DataService = require(game.ReplicatedStorage.Packages.DataServiceV2).Server
local TEMPLATE = {
Coins = 0,
Inventory = {},
}
DataService:Init({
Template = TEMPLATE,
StoreName = "PlayerData", -- opcional, default "PlayerData"
UseMock = false, -- opcional, true em Studio sem API services
Exclude = { { "Secret" } },-- caminhos que não replicam ao cliente
StrictPaths = true, -- opcional, default true (evita paths inválidos)
AutoCreateMissingTables = false, -- opcional, default false (modo legado = true)
})
game.Players.PlayerAdded:Connect(function(player)
local data = DataService:WaitFor(player)
-- Novo (recomendado): path token com autocomplete
data:Set(data.Coins, 100)
-- Compatibilidade legada (continua funcionando)
data:Set({ "Coins" }, 100)
end)
Cliente
local DataService = require(game.ReplicatedStorage.Packages.DataServiceV2).Client
local data = DataService:Init() -- yields até receber snapshot inicial
print(data:Get(data.Coins))
data:GetChangedSignal(data.Coins):Connect(function(new, old)
print("Coins:", old, "->", new)
end)
API
Server
Init(options)—{ Template, StoreName?, UseMock?, KeyPrefix?, Exclude?, StrictPaths?, AutoCreateMissingTables? }WaitFor(player)→ DataGet(player)→ Data?HasData(player)→ booleanGetProfile(player)→ ProfileStore profileGetBufferStats(player?)→ métricas de buffer/uso de rede da replicaçãoDestroy()→ limpa conexões e listeners do serviçoPaths→ token raiz de caminhos (disponível apósInit)
Client
Init()→ Data (yields)WaitForData()→ DataGet()→ Data?GetBufferStats()→ últimas métricas de buffer enviadas pelo servidorDestroy()→ limpa conexões/listeners do cliente
Data
Get(path?)— lê (caminho vazio = root), aceita token ou array legadoTyped<T>(path)— força tipo do caminho para inferência forte em sinais e Get/Set/UpdateSet(path, value)— server-only, aceita token ou array legadoUpdate(path, fn)— server-only, aceita token ou array legadoArrayInsert(path, value, index?)— server-only, aceita token ou array legadoArrayRemove(path, index)— server-only, aceita token ou array legadoGetChangedSignal(path)→ Signal(new, old), aceita token ou array legadoGetIndexChangedSignal(path)→ Signal(key, new, old), aceita token ou array legadoGetArrayInsertedSignal(path)→ Signal(index, value), aceita token ou array legadoGetArrayRemovedSignal(path)→ Signal(index, removed), aceita token ou array legado
Caminhos tipados / seguros (novo)
Agora você pode usar acesso encadeado para montar caminhos sem tabelas manuais:
data:Set(data.Currencies.Coins, 100)
local coins = data:Get(data.Currencies.Coins)
data:GetChangedSignal(data.Currencies.Coins):Connect(function(new, old)
print(old, new)
end)
local coinsPath = data:Typed<number>(data.Currencies.Coins)
data:GetPathChangedSignal(coinsPath):Connect(function(newValue, oldValue)
-- newValue e oldValue inferidos como number
print(newValue, oldValue)
end)
Isso reduz erros de digitação em paths ({"Currencies","Coins"}), mantendo compatibilidade com o formato antigo.
Compatibilidade e modo legado
- Compatível com chamadas antigas via array:
data:Set({ "Currencies", "Coins" }, 100) StrictPaths = true(default): bloqueia escrita em caminho inválidoAutoCreateMissingTables = false(default): não cria estruturas faltantes automaticamente- Para comportamento antigo (mais permissivo), use:
DataService:Init({
Template = TEMPLATE,
StrictPaths = false,
AutoCreateMissingTables = true,
})
Dependências
sleitnick/signal@2.0.3(instalado automaticamente pelo Wally)breadboardengineer1234/quicknet@0.3.0(replicação otimizada)1foreverhd/janitor@1.18.15(gerenciamento de conexões/recursos)- ProfileStore — embutido, sem necessidade de instalação separada
Package Details
Install command (Click to copy)
Version
3.2.0
License
MIT
Safe for commercial use
The package archive does not include its license text; the license is declared in its manifest metadata.
Automated license review — not legal advice.
