Why does my Leaderstats Datastore only save sometimes in Roblox Studio, but all the time in Roblox?

I am not sure if you even read to what he was responding too

(nvm)

i think i got it now, wait

This text will be hidden

YES I GOT IT NOW LOL

so, what was happening is in the player added, you used a different key
in here, when saving

i used “_id”… id

but not in here,

i changed it so it messed it up, but it’s working 100% now

full script:

local ds = game:GetService("DataStoreService"):GetDataStore("savedata")
game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.userId
	local save1 = plr.leaderstats:WaitForChild("Coins")
	local save2 = plr.leaderstats:WaitForChild("Money")
	local save3 = plr.leaderstats:WaitForChild("Gems")
	local save4 = plr.leaderstats:WaitForChild("Eggs Opened")
	local save5 = plr.leaderstats:WaitForChild("Snow Coins")
	local save6 = plr.leaderstats:WaitForChild("Snow Cash")

	local s, e = pcall(function()

		local GetSaved = ds:GetAsync("id_"..plr.UserId)

		if GetSaved ~= nil then
			save1.Value = GetSaved[1]; print(GetSaved[1])
			save2.Value = GetSaved[2]; print(GetSaved[2])
			save3.Value = GetSaved[3]; print(GetSaved[3])
			save4.Value = GetSaved[4]; print(GetSaved[4])
			save5.Value = GetSaved[5]; print(GetSaved[5])
			save6.Value = GetSaved[6]; print(GetSaved[6])
			print("player data was loaded")
		else
			local NumberforSaving = {save1.Value, save2.Value, save3.Value, save4.Value, 
				save5.Value, save6.Value}
			ds:GetAsync(plrkey, NumberforSaving)
			print("player was a starter player, default data was loaded instead")
		end
	end)

	if s then
		print("succefully loading player data")
	else
		warn("could not load player's data")
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local s, e = pcall(function()
		ds:SetAsync("id_"..player.UserId, {player.leaderstats.Coins.Value, player.leaderstats.Money.Value, player.leaderstats.Gems.Value, player.leaderstats["Eggs Opened"].Value, player.leaderstats["Snow Coins"].Value, player.leaderstats["Snow Cash"].Value})
	end)

	if not s then
		warn("Could not save "..player.Name.."'s data!")
	end
end)

game:BindToClose(function()
	local players = game.Players
	local s, errorms = pcall(function()    
		for _, v in pairs(players:GetChildren()) do
			local id = v.UserId
			ds:SetAsync("id_"..id, {v.leaderstats.Coins.Value, v.leaderstats.Money.Value, v.leaderstats.Gems.Value, v.leaderstats["Eggs Opened"].Value, v.leaderstats["Snow Coins"].Value, v.leaderstats["Snow Cash"].Value}) -- change data to the value you want to save
		end
	end)

	if s then
		print("success saving players data")
	else
		warn(errorms)
	end
end)
2 Likes

Studio doesn’t always register playerRemoving. Beware roblox also sometimes does this with the last player since the server closes before that, or if you shutdown all server or specific one. I recommend you use “BindToClose” which is a function that fires on server shutdown, whether forced or last player leaving.

When using the “BindToClose” event. If will halt server shutdown, which may make the studio stop button delay be longer. However, it increase player data security.

When the “BindToClose” fires. Run a loop of all players and save all their data. Then add a “:wait()” at the end because for some reason from my experience. It doesn’t always work without that “:wait()” to add extra server close delay. Cause roblox lua. Unless you use a loop then “:wait()” isn’t needed. Cause once again roblox stuff.

You must still use player removing to save data.

Bind To Close Documentation

My past example of BindToClose

local modulesF = game:GetService("ServerScriptService"):WaitForChild("Modules")--Module folder
local StatsController = require(modulesF:WaitForChild("StatsController"))--Stats Controller

local serverStorage = game:GetService("ServerStorage")

local statsF = serverStorage:WaitForChild("PlayerStats")--Folder to hold stats

game:BindToClose(function()
	local players = game:GetService("Players"):GetPlayers()
	for i,v in pairs(players) do
		local outcome = StatsController.saveStats(v)
		print(outcome)
	end
end)
1 Like

that’s not the problem now actually, it’s that the data is not loading.

Alright, so far I think it works! How could I remove the prints so it doesn’t flood the output?

Not loading cause it doesn’t save on servershutdown because server fully shutdowns before leaving event register. So bind to close saves data and hauls server shutdown.

nvm, just script writing error. It be like that, writing error take 10 years to find and u rewrite everything believing you did it all wrong.

Tip print all you data when loading and print after every if statement or request. So you can find where it breaks, remove prints once it works.

oh yes right, wait

change it to this, or just remove the comments

local ds = game:GetService("DataStoreService"):GetDataStore("savedata")
game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.userId
	local save1 = plr.leaderstats:WaitForChild("Coins")
	local save2 = plr.leaderstats:WaitForChild("Money")
	local save3 = plr.leaderstats:WaitForChild("Gems")
	local save4 = plr.leaderstats:WaitForChild("Eggs Opened")
	local save5 = plr.leaderstats:WaitForChild("Snow Coins")
	local save6 = plr.leaderstats:WaitForChild("Snow Cash")

	local s, e = pcall(function()

		local GetSaved = ds:GetAsync("id_"..plr.UserId)

		if GetSaved ~= nil then
			save1.Value = GetSaved[1]; --print(GetSaved[1])
			save2.Value = GetSaved[2]; --print(GetSaved[2])
			save3.Value = GetSaved[3]; --print(GetSaved[3])
			save4.Value = GetSaved[4]; --print(GetSaved[4])
			save5.Value = GetSaved[5]; --print(GetSaved[5])
			save6.Value = GetSaved[6]; --print(GetSaved[6])
			--print("player data was loaded")
		else
			local NumberforSaving = {save1.Value, save2.Value, save3.Value, save4.Value, 
				save5.Value, save6.Value}
			ds:GetAsync(plrkey, NumberforSaving)
			--print("player was a starter player, default data was loaded instead")
		end
	end)

	if s then
		print("succefully loading player data")
	else
		warn("could not load player's data")
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local s, e = pcall(function()
		ds:SetAsync("id_"..player.UserId, {player.leaderstats.Coins.Value, player.leaderstats.Money.Value, player.leaderstats.Gems.Value, player.leaderstats["Eggs Opened"].Value, player.leaderstats["Snow Coins"].Value, player.leaderstats["Snow Cash"].Value})
	end)

	if not s then
		warn("Could not save "..player.Name.."'s data!")
	end
end)

game:BindToClose(function()
	local players = game.Players
	local s, errorms = pcall(function()    
		for _, v in pairs(players:GetChildren()) do
			local id = v.UserId
			ds:SetAsync("id_"..id, {v.leaderstats.Coins.Value, v.leaderstats.Money.Value, v.leaderstats.Gems.Value, v.leaderstats["Eggs Opened"].Value, v.leaderstats["Snow Coins"].Value, v.leaderstats["Snow Cash"].Value}) -- change data to the value you want to save
		end
	end)

	if s then
		print("success saving players data")
	else
		warn(errorms)
	end
end)

i actually have to go now, lol.

yes, i already added a bind to close. a new problem just occured when we were fixing it

Alright I do too! Thank you so much, I appreciate it!

glad i could help :slight_smile:

This text will be hidden

1 Like

Hey quick question, how can I make it so when it loads in, it only shows for that one person? Instead of it showing many times because many people are joining?

(actually I think it only shows in server, nvm)

you can use a local script, so it’s only appearing on that client who joined. oh and also put it in starter player script so it doesn’t re appear when player respawns

1 Like