Hello! I am currently creating a leaderboard for my game, but it seems to not quite work. I put in some prints, and all works until the “for rank,” repeat. Anyone know how to fix this? Here is my code:
local dataStore = game:GetService("DataStoreService")
local buckStore = dataStore:GetOrderedDataStore("Bucks")
local function leaderboard()
local pages = buckStore:GetSortedAsync(false, 5)
local topFive = pages:GetCurrentPage()
for rank, data in pairs(topFive) do
local name = data.Key
print("test")
local nameText = game.Players:GetNameFromUserIdAsync(name)
script.Parent["Num".. rank].Name.Text = nameText
end
end
leaderboard()
Hey! I basically completely changed the post when I figured out the issue, but it’s just simply not getting data. The “for, rank” loop I have created refuses to run.
By universe do you mean game? The data is saved in the place within the place where you actually play, whereas I am trying to receive this dataStore in the main menu place.
It’s not a problem with GetOrderedDataStore because that just returns an OrderedDataStore object, it’s your code. Specifically, because you spelled key with a capital K. You should’ve been getting errors in your console, which it doesn’t look like you checked either and if you did, haven’t specified what’s there.
Your answers could have been found by referring to documentation: this is the first thing that you should’ve done before posting a thread, moreso if your code came from the sample here. Answers are more often found by searching first and debugging second.
A very easy debugging method you could’ve hopped to first was to actually print what was in each iteration. If you had a table, then you could iterate through that. You could also use a resource to facilitate this, such as Repr, for complex or unknown tables.
for rank, data in pairs(topFive) do
print(rank, data) -- This
GetSortedAsync returns a DataStorePages object. Each page is represented as an array of tables and each entry has two keys: key and value. Lua is case sensitive: you are writing out Key, not key.
NOW: If you can confirm that the for loop is NOT running, which you have not yet and can do so by adding the test print above the name declaration instead of below, then you have a different problem which is that your page is empty, so ignore everything above and look towards tackling that. That being said, this scenario can’t be possible unless there’s no data to be pulled at all, because OrderedDataStores do not accept non-integer values.
I did indeed prove that the loop isn’t running. I created a print(“LoopWorks”) for debugging before I specified data.key and nothing was outputted in console. I probably should have mentioned that in an earlier comment.
I should also mention that I did check console, and nothing popped up. Would this perhaps be a good time to use pcall() for a debugging check or does pcall() not work in this situation?
If you added a print right below the for loop and nothing else as I showed in my sample, then there’s nothing to iterate over, meaning you have no data in your DataStore.
To check in: I don’t know where exactly you save data from because that code is not included, but do you also use GetOrderedDataStore for that? If not, change that and try again. All cases of DataStores related to “Bucks” need to be fetched via GetOrderedDataStore: one can’t be GetDataStore and another GetOrderedDataStore.
As far as I know, they’re held in separate namespaces.
I used GetDataStore in a seperate place within my game/universe, and it does work fine. Let me try creating a seperate dataStore and use is solely for the leaderboard and see if that helps.
Yes that’s because when you save to the data store, the object you’re calling SetAsync on is also a GlobalDataStore, not an OrderedDataStore. I’m still making this assumption because I have no idea how you’re saving or if there’s any differences in any of your code working with the Bucks store (e.g. one script uses GetDataStore(“Bucks”) and some others use GetOrderedDataStore(“Bucks”)).
After you mentioned that and I went scrolling through the API, I noticed GetGlobalDataStore, whereas I am only using GetDataStore. Perhaps that could warrant what’s going on?
Also, here is all code involved in this “Bucks” DataStore:
Note these are snippets from seperate places of code, and are all from a seperate place then where my leaderboard currently is. The leaderboard is in my main place, and all of this code is within the place where the actual “game” is.
-- Defining the dataStore
local buckStore = dataStore:GetDataStore("Bucks")
-- OnPlayerAdded
local bucks = buckStore:GetAsync(player.UserId)
-- Player Leaving
local bucks = game.ReplicatedStorage.PlayerData["player".. player.UserId].Bucks.Value
buckStore:SetAsync(player.UserId, bucks)
There we go, thank you, that (sort of) worked.
The reason I couldn’t change “Bucks” to GetOrderedDataStore was because of how bucks was being used. It was also the primary part of my in-game shop, which if I am correct using it as a regular value with no intention of ordering it should simply be GetDataStore. This was fixed though by creating a new dataStore named “Leaderboard” and placing the same data within it, and using GetOrderedDataStore.
OrderedDataStores have the same functions as GlobalDataStores. Provided you are only saving positive integer values to that DataStore, you can just use GetOrderedDataStore in all cases of needing to interact with the Bucks DataStore.
When needing a leaderboard made, use GetSortedAsync and co. If you’re just concerned with the value, GetAsync. OrderedDataStores have the same functionalities as non-ordered DataStores specifically so you can have that versatility available without doubling up DataStores where not necessary. In your case, because it’s just one DataStore with one value, no need to use two.
local DataStoreService = game:GetService("DataStoreService")
-- In all cases of needing to get the store
local BucksStore = DataStoreService:GetOrderedDataStore("Bucks")
-- In all cases of just needing a single value:
BucksStore:GetAsync(player.UserId)
-- In all cases of having to create an ordered leaderboard:
BucksStore:GetSortedAsync(args)
Oh, I see now. Either way, I’m going to need 2 anyways since I am only using “Bucks” as a placeholder value until I get the dataStore that I really want for the Leaderboard up and running. Anyways, thanks for your help and patience! I’m still learning obviously.