Making a donator leaderboard

hi people, so i need help with optimizing my script…

local function processDonationData()
	local dataService = game:GetService("DataStoreService")
	local options = Instance.new("DataStoreOptions")
	options.AllScopes = true
	local DataStore = dataService:GetDataStore("Donations", "", options)

	local highestDonation = 0
	local topDonator = ""

	local listSuccess, pages = pcall(function()
		return DataStore:ListKeysAsync()
	end)

	if listSuccess then
		while true do
			local items = pages:GetCurrentPage()
			for _, v in ipairs(items) do
				local value = DataStore:GetAsync(v.KeyName)
				if value and type(value) == "table" and value.Donated then
					local fixedUserId = string.split(v.KeyName, "global/")
					local userId = fixedUserId[2]
					local donationAmount = value.Donated
					
					if donationAmount == 0 then
						return
					else
						print(game.Players:GetNameFromUserIdAsync(userId) .. donationAmount)
						if donationAmount > highestDonation then
							highestDonation = donationAmount
							topDonator = userId
							print(highestDonation .. " " .. topDonator)
						end
						task.wait(0.5)
					end
				end
			end
			if pages.IsFinished then
				break
			end
			pages:AdvanceToNextPageAsync()
		end

		if highestDonation > 0 then
			local success, userName = pcall(function()
				return game.Players:GetNameFromUserIdAsync(topDonator)
			end)

			if success then
				local userThumbnail = game.Players:GetUserThumbnailAsync(topDonator, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)

				game.Workspace.donateThing.SurfaceGui.Username.Text = userName
				game.Workspace.donateThing.SurfaceGui.Username.outlineUser.Text = userName
				game.Workspace.donateThing.SurfaceGui.Profile.Image = userThumbnail
				game.Workspace.donateThing.SurfaceGui.HowMuchDonated.Text = highestDonation .. " ROBUX"
				game.Workspace.donateThing.SurfaceGui.HowMuchDonated.outlineDonator.Text = highestDonation .. " ROBUX"
				game.Workspace.donateThing.CFrame = game.Workspace.donateThing.CFrame + Vector3.new(0,20,0)
			else
				print("Failed to get the top donator's username.")
			end
		else
			print("No donations found.")
		end
	else
		print("Failed to retrieve donation data.")
	end
end

local function hideDonateThing()
	game.Workspace.donateThing.CFrame = game.Workspace.donateThing.CFrame + Vector3.new(0, -20, 0)
	game.Workspace.donateThing.donating.CFrame = game.Workspace.donateThing.donating.CFrame + Vector3.new(0, -20, 0)
end

while true do
	--if game:GetService("RunService"):IsStudio() then
	--	hideDonateThing()
	--	return
	--end

	if game.PrivateServerOwnerId ~= 0 then
		hideDonateThing()
		return
	end

	processDonationData()
	task.wait(3600 * 2)
	print("refresh")
end

I literally have no idea what i can do because this loads atleast 1 PERSON per like 40 minutes…
I tried using :GetOrderedDataStore() but it doesnt work/show outdated data.

please… is there any fix…?

1 Like
local function processDonationData()
	local dataService = game:GetService("DataStoreService")
	local donationsStore = dataService:GetOrderedDataStore("Donations")

	local success, result = pcall(function()
		return donationsStore:GetSortedAsync(false, 1)
	end)

	if success and result then
		local pages = result
		if pages:IsFinished() then
			print("No donations found.")
			return
		end

		local topDonationData = pages:GetCurrentPage()[1]
		if topDonationData then
			local topDonator = topDonationData.key
			local highestDonation = topDonationData.value

			local userName = game.Players:GetNameFromUserIdAsync(topDonator)
			local userThumbnail = game.Players:GetUserThumbnailAsync(topDonator, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)

			game.Workspace.donateThing.SurfaceGui.Username.Text = userName
			game.Workspace.donateThing.SurfaceGui.Profile.Image = userThumbnail
			game.Workspace.donateThing.SurfaceGui.HowMuchDonated.Text = highestDonation .. " ROBUX"
			game.Workspace.donateThing.CFrame = game.Workspace.donateThing.CFrame + Vector3.new(0, 20, 0)
		else
			print("Failed to retrieve top donation data.")
		end
	else
		print("Failed to retrieve donation data.")
	end
end

local function hideDonateThing()
	game.Workspace.donateThing.CFrame = game.Workspace.donateThing.CFrame + Vector3.new(0, -20, 0)
end

if game.PrivateServerOwnerId ~= 0 then
	hideDonateThing()
else
	while true do
		processDonationData()
		wait(3600 * 2) -- Wait for 2 hours before refreshing
	end
end

its empty lol

siadhasdhasjashdkh

and it doesnt work and throws a error on :IsFinished

Yeah… using ListKeysAsync and GetAsync for each will eat up your request budget and memory.
I think that, like @RobloxHasTalentR made, you should use a similar structure - but since it is an OrderedDataStore and not a normal DataStore, entries from the other store will not copy across to it. this means you must manually write to the ordered store as well.

This should be done as a last thing when saving normal data.