Skip to content

feat(math): Route game logic math through WWMath with 3-mode deterministic support#2670

Open
Okladnoj wants to merge 4 commits intoTheSuperHackers:mainfrom
Okladnoj:okji/feat/deterministic-math-v2
Open

feat(math): Route game logic math through WWMath with 3-mode deterministic support#2670
Okladnoj wants to merge 4 commits intoTheSuperHackers:mainfrom
Okladnoj:okji/feat/deterministic-math-v2

Conversation

@Okladnoj
Copy link
Copy Markdown

@Okladnoj Okladnoj commented May 1, 2026

Rework of #2602, incorporating review feedback:

  • GameMath via FetchContent (per @stephanmeesters, @OmniBlade recommendation)
  • Trig.cpp preserved, redirected to WWMath instead of deleted (per @xezon request for standalone change)
  • 3 math modes: VC6 (x87 inline asm), CRT (standard library), GameMath deterministic (per @Mauller recommendation)
  • USE_DETERMINISTIC_MATH unconditional for non-VC6 — missing gmath.h is now a compile error instead of silent fallback to x87/CRT
  • Clean history from main

CI: win32 + vc6 ✅, replay checks ✅

Open question: Replay checks pass both with and without USE_DETERMINISTIC_MATH, even though golden replays were recorded with an x87 build. The replays may not contain MSG_LOGIC_CRC messages, meaning the check only validates absence of crashes rather than game state CRC parity. If anyone has insight on this — please share.

Integrate GameMath library (fdlibm) for bit-perfect cross-platform
floating-point reproducibility. When USE_DETERMINISTIC_MATH is active,
all WWMath functions (Sin, Cos, Sqrt, Inv_Sqrt, Float_To_Long, Acos,
Asin, Atan, Atan2) use fdlibm instead of x87 asm or system CRT.

- Add GameMath via FetchContent with global include paths
- Replace Trig.cpp with inline WWMath::*Trig wrappers
- Add WWMath::*Origin wrappers for bare CRT calls in game logic
- Prioritize USE_DETERMINISTIC_MATH over _MSC_VER/_M_IX86 guards
- Verified: win32 replay CRC matches original x87 output
Add global Sqrt(double) to trig.h/Trig.cpp, routing through
WWMath::SqrtOrigin(). Replace 5 bare CRT sqrt() calls in BaseType.h
(Coord2D::length, Coord2D::toAngle, ICoord2D::length,
Coord3D::length, ICoord3D::length) with the new Sqrt() gateway.

This closes the last known CRT math leak in CRC-critical code paths.
Same pattern as existing Sin/Cos/ACos routing via Trig.cpp.
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 1, 2026

Greptile Summary

This PR routes all game-logic math calls through WWMath with three modes: VC6 x87 inline assembly (unchanged), CRT standard library (non-deterministic fallback), and GameMath deterministic (default for all non-VC6 builds). The change is a large but mostly mechanical replacement of raw sqrt/fabs/atan2/sinf etc. calls with WWMath::*Origin and WWMath::*Trig wrappers across 84 files in both Generals/ and GeneralsMD/, with GameMath pulled via FetchContent at a pinned commit.

Confidence Score: 4/5

Safe to merge after verifying the global include_directories concern; the mechanical call-site changes are consistently applied and CI passes.

No P0 findings. One P2 style issue (global include_directories CMake anti-pattern) is present; prior-thread P1 items (USE_DETERMINISTIC_MATH/gmath.h decoupling, double-to-float narrowing, incomplete CRC routing) are already noted and partially addressed. The mass call-site migration is consistent and correct.

cmake/gamemath.cmake (global include_directories), Core/Libraries/Source/WWVegas/WWMath/wwmath.h (USE_DETERMINISTIC_MATH/gmath.h coupling and double wrappers, per prior threads)

Important Files Changed

