Leader board saving script problem

problem is that it isnt producing any error messages but everytime i change the value and leave and join back it is still at 0 can some one please help me

local datastorage = game:GetService("DataStoreService")
local mainstorage = datastorage:GetDataStore("MainScore")
local httpservice = game:GetService("HttpService")
local NormalData = {
	["Exp"] = 0,
	["Souls"] = 0,
}

game.Players.PlayerAdded:Connect(function(player)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	local Exp = Instance.new("IntValue", folder)
	Exp.Name = "Exp"
	local Souls = Instance.new("IntValue", folder)
	Souls.Name = "Souls"

	folder.Parent = player

	local data = NormalData

	local success, err = pcall(function()
		local plrdata = mainstorage:GetAsync(player.UserId)
		if plrdata then
			if type(plrdata) == "string" then
				plrdata = httpservice:JSONDecode(plrdata)
				data = plrdata
			else
				data = NormalData
			end
		else
			data = NormalData
		end
	end)

	if err then
		warn(err)
	end

	Exp.Value = data["Exp"] or 0 
	Souls.Value = data["Souls"] or 0
end)

game.Players.PlayerRemoving:Connect(function(player)
	local SaveData = {
		["Exp"] = player.leaderstats.Exp.Value,
		["Souls"] = player.leaderstats.Souls.Value,
	}

	local encodedData = httpservice:JSONEncode(SaveData)
	local success, err = pcall(function()
		mainstorage:SetAsync(player.UserId, encodedData)
	end)

	if err then
		warn("Data didnt save")
	end
end)
4 Likes

also it was suppost to input the data back

how do you change the data? if you’re changing it locally (you are changing the value from the explorer while on client view) then thats the problem. if the latter is true then switch to server, change the value then rejoin to see if it works

1 Like

There’s no need to JSON encode/decode data before using GetAsync or SetAsync, as they already do so automatically

The issue that you’re experiencing is happening due to Studio closing the play-test too quickly, so you can fix the issue by:

  • Adding this at the top of your script, next to the services:
local runservice = game:GetService("RunService")
  • Add this at the very bottom of the script, outside of any connections:
game:BindToClose(function()
	if runservice:IsStudio() then
		task.wait(2)
	else -- This will handle saving data for when the server unexpectedly shuts down
		local x, y = 0, 0

		local function emergencySave(player: Player)
			local SaveData = {
				["Exp"] = player.leaderstats.Exp.Value,
				["Souls"] = player.leaderstats.Souls.Value,
			}

			xpcall(mainstorage.SetAsync, warn, mainstorage, player.UserId, SaveData)
	
			y += 1
		end

		for _, player in game.Players:GetPlayers() do
			x += 1
			task.spawn(emergencySave, player)
		end

		repeat task.wait() until y == x
	end
end)
2 Likes

the script is located in server script so it isnt in local

thats not the point, do you go to the explorer while you’re on the client?
image
if you’re changing it while you’re still on the client, click it to go to the server and then change it
image

1 Like

thanks dude your a life savior

1 Like

Nvm i tryed it again yesterday and it didnt work at all :frowning:

Add prints when you set the data on the player and see if it works or not, for example when you check if the type of data is sting, set a print there, do the same on the else

Waiting for reply

1 Like

i will try it now, i will be rigth back!

i added a print system that prints the data before, and after, it seems to print the data fine, so it must be the mainstorage thats not storing it probably

it has to be this one

		local plrdata = mainstorage:GetAsync(player.UserId)

1 Like

So the data that is printed at save is the correct one and those at load are not the correct ones?

1 Like

Replace the entire script with this, and it will work:

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local mainStorage = DataStoreService:GetDataStore("MainScore")

local normalData = {
	Exp = 0,
	Souls = 0,
}


