SetAsync not always working

`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

  1. Line 88 is where the script just stops and gives no errors or warnings

  2. 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)
3 Likes

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?

2 Likes

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)
2 Likes

tried it both in studio and in published game still doesn’t work and yes i tested it solo on all attempts

2 Likes

What prints/warnings appear in the output?

1 Like

no warnings/errors/prints just the same empty output

1 Like

does savedata[Player.UserId] exist ? Try printing it in the leaving function and see what happens

1 Like

savedata does exist it gives me this table when printed

{
                          ["Cash"] = 59,
                          ["CursorRank"] = 1,
                          ["Diamonds"] = 0
                       } 
1 Like

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

1 Like

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)
1 Like

did u print the table to check if that has the values as 0?

1 Like

just did it now. i got the same exact table as last time. still not a single error

2 Likes

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)

How to properly utilize UpdateAsync – here is article about it

1 Like

Hello.

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.

Good luck with it.

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.

As it costs so much fro Roblox to renovate and serve their servers better, you will have to use stronger methods like the custom modules I provided.

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.

Exacly. I just believe that it would be easier.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.