Hello,
I have always used SetAsync() for saving data, until I saw this post.
I’m making my next game, and I want to use UpdateAsync(), so, following the tutorial linked above, I wrote the following code:
local function saveData(player,stat)
local startTime = tick()
warn('Loading '..player.Name..'\'s data...')
local success,errorMessage
local statStore
local attempts = 0
local playersData = stat.Value
while not success do
success,errorMessage = pcall(function()
dataStore:UpdateAsync(player.UserId..'-'..stat.Name,function(oldValue)
local previousData = oldValue or {DataId = 0}
if playersData.DataId == previousData.DataId then
playersData.DataId = playersData.DataId + 1
return playersData
else
return nil
end
end)
end)
attempts += 1
if attempts >= 10 then
break
end
if not success then
warn('Failed to load '..player.Name..'\'s data. Error: '..errorMessage)
end
end
if success then
local endTime = tick()
warn('Successfully saved '..player.Name..'\'s data! Processed in '..endTime - startTime..' milliseconds')
end
end
I know what a table is, but the old table is passed as a parameter.
Here is the full script if it helps:
local dataStoreService = game:GetService('DataStoreService')
local dataStore = dataStoreService:GetDataStore('Data')
local players = game:GetService('Players')
local function loadData(player,stat)
local startTime = tick()
warn('Loading '..player.Name..'\'s data...')
local success,errorMessage
local statStore
local attempts = 0
while not success do
success,errorMessage = pcall(function()
statStore = dataStore:GetAsync(player.UserId..'-'..stat.Name)
end)
attempts += 1
if attempts >= 10 then
break
end
if not success then
warn('Failed to load '..player.Name..'\'s data. Error: '..errorMessage)
end
end
if success then
local endTime = tick()
warn('Successfully loaded '..player.Name..'\'s data! Processed in '..endTime - startTime..' milliseconds')
if statStore ~= nil then
player.leaderstats[stat.Name].Value = statStore
end
end
end
local function saveData(player,stat)
local startTime = tick()
warn('Loading '..player.Name..'\'s data...')
local success,errorMessage
local statStore
local attempts = 0
local playersData = stat.Value
while not success do
success,errorMessage = pcall(function()
dataStore:UpdateAsync(player.UserId..'-'..stat.Name,function(oldValue)
local previousData = oldValue or {DataId = 0}
if playersData.DataId == previousData.DataId then
playersData.DataId = playersData.DataId + 1
return playersData
else
return nil
end
end)
end)
attempts += 1
if attempts >= 10 then
break
end
if not success then
warn('Failed to load '..player.Name..'\'s data. Error: '..errorMessage)
end
end
if success then
local endTime = tick()
warn('Successfully saved '..player.Name..'\'s data! Processed in '..endTime - startTime..' milliseconds')
end
end
players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new('Folder',player)
leaderstats.Name = 'leaderstats'
local wins = Instance.new('IntValue',leaderstats)
wins.Name = 'Wins'
local rounds = Instance.new('IntValue',leaderstats)
rounds.Name = 'Rounds'
local deaths = Instance.new('IntValue',leaderstats)
deaths.Name = 'Deaths'
wait()
for _, stat in pairs(leaderstats:GetChildren()) do
loadData(player,stat)
end
end)
players.PlayerRemoving:Connect(function(player)
for _, stat in pairs(player.leaderstats:GetChildren()) do
saveData(player,stat)
end
end)
game:BindToClose(function()
for _, player in ipairs(game.Players:GetPlayers()) do
for _, stat in pairs(player.leaderstats:GetChildren()) do
saveData(player,stat)
end
end
wait(2)
end)
playerData should refer to a properly formatted data that you want to store in the datastore when you are saving with UpdateAsync.
So given how you are using it, it should be a table with the key DataId. It should contain all the info that you want to save for a player. If you’re only saving one thing, e.g. DataId and that is what the stat.Value represents then you should say: local playersData = {DataId = stat.Value}.