Hello everyone! This is going to be my first ever post so apologies for any mistakes I’ll be making here
I have 2 problems to fix a leaderboard that would somehow make players with the worst time of speedrun(the highest in time) to be placed onto the top of the list(still shows the same speedrun time tho).
So for context me and my friend @hahaharee0814 have already finished making a tower obby game and we want to show the leaderboard of best speedruns(top 50) inside each respective towers. After publishing it the leaderboard seems to work fine(when there were fewer entries inside the leaderboard), but after around 20 entries from 20 different players or so the leaderboard started to error similar to the screenshots(but these screenshots I’ll be sending were taken more recent and after a few medium updates)
Here are the relevant scripts
Server
local function fetchGlobalLeaderboardData()
local leaderboardData = {}
local function getDataStorePage()
return orderedDataStore:GetSortedAsync(true, 50):GetCurrentPage() -- Sorting in ascending order (smallest time on top)
end
local success, data = retryWithExponentialBackoff(getDataStorePage, 5, false)
if success then
for _, entry in ipairs(data) do
local userId = tonumber(entry.key)
local username = "Unknown"
if userId then
local success, result = pcall(Players.GetNameFromUserIdAsync, Players, userId)
if success then
username = result
else
warn("Failed to get username for UserId:", userId, ":", result)
end
end
local timeInSeconds = entry.value / 1000
if timeInSeconds > MINIMUM_TIME_THRESHOLD then
table.insert(leaderboardData, {
userId = userId,
username = username,
time = timeInSeconds
})
end
end
else
warn("Failed to fetch global leaderboard data for Yangnyeom:", data)
end
-- Sort data by their time (ascending)
table.sort(leaderboardData, function(a, b)
return a.time < b.time
end)
return leaderboardData
end
-- skip the other unrelevant parts(the grant speedrun badge function)
local function updateLeaderboard()
local success, leaderboardData = pcall(fetchGlobalLeaderboardData)
print("Fetched leaderboard data:", leaderboardData)
if not success then
warn("Failed to update leaderboard:", leaderboardData)
return
end
UpdateLeaderboardEventYangnyeom:FireAllClients(leaderboardData)
for i, data in ipairs(leaderboardData) do
if data.time > MINIMUM_TIME_THRESHOLD then
local userId = data.userId
local username = data.username
local stand
if i == 1 then
stand = FirstPlaceStand
elseif i == 2 then
stand = SecondPlaceStand
elseif i == 3 then
stand = ThirdPlaceStand
end
if stand then
applyAppearanceToDummy(stand, userId, username, i)
local animationId = LeaderboardYangnyeom:WaitForChild("AnimationToPlay").AnimationId
AnimationPlayer.playAnimation(stand, animationId)
-- Check and grant badge if applicable
if userId then
local player = Players:GetPlayerByUserId(userId)
if player then
grantSpeedrunBadge(player, data.time)
end
else
warn("Invalid UserId:", userId)
end
end
end
end
end
while true do
updateLeaderboard()
wait(LEADERBOARD_UPDATE_INTERVAL)
end
Client
local function updateLeaderboardGui(leaderboardData)
print("Received leaderboard data:", leaderboardData)
-- Sort leaderboard data by time (ascending)
table.sort(leaderboardData, function(a, b)
return a.time < b.time
end)
-- Delete the existing entries and then create the new entries afterwards, the problem could be lying here somewhere I believe
for _, data in ipairs(leaderboardData) do
if data.time > MINIMUM_TIME_THRESHOLD then
-- Delete existing entry if it exists
local existingEntry = ListContent.Items:FindFirstChild(data.username)
if existingEntry then
existingEntry:Destroy()
end
-- Create a new entry
local entry = Sample:Clone()
entry.Name = data.username
entry.Values.Username.Text = data.username
entry.Values.Yangnyeom.Text = string.format("%.2f", data.time) -- Format time to 2 decimal
entry.Parent = ListContent.Items
entry.Visible = true
end
end
-- Adjust the position of each entry
local entries = ListContent.Items:GetChildren()
local entryCount = 0 -- This is to track the valid entries to skip the original Sample
for i, entry in ipairs(entries) do
if entry ~= Sample then -- We skip the original Sample entry
if entry:IsA("GuiObject") then
entryCount = entryCount + 1
entry.LayoutOrder = entryCount
if entry:FindFirstChild("Values") and entry.Values:FindFirstChild("Index") then
entry.Values.Index.Text = tostring(entryCount) -- Set the index number
-- Apply special colors based on index basically
if entryCount == 1 then
entry.Values.Index.TextColor3 = Color3.fromRGB(255, 215, 0) -- Gold color
elseif entryCount == 2 then
entry.Values.Index.TextColor3 = Color3.fromRGB(192, 192, 192) -- Silver color
elseif entryCount == 3 then
entry.Values.Index.TextColor3 = Color3.fromRGB(205, 127, 50) -- Bronze color
else
entry.Values.Index.TextColor3 = Color3.fromRGB(0, 0, 0) -- Default color
end
end
end
end
end
end
UpdateLeaderboardEvent.OnClientEvent:Connect(function(leaderboardData)
updateLeaderboardGui(leaderboardData)
end)
1st Update
2nd Update(notice how there is no data with the time 1503? It’s the worst one but hmmm doesn’t update it to the top like the rest)
A few updates later(still no 1503 I see)
I can’t seem to wrap my head around this lol, tried changing the logic a bit on the entry but still wouldn’t work. Maybe I need to put more conditional statements haha. The fetching leaderboard data print actually shows the correct order even after the updated leaderboard(server) and so is the receiving leaderboard data(client) prints. But the weird part is that it doesn’t actually update the worst time(like the most bottom one) to the top, only the 2nd worst and then so on. What a weird error huh?
Also for anyone wondering what datastore I’m using, it’s Suphi’s Datastore thanks @5uphi !!
And the 2nd problem is the lag, now I don’t know what might be causing already reduced lag from many scripts but still the same. It could be because of too many RunService connections that never gets stopped(I use RS on many scripts so could be that but I made sure to try and disconnect those when not needed, but sometimes it would just break the script).
But here’s the odd thing, me and my friend(the other dev) doesn’t actually lag while playing the game, even on different devices yet other people says the game is sooo laggy that even one of my other friend said that it’s “laggier than playing on other bigger games”. Here’s a screenshot taken from his PC. Oh yeah his CPU on average is at 78 in this game for some reasonsss
And other players that we invited& some random people also said the same things
(pretty sure they said lag)
Now here’s screenshots of current scripts from me and the other dev @hahaharee0814
And here’s the script profiler from me
(Sorry for posting too many images, I’m kind of baffled at this point and don’t know what might be the root cause. Could it be from all the RS connections perhaps? And what do you think is more likely to lag the game more? CPU or Ping?)
And for anyone wondering why it might be you could try the game for yourself, it’s called Korean Chicken Tower and make sure to give some suggestions aswell for the game lol(if you want)
TLDR; 1st problem: The leaderboard in my game somehow would show players with the worst ranking to be at the top of the ranking for some reason yet still stores the same data for each username. And it keeps putting the player from the worst rankings to the top(as if it’s trying to recreate the data over again but one by one.). Weird thing is that the worst of the worst(sorry hehe) data doesn’t get updated to the top though. 2nd problem: My game is laggy and I don’t know why, already made fixes for the lag but still ultimately the same.
Anyways thanks for reading till the end lol