Performance Tips
Client-side patterns for responsive UI without fighting replication or leaking listeners.
Readiness
Get/GetPathwait until data is ready—no manual wait loop required for normal UI.- Use
when you want to skip work (hide UI, show placeholder) before data exists.IsReady() - For bulk UI setup, check
once, then read paths—not once per label.IsReady()
See Status — IsReady.
Listen on specific paths
Avoid a global "." listener unless you are debugging.
- One listener per UI concern:
"Coins","Inventory","Plot.Likes". - In a global listener, branch on
info.actionandinfo.path—do not repaint the whole HUD every time.
lua
-- Narrow
PlayerState.OnChanged("Coins", updateCoinsLabel)
-- Debug only
PlayerState.OnChanged(".", onAnyChange)See Change listeners.
Disconnect listeners
Every OnChanged (and shared-session listener) should be disconnected when:
- The local player leaves.
- The UI instance is destroyed.
- The feature is torn down (shop closed, plot unloaded).
lua
local conn = PlayerState.OnChanged("Coins", updateCoins)
gui.Destroying:Connect(function()
if conn then conn:Disconnect() end
end)Safe reads
- Use
orfallbacks:PlayerState..Get("Coins") or 0 - Validate shape before iterating:
typeof(inventory) == ".table" - Do not assume nested tables exist—check
GetPathfornil.
lua
local inventory = PlayerState.GetPath("Inventory")
if typeof(inventory) ~= "table" then
inventory = {}
endDo not mutate returned tables
Get / GetPath can return references to replicated data.
- Mutating the table locally can change shared state unintentionally.
- Use
when you need a local copy to edit offline in UI code.Clone() - To change saved data, use your server remotes—the client API is read-only.
lua
-- Risky
local t = PlayerState.GetPath("Settings")
t.MusicEnabled = false
-- Safer for local UI logic
local t = PlayerState.Clone(PlayerState.GetPath("Settings"))See Common pitfalls.
Cache
is for debugging or rare recovery—not routine use.ClearCache()- The client rebuilds cache on access after a clear.
See Cache.
Shared session
- Prefer
before reading shared session in UI.IsSharedReady() - Use specific
OnSharedChangedpaths instead of listening to everything.
See Shared session.