Best data methods

I am going into contract work and want to make sure I have the best data store method that I can. I cannot have any data lost and I need to be able to have global leaderboards. I am advanced and would understand pretty much anything you tell me. I am not looking for a regular way to do datastore, but rather more advanced methods.

My current method of saving data is when a player joins, it checks if they have data. If they don’t have data, it creates new data. It puts all data into one dictionary called the players UserId. It puts that dictionary in another dictionary called “SessionData.” Anytime the script needs to access their data, it does SessionData[player.UserId]. When a player exits the game, I save the data. Anytime the data is saved it gets the dictionary in sessiondata and saves it as the players data. For the client to read the data, I create values in ReplicatedStorage to be read from. Anytime the script changes a players data it also changed the data in replicated storage. This way the client can read their players data if ever needed.

Are there any better ways for datastores? How would I go about doing a global leaderboard?

2 Likes

If the player’s data fails to load, don’t save the data, and also notify the user that their data isn’t lost and that it just wasn’t loaded (better UX).

I would recommend storing the data in a server script and firing the client whenever the data updates, as you’re avoiding storing a potentially large amount of instances (large arrays could mean a hundred or more). (don’t send all the data everytime, just what is updating, ex: server tells client to update the cash to 50)

Due to roblox’s limitations, you are unable to have leaderboards if you’re storing all of the user’s data in a dictionary. Leaderboards must be done using OrderedDataStores as they have the GetSortedAsync method, and normal datastores don’t.

To make a global leaderboard, you will need to save the data of what the leaderboard should be about in its own OrderedDataStore (unique for each stat). To get the top x players, you will need to call GetSortedAsync on the OrderedDataStore which you want to retrieve the top stat players from. GetSortedAsync will return a DataStorePages, and to get the data from the DataStorePages you will need to call GetCurrentPage which will return an array of dictionaries. Each dictionary contains they key and the value, in a format like this.

local form = {
    key = userId, -- assuming you're using userids for keys
    value = 100 -- the amount
}

The array which contain all the dictionaries will look like this

local data = {
    {
        key = 1,
        value = 100
    },
    {
        key = 2,
        value = 80
    },
    ...
}

The key of the player’s data should be the UserId, so to get the username simply call GetNameFromUserIdAsync to get the name (and probably cache it too).

local Players = game:GetService"Players"
for i,v in pairs(data)
    local key,value = v.key,v.value
    local success,name = pcall(Players.GetNameFromUserIdAsync,Players,key)
    name = (success and name) or "Unknown"
    --You now have the name of the player, and their data
end

How you want to design the hierarchy of the leaderboard is up to you, but I would recommend having a TextLabel for each spot on the leaderboard, and naming it for the spot (ex: 15th spot would be named 15) so that you can simply get the spot by indexing the parent of the TextLabels.

local frameChanging = workspace.Leaderboard1.Frame[i]
--i would be the spot in the leaderboard, as the keys in the data correspond to the leaderboard position
4 Likes