#142 crouch: the mech is fine -- it is a missing PANEL ANIMATION

Benched solo AND in MP on the same chassis: both presses reach
DuckRequestMessageHandler, zero drops, SQUAT -> squat clip parked -> RISE.
Locomotion is not the bug, and MP is not refusing it.

Added an ungated [duck] REQUEST DROPPED receipt at the consumer's silent miss.
The squatCapable==0 path skips the consumer entirely AND leaves duckState
latched at 1 with NO log today; the posture-gate miss logged only under
BT_DUCK_LOG, which no player sets.  Neither fired on madcat.

What the pilot sees, traced with BT_LAMP_LOG: the button lamp is momentary
press feedback, not state --

    PRESS   -> [lamp] 0x13 <- 0x3c
    SQUAT   -> mech crouches, clip parked
    RELEASE -> [lamp] 0x13 <- 0x14    <-- while still CROUCHED

so crouched and standing look identical.

Era testimony corrects the scope: the button should ANIMATE A MECH SYMBOL
beside it, standing <-> crouching (operator).  Lynx: 'When a mech stops,
crouch button lowers its stance and plays crouch animation.  Mech is
immobilized until crouch is pushed again, and mech rises.'  Draco concurs.

Two real gaps, neither fixed here:
  1. no immobilization while crouched -- nothing gates movement on duckState
     or the parked leg alarm.  NB a driven mech with a parked leg channel is
     the [skate] signature (#52), so this may not be cosmetic.
  2. no stance symbol -- no gauge element draws one, and the decomp carries no
     crouch/squat/stance/duck graphic string, so it is an authored IMAGE on the
     secondary MFD; find it in that gauge's element list, not by string.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NCJQkvq6G2JNrpVbA75tVZ
This commit is contained in:
Joe DiPrima
2026-08-07 16:16:12 -05:00
co-authored by Claude Opus 5
parent 61f21107b4
commit 0530366687
4 changed files with 209 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# =========================================================================
# #142 CROUCH does not toggle -- name the gate.
#
# FIELD (Oracle, night 13): "the crouch button did not toggle to display
# crouched ... no state change ... the light next to it always flashes when
# pressed, but state does not change. Remains in stand mode."
#
# That is the EJECT bug's signature: the press reaches the handler (lamp
# responds) and a GATE silently declines it. DuckRequestMessageHandler
# always succeeds -- it just sets duckState=1. The CONSUMER (mech4.cpp) is
# where it dies:
#
# if (duckState != 0 && squatCapable != 0) {
# if (mapPosture == 1) squat;
# else if (mapPosture == 2) rise;
# else if (BT_DUCK_LOG) log; <- only diagnostic, env-gated
# duckState = 0;
# }
#
# squatCapable == 0 skips the whole block: no log, and the latch is not even
# consumed. A new ungated [duck] REQUEST DROPPED receipt covers both misses.
#
# Runs the SAME chassis twice is pointless -- squatCapable is per-model
# ('squ'/'sqd' clips shipped), so sweep several. CROUCH is button 0x13
# (shipped bindings: left column 0x10-0x15 = map+/map-/IR/CROUCH/searchlight/
# display). BT_BTNTEST2 exists precisely for "crouch then rise".
# =========================================================================
set -x
V="${1:-madcat}"
. /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 cr_${V}.log
bt_expert_egg MP.EGG CR.EGG
sed -i "s/^map=.*/map=grass/; s/^time=.*/time=day/; s/^vehicle=.*/vehicle=${V}/" CR.EGG
( export BT_BTNTEST=0x13,900,960 # CROUCH press
export BT_BTNTEST2=0x13,1500,1560 # and again (toggle back / retry)
export BT_DUCK_LOG=1 BT_GAIT_LOG=1 BT_KEY_NOFOCUS=1
bt_launch cr_${V}.log CR.EGG 0x03 )
for i in $(seq 1 60); do grep -aq "btntest" cr_${V}.log 2>/dev/null && break; sleep 2; done
sleep 45
bt_kill_ours; sleep 2; taskkill //F //IM btl4.exe > /dev/null 2>&1; sleep 2
echo "=================== #142 CROUCH vehicle=$V ==================="
echo "--- 1. did the press reach the handler? ---"
grep -a "btntest" cr_${V}.log | head -4
grep -a "DuckRequest" cr_${V}.log | head -3
echo
echo "--- 2. THE GATE: why was it dropped? ---"
grep -a "REQUEST DROPPED" cr_${V}.log | head -4
echo -n "dropped-receipt count: "; grep -ac "REQUEST DROPPED" cr_${V}.log
echo
echo "--- 3. did a posture change actually happen? ---"
grep -aE "\[duck\] (SQUAT|RISE)" cr_${V}.log | head -4
echo -n "SQUAT/RISE events: "; grep -acE "\[duck\] (SQUAT|RISE)" cr_${V}.log
echo
echo "--- 4. does this chassis even ship the squat clips? ---"
grep -aiE "squatCapable|squ.*clip|sqd" cr_${V}.log | head -4
+59
View File
@@ -0,0 +1,59 @@
"""#142 -- correct the report and record what benching established. ASCII only."""
import sys
sys.path.insert(0, r"C:\git\bt411\scratchpad\night7")
import gitea
gitea.comment(142, """**RE-SCOPED 2026-08-07 -- the mech crouches fine; this is a missing PANEL ANIMATION.**
The original report ("the crouch button did not toggle to display crouched ... the light next to
it always flashes when pressed, but state does not change") reads like a locomotion or lamp bug.
Benching says it is neither.
## What works (benched, `scratchpad/night13/crouch142.sh` + `crouchmp.sh`)
* SOLO, madcat: both presses reach `DuckRequestMessageHandler`, zero drops, `[duck] SQUAT (posture
1 -> leg clip 2)` then `squat clip parked`, then `[duck] RISE`. A full toggle cycle.
* MULTIPLAYER, same chassis: identical -- 2 requests, 0 drops, SQUAT + RISE. So the MP path is not
refusing it either.
A receipt was added at the consumer's silent miss (`[duck] REQUEST DROPPED`, ungated) covering both
gates -- `squatCapable == 0` (which skips the consumer entirely AND leaves `duckState` latched at 1,
with no log at all today) and `mapPosture` not 1/2 (previously logged only under `BT_DUCK_LOG`,
which no player sets). Neither fired on madcat. Chassis without `squ`/`sqd` clips are still
untested; the bench takes a vehicle argument for that sweep.
## What the pilot actually sees
The crouch button's LAMP is momentary press feedback, not state. Traced with `BT_LAMP_LOG`:
PRESS -> [lamp] 0x13 <- 0x3c (lit)
SQUAT -> mech crouches, clip parked
RELEASE -> [lamp] 0x13 <- 0x14 (unlit) <-- while still CROUCHED
PRESS2 -> [lamp] 0x13 <- 0x3c
RISE -> mech stands
RELEASE -> [lamp] 0x13 <- 0x14
Crouched and standing are visually identical, so the lamp can never carry posture.
## What it is SUPPOSED to be (era testimony, this day)
The operator, correcting the framing: the crouch button is supposed to **animate a MECH SYMBOL next
to the button**, standing <-> crouching. Not a two-state lamp -- a missing animation.
VGL Lynx: *"When a mech stops, crouch button lowers its stance and plays crouch animation. Mech is
immobilized until crouch is pushed again, and mech rises."* Draco: *"Checks out with my memories."*
## Two gaps, and the second is the reported one
1. **No immobilization while crouched.** Nothing in the port gates movement on `duckState` or the
parked leg alarm -- grep of every consumer of both across `game/reconstructed/` finds no
speed/throttle/demand gate. Per Lynx the mech should be immobile until the button is pushed
again. ⚠ Worth checking what a crouched mech that IS driven does today, since the leg clip is
parked -- a moving mech with a parked leg channel is the [skate] signature (#52).
2. **No stance symbol.** No gauge element anywhere in `btl4gau*.cpp` draws a posture/stance icon,
and the decomp has no crouch/squat/stance/duck graphic STRING (only substring false positives:
"existance", "distance"). So it is likely an authored IMAGE element on the secondary/radar MFD
rather than something findable by name -- next step is the secondary MFD's element list in the
binary, not another string search.
Not fixed. Re-scoped, with the locomotion half cleared and the real target named.""")
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
# =========================================================================
# #142 CROUCH in MULTIPLAYER -- solo works, so MP is the variable.
#
# crouch142.sh proved a madcat crouches and rises cleanly SOLO: both presses
# reached DuckRequest, zero REQUEST DROPPED, SQUAT then RISE fired. The
# reporters were in MP, and the wording matters:
# Oracle: "the crouch button did not toggle to DISPLAY crouched ... no state
# change ... the light next to it always flashes when pressed, but
# state does not change. Remains in stand mode."
#
# Three things that could produce that with the mech itself working:
# (a) MP-only refusal -- some gate differs on a networked master
# (b) replication -- master squats, PEER never poses it
# (c) indicator -- mech squats, but the button LAMP / state readout
# never latches, so the pilot sees "stand"
#
# Same chassis as the passing solo run, so MP is the only changed variable.
# A presses crouch twice; B observes. Read all three layers.
# =========================================================================
set -x
. /c/git/bt411/scratchpad/night6/bench_common.sh
cd /c/git/bt411/content || exit 1
bt_assert_player_env
taskkill //F //IM btl4.exe > /dev/null 2>&1
sleep 2
rm -f cm_a.log cm_b.log cm_relay.log
bt_expert_egg MP.EGG CM.EGG
sed -i "s/^map=.*/map=grass/; s/^time=.*/time=day/; s/^vehicle=.*/vehicle=madcat/" CM.EGG
( export BT_DUCK_LOG=1 BT_GAIT_LOG=1 BT_MP_LOG=1
bt_launch cm_b.log CM.EGG 0x0C -net 1601 )
sleep 2
( export BT_BTNTEST=0x13,900,960 BT_BTNTEST2=0x13,1800,1860
export BT_DUCK_LOG=1 BT_GAIT_LOG=1 BT_MP_LOG=1 BT_KEY_NOFOCUS=1
bt_launch cm_a.log CM.EGG 0x03 -net 1501 )
sleep 5
python ../tools/btconsole.py CM.EGG 127.0.0.1:1501 127.0.0.1:1601 > cm_relay.log 2>&1 &
RELAY=$!
sleep 240
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]+" cm_a.log | head -1 | cut -d= -f2)
echo "=================== #142 CROUCH in MP (A=${AID:-?}) ==================="
echo "--- (a) did A's press reach the handler, and was it dropped? ---"
grep -a "btntest" cm_a.log | head -4
echo -n "DuckRequests : "; grep -ac "DuckRequest" cm_a.log
echo -n "REQUEST DROPPED: "; grep -ac "REQUEST DROPPED" cm_a.log
grep -a "REQUEST DROPPED" cm_a.log | head -3
echo
echo "--- (b) did A's own mech actually change posture? ---"
grep -aE "\[duck\] (SQUAT|RISE|squat clip)" cm_a.log | head -6
echo -n "SQUAT/RISE on A: "; grep -acE "\[duck\] (SQUAT|RISE)" cm_a.log
echo
echo "--- (c) did the PEER pose the squat? (legState ships in the type-3 record) ---"
echo -n "B duck lines for A: "; grep -ac "\[duck\]" cm_b.log
grep -a "\[duck\]" cm_b.log | head -4
echo -n "B legState-2/3 sightings: "; grep -aoE "legState=[23]" cm_b.log | wc -l
echo
echo "--- (d) the INDICATOR: does anything latch a crouched state? ---"
grep -aiE "lamp.*0x13|stability|duckState" cm_a.log | head -6