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

标签 networking multiplayer

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

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

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

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

我希望我已经说清楚了。

最佳答案

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

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

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

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

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

关于networking - 立即将输入发送到服务器或在网络游戏中定期发送输入缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28017244/

相关文章:

networking - Linux LXD 容器无法从 DHCP Ubuntu 16.04 TLS 获取 IP

javascript - 通过 Firefox 扩展检查网络连接

algorithm - 返回 N 窗口大小

c# - uNet 独立的客户端/服务器

iphone - 如何使用 GameKit 在 iPhone 蓝牙中区分主机和客户端

java - 无法打开 LibGDX 游戏的第二个实例?

c# - Tcp套接字突然关闭连接

linux - PPP 持久连接(3G 网络在 pppd 上自动重新连接)

java - MMO如何处理真人游戏的每一刻为成千上万的玩家计算和发送数据包?

multiplayer - 如何使用 firebase 向特殊在线用户发送警报消息