PlayerStore
A PlayerStore wraps a regular Store to provide a more convenient API for working with Player data. It automatically converts Players to UserId keys and handles player kicks on data errors.
local playerStore = PlayerStore.create({
name = "PlayerData",
template = {
coins = 0,
items = {},
},
schema = function(data)
return typeof(data.coins) == "number" and typeof(data.items) == "table",
"Invalid data format"
end,
})
-- Load data when player joins
Players.PlayerAdded:Connect(function(player)
playerStore:loadAsync(player)
end)
-- Unload data when player leaves
Players.PlayerRemoving:Connect(function(player)
playerStore:unloadAsync(player)
end)
Types
PlayerStoreConfig
interface PlayerStoreConfig {name: string--
The name of the store
template: T--
The template data for new keys
schema: (value: any) → (boolean,string?)--
A function to validate data
importLegacyData: ((key: string) → any?)?--
Optional function to import legacy data
changedCallbacks: {(key: string,newData: T,oldData: T?) → ()}?--
Optional callbacks for data changes
}Configuration for creating a new Store.
Functions
createPlayerStore
Creates a new PlayerStore with the given configuration. Configuration is similar to Store.createStore, but automatically adds player kick handling.
local playerStore = PlayerStore.create({
name = "PlayerData",
template = { coins = 0 },
schema = function(data)
return typeof(data.coins) == "number", "coins must be a number"
end,
-- Optional: Runs whenever data changes
changedCallbacks = {
function(key, newData, oldData)
print(key, "changed from", oldData.coins, "to", newData.coins)
end,
},
})
Players will be automatically kicked with an error message if:
- Their data fails to load
- The DataStore lock is lost during their session
get
Gets the current data for the given player.
playerStore:get(player):andThen(function(data)
print(player.Name, "has", data.coins, "coins")
end)
Errors
| Type | Description |
|---|---|
| "Key not loaded" | The player's data hasn't been loaded |
| "Store is closed" | The store has been closed |
getAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsSyntactic sugar for playerStore:get(player):expect().
See PlayerStore:get
load
Loads data for the given player. Must be called before using other methods.
playerStore:load(player):andThen(function()
print("Data loaded for", player.Name)
end)
CAUTION
If loading fails, the player will be kicked from the game.
Errors
| Type | Description |
|---|---|
| "Load already in progress" | Another load is in progress for this player |
| "Store is closed" | The store has been closed |
loadAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsSyntactic sugar for playerStore:load(player):expect().
See PlayerStore:load
unload
PlayerStore:unload(player: Player) → Promise<boolean>--
Resolves when the update is complete, with a boolean indicating success
Unloads data for the given player.
playerStore:unload(player):andThen(function()
print("Data unloaded for", player.Name)
end)
Errors
| Type | Description |
|---|---|
| "Store is closed" | The store has been closed |
unloadAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsSyntactic sugar for playerStore:unload(player):expect().
update
PlayerStore:update(transformFunction: (data: T) → boolean) → Promise--
Resolves when the update is complete
Updates data for the given player using a transform function. The transform function must return true to commit changes, or false to abort.
playerStore:update(player, function(data)
if data.coins < 100 then
data.coins += 50
return true -- Commit changes
end
return false -- Don't commit changes
end)
Errors
| Type | Description |
|---|---|
| "Key not loaded" | The player's data hasn't been loaded |
| "Store is closed" | The store has been closed |
| "Schema validation failed" | The transformed data failed schema validation |
updateAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsSyntactic sugar for playerStore:update(player, transformFunction):expect().
updateImmutable
PlayerStore:updateImmutable(transformFunction: (data: T) → T | false) → Promise--
Resolves when the update is complete
Updates data for the given player using a transform function that does not mutate the original data. The transform function must return the new data or false to abort.
playerStore:updateImmutable(player, function(data)
if data.coins < 100 then
return { coins = data.coins + 50 } -- Return new data to commit changes
end
return false -- Don't commit changes
end)
Errors
| Type | Description |
|---|---|
| "Key not loaded" | The player's data hasn't been loaded |
| "Store is closed" | The store has been closed |
| "Schema validation failed" | The transformed data failed schema validation |
updateImmutableAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsSyntactic sugar for playerStore:updateImmutable(player, transformFunction):expect().
tx
PlayerStore:tx() → Promise--
Resolves with true if the transaction was successful, or false if it was aborted. Rejects on error.
Performs a transaction across multiple players' data atomically. All players' data must be loaded first. Either all changes apply or none do.
playerStore:tx({player1, player2}, function(state)
-- Transfer coins between players
if state[player1].coins >= 100 then
state[player1].coins -= 100
state[player2].coins += 100
return true -- Commit transaction
end
return false -- Abort transaction
end)
Errors
| Type | Description |
|---|---|
| "Key not loaded" | One or more players' data hasn't been loaded |
| "Store is closed" | The store has been closed |
| "Schema validation failed" | The transformed data failed schema validation |
txAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsSyntactic sugar for playerStore:tx(players, transformFunction):expect().
See PlayerStore:tx
txImmutable
PlayerStore:txImmutable() → Promise--
Resolves with true if the transaction was successful, or false if it was aborted. Rejects on error.
Performs a transaction across multiple players' data atomically using immutable updates. All players' data must be loaded first. Either all changes apply or none do.
playerStore:txImmutable({player1, player2}, function(state)
-- Transfer coins between players
if state[player1].coins >= 100 then
return {
[player1] = { coins = state[player1].coins - 100 },
[player2] = { coins = state[player2].coins + 100 },
} -- Commit transaction with new data
end
return false -- Abort transaction
end)
Errors
| Type | Description |
|---|---|
| "Key not loaded" | One or more players' data hasn't been loaded |
| "Store is closed" | The store has been closed |
| "Schema validation failed" | The transformed data failed schema validation |
txImmutableAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsPlayerStore:txImmutableAsync() → ()Syntactic sugar for playerStore:txImmutable(players, transformFunction):expect().
save
Forces an immediate save of the given player's data.
INFO
Data is automatically saved periodically, so manual saves are usually unnecessary.
Errors
| Type | Description |
|---|---|
| "Key not loaded" | The player's data hasn't been loaded |
| "Store is closed" | The store has been closed |
saveAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsSyntactic sugar for playerStore:save(player):expect().
See PlayerStore:save
close
PlayerStore:close() → Promise--
Resolves when the store is closed
Closes the store and unloads all active sessions. The store cannot be used after closing.
closeAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsPlayerStore:closeAsync() → ()Syntactic sugar for playerStore:close():expect().
peek
PlayerStore:peek(userId: number) → Promise<T>--
Resolves with the current data
Returns the current data for the given key without loading it into the store.
playerStore:peek(userId):andThen(function(data)
print("Current coins:", data.coins)
end)
peekAsync
This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsPlayerStore:peekAsync(userId: number) → ()Syntactic sugar for playerStore:peek(userId):expect().
See PlayerStore:peek