DataRegistry — A lightweight state management system with server/client replication

What is DataRegistry?

DataRegistry is a lightweight module for managing player states on both the server and client. Instead of scattering flags and values across scripts, everything lives in one place; organized into state tables, with built-in replication so the server and client always stay in sync.

  • Modular state tables — define your states in child ModuleScripts, DataRegistry loads them automatically.
  • Two replication modesServer states are authority-only, The client can set local states for themselves.
  • StateChanged event — fires on both server and client whenever any state updates.
  • Duration support — set a state for X seconds, and it reverts automatically.
  • Automatic cleanup — player data is wiped on disconnect, no leaks.

Setup

Place DataRegistry in ReplicatedStorage. Create a StateTables folder inside it, then add ModuleScripts for each group of states:

ReplicatedStorage
└─ DataRegistry (ModuleScript)
    └─ StateTables (Folder)
        ├─ MovementStates (ModuleScript)
        ├─ CombatStates (ModuleScript)
        └─ StatusEffects (ModuleScript)

Each state table module should return two functions:

local MovementStates = {}

function MovementStates.GetDefaultStates()
    return {
        Running  = false,
        Crouching = false,
        Dashing  = false,
    }
end

function MovementStates.GetReplicationModes()
    return {
        Running   = "Local",   -- client can set this for themselves
        Crouching = "Local",
        Dashing   = "Server",  -- only server can set this
    }
end

return MovementStates

Quick Start

Server

local DataRegistry = require(game.ReplicatedStorage.DataRegistry)

-- Set a state (server only)
DataRegistry:SetState(player, "MovementStates", "Dashing", true)

-- Set with auto-revert after 2 seconds
DataRegistry:SetState(player, "MovementStates", "Dashing", true, 2)

Client

local DataRegistry = require(game.ReplicatedStorage.DataRegistry)

-- Set a Local-mode state for yourself
DataRegistry:SetStateLocal("MovementStates", "Running", true)

-- Read any state
local isRunning = DataRegistry.GetState(player, "MovementStates", "Running")

-- Listen for changes
DataRegistry.StateChanged.Event:Connect(function(player, tableName, stateName, newValue, oldValue)
    print(stateName, "changed to", newValue)
end)

API Reference

Reading States


DataRegistry.GetState(player, tableName, stateName)

Returns the current value of a state. Works on both server and client.

Parameter Type Description
player Player Target player. Use LocalPlayer on the client.
tableName string Name of the state table (e.g. "MovementStates").
stateName string Name of the state to read.

Returns: any


DataRegistry.GetTable(player, tableName)

Returns a deep copy of all states in a table for a player.

Returns: table


DataRegistry.GetReplicationMode(tableName, stateName)

Returns the replication mode of a state — either "Server" or "Local".

Returns: string


DataRegistry.GetRegisteredTables()

Returns an array of all registered table names.

Returns: table


Writing States


DataRegistry:SetState(player, tableName, stateName, value, duration?)

Sets a state. Server only.

Parameter Type Description
player Player Target player.
tableName string State table name.
stateName string State to modify.
value any New value.
duration number? Optional. Reverts to the previous value after this many seconds.

DataRegistry:SetStateLocal(tableName, stateName, value)

Sets a Local-mode state from the client. Only works for states with replication mode "Local". The server keeps a synced copy. Client only.


DataRegistry:ResetTable(player, tableName)

Resets all states in a table back to their defaults. Clears any active duration timers. Server only.


Events


DataRegistry.StateChanged

Fires whenever any state changes, on both server and client.

DataRegistry.StateChanged.Event:Connect(function(player, tableName, stateName, newValue, oldValue)

end)
Parameter Type Description
player Player The player whose state changed.
tableName string The table the state belongs to.
stateName string The state that changed.
newValue any The new value.
oldValue any The previous value.

Replication Modes

Mode Who can write Use case
"Server" Server only Health, combat flags, anything that must be authoritative
"Local" Client (for themselves) + server UI states, input-driven flags like Running or Aiming

When a client sets a Local state, the change fires StateChanged locally immediately, then notifies the server so it keeps a synced copy. The server validates that the state is actually Local mode before accepting it, so clients cannot spoof Server states.


Download

DataRegistry.rbxm (7.4 KB)


To note: I’d love to receive feedback or hear suggestions on the module, as I want to grow as a scripter and learn more.

3 Likes

looks cool might use this one day. Btw do you have any benchmark data (in terms of bandwith usage and performance) compared with other alternatives

I don’t have benchmark data comparing it to other options yet, but I plan to add that in the future as I continue optimizing the module as much as possible.