客户端中继多人游戏

借助实时多人游戏引擎,用户可以方便地设置和加入比赛,他们可以在其中与对手快速交换数据。这种中继多人游戏(也称为客户端权威)模式适用于许多游戏类型,例如简单的 1 对 1 或合作游戏,其中服务器上的权威控制并不重要(例如欺骗无关紧要)。

在中继多人游戏中,无论消息大小或内容如何,Nakama 都能促进数据交换。通过比赛传送的任何数据立即转发给请求比赛对手的客户端。Nakama 维护的仅有比赛数据比赛 ID 和此比赛中状态的列表

发往其他连接客户端的客户端消息由服务器转发,而不进行检查。由于 Nakama 不跟踪中继多人游戏比赛中转发的数据量或内容,因此没有欺骗检测、错误纠正或其他此类功能。此方法依赖每个比赛中的某个客户端(由客户端自己决定)充当主机。此主机将协调对等机之间的状态更改,并对从不良客户端发送的不明确或恶意消息执行仲裁。

任何用户都可以参加与其他用户的比赛,但无法对比赛的访问进行密码保护或以其他方式加以限制。对于比赛中的玩家数量没有明确限制,只有游戏设计(消息大小和频率)和可用资源(服务器硬件和网络能力)施加的实际限制。

用户可从客户端发送消息,创建加入退出比赛。

比赛始终停留在服务器上,直到最后一个参与者离开。它们保存在内存内,无法永远存在。

创建比赛 #

任何用户可调用“比赛创建”操作,创建新的比赛。在创建比赛时,创建者无法提供比赛状态。

服务器将向新比赛分配唯一 ID。可将此 ID 分享给其他用户,让他们加入比赛

在创建新比赛时,用户可以选择提供 name。此名称用于生成比赛 ID,这意味着两名创建同名比赛的玩家将得到相同的比赛 ID,结果处于同一场比赛中。

用户可以随时退出比赛,所有其他用户将得到通知。所有用户都离开后,比赛将不再存在。

加入比赛 #

用户可用特定比赛的 ID 加入其中。无法用密码保护或关闭比赛。如果用户有比赛 ID,则他们能够加入其中。用户可随时加入比赛,直到最后一名参与者退出。

在加入比赛时,将在成功回调中返回一个比赛对手列表。记住此表可能并不包含所有用户,只包含_在那个时间点_连接到比赛的用户。

列出对手 #

当用户创建或加入一个新的比赛时,他们会接收到一个已连接对手的初始列表。在这个初始列表之后,服务器将事件推送到发生比赛加入和比赛退出的已连接客户端 – 如果状态列表没有发生变化,则不发送服务器更新。为了提高效率,对事件进行批处理,这意味着任何事件都可以包含多次加入和/退出。

这些事件可用于更新连接对手的列表,以便您的玩家可以准确地看到所有比赛参与者。

记住列出对手的一些最佳做法:

  • 在加入或创建比赛_之前_注册客户端状态事件侦听器
  • 对于同一状态同时具有加入和退出的批处理的事件,对于列表中已存在的状态,先处理退出,然后再处理加入;对于列表中没有的状态,处理加入,然后再处理退出

发送数据消息 #

比赛中的用户可以发送数据消息,所有其他对手都会接收到这些消息。这些消息实时流式传输到目标客户端,可以包含任何二进制内容。Nakama 以接收顺序而不一定是发送顺序广播消息。

每条数据消息中的二进制内容应当尽量小,不超出最大传输单位 (MTU) 1500 字节数。通常使用的是 JSON,最好使用 Protocol BuffersFlatBuffers 等紧凑二进制格式。

在无法进一步减少消息大小和/或频率的情况下,最好优先发送更少的消息。例如,1 条每秒 1000 字节的消息优于 5 条每秒 200 字节消息。

为了将每条消息标识为特定的“命令”,它包含一个操作码以及有效负载。

默认情况下消息会广播到所有其他比赛状态,但用户可以选择指定所需的比赛参与者子集(即他们的好友、队友等)以独占方式接收消息。

操作码 #

操作码是发送的消息类型的数值标识符。操作码可以让用户在对消息解码之前了解消息的目的和内容。

可以将其用于定义游戏中属于某些用户操作的命令,例如:

  • 初始状态同步
  • 就绪状态
  • Ping / Pong
  • 游戏状态更新
  • 表情

有关示例实现,请参阅 Fish Game 教程

接收数据消息 #

服务器按照处理来自客户端的数据消息的顺序交付数据。客户端可以为传入的比赛数据消息添加回调。这应该在他们创建(或加入)和退出比赛之前完成。

退出比赛 #

用户可随时退出比赛。这可能通过客户端操作(退出比赛)自愿发生,也可能非自愿发生(例如因网络连接的原因),但在这两种情况下,都必须在游戏逻辑中进行适当的考虑和处理。

所有用户退出后,游戏结束。此时其 ID 失效,无法再次用于重新加入。

示例 #

比赛主机轮换 #

您必须确定如何从连接的客户端中选择比赛主机。最好的实现方式是不需要在比赛参与者之间进行任何“协商”,同时确保所有客户端都承认同一主机。

您可以通过对比赛状态进行决定性的排序,并根据任何所需的因素选择主机来实现这一点。在下面的示例中,我们对状态列表进行排序,并选择最低的索引会话 ID 作为主机:

Related Pages