I've been designing a distributed procedural generation system for a while now in my spare time and one of the problem's I've been thinking about recently, with respect to the broader architecture, is that of floating point determinism inconsistency when you can't ensure that you have a homogeneous cluster of machines running a persistent world.
Part of my design requires that any given machine can regenerate procedural content as needed, allowing for unimportant but resource-hungry content to be destroyed and recreated as needed on whatever machine is available to do the work.
I have been running on the basic idea that I will use high-precision 32/64 bit integers for most things, and that generally works fine, but the standard coherent noise algorithms all use floating point values in their calculations.
- Do I need to implement custom non-floating-point versions of all those algorithms (i.e. using longs) or is there a better approach?
- Should I be using fixed-point types for this kind of thing, and if so, how does that impact my desire to have the option to offload some of the PCG work to the GPU, when possible? Also, are fixed point types fast enough for heavy use within a game engine?
- Can I ignore floating point precision issues if I can get away with a maximum level of precision? i.e. If I'm happy to use no more than, say, six decimal places of a result, does that keep me safe across different machines and architectures?
Note: my engine is purely the simulation side of things. It doesn't matter to me if there are slight rendering inconsistencies when a user is playing the game; all that matters is that the procedurally-generated source data is consistently regenerated no matter which machine in a cluster is doing the work.
x_fp16 = floor( x * 65536) / 65536
. But then you'll have to call such a function on each computation, which might be both slower and harder to code. \$\endgroup\$