CROUCH complete: full cycle + MP replication verified
The WIP's 'pose does not hold' was a chain of bench-instrument errors, not a code bug: every capture ran in COCKPIT view (the pilot cannot see their own legs; the eye-height residual masked as reversion). Joint probes prove the park holds indefinitely (knee 1.138, root -2.219 steady); the 2-node bench shows the observer's replicant fully crouched and held (duckmpA_031 -- the type-3 state record carries it with zero new replication code); the second scripted press (new BT_BTNTEST2 env) verifies RISE -> standing zeros. MP button delivery confirmed mode-mask-clean (the one miss was round-start jitter). Diags added, all BT_DUCK_LOG-gated: SetLegAnimation re-arm tracer, 1 Hz joint probe, RIO press mode-mask, BT_TREE_LOG topology dump, and the squat-park log. RESIDUAL filed: pilot's own cockpit eye does not ride the root drop (DPLEyeRenderable chain composition; cosmetic). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
dd70061e0e
commit
591d205b19
@@ -311,6 +311,23 @@ resolved with gait v5, no shadow code changed — though (a) may have contribute
|
||||
T4]; (c) genuine slope burial when the quad is flat/mis-tilted (the depth-bias margin is finite).
|
||||
Check `[shadowobj]` tag lines and `[sync]`/`BT_SYNC_LOG` before touching bias/tilt.
|
||||
|
||||
## CROUCH -- COMPLETE 2026-08-06 [T1 decode / T2 full-cycle + MP benched]
|
||||
The manual's CROUCH button (streamed 0x13; glass key F4), end to end: DuckRequest (mech id 0x1a
|
||||
@0049fa00) latches duckState@0x398 -> the master posture block (mech4, from the dark master-perf
|
||||
@0x4a9cf0-0x4aa0af): posture selector @0x3f8 (mode 9/10/2/3/4 block, NOVICE simLive lockout,
|
||||
myomer-alive gate) -> standing: SetLegAnimation(2) ('sqd', squat down; LegClipFinished case-2
|
||||
PARKS the pose + leg alarm 1) / ducked: SetLegAnimation(3) ('squ', rise; case-3 alarm 0);
|
||||
stability alarm flips; ForceUpdate(8)+(1) ships the type-3 state record -- peers pose the squat
|
||||
for FREE (screenshot receipt: the crouched crimson madcat from the observer's cockpit,
|
||||
duckmpA_031). Clip data verified from BTL4.RES (root joint drops -2.22, knees +-1.14; squ/sqd
|
||||
are exact mirrors; interior 'squi/sqdi' variants ship for all 8 chassis). Full solo cycle
|
||||
benched (BT_BTNTEST + BT_BTNTEST2): squat -> hold (joints steady for minutes) -> rise ->
|
||||
standing zeros. Myomer speed-cripple feeder (@004b8be3) still deferred [T3] -- see mech4 banner.
|
||||
RESIDUAL (open-questions): the pilot's own cockpit EYE height does not ride the root drop
|
||||
(the interior clip authors joint-0 translation for exactly that; the DPLEyeRenderable chain
|
||||
composition needs a look). Bench traps for reruns: MP button delivery can miss if pressed
|
||||
during round-start jitter (press >= poll 900 after GO); diags all BT_DUCK_LOG-gated.
|
||||
|
||||
## Key Relationships
|
||||
- Detail: `docs/P3_LOCOMOTION.md`. Uses: [[asset-formats]] (SKL/ANI), [[decomp-reference]] (offsets).
|
||||
- Feeds: [[combat-damage]] (collision→damage), [[rendering]] (shadow/visual-conform).
|
||||
|
||||
@@ -1142,3 +1142,10 @@ Gitea #116 and `experience-levels.md`.
|
||||
- **des_night-family pages have subtle fog deltas** (both sets near-black); arena/polar night
|
||||
pages carry the dramatic 5↔40 near-plane swing. If testers report "searchlight does nothing"
|
||||
on some maps, it's page authoring, not the mechanism.
|
||||
|
||||
## Crouch residual (2026-08-06 — the feature itself is LIVE, [[locomotion]] §CROUCH)
|
||||
- **Pilot eye height does not ride the root drop.** The interior squat clip animates joint 0
|
||||
(ball+translation, −2.22) precisely so the cockpit eye lowers; the joint holds (probe-verified)
|
||||
and the eye's segment chain passes through jointlocal, yet the cockpit view returns to standing
|
||||
height after the squat parks. Suspect: DPLEyeRenderable's parent-chain composition not
|
||||
including the BallTranslateJointRenderable's live matrix. Cosmetic (body + replication correct).
|
||||
|
||||
@@ -2624,6 +2624,13 @@ void
|
||||
Verify(rio_event.Data.Unit < ButtonCount);
|
||||
temp = rio_event.Data.Unit + 1;
|
||||
|
||||
// DIAG (BT_DUCK_LOG): the mode mask a press dispatches under -- the
|
||||
// crouch-button (0x13) MP-delivery hunt (mode-gated streamed rows).
|
||||
if (getenv("BT_DUCK_LOG"))
|
||||
DEBUG_STREAM << "[duck] RIO press unit=0x" << std::hex
|
||||
<< (int)rio_event.Data.Unit << " modeMask=0x"
|
||||
<< (unsigned)mode_mask << std::dec << "\n" << std::flush;
|
||||
|
||||
Check(&buttonGroup[rio_event.Data.Unit]);
|
||||
buttonGroup[rio_event.Data.Unit].Update(&temp, mode_mask);
|
||||
//----------------------------------------
|
||||
|
||||
@@ -542,6 +542,33 @@ void
|
||||
DEBUG_STREAM << "[btntest] RELEASE 0x" << std::hex << s_btnAddr
|
||||
<< std::dec << " at poll " << s_poll << "\n" << std::flush;
|
||||
}
|
||||
// BT_BTNTEST2="addr,pressPoll,releasePoll": an optional SECOND
|
||||
// scripted cycle (e.g. crouch then rise) on the same poll clock.
|
||||
static int s_bt2Addr = -2, s_bt2On = 0, s_bt2Off = 0, s_bt2State = 0;
|
||||
if (s_bt2Addr == -2)
|
||||
{
|
||||
s_bt2Addr = -1;
|
||||
const char *e2 = getenv("BT_BTNTEST2");
|
||||
if (e2 != NULL)
|
||||
sscanf(e2, "%i,%i,%i", &s_bt2Addr, &s_bt2On, &s_bt2Off);
|
||||
}
|
||||
if (s_bt2Addr >= 0)
|
||||
{
|
||||
if (s_bt2State == 0 && s_poll >= s_bt2On)
|
||||
{
|
||||
s_bt2State = 1;
|
||||
EmitButton(s_bt2Addr, 1);
|
||||
DEBUG_STREAM << "[btntest] PRESS2 0x" << std::hex << s_bt2Addr
|
||||
<< std::dec << " at poll " << s_poll << "\n" << std::flush;
|
||||
}
|
||||
else if (s_bt2State == 1 && s_poll >= s_bt2Off)
|
||||
{
|
||||
s_bt2State = 2;
|
||||
EmitButton(s_bt2Addr, 0);
|
||||
DEBUG_STREAM << "[btntest] RELEASE2 0x" << std::hex << s_bt2Addr
|
||||
<< std::dec << " at poll " << s_poll << "\n" << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -558,6 +558,11 @@ HierarchicalDrawComponent*
|
||||
//
|
||||
if (segment->IsSiteSegment() /* [0x10] */ != 0)
|
||||
{
|
||||
if (getenv("BT_TREE_LOG"))
|
||||
DEBUG_STREAM << "[tree] SITE seg=" << segment->GetIndex()
|
||||
<< " name=" << (segment->GetName() ? (const char *)segment->GetName() : "?")
|
||||
<< " parent=" << (segment->GetParent() ? segment->GetParentIndex() : -1)
|
||||
<< "\n" << std::flush;
|
||||
// The authentic COCKPIT EYEPOINT. Built for the true inside view
|
||||
// AND for the player's chase build (buildDebugChaseCamera), so the
|
||||
// V-key toggle can switch to it -- the pod's only view was this
|
||||
@@ -678,6 +683,14 @@ HierarchicalDrawComponent*
|
||||
// the JointSubsystem's joint table.
|
||||
//
|
||||
int segment_slot = segment->GetIndex() /* [0xcc] */;
|
||||
// DIAG (BT_TREE_LOG): the built joint topology -- segment slot, name,
|
||||
// joint index/type, parent -- the crouch root-drop chain hunt.
|
||||
if (getenv("BT_TREE_LOG"))
|
||||
DEBUG_STREAM << "[tree] seg=" << segment_slot
|
||||
<< " name=" << (segment->GetName() ? (const char *)segment->GetName() : "?")
|
||||
<< " joint=" << segment->GetJointIndex()
|
||||
<< " parent=" << (segment->GetParent() ? segment->GetParentIndex() : -1)
|
||||
<< "\n" << std::flush;
|
||||
Joint *this_joint = NULL;
|
||||
Joint::JointType joint_type;
|
||||
if (segment->GetJointIndex() /* [0xc0] */ == -1)
|
||||
|
||||
@@ -530,6 +530,8 @@ Scalar
|
||||
return 0.0f;
|
||||
// slot10 state 2 (0x4a6b37): SetLevel(1).
|
||||
case 2:
|
||||
if (getenv("BT_DUCK_LOG"))
|
||||
DEBUG_STREAM << "[duck] squat clip parked (case 2 -> leg alarm 1)\n" << std::flush;
|
||||
m->legStateAlarm.SetLevel(1); return 0.0f;
|
||||
// slot2 (0x4a6b21) + slot1 state 32 (0x4a6b4d) + slot9 state 4 (0x4a6d6e): SetLevel(0).
|
||||
case 3: case 4: case 8: case 9: case 20: case 21:
|
||||
|
||||
@@ -4435,6 +4435,27 @@ void
|
||||
<< " squat=" << squatCapable << ")\n" << std::flush;
|
||||
duckState = 0; // consumed (@0x4aa0a9)
|
||||
}
|
||||
|
||||
// DIAG (BT_DUCK_LOG, 1 Hz): live joint sample -- does the parked
|
||||
// crouch HOLD at the JOINT level? Discriminates render-side loss
|
||||
// from a hidden joint writer (the crouch-hold hunt).
|
||||
if (getenv("BT_DUCK_LOG"))
|
||||
{
|
||||
static Scalar s_duckProbe = 0.0f;
|
||||
s_duckProbe += dt;
|
||||
if (s_duckProbe >= 1.0f)
|
||||
{
|
||||
s_duckProbe = 0.0f;
|
||||
JointSubsystem *duckJs = GetJointSubsystem();
|
||||
Joint *knee = (duckJs != 0) ? duckJs->GetJoint(11) : 0;
|
||||
Joint *root = (duckJs != 0) ? duckJs->GetJoint(0) : 0;
|
||||
DEBUG_STREAM << "[duck] probe legLvl=" << (int)legStateAlarm.GetLevel()
|
||||
<< " j11=" << (knee ? (float)knee->GetHinge().rotationAmount : -99.0f)
|
||||
<< " j0ty=" << ((root && root->GetJointType() == Joint::BallTranslationJointType)
|
||||
? (float)root->GetTranslation().y : -99.0f)
|
||||
<< "\n" << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
# SEARCHLIGHT bench 2 (external spot cone + replication): night 2-node.
|
||||
# A walks to 40u of B and stands (facing B). B presses the searchlight button
|
||||
# (BT_BTNTEST 0x14) at poll 300. B's lightState replicates (subsystem record
|
||||
# 0x14) -> A's replicant Searchlight LightOn flips -> A's TickSearchlight shows
|
||||
# the spot.bgf cone on B's mech.
|
||||
# PASS: A log "[spot] searchlight pass: ... (external: spot cone)" for B's mech
|
||||
# + "[spot] cone SHOWN (seg N)" after B's press; A BT_SHOT frames brighten near
|
||||
# B post-toggle. B log: "[light] ... requested ON" + lightState 0 -> 1.
|
||||
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 duckmp_a.log duckmp_b.log duckmp_relay.log duckmpA_*.png
|
||||
bt_expert_egg MP.EGG SG4.EGG
|
||||
sed -i "s/^map=.*/map=grass/; s/^time=.*/time=night/; s/^vehicle=.*/vehicle=madcat/" SG4.EGG
|
||||
|
||||
(
|
||||
export BT_BTNTEST=0x13,900,960 BT_DUCK_LOG=1
|
||||
export BT_FIRE_LOG=1 BT_FOG_LOG=1 BT_DEATH_LOG=1 BT_MP_LOG=1
|
||||
bt_launch duckmp_b.log SG4.EGG 0x0C -net 1601
|
||||
)
|
||||
sleep 2
|
||||
(
|
||||
export BT_GOTO=enemy BT_GOTO_STOP=40 BT_KEY_NOFOCUS=1 BT_DUCK_LOG=1
|
||||
export BT_SHOT_EVERY=60 BT_SHOT_PREFIX=duckmpA
|
||||
export BT_FIRE_LOG=1 BT_FOG_LOG=1 BT_MP_LOG=1
|
||||
bt_launch duckmp_a.log SG4.EGG 0x03 -net 1501
|
||||
)
|
||||
sleep 5
|
||||
python ../tools/btconsole.py SG4.EGG 127.0.0.1:1501 127.0.0.1:1601 > duckmp_relay.log 2>&1 &
|
||||
RELAY=$!
|
||||
sleep 90
|
||||
kill $RELAY 2>/dev/null
|
||||
taskkill //F //IM btl4.exe > /dev/null 2>&1
|
||||
sleep 3
|
||||
echo "=== B (lamp owner):"
|
||||
grep -aE "\[light\]|btntest|\[spot\]" duckmp_b.log | head -8
|
||||
echo "=== A (observer -- cone events):"
|
||||
grep -aE "\[spot\]" duckmp_a.log | head -8
|
||||
Reference in New Issue
Block a user