The un-wreck receipt had no partner, so counting ghosts in a field log meant
pairing it against
[BTrender] wreck: 'thrdbr.bgf' missing -> gendbr.bgf fallback
which is a MISSING-ASSET WARNING, not a death -- it only prints for chassis
whose wreck model is absent. Night 13's census found ONE ghost while testers
reported many, and there was no way to separate a real count from a chassis
accident.
Emit one ungated line for every REPLICANT entering the wreck state, symmetric
with the existing un-wreck line, so a log's ghost count is exactly
(wreck-enters minus un-wrecks) per entity:
[wreck] replicant H:E entered wreck state (mode X->9) at (x,z)
[respawn] replicant H:E un-wrecked + warp (mode 9->1) at (x,z)
Verified 2-node (200s, force-damage victim): 5 enters, 5 exits, exactly
paired -- while the old marker printed ZERO times in the same run. That gap
is the point: five real deaths, invisible to what the census was reading.
Also lands the night-13 census tooling (ghostcensus.py) and the eject benches
that did NOT reproduce, with their failure modes in the headers so the next
attempt does not repeat them: five rigs failed to trigger a punch-out at all
(BT_BTNTEST never reached the mapper for 0x3D or 0x14; BT_EJECT_AT did not
fire either). Panic-eject replication remains UNTESTED by bench.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NCJQkvq6G2JNrpVbA75tVZ
81 lines
3.3 KiB
Bash
81 lines
3.3 KiB
Bash
#!/usr/bin/env bash
|
|
# =========================================================================
|
|
# EJECT-GHOST bench (#108 / night 13) -- does a PANIC EJECT replicate its
|
|
# respawn to peers?
|
|
#
|
|
# FIELD REPORT: many ghost mechs tonight, all from panic-button self
|
|
# destructs, none respawning properly -- and the operator has seen
|
|
# eject-respawn work every time before tonight, so this is a REGRESSION
|
|
# (night 12 = build 774, tonight = 817).
|
|
#
|
|
# FIELD EVIDENCE (staged logs): the ejecting mech's OWNER ran the whole
|
|
# death path and respawned and kept driving in the same round, while BOTH
|
|
# peers created his wreck and never processed the un-wreck. The same mech's
|
|
# NORMAL deaths replicated their respawns 4-6 times in that same session.
|
|
#
|
|
# THE TEST: A punches out via the real click seam (button 0x3D, the panic
|
|
# button -- the same addr the field log shows). B watches.
|
|
# PASS : B logs "[respawn] replicant <A> un-wrecked + warp (mode 9->1)"
|
|
# FAIL : B logs the wreck and never the un-wreck <- the ghost
|
|
# A CONTROL kill comes first (B force-damages A), so the SAME run shows a
|
|
# normal death replicating correctly -- otherwise a silent B proves nothing.
|
|
#
|
|
# Press polls: >=900 per the harness contract (round-start jitter eats
|
|
# earlier presses). Panic twice, so one missed press does not read as a
|
|
# pass.
|
|
# =========================================================================
|
|
set -x
|
|
. /c/git/bt411/scratchpad/night6/bench_common.sh
|
|
cd /c/git/bt411/content || exit 1
|
|
|
|
taskkill //F //IM btl4.exe > /dev/null 2>&1
|
|
sleep 2
|
|
rm -f eg_a.log eg_b.log eg_relay.log
|
|
|
|
bt_assert_player_env
|
|
bt_expert_egg MP.EGG EG.EGG
|
|
sed -i "s/^map=.*/map=grass/; s/^time=.*/time=day/; s/^vehicle=.*/vehicle=madcat/" EG.EGG
|
|
|
|
# ---- node B: OBSERVER + the control killer -------------------------------
|
|
( export BT_MP_FORCE_DMG=1
|
|
export BT_DEATH_LOG=1 BT_MP_LOG=1 BT_MATCHLOG=1
|
|
bt_launch eg_b.log EG.EGG 0x0C -net 1601 )
|
|
sleep 2
|
|
# ---- node A: walks, gets killed (control), then PUNCHES OUT twice --------
|
|
( export BT_AUTODRIVE=0.6
|
|
export BT_BTNTEST=0x3d,900,960 # panic eject #1
|
|
export BT_BTNTEST2=0x3d,2400,2460 # panic eject #2
|
|
export BT_DEATH_LOG=1 BT_MP_LOG=1 BT_MATCHLOG=1
|
|
bt_launch eg_a.log EG.EGG 0x03 -net 1501 )
|
|
sleep 5
|
|
python ../tools/btconsole.py EG.EGG 127.0.0.1:1501 127.0.0.1:1601 > eg_relay.log 2>&1 &
|
|
RELAY=$!
|
|
sleep 300
|
|
kill $RELAY 2>/dev/null
|
|
sleep 3
|
|
bt_kill_ours
|
|
sleep 2
|
|
taskkill //F //IM btl4.exe > /dev/null 2>&1
|
|
sleep 3
|
|
|
|
AID=$(grep -aoE "MY mech entityID=[0-9]+:[0-9]+" eg_a.log | head -1 | cut -d= -f2)
|
|
echo "=================== EJECT-GHOST RESULT ==================="
|
|
echo "A's entity id: ${AID:-UNKNOWN}"
|
|
echo
|
|
echo "--- did the scripted panic actually press? ---"
|
|
grep -a "btntest" eg_a.log
|
|
echo
|
|
echo "--- A: punch-outs + its own death/respawn cycle ---"
|
|
grep -aE "\[eject\]|PUNCH-OUT|death cycle START|dz\] GRANTED|Mech::Reset" eg_a.log | head -20
|
|
echo
|
|
echo "--- B: the peer's view of A, in order (wreck / un-wreck) ---"
|
|
grep -aE "wreck:|respawn\] replicant" eg_b.log | grep -a "${AID:-@@@}" | head -20
|
|
echo
|
|
echo "--- B: totals for A ---"
|
|
echo -n "wrecks seen : "; grep -a "wreck:" eg_b.log | grep -ac "${AID:-@@@}"
|
|
echo -n "respawns seen : "; grep -a "respawn\] replicant" eg_b.log | grep -ac "${AID:-@@@}"
|
|
echo
|
|
echo "--- B: ghost detector ---"
|
|
grep -a "\[ghost\]" eg_b.log | head -5
|
|
echo -n "ghost lines: "; grep -ac "\[ghost\]" eg_b.log
|