cc: @COUNTYL1MITS, @Jaycbee05
The reason why you use pcall with data stores is because data store requests often fail at no fault of the developer. Pcall allows you to catch the error and do something with that error like doing a custom retry method. Roblox uses DynamoDB for data stores so web calls have to be preformed to access it so pcall should be used.
The reason why your script ins’t working is because you aren’t actually using any saving method in the PlayerRemoving function. This means the data wont save to a data store because you havn’t told it to. To fix this you should use either SetAsync()
or UpdateAsync()
to save data. I would recommend UpdateAsync()
because the developers hub recommends it over SetAsync()
and because of this community tutorial: Stop using SetAsync() to save player data.
As I mentioned above you should always wrap your data store requests in pcall because they often fail at no fault of the developer. Having your requests in a pcall will allow you to catch the error and do something when the request fails.
Here is your script with the changes that I mentioned above.:
local datastore = game:GetService("DataStoreService")
local singleStorage = datastore:GetDataStore("PlayerSaves")
game.Players.PlayerAdded:connect(function(plr)
local folder = Instance.new("Folder")
folder.Name = "leaderstats"
folder.Parent = plr
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = folder
coins.Value = 50
local gems = Instance.new("IntValue")
gems.Name = "Gems"
gems.Parent = folder
gems.Value = 10
local kills = Instance.new("IntValue")
kills.Name = "Kills"
kills.Parent = folder
local rank = Instance.new("IntValue")
rank.Name = "Rank"
rank.Value = 1
rank.Parent = folder
local Success, data = pcall(function() -- Added a pcall
return singleStorage:GetAsync(plr.UserId)
end)
if not Success then -- The data failed to load
-- Do something if the data faield
else -- The data loaded successfully
if data then
coins.Value = data[1]
gems.Value = data[2]
kills.Value = data[3]
rank.Value = data[4]
else
-- Give the player the default data
end
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
local leaderstats = plr:FindFirstChild('leaderstats')
if leaderstats then
local saveData = {
leaderstats['Coins'].Value,
leaderstats['Gems'].Value,
leaderstats['Kills'].Value,
leaderstats['Rank'].Value
}
local Success, Error = pcall(function() -- Added pcall
singleStorage:UpdateAsync(plr.UserId, function(OldData) -- Calls the UpdateAsync() function
return saveData
end)
end)
if not Success then
-- Do something if the save failed
end
end
end)
You should modify this script to fit your use case and where I have left comments. For further improvements you should add BindToClose()
for saving data: BindToClose & Data Loss Risk - #2 by Tiffblocks