Lesson 01 of 05
Clicker DataStore Implementation
Save coins and upgrades when the player leaves, load them when they join.
We save a dictionary: { coins, upgrades }. Use UpdateAsync for safety — it wraps the operation in an atomic read-modify-write cycle, preventing race conditions when two servers try to save the same player.
Always save on PlayerRemoving AND periodically (every 30s) in case of crashes. Use pcall to handle DataStore failures gracefully — never crash the server because a save failed.
luau
1local DataStoreService = game:GetService('DataStoreService')
2local Players = game:GetService('Players')
3local store = DataStoreService:GetDataStore('ClickerData_v1')
4
5local DEFAULT_DATA = { coins = 0, upgrades = {} }
6local cache = {} -- in-memory session data
7
8local function loadData(player)
9 local ok, data = pcall(function()
10 return store:GetAsync('user_' .. player.UserId)
11 end)
12 cache[player.UserId] = (ok and data) or table.clone(DEFAULT_DATA)
13end
14
15local function saveData(player)
16 local data = cache[player.UserId]
17 if not data then return end
18 pcall(function()
19 store:UpdateAsync('user_' .. player.UserId, function() return data end)
20 end)
21end
22
23Players.PlayerAdded:Connect(loadData)
24Players.PlayerRemoving:Connect(function(p)
25 saveData(p)
26 cache[p.UserId] = nil
27end)
READY · 27 lines
