我一直在阅读 Valve 的这篇文章,它似乎解释了他们的多人游戏系统的架构。 看起来它们在客户端上延迟了几个刻度,以便它们可以处理丢弃的数据包,但它们也将数据包作为“增量快照”(两个相邻状态之间的差异)发送。
假设有时间A、B、C,客户端在A时间是正确的,但在B时间丢包,然后在C时间收到数据包,那么它如何正确推断出C时间的状态呢? C 处的数据包仅告诉(我认为)状态 B 和 C 之间的增量,而客户端只知道 A 处的状态。我在这里缺少什么?
I've been reading this article from Valve that seems to explain the architecture of their multiplayer system. It seems they delay rendering by a couple ticks on the client so they can handle dropped packets, but they also send packets as "delta snapshots" (the difference between two adjacent states).
Suppose we have times A, B, C, and the client is correct at time A but drops the packet at B, and then receives the one at C. How can it correctly deduce the state at time C? The packet at C only tells (I think) the delta between states B and C, and the client only knows the state at A. What am I missing here?
发布评论
评论(6)
增量不必与之前发送的消息(通过增量或快照)相关。 相反,它们将与最后一个确认状态相关。 因此,在上面的示例中,C 处的更新可能是相对于 A 的增量。因此,随着增量变大(并且潜在的错误正在累积),丢失消息 B 会变得不便,但最终消息将通过并被确认,并且服务器可以开始发送相对于更新状态的增量。
The deltas don't have to be relative to the previous message that was sent (by delta or snapshot). Instead, they would be relative to the last acknowledged state. So in the example above, the update at C could be a delta relative to A. Losing message B therefore becomes an inconvenience as the deltas are getting larger (and potentially error is accumulating) but eventually a message will get through and be acknowledged, and the server can start sending deltas relative to that updated state.
定期或根据客户端请求同步完整状态。 插值/外推可用于补偿等待完整位置更新时的数据包丢失。 有些事件需要可靠的传递,并且可以添加确认接收的方法。
Glenn Fiedler 在他的博客。
这篇关于 Quake 3 网络的旧文章听起来很相似。 增量状态表示自上次收到的客户端确认状态以来的变化。 因此,如果服务器发现客户端落后,则将根据客户端状态和当前服务器状态之间的差异创建下一个增量。
The complete state is synchronized periodically or upon client request. Interpolation/extrapolation can be used to compensate for packet loss while waiting for a full position update. Some events require reliabe delivery and a means of acknowledging receipt could be added.
Glenn Fiedler has some excellent articles about networked games on his blog.
This old article about Quake 3 networking sounds similar. The delta states represent changes from the last client acknowledged state that was received. So, if the server sees that the client is behind then the next delta will be created from the difference between the client state and the current server state.
如果不看实现,我会想象数据包 C 还包含其增量数据包的 ID(在本例中为数据包 B)。
当客户端在数据包 A 之后收到数据包 C 时,它将知道它还没有看到数据包 B,因此可以向服务器请求完整更新。
Without looking at the implementation, I would imagine that packet C also includes the id of the packet it is the delta from (in this case, packet B).
When the client receives packet C following packet A, it will know that it hasn't seen packet B yet, and can consequently request a full update from the server.
我猜他们每隔一段时间就会发送一次完整的快照。 这就是为什么延迟游戏会导致人们在增量帧丢失时以错误的速度运行,然后在完整快照出现时“传送”到正确的位置。
I'm guessing every once in a while they send a full snapshot. this is why laggy games involve people running at the wrong speed as delta frames are dropped, then "teleporting" to the correct position when a full snapshot comes in.
来自链接的文章:
From the linked article:
服务器可能会定期但不太频繁地发送完全同步(即不是增量)。 至少我正在这么做。
The server probably sends fully syncs (ie not deltas) periodically but less frequently. That's what I'm doing, at least.