> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# リーダーボードでさらにできること

> PlayFab リーダーボードの高度な機能: 複数列のリーダーボードの構築、強化されたタイブレーク、外部エンティティ、プレイヤー周辺のランキングのクエリ。

このチュートリアルでは、複数列のリーダーボードの作成、強化されたタイブレーク、リーダーボードをクエリする複数の方法など、このサービスが提供する高度な機能を取り上げます。

この例では、[基本的なリーダーボードを作成する](/services/playfab/community/leaderboards/create-basic-leaderboard)で紹介されている内容にすでに慣れていることを前提とします。ここでは、これらの新機能がいくつかの問題の解決にどのように役立つかの例として、対戦性の高いシューティング ゲームを取り上げます。このゲームには、2 つのチームが対戦するチーム デスマッチというモードがあります。先に 75 キルを達成した方が勝者です。このゲームでは、1 つのスコアでプレイヤーをランキング付けするのではなく、キル数、アシスト数、デス数の 3 つに基づいて誰が最強かを決めます。

## 複数列のリーダーボード定義を作成する

この例を始めるにあたり、これまでよりも複雑なリーダーボード定義を作成する必要があります。ゲームの主要な要素であるキル、アシスト、デスをマッピングするために、複数の列を定義します。以下の例では、C# SDK を使用してリーダーボード定義を作成する方法を示します。

```C# theme={null}
public static async Task CreateLeaderboardDefinitionAsync(PlayFabAuthenticationContext context, string leaderboardName)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    CreateLeaderboardDefinitionRequest leaderboardDefinitionRequest = new CreateLeaderboardDefinitionRequest()
    {
        AuthenticationContext = context,
        Name = leaderboardName,
        SizeLimit = 1000,
        EntityType = "title_player_account",
        VersionConfiguration = new VersionConfiguration()
        {
            MaxQueryableVersions = 1,
            ResetInterval = ResetInterval.Manual,
        },
        Columns = new List<LeaderboardColumn>()
        {
            new LeaderboardColumn()
            {
                Name = "Eliminations",
                SortDirection = LeaderboardSortDirection.Descending,
            },
            new LeaderboardColumn()
            {
                Name = "Assists",
                SortDirection = LeaderboardSortDirection.Descending,
            }
            new LeaderboardColumn()
            {
                Name = "Deaths",
                SortDirection = LeaderboardSortDirection.Ascending,
            }         
        }
    };

    PlayFabResult<PlayFab.LeaderboardsModels.EmptyResponse> createLbDefinitionResult = await leaderboardsAPI.CreateLeaderboardDefinitionAsync(leaderboardDefinitionRequest);
}
```

次に、この例の主要な要素をいくつか説明します。

* `SizeLimit`: このパラメーターは、リーダーボードが持つことのできる行数を制限するために使用します。ここでの値はあくまで例です。
* `VersionConfiguration`: このパラメーターは、リーダーボードに対するバージョン管理を可能にします。詳細については次のページを参照してください: [シーズナル リーダーボード](/services/playfab/community/leaderboards/seasonal-leaderboards)
* `Columns`: このパラメーターにより、1 つの定義あたり最大 5 つまでの複数列を定義できます。ここでは、Eliminations、Assists、Deaths を設定しています。ここで重要な要素は `SortDirection` パラメーターであり、リーダーボードのソートを決定します。この例では、プレイヤーはキル数とアシスト数が多い (SortDirection = Descending) ほど、そしてデス数が少ない (SortDirection = Ascending) ほど、上位にランクされます。

他のパラメーターやリーダーボード定義の管理方法の詳細については、[基本的なリーダーボードを作成する](/services/playfab/community/leaderboards/create-basic-leaderboard)を参照してください。

## 外部エンティティを持ち込む

リーダーボード サービスは、スタンドアロンのコンポーネントとして使用でき、ゲームのコンテキストでのみ意味を持つ外部エンティティを持ち込むことをサポートしています。プレイヤー ID が PlayFab のログインと結び付いていなくても、リーダーボード サービスを使用できます。PlayFab システムの外部のエントリの場合、リーダーボード上のエントリのエンティティ タイプは *external* である必要があります。この場合、entityId はご自身のシステムにおけるプレイヤーの ID となります。このようなケースでは、リーダーボード上の*すべて*のエントリが *external* エンティティである必要があります。

## リーダーボードにデータを追加する

リーダーボードを作成したので、データを追加していきます。この主題に関する前のチュートリアルとの主な違いは、同じ行に 3 つの異なるスコアを追加する必要があることです。以下の例では、C# SDK を使用してリーダーボードにデータを追加する方法を示します。

