# 群组最佳实践

**URL:** https://heroiclabs.com/docs/zh/nakama/concepts/groups/best-practices/
**Summary:** 群组是游戏中社交互动的基本组成部分，它让用户有机会与其他用户和游戏建立更紧密的联系。为支持游戏中的群组玩法，Nakama提供了一个核心群组系统，该系统包括一个数据模型和多个API。

---


# 群组最佳实践

群组（有时称为“家族”）是游戏中社交互动的基本组成部分。用户聚集到一起时，有机会与其他用户和游戏建立更紧密的联系。为支持游戏中的群组玩法，Nakama提供了一个核心群组系统，该系统包括一个数据模型和多个API。

继续阅读以了解：

- Nakama如何为群组及群组成员建模
- Nakama如何高效存储数据
- 开发人员如何使用群组构建游戏

## 使用群组

Nakama的群组系统没有硬性规定。群组可以用来表示具有多种形状、规模和特征的社区，例如家族、公会、团队和派别。

群组是许多用户的集合，但群组的用途由您决定。无论您的目标是什么，都可以使用群组系统记录成员资格、关系状态和相关的元数据。

## 群组建模

在Nakama中，群组由两部分组成：群组本身，群组与用户的联系，称为_群组边缘_。

_群组_表示整个群组的详细信息，例如：

- 群组对新成员开放还是关闭
- 群组原始创建者的ID（无论该创建者目前的成员资格如何）。
- 群组最大成员数（默认为100）
- 自定义元数据

_群组边缘_表示群组与用户之间的关系。Nakama基于概念为这些关系创建了有向图。与有向图中的边缘一样，群组边缘表示用户和群组之间的连接。因为每个边缘都有方向，所以群组成员资格是成对表示的：从用户到群组的边缘，以及从群组到用户的边缘。

![有向图显示了从群组指向用户的边缘和从用户指向群组的边缘](images/graph.png)

用户与群组开始新的关系时，Nakama会创建成对的群组边缘。该系统不会表现空值的关系。

另外，每个边缘都会记录关系状态：

- 请求成为成员（或请求待接受，由您决定）
- 接受成为成员
- 作为管理员或超级管理员的成员
- 被封禁

从新的群组成功创建开始，群组和群组边缘也随之存在。Nakama用以下方式表示新组的存在：

- 群组本身
- 从群组到群组创建者（群组的首位超级管理员）的边缘
- 从创建者到群组的边缘

如果这听起来很熟悉，那么您可能了解[Nakama表示好友关系的方式](../../friends/best-practices/)。和好友一样，群组的建模支持游戏所需的最常见的群组关系，同时又有足够的灵活性处理游戏的独特特点。

群组模型的另一个优点：高效地存储和查询。

## 存储和扩展群组

在数据库中，Nakama使用简洁的群组和群组边缘表示。这种表示方法经过调整，可以快速、高效、可扩展地完成常见任务，例如查询群组的所有成员或一位用户所在的所有群组。

群组的架构使用的主键包括：

- 设置的群组到期时间 (`disable_time`)
- 语言 (`lang_tag`)
- 与群组关联的边缘的数量 (`edge_count`)
- 唯一的ID (`id`)

这个主键确保同一语言的大型活跃群组被物理紧密存储到一起。这加快了查找用户要加入的合适群组的最常见查询。此外，Nakama索引了成员编号和上次更新时间，以加快对最大规模群组和最近活跃群组的查询。

对于群组边缘，主键包括：

- 用户或群组ID
- 目标ID
- 关系的状态，例如待接受的成员请求或管理员成员资格
- 计数器

这个主键可以确保一个用户的群组成员资格紧密存储到一起，并针对成员资格的类型和时期进行连续存储。由于用户和群组之间关系的两个方向都被存储为单独的行，因此群组的所有成员都会根据成员资格的类型和时期紧密存储到一起。

每个群组都有这些记录。创建新组时，开始时至少有三条数据库行，每个行用于：

- 群组本身
- 从群组到创建者的边缘
- 从创建者到群组的边缘

它是您建立特定于应用程序的社交关系的基础。

## 与群组一起开发

Nakama的群组系统旨在支持您和您的用户进行广泛的社交活动。遵循这些最佳实践，充分利用群组功能。

### 默认值并非一成不变

默认将群组限制在100个成员以内 (`max_count`),但这不是硬编码限制。通常，您不仅可以在总体上增加或减少最大用户数，还可以按群组增加或减少用户数。

