> ## 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.

# 创建基础排行榜

> 使用 C# SDK 创建 PlayFab 基础排行榜：定义列和排序方向、添加玩家条目、查询排名并处理分数打破平局。

# 创建基础排行榜

在本教程中，我们向您展示如何使用新的排行榜服务创建基础排行榜。让我们从一个街机游戏的示例开始，目标是击败尽可能多的敌人，直到被击败。此时，您会得到一个分数。现在，我们希望创建一个排行榜来帮助此游戏确定谁是最好的玩家。

## 创建排行榜

第一步是创建排行榜定义，其中包含用于对玩家进行排名的主要元素。对于我们的街机游戏，只需要一列作为分数。以下示例演示了如何使用 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 = "arcadeScore",
                SortDirection = LeaderboardSortDirection.Descending,
            }          
        }
    };

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

现在，让我们解释此示例中的一些关键元素：

* `AuthenticationContext`：此参数处理向我们的服务发出的每个请求背后的所有身份验证。有关详细说明，可以查看下面的页面：[排行榜快速入门](/services/playfab/community/leaderboards/quickstart-leaderboards)。
* `Name`：此参数帮助您标识排行榜定义。选择一个有意义的名称非常重要，因为它将用于发出其他请求以检索信息。此外，此名称必须是唯一的，因此每次创建排行榜时都应使用新的名称。
* `EntityType`：此参数指定您要为其创建排行榜的实体类型。您可以在此处了解更多信息：[实体编程模型](/services/playfab/live-service-management/game-configuration/entities)。
  * `title_player_acount`：此实体类型指的是 PlayFab 中的玩家。为了创建玩家，您可以使用此处描述的 `LoginAsPlayer` 方法：[快速入门](/services/playfab/community/leaderboards/quickstart-leaderboards)。
  * `group`：此实体类型指的是一组玩家，此概念通常适用于“氏族”、“公会”等游戏。请在此处查看更多信息：[组排行榜](/services/playfab/community/leaderboards/group-leaderboards)。
  * `external`：此实体类型用于向我们的排行榜添加自定义数据。每一行不需要绑定到 PlayFab 上的任何内容，它是您自己的数据。您可以在 `EntityId` 字段中使用您自己的标识符，只要它们是字符串。
  * `master_player_account`：此实体类型指的是跨游戏的玩家。当工作室有多个游戏，并且您的玩家从一个游戏转移到另一个游戏，或者他们在玩同一工作室的多个游戏时，此概念适用。基于此概念，您可以创建来自同一工作室多个游戏的玩家排行榜。您需要使用主玩家账户 ID（也称为 PlayFabId）将其映射到 `EntityId`。
  * `character`：此实体类型与那些拥有一系列角色供玩家选择并开始游戏旅程的游戏相关。基于此概念，要创建角色排行榜，您需要先创建一名玩家，然后创建与该玩家关联的角色。之后，您可以使用 `CharacterId` 作为实体 ID 并插入具有相应分数的行。
* `VersionConfiguration`：此参数允许您为在一定时间后自我重置的排行榜设置版本控制策略。此概念在此处进行了深入介绍：[赛季排行榜](/services/playfab/community/leaderboards/seasonal-leaderboards)。
* `Columns`：在这里，我们定义排行榜将拥有的列数。在此示例中，我们仅为分数设置了一列。我们还将 `SortDirection` 定义为降序，这意味着得分最高的玩家将排在最上面。每个定义允许的最大列数为 5。

有了所有这些信息，您现在可以运行示例并创建您的第一个排行榜。

### 获取排行榜定义

在向此排行榜添加数据之前，我们希望确保它已正确创建。为此，我们提供了一个如何检索排行榜定义的示例。

```C# theme={null}
public static async Task GetLeaderboardDefinition(PlayFabAuthenticationContext context, string leaderboardName)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    GetLeaderboardDefinitionRequest leaderboardDefReq = new GetLeaderboardDefinitionRequest()
    {
        Name = leaderboardName
    };

    PlayFabResult<GetLeaderboardDefinitionResponse> getleaderboardDefResult = await leaderboardsAPI.GetLeaderboardDefinitionAsync(leaderboardDefReq);
}
```

若要检索排行榜定义，请指定您创建的排行榜的名称。如果您有多个排行榜定义，可以使用下一个示例获取其中一组。

