bench parity: local nodes now launch exactly like a player's shortcut

Local benches had drifted from the shipped launchers and every divergence
cost a debugging session:

  * no BT_START_INSIDE -> benches opened in the EXTERNAL CHASE camera while
    every player starts in the COCKPIT.  The first first-person look at a
    bench window was misread as a broken HUD.
  * novice bench eggs  -> every SHIPPED egg is expert; novice gates off the
    entire heat model, crits and jams, so bench combat was not field combat.
    (Verified: the aligned node now boots experience=3 simLive=1
    heatModelOn=1, where it used to boot 0/0/0.)
  * 1-LP affinity pins -> starved the gauge executive and produced a false
    "the comms panel never counts deaths" reading.  Two LPs per node keeps
    the documented single-box jitter fix without the starvation.

scratchpad/night6/bench_common.sh now owns the contract (bt_player_env,
bt_launch, bt_expert_egg, bt_novice_egg) copied verbatim from play_solo.bat,
with bt_assert_player_env warning if the shipped bat ever drifts.  All three
4-node benches source it.  The limp bench keeps a novice egg -- expert crits
the aimed leg and the mech turns-but-never-moves -- and now says so loudly.

Also: BT_SHOT_EVERY=<n> headless backbuffer capture (btl4vid.cpp), the tool
this was diagnosed with.  It must sit above the warp phase-0 early-out since
that fn is the per-frame alpha-pass hook.  OS screen-capture is off-limits:
a foreground-lock failure photographed the user's browser instead of the game.

KB: build-and-run.md gains the bench-parity rule + the capture diag;
cockpit-view.md gains the measured aspect/FOV finding (the surround's 2.05:1
view collapses vertical FOV to 31.5 deg vs the pod's 46.8, so fixed canopy
geometry covers 68.6% of the lower half -- NOT a regression: the shipped 643
binary reports identical geometry).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-07-30 13:30:30 -05:00
co-authored by Claude Fable 5
parent 82f1ea1183
commit 4e89baeff3
8 changed files with 323 additions and 2 deletions
+29
View File
@@ -2921,6 +2921,35 @@ void
BTDrawTranslocationSpheres(LPDIRECT3DDEVICE9 device, const D3DXMATRIX *view,
float dt, Time frame_time)
{
// DIAG (off by default; MUST sit before the phase-0 early-out -- this
// fn is the per-frame alpha-pass hook, L4VIDEO.cpp:8831): BT_SHOT_EVERY=<n> dumps the backbuffer every n
// frames as <BT_SHOT_PREFIX|shot>_NNN.png -- the GENERAL headless-eyes
// harness (view/HUD/layout debugging without foregrounding the window).
{
static int s_shotEvery = -2;
if (s_shotEvery == -2)
{
const char *se = getenv("BT_SHOT_EVERY");
s_shotEvery = (se && *se) ? atoi(se) : 0;
if (s_shotEvery < 0) s_shotEvery = 0;
}
if (s_shotEvery > 0)
{
static int s_frameN = 0, s_dumpN = 0;
if ((++s_frameN % s_shotEvery) == 0 && s_dumpN < 400)
{
const char *pfx = getenv("BT_SHOT_PREFIX");
char fn[600];
_snprintf(fn, sizeof fn, "%s_%03d.png", (pfx && *pfx) ? pfx : "shot", s_dumpN++);
IDirect3DSurface9 *bb = 0;
if (SUCCEEDED(device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb)) && bb)
{
D3DXSaveSurfaceToFileA(fn, D3DXIFF_PNG, bb, 0, 0);
bb->Release();
}
}
}
}
// DIAG (off by default): BT_WARP_SELFTEST=1 forces a steady POV warp
// (held in WaitForReincarnate, world masked) so the swirl can be frame-captured and
// compared against the original (capture.png) in a solo game -- no death/respawn