KB: EXPERIENCE LEVELS decoded -- the 0x25c block is the simulation-mode flags
The egg's per-pilot 'experience' (novice/standard/veteran/expert) is the pod's simulation-fidelity tier -- stored at BTMission+0xe4 and seeded into the BTPlayer ctor's flag block @4c0bc8 [T1]. The old 'per-role display toggles / returnFromDeath' reading was WRONG: the source is mission->experienceLevel, and the neighboring pair copies mission->advancedDamageOn (the egg's technician splash/collision switch), not role floats. Known consumers: 0x260 = the HEAT-MODEL master switch (FUN_004ad7d4), 0x25c = the novice sim-lockout (jams/searchlight/powersub), 0x274 = the raw level (FUN_004ac9c8 ==0 novice predicate). NEW established topic context/experience-levels.md (data path, binary flag rows per level, manual cross-refs, corrections log) + router row; sweeps in decomp-reference/gauges-hud/open-questions/pod-hardware/subsystems. btplayer.cpp/.hpp re-annotated with the corrected semantics; the guarded role-based seeding stays as a marked [T3] stand-in (slot drift vs the binary switch documented inline) until the wiring task points it at BTMission::ExperienceLevel(). (Research by the parallel context session; committed from the glass line.) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
---
|
||||
id: experience-levels
|
||||
title: "Experience levels / simulation modes — novice, standard, veteran, expert"
|
||||
status: established
|
||||
source_sections: "decomp part_013.c:10816-10871 (@4c0bc8), part_014.c:7830-7900 (@4d2f3e), FUN_004ad7d4/FUN_004ac9c8/FUN_004bbfcc; BTMSSN.HPP (survived); Tesla40_BT_manual.pdf pp.7,11-14,21,22,24"
|
||||
related_topics: [subsystems, combat-damage, gauges-hud, pod-hardware, multiplayer, decomp-reference, open-questions]
|
||||
key_terms: [master, replicant]
|
||||
open_questions:
|
||||
- "player+0x26c (std+vet only) and +0x270 (all but novice) consumers not located — 0x26c hypothesis: myomer supercharge clamp (manual p22) [T4]"
|
||||
- "does a remote pilot's experience matter cross-pod? flags are computed only on the master branch of the BTPlayer ctor [T4]"
|
||||
- "movement-heat magnitude veteran vs expert (4.0 manual says expert-only; 4.10 gate is vet+expert) [T4]"
|
||||
---
|
||||
|
||||
# Experience levels / simulation modes
|
||||
|
||||
The egg's per-pilot `experience` field is the pod's **simulation-fidelity tier** — the thing the
|
||||
1995 site operator set per player at sign-up. It is NOT the BAS/MID/ADV control mode (a free
|
||||
in-cockpit choice, [[locomotion]]/[[pod-hardware]]) and NOT the scenario role (scoring modifiers).
|
||||
Researched end-to-end 2026-07-18; this file supersedes the older "role display toggles" /
|
||||
"ROOKIE-role lockout" readings (see Corrections below).
|
||||
|
||||
## The data path [T1]
|
||||
|
||||
1. **Egg**: pilot page key `experience` ∈ {`novice`,`standard`,`veteran`,`expert`}; required unless
|
||||
`vehicle=camera`; unknown value = hard abort. Parse @4d2f3e (part_014.c:7830-7900, strings
|
||||
@51e6f1); `tools/eggmodel.py` knows the value set.
|
||||
2. **BTMission** (`BTMSSN.HPP` survived, T0): stored at `mission+0xe4` (`experienceLevel`, accessor
|
||||
`ExperienceLevel()`); the neighboring egg key `advancedDamage` → `mission+0xf0`
|
||||
(`advancedDamageOn`) — the separate site-technician splash/collision switch (manual p13).
|
||||
3. **BTPlayer ctor @4c0bc8** (part_013.c:10816-10871): on the MASTER branch
|
||||
(`(simulationFlags & 0xc) != 4`; the replicant branch instead swaps in the console-update
|
||||
Performance) it reads `btMission(+0x1f8)->experienceLevel(+0xe4)` and fans it out:
|
||||
|
||||
| egg value | +0x25c | +0x260 | +0x26c | +0x270 | +0x274 (raw) |
|
||||
|---|---|---|---|---|---|
|
||||
| novice | 0 | 0 | 0 | 0 | 0 |
|
||||
| standard | 1 | 0 | 1 | 1 | 1 |
|
||||
| veteran | 1 | 1 | 1 | 1 | 2 |
|
||||
| expert | 1 | 1 | 0 | 1 | 3 |
|
||||
|
||||
then unconditionally `+0x264 = +0x268 = mission->advancedDamageOn(+0xf0)` (both copies). [T1]
|
||||
|
||||
## What each flag gates (binary consumers, all reached via `mech+0x190` → BTPlayer) [T1]
|
||||
|
||||
- **+0x25c — "sim live", off only for novice.** Consumers: ballistic jam roll `CheckForJam`
|
||||
@4bbfcc early-returns NO-JAM when 0 (projweap.cpp calls this `LiveFireEnabled`); Searchlight
|
||||
`ToggleLamp` @4b860c (searchlight.cpp `ControlsAllowLights`); PoweredSubsystem message handler
|
||||
@4b0efc (powersub.cpp's "message-manager short-event flag" — same flag, misattributed); the mech
|
||||
combat-ineffective evaluation (part_012.c:9364: mech state ∈ {3,4} && novice is an extra OR-term
|
||||
setting `mech+0x414`). The `#if 0` block in surviving PPC.CPP:63-95 (novice PPCs deal no damage)
|
||||
shows the original intent of the tier.
|
||||
- **+0x260 — the HEAT-MODEL master switch, ON for veteran+expert.** This is `FUN_004ad7d4`
|
||||
(`*(*(sub+0xD0)+0x190)+0x260`), the single most-called gate in the subsystem family: Myomers
|
||||
work→heat (movement heat, MyomersSimulation @4b8d18), Emitter/energy-weapon firing heat, missile
|
||||
launch heat, the heat.cpp simulation, projectile-weapon heat, and the heat-scaled part of the jam
|
||||
chance. Standard mode has NO heat consequences; that is authentic, not a port gap.
|
||||
- **+0x274 — the raw level.** `FUN_004ac9c8` = (level == 0), the NOVICE lockout used as the
|
||||
condenser-valve guard ([[gauges-hud]] task #13) and by the PoweredSubsystem handler @4b21d0
|
||||
(not-novice gate). The port's `BTPlayerRoleLocksAdvanced` bridge implements this predicate
|
||||
(correct behavior, wrong seeding — see Port state).
|
||||
- **+0x264/+0x268 — advancedDamage copies.** Read in the heat-family sim (part_013.c:8757).
|
||||
Independent of experience.
|
||||
- **+0x26c / +0x270 — consumers NOT located** via the mech→player hop. 0x26c (standard+veteran
|
||||
only) best fits the manual-p22 myomer supercharge clamp (standard locked, expert unlocked) [T4].
|
||||
|
||||
## Player-facing behavior (Tesla 4.0 manual) [T1 primary source]
|
||||
|
||||
Manual pp. 7, 11-14, 21, 22, 24 (the dedicated Simulation Modes page, manual p2, is MISSING from
|
||||
the `Tesla40_BT_manual.pdf` scan along with p3):
|
||||
- **Standard**: armor-only damage — no criticals, no generator outages, no jams, no heat concerns;
|
||||
MechTech limited to the leg-damage audio warning; viewscreen hunting aids (red hot box + guide
|
||||
arrow, 60° FOV) on; myomer supercharge locked.
|
||||
- **Veteran**: critical hits (any hit can go internal; likelihood rises as armor thins; a crit can
|
||||
kill the mech), generators take damage/go offline (reroute power), ballistic jams (manual
|
||||
clearing), full MechTech audio + smart buttons; viewscreen hunting aids OFF (radar hot box stays).
|
||||
- **Expert**: veteran + heat as a core mechanic: movement generates heat (accel/decel worst),
|
||||
heat slows recharge/top speed, incoming fire causes coolant leaks, ammo-bay fires/cook-off;
|
||||
myomer supercharge allowed.
|
||||
- Scoring identical in all modes (p4). Splash/collision damage = a separate technician setting.
|
||||
|
||||
## 4.0 → 4.10 drift [T1]
|
||||
|
||||
- **The viewscreen hunting-aid gate is GONE in 4.10**: part_014 (HUD/btl4vid TU) reads none of the
|
||||
player flags — the target hotbox/edge arrows (@4cdf6f) are gated on lock state only, every mode.
|
||||
Fits the 4.10 arcade-cities positioning.
|
||||
- **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]
|
||||
|
||||
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.
|
||||
|
||||
## Corrections (swept 2026-07-18)
|
||||
|
||||
- `btplayer.hpp` "per-role display toggles from returnFromDeath" for 0x25c-0x274 was WRONG — the
|
||||
source is `btMission+0xe4/+0xf0`, not the role; the `showKills`/`roleClassIndex` names date from
|
||||
the scoring work and don't match the gate semantics (kept in code for now, comments corrected).
|
||||
- `gauges-hud.md` "ROOKIE-role lockout" for FUN_004ac9c8 → novice-EXPERIENCE lockout.
|
||||
- `open-questions.md` "true semantic of player+0x260/0x274 not yet pinned" → pinned here.
|
||||
|
||||
## Key Relationships
|
||||
- Feeds: [[subsystems]] (the heat model + jam/valve gates) · [[combat-damage]] (criticals tier intent) · [[gauges-hud]] (valve guard)
|
||||
- Sourced from: the egg ([[multiplayer]] egg format) · `BTMission` (BTMSSN.HPP, T0)
|
||||
- Offsets: [[decomp-reference]] §3 (mech+0x190 row + BTPlayer flag block)
|
||||
- Manual audit: [[pod-hardware]] §Manual
|
||||
Reference in New Issue
Block a user