question

Lars Krakhecke avatar image
Lars Krakhecke asked

Wrong leaderboard position

Hello there,

I seem to have a problem using the leaderboard, altough I'm not sure what could possibly be wrong.

I'm trying to get my position on a dummy-leaderboard I created, the StatValueI receive through the API is correct, but the position is wrong and even is identical for multiple players.

My request looks like this:

GetLeaderboardAroundPlayerRequest request = new GetLeaderboardAroundPlayerRequest();

request.MaxResultsCount = 1;

request.StatisticName = "MoneyExponent";

request.PlayFabId = PlayFabAuthManager.playFabId;

PlayFabClientAPI.GetLeaderboardAroundPlayer(request, LeaderboardRetrieved, LeaderboardError);

In the result is the correct PlayFabId, the correct StatValue (here 17) but the wrong Position (always 4).

What could be the problem?

Leaderboards and Statistics
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image
brendan answered

What is the Title ID you are using for your testing?

7 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Lars Krakhecke avatar image Lars Krakhecke commented ·

Title ID is F275

0 Likes 0 ·
brendan avatar image brendan Lars Krakhecke commented ·

Actually, reviewing your question, I think I see the issue. The position returned is relative to the overall leaderboard - not the "around" leaderboard. So in other words, if I'm in position 20, and I make a call to get the two players around me, they would be in positions 19 and 21.

0 Likes 0 ·
Lars Krakhecke avatar image Lars Krakhecke brendan commented ·

I'm not sure if I understand correctly how to get my position on the leaderboard then. What would be the intended way to get the position of the current player?

0 Likes 0 ·
Show more comments
e.timofeev@flexilestudio.com avatar image e.timofeev@flexilestudio.com commented ·

Good Day!

We also have problem with GetLeaderboardAroundPlayer().

On screen you can see call GetLeaderboardAroundPlayer() for "sound4". and for differnt MaxResultsCount it's return different positions!

I think its because some player has equal statValue.

But, what best practice in this situation?

wrongleader.png

PS Title ID: 6B9C

Thanks.

0 Likes 0 ·
wrongleader.png (183.2 KiB)
brendan avatar image brendan e.timofeev@flexilestudio.com commented ·

Two players with equal scores can indeed appear with A before B on one call, and B before A on another. As they have an identical score, they are effectively tied for position. We do have a backlog item to add a timestamp to the leaderboard reporting, and use that as a secondary index so that the first player to report the score will always be "ahead" of others, though that work has not yet been scheduled, as it hasn't been identified as a priority by our developer community.

1 Like 1 ·
hampusbankler avatar image hampusbankler brendan commented ·

I'm having this problem as well. In my game, a player can change view between "top 10" or "surrounding me". If two players are tied, it consistently shows different on these two views (it does not appear to be random).

When showing top ten, I consistently see myself in position 10. When switching to "surrounding", I consistently see myself in position 9 (switching place with the other tied player).

It's quite messy to fix this per game on the client-side, so I wish that this could be solved. As it appears (at least to me) that it's not random, it feels more like a bug and a matter of rewriting one function to match the other's logic, rather than it requires you to have a second field. Obviously, this is pure guesswork, and I might be wrong.

As it was brought up in 2016 already, any chances it has been scheduled? :)

0 Likes 0 ·
hampusbankler avatar image
hampusbankler answered

Maybe this clientside haxx could be of use for someone else struggling with this? The type LeaderboardEntry in this code is just a container with the same stuff you get in the PlayFab leaderboard entries.

The approach here is to download each array of entries. Then through them and sort them by "Value" and one more thingy of your choice that you know will differ (in my case "UserId", but you can take UserName or whatever).

Finally, since you might have been fiddling around with the positions, we iterate through them and make sure the positions are in order.

Upside: It will show the same, regardless of the Playfab function you have called.

Downside 1: It ain't pretty nor fast.

Downside 2: What the player see might differ from the order the Playfab web gui shows.

C#:

public class LeaderboardEntry
{
    public int Position;
    public string Username;
    public string UserId;
    public int Value;
}    

private void OnEntriesDownloaded(List<LeaderboardEntry> entriesTop10, List<LeaderboardEntry> entriesAroundPlayer)
    {
        if(entriesTop10 == null)
            return;

        if(entriesAroundPlayer == null)
            return;

        m_entriesTop10 = SortTies(entriesTop10);
        m_entriesAroundPlayer = SortTies(entriesAroundPlayer);

        RefreshSlots();
    }

    private List<LeaderboardEntry> SortTies(List<LeaderboardEntry> list)
    {
        if (list.Count < 1)
            return list;

        int bestPositionInList = list[0].Position;

        var sortedList = list.OrderByDescending(c => c.Value).ThenBy(n => n.UserId).ToList();

        for(int i = 0; i < sortedList.Count; i++)
        {
            sortedList[i].Position = bestPositionInList + i;
        }

        return sortedList;
    }
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.