这意味着您可以针对不同的目的设立不同规模的群组。例如，您可以为代表联盟的群组增加`max_count`用户数，为代表单个团队或队列的群组减少`max_count`用户数。您甚至可以动态更改特定群组的规模限制。例如，您可能奖励完成了一项具有挑战性任务的群组，将其用户数`max_count`加一。

### 使用元数据将新功能分层

在Nakama中，即使群组的实施似乎很简单，但可以从群组入手开发有趣、有能力完成的社交互动。与建立您自己的群组系统相比，您可以使用JSONB`metadata`字段更快地开发复杂的群组功能。思考几个示例：可见性和权限。

如果没有额外的元数据，群组只有一个二进制隐私设置：对新成员开放和对新成员关闭。然而，如果有额外的元数据，您可以添加更细微的隐私项。例如，如果您向您的元数据中添加单个布尔`visibility`字段，那么您可以进行更广泛的群组隐私设置：

<table style="text-align: center">
  <tr>
    <td rowspan="2" colspan="2"></td>
    <td colspan="2">
      <code>visibility</code>
    </td>
  </tr>
  <tr>
    <td>Visible (<code>true</code>)</td>
    <td>Invisible (<code>false</code>)</td>
  </tr>
  <tr>
    <td rowspan="2">
      <code>state</code>
    </td>
    <td style="text-align: right">Open (<code>0</code>)</td>
    <td><strong>Public drop-in groups</strong></td>
    <td><strong>Join-by-secret-link groups</strong></td>
  </tr>
  <tr>
    <td style="text-align: right">Closed (<code>1</code>)</td>
    <td><strong>Invite-only groups</strong></td>
    <td><strong>Private groups</strong></td>
  </tr>
</table>

与可见性一样，您可能想向群组添加另一个层面，即角色或特权。Nakama默认为群组成员设置一套粗略的角色：超级管理员、管理员和成员。但这并非全部。

通过将元数据与服务器运行代码配对，您可以自由地扩大角色和权限的范围。您可以使用元数据创建等级、特权成员（如版主），或向群组成员授予细微的权限，而不管其是超级管理员、管理员还是成员。在幕后，您的服务器运行代码可以使用特殊的nil ID代表群组执行操作，从而根据用户权限触发操作。

例如，您的群组元数据可能为用户设置_保镖_角色，使用户可以接受新成员或踢出（驱逐）群组中已有的成员。这个角色的群组`metadata`可能是这样的：

```json
{
  "roles": {
    "2c0c8e80-fcbc-4b61-901a-dace129f45f5": ["bouncer"],
    "000d8152-3258-457b-905b-05a9223c5c8c": ["bouncer"],
    "b5f5d399-340c-460a-a29a-3720c711a82f": []
  }
}
```

使用此元数据，您可以构建用于管理群组成员的用户界面，该界面仅向具有保镖角色的用户显示。在服务器上，您可以在某些事件--添加或踢出群组用户事件--之前注册自定义行为，只有在由保镖发起这些行为时才会完成这些行为（即， `roles[userId].includes('bouncer')` 为true）。

`metadata`字段并非事后添加的，它是用Nakama提供的支撑架构建游戏的关键部分。

### 使用Nakama的其他系统构建群组

您不仅可以用群组`metadata`字段扩展群组，还可以将群组链接到Nakama的其他系统。

Nakama的一些系统以明确定义的方式与群组协作，例如仅在群组中进行[聊天](../../chat/)对话。Nakama可以根据群组的成员资格确定哪些用户可以参与群组聊天。

但是有很多机会可以使用Nakama的其他系统和您的游戏系统构建群组。示例如下：

- [排行榜](../../leaderboards/)记录拥有所有者ID。这通常是一个用户ID，但您可以用群组ID来代替，从而对团队或派别的结果进行排名。
- 可以使用当前在线的群组成员子集构建[实时派对](../../parties/)。
- [配对](../../multiplayer/matchmaker/)属性可以包含任意字段。您可以将用户的群组ID作为配对属性提交，并使用偏好匹配包含共同群组成员的查询。

不要让群组系统成为孤岛。它是游戏中群组互动的开始而不是结束。

## 延伸阅读

请在[_Pirate Panic_](../../../tutorials/unity/pirate-panic/)教程的[_家族_](../../../tutorials/unity/pirate-panic/clans/)部分查看真实游戏中的群组。
