Stat leaderboard problem

Hey!

I have had an issue with my leaderboard script, however I cannot locate it.

I was given this warning in the output:

Here is the code:

local DataStoreService = game:GetService("DataStoreService")
local PlayerData = DataStoreService:GetOrderedDataStore("PlayerData")


function SyncLeaderB()
	local suc, err = pcall(function()
		local Data = PlayerData:GetSortedAsync(false,10)
		local CurPage = Data:GetCurrentPage()
		for rank, inf in ipairs(CurPage) do
			local Username = game.Players:GetNameFromUserIdAsync(tonumber(inf.key))
			local Score = inf.Score
			local isOnLB = false
			for i, v in pairs(game.Workspace.ScoreLB.LBgui.CoreFrame.BaseFrame:GetChildren()) do
				if v.NameF.Text == Username then
					isOnLB = false
					break
				end
			end
			
			if isOnLB == false then
				local NFrame = game.ServerStorage.Storage.GUI.PointFrame:Clone()
				NFrame.Parent = game.Workspace.ScoreLB.LBgui.CoreFrame.BaseFrame
				NFrame.Position = UDim2.fromScale(0,0) + UDim2.fromScale(0,0.9)*(rank-1)
				NFrame["CountF"].Text = Score
				NFrame["NameF"].Text = Username
			end
		end
	end)
end

while true do 
	task.wait(0.5)
	SyncLeaderB()
end

Any help would be appreciated :happy1:

Roblox datastores have certain limits which can be found here. The total amount of :GetSortedAsync() requests that can be made in a minute are given from this formula: 5 + numPlayers ⨉ 2. The script provided makes 60/0.5=120 requests per minute which far exceeds the limit causing the warning. Instead try sending fewer requests or use the new MemoryStoreService which has a limit of 1000 + 100 ⨉ [number of users] requests per minute, although it only stores data for a limited amount of time.

Every 0.5 seconds you are initializing a datastore function. AKA. you’re spamming the system

In my opinion thats just way too advanced and a way of misusing the service.

1 Like

I think that sorting it when the contents are tables may also cause a problem

Have you tried waiting for 12 seconds instead of 0.5?

I did that but the Score is still blank

(ignore the dummy, it is just for size referance)

Ordered datastores are NOT normal datastores, they do not store dictionaries/arrays and do not share the same keys with them. Basically if data is saved in a normal datastore named “PlayerData” it wont replicate in an ordered datastore named “PlayerData” unless you move/add it manually.

So should I make a script to copy all of the players’ Score to the Ordered Data Store?

Slightly unrelated, this is my script that manages data:

local RepStore = game:GetService("ReplicatedStorage")
local SvrStore = game:GetService("ServerStorage")
local DatStore = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local PlayerDataFolder = RepStore.PlayerData

local InfoStore = DatStore:GetDataStore("PlayerData")

local Incall = game.ServerScriptService.DataManager.InCall

function UnloadPlayerData(PlayerID)
	local success, err = pcall(function()
		local PlayerData = InfoStore:GetAsync(PlayerID)

		if not PlayerData.Level and PlayerData.Score then
			warn("data empty")
			PlayerData = {}
			PlayerData.Level = 0
			PlayerData.Score = 0
		end

		local PlayerFolder = Instance.new("Folder")
		PlayerFolder.Name = PlayerID
		PlayerFolder.Parent = PlayerDataFolder

		for store, data in pairs(PlayerData) do
			local IntHolder = Instance.new("IntValue")
			IntHolder.Name = store
			IntHolder.Value = data
			IntHolder.Parent = PlayerFolder
		end
	end)
	if not success then warn(err) end
end

function PackPlayerData(PlayerID)
	local PlayerFolder = PlayerDataFolder:FindFirstChild(PlayerID)
	local success, err = pcall(function()
		local PlayerData = {}

		for i, v in pairs(PlayerFolder:GetChildren()) do
			PlayerData[v.Name] = v.Value
		end

		InfoStore:SetAsync(PlayerID,PlayerData)
	end)
	if success then
		PlayerFolder:Destroy()
	else
		warn(err)
	end
end

function TranslateCall(callData)
	for i, v in pairs(callData) do
		local suc, err = pcall(function()
			local PlrId = v.PlrId
			local Ttype = v.Type
			local value = v.Value
			local LPlrFol = PlayerDataFolder[PlrId]
			local SVal = LPlrFol[Ttype]
			SVal.Value = SVal.Value + value
		end)
		if not suc then warn(err) end
	end
end


Players.PlayerAdded:Connect(function(player) UnloadPlayerData(player.UserId) end)
Players.PlayerRemoving:Connect(function(player) PackPlayerData(player.UserId) end)
Incall.Event:Connect(function(par) TranslateCall(par) end)

Once in every 12 seconds, loop through all the in-game players and store their value to the ordered datastore(wins/time whatever you like) then after the data updates make the :GetSortedAsync() request to show it on the board.

1 Like

Thanks! I will try implementing that

1 Like

I added some extra code to my DataManager Script

function ConvertScoreListToODS()
	for order, store in pairs(InfoStore) do
		local UserID = store.key
		local score = store.Score
		ScoreOrd:SetAsync(UserID,score)
	end
end

function LoopCSLTO()
	while true do
		task.wait(12)
		ConvertScoreListToODS()
	end
end