Appearance
Session Data (Non-Persistent)
PlayerState supports runtime-only data that replicates during play but is never persisted to the DataStore. Use session data for temporary state that should reset each time a player joins.
Quick Start
Add a session root to your DefaultData and use normal API calls. Session data syncs to clients but is never saved.
lua
-- DefaultData
session = {
isChopping = false,
isSprinting = false,
}
-- Server: set session state
PlayerState.SetPath(player, "session.isSprinting", true)
-- Client: read session state
local sprinting = PlayerState.GetPath("session.isSprinting")What It Is
Session data (also called non-persistent or runtime-only data) lives at special roots such as session. PlayerState treats these roots differently:
- Replicates during play — clients can read it and listeners fire when it changes
- Never persisted — stripped from the save payload
- Reset on load — cleaned on profile load and re-seeded from template defaults
Use it for activity flags, temporary UI state, minigame progress, or any value that should not survive rejoin or server restart.
Why Use It
| Use Case | Example |
|---|---|
| Activity flags | session.isChopping, session.isSprinting, session.inCombat |
| Temporary progress | session.currentMinigameScore, session.questStep |
| UI / client state | session.selectedTab, session.tutorialStep |
| Per-session counters | session.killsThisSession, session.deathsThisSession |
You get real-time sync and change listeners without bloat in the DataStore or save/load cost.
DefaultData Example
Define session roots in your template. They will be initialized from these defaults on every profile load:
lua
-- ReplicatedStorage.Libraries.PlayerState.DefaultData
return {
Coins = 100,
Level = 1,
session = {
isChopping = false,
isSprinting = false,
inCombat = false,
currentMinigame = nil,
},
}Server: Set and Get
Use SetPath / GetPath (or Set / Get) the same way as persistent data:
lua
-- ServerScriptService
local PlayerState = require(game.ReplicatedStorage.Libraries.PlayerState.PlayerStateServer)
Players.PlayerAdded:Connect(function(player)
PlayerState.Init(player)
-- Set session state
PlayerState.SetPath(player, "session.isSprinting", true)
PlayerState.SetPath(player, "session.isChopping", false)
-- Read it back
local sprinting = PlayerState.GetPath(player, "session.isSprinting")
end)Client: Read and Listen
Clients read session data like any other path. It is available as soon as the profile is loaded:
lua
-- LocalScript
local PlayerState = require(game.ReplicatedStorage.Libraries.PlayerState.PlayerStateClient)
local sprinting = PlayerState.GetPath("session.isSprinting")
print("Is sprinting:", sprinting)
PlayerState.OnChanged("session.isSprinting", function(newValue, oldValue)
print("Sprinting changed:", oldValue, "->", newValue)
end)Save Behavior
Session roots are never persisted:
- Stripped from the save payload before writing to the DataStore
- Restored in-memory from template defaults after save
- On load, runtime roots are cleaned and re-seeded from DefaultData
You do not need to do anything special. PlayerState handles this automatically.
Common Mistakes
Using SetOfflineData for Session Paths
SetOfflineData writes to the persistent profile. It blocks runtime-only paths such as session.* and will warn or fail for those writes.
lua
-- ❌ WRONG: session data cannot be set offline
PlayerState.SetOfflineData(userId, "session.isSprinting", true)
-- ✅ Use SetPath when the player is in-server only
PlayerState.SetPath(player, "session.isSprinting", true)Session data only exists while the player has an active profile session. There is no offline equivalent.
Mixing Session and Persistent Data
Keep session and persistent data clearly separated by root:
lua
-- ✅ Clear separation
session = { isSprinting = false }
Stats = { TotalPlayTime = 0, LastLogin = 0 }
-- ❌ Avoid putting session state inside persistent roots
Stats = { TotalPlayTime = 0, isSprinting = false }Expecting Session Data After Rejoin
Session data resets on every join. Do not rely on it across sessions:
lua
-- Session data is per-session only
PlayerState.SetPath(player, "session.killsThisSession", 10)
-- Player leaves and rejoins -> session.killsThisSession is 0 againTroubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Session data not syncing to client | Client may not be ready | Use PlayerState.IsReady() before reads |
| SetOfflineData fails for session path | Runtime roots are not persisted | Use SetPath when player is in-game only |
| Session values persist after rejoin | Wrong root used | Ensure data is under session (or configured runtime root) |