Quick answer: [BurstCompile(FloatMode = FloatMode.Strict, FloatPrecision = FloatPrecision.Standard)]. For real determinism, prefer fixed-point integer state.
Lockstep multiplayer sim. Same inputs, two clients diverge after 30 ticks. Burst’s default float mode reorders math; one CPU does an FMA, another doesn’t. Different bits.
The Symptom
Cross-play desync. Replays from one platform fail to reproduce on another. Hash-checks of physics state diverge after a handful of ticks.
The Fix
using Unity.Burst;
[BurstCompile(// strict cross-platform determinism
FloatMode = FloatMode.Strict,
FloatPrecision = FloatPrecision.Standard
)]
public struct SimulationStep : IJob {
public void Execute() {
// math here is portable
}
}
Strict mode disables FMA contraction, associativity reorder, and reciprocal-multiply substitutions. Slower — but every ISA produces identical bits.
Better: Fixed-Point
struct Fix64 { // 32.32 fixed-point
public long raw;
public static Fix64 operator +(Fix64 a, Fix64 b) =>
new Fix64 { raw = a.raw + b.raw };
// ... mul with shift, div with shift
}
Integer arithmetic is bit-identical across all CPUs Burst targets. Slightly more work to maintain but immune to float-mode regressions.
Verifying
Run the sim on Windows x64, ARM macOS, and IL2CPP-Android. Hash the state every tick. Hashes must match. With FloatMode.Fast: divergence within 100 ticks; with Strict or Fix64: matches to 100,000+.
“Strict mode for floats. Fixed-point for paranoia. Determinism holds.”
Related Issues
For Burst parallel batch size, see batch size. For IL2CPP reflection, see link.xml.
Strict floats. Or fixed-point. Sim agrees.