Seb*_*iot 6 c++ cross-platform deterministic
我正在考虑用C++编写多用户RTS游戏(部分)的可行性.我很快发现,一个硬性要求是游戏模拟必须对服务器和所有客户端的最后一点完全确定,以便能够将网络通信限制为用户输入,而不是游戏状态本身.由于每个人都有不同的计算机,这似乎是一个难题.
那么,是否有一些"神奇"的方法让C++编译器创建一个可在Linux(服务器),Windows和Mac上完全确定的可执行文件?我认为两个主要的OSS C++编译器是GCC和Clang,所以我想知道在这方面一个是否比另一个表现更好.
我也对任何可用于验证C++确定性的测试套件感兴趣.
[编辑]通过确定性,我的意思是编译的程序,给定相同的初始状态,并以相同的顺序输入,将始终在其运行的任何平台上产生相同的输出.所以,也是整个网络.一致的声音对我来说是对这种行为的恰当定义,但我不是母语人士,所以我可能会误解其确切含义.
[编辑#2]虽然关于确定性/一致性是否重要,以及我是否应该在游戏引擎中实现这一目标的讨论,以及它在C++中通常存在多大问题,但是它非常有趣,它实际上并没有真正回答题.到目前为止,没有人告诉我是否应该使用Clang或GCC来获得最可靠/确定/一致的结果.
[编辑#3]我刚想到有一种方法可以在Java中获得与C++完全相同的结果.必须采用JVM的开源实现,并提取实现运算符和数学函数的代码.然后将其转换为独立库并在其中调用可内联函数,而不是直接使用运算符.手动完成会很痛苦,但如果生成代码,那么这是一个完美的解决方案.也许这甚至可以通过类和运算符重载来完成,所以它看起来也很自然.
由于每个人都有不同的计算机,这似乎是一个难题。
它不是。事实上,这种网络非常简单,只要你不做任何规范中未定义的事情即可。IEEE-754非常清楚如何进行浮点数学运算、如何进行舍入等,并且跨平台的实现方式相同。
您需要避免做的最重要的事情是在需要确定性的代码中依赖 SIMD CPU 指令(注意:这是物理、人工智能等:游戏状态。而不是图形,这是您需要 SIMD 的地方)。这些类型的指令与浮点规则一起快速而宽松地发挥作用。所以你的游戏代码中没有SIMD;仅在“客户端”代码(图形、声音等)中。
另外,您需要确保您的游戏状态不依赖于时间等因素;每个游戏状态时钟滴答应该是固定的时间间隔,而不是基于 PC 的时钟或任何类似性质的东西。
显然,您应该避免任何您没有代码的随机函数。但同样,仅适用于您的主要游戏循环;图形内容可以是特定于客户的,因为它只是视觉效果,并不重要。
就保持两个游戏状态同步而言,就这样了。您使用的编译器对您来说不会是一个大问题。
请注意,《星际争霸》和《星际争霸 II》使用此作为其网络模型的基础。它们都可以在 Mac 和 PC 上运行,并且都可以互相对战。所以这是很有可能的,并且不需要 Clang。
不过如果你喜欢 Clang,你应该使用它。但这应该是因为你喜欢它,而不是为了社交。