BT410 Phase 5.3.2e: source authentic per-mech locomotion params from GameModel resource

The Mech ctor now reads walkingTurnRate / runningTurnRate / maxAcceleration /
throttleAdjustment from the GameModel resource (SearchList(GameModelResourceType)
-> ModelResource), replacing the bring-up-default constants for those fields.

Each read is sanity-guarded (out-of-band -> keep default) since BT411 flags parts
of the ModelResource layout as mis-decoded -- but the live values came back clean
and authentic: walkTR=75deg/s, runTR=50deg/s, maxAcc=30 u/s^2, throttleAdj=1.0
(walking turns faster than running; maxAcc matches the madcat note), confirming
our reconstructed struct layout is correct for these fields.

Verified: at walk speed the authentic 75deg/s tightens the turn circle to r~6.9
(=speed/turnRate); zero Fail. Still on defaults (pending LoadLocomotionClips):
reverseStrideLength (top speed) / walkStrideLength / reverseSpeedMax -- measured
from the walk/run animation clips.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-21 15:52:20 -05:00
co-authored by Claude Fable 5
parent ccc6ee6914
commit 0cc7713865
2 changed files with 69 additions and 4 deletions
+53
View File
@@ -329,6 +329,59 @@ Mech::Mech(
<< " weaponCount=" << weaponCount << endl << flush;
}
//
//-----------------------------------------------------------------------
// Source the authentic per-mech locomotion params from the GameModel
// resource (mech.cpp @~1430: walkingTurnRate/runningTurnRate deg->rad,
// maxAcceleration, throttleAdjustment). The reconstructed ModelResource
// struct layout is only partially verified (BT411 flags it mis-decoded in
// places), so every read is SANITY-GUARDED: a value outside a sane band
// leaves the bring-up default in place. The stride/top speeds still come
// from the bring-up defaults (their authentic source is LoadLocomotionClips,
// which measures them from the walk/run animation clips -- a later wave).
//-----------------------------------------------------------------------
//
{
ResourceDescription *modelDesc =
application->GetResourceFile()->SearchList(
modelResourceID,
ResourceDescription::GameModelResourceType
);
if (modelDesc != NULL)
{
modelDesc->Lock();
ModelResource *model = (ModelResource *)modelDesc->resourceAddress;
if (model != NULL)
{
if (getenv("BT_MECH_LOG"))
{
DEBUG_STREAM << "[mech] model params: walkTR="
<< model->walkingTurnRate << " runTR=" << model->runningTurnRate
<< " maxAcc=" << model->maxAcceleration
<< " throttleAdj=" << model->throttleAdjustment
<< " (deg,deg,u/s^2,scale)" << endl << flush;
}
if (model->walkingTurnRate > 1.0f && model->walkingTurnRate < 360.0f)
{
walkingTurnRate = model->walkingTurnRate * RAD_PER_DEG;
}
if (model->runningTurnRate > 1.0f && model->runningTurnRate < 360.0f)
{
runningTurnRate = model->runningTurnRate * RAD_PER_DEG;
}
if (model->maxAcceleration > 1.0f && model->maxAcceleration < 500.0f)
{
maxBodyAcceleration = model->maxAcceleration;
}
if (model->throttleAdjustment > 0.05f && model->throttleAdjustment < 20.0f)
{
forwardThrottleScale = model->throttleAdjustment;
}
}
modelDesc->Unlock();
}
}
//
// Install the per-frame body Performance. Until now the mech ran the base
// DoNothingOnce; from here the engine dispatches Mech::Simulate every frame
+16 -4
View File
@@ -208,10 +208,22 @@ publishes `speedDemand` (world u/s = topSpeed·throttle·fwdScale) and `turnDema
New named Mech members (out of `reservedState`, now [211]): `walkingTurnRate`,
`runningTurnRate`, `reverseStrideLength` (top speed), `walkStrideLength`,
`reverseSpeedMax`, `forwardThrottleScale`, `maxBodyAcceleration`,
`bodyTargetSpeed`, `currentBodySpeed`. **BRING-UP DEFAULTS** — the authentic
values come from the Mech model resource (WalkingTurnRate/RunningTurnRate/
MaxAcceleration) + LoadLocomotionClips (stride/top speeds from the walk/run
clips); wiring the model-resource pointer + clip loader is the next refinement.
`bodyTargetSpeed`, `currentBodySpeed`.
**Model-resource sourcing (2026-07-21, VERIFIED).** The ctor now sources the
authentic per-mech `walkingTurnRate` / `runningTurnRate` / `maxBodyAcceleration`
/ `forwardThrottleScale` from the GameModel resource
(`SearchList(GameModelResourceType)` → `ModelResource`), replacing those
bring-up defaults. Each read is SANITY-GUARDED (out-of-band → keep the default)
because BT411 flags parts of the ModelResource layout as mis-decoded — but the
live values came back clean and authentic: **walkTR=75°/s, runTR=50°/s,
maxAcc=30 u/s², throttleAdj=1.0** (walking turns faster than running; maxAcc
matches BT411's madcat note), confirming the struct layout is correct for these
fields. Verified drive: at walk speed the authentic 75°/s tightens the turn
circle to r≈6.9 (=speed/turnRate). Still on bring-up defaults:
`reverseStrideLength` (top speed) / `walkStrideLength` / `reverseSpeedMax` —
their authentic source is `LoadLocomotionClips` (measured from the walk/run
animation clips), a later wave.
**VERIFIED headlessly** (`BT_MECH_LOG` `[sim]`/`[mppr]`; forced-input dev hooks
`BT_FORCE_THROTTLE`/`BT_FORCE_TURN` in InterpretControls):