Client writes via remotes β
PlayerState keeps saved data server-authoritative. The client API is read-only for profile data. PlayerState does not include RemoteEvents or RemoteFunctions for gameplay writesβyou expose your own and validate on the server.
Related: API overview Β· Troubleshooting β client can't write Β· Best practices
Pattern β
- Client fires your
RemoteEventwith a small payload (for example action name + amount). - Server checks the player is in the game, types, ranges, cooldowns, and permissions.
- Server calls
PlayerState.Set,Increment,SetPath, or other server APIs.
Minimal example β
Adjust paths if you moved modules β see Installation.
Server (ServerScriptService or equivalent):
lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerState = require(ReplicatedStorage.Libraries.PlayerState.PlayerStateServer)
local purchaseRemote = Instance.new("RemoteEvent")
purchaseRemote.Name = "PurchaseItem"
purchaseRemote.Parent = ReplicatedStorage
local ITEM_COST = 100
purchaseRemote.OnServerEvent:Connect(function(player, itemId)
if not player or not player.Parent then
return
end
if typeof(itemId) ~= "string" then
return
end
local coins = PlayerState.Get(player, "Coins") or 0
if coins < ITEM_COST then
return
end
PlayerState.Increment(player, "Coins", -ITEM_COST)
-- Grant item, update inventory paths, etc.
end)Client:
lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local purchaseRemote = ReplicatedStorage:WaitForChild("PurchaseItem")
purchaseRemote:FireServer("sword_01")Checklist β
- Validate every argument from the client (type, range, whitelist).
- Never call client-only APIs to mutate saved data.
- Rate-limit or debounce spam-prone remotes.
- For UI that must show live values, use
OnChangedon the client β Change listeners.
Built-in remotes β
PlayerState may expose a small number of read-only helpers (for example offline profile snapshots). Those are documented on the relevant API pages β do not confuse them with general write remotes. See GetOfflineData and Client errors.