local function onPlayerAdded(player: Player)
	local success, data = pcall(mainStorage.GetAsync, mainStorage, player.UserId)

	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local exp = Instance.new("IntValue")
	exp.Name = "Exp"
	exp.Value = normalData.Exp

	local souls = Instance.new("IntValue")
	souls.Name = "Souls"
	souls.Value = normalData.Souls

	if success then
		if data then
			exp.Value = data.Exp
			souls.Value = data.Souls
		end
	else
		warn(`Failed to get data for Player {player.UserId} ({player.DisplayName})\nError: {data}`)
	end

	exp.Parent = leaderstats
	souls.Parent = leaderstats
end

local function onPlayerRemoving(player: Player)
	local leaderstats = player:FindFirstChild("leaderstats")
	if leaderstats == nil then return end

	local exp = leaderstats:FindFirstChild("Exp")
	local souls = leaderstats:FindFirstChild("Souls")

	local saveData = {
		Exp = if exp then exp.Value else 0,
		Souls = if souls then souls.Value else 0,
	}

	local success, error = pcall(mainStorage.SetAsync, mainStorage, player.UserId, saveData)
	if success then return end

	warn(`Failed to save data for Player {player.UserId} ({player.DisplayName})\nError: {error}`)
end

game:BindToClose(function()
	if RunService:IsStudio() then
		task.wait(2)
	else
		local x, y = 0, 0

		local function emergencySave(player: Player)
			onPlayerRemoving(player)
			y += 1
		end

		for _, player in Players:GetPlayers() do
			x += 1

			task.spawn(emergencySave, player)
		end

		repeat task.wait() until y == x
	end
end)

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)
1 Like

my bad for not being online for 2 days, i had some work that involves me being offline, but i tested your script and it says this error

value of type nil cannot be converted to a number 

The code that @JohhnyLegoKing provided works fine. I believe you may have damaged it during your implementation, or the error is being raised elsewhere

2 Likes

No what i mean is that the value for exp is working, just that the other one “Souls” isnt, sorry for the misunderstanding

Which line is the error originating from?

Just-in-case, please provide the code so that I can see if there were any changes done to it

1 Like

ok i just changed the value name

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local mainStorage = DataStoreService:GetDataStore("MainScore")

local normalData = {
	Exp = 0,
	Souls = 0,
}


local function onPlayerAdded(player: Player)
	local success, data = pcall(mainStorage.GetAsync, mainStorage, player.UserId)

	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local exp = Instance.new("IntValue")
	exp.Name = "Exp"
	exp.Value = normalData.Exp

	local souls = Instance.new("IntValue")
	souls.Name = "G"
	souls.Value = normalData.Souls

	if success then
		if data then
			exp.Value = data.Exp
			souls.Value = data.Souls
		end
	else
		warn(`Failed to get data for Player {player.UserId} ({player.DisplayName})\nError: {data}`)
	end

	exp.Parent = leaderstats
	souls.Parent = leaderstats
end

local function onPlayerRemoving(player: Player)
	local leaderstats = player:FindFirstChild("leaderstats")
	if leaderstats == nil then return end

	local exp = leaderstats:FindFirstChild("Exp")
	local souls = leaderstats:FindFirstChild("Souls")

	local saveData = {
		Exp = if exp then exp.Value else 0,
		Souls = if souls then souls.Value else 0,
	}

	local success, error = pcall(mainStorage.SetAsync, mainStorage, player.UserId, saveData)
	if success then return end

	warn(`Failed to save data for Player {player.UserId} ({player.DisplayName})\nError: {error}`)
end

game:BindToClose(function()
	if RunService:IsStudio() then
		task.wait(2)
	else
		local x, y = 0, 0

		local function emergencySave(player: Player)
			onPlayerRemoving(player)
			y += 1
		end

		for _, player in Players:GetPlayers() do
			x += 1

			task.spawn(emergencySave, player)
		end

		repeat task.wait() until y == x
	end
end)

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)

i changed the soul, to g, im sorry if im bothering you

1 Like