`1. i want it to work 100% of the time but so far it has worked about 8% of the time both in studio and in the actual game
Line 88 is where the script just stops and gives no errors or warnings
I have sued Print statements to see if i made any errors typing none were found
I have looked on this forum to find people with the same problem as me (SetAsync Not working) none were even related to my issue
Script:
local Players = game:GetService("Players")
local DSS = game:GetService("DataStoreService")
local Data = DSS:GetDataStore("data")
local savedata = {}
local RunService = game:GetService("RunService")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = ("leaderstats")
local clicks = Instance.new("IntValue")
clicks.Name= ("Clicks")
clicks.Parent = leaderstats
clicks.Value = 0
local cash = Instance.new("IntValue")
cash.Name= ("Cash")
cash.Parent = leaderstats
local diamonds = Instance.new("IntValue")
diamonds.Name= ("Diamonds")
diamonds.Parent = leaderstats
local CursorRank = Instance.new("IntValue")
CursorRank.Name = "CursorRank"
CursorRank.Parent = leaderstats
local success = nil
local PlayerData = nil
local attempt = 1
repeat
success, PlayerData = pcall(function()
return Data:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(PlayerData)
task.wait(3)
end
until success or attempt == 5
if success then
if not PlayerData then
PlayerData = {
["Cash"] = 0,
["Diamonds"] = 0,
["CursorRank"] = 1
}
end
savedata[player.UserId] = PlayerData
else
warn("unable to get data for:", player.UserId)
player:Kick("Unable to load saved data")
end
cash.Value = savedata[player.UserId].Cash
cash.Changed:Connect(function()
savedata[player.UserId].Cash = cash.Value
end)
diamonds.Value = savedata[player.UserId].Diamonds
diamonds.Changed:Connect(function()
savedata[player.UserId].Diamonds = diamonds.Value
end)
CursorRank.Value = savedata[player.UserId].CursorRank
CursorRank.Changed:Connect(function()
savedata[player.UserId].CursorRank = CursorRank.Value
end)
leaderstats.Parent = player
end)
function PlayerLeaving(Player)
if savedata[Player.UserId] then
local success = nil
local errorMessage = nil
local attempt = 1
repeat
success, errorMessage = pcall(function()
Data:SetAsync(Player.UserId, savedata[Player.UserId])
end)
if not success then
warn(errorMessage)
task.wait(1)
attempt += 1
end
until success or attempt == 10
if success then
print("saved Player:", Player.Name)
else
warn("unable to save Player:", Player.Name)
end
end
end
game:BindToClose(function()
if RunService:IsStudio() then
return
end
for i, player in ipairs(Players:GetPlayers()) do
task.spawn(PlayerLeaving,player)
end
end)
Players.PlayerRemoving:Connect(PlayerLeaving)
Maybe it does not print anything sometimes, but does it mean that it didn’t save? I don’t know man. I went to test > Start. I started 3 servers each time I closed the previous one. It saved every single time. Could it be because the server closes too soon in roblox studio?
add task.wait(2) before returning from the bind to close function to give it time to save. If I were to guess your testing it solo and because when you leave the whole server closes its not getting enough time to save.
Here is what the code would look like:
local Players = game:GetService("Players")
local DSS = game:GetService("DataStoreService")
local Data = DSS:GetDataStore("data")
local savedata = {}
local RunService = game:GetService("RunService")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = ("leaderstats")
local clicks = Instance.new("IntValue")
clicks.Name= ("Clicks")
clicks.Parent = leaderstats
clicks.Value = 0
local cash = Instance.new("IntValue")
cash.Name= ("Cash")
cash.Parent = leaderstats
local diamonds = Instance.new("IntValue")
diamonds.Name= ("Diamonds")
diamonds.Parent = leaderstats
local CursorRank = Instance.new("IntValue")
CursorRank.Name = "CursorRank"
CursorRank.Parent = leaderstats
local success = nil
local PlayerData = nil
local attempt = 1
repeat
success, PlayerData = pcall(function()
return Data:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(PlayerData)
task.wait(3)
end
until success or attempt == 5
if success then
if not PlayerData then
PlayerData = {
["Cash"] = 0,
["Diamonds"] = 0,
["CursorRank"] = 1
}
end
savedata[player.UserId] = PlayerData
else
warn("unable to get data for:", player.UserId)
player:Kick("Unable to load saved data")
end
cash.Value = savedata[player.UserId].Cash
cash.Changed:Connect(function()
savedata[player.UserId].Cash = cash.Value
end)
diamonds.Value = savedata[player.UserId].Diamonds
diamonds.Changed:Connect(function()
savedata[player.UserId].Diamonds = diamonds.Value
end)
CursorRank.Value = savedata[player.UserId].CursorRank
CursorRank.Changed:Connect(function()
savedata[player.UserId].CursorRank = CursorRank.Value
end)
leaderstats.Parent = player
end)
function PlayerLeaving(Player)
if savedata[Player.UserId] then
local success = nil
local errorMessage = nil
local attempt = 1
repeat
success, errorMessage = pcall(function()
Data:SetAsync(Player.UserId, savedata[Player.UserId])
end)
if not success then
warn(errorMessage)
task.wait(1)
attempt += 1
end
until success or attempt == 10
if success then
print("saved Player:", Player.Name)
else
warn("unable to save Player:", Player.Name)
end
end
end
game:BindToClose(function()
if not RunService:IsStudio() then
for i, player in ipairs(Players:GetPlayers()) do
task.spawn(PlayerLeaving,player)
end
end
task.wait(2)
end)
Players.PlayerRemoving:Connect(PlayerLeaving)
well then its likely that the server is closing and the rest of the code can’t execute, try increasing the wait time in the bind to close function and see what happens
ok thank you for making it save but another issue has appeared and that its no longer loading the values saved and instead its all showing up as 0
without error or warnings
script to load values :
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = ("leaderstats")
local clicks = Instance.new("IntValue")
clicks.Name= ("Clicks")
clicks.Parent = leaderstats
clicks.Value = 0
local cash = Instance.new("IntValue")
cash.Name= ("Cash")
cash.Parent = leaderstats
local diamonds = Instance.new("IntValue")
diamonds.Name= ("Diamonds")
diamonds.Parent = leaderstats
local CursorRank = Instance.new("IntValue")
CursorRank.Name = "CursorRank"
CursorRank.Parent = leaderstats
local success = nil
local PlayerData = nil
local attempt = 1
repeat
success, PlayerData = pcall(function()
return Data:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(PlayerData)
task.wait(3)
end
until success or attempt == 5
if success then
if not PlayerData then
PlayerData = {
["Cash"] = 0,
["Diamonds"] = 0,
["CursorRank"] = 1
}
end
savedata[player.UserId] = PlayerData
else
warn("unable to get data for:", player.UserId)
player:Kick("Unable to load saved data")
end
cash.Value = savedata[player.UserId].Cash
cash.Changed:Connect(function()
savedata[player.UserId].Cash = cash.Value
end)
diamonds.Value = savedata[player.UserId].Diamonds
diamonds.Changed:Connect(function()
savedata[player.UserId].Diamonds = diamonds.Value
end)
CursorRank.Value = savedata[player.UserId].CursorRank
CursorRank.Changed:Connect(function()
savedata[player.UserId].CursorRank = CursorRank.Value
end)
leaderstats.Parent = player
end)
for the future, use update async to save data, you can then compare if current data is correct and if there will be error, data before player joined the game will be still here, soo no data lost, and one thing more, using loop to save data is really bad and it’s a reason, you see you can fire setAsync per key only once a 6 seconds, soo you are blocking your set async, stop doing this, instead use update async as i told to compare data and safely save it. When you save data, never use wait or something it can make game think it’s saved or not soo it glitches, i think i helped you.
Example:
local succes,err = pcall(function()
DataStore:UpdateAsync(key,
function(PastData)
if PastData.Version ~= CurrentData.Version then
return nil -- data is not safe to overwrite
else
CurrentData.Version += 1
return CurrentData -- return current data, safe to overwrite
)
end)
That’s because your datastore is not strong enough.
Roblox DataStores aren’t usually that stable, but recently people have been creating methods to save data more efficiently by saving tables over tables, encoding and decoding them with HttpService.
The most probably and constant way to save datastores like pretty big games does is using custom made modules specifically for this usage.
Such as, ProfileService or DataStore2.
You can search them on the DevForum as I wrote them and you’ll stumble upon their API.
Although they include pretty different methods, I believe that is the best way to do it like that.
Oh well, there’s no such thing as a strong datastore. I wouldn’t call Roblox DataStores unstable (Their servers are) But, it is being limited by roblox to prevent their (databases?) from being spammed and costing them a lot.
You don’t necessarily need to use the custom modules, you can make your own. And it also depends on how much information you store and load from datastoreservice.