#82 ROOT FIX: reconstruct the crash SELF-DAMAGE -- wall-grinding now hurts,
the knockdown storm self-limits, peers keep the limp
The 'peers see a limping mech skating' report decomposed into a wall-grind
KNOCKDOWN STORM: a gimped mech held against a blocking solid re-crashes each
time its gg cycle rebuilds speed (the gg ceiling is authentically the clip's
natural speed -- bhk1 ~14.9 u/s, ceiling+divisor @0x544/0x548, loader formula
byte-matched -- so iv2 ~222 >> the 40.0 threshold @0x4ab184), and every
type-5 KNOCKDOWN broadcast floors all peers' replicants into knockdown/trn
churn: gliding + leg-lifts = skating. Turning and crushable cars were
A/B-exonerated (grass circling: 198 replicant gimp entries, 17 crunches,
zero broadcasts).
What the binary has that the port lacked -- recovered from the EXPORT GAP by
raw disasm (scratchpad/night6/gap_4a9770.txt, @4aa89f-4aaab4) -- is the crash
branch's tail: fallDirection = worldToLocal(damageForce) (FUN_0040879c, M^T v,
un-normalized), fallScalar = -(fallDirection . localVelocity.linearMotion),
and a self-dispatched TakeDamageMessage{0x64, zone=-1, the engine-computed
collision Damage verbatim}. A wall crash COSTS ARMOR, so the grind degrades
the mech instead of looping forever. That dispatch was the long-standing
'DEFERRED' note in the response policy; now reconstructed.
Falsified en route (comments + KB corrected, do not revive): the stagger's
FUN_004a4c54(1)/(0x20) 'action-request flags' feed NO drive suppressor --
image-wide sweep + full gap disasm show word[this+0x18] is read only by the
net record emitter; the bmp clip applies NO root motion (adv=0 measured); the
'gimp cap 5.8' figure was the BACK-cycle stride printed under a misleading
label (now ggCapL/R; @0x52c has no binary consumer).
Verified (mp_gimpAB rigs): arena1 wall-grind now 4 bounded strikes, limper
dies of its crashes and respawns cleanly twice (START->RESET, no strand);
grass circling unchanged-clean (198 replicant gimp states, 0 knocks).
Rig: pid capture race fixed (a missed winpid left a stale node holding the
-net port -> null runs), per-config sweep added.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
19fe1e5fa2
commit
9c83a468db
@@ -25,6 +25,12 @@
|
||||
BT_ROOT=/c/git/bt411
|
||||
BT_EXE=$BT_ROOT/build/Release/btl4.exe
|
||||
|
||||
# PIDs THIS run launched. A blanket `taskkill /IM btl4.exe` at teardown kills
|
||||
# every game on the machine -- including a NEWER bench a previous wrapper's
|
||||
# sleep outlived. That silently shot down two live sessions, so each run now
|
||||
# tracks and kills only its own children.
|
||||
BT_PIDFILE=/tmp/bt_bench_pids.$$
|
||||
|
||||
# --- the exact env every shipped launcher sets -----------------------------
|
||||
bt_player_env () {
|
||||
export BT_PLATFORM=glass # unified build, desktop cockpit layer
|
||||
@@ -49,7 +55,13 @@ bt_launch () {
|
||||
local log="$1" egg="$2" aff="$3"; shift 3
|
||||
( bt_player_env
|
||||
export BT_LOG="$log" BT_AFFINITY="$aff"
|
||||
"$BT_EXE" -egg "$egg" "$@" & )
|
||||
"$BT_EXE" -egg "$egg" "$@" &
|
||||
# the winpid pseudo-file races process start -- poll briefly; a missed pid
|
||||
# here left a stale node holding the -net port and null-ran the next config
|
||||
for _i in 1 2 3 4 5; do
|
||||
[ -f /proc/$!/winpid ] && { cat /proc/$!/winpid >> "$BT_PIDFILE"; break; }
|
||||
sleep 0.3
|
||||
done )
|
||||
}
|
||||
|
||||
# --- an EXPERT copy of an egg (what players actually fly) ------------------
|
||||
@@ -68,3 +80,12 @@ bt_novice_egg () { # bt_novice_egg <src.egg> <dst.egg>
|
||||
sed 's/^experience=.*/experience=novice/' "$1" > "$2"
|
||||
echo "[bench] NOTE: novice egg $2 -- crits/heat/jams are GATED OFF (harness requirement)"
|
||||
}
|
||||
|
||||
# --- kill ONLY the nodes this run started --------------------------------
|
||||
bt_kill_ours () {
|
||||
[ -f "$BT_PIDFILE" ] || return 0
|
||||
while read -r pid; do
|
||||
[ -n "$pid" ] && taskkill //F //PID "$pid" > /dev/null 2>&1
|
||||
done < "$BT_PIDFILE"
|
||||
rm -f "$BT_PIDFILE"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
# #82 REPLICANT-LIMP A/B MATRIX: which factor breaks the peer's limp view --
|
||||
# TURNING (replicant trn-arming outprioritizes the gimp cycle at gimp speeds)
|
||||
# or TERRAIN (arena1 ground staggers -> type-5 knockdown broadcasts)?
|
||||
#
|
||||
# 4 configs x 2 nodes x ~3min, sequential:
|
||||
# g_straight grass, limper walks straight (the old mp_skate baseline)
|
||||
# g_circle grass, limper circles (run-6 shape)
|
||||
# a_straight arena1, limper walks straight
|
||||
# a_circle arena1, limper circles (run-13 shape = the user's repro)
|
||||
#
|
||||
# VERDICT per config, from logs alone (no eyes needed):
|
||||
# observer [animind] inst=1 states 22-27 -> replicant LIMPS (good)
|
||||
# observer trn(4)/knockdown(32) churn -> skating (bad)
|
||||
# observer type=5 rx count + limper [knock] rows -> the stagger factor
|
||||
set -x
|
||||
. /c/git/bt411/scratchpad/night6/bench_common.sh
|
||||
cd /c/git/bt411/content || exit 1
|
||||
|
||||
run_config () { # $1=tag $2=map $3=circle(0|1)
|
||||
local tag=$1 map=$2 circle=$3
|
||||
# headless rig only: a leftover node from the previous config holds the -net
|
||||
# port and null-runs this one -- sweep before every config
|
||||
taskkill //F //IM btl4.exe > /dev/null 2>&1
|
||||
sleep 2
|
||||
sed "s/^map=.*/map=$map/; s/^time=.*/time=day/; s/^experience=.*/experience=novice/" MP.EGG > AB.EGG
|
||||
rm -f ab_${tag}_obs.log ab_${tag}_limp.log
|
||||
# observer: static, replicant-diagnostics on
|
||||
BT_MP_LOG=1 BT_REPL_LOG=1 BT_AUDIO_SPATIAL=1 BT_SYNC_LOG=1 \
|
||||
bt_launch ab_${tag}_obs.log AB.EGG 0x0C -net 1601
|
||||
sleep 2
|
||||
# limper: symbolic leg gimp ~2s after alive; straight or circling
|
||||
if [ "$circle" = "1" ]; then
|
||||
BT_FORCE_TURN=0.45 \
|
||||
BT_MP_LOG=1 BT_DMG_LOG=1 BT_AUDIO_SPATIAL=1 BT_GROUND_LOG=1 \
|
||||
BT_SELF_DAMAGE=60 BT_SELF_DAMAGE_ZONE=leg BT_SELF_DAMAGE_TICKS=2 BT_SELF_DAMAGE_DELAY=2 \
|
||||
BT_AUTODRIVE=0.4 \
|
||||
bt_launch ab_${tag}_limp.log AB.EGG 0x03 -net 1501
|
||||
else
|
||||
BT_MP_LOG=1 BT_DMG_LOG=1 BT_AUDIO_SPATIAL=1 BT_GROUND_LOG=1 \
|
||||
BT_SELF_DAMAGE=60 BT_SELF_DAMAGE_ZONE=leg BT_SELF_DAMAGE_TICKS=2 BT_SELF_DAMAGE_DELAY=2 \
|
||||
BT_AUTODRIVE=0.4 \
|
||||
bt_launch ab_${tag}_limp.log AB.EGG 0x03 -net 1501
|
||||
fi
|
||||
sleep 4
|
||||
python ../tools/btconsole.py AB.EGG 127.0.0.1:1501 127.0.0.1:1601 &
|
||||
local PC=$!
|
||||
sleep 180
|
||||
kill $PC 2>/dev/null
|
||||
bt_kill_ours
|
||||
sleep 3
|
||||
}
|
||||
|
||||
run_config g_straight grass 0
|
||||
run_config g_circle grass 1
|
||||
run_config a_straight arena1 0
|
||||
run_config a_circle arena1 1
|
||||
rm -f AB.EGG
|
||||
|
||||
echo "=== A/B VERDICTS ==="
|
||||
for tag in g_straight g_circle a_straight a_circle; do
|
||||
obs=ab_${tag}_obs.log
|
||||
gimp=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=2[2-7] ')
|
||||
trn=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=4 ')
|
||||
kd=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=32 ')
|
||||
t5=$(grep -a '\[mrec-rx\]' $obs 2>/dev/null | grep -c 'type=5 ')
|
||||
knocks=$(grep -ac '\[knock\]' ab_${tag}_limp.log 2>/dev/null)
|
||||
gsim=$(grep -a '\[gimp-sim\]' ab_${tag}_limp.log 2>/dev/null | head -1)
|
||||
echo "VERDICT $tag: replicantGimp=$gimp trn=$trn knockdown=$kd type5rx=$t5 limperKnocks=$knocks ($gsim)"
|
||||
done
|
||||
echo "=== DONE ==="
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
# #82 REPLICANT-LIMP A/B MATRIX: which factor breaks the peer's limp view --
|
||||
# TURNING (replicant trn-arming outprioritizes the gimp cycle at gimp speeds)
|
||||
# or TERRAIN (arena1 ground staggers -> type-5 knockdown broadcasts)?
|
||||
#
|
||||
# 4 configs x 2 nodes x ~3min, sequential:
|
||||
# g_straight grass, limper walks straight (the old mp_skate baseline)
|
||||
# g_circle grass, limper circles (run-6 shape)
|
||||
# a_straight arena1, limper walks straight
|
||||
# a_circle arena1, limper circles (run-13 shape = the user's repro)
|
||||
#
|
||||
# VERDICT per config, from logs alone (no eyes needed):
|
||||
# observer [animind] inst=1 states 22-27 -> replicant LIMPS (good)
|
||||
# observer trn(4)/knockdown(32) churn -> skating (bad)
|
||||
# observer type=5 rx count + limper [knock] rows -> the stagger factor
|
||||
set -x
|
||||
. /c/git/bt411/scratchpad/night6/bench_common.sh
|
||||
cd /c/git/bt411/content || exit 1
|
||||
|
||||
run_config () { # $1=tag $2=map $3=circle(0|1)
|
||||
local tag=$1 map=$2 circle=$3
|
||||
# headless rig only: a leftover node from the previous config holds the -net
|
||||
# port and null-runs this one -- sweep before every config
|
||||
taskkill //F //IM btl4.exe > /dev/null 2>&1
|
||||
sleep 2
|
||||
sed "s/^map=.*/map=$map/; s/^time=.*/time=day/; s/^experience=.*/experience=novice/" MP.EGG > AB.EGG
|
||||
rm -f ab_${tag}_obs.log ab_${tag}_limp.log
|
||||
# observer: static, replicant-diagnostics on
|
||||
BT_MP_LOG=1 BT_REPL_LOG=1 BT_AUDIO_SPATIAL=1 BT_SYNC_LOG=1 \
|
||||
bt_launch ab_${tag}_obs.log AB.EGG 0x0C -net 1601
|
||||
sleep 2
|
||||
# limper: symbolic leg gimp ~2s after alive; straight or circling
|
||||
if [ "$circle" = "1" ]; then
|
||||
BT_FORCE_TURN=0.45 \
|
||||
BT_MP_LOG=1 BT_DMG_LOG=1 BT_AUDIO_SPATIAL=1 BT_GROUND_LOG=1 \
|
||||
BT_SELF_DAMAGE=60 BT_SELF_DAMAGE_ZONE=leg BT_SELF_DAMAGE_TICKS=2 BT_SELF_DAMAGE_DELAY=2 \
|
||||
BT_AUTODRIVE=0.4 \
|
||||
bt_launch ab_${tag}_limp.log AB.EGG 0x03 -net 1501
|
||||
else
|
||||
BT_MP_LOG=1 BT_DMG_LOG=1 BT_AUDIO_SPATIAL=1 BT_GROUND_LOG=1 \
|
||||
BT_SELF_DAMAGE=60 BT_SELF_DAMAGE_ZONE=leg BT_SELF_DAMAGE_TICKS=2 BT_SELF_DAMAGE_DELAY=2 \
|
||||
BT_AUTODRIVE=0.4 \
|
||||
bt_launch ab_${tag}_limp.log AB.EGG 0x03 -net 1501
|
||||
fi
|
||||
sleep 4
|
||||
python ../tools/btconsole.py AB.EGG 127.0.0.1:1501 127.0.0.1:1601 &
|
||||
local PC=$!
|
||||
sleep 180
|
||||
kill $PC 2>/dev/null
|
||||
bt_kill_ours
|
||||
sleep 3
|
||||
}
|
||||
|
||||
run_config a_circle arena1 1
|
||||
run_config g_circle grass 1
|
||||
rm -f AB.EGG
|
||||
|
||||
echo "=== A/B VERDICTS ==="
|
||||
for tag in a_circle g_circle; do
|
||||
obs=ab_${tag}_obs.log
|
||||
gimp=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=2[2-7] ')
|
||||
trn=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=4 ')
|
||||
kd=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=32 ')
|
||||
t5=$(grep -a '\[mrec-rx\]' $obs 2>/dev/null | grep -c 'type=5 ')
|
||||
knocks=$(grep -ac '\[knock\]' ab_${tag}_limp.log 2>/dev/null)
|
||||
gsim=$(grep -a '\[gimp-sim\]' ab_${tag}_limp.log 2>/dev/null | head -1)
|
||||
echo "VERDICT $tag: replicantGimp=$gimp trn=$trn knockdown=$kd type5rx=$t5 limperKnocks=$knocks ($gsim)"
|
||||
done
|
||||
echo "=== DONE ==="
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
# #82 REPLICANT-LIMP A/B MATRIX: which factor breaks the peer's limp view --
|
||||
# TURNING (replicant trn-arming outprioritizes the gimp cycle at gimp speeds)
|
||||
# or TERRAIN (arena1 ground staggers -> type-5 knockdown broadcasts)?
|
||||
#
|
||||
# 4 configs x 2 nodes x ~3min, sequential:
|
||||
# g_straight grass, limper walks straight (the old mp_skate baseline)
|
||||
# g_circle grass, limper circles (run-6 shape)
|
||||
# a_straight arena1, limper walks straight
|
||||
# a_circle arena1, limper circles (run-13 shape = the user's repro)
|
||||
#
|
||||
# VERDICT per config, from logs alone (no eyes needed):
|
||||
# observer [animind] inst=1 states 22-27 -> replicant LIMPS (good)
|
||||
# observer trn(4)/knockdown(32) churn -> skating (bad)
|
||||
# observer type=5 rx count + limper [knock] rows -> the stagger factor
|
||||
set -x
|
||||
. /c/git/bt411/scratchpad/night6/bench_common.sh
|
||||
cd /c/git/bt411/content || exit 1
|
||||
|
||||
run_config () { # $1=tag $2=map $3=circle(0|1)
|
||||
local tag=$1 map=$2 circle=$3
|
||||
# headless rig only: a leftover node from the previous config holds the -net
|
||||
# port and null-runs this one -- sweep before every config
|
||||
taskkill //F //IM btl4.exe > /dev/null 2>&1
|
||||
sleep 2
|
||||
sed "s/^map=.*/map=$map/; s/^time=.*/time=day/; s/^experience=.*/experience=novice/" MP.EGG > AB.EGG
|
||||
rm -f ab_${tag}_obs.log ab_${tag}_limp.log
|
||||
# observer: static, replicant-diagnostics on
|
||||
BT_MP_LOG=1 BT_REPL_LOG=1 BT_AUDIO_SPATIAL=1 BT_SYNC_LOG=1 \
|
||||
bt_launch ab_${tag}_obs.log AB.EGG 0x0C -net 1601
|
||||
sleep 2
|
||||
# limper: symbolic leg gimp ~2s after alive; straight or circling
|
||||
if [ "$circle" = "1" ]; then
|
||||
BT_FORCE_TURN=0.45 \
|
||||
BT_MP_LOG=1 BT_DMG_LOG=1 BT_AUDIO_SPATIAL=1 BT_GROUND_LOG=1 \
|
||||
BT_SELF_DAMAGE=60 BT_SELF_DAMAGE_ZONE=leg BT_SELF_DAMAGE_TICKS=2 BT_SELF_DAMAGE_DELAY=2 \
|
||||
BT_AUTODRIVE=0.4 \
|
||||
bt_launch ab_${tag}_limp.log AB.EGG 0x03 -net 1501
|
||||
else
|
||||
BT_MP_LOG=1 BT_DMG_LOG=1 BT_AUDIO_SPATIAL=1 BT_GROUND_LOG=1 \
|
||||
BT_SELF_DAMAGE=60 BT_SELF_DAMAGE_ZONE=leg BT_SELF_DAMAGE_TICKS=2 BT_SELF_DAMAGE_DELAY=2 \
|
||||
BT_AUTODRIVE=0.4 \
|
||||
bt_launch ab_${tag}_limp.log AB.EGG 0x03 -net 1501
|
||||
fi
|
||||
sleep 4
|
||||
python ../tools/btconsole.py AB.EGG 127.0.0.1:1501 127.0.0.1:1601 &
|
||||
local PC=$!
|
||||
sleep 180
|
||||
kill $PC 2>/dev/null
|
||||
bt_kill_ours
|
||||
sleep 3
|
||||
}
|
||||
|
||||
|
||||
run_config g_circle grass 1
|
||||
rm -f AB.EGG
|
||||
|
||||
echo "=== A/B VERDICTS ==="
|
||||
for tag in g_circle; do
|
||||
obs=ab_${tag}_obs.log
|
||||
gimp=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=2[2-7] ')
|
||||
trn=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=4 ')
|
||||
kd=$(grep -a '\[animind\]' $obs 2>/dev/null | grep 'inst=1' | grep -c 'state=32 ')
|
||||
t5=$(grep -a '\[mrec-rx\]' $obs 2>/dev/null | grep -c 'type=5 ')
|
||||
knocks=$(grep -ac '\[knock\]' ab_${tag}_limp.log 2>/dev/null)
|
||||
gsim=$(grep -a '\[gimp-sim\]' ab_${tag}_limp.log 2>/dev/null | head -1)
|
||||
echo "VERDICT $tag: replicantGimp=$gimp trn=$trn knockdown=$kd type5rx=$t5 limperKnocks=$knocks ($gsim)"
|
||||
done
|
||||
echo "=== DONE ==="
|
||||
Reference in New Issue
Block a user