I’m trying to make a global leaderboard for the first time for total streaks and total kills of an user. The leaderboard shows only total kills for 0.1 seconds every couple of seconds(don’t know exact amount, could be 15) and doesn’t show streaks, also, it positions frame in the middle instead of having streak on the left and kills on the right.
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local total_kills_store = DataStoreService:GetOrderedDataStore("Total kills")
local streak_data = DataStoreService:GetOrderedDataStore("Streak")
-- Memoization: since these results are rarely (if ever) going to change
-- all we have to do is check a cache table for the UserId.
-- If we find the UserId, then we have no work to do! Just return the name (fast).
-- If we don't find the UserId (cache miss), go look it up (takes time).
local cache = {}
--https://developer.roblox.com/en-us/api-reference/function/Players/GetNameFromUserIdAsync
function getUsernameFromUserId(userId)
-- First, check if the cache contains the name
if cache[userId] then return cache[userId] end
-- Second, check if the user is already connected to the server
local player = Players:GetPlayerByUserId(userId)
if player then
cache[userId] = player.Name
return player.Name
end
-- If all else fails, send a request
local name
pcall(function ()
name = Players:GetNameFromUserIdAsync(userId)
end)
cache[userId] = name
return name
end
local model = script.Parent
local mainFrame = model.Leaderboard.SurfaceGui.MainFrame
local listFrame = mainFrame.ScrollingFrame
local userTemplate = mainFrame.UserTemplate
local function updateLeaderboard1()
local top20
local success, errorMessage = pcall(function()
local pages = total_kills_store:GetSortedAsync(false, 20, 1)
top20 = pages:GetCurrentPage()
end)
if success then
for _, item in pairs(listFrame:GetChildren()) do
if item:IsA("Frame") then
item:Destroy()
end
end
for index, entry in ipairs(top20) do
local userCopy = userTemplate:Clone()
userCopy.Visible = true
userCopy.Parent = listFrame
local idFromKey = tonumber(string.sub(entry.key, 8))
local nameFromId = getUsernameFromUserId(idFromKey)
if not nameFromId then
nameFromId = "failed to load name"
end
userCopy:WaitForChild("Username").Text = index..". "..nameFromId
userCopy.Name = nameFromId
userCopy:WaitForChild("Amount").Text = entry.value
model:SetAttribute("LowestAmountOnBoard", entry.value)
end
else
print("Leaderboard update failed: "..errorMessage)
end
end
local function updateLeaderboard2()
local top20
local success, errorMessage = pcall(function()
local pages = streak_data:GetSortedAsync(false, 20, 1)
top20 = pages:GetCurrentPage()
end)
if success then
for _, item in pairs(listFrame:GetChildren()) do
if item:IsA("Frame") then
item:Destroy()
end
end
for index, entry in ipairs(top20) do
local userCopy = userTemplate:Clone()
userCopy.Visible = true
userCopy.Parent = listFrame
local idFromKey = tonumber(string.sub(entry.key, 8))
local nameFromId = getUsernameFromUserId(idFromKey)
if not nameFromId then
nameFromId = "failed to load name"
end
userCopy.Position = Vector2.new(0.5,0)
userCopy:WaitForChild("Username").Text = index..". "..nameFromId
userCopy.Name = nameFromId
userCopy:WaitForChild("Amount").Text = entry.value
model:SetAttribute("LowestAmountOnBoard", entry.value)
end
else
print("Leaderboard update failed: "..errorMessage)
end
end
-- Updates when the game first loads and then every 120 seconds
while true do
updateLeaderboard1()
updateLeaderboard2()
wait(15)
end