Datastore broken

Hi there!
I’m trying to work on a datastore, but for some reason it does not work.
What is wrong?

local players = game:GetService("Players")
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("CashValueSaver")
local ds2 = datastore:GetDataStore("RebirthsValueSaver")

players.PlayerAdded:connect(function(player)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = player
	
	local currency1 = Instance.new("IntValue")
	currency1.Name = "Points"
	currency1.Parent = player.leaderstats
	currency1.Value = ds1:GetAsync(player.UserId) or 0
	ds1:SetAsync(player.UserId, currency1.Value)
	local currency2 = Instance.new("IntValue")
	
	currency2.Name = "Clicks"
	currency2.Parent = player.leaderstats
	currency2.Value = ds2:GetAsync(player.UserId) or 0
	ds2:SetAsync(player.UserId, currency2.Value)
	
	currency1.Changed:connect(function()
		ds1:SetAsync(player.UserId, currency1.Value)
	end)
	currency2.Changed:connect(function()
		ds2:SetAsync(player.UserId, currency2.Value)
	end)
	
end)
2 Likes

Mhm… as I’m looking trough the script, I think you forgot to implement when the player leaves to save the values…

1 Like

So instead, can I make it save whenever a change in value happens?

I forgot I already have that in the code.

	currency1.Changed:connect(function()
		ds1:SetAsync(player.UserId, currency1.Value)
	end)
	currency2.Changed:connect(function()
		ds2:SetAsync(player.UserId, currency2.Value)
	end)
	
end)

Why does it still not work?

I wouldn’t recommend doing that, that would just fill up roblox’s queue system, and it would drop a lot of requests

You could be using up your SetAsync limit. Try saving the players data when they leave, when the server ends, and every 5 minutes or so.

the problem with that is, it only runs when the player joins. It won’t run if the value will update after the player joined.

while wait()do
currency1.Changed:connect(function()
	ds1:SetAsync(player.UserId, currency1.Value)
end)
currency2.Changed:connect(function()
	ds2:SetAsync(player.UserId, currency2.Value)
end)
end

end)
This is a fex then?

no it won’t that would just fill up roblox’s queue system again. And it would probably lag out a lot of users.

Actually, the connection to changed will run until the value instance is destroyed.

image
That didn’t work anyways.

What I would recommend doing:

  • Make a function called save player data that gets the IntValues/NumberValues and takes a player as a parameter. It should then take those values and save them.
  • Run this function when a player leaves (connect to Players.PlayerRemoving)
  • Run this function when the server ends for every player (use game:BindToClose)
  • Run this function for every player every 5 mins or so (while loop at the end of your code or in a spawn() with a wait(5*60) to yield)

Can you show me in my code? I’m a bit confused.

Ok so, here’s a script that shows you how you should save/load things with data store service

local dataStore = game:GetService("DataStoreService")
local moneys = dataStore:GetDataStore("Moneys")

game.Players.PlayerAdded:Connect(function(plr)
	local folder = Instance.new("Folder",plr)
	folder.Name = "leaderstats"
	
	local value = Instance.new("IntValue",folder)
	value.Name = "Money"
	
	local data
	
	local success,err = pcall(function()
		data = moneys:GetAsync("Money-"..plr.UserId)
	end)
	
	if data and success then
		value.Value = data
	else
		warn(err)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr) -- if a player leaves
	if plr:FindFirstChild("leaderstats") then
		local toSave = plr:FindFirstChild("leaderstats").Money
		
		local data
		local success, err = pcall(function()
			data = moneys:SetAsync("Money-"..plr.UserId,toSave.Value)
		end)
		
		if success then
			print("Successfully saved player data")
		else
			warn(err)
		end
	end
end)

game:BindToClose(function() -- just in case if the server closes before the script can save the player data
	for _, player in pairs(game.Players:GetPlayers()) do
		if player:FindFirstChild("leaderstats") then
			local toSave = player:FindFirstChild("leaderstats").Money

			local data
			local success, err = pcall(function()
				data = moneys:SetAsync("Money-"..player.UserId,toSave.Value)
			end)

			if success then
				print("Successfully saved player data")
			else
				warn(err)
			end
		end
	end
end)


while wait(500) do -- if you want auto save
	for _, player in pairs(game.Players:GetPlayers()) do
		if player:FindFirstChild("leaderstats") then
			local toSave = player:FindFirstChild("leaderstats").Money

			local data
			local success, err = pcall(function()
				data = moneys:SetAsync("Money-"..player.UserId,toSave.Value)
			end)

			if success then
				print("Successfully saved player data")
			else
				warn(err)
			end
		end
	end
end

Hopefully this helped!
Speedrun scripting

2 Likes

I duplicated the script for 2 values, and only got 1.
image

Did you change the data store key?
Did you change the int value name?

What is the ke yhere?

	local data

	local success,err = pcall(function()
		data = moneys:GetAsync("Money-"..plr.UserId)
	end)

This is what I was thinking. You need to change this, other wise they will overwrite each other

image

image
Did not fix.

What I see on the picture is that you use a custom leaderboard, am I right?