During online multiplayer games involving Linux or Windows client, we observe frequent desyncs that are unrecoverable.
Error: [DESYNC WARNING] checksum x from demo player 1 (x) does not match our checksum x for frame-number x As those desyncs are also present in replay and always in the same frame, they are consistent and reproducible. On each state update (frame), variables changed are fed into a hash. Then, on a regular basis, the server checks that all hashes are equal, which means all engines are synced and have the same state of the game (unit position, life, movement, ...). The game engine is based on floats. Using -msse helps make some progress as the first desync happens later in the same replay, but this isn't enough. Comparing dumpstate between OpenBSD and Linux, we manage to find the first difference at a specific frame, which involves CGroundMoveType/nextWayPoint (path calculation stuff in float). Units could be in different positions, and both games could be totally different then. We also notice inconsistent initSeed and gameID over different tests on the same replay, which looks like it also depends on -fp* compilation flags, but that's only a guess atm. Until this is sorted out, we need to disable online multiplayer. The following diff ensures there is no server address defined in the config, then starts the game. This allows playing BAR, but only offline. You could still download maps, but you will not be able to login and play online. The menu needs a server address defined in its configuration. Otherwise, it will crash. By setting an empty address, the menu is not able to resolve and just displays a warning in the console. [liblobby] Error: Error in connect: No address associated with name Maybe someone who better understands all the FP math and differences between gcc, clang, Linux and OpenBSD could fix it, but this engine deviation from upstream looks tricky to fix. On Linux, both gcc with all the specific args that cmake brings and clang without those args equally work. Maybe there are some flags I'm missing or misusing (I tried many), maybe there is another hidden bug unrelated to FP. At this stage, I have some homework to do before even thinking this could be related to OpenBSD ieee/sse/*** (all that stuff I don't know). Note also that spring depends on STREFLOP_SSE (https://nicolas.brodu.net/en/programmation/streflop/) and should only use that lib in order to keep engine state consistent across machines. Index: Makefile =================================================================== RCS file: /cvs/ports/games/recoil-rts/Makefile,v diff -u -p -r1.8 Makefile --- Makefile 14 Jul 2024 13:51:51 -0000 1.8 +++ Makefile 30 Jul 2024 18:41:06 -0000 @@ -13,7 +13,7 @@ MN = 1.1 BLD = 2511 HASH = g747f18b V = ${MJ}.${MN}pl${BLD} -REVISION = 0 +REVISION = 1 # ${IN_ENGINE_V} is what recoil uses/displays internally IN_ENGINE_V = "${MJ}.${MN}-${BLD}-${HASH} BAR${MJ}" Index: files/beyond-all-reason =================================================================== RCS file: /cvs/ports/games/recoil-rts/files/beyond-all-reason,v diff -u -p -r1.1 beyond-all-reason --- files/beyond-all-reason 14 Jul 2024 13:51:51 -0000 1.1 +++ files/beyond-all-reason 30 Jul 2024 18:41:06 -0000 @@ -2,6 +2,7 @@ GAME_DIR=~/.local/state/BAR CONFIG_FILE=${GAME_DIR}/chobby_config.json +CONFIG_LUA=${GAME_DIR}/LuaMenu/Config/IGL_data.lua SETTINGS_FILE=${GAME_DIR}/springsettings.cfg DATASIZE="8388608" # 8G @@ -17,12 +18,17 @@ if [ $(ulimit -Sd) -lt ${DATASIZE} ]; th [ $? -eq 0 ] || exit fi +# remove previous config to ensure game run offline +grep -qs "server4.beyondallreason.info" ${CONFIG_LUA} && \ + rm -f ${CONFIG_FILE} && \ + sed -i "/serverAddress/d" ${CONFIG_LUA} + # setup [[ -d ${GAME_DIR} ]] || mkdir -p ${GAME_DIR} [[ -f ${CONFIG_FILE} ]] || cat > ${CONFIG_FILE} <<EOF { "server": { - "address": "server4.beyondallreason.info", + "address": "", "port": 8200, "protocol": "spring", "serverName": "BAR"