Appearance
Change Subscription Functions ​
OnChanged ​
OnChanged(player, pathOrKey, callback) → Connection?
Subscribes to changes in a specific player's profile.
Parameters:
player: Player- The player to watchpathOrKey: string- A top-level key (e.g."Coins") or a dot-separated path (e.g."Inventory.Slots")callback: (newValue, oldValue, info) -> ()- Fired when data at the path changes
Returns: Connection? - Connection to disconnect when done, or nil if invalid (player invalid, path not a string, or callback not a function)
The third callback argument depends on the change:
- For path
".",infois always a table:{ action, path }(andindexfor insert/remove). - For a normal path or key (not
"."):- On a direct
Set/SetValuesat that path,infois the path key array (e.g.{ "Coins" }or{ "Plot", "Likes" }) — same shape as clientOnChangedfor the simple case. - When the change is on a child path (e.g. listening on
"Plot"but something underPlot.Buildingschanged), the callback receives(currentValueAtListenedPath, nil, { action, path })wherepathis the Replica path array for the mutation.
- On a direct
- For table operations,
infoincludesaction,path, andindexwhere applicable.
Using the root path "." subscribes to every change on that profile. Not recommended except for debugging, since it fires on every mutation and can hurt performance. Prefer listening on the narrowest path you need (e.g. "Coins" or "Mailbox.UnreadCount").
Example
lua
local connection = PlayerState.OnChanged(player, "Coins", function(newValue, oldValue, info)
-- For a direct Set on "Coins", `info` is often the path key list, e.g. { "Coins" }
print(`Coins: {oldValue} -> {newValue}`)
end)
PlayerState.OnChanged(player, "Inventory.Slots", function(newValue, oldValue, info)
if type(info) == "table" and info.action == "TableInsert" then
print(`Item added at index {info.index}`)
end
end)
game.Players.PlayerRemoving:Connect(function(leavingPlayer)
if leavingPlayer == player and connection then
connection:Disconnect()
end
end)Disconnect When Done
Call connection:Disconnect() when the listener is no longer needed (e.g. when the player leaves or the feature is destroyed) to avoid leaks and unnecessary work.
Server-only paths
OnChanged is wired to the player Replica. Updates under ServerOnlyRoots (for example Server.*) apply to profile.Data only and do not change the Replica, so no OnChanged callback runs for those paths. Use your own server flow after writes, or read with GetPath / GetAll on the server.