```C# theme={null}

 public static async Task ListLeaderboards(PlayFabAuthenticationContext context)
 {
     PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
     ListLeaderboardDefinitionsRequest listLbRequest = new ListLeaderboardDefinitionsRequest()  
     {
         AuthenticationContext = context,                
     };
     PlayFabResult<PlayFab.LeaderboardsModels.ListLeaderboardDefinitionsResponse> lbResponse = await leaderboardsAPI.ListLeaderboardDefinitionsAsync(listLbRequest);
    
 }
```

### 更新排行榜定义

如果要更新排行榜定义，您可以按如下所示操作：

```C# theme={null}

 public static async Task UpdateLeaderboardDefinitionAsync(PlayFabAuthenticationContext context, string leaderboardName, int sizeLimit, VersionConfiguration version)
 {
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    UpdateLeaderboardDefinitionRequest updateLbDefinitionRequest = new UpdateLeaderboardDefinitionRequest()
    {
        AuthenticationContext = context,
        Name = leaderboardName,
        SizeLimit = sizeLimit,
        VersionConfiguration = version,
     };
     PlayFabResult<PlayFab.ProgressionModels.EmptyResponse> updateLbDefinitionResult = await leaderboardsAPI.UpdateLeaderboardDefinitionAsync(updateLbDefinitionRequest);
           
 }
```

请注意，Columns、EntityType 和 `ResetInterval` 无法作为更新的一部分进行修改。

### 删除排行榜定义

如果要删除排行榜定义，可以按如下所示操作：

```C# theme={null}

public static async Task DeleteLeaderboard(PlayFabAuthenticationContext context, string leaderboardName)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    DeleteLeaderboardDefinitionRequest deleteLbRequest = new DeleteLeaderboardDefinitionRequest()
    {
        AuthenticationContext = context,
        Name = leaderboardName,
    };

    PlayFabResult<PlayFab.LeaderboardsModels.EmptyResponse> lbResponse = await leaderboardsAPI.DeleteLeaderboardDefinitionAsync(deleteLbRequest);
}
```

## 向排行榜添加数据

继续我们的街机游戏示例，我们现在知道如何创建排行榜定义、检索它，并在必要时将其删除。下一步是开始向排行榜添加数据。

请记住，这些是基于实体的排行榜，这意味着条目是实体。我们还支持带入您自己的外部身份，这在[排行榜的更多用法](/services/playfab/community/leaderboards/doing-more-with-leaderboards)中有详细讨论。

在我们的具体示例中，我们使用的实体类型是 title\_player\_account，因此我们的排行榜由玩家填充。但请记住，您还可以使用其他实体类型。您可以在此处查看它们：[可用的内置实体类型](/services/playfab/live-service-management/game-configuration/entities/available-built-in-entity-types)。

现在让我们深入了解如何向排行榜添加数据。

```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()}                
            }
        },
        AuthenticationContext = context,
        LeaderboardName = leaderboardName,
    };

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

现在，让我们解释此示例中的一些关键元素：

* `Entries`：此参数对应于添加到排行榜的实际行。它有一个 `EntityId`，这是一个字符串，用于在排行榜中标识实体。由于此服务是独立组件，因此您可以在此处使用自己的标识符。但是，如果您正在使用其他 PlayFab 服务，则此值应在所有服务中保持一致。
* `Scores`：此参数对应于您可以添加到一个实体的分数列表。请记住，排行榜可以有多个列。您可以在此处深入了解这些概念：[排行榜的更多用法](/services/playfab/community/leaderboards/doing-more-with-leaderboards)
* `Name`：此参数对应于您在创建排行榜定义时设置的排行榜名称。

您现在可以向排行榜添加数据。

## 从排行榜检索数据

让我们快速回顾一下。此时，您已经创建了排行榜、检查了所有配置详细信息，并开始向其中添加实体。现在，让我们想象一些玩家已经开始使用您的游戏，所有玩家都取得了令人印象深刻的分数。我们希望确定谁是最好的玩家。在以下示例中，我们向您展示如何执行此操作。

```C# theme={null}
public static async Task<List<EntityLeaderboardEntry>> GetLeaderboard(PlayFabAuthenticationContext context, string leaderboardName)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    GetEntityLeaderboardRequest getLbRequest = new GetEntityLeaderboardRequest()
    {
        LeaderboardName = leaderboardName,
        StartingPosition = 1,
        PageSize = 20,
        AuthenticationContext = context,
    };

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

现在，让我们解释此示例中的一些关键元素：

