【问题标题】:Real-time multiplayer game (concept question)实时多人游戏(概念题)
【发布时间】:2010-09-28 06:02:30
【问题描述】:

我一直在阅读 Valve 的 this article,这似乎解释了他们的多人游戏系统的架构。似乎他们在客户端延迟渲染几个滴答,以便他们可以处理丢弃的数据包,但他们也将数据包作为“增量快照”(两个相邻状态之间的差异)发送。

假设我们有时间 A、B、C,并且客户端在时间 A 是正确的,但在 B 丢弃数据包,然后在 C 接收数据包。它如何正确推断时间 C 的状态? C 的数据包只告诉(我认为)状态 B 和 C 之间的增量,而客户端只知道 A 的状态。我在这里缺少什么?

【问题讨论】:

标签: networking compression real-time multiplayer


【解决方案1】:

增量不必与之前发送的消息相关(通过增量或快照)。相反,它们将与最后一个已确认状态相关。因此,在上面的示例中,C 处的更新可能是相对于 A 的增量。因此,随着增量变大(并且潜在的错误正在累积),丢失消息 B 会带来不便,但最终消息会通过并被确认,并且服务器可以开始发送相对于该更新状态的增量。

【讨论】:

    【解决方案2】:

    完整状态会定期同步或根据客户端请求同步。 Interpolation/extrapolation 可用于在等待完整位置更新时补偿丢包。某些事件需要可靠交付,并且可以添加确认接收的方法。

    Glenn Fiedler 在他的blog 上有一些关于网络游戏的excellent articles

    This old article about Quake 3 networking 听起来很相似。增量状态表示从收到的最后一个客户端确认状态的更改。因此,如果服务器发现客户端落后,则将根据客户端状态和当前服务器状态之间的差异创建下一个增量。

    【讨论】:

      【解决方案3】:

      如果不看实现,我会想象数据包 C 还包括数据包的 id,它是来自 delta 的数据包(在本例中为数据包 B)。

      当客户端收到包 A 之后的包 C 时,它会知道它还没有看到包 B,因此可以向服务器请求完整的更新。

      【讨论】:

      • 这不是假设 delta B 和 delta C 有相同的内容吗?
      • 数据包的 id 或序列号,或者其他一些简单的方法来跟踪数据包的顺序......
      • 嗯,通常数据包有一个时间戳和一个序列号。它使丢失数据包之间的精确插值成为可能。
      • 但是文章说,“......如果快照 [B] 由于丢包而丢失,插值甚至可以工作” - 这似乎表明它不需要完全更新一个丢失的数据包。
      • 是的。我确信增量会足够小,插值就可以了。它只是不太准确。他们可能还使用基于对象可能投影路径的预测算法来“合成”一个 B 位置进行插值。 Quake 3 在这方面做了很多工作。
      【解决方案4】:

      我猜他们每隔一段时间就会发送一个完整的快照。这就是为什么滞后游戏会导致人们在 delta 帧丢失时以错误的速度运行,然后在完整快照出现时“传送”到正确的位置。

      【讨论】:

        【解决方案5】:

        来自链接的文章:

        通常只有在游戏开始或客户端遭受严重数据包丢失几秒钟时才会发送完整(非增量)快照。客户端可以使用 cl_fullupdate 命令手动请求完整快照。

        【讨论】:

        • 是的,但这是在谈论“几秒钟的大量数据包丢失”。没有一个数据包丢失,它明确表明它可以从中恢复。
        【解决方案6】:

        服务器可能会定期但不那么频繁地发送完全同步(即不是增量)。至少我正在这样做。

        【讨论】:

          猜你喜欢
          • 2012-12-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-10
          • 2014-03-08
          • 2021-03-13
          相关资源
          最近更新 更多