crit panel: the roll has no caller and the sink is a stub -- filed as #80

Night-6 observation (Conn Man, with screenshot): armor panel showing damage,
Critical damage display showing no crits. Investigated; it is a real port gap
in three layers, stacked on one authentic fact.

The authentic fact: the paper doll shows per-ZONE armor tint and the Critical
view is a per-SUBSYSTEM list. Different data by design -- the panel staying
dark while armor accumulates is correct right up until a subsystem takes
critical damage.

The gap: subsystem critical damage essentially cannot happen.

  1. Mech__DamageZone::CriticalHit @0049ccc4 -- the authored roll, half the
     hit to armour, half to one critical subsystem by criticalWeight -- has
     ZERO callers in the port. A raw byte-scan of the binary finds exactly
     one call site, @0x4a0461, and it sits in the un-exported decomp gap
     (nothing covers 0x4a03xx-0x4a05xx, the same dark region as the
     targeting-pick writer). The trigger conditions are unknown.
  2. MechSubsystem::TakeDamage is an empty bring-up stub (btstubs.cpp:179),
     so even a wired caller would measure a delta of zero through
     ApplyDamageAndMeasure.
  3. The only live crit sources are zone destruction (SendSubsystemDamage)
     and ammo cook-off (DistributeCriticalHit), which pin subsystem damage
     directly -- so the panel can light after a zone is destroyed outright,
     never from accumulating fire.

#28 (the vital-subsystem-crit death path) very likely shares this root and is
cross-linked. Recovery plan on #80: raw-disasm the 0x4a04xx container for the
trigger, dump MechSubsystem vtable 0050e210 slot +0x24 for the real TakeDamage
body, wire both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-07-29 09:06:28 -05:00
co-authored by Claude Fable 5
parent a5dd0eabc5
commit f7cf9850b1
+19
View File
@@ -394,6 +394,25 @@ plausibly intersected the mech's *cylinder* — the damage table is literally cy
Deciding whether that distortion is material needs a per-hit theta probe + a wheel dump (slices ×
percent tables, MadCat) — see #73 on the tracker.
## ⚠ CRITS NEVER ROLL FROM WEAPON FIRE — the trigger is un-exported + the sink is a stub (2026-07-29) [T1]
The authored crit machinery exists and is reconstructed — `Mech__DamageZone::CriticalHit @0049ccc4`
(half the damage to armour, half to ONE critical subsystem chosen by `criticalWeight`, capped by
`damagePercentage`) — but **nothing in the port calls it**. Raw byte-scan of the binary: exactly ONE
call site, `@0x4a0461`, inside the **un-exported gap** (no decomp covers `0x4a03xx-0x4a05xx` — the
same dark region as the `0x37c/0x388/0x38c` pick writer), so the crit TRIGGER CONDITIONS (per-hit
chance? threshold crossing?) are unknown and unreconstructed. Second layer:
`MechSubsystem::TakeDamage` is an **empty bring-up stub** (`btstubs.cpp:179`), so even a wired
caller would measure a delta of 0 through `ApplyDamageAndMeasure` (and the weapon-family overrides
chain to the engine base whose private-zone write is the zero-`damageScale` no-op — see the
subsystem-zone finding above). Net: **the Critical view lights ONLY on zone destruction
(`SendSubsystemDamage`, direct pin) or ammo cook-off (`DistributeCriticalHit`, direct pin), never
from accumulating fire.** The DISPLAY is fine — the paper doll shows ZONE ARMOR, the Critical panel
shows SUBSYSTEM crits (different data by design); the panel's near-permanent emptiness is the gap.
Field signature (night 6, Conn Man): "Armor panel damage. Critical damage display did not show any
crits." **#28 (vital-subsystem-crit death path) is very likely blocked by the same missing caller.**
Recovery: raw-disasm the `@0x4a04xx` container (#60-class gap work) for the trigger; dump
MechSubsystem vtable `0050e210` slot `+0x24` for the real TakeDamage body; wire both. Tracker: #80.
## Damage delivery + the real damage model
`Entity::TakeDamageMessage(id, size, inflictingEntityID, zone, Damage&)``target->Dispatch`.
**Base handler IGNORES zone==1** (`Entity::TakeDamageMessageHandler`, ENTITY.cpp:878 — returns on