Change Subscription Functions
Subscribe to profile data changes on the server. For when the third callback argument is a path array vs ChangeInfo, see the Change listeners guide.
OnChanged
OnChanged(player, pathOrKey, callback) → Connection?
Subscribes to changes in a specific player's profile.
Parameters:
- player:
Player- The player to watch - pathOrKey:
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 argument is either a path key array (simple sets) or a change table (action, path, optional index) for nested/table updates. Listening on "." is for debugging only.
Example
local connection = PlayerState.OnChanged(player, "Coins", function(newValue, oldValue, info)
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.