How to make a server leaderboard?

hi, i’m trying to make my global leaderboard become a server leaderboard, just i don’t really know how to do it. any suggestions? this is the script of the global leaderboard. i i’m not the creator of the script, i just slightly edited it. thanks in advice

-- [ SETTINGS ] --

local statsName = "Kills" -- Your stats name
local maxItems = 100 -- Max number of items to be displayed on the leaderboard
local minValueDisplay = 1 -- Any numbers lower than this will be excluded
local maxValueDisplay = 10e15 -- (10 ^ 15) Any numbers higher than this will be excluded
local abbreviateValue = true -- The displayed number gets abbreviated to make it "human readable"
local updateEvery = 30 -- (in seconds) How often the leaderboard has to update

-- [ END SETTINGS ] --




-- Don't edit if you don't know what you're doing --

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local DataStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard_" .. statsName)
local Frame = script.Parent.Frame
local Contents = Frame.Contents
local Template = script.objTemplate

local COLORS = {
	Default = Color3.fromRGB(255,255,255),
	Gold = Color3.fromRGB(255, 215, 0),
	Silver = Color3.fromRGB(192, 192, 192),
	Bronze = Color3.fromRGB(205, 127, 50)
}
local ABBREVIATIONS = { "K", "M", "B", "T" }