* `StartingPosition`：此参数指的是您希望从中开始查询数据的位置。在此示例中，我们希望获得排名靠前的玩家，因此我们将此参数设置为 1。此参数还与 `PageSize` 参数配合使用，根据需要查询整个排行榜。
* `PageSize`：此参数指定该请求中拉取的记录数。
* `Name`：此参数对应于您在创建排行榜定义时设置的排行榜名称。

### 打破平局

现在让我们想象一下，一些正在使用您游戏的玩家正在争夺谁是最好的。我们面临一个问题：两个玩家的分数相同，因为他们击败了相同数量的敌人。那么，谁应该是排名靠前的玩家？

为了回答这个问题，我们默认采用一个简单的打破平局策略。我们根据达到分数时的时间戳来选择最佳玩家。谁先达到，谁就是排名靠前的玩家。但是，根据游戏的具体情况，这可能还不够或不够准确。有关更复杂的打破平局功能，请参阅：[排行榜的更多用法](/services/playfab/community/leaderboards/doing-more-with-leaderboards)。

在我们当前的示例中，排名将是：

| 排名 | 实体 ID          | 分数  | LastUpdated                |
| -- | -------------- | --- | -------------------------- |
| 1  | "player 3"     | 103 | "2024-08-27T20:24:36.738Z" |
| 2  | "player 2"     | 102 | "2024-08-27T20:24:29.251Z" |
| 3  | **"player 1"** | 100 | "2024-08-27T19:52:26.642Z" |
| 4  | **"player 4"** | 100 | "2024-08-27T20:24:44.552Z" |

在此特定示例中，“player 1”和“player 4”的分数相同。谁先入榜取决于时间戳。由于“player 1”先达到该分数，因此这就是他排名在前的原因。

## 删除排行榜行

您的排行榜正按预期运行，并且游戏中有大量玩家。但是，您开始注意到一些异常行为，似乎有些玩家在作弊以到达排行榜的顶部。您不会容忍这种行为，因此您想将他们从排行榜中移除。在下一个示例中，您可以看到如何从排行榜中删除行。

```C# theme={null}

public static async Task DeleteLeaderboardEntries(PlayFabAuthenticationContext context, string leaderboardName, List<string> entityIds)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    DeleteLeaderboardEntriesRequest leaderboardsDelReq = new DeleteLeaderboardEntriesRequest() {
        Name = leaderboardName,
        EntityIds = entityIds
    };

    PlayFabResult<PlayFab.LeaderboardsModels.EmptyResponse> delLeaderboardDefResult = await leaderboardsAPI.DeleteLeaderboardEntriesAsync(leaderboardsDelReq);
}

```

现在，让我们解释此示例中的一些关键元素：

* `EntityIds`：此参数是您想要删除的实体 ID 列表。
* `Name`：此参数对应于您在创建排行榜定义时设置的排行榜名称。

## 结论

在本教程中，我们学习了如何执行以下操作：

* 创建排行榜。
* 检查排行榜的配置。
* 更新排行榜配置。
* 删除排行榜配置。
* 填充排行榜。
* 了解打破平局的工作原理。
* 删除排行榜中的条目。

## 另请参阅

* [排行榜的更多用法](/services/playfab/community/leaderboards/doing-more-with-leaderboards)。
* [限制](/services/playfab/community/leaderboards/limits-leaderboards)。
* [配额](/services/playfab/community/leaderboards/quota-leaderboards)。
* [赛季排行榜](/services/playfab/community/leaderboards/seasonal-leaderboards)。
* [根据统计信息为玩家排名](/services/playfab/community/leaderboards/leaderboards-linked-to-stats)。
* [向排行榜添加上下文数据](/services/playfab/community/leaderboards/metadata-leaderboards)。
* [组排行榜](/services/playfab/community/leaderboards/group-leaderboards)。
* [手动等级](/services/playfab/community/leaderboards/manual-tiers)。
* [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

- [组排行榜](/zh-CN/services/playfab/community/leaderboards/group-leaderboards.md)
- [API 排行榜参考](/zh-CN/services/playfab/community/leaderboards/api-reference.md)
- [使用 Azure Functions 的排行榜](/zh-CN/services/playfab/community/leaderboards/leaderboards-cloudscript.md)
- [排行榜的更多用法](/zh-CN/services/playfab/community/leaderboards/doing-more-with-leaderboards.md)
- [根据统计信息为玩家排名](/zh-CN/services/playfab/community/leaderboards/leaderboards-linked-to-stats.md)