```C# theme={null}
public static async Task UpdateLeaderboardForPlayer(PlayFabAuthenticationContext context, string leaderboardName, string entityId, int score)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    UpdateLeaderboardEntriesRequest updateLeaderboardRequest = new UpdateLeaderboardEntriesRequest()
    {
        Entries = new List<LeaderboardEntryUpdate>()
        {
            new LeaderboardEntryUpdate()
            {
                EntityId = entityId,
                Scores = new List<string> { score.ToString(), (score + 1).ToString(), (score + 2).ToString() },
                Metadata = "metadata",
            }
        },
        AuthenticationContext = context,
        LeaderboardName = leaderboardName,
    };

    PlayFabResult<PlayFab.LeaderboardsModels.EmptyResponse> updateResult = await leaderboardsAPI.UpdateLeaderboardEntriesAsync(updateLeaderboardRequest);
}
```

重要な注意点として、Scores パラメーターには 3 つの値が与えられています。任意のエントリに指定するスコアのリストの長さは、リーダーボード定義の列数と一致する必要があります。各値は有効な 64 ビット整数である必要があります (文字列表現は、すべてのクライアントが 64 ビット値を扱えるようにするためだけのものです)。

## リーダーボードからデータを取得する

ここからは、リーダーボードをクエリするさまざまな方法を学びます。それぞれには特定の目的があり、開発者がゲームで表示する必要のあるプレイヤーを取得できるように意図されています。

### エンティティ周辺のリーダーボードを取得する

このリーダーボードのクエリ方法では、特定のエンティティ近辺のリーダーボードのセクションを取得できます。この状況を実務的に見ると、非常に大きなリーダーボードがあり、ゲームでアクティブなプレイヤーに対して関連情報のみを表示したい場合が該当します。プレイヤーが 1000 位にいる場合、トップ プレイヤーではなく、近くの近隣を表示できます。以下の例では、C# SDK を使用してエンティティ周辺のリーダーボードをクエリする方法を示します。

```C# theme={null}
public static async Task<List<EntityLeaderboardEntry>> GetLeaderboardAroundEntity(PlayFabAuthenticationContext context, string leaderboardName, string entityId)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    GetLeaderboardAroundEntityRequest getLbRequest = new GetLeaderboardAroundEntityRequest()
    {
        LeaderboardName = leaderboardName,
        AuthenticationContext = context,
        Entity = new PlayFab.LeaderboardsModels.EntityKey()
        {
            Id = entityId,
            Type = EntityType
        },
        MaxSurroundingEntries = 20,
    };

    PlayFabResult<GetEntityLeaderboardResponse> lbResponse = await leaderboardsAPI.GetLeaderboardAroundEntityAsync(getLbRequest);
    
    return lbResponse.Result.Rankings;

}
```

ここで最も重要な要素は `MaxSurroundingEntries` で、これによってリーダーボードから特定のエンティティ周辺にランクされたエンティティを抽出できます。たとえば、100 位のプレイヤーがいて `MaxSurroundingEntries` = 20 を使用すると、90 位から 110 位までのプレイヤーが取得されます。プレイヤーがリーダーボードのトップにいる場合は、上位 20 件が取得されます。最下位の場合は、最下位 20 件が取得されます。リーダーボードの最上位や最下位の位置を除き、API は、ランキングを要求したエンティティが取得された位置の中央に来るように試みます。

### 複数のエンティティに対するリーダーボードを取得する

この API は、リーダーボードをクエリするもう 1 つの方法を提供します。リーダーボード内で複数のエンティティを検索してソートしたいケースに役立ちます。以下の例では、C# SDK を使用して複数のエンティティのリストに対してリーダーボードをクエリする方法を示します。

```C# theme={null}
public static async Task<List<EntityLeaderboardEntry>> GetLeaderboardForEntities(PlayFabAuthenticationContext context, string leaderboardName, List<string> entityIds)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    GetLeaderboardForEntitiesRequest getLbRequest = new GetLeaderboardForEntitiesRequest()
    {
        LeaderboardName = leaderboardName,
        AuthenticationContext = context,
        EntityIds = entityIds,
    };

    PlayFabResult<GetEntityLeaderboardResponse> lbResponse = await leaderboardsAPI.GetLeaderboardForEntitiesAsync(getLbRequest);

    return lbResponse.Result.Rankings;
}
```

### フレンドのリーダーボードを取得する

たまにやってきてゲームをプレイするカジュアルなプレイヤーもいるでしょう。彼らはリーダーボードのトップからは遠いかもしれませんが、フレンド同士では競争が繰り広げられているかもしれません。この API を使用すると、リーダーボードをクエリして、プレイヤーのフレンドを見つけることができます。

