【问题标题】:Mutli Player Game synchronization多人游戏同步
【发布时间】:2011-01-07 01:33:07
【问题描述】:

情况:

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

问题:

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

可能性?

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

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

【问题讨论】:

    标签: iphone synchronization multiplayer


    【解决方案1】:

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

    (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) 似乎适合您的问题。如果您还有其他问题或需要更多详细信息,请再次询问。

    【讨论】:

    • 游戏时钟的解释对我来说似乎很清楚。如果我理解正确,您基本上将服务器时间发送给客户端,以便客户端相应地调整它的游戏时间。如果这种情况发生在 BT 或本地网络上,则可以忽略同步消息从服务器到 lient 所需的时间。例如,如果服务器在时间 123 -> 将其发送到客户端 -> 客户端也可以将其自己的时间设置为 123(如果所有时间都发生在同一时间,则可以忽略接收服务器时间和更新自己时间之间的延迟方法)这样对吗?
    • 我剩下的问题是,这可以通过苹果的 GameCenter 工作吗?从苹果 GameCenter 的介绍中,我了解到他们有一个版本的 GKtank 比 GameCenter 更胜一筹。但是如果两个玩家之间的消息需要更长的时间,他们如何同步呢?游戏会暂停吗?再次感谢
    【解决方案2】:

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

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

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

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

    【讨论】:

    • ...不幸的是,使用刻度并不能消除同步的要求。即使是 GKTank&punchball 的两个示例也会同步它们的 2 个对象 - 如果没有同步调用,它们很容易不同步。但是缩放那里使用的方法在我的情况下不起作用,因为我有太多对象......
    【解决方案3】:

    有关更多详细信息,请查看此帖子:- Synchronization in multiplayer networked game?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多