7

情况:

我想问在使用 BT 或网络服务器的多人 1:1 游戏中同步对象的最佳逻辑是什么。游戏有两个玩家,每个人都有多把枪和子弹,子弹是动态创建的,一段时间后会消失,玩家同时移动物体。

问题:

我对同步有一个真正的问题,因为一个设备上的子弹可能比另一个设备上的子弹更快,而且它们可能已经在一个设备上消失或击中了一个物体,而在另一个设备上它仍然在空中。

可能性?

在这种情况下处理同步的最佳方法是什么?是否所有对象都由一个充当服务器的设备控制,而另一个只是获取值、位置并且很少思考。或者应该将控制分布在每个设备创建、销毁和移动自己的对象的位置,然后通过同步告诉另一个设备。

处理传输延迟的最佳方法是什么,因为 BT 可能比通过网络播放更快?最好的将是一个工作样本 - 非常感谢!

4

3 回答 3

10

您似乎已经开始提出一些关于同步的好主意,但是您遇到的两个问题可能会重叠:游戏时钟的同步和游戏状态的同步。

(1) 同步游戏时钟,您需要为您的游戏提供一些“游戏时间”的表示。对于一个 2 人游戏,简单地声明一个人是非常合理的。

等等权威客户端:

OnUpdate()
  gameTime = GetClockTime();
  msg.gameTime = gameTime
  SendGameTimeMessage(msg);

在另一个客户端上可能是这样的:

OnReceivGameTimeeMessage(msg)
 lastGameTimeFromNetwork = msg.gameTime;
 lastClockTimeOfGameTimeMessage = GetClockTime();

OnUpdate()
 gameTime = lastGameTimeFromNetwork + GetClockTime() - lastClockTimeOfGameTimeMessage;

有一些复杂的问题,比如跳过/滑动(即从网络上获取时间,向前/向后太多)需要进一步的工作,但希望你能明白这一点。如果需要,请跟进另一个问题。

注意:此示例不区分“滴答声”与“秒”,也不与您的网络协议或运行游戏的设备类型相关(保存“设备具有本地时钟”的要求)。

(2) 同步游戏状态 在你有一个一致的游戏时钟之后,你仍然需要弄清楚如何一致地模拟和传播你的游戏状态。对于同步游戏状态,您有几个选择:

异步

  • 每个游戏状态单元都由一个进程“拥有”。只有那个过程被允许改变那个游戏状态。这些更改会传播到所有其他进程。
  • 如果一切都归一个进程所有,这通常被称为“客户端/服务器”游戏。
  • 请注意,使用此模型,每个客户端在任何时候都有不同的游戏世界视图。
  • 示例游戏:地震、魔兽世界

为了优化带宽和隐藏延迟,您通常可以对更新频率较高的字段进行一些本地模拟。例子:

drawPosition = lastSyncPostion + (currentTime - lastSyncTime) * lastSyncVelocity

当然,在这种情况下,您必须将新信息与您的模拟版本进行协调。

同步

  • 每个游戏状态单元在所有过程中都是相同的。
  • 来自每个进程的命令以其所需的启动时间(将来的某个时间)相互传播。
  • 在最简单的形式中,一个进程(通常称为主机)发送特殊消息,指示何时提前游戏时间。当每个人都收到该消息时,他们被允许模拟游戏直到那时。
  • “未来”的要求导致输入命令和游戏状态变化之间的高延迟。
  • 在像文明这样的非实时游戏中,这很好。在星际争霸这样的游戏中,通常会立即确认输入的声音,但实际影响游戏状态的动作会延迟。这种风格不适合需要时间敏感动作(约 100 毫秒规模)的射击游戏。

与重新模拟同步

  • 每个游戏状态单元在所有过程中都是相同的。
  • 每个进程向所有其他进程发送其输入及其当前时间戳。另外会定期发送“什么都没发生”消息。
  • 每个进程都有 2 个游戏状态副本。
  • 游戏状态的副本 1 被传播到它从所有其他客户端收到的“最后一条最早的消息”。这相当于同步模型,但有一个弱点,它代表了“一点点以前”的游戏状态
  • 游戏状态的副本 2 是副本 1 加上所有剩余的消息。它是对客户端当前时间的游戏状态的预测,假设没有新的事情发生。
  • 玩家与两种游戏状态的某种组合进行交互(理想情况下是 100% 副本 2,但必须考虑避免在新消息出现时弹出)
  • 示例游戏:街头霸王 4(网络游戏)

根据您的描述,选项(1)和(3)似乎适合您的问题。如果您还有其他问题或需要更多详细信息,请再次询问。

于 2011-01-07T19:59:57.443 回答
1

因为一台设备上的子弹可能比其他设备更快

如果游戏的架构正确,则不应发生这种情况。

如今,大多数游戏(尤其是多人游戏)都在滴答声上工作——小时间片。每个系统在计算滴答期间发生的事情时都应该得到完全相同的结果 - 没有“子弹在一台机器上移动得比在另一台机器上移动得更快”。

然后确保每个系统为每个玩家获得相同的输入(您需要将每个玩家的输入广播给其他玩家,以及输入在其中注册的滴答声),并确保每个系统以相同的速率计算刻度。

于 2011-01-07T01:44:26.053 回答
0

有关更多详细信息,请查看此帖子:- 多人网络游戏中的同步?

于 2011-05-12T05:51:30.180 回答