```C# theme={null}
public static async Task<List<EntityLeaderboardEntry>> GetFriendLeaderboardForEntity(PlayFabAuthenticationContext context, string leaderboardName, string entityId)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    GetFriendLeaderboardForEntityRequest getLbRequest = new GetFriendLeaderboardForEntityRequest()
    {
       LeaderboardName = leaderboardName,
       Entity = new PlayFab.LeaderboardsModels.EntityKey()
       {
           Id = entityId,
           Type = EntityType
       },
    };

    PlayFabResult<GetEntityLeaderboardResponse> lbResponse = await leaderboardsAPI.GetFriendLeaderboardForEntityAsync(getLbRequest);
  
    return lbResponse.Result.Rankings;
}
```

PlayFab サービスからフレンドを取得する方法は複数あります。利用可能なパラメーターの詳細については、[API リファレンス](/services/playfab/community/leaderboards/api-reference)を参照してください。

### 強化されたタイブレーク

対戦性の高いシューティング ゲームの例では、複数のプレイヤーが同じキル数を持つ場合があります。そのような状況では、タイブレークを行う別の方法が必要です。ここで強化されたタイブレーク機能が役に立ちます。

リーダーボード定義を作成するとき、複数の列を持つことができます。列を追加する順序が、ソートとタイブレークの動作を決定します。優先順位があり、最初に追加された列が最も重要で、次に 2 番目、というように続きます。今回の例に当てはめると、キル数が同点の場合、次の基準はアシスト数、最終的な基準はデス数となります。それでも同点が続く極端な場合、既定でタイムスタンプにフォールバックし、先にスコアを達成した方が上位となります。

\| ランク     | エンティティ ID                         | Eliminations|  Assists        | Deaths | LastUpdated\
\|----------------------|------------------------------------|-------------------|--------------------------
|1 | "player 3" | 103               |24 | 15|"2024-08-27T20:24:36.738Z"
|2 | "player 2" | 102               | 30| 20 |"2024-08-27T20:24:29.251Z"
|3 | **"player 1"** | 100               | 25 |18 |"2024-08-27T19:52:26.642Z"\
|4 | **"player 4"** | 100               | 25 | 18 |"2024-08-27T20:24:44.552Z"
|4 | **"player 5"** | 100               | 25 | 19 |"2024-08-27T20:25:47.552Z"

この例では、3 人のプレイヤー間で同点となっています。

* "player 5": キル数とアシスト数は同じですが、デス数が多いため、リーダーボードの最下位に位置します。
* "player 4": このプレイヤーは "player 5" よりデス数が少なく、"player 1" と同じですが、player 1 の方が先にこれらの数値を達成しました。
* "player 1": "player 4" と同じ数値ですが、ゲーム内でこのスコアを最初に達成したのはこのプレイヤーであるため、このタイブレーク シナリオでは上位にランクされます。

## まとめ

このチュートリアルでは、次の操作の方法を学びました:

* 複数列のリーダーボードの作成。
* さまざまなクエリの方法の確認。
* 強化されたタイブレーク メカニズムの理解。

## 関連項目

* [基本的なリーダーボードを作成する](/services/playfab/community/leaderboards/create-basic-leaderboard)
* [シーズナル リーダーボード](/services/playfab/community/leaderboards/seasonal-leaderboards)
* [制限](/services/playfab/community/leaderboards/limits-leaderboards)
* [クォータ](/services/playfab/community/leaderboards/quota-leaderboards)
* [統計によってプレイヤーをランキング付けする](/services/playfab/community/leaderboards/leaderboards-linked-to-stats)
* [グループ リーダーボード](/services/playfab/community/leaderboards/group-leaderboards)
* [手動ティア](/services/playfab/community/leaderboards/manual-tiers)
* [リーダーボードに追加データを付与する](/services/playfab/community/leaderboards/metadata-leaderboards)
* [API リファレンス](/services/playfab/community/leaderboards/api-reference)
* [リーダーボードと Cloudscript](/services/playfab/community/leaderboards/leaderboards-cloudscript)
* [Playstream を使用したリーダーボード](/services/playfab/community/leaderboards/leaderboards-with-playstream-and-telemetry)


## Related topics

- [グループ リーダーボード](/ja-jp/services/playfab/community/leaderboards/group-leaderboards.md)
- [API リーダーボード リファレンス](/ja-jp/services/playfab/community/leaderboards/api-reference.md)
- [手動ティア リーダーボード](/ja-jp/services/playfab/community/leaderboards/manual-tiers.md)
- [シーズナル リーダーボード](/ja-jp/services/playfab/community/leaderboards/seasonal-leaderboards.md)
- [リーダーボードにコンテキスト データを追加する](/ja-jp/services/playfab/community/leaderboards/metadata-leaderboards.md)
