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

Hello! My Datastore for my leader stats seems to save in Roblox Studio sometimes, but in Roblox, it saves all the time. How can I fix this?

Script:

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

	local GetSaved = ds:GetAsync(plrkey)
	if GetSaved then
		save1.Value = GetSaved[1]
		save2.Value = GetSaved[2]
		save3.Value = GetSaved[3]
		save4.Value = GetSaved[4]
		save5.Value = GetSaved[5]
		save6.Value = GetSaved[6]
	else
		local NumberforSaving = {save1.Value, save2.Value, save3.Value, save4.Value, save5.Value, save6.Value}
		ds:GetAsync(plrkey, NumberforSaving)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync("id_"..plr.userId, {plr.leaderstats.Coins.Value, plr.leaderstats.Money.Value, plr.leaderstats.Gems.Value, plr.leaderstats["Eggs Opened"].Value, plr.leaderstats["Snow Coins"].Value, plr.leaderstats["Snow Cash"].Value})
end)

Any help will be appreciated! :grinning_face_with_smiling_eyes:

Because PlayerRemoving doesn’t always fire in Studio.
You can use BindToClose() to achieve the effect “PlayerRemoving” would have in Studio.

https://developer.roblox.com/en-us/api-reference/function/DataModel/BindToClose

game:BindToClose(function()
	ds:SetAsync("id_"..plr.userId, {plr.leaderstats.Coins.Value, plr.leaderstats.Money.Value, plr.leaderstats.Gems.Value, plr.leaderstats["Eggs Opened"].Value, plr.leaderstats["Snow Coins"].Value, plr.leaderstats["Snow Cash"].Value})
end)
1 Like

Player.PlayerRemoving doesn’t run all times in studio, from what I’ve heard.

1 Like

So like this?

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

	local GetSaved = ds:GetAsync(plrkey)
	if GetSaved then
		save1.Value = GetSaved[1]
		save2.Value = GetSaved[2]
		save3.Value = GetSaved[3]
		save4.Value = GetSaved[4]
		save5.Value = GetSaved[5]
		save6.Value = GetSaved[6]
	else
		local NumberforSaving = {save1.Value, save2.Value, save3.Value, save4.Value, save5.Value, save6.Value}
		ds:GetAsync(plrkey, NumberforSaving)
	end
end)

game:BindToClose(function(plr)
	ds:SetAsync("id_"..plr.userId, {plr.leaderstats.Coins.Value, plr.leaderstats.Money.Value, plr.leaderstats.Gems.Value, plr.leaderstats["Eggs Opened"].Value, plr.leaderstats["Snow Coins"].Value, plr.leaderstats["Snow Cash"].Value})
end)

BindToClose does not have a parameter. It runs when the server closes, so instead of doing what you showed me above, you save the data for every single player.

Like how I provided above is fine.

What exactly do you mean? I need to add plr so the plr thing works

Yeah, add it inside the function connected to PlayerAdded.

Use a for loop to loop through every player in the server, then save their data.

studio closes too fast so you have to use bindtoclose() to delay the server from closing and then saving all players data

like this,

local datastoreservice = game:GetService("DataStoreService")
local yourDataStore = datastoreservice:GetDataStore("yourDataStore") -- your data store ofc

game:BindToClose(function()
    local players = game.Players
    local s, errorms = pcall(function()    
        for _, v in pairs(players:GetChildren()) do
            local id = v.UserId
            yourDataStore:SetAsync("id_"..id, data) -- change data to the value you want to save
        end
    end)

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

sorry i accidentally pressed enter

???

Do I put this at the bottom of my script?

you can put it anywhere, or a different script

the first script was wrong, i edited it now

Is this what you mean?

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

	local GetSaved = ds:GetAsync(plrkey)
	if GetSaved then
		save1.Value = GetSaved[1]
		save2.Value = GetSaved[2]
		save3.Value = GetSaved[3]
		save4.Value = GetSaved[4]
		save5.Value = GetSaved[5]
		save6.Value = GetSaved[6]
	else
		local NumberforSaving = {save1.Value, save2.Value, save3.Value, save4.Value, save5.Value, save6.Value}
		ds:GetAsync(plrkey, NumberforSaving)
	end
end)

local datastoreservice = game:GetService("DataStoreService")
local yourDataStore = datastoreservice:GetDataStore("yourDataStore") -- your data store ofc

game:BindToClose(function()
	local players = game.Players
	local s, errorms = pcall(function()    
		for _, v in pairs(players:GetChildren()) do
			local id = v.UserId
			yourDataStore:SetAsync("id_"..id.userId, {id.leaderstats.Coins.Value, id.leaderstats.Money.Value, id.leaderstats.Gems.Value, id.leaderstats["Eggs Opened"].Value, id.leaderstats["Snow Coins"].Value, id.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)

yes, that is right.

asdasdasda

For

local yourDataStore = datastoreservice:GetDataStore(“yourDataStore”) – your data store ofc
what do I put for the “yourDataStore”

you did this, so your data store is ‘savedata’

So this?

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

	local GetSaved = ds:GetAsync(plrkey)
	if GetSaved then
		save1.Value = GetSaved[1]
		save2.Value = GetSaved[2]
		save3.Value = GetSaved[3]
		save4.Value = GetSaved[4]
		save5.Value = GetSaved[5]
		save6.Value = GetSaved[6]
	else
		local NumberforSaving = {save1.Value, save2.Value, save3.Value, save4.Value, save5.Value, save6.Value}
		ds:GetAsync(plrkey, NumberforSaving)
	end
end)

local datastoreservice = game:GetService("DataStoreService")
local savedata = datastoreservice:GetDataStore("savedata") -- your data store ofc

game:BindToClose(function()
	local players = game.Players
	local s, errorms = pcall(function()    
		for _, v in pairs(players:GetChildren()) do
			local id = v.UserId
			savedata:SetAsync("id_"..id.userId, {id.leaderstats.Coins.Value, id.leaderstats.Money.Value, id.leaderstats.Gems.Value, id.leaderstats["Eggs Opened"].Value, id.leaderstats["Snow Coins"].Value, id.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)

yes, that is right again.

asdasd