local function toHumanReadableNumber(num)
	if num < 1000 then
		return tostring(num)
	end
	
	local digits = math.floor(math.log10(num)) + 1
	local index = math.min(#ABBREVIATIONS, math.floor((digits - 1) / 3))
	local front = num / math.pow(10, index * 3)
	
	return string.format("%i%s+", front, ABBREVIATIONS[index])
end

local function getItems()
	local data = DataStore:GetSortedAsync(false, maxItems, minValueDisplay, maxValueDisplay)
	local topPage = data:GetCurrentPage()

	Contents.Items.Nothing.Visible = #topPage == 0 and true or false

	for position, v in ipairs(topPage) do
		local userId = v.key
		local value = v.value
		local username = "[Not Available]"
		local color = COLORS.Default

		local success, err = pcall(function()
			username = Players:GetNameFromUserIdAsync(userId)
		end)

		if position == 1 then
			color = COLORS.Gold
		elseif position == 2 then
			color = COLORS.Silver
		elseif position == 3 then
			color = COLORS.Bronze
		end

		local item = Template:Clone()
		item.Name = username
		item.LayoutOrder = position
		item.Values.Number.TextColor3 = color
		item.Values.Number.Text = position
		item.Values.Username.Text = username
		item.Values.Value.Text = abbreviateValue and toHumanReadableNumber(value) or value
		item.Parent = Contents.Items
	end
end

while true do
	for _, player in pairs(Players:GetPlayers()) do
		local leaderstats = player:FindFirstChild("leaderstats")

		if not leaderstats then
			warn("Couldn't find leaderstats!")
			break
		end

		local statsValue = leaderstats:FindFirstChild(statsName)

		if not statsValue then
			warn("Couldn't find " .. statsName .. " in leaderstats!")
			break
		end

		pcall(function()
			DataStore:UpdateAsync(player.UserId, function()
				return tonumber(statsValue.Value)
			end)
		end)
	end

	for _, item in pairs(Contents.Items:GetChildren()) do
		if item:IsA("Frame") then
			item:Destroy()
		end
	end

	getItems()

	wait()
	Contents.GuideTopBar.Value.Text = statsName
	wait(updateEvery)
end

please be kind and clear i’m not that confident at scripting yet

1 Like

Put a “leaderboard” folder in the player object when they join and put value instances in it.

If it didn’t work try “leaderboards”

Edit: wait do you mean to make it not save? Just disable the datastore stuff

1 Like

i’ve already put the leaderboard stuff with the values, but you got it right when you said to remove the data store, i just don’t know how to do it, because i’m afraid to remove the wrong parts, may you help me with that?

1 Like

Most of this code is revolved around the datastore. Removing the datastore would mean basically rewriting this piece of code.

What exactly are you wanting on this leaderboard?

that is right, yesterday i tried removing the datastore, but as you said the code is all about it, and if i remove something of the datastore, it automatically removes some important variables, so what i can’t figure out is how to remove the datastore without affecting too much the code and make it work the same way, thanks in advance

just make it so when the player joins it doesn’t load their data from the datastore
edit: try this???

-- [ SETTINGS ] --

local statsName = "Kills" -- Your stats name
local maxItems = 100 -- Max number of items to be displayed on the leaderboard
local minValueDisplay = 1 -- Any numbers lower than this will be excluded
local maxValueDisplay = 10e15 -- (10 ^ 15) Any numbers higher than this will be excluded
local abbreviateValue = true -- The displayed number gets abbreviated to make it "human readable"
local updateEvery = 30 -- (in seconds) How often the leaderboard has to update

-- [ END SETTINGS ] --




-- Don't edit if you don't know what you're doing --

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local DataStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard_" .. statsName)
local Frame = script.Parent.Frame
local Contents = Frame.Contents
local Template = script.objTemplate

local COLORS = {
	Default = Color3.fromRGB(255,255,255),
	Gold = Color3.fromRGB(255, 215, 0),
	Silver = Color3.fromRGB(192, 192, 192),
	Bronze = Color3.fromRGB(205, 127, 50)
}
local ABBREVIATIONS = { "K", "M", "B", "T" }


local function toHumanReadableNumber(num)
	if num < 1000 then
		return tostring(num)
	end
	
	local digits = math.floor(math.log10(num)) + 1
	local index = math.min(#ABBREVIATIONS, math.floor((digits - 1) / 3))
	local front = num / math.pow(10, index * 3)
	
	return string.format("%i%s+", front, ABBREVIATIONS[index])
end

local function getItems()
	local data = DataStore:GetSortedAsync(false, maxItems, minValueDisplay, maxValueDisplay)
	local topPage = data:GetCurrentPage()

	Contents.Items.Nothing.Visible = #topPage == 0 and true or false

	for position, v in ipairs(topPage) do
		local userId = v.key
		local value = v.value
		local username = "[Not Available]"
		local color = COLORS.Default

		local success, err = pcall(function()
			username = Players:GetNameFromUserIdAsync(userId)
		end)

		if position == 1 then
			color = COLORS.Gold
		elseif position == 2 then
			color = COLORS.Silver
		elseif position == 3 then
			color = COLORS.Bronze
		end

		local item = Template:Clone()
		item.Name = username
		item.LayoutOrder = position
		item.Values.Number.TextColor3 = color
		item.Values.Number.Text = position
		item.Values.Username.Text = username
		item.Values.Value.Text = abbreviateValue and toHumanReadableNumber(value) or value
		item.Parent = Contents.Items
	end
end

while true do
	for _, player in pairs(Players:GetPlayers()) do
		local leaderstats = player:FindFirstChild("leaderstats")

		if not leaderstats then
			warn("Couldn't find leaderstats!")
			break
		end

		local statsValue = leaderstats:FindFirstChild(statsName)

		if not statsValue then
			warn("Couldn't find " .. statsName .. " in leaderstats!")
			break
		end

		pcall(function()
			DataStore:UpdateAsync(1, function()
				return tonumber(statsValue.Value)
			end)
		end)
	end

	for _, item in pairs(Contents.Items:GetChildren()) do
		if item:IsA("Frame") then
			item:Destroy()
		end
	end

	getItems()

	wait()
	Contents.GuideTopBar.Value.Text = statsName
	wait(updateEvery)
end

it sadly doesn’t work :frowning: have you tested it?

idk man, I’m just throwing ideas out

All you should need to do is create a separate table inside your module script that holds the datastore data for the current players in the server.

When a player enters the server take their stats from the data store and copy them to the temporary server table. Same as you would the datastore table. If the player leaves then remove them from the server table. Use this table as the leader board for the server but continue to update the datastore normally.

When stats change update the datastore normally as well as the local table.