# 排行榜最佳做法

**URL:** https://heroiclabs.com/docs/zh/nakama/concepts/leaderboards/best-practices/
**Summary:** 排行榜通常会增加游戏的竞争体验。Nakama 提供用于创建、计算和管理排行榜的数据模型和 API。了解这些功能的运作原理及其最佳实现方式。

---


# 排行榜最佳做法

排行榜通常会增加游戏的竞争体验。Nakama 提供用于创建、计算和管理排行榜的数据模型和 API。在本文中，您将了解：

- 排行榜生命周期
- Nakama 如何对排行榜和各个分数建模
- 如何用最佳做法发挥排行榜的最大作用

## 排行榜和您应使用它们的原因

Nakama 中的排行榜是实时分数排名。如果您可以用数量级表示分数，那么您可以将其放在排行榜上。排行榜可以跟踪越大越好的结果（例如获得的积分或收集的黄金和珠宝），或者越小越好的结果（例如使用的能量提升或经过的秒数）。

排行榜为您产生游戏的特色排行榜提供了一个基础。排行榜容易储存，重新计算速度快（因为有内存内缓存和排名），足够灵活因而可用于任何可排序积分榜。

## 排行榜生命周期

Nakama 从高层开始，通过分为三个部分的生命周期来处理排行榜和分数：

1. **开始。**在创建排行榜时，您为其选择一些规则，例如是否越高的分数越好，或者它是否按一个时间表重置。这些排行榜属性在创建时即已固定，在排行榜存续期内保持不变。

2. **分数。**开始玩游戏后，您的游戏就会向排行榜植入分数。每次记录分数时，Nakama 依据排行榜创建时设置的规则重新计算排名。

   您的应用程序可以使用 4 种方法记录分数：

   - `set` — 插入新分数
   - `best` — 在新分数比所有者先前的分数好的情况下，插入新分数
   - `incr` — 加到所有者先前的分数
   - `decr` — 从所有者先前的分数减去

   如果排行榜没有重置时间表，则其在此阶段无限继续。

3. **过期。**当排行榜达到其预定的重置时间时，Nakama 会触发回调并从排名中清除过期分数。

   对于为排行榜过期而注册的任何事件处理程序，过期会在迭代结束时触发排行榜状态的回调。例如，触发一个事件处理程序，奖励前五名完成者。

   同时，Nakama 从排行榜排名中清除过期分数。过期分数不会被删除，但是不会在排行榜的实时排名中计算这些分数。换言之，排名从生命周期分数阶段的开头重新开始。

## 对排行榜建模

接下来讨论 Nakama 实际上如何表示排行榜。Nakama 的排行榜分成两个部分记录：_排行榜_和许多_排行榜记录_。

### 排行榜

在创建_排行榜_时，您设定一些不变的属性来确定 Nakama 如何重新计算排名，是否让记录过期，以及向排行榜插入新分数的语义。

排行榜最重要的属性包括：

| 属性                 | 描述                                                                       | 示例                                        |
| ------------------------ | --------------------------------------------------------------------------------- | ---------------------------------------------- |
| ID                       | 排行榜唯一键值                                                  | weekly_best_lap_time                           |
| 权威状态     | 是否允许客户插入自己的分数                            | false                                          |
| 排序               | 分数的升序（越低越好）或降序（越高越好）排名 | asc                                            |
| 运算符                 | 分数插入语义，例如最新、个人最佳或添加      | 作为增量添加到前一分数              |
| 分数的最大数量 | 分数所有者可进入排名的次数                      | 3                                              |
| 重置时间表           | 让旧分数过期的类似于 cron 的时间表                                      | 59 23 * * 0，在每个星期天结束时重置 |
| JSONB 元数据           | 排行榜元数据                                                      | { "displayString": "Weekly Top Scores" }       |


从存储角度看，Nakama 将排行榜详细信息作为排行榜配置的权威、永久记录写入数据库。于此同时，Nakama 创建排行榜的内存内缓存，便于实时排序。

### 排行榜记录

_排行榜记录_捕捉添加到排行榜的各个分数。

排行榜记录最重要的属性包括：

| 属性       | 描述                                                | 示例                              |
| -------------- | ---------------------------------------------------------- | ------------------------------------ |
| 排行榜 ID | 分数关联的排行榜                       | weekly_best_lap_time                 |
| 所有者 ID       | 分数的所有者，例如用户或群组            | e4f8c28d-1680-4f35-8ccc-67910185d84e |
| 用户名       | 记录所有者的显示名称               | anon1234                             |
| 分数          | 整数分数                                    | 70（秒）                         |
| 子分数       | 打破平局的次级分数或部分分数              | 54（百分之一秒）          |
| 过期时间    | 条目超出排行榜排名的时间 | 2021-01-02T23:59:00                  |
| JSONB 元数据 | 分数元数据                                     | { "raining": false }                 |


与排行榜本身一样，排行榜记录驻留在两个地方：数据库，在其中为分数的规范记录；以及排行榜在 Nakama 内存内的表示，用于实时排序。

注意，分数本身的排名不属于存储模型。排名保留在内存中，用于快速重新计算和检索。

排行榜和排行榜记录一起实现快速查找、快速排名更新和整个集群的持久性和弹性。

## 最佳做法

既然您已基本了解 Nakama 的排行榜定义，那么请考虑在您的游戏中使用排行榜的这些最佳做法。

### 不只是对玩家使用所有者 ID

每条排行榜记录都有所有者。排行榜所有者的常见选择是表示单个玩家的所有者 ID。但这只是排行榜诸多可能的起点。

例如，您可以创建多个排行榜，在一个排行榜中记录一个玩家的表现，在另一个排行榜中记录该用户所在群组的集体分数，从而为个人和团队的努力提供实时排名。

### 用重置时间表重复排行榜

请勿忽视排行榜的过期时间表。您可能想要定期创建新的排行榜。在大多数情况下，Nakama 都可以提供帮助。

如果您重置排行榜而不是创建新排行榜，则客户端排行榜记帐将被简化。例如，客户端只需要知道每小时排行榜的 ID，而不需要知道各个最新每小时排行榜的 ID（以及相关联的所有时区和同步详细信息）。此外，管理控制台工具本身就能识别时间表，从而简化了排行榜所用数据的管理。

### 用分桶排行榜拆分大队列

大排行榜会不断变得更加静止和游离。随着您的用户的游戏技能和经验的增加，最佳分数会凝滞，很少出现奇迹般的改变。将排行榜划分为更小的队列——甚至是随机的用户子集——可以增加排名的周转率和参与度。

在某些情况下，可以制作全球排行榜的小切片，例如按用户的朋友筛选全球排行榜。但随着子集增大，计算排行榜子集的排名将需要很高的代价。

不如将大队列分成单独的排行榜，称作_分桶排行榜_。创建多个排行榜通常比筛选更大的排行榜更有利于提高性能。若要进一步了解分桶排行榜，请阅读[本主题指南](/docs/nakama/guides/concepts/bucketed-leaderboards/)。
