LeaderBoard Not Working

So i made a LeaderBoard for my Vibe game to let people see who is the best in my game but it doesn’t work.

This is my LeaderBoardHandler script what imports the ui but it doesn’t

local DataStoreService = game:GetService("DataStoreService")
local LevelLeaderBoard = DataStoreService:GetOrderedDataStore("DataStoreLevels")

local function Update ()
	local Succes, ErrorMessage = pcall(function()
		local Data = LevelLeaderBoard:GetSortedAsync(false, 5)
		local LevelPage = Data:GetCurrentPage()
		
		for rank, data in ipairs(LevelPage) do
			local UserName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
			local Name = UserName
			local Level = data.Value
			local isOnLeaderBoard = false
			
			for i, v in pairs(game.Workspace["LeaderBoard - Levels"].Screen.SurfaceGui.MainFrame.Holder:GetChildren()) do
				if v.Player.Text == Name then
					isOnLeaderBoard = true
					break
				end
			end
			if Level and isOnLeaderBoard == false then
				local NewLbFrame = game.ReplicatedStorage:WaitForChild("LevelLeaderBoard"):Clone()
				
				NewLbFrame.Name.Text = Name
				NewLbFrame.Level.Text = Level
				NewLbFrame.Number.Text = rank.."."
				NewLbFrame.Position = UDim2.new(0, 0, NewLbFrame.Position.Y.Offset + (30 * #game.Workspace["LeaderBoard - Levels"].Screen.SurfaceGui.MainFrame.Holder:GetChildren()), 0)
				NewLbFrame.Parent = game.Workspace["LeaderBoard - Levels"].Screen.SurfaceGui.MainFrame.Holder
			end
		end
	end)
	if not Succes then
		print(ErrorMessage)
	end
end

while true do
	
	for _, player in pairs(game.Players:GetPlayers()) do
		LevelLeaderBoard:SetAsync(player.UserId, player.leaderstats.Level.Value)
	end
	
	for _, frame in pairs(game.Workspace["LeaderBoard - Levels"].Screen.SurfaceGui.MainFrame.Holder:GetChildren()) do
		frame:Destroy()
	end
	
	Update()
	print("Updated")
	
	wait(60)
end

And this is my datastore where i save the levels

local currencyName = "Level"
local DataStore = game:GetService("DataStoreService"):GetDataStore("DataStoreLevels")
game.Players.PlayerAdded:Connect(function(player)

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

	local currency = Instance.new("IntValue")
	currency.Name = currencyName
	currency.Parent = folder

	local ID = currencyName.."-"..player.UserId
	local savedData = nil	

	pcall(function()
		savedData = DataStore:GetAsync(ID)
	end)

	if savedData ~= nil then
		currency.Value = savedData

	else
		-- New player
		currency.Value = 0
		print("New player to the game")
	end
	
	while true do
		wait(30)
		currency.Value += 1
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local ID = currencyName.."-"..player.UserId
	DataStore:SetAsync(ID,player.leaderstats[currencyName].Value)
end)

game:BindToClose(function()

	-- When game is ready to shutdown

	for i, player in pairs(game.Players:GetPlayers()) do
		if player then
			player:Kick("This game is shutting down")
		end
	end

	wait(5)	

end)

So the levels are saving but it isn’t going onto the LeaderBoard.

Also it doesn’t give me any errors.

Have you enabled API services in settings?

1 Like

Yes i did enable API service

One thing I am wondering about is why you’re kicking the players in your :BindToClose() function, instead of saving player data. This leads me to wonder if that’s preventing data from ever being written to the DataStore.

2 Likes

What do you mean with kicking players

also this is from a tutorial on youtube i was learning it from the devking but it doesn’t work.
i post this cause i am trying to learn this.

And it doesn’t work.

One other thing I’m noticing is it looks like you’re actually writing to 2 different keys (I assume you’re trying to set the player’s level data from both :SetAsync() calls?)

1 Like

Do you mean like in both scripts cause one of the scripts is for just the player there levels it is the old script is whas made before and i didn’t change it.

so can it be this where the problem is?

The script i made right now is the first one.

So can you help me now with this cause i don’t understand why it doesn’t work cause like your saying things that are wrong but then you don’t help me your just saying what is wrong.

I think you don’t even understand how to do this cause i’m waiting for you and you don’t even look and now ty for not helping me and no-one will help me again and idk why no-one else is helping me.

Why are you kicking players in the script? Is this to test the datastore?

Wait am i kicking players cause like i don’t see where i kick players can you maybe show me the part of the script please

also thank you for reply i am waiting 30 minutes already.

also it is from a youtube vid this script.

You’re not handling pcall failures. pcall returns a status boolean. it’s false if the code in pcall errored. If that status boolean is false then pcall also returns the error message string.

local status, msg = pcall(function()
    savedData = DataStore:GetAsync(ID)
end)

if not status then
    warn(msg)
end

You should be pcalling the SetAsync too. Any roblox method that has the Async suffix needs a pcall.

Other than that the code looks fine; PlayerRemoving and BindToClose don’t execute fast enough in studio if you’ve been trying to test there. You need to go ingame to test those.

1 Like

Np! In the script it says:

		if player then
			player:Kick("This game is shutting down")

(At the end of the datastore script)

It is fine i used this script for now like more then 1 month and it works but the problem is in the other script cause that is making clones of a frame and the parent is becoming in the leaderboard but the problem is that this doesn’t work for some reason.

So i changed my script with this and i did test it and it does not work i also played it on roblox and not in studio.

Didn’t notice your first codeblock. Did you add the pcall for the LevelLeaderBoard:SetAsync line?

Also for the GetSortedAsync load youd prefer to keep the protected code as small as possible and just filter out updating with that status boolean.

local Success, MsgOrLevelPage = pcall(function()
    local Data = LevelLeaderBoard:GetSortedAsync(false, 5)
    return Data:GetCurrentPage()
end

if not Success then
    warn(MsgOrLevelPage)

else
    for rank, data in ipairs(LevelPage) do
        -- all that logic
    end
end

if the load fails it just wont make the new leaderboard gui.

1 Like

So like i tried to do this in my script but it does error at the for

Oh i found it i need ot change something i forgot an end

I forgot a closing parenthesis

1 Like

So i joined the game and i think the part where i have this:

if MsgOrLevelPage then
warn(MsgOrLevelPage)
else

It is warning in my game and it says this:
image

This is also the script right now what i changed cause you did say it to me to change it:

local DataStoreService = game:GetService("DataStoreService")
local LevelLeaderBoard = DataStoreService:GetOrderedDataStore("DataStoreLevels")

local function Update ()
	local Success, MsgOrLevelPage = pcall(function()
		local Data = LevelLeaderBoard:GetSortedAsync(false, 5)
		return Data:GetCurrentPage()
	end)
		
	for rank, data in ipairs(MsgOrLevelPage) do
			local UserName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
			local Name = UserName
			local Level = data.Value
			local isOnLeaderBoard = false
			
			if MsgOrLevelPage then
			warn(MsgOrLevelPage)

			else
			for rank, data in ipairs(MsgOrLevelPage) do
					for i, v in pairs(game.Workspace["LeaderBoard - Levels"].Screen.SurfaceGui.MainFrame.Holder:GetChildren()) do
						if v.Player.Text == Name then
							isOnLeaderBoard = true
							break
						end
					end
					if Level and isOnLeaderBoard == false then
						local NewLbFrame = game.ReplicatedStorage:WaitForChild("LevelLeaderBoard"):Clone()

						NewLbFrame.Name.Text = Name
						NewLbFrame.Level.Text = Level
						NewLbFrame.Number.Text = rank.."."
						NewLbFrame.Position = UDim2.new(0, 0, NewLbFrame.Position.Y.Offset + (30 * #game.Workspace["LeaderBoard - Levels"].Screen.SurfaceGui.MainFrame.Holder:GetChildren()), 0)
						NewLbFrame.Parent = game.Workspace["LeaderBoard - Levels"].Screen.SurfaceGui.MainFrame.Holder
					end
				end
			end
		end
	end

Update()

while true do
	
	for _, player in pairs(game.Players:GetPlayers()) do
		LevelLeaderBoard:SetAsync(player.UserId, player.leaderstats.Level.Value)
	end
	
	for _, frame in pairs(game.Workspace["LeaderBoard - Levels"].Screen.SurfaceGui.MainFrame.Holder:GetChildren()) do
		frame:Destroy()
	end
	
	Update()
	print("Updated")
	
	wait(60)
end