4 ms·
Just do everything with integers. RTS games of the 90's did it. They were able to sync 8 PCs across the world to run the same historical simulation (think Age o
by glouwbug 5y ago
Just do everything with integers. RTS games of the 90's did it. They were able to sync 8 PCs across the world to run the same historical simulation (think Age of Kings) by passing nothing more than mouse clicks and keyboard presses over peer to peer. Determinism is king in lockstep programming
- ChrisLomont 5y ago> Just do everything with integers. It gets cripplingly inefficient to do many calculations with integers. Simulating weather, or doing nearly any scientific calculation, using only integers would be a massively terrible idea. Same with neural networks (even though there is some work in that area), or a large part of signal processing, or medical work.... and on and on. >Determinism is king in lockstep programming Pretty much all modern games don't do lockstep because it's far too slow, messy, and error prone. It's much better to build a tolerant system that can handle missed frames, lags, and instead do predictive and catchup computing. Maybe use the right tool for the job, and learn new tools to access new jobs, is a better approach. Learning IEEE 754 nuances is a useful skill, and one can program many things by using this tool well that cannot be done efficiently or cleanly otherwise.
- gumby 5y agoOr if you need rationals, use fixed point (unfortunately not native in many languages)
- throwaway858 5y agoThere is a persistent myth that floating point is non-deterministic and therefore cannot be used for "lockstep" multiplayer games. This may have been true in the 90s because of buggy C compilers, but has long not been the case. you can use 32 bit or 64 bit floating point and your code will be completely determistic across all modern CPUs and operating systems and even across most programming languages. The only thing you need to avoid are trig functions (sin, cos) since different platforms have different implementations. so you use your own implementation for these functions(for games you can an approximation which will be even faster than the library implementation). many platforms have an identical sqrt function, but this should be thoroughly tested. Also if you are running on an intel CPU on 32 bit OS (rare nowadays) you need to call a function at the start of your program to disable 80 bit extended fp.
- protastus 5y ago> There is a persistent myth that floating point is non-deterministic and therefore cannot be used for "lockstep" multiplayer games. Indeed, on all systems I've used, FP is deterministic in the strict sense that running the same code twice on the same platform (with identical HW and SW stack) will produce the same results. But the results may change depending on: - programming language - libraries used and their versions - underlying silicon - whether SIMD is used - FPU flags - compiler flags (example: ffast-math affects many things behind the scenes, as does /fp:fast, including things that dramatically affect accuracy like the use of approximate reciprocal instructions) - bugs affecting all of the above At scale, this matrix becomes difficult to track and control. So it shouldn't be a surprise that reproducibility is an issue, and this myth persists.
- throwaway858 5y ago> But the results may change depending on: > - programming language As I mentioned in my comment, this is part of the myth. most programming languages have the exact same semantics regarding floating point and if you port an algorithm between them you will get identically deterministic results. this is true for at least c/c++, java, c#, python, javascript, and many more. - libraries used and their versions As I mentioned in my comment, this is the only true part of the myth. sqrt should be safe, but trig functions will be different. for games, a lot of them use there own "fast" versions anyway, so not a problem. - underlying silicon nothing to worry about here. All modern CPUs have identical IEE754 semantics (except intel 32 bit which I addressed in my original comment) - whether SIMD is used Again, nothing to worry about here, whether it is hand coded SIMD assembly, or compiler generated, you will always get identical and portable results. the compiler is obligated to ensure this for autogenerated SIMD. - FPU flags not relevant on any system from the last 10 years - compiler flags (example: ffast-math affects many things behind the scenes, as does /fp:fast, including things that dramatically affect accuracy like the use of approximate reciprocal instructions) ffast-math by definition introduces imprecise semantics so simply don't use it - bugs affecting all of the above compilers (and CPUs!) may have been buggy decades ago but in the modern age floating point is extensively tested. I would be very surprised to see a floating point related bug in a compiler or programming language from the last 10 years