Sign In Register

How can we help you today?

Start a new topic

Get a list of all the leaderboards for which a player has ever posted a score

Hello,


I have been scratching my head trying to find a way to get a list of all the leaderboard for which a specified user has posted a score.


First, I expected 

{

  "@class": ".GetLeaderboardEntriesRequest",

  "leaderboards": [

    "ldb_daily_event.eventId.*"

  ]

}


To work, but after testing, wildcards don't see to have an effect. Then I tried

{

  "@class": ".GetLeaderboardEntriesRequest"

}

but that returns an error.


I tried ListLeaderboardsRequest, but that returns everything. Admittedly, I could parse each returned board for a match, but I can't imagine there's no better way to do it?


Finally, what is the difference between GetLeaderboardEntriesRequest and LeaderboardsEntriesRequest? They take the same parameters and appear to return the same results.


Cheers,

Alain-Daniel


Yeah, using the message boards would have been better for search-ability in the future. Anyhow, their solution was:


"The method outlined above by Liam would store an Array of ShortCode strings in the players scriptData. You would pass these values individualy or as an array into the Leaderboad Api, to return the the appropriate player data."


Basically they say that each time you post a score, store the leaderboard somewhere for you to query later. Not a very satisfying solution as it still feels like this is functionality that should be baked in the system.


I ended up using a table instead of player data however.


Cheers,

Alain-Daniel


1 person likes this

@Alain


I have the same question and wish you had posted your response here instead of a ticket.

Thank you very much for your response and info on how you addressed it.


Would you please be able to post "The method outlined above by Liam" for completeness. This would allow me to evaluate this approach, too. If I understand it correctly the solution is about keeping a reference to all directories posted in in code. This indeed is not very elegant and in particular problematic, if you want to recreate this at game start (i.e. without ever posting a score).


Would you mind sharing your solution? I am new to GameSparks and it would benefit me, but I understand if it's something that you rather not share...



"The method outlined above by Liam" is "store an Array of ShortCode strings in the players scriptData."


I don't know if my solution would work for you, but I have a daily leaderboard. At the end of the day, I process the data in it (assign rewards and points) and save the results in a dailyEvent_History table. Then I can check for which event does a player have an entry in there (mongoCollection.find({"playerId": <any_playerId>})).


On the client side, instead of querying the leaderboard data, I create a new event that returns the requested info from dailyEvent_History.


I just didn't like storing the data in playerData, you can't query that very well.

Do you think something like this could work? I have to read up on cloud code....


This is just the principle in kind of pseudo code:

  

1. Create Custom Event 

{
  "@class": ".CUSTOMGetLeaderboardEntriesRequest",
  "leaderboards": [
    "SHORT_CODE"
  ]
}

   2. Intercept with Cloud Code and get all partitions, then run over all partitions and get best player score for each partition, if player has a score in a partition, add to output JSON 

var partitions = Spark.getLeaderboards().getLeaderboard(SHORT_CODE).getPartitions();
 
foreach (var leaderboard in partitions)
{
var entry = leaderboard.getEntriesFromPlayer(myPlayerId, 1);
// add PARTITION to JSON
if (entry != "")
// add rank to RETURN JSON
else
// add "-1" as rank to RETURN JSON
}
 

 3. Return the data of the query via cloud code   

Looks like it would work. However part #2 seems incredibly slow. As you accumulate partitions each request will take longer and longer. That seems a little excessive at first glance as there could be thousands of partitions, but I don't know your system. If you know there will ever only be 10 partitions (for example), it sounds fine.


As I said in the previous post, I ended up using a system where I know when I'm done with a partition and I cache all the results in a runtime collection. This ends up being a single call to find all the entries for a player and another call to get all the possible partitions. Then it is just a matter of comparing those two lists.


It really depends on what you are trying to do and how many partitions you will have.

I am trying this right now...


I get the partitions and can return them in the query... see example below...


Do you know how I can just extract the shortCode from the partitions in cloud code and store them in a List / array?


 

{
  "@class": ".LogEventResponse",
  "scriptData": {
    "eventAttr1": [
      {
        "archived": false,
        "description": "High Score per Level",
        "entries": {},
        "entryCount": 2,
        "name": "HighScoreTable",
        "partition": true,
        "partitioned": false,
        "propertySet": null,
        "scoreFields": [
          "Level",
          "LT",
          "LM"
        ],
        "shortCode": "HSPL.Level.1"
      },

and so on...

 



I got it to work. I will try now to see if there is a way to access the database directly (not the individual partitions) and extract the data directly.


Since the code runs on the server, the execution time might be pretty much irrelevant as the get/post is the bottleneck.


 

// ====================================================================================================
//
// Cloud Code for CCE, write your code here to customize the GameSparks platform.
//
// For details of the GameSparks Cloud Code API see https://docs.gamesparks.com/
//
// ====================================================================================================
var shortCode = Spark.getData().DB_Short;
var playerId = Spark.getPlayer().getPlayerId();
var partitions = Spark.getLeaderboards().getLeaderboard(shortCode).getPartitions();
var shortCodes = [];
var leaderboardEntries = [];
var leaderboardID = [];
var leaderboardRank = [];

for (index = 0; index < partitions.length; index++)
{
    var sc = partitions[index].getShortCode();
    shortCodes.push(sc);
}

for (index = 0; index < shortCodes.length; index++)
{
    var lb = Spark.getLeaderboards().getLeaderboard(shortCodes[index]);
    var cursor = lb.getEntriesFromPlayer(playerId, 1);
    var entry = cursor.next();
    
    if (entry != null)
    {
        leaderboardEntries.push(entry);
        //leaderboardID.push(shortCodes[index]);
        leaderboardID.push(entry.getAttribute("Level"));
        leaderboardRank.push(entry.getRank());
    }

}

//Spark.setScriptData("Leaderboard Entries", leaderboardEntries);
Spark.setScriptData("Leaderboard ID", leaderboardID);
Spark.setScriptData("Leaderboard Rank", leaderboardRank);

 

Hi Alain,


We have addressed this in your ticket.


Regards,

Liam

Login to post a comment