在使用浮点运算的多人RTS游戏中保持同步

时间:2009-12-22 20:29:21

标签: c# network-programming floating-point multiplayer

我正在用C#编写2D空间RTS游戏。单人运动。现在我想添加一些多人游戏功能。我用google搜索它似乎只有一种方法可以让数千个单元在没有强大的网络连接的情况下连续移动:在每个玩家运行相同的模拟时,只通过网络发送命令。

现在有一个问题,整个引擎到处使用双打。浮点计算在很大程度上取决于编译器优化和cpu体系结构,因此很难保持同步。 它根本不是基于网格的,并且有一个简单的phisics引擎来移动太空船(太空船有冲动和角动量......)。所以重新编码整个东西以使用固定点将是非常麻烦的(但可能是唯一的解决方案)。

所以到目前为止我有两个选择:

  • 再见当前代码并使用整数从头开始重新启动
  • 只有在有足够带宽的情况下才能让局域网局域网拥有8个拥有数千个单位的玩家并在(几乎)每一帧中发送位置和方向... ...

所以我寻找更好的意见,(甚至是将代码迁移到定点而不会弄乱一切的提示......)

4 个答案:

答案 0 :(得分:2)

当然,您的所有客户端都将使用相同的二进制文件,因此编译器优化对同步问题没有影响。

此外,如果您只打算定位一个架构(或者至少只允许人们在相同的架构上互相对战),那么这也无所谓。

我在使用C#开发适用于iPhone和桌面的游戏时使用浮点完全相同,即使iPhone是ARM而桌面是x86,它们也会给出相同的结果。

只要确保游戏完全进行相同的计算,你就可以了。

如果所有其他方法都失败了,只需将游戏中float的所有实例替换为标准的定点算术类。这样,您可以100%确定您的计算在各种体系结构中是确定性的,尽管定点算术的性质可能会对您的游戏产生负面影响。

答案 1 :(得分:1)

我对此有点迟,但从游戏安全的角度来看,模拟应该只在服务器/主机上运行(即:不信任客户端,他们可能在作弊):

  1. 客户端应该只将他们的动作/命令发送到服务器(丢弃不良输入或将其限制在游戏限制内,因此客户说“我以10,000m / s的速度运行”会受到服务器说10米/秒)。

  2. 服务器/主持人只告诉客户其视野范围内发生的事情(即:0号坐标的玩家没有被告知两个AI在200,0时互相争斗,如果他只能在他/她周围看到半径50个单位。

  3. 这是节省带宽的第二部分 - 服务器/主机上的模拟可能需要管理数千个对象,但客户只需要知道自己视野内的100或200件事物。

    情况中唯一的皱纹是动态射击(子弹,导弹等),其范围可能大于客户的视野半径。服务器/主机告诉客户端它们的起源和初始轨迹/目标对象,然后客户端根据相同的规则模拟它们的路径,但是杀戮只在服务器/主机上的模拟中有效。

    序列化特定于客户端的世界状态并在传输之前压缩它也可能是一个巨大的胜利,特别是如果您的类属性仅在需要时公开。 (我通常会避免使用XML,但是我们通过序列化为XML并将其压缩而不是序列化为二进制格式并压缩它来显着提高一个应用程序中的压缩率。我怀疑使用的ASCII字符范围有限,YMMV。)

答案 2 :(得分:0)

一种常见的技术是让所有客户定期向其他客户描述其当前状态。

当两台计算机不同意对象的状态时,可能是由于浮点错误,游戏有一些规则来确定哪个是正确的,并且所有客户端都会调整以匹配它。

答案 3 :(得分:0)

你具体使用双打是什么?你能用十进制代替吗?

通常,服务器会存储所有玩家单位的状态(位置/位置/类型)。

当player1移动一个单位时 要么...移动的提示被发送到服务器 或者......更新后的状态被发送到服务器

当玩家客户端需要渲染场景时,服务器会发回所请求范围内所有单位位置的状态信息。