Leaderstats Not Saving

Hello fellow developers! I’ve made a leaderstat saver and for some reason it doesn’t save when I leave. Is there a way to fix this?

local dataStoreService = game:GetService("DataStoreService")
local DS = dataStoreService:GetDataStore("LeaderSave")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	--------

	local koi = Instance.new("IntValue")
	koi.Name = "Koi"
	koi.Value = 0 -- Always 100
	koi.Parent = leaderstats

	local wins = Instance.new("IntValue")
	wins.Name = "Wins"
	wins.Value = 0
	wins.Parent = leaderstats

	local deaths = Instance.new("IntValue")
	deaths.Name = "Deaths"
	deaths.Value = 0
	deaths.Parent = leaderstats
	
	-------
	
	local comets = Instance.new("IntValue")
	comets.Name = "Comets"
	comets.Value = 0
	comets.Parent = leaderstats
	--[[
	Coments. 20 Comets : 1 Koi. If Comets are not exactly a 20 multiple, then it will be rounded to the nearest
	twenty. If it's not convertable, then it will be rounded down.]]
	
	print("Leaderstats Loaded!")
	
	--------------------------------------------
	
	local DeathsData, WinsData, KoiData
	
	local success, errormessage = pcall(function()
		DeathsData = DS:GetAsync("deaths-"..player.UserId)
		WinsData = DS:GetAsync("wins-"..player.UserId)
		KoiData = DS:GetAsync("koi-"..player.UserId)
		
	end)
	
	if success then
		print("Successful!")
		deaths.Value = DeathsData
		wins.Value = WinsData
		koi.Value = KoiData
	end
	
	if errormessage then
		print("Error! Error!")
		deaths.Value = DeathsData
		wins.Value = WinsData
		koi.Value = KoiData
		repeat until success
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		DS:SetAsync("deaths-"..player.UserId, player.leaderstats.Deaths.Value)
		DS:SetAsync("wins-"..player.UserId, player.leaderstats.Wins.Value)
		DS:SetAsync("koi-"..player.UserId, player.leaderstats.Koi.Value)
	end)
	
end)

I’m not sure what broke or I need to fix. Any help is appreciated!

(BTW Comets isn’t supposed to save, just the others arent saving.)

1 Like

Check if API Services are enabled
Settings > Security > API Services

API Services are enabled

adding more text because of the limit

Try checking if it’s a success then if it isn’t print out the error message. also try using game:BindToClose()

What does game:BindToClose() do?

It basically just stops the game server from closing until that function you put into it has been completed you can look at the documentation here: DataModel | Documentation - Roblox Creator Hub

Would something like this work?

local DeathsData, WinsData, KoiData
	
	local success, errormessage = pcall(function()
		DeathsData = DS:GetAsync("deaths-"..player.UserId)
		WinsData = DS:GetAsync("wins-"..player.UserId)
		KoiData = DS:GetAsync("koi-"..player.UserId)
		
	end)
	
	if success then
		print("Successful!")
		deaths.Value = DeathsData
		wins.Value = WinsData
		koi.Value = KoiData
		
	else
		print("Error!")
		game:BindToClose()
	end

It would be more like:


local function SaveData(player)

 local success, errormessage = pcall(function()
		DS:SetAsync("deaths-"..player.UserId, player.leaderstats.Deaths.Value)
		DS:SetAsync("wins-"..player.UserId, player.leaderstats.Wins.Value)
		DS:SetAsync("koi-"..player.UserId, player.leaderstats.Koi.Value)
	end)

end

local function GameBind()

 for i,v in pairs(game.Players:GetPlayers) do
  SaveData(v)

 end
end

game:BindToClose(GameBind)

I’m going to test this out

roblox character limit thingy

1 Like

It sent me this DataStore request was added to queue. If request queue fills, further requests will be dropped. Try sending fewer requests.Key = wins-526801380

Also I made it game.Players.GetPlayers(). It still doesn’t save

1 Like

Do you have an autosave bit or is that all the code?

local dataStoreService = game:GetService("DataStoreService")
local DS = dataStoreService:GetDataStore("LeaderSave")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	--------

	local koi = Instance.new("IntValue")
	koi.Name = "Koi"
	koi.Value = 0 -- Always 100
	koi.Parent = leaderstats

	local wins = Instance.new("IntValue")
	wins.Name = "Wins"
	wins.Value = 0
	wins.Parent = leaderstats

	local deaths = Instance.new("IntValue")
	deaths.Name = "Deaths"
	deaths.Value = 0
	deaths.Parent = leaderstats
	
	-------
	
	local comets = Instance.new("IntValue")
	comets.Name = "Comets"
	comets.Value = 0
	comets.Parent = leaderstats
	--[[
	Coments. 20 Comets : 1 Koi. If Comets are not exactly a 20 multiple, then it will be rounded to the nearest
	twenty. If it's not convertable, then it will be rounded down.]]
	
	print("Leaderstats Loaded!")
	
	--------------------------------------------
	

	local function SaveData(player)

		local success, errormessage = pcall(function()
			DS:SetAsync("deaths-"..player.UserId, player.leaderstats.Deaths.Value)
			DS:SetAsync("wins-"..player.UserId, player.leaderstats.Wins.Value)
			DS:SetAsync("koi-"..player.UserId, player.leaderstats.Koi.Value)
		end)

	end

	local function GameBind()

		for i,v in pairs(game.Players:GetPlayers()) do
			SaveData(v)

		end
	end

	game:BindToClose(GameBind)
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		DS:SetAsync("deaths-"..player.UserId, player.leaderstats.Deaths.Value)
		DS:SetAsync("wins-"..player.UserId, player.leaderstats.Wins.Value)
		DS:SetAsync("koi-"..player.UserId, player.leaderstats.Koi.Value)
	end)
	
end)

This is my current code

move game:BindToClose(GameBind) to be outside of the function

GameBind has a red underline.

roblox character limit

remove those bits outside the function

So instead of having them inside the player joined just move them out

Not necessarily on topic, but is there a reason you save data like this? You do know you can save tables, right? You would only need to use GetAsync once for all of these.

local data = {
	Deaths = player.leaderstats.Deaths.Value;
	Wins = player.leaderstats.Wins.Value;
	Koi =  player.leaderstats.Koi.Value;
}

DS:SetAsync(player.UserId, data)

I was going to suggest that but that would of added some extra complication e.g if a value got to big you may need to compact it

It easier for my brain to process

1 Like