Floating Point Determinism

I’m making a network RTS game, loosely following the Age of Empires network model. ( 1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond ). Basically this means that I send commands over the network, then each computer receives the commands and performs a simultaneous simulation.

In order for this type of system to work, I have to guarantee that each computer runs the simulation exactly the same as the others. Lately I’ve been reading up on floating point determinism, and it seems that what I’m trying to do may be a tall order for Unity/C#.

I wrote a small plugin that sets the floating point precision control and rounding control registers via a call to the _controlfp_s function. ( http://msdn.microsoft.com/en-us/library/c9676k6h(VS.80).aspx )

From what I’ve read, that should make the basic floating point operations deterministic across platforms. But what about the transcendental functions like sin and cos? Is there a way I can guarantee that those operations will be equal on different machines, all the way down to the last bit of precision? Also, what about Unity colliders? If two colliders intersect on one machine, does that guarantee that they intersect on all machines? (assuming I place them consistently across all machines of course)

Thanks in advance for your ideas.

ChrisH, I have exactly the same problem and you are many steps ahead of me. Please tell me if your plugin worked.
Did you find answers for your - very convenient - questions?

Based on what Elijah from Gas Powered Games said on this article:

,I’m afraid that setting the FPU, besides all other problems, may not work.

Is there any follow up on this?

Hey ChrisH. Unfortunately, you’re barking up an impossible tree. You cannot guarantee deterministic floating point math on a software level - it’s just a consequence of hardware. Even setting _controlfp_s variables aren’t a guarantee, although they can help in some scenarios. Unity Physics is non-deterministic. If you want deterministic physics simulations, you need to simulate on the server and send that information to the client.

The easiest solution, I think, is to just not use floating points in your simulation. That’s not to say you can’t use it in your whole game logic! I would look at interpolation for things like unit movement, or using very small cell sizes for your integer coordinates. But for the actual simulation, stick with integer math.

The alternative - trickier, but you get to keep all your fancy floating points - is to simulate and interpolate. This is a networking model things like multiplayer FPSs use. While you do simulate on the client, it’s not a trusted simulation. The server runs the cardinal simulation, and occasionally tells the client about the state of the system. The client then corrects their simulation so the two are back in sync if they ever got out of sync. Pros - much more secure, and follows the golden rule of “never trust a client”. Cons - more bandwidth intensive, more complex code (although all the problems have been solved years ago).

Just use ints instead of floats. Problem solved.

these might be useful

This thread is super old.

Holy crap yeah it is lmao
well… helped me, i wouldntve searched and found

looks pretty sweet

Oh snap, I did not see that! Sorry to assist in rezzing this.