Filename Overview
Core/Libraries/Source/WWVegas/WWMath/wwmath.h Core of the PR: adds USE_DETERMINISTIC_MATH block and ~80 new Origin/Trig inline wrappers over GameMath gm_* functions; USE_DETERMINISTIC_MATH is defined unconditionally for non-VC6 regardless of whether gmath.h was found (discussed in prior threads), and double overloads silently narrow to float before calling gm_*f (also in prior threads).
cmake/gamemath.cmake New CMake module: fetches GameMath at a pinned commit, disables intrinsics/tests with FORCE overrides, and adds a global include_directories for gmath.h — a CMake anti-pattern that could cause silent link failures in targets that include wwmath.h without linking gamemath.
Core/GameEngine/Source/Common/Diagnostic/SimulationMathCrc.cpp Math CRC fingerprint updated to use WWMath Origin wrappers; remaining raw CRT calls (tanf/asinf/acosf) replaced with deterministic equivalents per prior thread; sinhf/coshf/tanhf/logf wrappers now go through GameMath equivalents.
Core/Libraries/Include/Lib/BaseType.h sqrt → Sqrt migration in Coord2D/Coord3D/ICoord2D/ICoord3D length() methods; changes are mechanical and correct.
Core/Libraries/Include/Lib/trig.h Adds double Sqrt(double x) declaration to the global trig helper header; consistent with the new Trig.cpp implementation that routes through WWMath::SqrtOrigin.
Core/Libraries/Source/WWVegas/WWMath/CMakeLists.txt Links gamemath as a PUBLIC dependency of core_wwmath for non-VC6 builds, ensuring transitive propagation to downstream targets.
Generals/Code/GameEngine/Source/Common/System/Trig.cpp All five trig functions redirected to WWMath::*Trig wrappers; new double Sqrt(double) added that routes through SqrtOrigin.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp Comprehensive routing of fabs/sqrtf/atan2/fabsf calls to WWMath Origin wrappers in physics simulation — mechanical and consistent.
CMakeLists.txt Includes gamemath.cmake for non-VC6 builds via a conditional include block; minimal and correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Math call site\ne.g. sqrtf / fabs / atan2] --> B{Compiler target?}
    B -- VC6\n_MSC_VER < 1300 --> C[x87 inline ASM\noriginal WWMath]
    B -- Non-VC6 --> D{USE_DETERMINISTIC_MATH\nalways defined}
    D -- gmath.h found\nvia global include_dirs --> E[GameMath gm_*f\ncross-platform deterministic]
    D -- gmath.h NOT found\nlinker error --> F[Link failure\nunresolved gm_* symbols]
    E --> G[WWMath::*Origin / *Trig\ninline wrappers in wwmath.h]
    G --> H[Game logic\nsimulation result]
    C --> H
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
cmake/gamemath.cmake:14-16
**Global `include_directories` pollutes all target include paths**

`include_directories()` is a directory-scope CMake command that injects `${gamemath_SOURCE_DIR}/include` into every target compiled under this directory. Combined with `USE_DETERMINISTIC_MATH` being unconditionally defined on non-VC6, any target that transitively includes `wwmath.h` but does **not** link `core_wwmath` (or `gamemath` directly) will compile cleanly (because `gmath.h` is now found globally) but fail at link time with unresolved `gm_*` symbols. The comment acknowledges the intent, but the modern CMake idiom — `target_include_directories(core_wwmath PUBLIC ${gamemath_SOURCE_DIR}/include)` — achieves the same ODR-safe propagation to all downstream consumers of `core_wwmath` without silently affecting unrelated targets.

Reviews (3): Last reviewed commit: "fix(math): Restore original formatting a..." | Re-trigger Greptile

Comment thread Generals/Code/GameEngine/Source/Common/System/Trig.cpp Outdated
Comment thread Core/GameEngine/Source/Common/Diagnostic/SimulationMathCrc.cpp Outdated
Comment thread Core/Libraries/Source/WWVegas/WWMath/wwmath.h
Comment thread Core/Libraries/Source/WWVegas/WWMath/wwmath.h
@Okladnoj
Copy link
Copy Markdown
Author

Okladnoj commented May 1, 2026

image Here is what replay playback looks like at the moment.

I’m testing this on a separate branch:
https://github.com/Okladnoj/GeneralsGameCode/okji/test/deterministic-math-v2

I slightly adjusted the CI there so I can run Win32 and get access to the game resources.

@Okladnoj Okladnoj force-pushed the okji/feat/deterministic-math-v2 branch from 854cc7b to 779f714 Compare May 1, 2026 00:49
@Skyaero42
Copy link
Copy Markdown

You did not review the changes you made with AI. It has issues that you should fix before asking it to be reviewed.

…erage

- Restore original Trig.cpp code (author comments, defines, REGENERATE_TRIG_TABLES)
- Keep only functional changes: sinf->WWMath::SinTrig redirects + Sqrt(double)
- Restore original tab alignment in wwmath.h #define block
- Route remaining CRT calls in SimulationMathCrc through WWMath (sinh/cosh/tanh/logf)
- Add cmake comments explaining FORCE usage
Copy link
Copy Markdown
Author

@Okladnoj Okladnoj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviwed all changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants