Experience levels WIRED: the egg field drives the simulation tier (Gitea #2)

BTPlayer's master ctor now seeds the flag block from
btMission->ExperienceLevel() + AdvancedDamageOn() (accessors from the
SURVIVED 1995 BTMSSN.HPP [T0]) instead of the NULL-stubbed scenario
role -- the egg experience knob works for the first time.  Both switch
slot errors fixed vs the binary @4c0bc8; phantom btMission duplicate
member removed (+0x1f8 IS Player::playerMission).

SEVEN gate stubs unified onto the real flags (two found empirically):
HeatModelActive, OwnerAdvancedDamage, LiveFireEnabled,
ControlsAllowLights, powersub @4b0efc, emitter's file-local FUN_004ad7d4
+ FUN_004ac9c8 stubs.  FUN_004ac9c8 family swept (incl. a live raw-offset
databinding trap in MechSubsystem::IsDamaged).  Flag block renamed to its
true semantics (simLive/heatModelOn/...), scoring-era names kept as
comments.  Includes the #5 [aud-tail] diag in emitter.cpp.

ALL 19 shipped eggs say experience=expert -> default behavior UNCHANGED
(per-tier verified: novice/standard = no heat/jams, authentic; veteran/
expert = today's exact behavior).  Real delta: egg advancedDamage=1 now
reaches player+0x264/0x268 (was hardwired 0).  Follow-up flagged: the
glass FE defaults empty experience to veteran (one tier below shipped).

Awaiting human verification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-20 14:51:35 -05:00
co-authored by Claude Fable 5
parent a0cec48e3f
commit d7158f1f82
14 changed files with 294 additions and 130 deletions
+23 -22
View File
@@ -164,8 +164,9 @@ register. ⚠ The audit also flags the damage-economy item as SELF-CONTRADICTOR
btl4vid.cpp `MakeMechRenderables` reticle-build/inside pass (== arcade part_014.c:5173, Dynamic,
bound per Searchlight `lightState` via a new `LightStatePtr()` accessor); (3) a toggle input (the
authentic cockpit button-5→`ToggleLamp` dispatch is a controls-family reconstruction; a dev key
stands in). Also flags a deferred **`Mech::ControlsAllowLights()`** (searchlight.hpp:158 stub;
2026-07-18: identified as the `player+0x25c` not-novice experience flag — [[experience-levels]]).
stands in). `ControlsAllowLights()` (searchlight.hpp) is WIRED since issue #2 to the
`player+0x25c` not-novice experience flag via the BTPlayerExperienceSimLive bridge
([[experience-levels]]); the consumer (ToggleLamp) still needs the cockpit button dispatch.
See [[rendering]] fog section. Verified inert live: BT_FOG_LOG shows zero `SetFogStyle(2/3)`.
- **Factory capability-roster loops 2-4 are STILL DEAD (task #57 discovery).** mech.cpp's
post-roster loops add to `heatableSubsystems`(0x51155c)/`weaponRoster`(0x511830)/
@@ -208,17 +209,15 @@ register. ⚠ The audit also flags the damage-economy item as SELF-CONTRADICTOR
behavior in [[experience-levels]] (+ [[decomp-reference]] §3 flag table).** Resolved en route: the
old "resolve first" items — `FUN_004ad7d4` (labeled both `HeatModelActive` and `OwnerAdvancedDamage`)
is ONE body reading `player+0x260` = the heat-model master switch (veteran+expert); `FUN_004ac9c8`
reads `player+0x274` = the novice lockout; the btplayer.hpp `showKills`/`roleClassIndex` scoring
names indeed do NOT match the gate semantics (comments corrected in place, member names kept).
**The wiring (small, still open):** ONE accessor family on BTPlayer named members seeded from
`BTMission::ExperienceLevel()`/`AdvancedDamageOn()` (databinding trap: do NOT raw-read
`player+0x260`), then point the five stub sites at it (`HeatModelActive` permissive-1 in
emitter/heat/mislanch/projweap vs `OwnerAdvancedDamage` False in myomers — currently the SAME gate
answered both ways; `LiveFireEnabled`/`ControlsAllowLights`/powersub short-event = the +0x25c
flag under three names; ctor seeding from role->returnFromDeath is a bring-up stand-in that runs
every mission as VETERAN). NOTE: these are MODE flags — an egg with `experience=standard` should
authentically have inert movement-heat/jams; wiring makes the tier selectable, not the basic
mission different. The MessageBoard feed is separate (StatusMessagePool, below).
reads `player+0x274` = the novice lockout.
**✅ THE WIRING LANDED (issue #2, 2026-07-20) [T2]:** the ctor now seeds from
`BTMission::ExperienceLevel()`/`AdvancedDamageOn()` via the inherited `Player::playerMission`
(the binary's +0x1f8; the old `btMission` phantom member removed), the members are renamed to
the true semantics (`simLive`/`heatModelOn`/`experienceLevel`/…), and all five gate stubs +
the FUN_004ac9c8 family (`MechSubsystem::IsDamaged`, `BT_IsBusLive`, powersub call sites) route
through the three complete-type bridges (`BTPlayerExperienceSimLive`/`…HeatModelOn`/
`BTPlayerRoleLocksAdvanced`). Every shipped egg says `experience=expert`, so default behavior is
unchanged. Detail: [[experience-levels]] §Port state.
- **✅ Authentic target acquisition RECONSTRUCTED (tasks #36/#39, 2026-07-08)** — the `Reticle`
pick-ray chain is LIVE (see [[combat-damage]] Targeting for the full port map): the crosshair =
**torso boresight** (NO free-aim mouse — the pod stick twisted the torso; you steer to aim) →
@@ -373,16 +372,18 @@ register. ⚠ The audit also flags the damage-economy item as SELF-CONTRADICTOR
-> +0x274 == 0` = the NOVICE-experience lockout for advanced cockpit systems
(2026-07-18 correction: +0x274 = the egg experience level, NOT a role class --
see [[experience-levels]]; port bridge BTPlayerRoleLocksAdvanced, btplayer.cpp;
NULL player = unlocked [T3]; bring-up seeding defaults to 2 ≈ veteran = unlocked).
AUDIT TAIL: the other
powersub.cpp sites annotated FUN_004ac9c8 (the coolant-draw gate ~:427,
ForceShortRecovery ~:444, the Generator/PowerWatcher site ~:1085) still call the
heat-family IsDamaged (simulationState != 0) stand-in -- each needs its raw fn
re-checked and swapped to the role bridge where the binary calls 4ac9c8.
NULL player = unlocked [T3]; seeded from the egg experience since issue #2).
AUDIT TAIL CLOSED (issue #2, 2026-07-20): every powersub.cpp site annotated
FUN_004ac9c8 (PoweredSubsystem::HandleMessage @4b0efc, ForceShortRecovery
@4b11bc, Generator::HandleMessage @4b21d0, PowerWatcher::HandleMessage @4b179c)
plus MechSubsystem::IsDamaged and BT_IsBusLive now call the bridge; the
state-based HeatSink::IsDamaged shadow remains only for the gauge tint.
- **Myomers authentic coupling** — the structural un-stub is INERT (mover feed + heat-gen no-op).
Real coupling needs the heat-model gate (`OwnerAdvancedDamage`/`FUN_004ad7d4` → the owning
**BTPlayer** `mech+0x190`+0x260 = veteran/expert experience, NOT 0xBD3 — see [[experience-levels]])
+ `MoverAttach` routing into the LIVE JointedMover (must be reconciled with the gait cutover first).
The heat-model gate (`OwnerAdvancedDamage`/`FUN_004ad7d4` → the owning **BTPlayer**
`mech+0x190`+0x260 = veteran/expert experience — see [[experience-levels]]) is WIRED since
issue #2, but the sim stays arithmetically inert (the Owner* motion accessors return neutral
0s). Real coupling still needs those accessors + `MoverAttach` routing into the LIVE
JointedMover (must be reconciled with the gait cutover first).
- **SeekVoltageGraph** — 4 Seek* attrs unpublished (a cluster-child, not config-called; non-blocking).
- **✅ DAMAGE ECONOMY — AUTHENTIC (task #8, 2026-07-11) [T1/T2].** The whole economy closes: