Ordered Datastores

So I’m trying to create a leaderboard for my games, and I need to use something called an Ordered Datastore. Whats the best practice? Would I save data to both a regular and ordered datastore, or just one? If someone could explain this I’d be very grateful.

Since I got here before any of the professionals, I’ll tell you my “best” practice and see if there is anybody with better methods.

To start, you have to understand what we’re trying to accomplish on the backend. (You’ll probably be fine on the frontend, such as setting up ScrollingFrames or playerTemplates for the leaderboard itself.)

every X seconds, you want to “refresh” the leaderboard, using data from an ordered data store, which can only exclusively come from the server.

Problem 1. Loading this stuff ALL on the server is not efficient at all! We’ll need to load everything on the client. But what about all the data coming exclusively from the server? we’ll use one-sided communication, our ol’ pal remoteEvent.

Now, our goal is every x seconds, we send a remote event with leaderboard data to all clients so each can load the players on their behalf.

Problem 2, roblox’s rate limits. Assuming you are going to get the users’ names and profile pictures, that will hit the Players Service’s rate limits within a few refreshes.

The solution? Caching data.

Lets backtrack a bit before we go onto caching data. You don’t even have an ordered data store set up, and I assume you already have precious data in place for your game.

Create an ordered data store and put the server on a loop (one loop for the whole server) to search for and save that specific value on the player every X seconds. (THE KEY SHOULD BE THE PLAYER’S USER ID, AND THE VALUE IS THE SPECIAL VALUE) Since it’s leaderboard data unlinked to actual gameplay data, it isn’t important and you don’t need to BindToClose* or anything.

*For clarification, this is assuming your ordered data store is set up AFTER implementing your actual player data. If your ordered data store loads actual data, always use BindToClose! Additionally, since you’re starting out I’d assume you don’t know what datastore2 is. Go to roblox’s official datastore2 rewrite and start using it for actual player data. For leaderboard data, a seperate ordered data store is easier to use.

Now, to utilize the ordered data store, we can go back to caching. Create a regular datastore that is intended to hold Player UserIds as keys, and names and pfp as values in a table (the special value on the leaderboard is included in the ordered data store). This is so all servers don’t have to keep getting the same name and same pfp over and over.

Now, this is how the system works:

  1. Player gets a win or something (special value)
  2. Server saves everybody in the server after x seconds, putting the special value into the ordered datastore.
  3. After x seconds, it is time for the server to send leaderboard data to the clients for refreshing. It uses page = OrderedDataStores:GetPagesAsync(false, PLAYER_AMOUNT, MIN_AMOUNT) to create a page then playerIDs = page:GetCurrentPage() to return an array (table) of player IDS, which is then ready to search for cached information in the datastore…
  4. Server sends a client event to all players in the game. The payload contains a table of all the players LB positions, pfps, names, and special value, in order of the array of IDs. The server gets this information from the cache datastore you made before, and if none exists, it creates a new datastore entry (gets the name + profile picture) for other servers (and itself) to use.

I understand this might be a bit for a scripter just starting out. If you don’t understand what I said but trust that I have a good method, you could just feed it to an AI and see what it gives you :wink: