I made a post (I think yesterday) about my global leaderboard not working, and it got solved but just today it broke again in a different way. The leaderboard has no errors, but for some people it shows double rows
I seriously dont understand what is wrong, especially since there are no errors. Here is the code:
--// GENERAL VARIABLES
local DSS = game:GetService("DataStoreService")
local DataStore = DSS:GetOrderedDataStore("Wins")
--// UI VARIABLES
local UI = script.Parent.SurfaceGui
local basePlayerFrame = UI.BasePlayerFrame
local boardFrame = UI.ScrollingFrame
--// Functions
local function SaveData()
for _, player in pairs(game:GetService("Players"):GetPlayers()) do
if player.UserId < 1 then
continue -- don't save this info
end
local plr_key = "id_"..player.UserId.."_Wins"
local tokens = player.leaderstats:FindFirstChild("Wins")
local success, result = pcall(function()
DataStore:SetAsync(plr_key, tokens.Value)
end)
if not success then
warn(result)
end
end
end
local function getTop50Players()
local isAscending = false
local pageSize = 50
local pages = DataStore:GetSortedAsync(isAscending, pageSize)
local top50 = pages:GetCurrentPage()
local top = {}
for rank, data in ipairs(top50) do
local dataName = data.key
local userId = tonumber(dataName:split('_')[2]) -- it's easier to just have it as its own variable
if userId < 1 then -- check for valid id
pcall(function() -- of course in your actual code base, this would be more detailed
DataStore:RemoveAsync(dataName) -- remove the invalid user from the data store list
end)
continue -- skip this person, it's not an actual roblox user
end
local name = game:GetService("Players"):GetNameFromUserIdAsync(userId)
local wins = data.value
local currentPlayer = { Player = name, Wins = wins, Rank = rank, }
table.insert(top, rank, currentPlayer)
end
return top
end
local function ClearList()
task.spawn(function()
for _, plrFrame in pairs(boardFrame:GetChildren()) do
if not plrFrame:IsA("Frame") then continue end
plrFrame:Destroy()
task.wait(0.25)
end
end)
end
local function UpdateList()
SaveData()
ClearList()
local top50 = getTop50Players()
task.spawn(function()
for _, plr in ipairs(top50) do
local frame = basePlayerFrame:Clone()
frame.Parent = boardFrame
frame.Plr.Text = plr.Player
frame.Amount.Text = plr.Wins
frame.Rank.Text = plr.Rank
frame.Visible = true
task.wait(0.25)
end
end)
end
task.spawn(function()
while true do
UpdateList()
wait(60)
end
end)
Its just a random thought, don’t know if it would work or wether its even possible. In stead of resetting all data you could just loop over all the players data, place them in a table or something check if they are already in the table. Then afterwards save that as the new datastore.
local DSS = game:GetService("DataStoreService")
local DataStore = DSS:GetOrderedDataStore("Wins")
--// UI VARIABLES
local UI = script.Parent.SurfaceGui
local basePlayerFrame = UI.BasePlayerFrame
local boardFrame = UI.ScrollingFrame
--// Functions
local function SaveData()
for _, player in pairs(game:GetService("Players"):GetPlayers()) do
if player.UserId < 1 then
continue -- don't save this info
end
local plr_key = "id_"..player.UserId.."_Wins"
local tokens = player.leaderstats:FindFirstChild("Wins")
local success, result = pcall(function()
DataStore:SetAsync(plr_key, tokens.Value)
end)
if not success then
warn(result)
end
end
end
local function getTop50Players()
local isAscending = false
local pageSize = 50
local pages = DataStore:GetSortedAsync(isAscending, pageSize)
local top50 = pages:GetCurrentPage()
local top = {}
for rank, data in ipairs(top50) do
local dataName = data.key
local userId = tonumber(dataName:split('_')[2]) -- it's easier to just have it as its own variable
if userId < 1 then -- check for valid id
pcall(function() -- of course in your actual code base, this would be more detailed
DataStore:RemoveAsync(dataName) -- remove the invalid user from the data store list
end)
continue -- skip this person, it's not an actual roblox user
end
local name = game:GetService("Players"):GetNameFromUserIdAsync(userId)
local wins = data.value
local currentPlayer = { Player = name, Wins = wins, Rank = rank, }
table.insert(top, rank, currentPlayer)
end
return top
end
local function ClearList()
for _, plrFrame in pairs(boardFrame:GetChildren()) do
if plrFrame:IsA("Frame") then
plrFrame:Destroy()
end
end
end
local function UpdateList()
SaveData()
ClearList()
local top50 = getTop50Players()
for _, plr in ipairs(top50) do
local frame = basePlayerFrame:Clone()
frame.Parent = boardFrame
frame.Plr.Text = plr.Player
frame.Amount.Text = plr.Wins
frame.Rank.Text = plr.Rank
frame.Visible = true
end
end
task.spawn(function()
while true do
UpdateList()
wait(60)
end
end)
I don’t see anything immediately noticable about why it would be duplicating, is it just a visual error? (As in: the player doesn’t have duplicate data, it’s just displaying weirdly on the board)
alr it’s the next day and Ive remade the leaderboard completely because the old one had too many problems, and it works now. thanks for everyone’s help