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"
No comments:
Post a Comment