“星际争霸”和“帝国时代”等即时战略游戏的协议是怎样的呢?
我感兴趣的是这些游戏的协议(和游戏循环)是如何工作的; 任何指针或见解都被赞赏。
我猜测主循环会有一个每秒提前几个“滴答”的世界状态,但是玩家的命令是如何执行的呢? 什么样的数据需要来回?
我可以进入很多细节,但首先阅读“1500弓箭手” http://www.gamasutra.com/view/feature/3094/1500_archers_on_a_288_network_.php ,这将回答你的许多问题。 下面是一个总结:首先,由于游戏的实时性,大多数游戏使用UDP。 游戏循环看起来像这样:
- 读取networking数据
- 做客户端的预测,并与networking上的对象进行比较
- 与物理混乱欺骗networking说你的本地游戏状态是什么
- 基于你做了这个帧(如果有的话)发送数据到networking上,
- 给予
这是非常简单的,“搞乱物理”可以很容易地成为一个200页的书本身,但它涉及预测客户端的东西很可能是从服务器获取旧的数据,但确切地告诉对象是/应该在哪里然后以某种方式插入这些值,使对象看上去“足够接近”,实际上应该是没有人注意到的。 这对于第一人称射击游戏来说是超级重要的,但对于实时战略来说并不那么重要。
对于实时策略,通常发生的是基于回合的系统,其中时间被划分为依次发生的被称为“回合”的离散块,并且每一回转具有由单调函数产生的数字,该单调函数保证以特定顺序不断增加的值重复。 在任何给定的转弯n上,每个客户在转弯n + m时以其预期行动向所有其他客户发送消息,其中m是通常相当小的任意数字,并且可以通过反复试验和testing来最好地确定。 一旦所有的客户端发送了他们预期的动作,每个客户端执行在n + m轮发送的所有动作。 这引起了一个小小的延迟,当一个行动是由用户命令和执行时,但是这通常是不明显的。
有几种技术可以用来哄骗时间。 例如,如果您将一个单位竖起来,然后让它移动,它会发出声音,并在开始移动时有一个animation,但不会立即移动。 但是,当屏幕响应播放器的input时,立即发送意图移动该单元的networking消息,networking消息已经被发送并被确认。 通过在鼠标点击和游戏对象的响应之间引入一个小的延迟(100ms左右),可以进一步调整它。 这通常不是由玩家通知的,但100ms在LAN游戏中是永恒的,甚至在家庭计算机上的宽带连接平均ping可能大约在15-60ms左右,这给你充足的时间在发送数据包之前此举。
至于要发送的数据,游戏中有两种types的数据:确定性和非确定性。 确定性的行动是基于游戏物理的,所以当行动开始的时候,我有100%的保证,可以预测行动的结果。 这个数据不需要通过networking发送,因为我可以根据初始状态来确定客户端上的内容。 请注意,在每个客户机上使用具有相同种子的随机数生成器会将“随机”事件转化为确定性行为。 非确定性数据通常是用户input,但是可以在很多情况下预测用户input的可能性。 在实时策略游戏中,这些配对的方式是,非确定性事件对我的一个游戏对象是某种顺序。 一旦游戏对象被命令移动,其移动的方式是100%确定性的。 因此,你需要在networking上发送的只是对象的ID,给出的命令(把它作为一个枚举来节省带宽)以及命令的目标(如果有的话,那么一个咒语可能没有目标,如果它是一个但是移动命令具有结束目的地)。 如果用户点击100次以使单位移动,则不需要为每次点击发送单独的移动命令,因为它们都在相同的一般区域中,所以一定要过滤掉,因为它会杀死你带宽。
处理命令与其执行之间可能延迟的最后一个技巧就是所谓的本地感知filter。 如果在订单发出之后的一段时间内我收到一个移动订单,我知道该单元应该何时开始移动,而且我知道它的结束目的地。 我可以不用传送单位把它放到应有的位置,而是可以晚点开始运动,然后用物理学来加速它,以便能够赶上它应该在的位置,然后慢慢地回到原来的位置把它放在正确的地方。 你需要加速的确切数值也是相对的,玩游戏testing是唯一确定正确数值的方法,因为它只是为了“正确”才能正确。 你也可以用发射子弹和导弹来做同样的事情,对此非常有效。 这样做的原因是,人类看到运动中的细微变化并不是很好,特别是如果一个物体直接朝向它们或远离它们,所以它们就不会注意到。
接下来要考虑的是减less带宽。 请勿将消息发送给无法看到或与正在移动的设备交互的客户端。 不要一次又一次地发送相同的消息,因为用户点击。 不要立即发送消息来处理没有直接影响的事件。 最后,不要求承认事件,如果它们不被接收,将会失效。 如果我没有得到移动更新,那么当我重新发送更新时,它的值将会过时,不再相关,所以最好只发送另一个移动,并使用本地感知filter来追赶或使用一个三次样条插值运动,使其看起来更加正确或者是某种性质。 但是,如果需要的话,应该确认并重新发送一个至关重要的事件,例如“你已经死了”或“你的旗子已经被采取了”。 我在Digipen教networking游戏编程,所以随时问任何其他的问题,因为我可以给你一个答案。 networking游戏编程可能相当复杂,但最终都是在实施过程中做出select,并理解您select的后果。
这里讨论帝国时代的networking架构
恕我直言,这种基于点对点复制重播架构的风格令人印象深刻,但对于超过8名玩家的任何东西来说,这是一个死路一条。