Jahni asked the right question: does the same seed produce identical results
across OS builds today? Checking the other toolchain made the answer sharper and
worse than what C9 originally said.
ClangToolChain.cs (Linux, Mac, Windows-with-Clang):
case FPSemanticsMode.Default: // Default to precise FP semantics.
case FPSemanticsMode.Precise: Arguments.Add("-ffp-contract=off");
and VCToolChain forces Precise when Windows uses Clang. So the same
FPSemanticsMode.Default resolves to OPPOSITE float models per toolchain, and
Windows/MSVC is the only imprecise configuration in the engine's defaults. Two
builds of identical source are not merely permitted to diverge -- they are
compiled under different rules.
Also added, so the entry does not over-fear itself:
- Calibration: 0 of 20000 samples crossed the isosurface under a 1-ULP
perturbation, so divergence means occasional single-voxel surface differences,
not different terrain. The case that bites is topological (a cave pinch-point
connecting on one build and not the other), which is rare and unreproducible --
the expensive kind.
- Precise everywhere still would not guarantee cross-platform bit-identity:
FMath::Sin/Cos route to platform libm, which is not bit-standardised. It closes
the large gap, not every gap.
- The knob would ALIGN Windows with every other platform rather than being a
one-sided cost -- but still must not be turned speculatively.
- The claim is inferred, not measured. The cheap decisive test is one Windows
build with FPSemantics = Precise: if MazeEquivalence's 454-sample residue
vanishes, the FP model is confirmed as the sole cause.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The bisect settled it. The difference survives every stage removal down to
"corridors + carve ONLY", which is character-for-character transcribed code, so
it is not in anything the decomposition added.
Cause, read out of the engine rather than assumed (VCToolChain.cs):
case FPSemanticsMode.Default: // Default is imprecise FP semantics.
case FPSemanticsMode.Imprecise: Arguments.Add("/fp:fast"); break;
with UBT's own doc: "the compiler is allowed to transform math expressions in
ways that might result in differently rounded results". Identical source in two
translation units may reassociate differently, worth ~1 ULP. It shows up on
exactly the ~2% of samples inside the SDF blend shell, where Blend - Sdf
catastrophically cancels; outside it Carve is exactly 0 or 1 and both agree.
So MazeEquivalence now grades what it can actually assert:
- hard fail : any isosurface crossing (geometry moves)
- info : differences at ULP scale (the unavoidable floor)
- warn : anything larger, which IS port drift, and runs the bisect
A test that warns on every port would get ignored by the port that matters.
Recorded in OPSTACK-PLAN 2.6, and as AUDIT C9 for the part that outlives this
refactor: ARCHITECTURE 9.1's "every peer regenerates identically" holds only
between bit-identical binaries under /fp:fast. Fine for one build on one
platform; a real desync source for a Linux server plus Windows clients both
regenerating authoritative geometry. The FPSemantics::Precise knob exists but
must not be turned speculatively -- it blocks the vectorisation T2.a was chasing,
on the hot loop, for an unmeasured cost.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AUDIT P1: every markdown design doc except CODEMAP.md was untracked, so
ARCHITECTURE / AUDIT / OPSTACK-PLAN / fable-idea / REVIEW_FINDINGS lived
only on disk. Replaces the single !CODEMAP.md exception with !*.md.
Also makes OPSTACK-PROGRESS.md commits actually record something, which
the unattended crash-safety discipline depends on.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>