So I originally made a datastore for my game and gave it to my friend to help me out with it. Because it was not working. He then in turn made it better but for some reason it still does not save
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 data = singleStorage:GetAsync(plr.UserId)
if data then
coins.Value = data[1]
gems.Value = data[2]
kills.Value = data[3]
rank.Value = data[4]
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
}
end
end)
I’m pretty sure that you(or your friend) aren’t saving anything at all in the player removing event, there is no saving method there from
what I can see (SetAsync, UpdateAsync etc).
If you wanted to use UpdateAsync, you could do something like this in your player removing event
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
}
singleStorage:UpdateAsync(plr.UserId,function(PreviousData)
return saveData
end)
end
end)
For data to be saved you need to add in a saving method, like UpdateAsync for example, the one I provided above. Try replacing the player removing event with the one I provided and see if that works.
Hiya, I have a few tips for you that I would recommend taking into consideration.
Use Connect over connect because the one with a lowercase c is deprecated and can be removed at any time which results in breaking your script altogether.
Wrap your DataStore functions in pcalls, here is an article to assist you in adding them. Pcalls can prevent data loss which is a win for both you and your players.
I agree that pcalls should be used, not to be nit-picky but I think it is slightly misleading to say that they prevent dataloss just in general, I think it’s more that they are something that some one can use to help someone prevent data loss. They dont prevent data loss on their own, pcalls really just isolate or “quarantine” whatever is wrapped in them and you can use them to your advantage to “validate” stuff.
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
Thank you for this script but I have one more question,
so at this part what would I put as the default data?
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)
The default data refers to the stats the player starts out with when they join your game for the first time. For your game you could create a table that stores all the default stats and you can reference it when you need to:
local DefaultStats = {
coins = 0;
gems = 0;
kills = 0;
rank = "Default";
}
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
coins.Value = DefaultStats.coins
gems.Value = DefaultStats.gems
kills.Value = DefaultStats.kills
rank.Value = DefaultStats.rank
end
end