I was watching a tutorial on how to create a global leaderboard script which displays players with the most gems from leaderstats in order, however it doesn’t seem to work. I have a LocalScript inside of the scrolling frame, a leaderstats script for the gems and another Leaderboard script in ServerScriptService.
Leaderboard script:
local newEvent = Instance.new("RemoteEvent")
newEvent.Name = "Leaderboard"
newEvent.Parent = game:GetService("ReplicatedStorage")
local data = game:GetService("DataStoreService"):GetOrderedDataStore("Leaderboard")
local storedDataName = "Gems"
wait(5)
while true do
for i, player in pairs(game.Players:GetPlayers()) do
local leaderstats = player:FindFirstChild("Leaderboard")
if leaderstats then
local gems = leaderstats:FindFirstChild(storedDataName)
if gems then
pcall(function()
data:UpdateAsync(player.UserId, function(oldVal)
return gems.Value
end)
end)
end
end
end
-- Fetch and update leaderboard data
local pages = data:GetSortedAsync(false, 25)
local top = pages:GetCurrentPage()
local datab = {}
local on = 1
for i, data in ipairs(top) do
local userid = data.key
local gems = data.Value
local name = "Loading..."
local s, e = pcall(function()
name = game.Players:GetNameFromUserIdAsync(userid)
end)
if not s then
warn("Error getting name for " .. userid .. ". Error:" .. e)
end
local image = "https://roblox.com/headshot-thumbnail/image?userId=" .. userid .. "&width=150&height=150&format=png"
datab[on] = {
["Name"] = name,
["Image"] = image,
["Gems"] = gems
}
on = on + 1
end
newEvent:FireAllClients(datab)
wait(5) -- Reduce wait time
end
GemHandler (leaderstats) script:
local DataStoreService = game:GetService("DataStoreService")
local GemStore = DataStoreService:GetDataStore("GemStore")
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(Player)
local userID = Player.UserId
local Currency = GemStore:GetAsync(userID)
-- Create leaderstats folder if it doesn't exist
local leaderstats = Player:FindFirstChild("leaderstats")
if not leaderstats then
leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = Player
end
-- Check if Currency exists, set default value if not
if not Currency then
Currency = 0
end
-- Set Gems value in leaderstats
local gems = leaderstats:FindFirstChild("Gems")
if not gems then
gems = Instance.new("IntValue")
gems.Name = "Gems"
gems.Value = Currency
gems.Parent = leaderstats
else
gems.Value = Currency
end
-- Connect a function to update the datastore when Gems value changes
gems.Changed:Connect(function(NewValue)
GemStore:SetAsync(userID, NewValue)
end)
end)
LocalScript in frame:
local event = game:GetService("ReplicatedStorage"):WaitForChild("Leaderboard")
local sample = script:WaitForChild("Sample")
local frame = script.Parent
local ui = frame:WaitForChild("UI")
local function createFrame(number,name,image,val)
local color = Color3.new(1,1,1)
if number == 1 then
color = Color3.new(1,1,0)
elseif number == 2 then
color = Color3.new(0.9,0.9,0.9)
elseif number == 3 then
color = Color3.fromRGB(166,122,0)
end
local new = sample:Clone()
new.Image.Image = image
new.Image.Num.Text = number
new.Name.Text = name
new.Gems.Text = val
new.LayoutOrder = number
new.Image.Num.TextColor3 = color
new.Gems.TextColor3 = color
new.Name.TextColor3 = color
new.Parent = frame
end
event.OnClientEvent:Connect(function(data)
for i,v in pairs(frame:GetChildren()) do
if v.Name == "Sample" then
v:Destroy()
end
end
for i,v in pairs(data) do
local name = data[i]["Name"]
local image = data[i]["Image"]
local val = data[i]["Gems"]
createFrame(i,name,image,val)
end
wait(0.1)
frame.CanvasSize = UDim2.new(0,0,0,ui.AbsoluteContentSize.Y)
end)