I have a global leaderboard that worked for a few days until suddenly it stopped and I started getting this error:
ive searched a lot over the internet, but this seems to be an uncommon error.
this is the script:
[quote=“DevOrange, post:1, topic:2977515, full:true, username:Waffle_Gamer6”]
I have a global leaderboard that worked for a few days until suddenly it stopepd and I started getting this error:
ive searched a lot over the internte, but this seems to be an uncommon error.
this is the script:
--// 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
local plr_key = "id_"..player.UserId.."_Wins"
local wins = player.leaderstats.Wins
local success, result = pcall(function()
DataStore:SetAsync(plr_key, wins.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 name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
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)
Print the value of dataName:split('_')[2] to make sure it’s a valid number above 0:
for rank, data in ipairs(top50) do
local dataName = data.key
print(dataName:split('_')[2]) -- see what this says
local name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
local wins = data.value
local currentPlayer = { Player = name, Wins = wins, Rank = rank, }
table.insert(top, rank, currentPlayer)
end
-2 is an invalid userid, i assume that’s saved data from a studio playtest you may’ve done. Just add this check to your code to make sure data is only loaded for valid roblox users:
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
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
that makes a lot of sense, thank you! I did this code and it works but instead of just skipping the “false” player it just stops at where they would be with no errors
That’s likely because the invalid user is still part of the top 50 (data wise), so the code doesn’t display them on the leaderboard, but they’re still returned here:
local top50 = pages:GetCurrentPage()
This may be a little complicated, but for this specifically, you’d have to fetch more players (you can likely just get the next page) and add those next users to the list.
(Here’s a poorly made diagram I made in ms paint):
Don’t add all the next users, just enough for the list to reach 50. You can also use DataStoreService:RemoveAsync to remove the invalid users from the DataStore when you find them:
for rank, data in ipairs(top50) do
local dataName = data.key
local userId = tonumber(dataName:split('_')[2])
if userId < 1 then
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
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
You can add this check to your SaveData function to prevent it from saving studio sessions in the future:
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"
I dont mean to be annoying here, but my leaderboard broke again in a different way. I made another post for it (although now I realize I shouldve just put it here). here is the link, if you’re able to help thank you! Problem with global leaderboard