Global Leaderboard Datastore help

Alright I am going to keep this simple. I am trying to make a global leaderboard for my game and am not the biggest expert at DataStores, I am planning on using Ordered Data Store for it but the way my datastore system is it stores all the data in uh I don’t know how to say this but one key?

	local DS = game:GetService("DataStoreService"):GetDataStore(p.userId, "HereItIs")

Thats kinda how my normal datastore is and all the data is stored inside a table or dictionary (whatever you wanna call it Anyway how would I use an ordered datastore to rank a certain stat in the datastore. Like money for example.

local DataStoreService = game:GetService("DataStoreService")
local MoneyStore = DataStoreService:GetOrderedDataStore("HereItIs")
while true do
		wait(5)
		local pages = MoneyStore:GetSortedAsync(false, 10)
			local Top = pages:GetCurrentPage()
end

That is how it is so far. But see this is where I am confused on which is how would I make it only do it to the money stat and not mess up or something. Most of this is just edited and doing what the wiki is saying to do but it doesn’t say anything about doing 1 certain stat by itself that is stored in a dictionary. Yes there is more I need to do to make it show up but right now im just focused on how i’m going to get it to sort it from that money stat.
And the reason I can’t just make it in its own separate datastore or something is because I already have at least 30 - 100 Different players who have played who most likely would not be happy if I reset their money.

There were quite a few sentences that my brain just couldn’t wrap around, but from what I’m understanding, you seem to be having trouble with DataStores.

To start off, you can only use either :GetDataStore() or :GetOrderedDataStore() on a DataStore at once, it cannot be called as both at the same time. If you’re aiming for a leaderboard, just use :GetOrderedDataStore(), as it functions the same way a normal DataStore would plus the leaderboard bonus.

Next, I seem to see an issue with how you’re getting your DataStore in the original code. I would suggest that you do not use p.userId (another flag, it’s UserId with the u capitalized) as the key. Instead, aim for something that can be easier to read, such as "Stats" or "Money". I find it easier to have all the stats in one DataStore with separate key value pairs instead of having the DataStore declared as a UserId with their stats within.

With the way your DataStores are currently set up, there is no possible way for you to be able to load up all the stats in an OrderedDataStore, as the scope is not the DataStore name and will not be able to retrieve all of the player stats at once. You should restructure your DataStores in a way that can be stored in one DataStore under one name without having them stored in different DataStores so that you can utilize OrderedDataStores.

Yes, this will probably mean a whole rewrite on everything data related. However, 30-100 players is not a lot, something that you can easily sacrifice. Many players will come to understand it if the reason why their data was reset is carefully explained to them. If you still do not want to do that, then your only option will be retrieving their data from the former DataStore (local DS = game:GetService("DataStoreService"):GetDataStore(p.userId, "HereItIs")), overwriting it in the new DataStore (game:GetService("DataStoreService"):GetOrderedDataStore("SomeNewName"):SetAsync(p.UserId, NewStatsHere). The code examples I provided here were written as an example, it should not be used as actual code as I do not know if it is working or not.

Alright so im just going to test some stuff on a test place but currently im working on making an ordered data store ect. Will everything work the same as a normal datastore would other than its ordered and must be positive? Is there anything I should know about making one?

game.Players.PlayerAdded:connect(function(plr)
	plr:WaitForChild("Data")
	-- THIS is waiting for the players data folder which is made by the other datastore. This is here so I don't have to rewrite every single script(Money is very important in the game lol)
local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetOrderedDataStore("Money")
local Yo = Instance.new("NumberValue", plr.Data)
Yo.Name = "Money"
Yo.Value = dataStore:GetAsync(plr.UserId)
-- Im trying to load the players stat in uh I don't know if I did this right, Feedback?
			local Stat = plr.Data.Power.Value
			if Stat then
				pcall(function()
					dataStore:UpdateAsync(plr.UserId,function(oldVal)
						return tonumber(Stat)
					end)
				end)
	end

end)

I’m horrible with normal datastores let alone ordered. Please let me know if I did this right so it will load the players data and save it to the ordered datastore.
Some of this I read off of a guide on here. ( the updating async part)
Just noticed I should prob loop saving huh

Everything that you find in a normal DataStore you will find in an OrderedDataStore. All the usual functions and capabilities of a DataStore will also be carried to the OrderedDataStore.

The code looks fine to me, although you should be aware of Yo.Value = dataStore:GetAsync(plr.UserId), as a first time player will have no data, so its value will become nil, thus erroring that line.

Yes I saw that. I left it like that because I plan on editing it so that it transfers your old data over when you join (The default starting cash is 1k) Thank you for your help. I’ll do some more test and edits and tomorrow if I have it working how I want it i’ll mark your answer. Thanks for the help :smiley:

2 Likes

I don’t think it’s accurate to say that GlobalDataStores and OrderedDataStores are the same. They do sport relatively the same functionality but they aren’t meant to be used the same. A GDS is meant for standard key-value access while an ODS should be used for order-based retrieval.

OrderedDataStores don’t work at their full potential or appropriate purpose if the value for a key isn’t an integer. That being said; they shouldn’t be combined either. If you’ve told OP that they should only be using OrderedDataStore, then that’d be appropriate.

I don’t know how accurate this is but I believe GlobalDataStores and OrderedDataStores don’t sport the same namespaces. For example, using the same name when retrieving both types of DataStores won’t necessarily return the same data set.

Maybe I am miss reading this or did not explain what I said above well enough(or forgot to say this). I am using my normal datastore for all other things that need saving. I am using the ordered just for money and that only.
EDIT:
On a side note im currently having issues with the leaderboard and simply making the text for the players Money amount show up
string expect got nil error is what the console is showing. How can I enter the number in a value to a text / string. (It is saying the value is not a string cause its not oof)

Oh, that’d be somewhat easy to resolve. Since fetching a DataStore doesn’t use any request budget, you can fetch both your player DataStore and an OrderedDataStore dedicated to a specific stat. When you save data, you can also use a Player’s UserId as the key and their money as the value and set it to the OrderedDataStore. At least that’s how I think it’s done.

As for the error, I’m not too sure I understand what you’re asking. Mind providing a code sample and the console error associated with the bugged code?

1 Like

Here im trying to make a global board for money

local DataStoreService = game:GetService("DataStoreService")
local MoneyStore = DataStoreService:GetOrderedDataStore("Money")



	while true do
		wait(6)
		local pages = MoneyStore:GetSortedAsync(false, 10)
			local Top = pages:GetCurrentPage()
			
for _, entry in pairs(Top) do
		local userid = entry.key
local username = ""
		 username = game.Players:GetNameFromUserIdAsync(userid)
local Yeet = script.Sample:Clone()
local Val = entry.Value
Yeet.Name1.Text = username
Yeet.Power.Text =  Val -- ERRORS HERE
		
	end

	if pages.IsFinished then
		break
	else
		pages:AdvanceToNextPageAsync()
	end
end


The error I am getting is saying that I am trying to apply a nil value to a string. / invalid argument.

By providing an error, I meant that it would help to provide an explicit error message from the console, line number included. The whole stack trace, from the red message to the blue “Stack End” message. There are several vectors for this error. Hard to work off of a “ERRORS HERE” comment in your code.

That being said, it might help if you make two changes:

Make value lowercase. I don’t think you can access the key-value pair from an OrderedDataStore page by using a capital v. Dictionary entries are case sensitive.

After that, add print(Val) underneath it to see if you’re getting a legitimate value from it. It could be printing nil, which then you need to handle that case by replacing it with a placeholder string. Something that’s non-nil and that tostring works on.

Yeet.Power.Text = Val or "unknown"

Did what you said and it worked thanks for the help on the global. It’d be nice if we could accept 2 different answers on things like this. I’m going to mark nicholas’s answer as the solution because he answer’d my original question. Thank you both very much :upside_down_face: