Initial commit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shweetandClaude Opus 5.5 committed 2026-11-08 01:30:33 -05:00
commit 2007fb7edc
200 files changed
+27710

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
#!/usr/bin/env bash
# Checks the simulation is deterministic across builds and platforms, which desktop/web crossplay depends on.
#
# Fails if any source calls the maths library's transcendentals (src/dmath.h replaces them), then builds the game
# several ways and plays the same seeded bot matches in each (--balance with RPG_SEED), comparing the determinism hash
# they print:
# gcc GCC, optimised (the usual build)
# gcc-fma GCC for this CPU (with FMA if it has it, standing in for arm64's fused multiply-adds)
# clang-O0 Clang, unoptimised
# wasm Emscripten, run under node (needs EMSDK, or emsdk_env.sh sourced)
#
# Usage: tools/determinism_check.sh [matches per seed, default 20] [seeds, default "1 2 3"]
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT="$ROOT/build-check"
MATCHES="${1:-20}"
SEEDS="${2:-1 2 3}"
banned=$(grep -nE "std::(sin|cos|tan|atan2|atan|asin|acos|exp|exp2|expm1|log|log2|log10|log1p|pow|hypot|cbrt|sinh|cosh|tanh|lerp)\(|\b(sinf|cosf|tanf|atan2f|powf|expf|logf|log2f)\(|SDL_(sin|cos|tan|atan2|atan|pow|exp|log)f?\(" \
"$ROOT"/src/*.cpp "$ROOT"/src/*.h | grep -v "src/dmath.h" || true)
if [ -n "$banned" ]; then
echo "Maths library transcendentals in the source (use math_sin and friends from src/dmath.h):"
echo "$banned"
exit 1
fi
configure() # name, cmake arguments...
{
local name="$1"
shift
if [ ! -f "$OUT/$name/build.ninja" ]; then
cmake -S "$ROOT" -B "$OUT/$name" -G Ninja "$@" > "$OUT/$name.log" 2>&1
fi
cmake --build "$OUT/$name" >> "$OUT/$name.log" 2>&1 || {
echo "$name failed to build, see $OUT/$name.log"
exit 1
}
}
mkdir -p "$OUT"
names=(gcc gcc-fma clang-O0)
configure gcc -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
configure gcc-fma -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ \
-DCMAKE_CXX_FLAGS=-march=native -DCMAKE_C_FLAGS=-march=native
configure clang-O0 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
if [ -n "${EMSDK:-}" ] || command -v emcmake > /dev/null; then
[ -n "${EMSDK:-}" ] && source "$EMSDK/emsdk_env.sh" > /dev/null 2>&1
if [ ! -f "$OUT/wasm/build.ninja" ]; then
emcmake cmake -S "$ROOT" -B "$OUT/wasm" -G Ninja -DCMAKE_BUILD_TYPE=Release -DRPG_NODE=ON > "$OUT/wasm.log" 2>&1
fi
cmake --build "$OUT/wasm" >> "$OUT/wasm.log" 2>&1 || {
echo "wasm failed to build, see $OUT/wasm.log"
exit 1
}
names+=(wasm)
else
echo "Emscripten not found (set EMSDK): skipping the wasm build."
fi
hash_get() # name, seed
{
local run=("$OUT/$1/smack-a-brother")
[ "$1" = wasm ] && run=(node "$OUT/wasm/smack-a-brother.js")
(cd "$OUT/$1" && RPG_SEED="$2" "${run[@]}" --balance "$MATCHES" 2>&1 | grep -oE "hash: [0-9a-f]+" | cut -d' ' -f2)
}
failed=0
for seed in $SEEDS; do
line="seed $seed:"
first=""
for name in "${names[@]}"; do
hash=$(hash_get "$name" "$seed")
line+=" $name $hash"
[ -z "$first" ] && first="$hash"
[ "$hash" != "$first" ] && failed=1
done
echo "$line"
done
if [ "$failed" = 1 ]; then
echo "DESYNC: the builds disagree."
exit 1
fi
echo "Deterministic: every build agrees."