DataStore not working!

Hello!
I was helping my friend with his game until I ran a problem.
While trying to make datastore, when it increases the amount by 10 or 5, it resets back to 0 and does not save!
I’m new to making datastore so there may be a lot of errors.

Script
--- Add Leaderstats ---
game:GetService("Players").PlayerAdded:Connect(function(Player)
	local Folder = Instance.new("Folder", Player)
	Folder.Name = "leaderstats"
	local NumberValue = Instance.new("NumberValue", Folder)
	NumberValue.Name = "Studs"
end)

--- Add Studs/minute and Save Currency ---
game:GetService("Players").PlayerAdded:Connect(function(Player)
	local NumberValue = Player:WaitForChild("leaderstats").Studs
	local DataStore = game:GetService("DataStoreService")
	local GameDataStore = DataStore:GetDataStore("GameDataStore")
	local Data

	if Player.MembershipType == Enum.MembershipType.None then
		while wait(60) do
			Player.leaderstats.Studs.Value += 5
			wait(1)
			local Success, ErrorMessage = pcall(function()
				Data = GameDataStore:GetAsync(Player.UserId.."-NumberValue")
			end)
			
			if Success then
				NumberValue.Value = Data
			else
				local GUI = Player:WaitForChild("PlayerGui").DataSaveFailed
				GUI.TextLabel.Visible = true
				warn("Saving for player ||"..Player.Name.."|| failed!")
			end
		end
	elseif Player.MembershipType == Enum.MembershipType.Premium then
		while wait(30) do
			Player.leaderstats.Studs.Value += 10
			wait(1)
			local Success, ErrorMessage = pcall(function()
				Data = GameDataStore:GetAsync(Player.UserId.."-NumberValue")
			end)

			if Success then
				NumberValue.Value = Data
			else
				local GUI = Player:WaitForChild("PlayerGui").DataSaveFailed
				GUI.TextLabel.Visible = true
				warn("Saving for player ||"..Player.Name.."|| failed!")
			end
		end
	end
end)

--- Save Currency When Player Is Leaving ---
game:GetService("Players").PlayerRemoving:Connect(function(Player)
	local NumberValue = Player.leaderstats.Studs
	local DataStore = game:GetService("DataStoreService")
	local GameDataStore = DataStore:GetDataStore("GameDataStore")
	
	local Success, ErrorMessage = pcall(function()
		GameDataStore:SetAsync(Player.UserId.."-NumberValue", Player.leaderstats.Studs.Value)
	end)
	
	if Success then
		print("Data for player ||"..Player.Name.."|| was saved succesfully!")
	else
		warn("Saving data upon leaving for player ||"..Player.Name.."|| failed!")
	end
end)

waiting for a response!

Hey!

I’ve messed with your code a bit and compiled a list of problems I saw, both opinionated and technical.

  • Two functions for playeradded is redundant and may cause one or the other to not register

  • I personally recommend avoiding inescapable loops (event based code instead of repeat until / while true/wait do) and the use of task.wait() (Uses heartbeat) instead of wait() due to this, I’ve changed it to a task.delay with a looping function call per player.

  • It appears originally every give you would getasync on the saved value, set it to that before saving, then save the new value causing a loop with no progress (you could only get to 5) to compound this, you also did not set the studs value from cache on join resulting in the appearance of a reset (values were still saved behind the scenes)

  • I may also add that saving / fetching the datastore every give is not an efficient way to do datastore. I recommend doing it ONLY when the player leaves

  • I have added functionality to kick the player upon unsuccessfully retrieving data as a safeguard to data loss. (can be removed in line 30)

  • ALSO: Make sure you turn on studio datastore access in studio if you want to test this in studio.

No need to fret, I’ve already tested this and can confirm it works. This should go in serverscriptservice.

Script
--- Leaderstats / Add Studs/minute and Save Currency ---

game.Players.PlayerAdded:Connect(function(plr)
	Instance.new("Folder",plr).Name = "leaderstats"
	Instance.new("NumberValue",plr:WaitForChild("leaderstats")).Name = "Studs"
	local gds = game:GetService("DataStoreService"):GetDataStore("GameDataStore")
	local togive
	local s,e = pcall(function()
		togive = gds:GetAsync(plr.UserId)
	end)
	if s then
		print("Data for player ||"..plr.Name.."|| was fetched succesfully!")
		plr.leaderstats.Studs.Value = togive
		local basetime = 60
		local baseamt = 5
		if plr.MembershipType == Enum.MembershipType.Premium then
			basetime /= 2
			baseamt *= 2
		end
		local function give()
			plr.leaderstats.Studs.Value += baseamt
		end
		local function loop()
			task.delay(basetime,function()
				give()
				task.wait(0.1)
				loop()
			end)
		end
		loop()
	else
		warn("Saving data upon leaving for player ||"..plr.Name.."|| failed! || " .. e)
		plr:Kick("Failed to fetch datastore. Please try again. If this issue persists, contact the developer.")
	end
end)

--- Save Currency When Player Is Leaving ---

game.Players.PlayerRemoving:Connect(function(plr)
	local gds = game.DataStoreService:GetDataStore("GameDataStore")
	local s,e = pcall(function()
		gds:SetAsync(plr.UserId,plr.leaderstats.Studs.Value)
	end)
	if s then
		print("Data for player ||"..plr.Name.."|| was saved succesfully!")
	else
		warn("Saving data upon leaving for player ||"..plr.Name.."|| failed! || " .. e)
	end
end)
2 Likes