Skip to content

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
lua
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.


PlayerState - High-Performance Roblox Data Management