像星际争霸和帝国时代这样的实时战略游戏的协议是什么样子的?

44

我对这些类型的游戏的协议(和游戏循环)如何工作感兴趣;任何提示或见解都将受到赞赏。

我想主要循环会有一个世界状态,每秒钟会提前几个“ticks”,但是玩家的命令是如何执行的?需要交换哪种类型的数据?

3个回答

93
我可以详细地说明这一点,但首先,请阅读“1500名弓箭手”http://www.gamasutra.com/view/feature/3094/1500_archers_on_a_288_network_.php ,这将回答你很多问题。以下是摘要:
首先,由于游戏的实时性,大多数游戏使用UDP。游戏循环大致如下:
1. 读取网络数据 2. 进行客户端预测,并与网络告诉你的对象实际位置进行比较 3. 更改物理引擎,用本地游戏状态来伪造网络告诉你的内容 4. 基于此帧的操作(如果有)将数据发送回网络 5. 渲染
这只是极为简化的概括,“更改物理引擎”可能需要一本200页的书来解释。它涉及在客户端预测对象可能会出现的位置,从服务器获取旧数据,该数据确切地指示对象的位置/应该出现的位置,然后以某种方式插值这些值,使对象看起来“足够接近”其实际位置,以至于没有人注意到。这对于第一人称射击游戏非常关键,但对于实时策略游戏的影响不那么大。
对于实时策略游戏,通常会发生一种基于回合制的系统,其中时间被划分为称为“回合”的离散块,这些块按顺序依次发生,每个回合都有一个由单调函数生成的数字,该函数保证按特定顺序而无重复地增加值。在任何给定的第n个回合,每个客户端向所有其他客户端发送一个包含其在第n + m个回合上的预期动作的消息,其中m是一个任意数,通常很小,并且可以通过试错和玩测试来最佳确定。一旦所有客户端都发送了它们的预期操作,每个客户端就会执行在第n + m个回合上发送的所有操作。这引入了一个微小的延迟,即用户下达命令和执行命令之间的延迟,但通常不会被注意到。
还有几种技术可以用于伪造时间。例如,如果你选择一个单位并告诉它移动,它会在开始移动时发出声音并进行动画,但实际上不会立即移动。但是,移动那个单位的网络消息立即发送,因此当屏幕响应玩家输入时,网络消息已经被发送并得到确认。你还可以通过在鼠标单击和游戏对象响应之间引入短暂延迟(大约100毫秒)来进一步伪造它。这通常不会被玩家注意到,但在局域网游戏中,100毫秒是一个漫长的时间,即使在家用电脑上的宽带连接上,平均ping也可能在15-60毫秒左右,这给你足够的时间在移动之前发送数据包。
关于要发送的数据,游戏中有两种类型的数据:确定性数据和非确定性数据。确定性事件基于游戏物理学,并且当该动作开始时,可以100%保证可以预测该动作的结果,因此无需通过网络发送此类数据,因为可以根据初始状态在客户端上确定它将是什么。请注意,在每个客户端上使用相同的种子生成随机数可以将“随机”事件转换为确定性行为。 非确定性数据通常是用户输入,但在许多情况下可以预测用户的输入内容。在实时策略游戏中,这些数据成对出现,其中非确定性事件是针对我的游戏对象的某种命令。一旦已经命令游戏对象移动,其移动方式就是100%确定性的。因此,在网络上需要发送的仅是对象ID、给定的命令(将其作为枚举类型以节省带宽)以及命令的目标(如果有的话,例如一个法术可能没有目标,如果它是一个区域攻击,但移动命令则有一个终点)。如果用户点击了100次以使单位移动,则没必要为每次单独发送一个移动命令,因为它们都在同一大致区域内,因此务必过滤掉这些命令,否则将会占用大量带宽。
处理命令和执行之间可能存在的延迟的一种最终技巧是所谓的本地感知过滤器。如果我在命令给出之后的t时间内收到移动订单,则知道该单位应该何时开始移动以及其终点。与传送单位以使其到达目标位置不同,可以稍后启动其移动,然后通过改变物理参数略微加速其速度,以便它可以追上目标位置,然后减慢速度以将其放在正确的位置。需要加速的确切值也是相对的,只有通过游戏测试才能确定正确的值,因为它必须“感觉正确”才能正确。您还可以使用同样的方法来进行子弹和导弹发射,这对于这些事件非常有效。这种方法有效的原因是人类并不擅长看到运动中的微妙变化,特别是如果物体直接朝向他们或背向他们时,他们就不会注意到。
下一步需要考虑的是减少带宽使用。不要向无法看到或与移动单元交互的客户端发送消息。不要因为用户点击而反复发送相同的消息。不要立即发送对没有即时影响的事件的消息。最后,不要要求对于可能会过期的事件发送确认。如果我没有收到移动更新,当我重新传输该更新时,其价值将变得非常陈旧,因此最好只是发送另一个移动并使用本地感知过滤器来赶上或使用三次样条插值来插值移动,以使其看起来更正确或类似的内容。然而,像“你死了”或“你的旗帜被拿走了”这样关键的事件应该得到确认,并在需要时进行重新传输。我在Digipen教授网络游戏编程,所以随时可以问我其他问题,我可能能够为您提供答案。网络游戏编程可能非常复杂,但最终它都是关于在实现中做出选择并理解您选择的后果。

8
即使对我这样的非游戏玩家来说,这个东西也很有意思。+1 - JonnyD

3

看看《维斯诺之战》吧。

http://www.wesnoth.org/

它是免费、开源的,非常棒。你可以从挖掘它的源代码中学到很多东西。


2
它似乎是回合制的,所以我不确定那会有多大帮助。 不过我会去看看的,谢谢! - JOrik

3
讨论帝国时代网络架构在这里 个人认为,那种基于点对点复制回放的架构令人印象深刻,但超过8名玩家的游戏会遇到一些瓶颈。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接