立即将输入发送到服务器或在网络游戏中定期发送输入缓存

Send inputs immediately to server or in an input cache periodically in network game

我正在编写一个网络多人游戏,其中所有影响游戏玩法的输入都被保存并作为队列中的事件处理,以便在给定一组事件的情况下重新生成所有操作。 例如:用户按下向左箭头按钮;然后将带有 "Press Left" 的事件添加到队列中,保存当前时间 t,然后使用固定时间步 http://gafferongames.com/game-physics/fix-your-timestep/.

执行

这些事件也被发送到服务器,该服务器定期将从客户端接收到的一组事件发送给所有其他客户端,比方说每 100 毫秒一次。该游戏是快节奏的多人游戏,因此使用实体插值,如下所述:http://www.gabrielgambetta.com/fpm3.html

将这些事件发送到服务器的最佳方式是什么?立即单独发送每个事件,或者在客户端上保存一个 "Event cache",并且在客户端上定期向服务器发送新事件列表是否有意义?我担心如果我立即发送事件,事件的同步可能会发生一些事情,或者它可能会因网络上过多的消息而以某种方式阻塞。

事件缓存的问题是我必须为所有内容添加额外的延迟,因为事件只会每 n 秒从客户端发送一次,然后每 n 秒从服务器再次发送一次。玩家从输入到执行的容忍延迟是多少?

我希望我已经说清楚了。

可接受的延迟实际上取决于游戏的类型。对于快节奏的游戏(例如 FPS),您希望延迟尽可能低,我认为在这种情况下,任何不立即的事情都是不可接受的。

您可能应该以固定的时间间隔向服务器发送更新,但如果可以的话将它们降低到,比方说,15-20 毫秒。在更新间隔之间,您将缓冲命令(事件)。我不知道它到底是什么类型的游戏,但可能最好在客户端计算对象状态(并立即显示)并将状态发送到服务器进行验证。例如,如果我们谈论玩家移动,您将发送当前坐标和速度矢量,服务器将检查提供的新坐标是否有效(是否有可能从前一点到达那里)。同时,您将在客户端中显示新坐标,并在服务器响应后根据需要更正它们。

对于以这些速率联网的最佳选择是 UDP。由于它是无连接的,因此您需要自己处理丢失或乱序的数据包。根据游戏的不同,您可以将命令分为必须可靠传输的命令和不需要可靠传输的命令。来自服务器的响应可以以更大的间隔发送(例如 100 毫秒)。回到玩家移动的例子,如果你每 15 毫秒发送一次你的坐标(让我们坐在 tt+1t+2)并且如果你在 t+1 丢弃数据包,你仍然可以从 tt+2 中插入 t+1 值(因为服务器将以 100 毫秒的间隔进行响应),以便可以不可靠地传输此类内容。但是如果玩家施放咒语,使用物品或类似的东西,您需要确保该消息到达服务器。

您对同步和数据包丢失的担忧是有道理的,但在这两种情况下这些事情都可能(并且会不时发生)。无论如何,我认为最好是丢弃一个包含一两个事件(更小的间隔)的数据包,而不是丢弃一个包含数十个事件的数据包。在大多数使用 QoS 的网络配置中,较小的数据包也不太可能被丢弃或延迟。此外,根据您发送到服务器的数据,所需的带宽量可能根本不会那么大。

这是一个比较宽泛的问题,所以这些只是一些需要考虑的事情。其中一些可能在您提供的 link 中有解释,您也可以阅读 this