HEY Devs hope you are having a good day so far…Im here cause im having a tiny bug with my leaderboard code…So the leaderboard contains two values under the player EBITS(Cash) and the Level of the player and so every 10 seconds it updates the leaderboard incase theres a change in the values but the bug is ofc it doesnt update it only shows 1 Under Levels and 1 Under EBits here’s a image…I hope someone can help me and guide me on what I did wrong Thank you very much here’s the leaderboard code.
local DataStoreService = game:GetService('DataStoreService')
local LevelsLeaderboard = DataStoreService:GetOrderedDataStore("LevelsLeaderboard");
local CashLeaderboard = DataStoreService:GetOrderedDataStore("CashLeaderboard")
for _,player in pairs(game.Players:GetPlayers()) do
LevelsLeaderboard:SetAsync(player.UserId, player.leaderstats.Level.Value)
CashLeaderboard:SetAsync(player.UserId, player.leaderstats.EBits.Value)
end
local function updateLeaderboard()
local succes, errormessage = pcall(function()
local LevelData = LevelsLeaderboard:GetSortedAsync(false, 5)
local CashData = CashLeaderboard:GetSortedAsync(false, 5)
local LevelsPage = LevelData:GetCurrentPage()
local CashPage = CashData:GetCurrentPage()
for index, data in ipairs(LevelsPage, CashPage) do
local Username = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
local Name = Username
local Level = data.value
local Cash = data.value
local isOnLeaderboard = false
for i,v in pairs(game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()) do
if v.Player.Text == Name then
isOnLeaderboard = true
break
end
end
if Level and Cash and isOnLeaderboard == false then
local newLeaderboardFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
newLeaderboardFrame.Player.Text = Name
newLeaderboardFrame.Rank.Text = Level
newLeaderboardFrame.EBITS.Text = Cash
newLeaderboardFrame.Position = UDim2.new(0,0, newLeaderboardFrame.Position.Y.Scale + (.08*#game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()),0)
newLeaderboardFrame.Parent = game.Workspace.GlobalLeaderboard.SurfaceGui.Holder
end
end
end)
if succes then
else
end
end --End of updateLeaderboard function
while true do --Loop which updates the leaderboard every 10 seconds
for _, frame in pairs(game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()) do
frame:Destroy()
end
updateLeaderboard()
wait(10)
end
Try changing it to update every ~45 seconds as updating it every 10 seconds can put stress on data stores, and can cause data store services to fill up which can prevent the leaderboard from updating more.
A good method that you can use instead of using your current system for ranking the player is to do this:
for rank, data in ipairs(LevelsPage, CashPage) do
local Username = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
local Name = Username
local Level = data.value
local Cash = data.value
local isOnLeaderboard = false
for i,v in pairs(game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()) do
if v.Player.Text == Name then
isOnLeaderboard = true
break
end
end
if Level and Cash and isOnLeaderboard == false then
local newLeaderboardFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
newLeaderboardFrame.Player.Text = Name
newLeaderboardFrame.Rank.Text = rank
newLeaderboardFrame.EBITS.Text = Cash
newLeaderboardFrame.Position = UDim2.new(0,0, newLeaderboardFrame.Position.Y.Scale + (.08*#game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()),0)
newLeaderboardFrame.Parent = game.Workspace.GlobalLeaderboard.SurfaceGui.Holder
end
end
end)
This new code sets the rank of the player using the for loops index.
local DataStoreService = game:GetService('DataStoreService')
local LevelsLeaderboard = DataStoreService:GetOrderedDataStore("LevelsLeaderboard");
local CashLeaderboard = DataStoreService:GetOrderedDataStore("CashLeaderboard")
for _,player in pairs(game.Players:GetPlayers()) do
LevelsLeaderboard:SetAsync(player.UserId, player.leaderstats.Level.Value)
CashLeaderboard:SetAsync(player.UserId, player.leaderstats.EBits.Value)
end
local function updateLeaderboard()
local succes, errormessage = pcall(function()
local LevelData = LevelsLeaderboard:GetSortedAsync(false, 5)
local CashData = CashLeaderboard:GetSortedAsync(false, 5)
local LevelsPage = LevelData:GetCurrentPage()
local CashPage = CashData:GetCurrentPage()
for rank, data in ipairs(CashPage) do
local Username = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
local Name = Username
local Cash = data.value
local isOnLeaderboard = false
for i,v in pairs(game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()) do
if v.Player.Text == Name then
isOnLeaderboard = true
break
end
end
if Cash and isOnLeaderboard == false then
local newLeaderboardFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
newLeaderboardFrame.Player.Text = Name
newLeaderboardFrame.Rank.Text = rank
newLeaderboardFrame.EBITS.Text = Cash
newLeaderboardFrame.Position = UDim2.new(0,0, newLeaderboardFrame.Position.Y.Scale + (.08*#game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()),0)
newLeaderboardFrame.Parent = game.Workspace.GlobalLeaderboard.SurfaceGui.Holder
end
end
end)
end --End of updateLeaderboard function
while true do --Loop which updates the leaderboard every 10 seconds
for _, frame in pairs(game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()) do
frame:Destroy()
end
updateLeaderboard()
wait(10)
end
I may have found the problem, as according the my understanding the players EBITS and Levels will only be updated once and will not be updated after the for loop has ran as the loop that gets the players new cash value is only running on, meaning that refreshing the leaderboard is basically doing nothing except reloading the exact same data. To fix this you must try placing the for loop that gets the players EBITS and Level value inside of the refresh function.
This is the updated code:
local DataStoreService = game:GetService('DataStoreService')
local LevelsLeaderboard = DataStoreService:GetOrderedDataStore("LevelsLeaderboard");
local CashLeaderboard = DataStoreService:GetOrderedDataStore("CashLeaderboard")
local function updateLeaderboard()
for _,player in pairs(game.Players:GetPlayers()) do
LevelsLeaderboard:SetAsync(player.UserId, player.leaderstats.Level.Value)
CashLeaderboard:SetAsync(player.UserId, player.leaderstats.EBits.Value)
end
local succes, errormessage = pcall(function()
local LevelData = LevelsLeaderboard:GetSortedAsync(false, 5)
local CashData = CashLeaderboard:GetSortedAsync(false, 5)
local LevelsPage = LevelData:GetCurrentPage()
local CashPage = CashData:GetCurrentPage()
for rank, data in ipairs(CashPage) do
local Username = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
local Name = Username
local Cash = data.value
local isOnLeaderboard = false
for i,v in pairs(game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()) do
if v.Player.Text == Name then
isOnLeaderboard = true
break
end
end
if Cash and isOnLeaderboard == false then
local newLeaderboardFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
newLeaderboardFrame.Player.Text = Name
newLeaderboardFrame.Rank.Text = rank
newLeaderboardFrame.EBITS.Text = Cash
newLeaderboardFrame.Position = UDim2.new(0,0, newLeaderboardFrame.Position.Y.Scale + (.08*#game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()),0)
newLeaderboardFrame.Parent = game.Workspace.GlobalLeaderboard.SurfaceGui.Holder
end
end
end)
end --End of updateLeaderboard function
while true do --Loop which updates the leaderboard every 10 seconds
for _, frame in pairs(game.Workspace.GlobalLeaderboard.SurfaceGui.Holder:GetChildren()) do
frame:Destroy()
end
updateLeaderboard()
wait(45)
end