Open
Conversation
be5677a to
a7e07c8
Compare
fa8b594 to
a0289f1
Compare
…ndency
Root cause of OOS in network games
-----------------------------------
IEEE 754 mandates bit-identical results only for the five basic operations
(+, -, *, /, sqrt). Transcendental functions (atan2, sin, cos, …) may
differ by 1-2 ULPs between libm implementations on Linux, macOS, and
Windows. The four streflop::atan2 calls in unit.cpp produced float values
that were written into logSynchData() checkpoints; even a 1-ULP difference
caused "Game out of synch" errors between cross-platform clients.
Fix: deterministic_math.h
--------------------------
New header source/shared_lib/include/platform/common/deterministic_math.h
provides deterministicAtan2Deg(float y, float x). It uses only IEEE 754
basic arithmetic (+, -, *, /) on doubles, so its output is bit-identical on
all conforming platforms. Algorithm:
1. Range-reduce |y|/|x| to t in [0, tan(pi/12)] using the identity
atan(x) = pi/6 + atan((x*sqrt(3)-1)/(sqrt(3)+x)) for x in (tan(pi/12),1]
atan(x) = pi/2 - atan(1/x) for x > 1
2. Evaluate atan(t) via a 6-term Taylor series.
Maximum error for |t| <= tan(pi/12): < 4e-11 rad (~5e-9 degrees),
well within the truncateDecimal(6) applied by callers.
3. Restore quadrant, convert to degrees in double, return as float.
unit.cpp: replace 4 atan2 call sites
--------------------------------------
calculateXZRotation() (terrain slope, lines ~953/964)
setTargetPos() (move command target, line ~1487) -- directly logged
updateTarget() (combat facing, line ~3926)
All four #ifdef USE_STREFLOP / streflop::atan2 / #else / atan2 / #endif
blocks are replaced with a single deterministicAtan2Deg() call.
radToDeg() is no longer needed; the new function returns degrees directly.
Other streflop uses: collapse trivial #ifdef blocks
-----------------------------------------------------
The remaining streflop uses (fabs in tileset.cpp / map.cpp, floor in
unit_updater.cpp / map.cpp) are inherently deterministic: fabs is a
single-bit operation and floor of sqrt (an IEEE 754 exact operation) of
integer inputs is deterministic. The #ifdef USE_STREFLOP blocks that
already had identical #else branches are collapsed to the standard-library
form, removing dead preprocessor noise.
CMakeLists.txt: disable streflop by default
--------------------------------------------
WANT_USE_STREFLOP default changed from ON to OFF. Streflop may still be
enabled explicitly, but is no longer required for multiplayer sync
correctness. The old "Out of synchs may occur" warning is replaced with a
note describing the deterministic replacement.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
streflop is no longer needed: the four atan2 calls that affected
sync-logged game state now use deterministicAtan2Deg() (previous
commit), and the remaining streflop uses (fabs, floor, sqrt) are
inherently deterministic under IEEE 754.
Source file cleanup
-------------------
Every #ifdef USE_STREFLOP / streflop:: / #else / stdlib / #endif block
is collapsed to the stdlib branch:
unit_updater.cpp - floor() for range checks
map_preview.cpp - sqrtf() distance, fabs() gradient
particle.cpp - fabsf/sinf/cosf/sqrtf/fmod/cos/sin/atan2
(all rendering-only, no sync impact)
vec.h - std::sqrt() in Vec2/Vec3::length()
main.cpp - remove STREFLOP mode/enabled log prints
math_wrapper.h - unconditional #include <cmath>
lua_script.cpp: remove Lua_STREFLOP_Wrapper class and all ~25
instances. The class toggled streflop precision around Lua calls to
avoid FPU state corruption; with streflop gone it is a no-op.
platform_main.h
---------------
- Remove --disable-streflop-checks CLI arg and GAME_ARG enum value
- Remove the SSE capability runtime check (was only needed to
validate streflop's SSE mode requirement)
- Remove streflop_init<streflop::Simple>() startup call
CMakeLists.txt
--------------
- Remove WANT_USE_STREFLOP and FORCE_STREFLOP_SOFTWRAPPER options
- Remove the STREFLOP_SSE/X87/SOFT detection and ADD_DEFINITIONS block
source/shared_lib/CMakeLists.txt
---------------------------------
- Remove pkg_search_module(STREFLOP …) discovery
- Remove ADD_SUBDIRECTORY(sources/streflop) and link step
- Remove ${STREFLOP_PROPERTIES} from compile flags
- Remove ${MG_STREFLOP} from Windows link libraries
Deleted files
-------------
source/shared_lib/sources/streflop/ (~70 .cpp files)
source/shared_lib/include/streflop/ (~20 .h files)
source/shared_lib/include/platform/common/streflop_cond.h
source/tests/shared_lib/streflop/ (OOS regression test)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
a0289f1 to
2d39a7c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.