# BTPLAYER.CPP / .HPP — reconstruction notes **Status: constructor / dtor / Make / TestInstance / GetExperienceLevel + message-handler table + DropZoneReply dispatch RECONSTRUCTED; the scoring/death handlers, PlayerSimulation, and CreatePlayerVehicle/InitializePlayerLink (the Mech-subsystem frontier) still staged.** ## Message-handler table (wired 2026-07-19) DefaultData now uses `BTPlayer::MessageHandlers` (chained onto `Player::MessageHandlers`) instead of reusing the base set — the earlier reuse left BTPlayer's own handlers unwired, so a DropZoneReply reached the base `Player::DropZoneReplyMessageHandler` stub that Fails "should not be handled by base player class!" (PLAYER.CPP:179). Table entries (BT411 .data @005130c0): DropZoneReply, VehicleDead, Score, ScoreInflicted, ScoreUpdate. ScoreInflicted/ ScoreUpdate add two BT message IDs (`Player::NextMessageID`+0/+1). MissionStarting/ MissionEnding are inherited from Player unchanged (not re-listed — BT411 lists them but they point at the same base handlers). `DropZoneReplyMessageHandler` is the real spawn/respawn dispatch skeleton; its mech-placement tail (vehicle-class performance select, Mech::Reset respawn) is deferred with the Mech subsystem. On the first fresh-drop reply it calls `CreatePlayerVehicle` → the current boot frontier. ## Sources - BT411 `game/reconstructed/btplayer.cpp` (Ghidra-recovered ctor @004c0bc8, Make @004c0ecc, dtor @004c0efc, TestInstance @004c0f28) — byte-offset annotated body. - Surviving 1995 headers pin every base API: PLAYER.HPP (base members currentScore/scenarioRole/deathCount/playerMission, GetMission), SIMULATE.HPP (lastPerformance/lastUpdate/simulationFlags/activePerformance — `lastPerformance` is a BASE member, not BT-own), ENTITY.HPP (GetInstance/ReplicantInstance), NTTMGR.HPP (EntityManager::FindGroup, EntityGroup::groupMembers = ChainOf), TEAM.HPP (Team::teamName[64], public — BTTeam inherits it), BTMSSN.HPP (BTMission::ExperienceLevel()/AdvancedDamageOn(), enum Novice/Standard/ Veteran/Expert = 0..3), SCNROLE.HPP. ## Member layout note The staged header's `int reserved[38]` placeholder was replaced with the real BT-own members (btMission, teamName[64], teamEntity, freeForAll, consoleAttached, suppressConsole, the experience-flag block, killCount/padScore, objectiveMech, lastConsoleUpdate, deathPending). Byte offsets do NOT need to match the shipped 0x294-byte object — this is a fresh self-consistent build; only wire-format structs (MakeMessage) must match the binary, and those are unchanged. ## Experience-level flag mapping — the [T1] correction The ctor derives the game-mode flags from **btMission->ExperienceLevel()** (mission+0xe4, the egg's per-pilot "experience" key), NOT from the scenario role's returnFromDeath — see [[bt-experience-levels]]. BT411's ported ctor uses `scenarioRole->GetReturnFromDeath()` as a stand-in and marks it [T3]; this 1995 reconstruction encodes the binary-accurate reading instead. Binary switch rows (member ← value per level), from the [T1] disassembly: | level | showDamageReceived (0x25c) | showKills (0x260) | roleReturnDelay2 (0x26c) | showScore (0x270) | |----------|:--:|:--:|:--:|:--:| | novice | 0 | 0 | 0 | 0 | | standard | 1 | 0 | 1 | 1 | | veteran | 1 | 1 | 1 | 1 | | expert | 1 | 1 | 0 | 1 | Plus `showDamageInflicted` (0x264) = `roleReturnDelay` (0x268) = advancedDamageOn. **Member NAMES are wrong-but-kept** (they date from the earlier scoring work): `showKills` is really the HEAT-MODEL master switch (FUN_004ad7d4), `showDamageReceived` is the "sim live / novice lockout" gate, `showScore`/`roleReturnDelay2` consumers not fully located ([T4]). Rename is a follow-up wiring task; the VALUES are correct. ## Deliberate differences from BT411's port - Make: the 1995 `return new BTPlayer(creation_message);` — BT411's replicant `SetValidFlag()` is a P6 network-bring-up addition, dropped. - Replicant-mission caching uses `application->GetCurrentMission()` (the real 1995 accessor, PLAYER.CPP:689) instead of BT411's raw `application+0xc8`. ## Still staged (next bricks, in boot order) 1. **CreatePlayerVehicle → Mech::Make** (CURRENT FRONTIER) — the spawn chain pulls in the whole Mech subsystem: Mech ctor + mech2/mech3/mech4, mechsub, the subsystems (sensor, gnrator, gyro, torso, hud, myomers), and the weapons (mechweap, ppc, gauss, projtile, missile...). Mech::Make is still Fail-staged in MECH.CPP. This is the large game-content frontier — a major milestone, not a single brick. 2. InitializePlayerLink, the mech-placement tail of DropZoneReply (Mech::Reset). 3. VehicleDead / Score / ScoreInflicted / ScoreUpdate handlers (scoring wave), PlayerSimulation (console update), CalcInflictedScore.