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:
co-authored by
Claude Fable 5
parent
a0cec48e3f
commit
d7158f1f82
@@ -86,22 +86,41 @@ the `Tesla40_BT_manual.pdf` scan along with p3):
|
||||
- **Movement heat is veteran+expert in 4.10** (the +0x260 gate), not expert-only as the 4.0 manual
|
||||
states. Whether a coefficient still differentiates them is open.
|
||||
|
||||
## Port state (as of 2026-07-18) — wiring needed [T3]
|
||||
## Port state (as of 2026-07-20) — WIRED (issue #2) [T2]
|
||||
|
||||
The reconstruction met this system piecemeal and stubbed the same gates inconsistently:
|
||||
- `btplayer.cpp` ctor seeds `roleClassIndex` from `scenarioRole->GetReturnFromDeath()` (default 2)
|
||||
— the binary seeds it from `btMission->ExperienceLevel()`. Bring-up therefore runs as VETERAN.
|
||||
Two slot errors in the port's switch vs the binary: the binary's switch never touches +0x264
|
||||
(that's advancedDamage, set after), and expert's `0` lands on +0x26c, not +0x270.
|
||||
- `HeatModelActive()` stubbed permissive `return 1` (emitter/heat/mislanch/projweap) while
|
||||
`Myomers::OwnerAdvancedDamage()` returns `False` — the SAME binary gate (+0x260) answered both
|
||||
ways: heat accrues from weapons but never from movement, and no experience below veteran can
|
||||
switch it off.
|
||||
- `LiveFireEnabled` / `ControlsAllowLights` / powersub's short-event flag = the +0x25c not-novice
|
||||
flag under three names.
|
||||
- **The fix**: one accessor family on BTPlayer named members (databinding trap — never raw-read
|
||||
`player+0x260`), seeded from `BTMission::ExperienceLevel()` + `AdvancedDamageOn()`, with all five
|
||||
stub sites pointed at it; then an egg `experience` line actually selects the sim tier as shipped.
|
||||
The wiring landed (uncommitted during the coordination pause; issue #2):
|
||||
- **Seed**: the `BTPlayer` master ctor (`btplayer.cpp` ~1305) now reads
|
||||
`((BTMission *)playerMission)->ExperienceLevel()` + `->AdvancedDamageOn()`. The binary's +0x1f8
|
||||
mission pointer IS the inherited `Player::playerMission` (master: set by the base ctor;
|
||||
replicant: back-filled from `Application::GetCurrentMission()` = app+0xc8) — the old separate
|
||||
`btMission` member was a phantom duplicate, never set on the master branch; removed. The two
|
||||
switch slot errors are fixed (binary rows verified against part_013.c:10843-10870). A `[exp]`
|
||||
sentinel logs the seeded flags per master player.
|
||||
- **Renames** (btplayer.hpp): showDamageReceived→`simLive` (0x25c), showKills→`heatModelOn`
|
||||
(0x260), showDamageInflicted→`advancedDamageOn` (0x264), roleReturnDelay→`advancedDamageOn2`
|
||||
(0x268, was mistyped Scalar), roleReturnDelay2→`levelFlag26c` (0x26c), showScore→`levelFlag270`
|
||||
(0x270), roleClassIndex→`experienceLevel` (0x274).
|
||||
- **Bridges** (btplayer.cpp, complete-type TU): `BTPlayerExperienceSimLive` (+0x25c) and
|
||||
`BTPlayerExperienceHeatModelOn` (+0x260) join `BTPlayerRoleLocksAdvanced` (+0x274==0). All
|
||||
consumers route mech→`GetPlayerLink()`→named member; NULL player reads permissive [T3].
|
||||
- **Gates unified**: `HeatSink::HeatModelActive()` (heat.hpp; also serves mislanch/projweap/
|
||||
heatfamily call sites) + `Myomers::OwnerAdvancedDamage()` (myomers.hpp) → the +0x260 bridge;
|
||||
`ProjectileWeapon::LiveFireEnabled()` (projweap.cpp) + `Searchlight::ControlsAllowLights()`
|
||||
(searchlight.hpp) → the +0x25c bridge; `PoweredSubsystem::HandleMessage` @4b0efc (powersub.cpp)
|
||||
→ not-novice + the +0x25c bridge (the old "message-manager short-event flag" misattribution and
|
||||
its dead `BT_GetMessageManager` guard are gone).
|
||||
- **FUN_004ac9c8 family corrected**: `MechSubsystem::IsDamaged` (mechsub.cpp — was a live
|
||||
raw-offset databinding trap `*(*(*(owner+0xd0)+0x190)+0x274)`), `BT_IsBusLive` (btstubs.cpp —
|
||||
was `return True`), and powersub's `IsDamaged()` call sites @4b11bc/@4b21d0/@4b179c now all
|
||||
route through `BTPlayerRoleLocksAdvanced`. `HeatSink::IsDamaged` (heat.hpp) deliberately keeps
|
||||
the simulationState shadow for the gauge tint (btl4gaug.cpp:172).
|
||||
- **SHIPPED EGGS ARE ALL `expert`** (every pilot page in all 19 content/*.EGG, camera pages
|
||||
included) — so the default felt behavior is unchanged by the wiring (expert and the old
|
||||
hardwired veteran agree on every LOCATED consumer: sim live, heat on, controls unlocked; they
|
||||
differ only in the unlocated +0x26c flag). The glass front-end writes `veteran` when a pilot's
|
||||
experience is empty (btl4fe.cpp:307).
|
||||
- Myomers movement heat remains arithmetically inert (the Owner* motion accessors still return
|
||||
neutral 0s — the gate is wired, the couplings are the reconciled follow-up).
|
||||
|
||||
## Corrections (swept 2026-07-18)
|
||||
|
||||
|
||||
+23
-22
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user