Help with world record Datastore

Hello Developers,

I have recently been trying to make a world record system for how long a player has been staring at a certain image. I have 2 values that I am trying to save, and I have attempted to create a system that will fetch the world record (of every player in the datastore) for the second value (Not the first, which is for the player’s money). However, I just cannot get it to work.

I am not very good with datastores, but here is the full script:

wait(5)

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

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage.Events.MoreUiEvents.MostTime

local Record = 0

local function SaveData()
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		local plr_key = "Player_".. player.UserId
		local tries = 0
		
		local Money = player.Values.Money
		local BoxWatch = player.Values.BoxWatch
		
		local SaveTheData =  {}
		for _,Child in pairs(player.Values:GetChildren())do
			table.insert(SaveTheData,Child.Value)
			print(Child.Value)
		end

		repeat
			tries += 1
			local success = pcall(function()
				PlayerData:SetAsync(plr_key, SaveTheData)
			end)
		until success or tries == 20

		--[[if not success then 
			warn(result)
		end]]--
	end
end

local function getTop1Players()
	local DataStore = DataStoreService:GetOrderedDataStore("PlayerData")
	local isAscending = false
	local pageSize = 1
	local pages = DataStore:GetSortedAsync(isAscending, pageSize)
	local top1 = pages:GetCurrentPage()

	local top = {}

	for rank, data in ipairs(top1) do
		local dataName = data[2].key
		local name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
		local coins = data[2].value
		print(coins)

		local currentPlayer =  { Player = name, Coins = coins, Rank = rank, }
		table.insert(top, rank, currentPlayer)
		print(currentPlayer)
	end

	return top
end

local function UpdateList()
	SaveData()
	
	local top1 = getTop1Players()

	task.spawn(function()	
		for _, plr in ipairs(top1) do
			Record = plr.BoxWatch
			print(Record)
		end
	end)
end

task.spawn(function()
	while true do
		UpdateList()
		for count=20,0,-1 do
			task.wait(1)
			Event:FireAllClients(Record)
		end
	end
end)

I would appreciate any help that I can get.

1 Like

What part isn’t working? Is the data saving? When you print(rank), what do you get?

The strange thing is, it won’t print anything, so I don’t even know if it is running. The problem I am having is that it is not getting my data from the datastore, and setting it to the world record (The “Record” value isn’t changing)

Is the print(Child.Value) giving anything? After you insert it into the “SaveTheData”.

The for rank, data in ipairs(top1) do, doesn’t get any data?

The print(Child.Value) does its job, printing out the values i need to save, implying that the datastore saved the values.

The for rank, data in ipairs(top1) doesn’t get any data, and as far as I am concerned, the loop isn’t running at all, so this loop may be what I need to work on.

I’m not sure what the for count=20,0,-1 do does, can you tell me?
does the print(Record) print sucessfully?

the count part just creates a countdown from 20 to 0, meaning the world record will be refreshed every 20 seconds (calls the updatelist function, and then waits 20 seconds before doing it again)

One thing I noticed was that you were saving the data right before retrieving the data. I’m not sure if saving data yields, but if that isn’t the case, the data may be retrieved before the data can be updated.

Why are these all local functions?

for rank, data in ipairs(top1) do , should be for rank, data in pairs(top1) do Because it’s a table.

I’m not sure, but you may want to do - table.insert(top, rank, currentPlayer) to table.insert(top, currentPlayer), and then use a custom table.sort function.

Right after you finish the - local function getTop1Players(), put - getTop1Players(), to get the leaderboard, and confirm that it isn’t an issue with the loop.

Thank you for all of your feedback, I really appreciate it,

I have been experimenting with my script and have changed some stuff around. By the way, is top1 truly a table? Because I have it in my script defined as local top1 = pages:GetCurrentPage().

Also, could you inform me on how to try this custom table.sort function if you are confident it would work? I am not very good with tables.

Here is the updated code:

wait(5)

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

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage.Events.MoreUiEvents.MostTime

local Record = 0

local function SaveData()
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		local plr_key = "Player_".. player.UserId
		local tries = 0
		
		local Money = player.Values.Money
		local BoxWatch = player.Values.BoxWatch
		
		local SaveTheData =  {}
		for _,Child in pairs(player.Values:GetChildren())do
			table.insert(SaveTheData,Child.Value)
		end

		repeat
			tries += 1
			local success = pcall(function()
				PlayerData:SetAsync(plr_key, SaveTheData)
			end)
		until success or tries == 20
	end
end

local function getTop1Players()
	local DataStore = DataStoreService:GetOrderedDataStore("PlayerData")
	local isAscending = false
	local pageSize = 1
	local pages = DataStore:GetSortedAsync(isAscending, pageSize)
	local top1 = pages:GetCurrentPage()

	local top = {}

	for rank, data in pairs(top1) do
		local dataName = data.key
		local name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
		local coins = data.value
		print(coins)

		local currentPlayer =  { Player = name, Coins = coins, Rank = rank, }
		table.insert(top, rank, currentPlayer)
		print(currentPlayer)
	end

	return top
end

getTop1Players()

wait(3)
task.spawn(function()
	while true do
		SaveData()
		wait(1)
		local top1 = getTop1Players()

		for _, plr in ipairs(top1) do
			Record = plr.Values.BoxWatch.Value
		end
		for count=5,0,-1 do
			task.wait(1)
			Event:FireAllClients(Record)
			print(Record)
		end
	end
end)

I do think that pages:GetCurrentPage() is a table, but I’m not sure.

You still can’t get the function getTop1Players() to activate yet? IS that correct?

local currentPlayer =  { name, coins,rank, }
table.insert(top, currentPlayer)
local function customSort(a, b)
    
    return a[2] > b[2]-- the > may need to be switched to <, it may give reverse order.
end
table.sort(top, customSort)

This is assuming that the “coins” is what you need to sort

The function runs, but the loop doesn’t (the for rank, data in pairs loop)

print top1 and see what you get.

I think top1 is the problem; I printed it, and it returned as an empty table { }

So the problem is it isn’t pulling any data from the datastore

Is HttpRequests on for the game? – I think this allows datastores, but not sure.


		until success or tries == 20-- add a print(tries) below here. If it isn't 20, it is saving sucessfully

HttpRequests is enabled, and I tried the print(tries) earlier and it only printed 1, so the data is saving

Hmmm… If you increase the page size, does that change anything? try print(pages) as well.

Sadly, the page size doesn’t affect it either, and for some reason, when I try print(pages), it prints “Instance” in the output

Either the data isn’t saving, or the data isn’t retrieving.

If you try PlayerData:UpdateAsync(plr_key, SaveTheData), does that work?

Are you sure that the data is saving?

UpdateAsync doesn’t affect it, but I am pretty positive that the data is saving.

I am thinking it may be because there is only one player (me) to test the datastore, or maybe it is an error retrieving the data. Thoughts?

I am going to stop working on the script now, but I will try any suggestions later.

The data should be saving and retrieving properly. I’m not sure. You probably need someone else, I’m not a pro in datastores.