The Mech per-impact hit-location resolver (the cylinder damage table) is now functional, wired, and runtime-verified [T2]. Unaimed (zone==-1) hits — the collision-damage path — now resolve an impact point to a damage zone via the authentic height x angle grid + weighted dice roll, instead of dropping. dmgtable.cpp/.hpp was a non-functional skeleton on no-op ReconTable/stream shims; backed it with real std::vector storage and fixed 5 latent runtime bugs: - ReadEntries now consumes the leading cell name-string ([i32 len][len+1]) - PieSlice ctor reads rotateWithTorso into the correct member - SelectSlice direct-indexes (was int lookup on a float-keyed table) - ResolveHit returns the zone (chains SelectSlice -> SelectZone) - real MemoryStream::ReadBytes (was a variadic no-op) mech.cpp ctor: replaced the empty-name StandingAnimation stub with the real load — FindResourceDescription(dzRes->resourceName, type 0x1d) -> stream -> new DamageLookupTable, cached at mech[0x111]; ~Mech deletes it. Mech::TakeDamageMessageHandler override registered (MESSAGE_ENTRY overlays Entity's by ID): on invalidDamageZone, resolve via the table then base-route; aimed reticle hits pass through unchanged. Three named accessors (no databinding-trap raw reads): WorldToLocal (localToWorld.MultiplyByInverse), CylinderReferenceHeight (standingTemplateMaxY == collisionTemplate->maxY == binary mech+0x2ec[+0xc]), TorsoHeading via a BTGetTorsoTwist bridge in torso.cpp (Torso::CurrentTwist == torso+0x1d8; torso.hpp cannot be included into mech.cpp — subsystem-stub collision). Stream format + geometry + roll + handler were all byte-verified against the shipped BTL4.RES type-29 resources (18 tables, exact consumption) and the disassembly (FUN_0049eb54/e678/de14, glue 0x49ed0c, handler @0x4a037a). Runtime: boots clean, "[cyl] table 'bhk1' layers=7" (exact byte-verified layer count, found by name), mech spawns + walks, no asserts/AV/0xCDCDCDCD. Env gate BT_CYL_LOG=1. Unblocks collision-damage application. KB updated (combat-damage.md STEP 6 COMPLETE, open-questions.md marked done). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9.2 KiB
9.2 KiB
id, title, status, source_sections, related_topics
| id | title | status | source_sections | related_topics | |||||
|---|---|---|---|---|---|---|---|---|---|
| open-questions | Open Questions — deferred systems, unknowns, get-from-Nick | living | CLAUDE.md §9; docs/HARD_PROBLEMS.md; per-subsystem deferral notes |
|
Open Questions
Known unknowns + deliberately-deferred systems. For each: what's known, what's missing, what would resolve it, status. Deferred ≠ broken — most are marked-and-guarded stand-ins with the authentic path scoped.
From Nick (external — gating for some paths)
- [GATING] The BT game SOURCE CODE — the missing implementation
.cpp(mech, subsystems, mapper, HUD, app; see source-completeness). Without it, Route A (recompile original) is impossible; we reconstruct from the binary instead. Likely on a backup/dev drive. Status: OPEN. - Confirmation the PodPC image is the complete content master. (Low priority — the runtime
BTL4.RESalready has 8 maps + the full mech anim set.) Status: OPEN. - Pod specifics for Phase 8: the 7-monitor driver setup, the RIO cockpit I/O protocol, current Win10+wrapper pod config. Status: OPEN.
Deferred subsystems / feeds (authentic path scoped, marked in code)
- 0xBD3 SubsystemMessageManager (WAVE 8) — a per-mech damage/explosion consolidation hub
(
ConsolidateAndSendDamagePerformance @0049b784,weaponExplosionsqueue,CommonDamageInformation; messmgr.hpp). ctorFUN_0049bca4(vtable 0x50b954, installs a Performance → ticks). The factory caches it toMech[0x10d]= byte 0x434. What wiring it needs: an untangle — our reconstruction MISLABELEDMech[0x10d]ascontrolsMapperandmech4's live drive reads it as the mapper, so the real messmgr can't land there until the drive is re-pointed to the true mapper (roster slot 0, installed bySetMappingSubsystem/MakeViewpointEntity; aMechRIOMapper). Payoff = authentic damage/explosion consolidation (a COMBAT-fidelity improvement) + fixing the mapper/messmgr conflation. ⚠ CORRECTION (verified 2026-07): 0xBD3 does NOT gate the valve/Myomers/MessageBoard — those read a DIFFERENT object atmech+0x190(bothFUN_004ac9c8the valve guard→+0x274andFUN_004ad7d4the Myomers gate→+0x260derefowner+0x190, which ≠ the 0x434 messmgr cache). The earlier "0xBD3 gates 4 things" note was wrong. - ✅
mech+0x190IDENTIFIED (2026-07): it is the owningBTPlayer(Mech::GetPlayerLink(),MECH_OWNING_PLAYER; ENTITY.h:430). Set byFUN_0049f624(the mech↔player bind:mech+0x190 = playerANDplayer->playerVehicle(+0x1fc) = mech), which resolves the player from the mission player registry (app+0x2c+0x54,FUN_0041fd18) by the pilot key. The valve/Myomers "gates" read the owning player's fields atplayer+0x260andplayer+0x274(the reconstruction maps this block asshowDamageReceived@0x25c / showKills@0x260 / showDamageInflicted@0x264 / roleClassIndex@0x274in btplayer.hpp — from the SCORING work, so the names may NOT match the gate semantics; the true meaning + the WRITER ofplayer+0x260/0x274are not yet pinned — part_013.c:4553-4660 is the TorsoSimulation, a different object, not the setter). So there is NO new subsystem to build. The wiring (small): pointMechSubsystem::IsDamaged()(FUN_004ac9c8, valve guard) atGetPlayerLink()->(0x274) andMyomers::OwnerAdvancedDamage()(FUN_004ad7d4) atGetPlayerLink()->(0x260) — via NAMED members (databinding trap: our BTPlayer layout ≠ binary; do NOT raw-readplayer+0x260). ⚠ Resolve first: (a) a naming conflict —FUN_004ad7d4is labeled BOTHHeatModelActive(heat.hpp) ANDOwnerAdvancedDamage(myomers.cpp); re-verify which body is which; (b) the true semantic ofplayer+0x260/0x274vs the scoring-derivedshowKills/roleClassIndexnames. NOTE: these are MODE flags — in the basic test mission the inert Myomers / dormant valve is likely AUTHENTIC (advanced damage off); wiring makes them RESPOND when a mission enables the mode, not necessarily change the basic-mission behavior. The MessageBoard feed is separate (StatusMessagePool, below). - StatusMessagePool (NULL stub, btstubs.cpp:62) — the per-player status-message queue.
BTPlayer+0x1dc is never populated → MessageBoard is empty (authentic for bring-up). What
resolves it: wire the pool + decode
AddStatusMessage @0042e580+ thePlayer__StatusMessagerecord ({messageId@+0xc, nameEntity@+0x10}). - Gyroscope (0xBC4) — layout + joint-I/O reconstructed, but the ctor field-init + the two integrators (IntegrateEyeJoint @004b2ec0 / IntegrateBody @004b30ec) are incomplete → writes NaN to the root joint. Reverted to a stub. A full subsystem-sim reconstruction (bigger than Torso).
- MechControlsMapper look/eyepoint commit — reconstructed but its offsets collide with declared
members; arbitrate before enabling (no port consumer yet). The fire-trigger-through-mapper is
still the
gBTWeaponTriggerbring-up. - Myomers authentic coupling — the structural un-stub is INERT (mover feed + heat-gen no-op).
Real coupling needs the advanced-damage gate (
OwnerAdvancedDamage/FUN_004ad7d4→ the owning BTPlayermech+0x190+0x260, NOT 0xBD3 — see the mech+0x190 item above) +MoverAttachrouting 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).
Locomotion / combat polish (non-gating)
- Authentic per-mech TURN-RATE constant (currently a bring-up constant rate).
- Body-callback gimp handlers (states 16-19, targets 0x70b2/0x7161 undecoded → fall back to stand);
airborne callbacks (
FUN_004a6344/FUN_004a7970). - Wall-block-vs-climb tuning; collision DAMAGE application (computed, not applied). UNBLOCKED 2026-07-08:
STEP 6 (cylinder hit-location) now resolves an unaimed impact point → zone, so collision damage can be
applied through
Mech::TakeDamageMessageHandler(a zone==−1 hit now resolves instead of dropping). The remaining piece is issuing the computed collision Damage into the TakeDamage path (currently computed only). - ✅ Cylinder hit-location (STEP 6) — DONE 2026-07-08 [T2]. Built + runtime-verified: the
dmgtable.cppclasses now have real storage + a workingResolveHit→zone, the mech ctor loads the type-0x1d table by the DamageZoneStream name ([cyl] table 'bhk1' layers=7), andMech::TakeDamageMessageHandlerresolves unaimed (zone==−1) hits before base-routing. Full change list in combat-damage "STEP 6 COMPLETE". The live collision-damage path (zone==−1 → resolve) is now UNBLOCKED. Historical investigation notes retained below for provenance. Re-investigated 2026-07 (see combat-damage for the full algorithm): the table (height×angle grid, resource type 0x1d) IS built (reconStandingAnimation@Mech[0x111], but with an EMPTY name → 0 rows, becauseResourceFindByNameis a no-op template stub). CORRECTION to the earlier note: the LOOKUP is exported [T1] —FUN_0049eb54(table height→row) +FUN_0049e678(row angle→cell), NOT unexported. Only the thinMech::TakeDamageMessageHandlerglue (zone==-1 → call the lookup →damageZones[zone]->TakeDamage) is unexported, and it's fully implied by pieces already reconstructed → no disassembly needed. Remaining: 6b realFindByName(name = the mech's type-0x14 DamageZoneStream name @ResourceDescription+0xc); 6c the 3 container ctors + the lookup as aBTCylinderResolveZonebridge (ground the cell zone-dict stream format vs the real .RES bytes); 6d register the handler + verify. Feasible; the only open risk is the cell stream format. The earlier-citedFUN_004a0230/FUN_0049ed0cdon't exist. - Death: reconstruct
DeathShutdown(RPVTV::DeathShutdownanalog) + collapse anim + destroyed skin. The wreck-stays behavior we ship is faithful; do NOT issue DestroyEntityMessage on death.
Multiplayer (Phase 7 / P6)
- Cross-pod COMBAT (target a replicant + route damage to the owning master).
- Replicant GAIT animation (replicants don't animate joints yet — derive from replicated velocity).
- The pod-LAN config (real IPs, bare-IP pilot entries). The WinSock2 TCP stack (L4NET.CPP) is reconstructed + smoke-tested on one box (two instances share a world, movement replicates).
Rendering follow-ups (non-blocking)
- Replacement-LOD selection for NON-additive multi-LOD models (needs the board's hot-spot/
reference-point semantics; leads:
s_dplobject.lod_ranges[16]/lod_hot_spot, 0x2047/0x2048). - Day/night MATERIAL path priority (BMF/IMG) — infrastructure done, gated
BT_MATPRI(over-applies to shared terrain mats); needs the terrain-material model understood. - RGBA4444 alpha (TREE.BSL cutout) decoded but not alpha-tested outside punch batches; VTX/TGA paths.
Content build sub-project (low priority)
- Lab/other-build maps (
des/burnt/frstrm) are source-only (.mapin CONTENT/BT/MAPS/); would need compiling into a RES via the DOSbtl4tool.exe. The 8 RES maps cover testing.
Key Relationships
- Feeds from: every subsystem/render topic (their deferral notes collect here).
- Gating master: source-completeness (the missing BT source).