#83: the COLLISION DIVERT -- type-0 damage prices as internal rattle, never armor
The crash self-damage reconstruction (9c83a46) exposed its missing second
half: the binary's TakeDamage hub DIVERTS damageType 0 (@0x4a0368) into
FUN_0049ffcc -- an export-gap distributor recovered by raw disasm -- so
collision damage NEVER reaches the zone/armor loop. Without the divert the
mover's raw kinetic-energy figure (60-ton mech: ~1000+ per wall tap, 90k+ on
a hard slam) fell into the WEAPON loop: 'tapped a wall and died instantly'.
The distributor, byte-anchored: gate on the owning player's advancedDamage
copy (+0x268 -- the manual's 'splash/collision damage' technician setting);
scale = (2000/moverMass) / (100 km/h in u/s)^2 / (1 - elasticity^2)
(tbyte 1/3.6 @0x4a0148; mass @+0x20c; elasticity @+0x244); scaled < 0.5 is
FREE; else Round(2x) sub-hits of 0.5 land on random INTERNAL subsystems
(HeatSink family / Gyroscope / Torso, drawn by collisionCriticalHitWeight
@0x10C) via ApplyDamageAndMeasure (@0x4ac07c). Bridges: family derivations
(heat/gyro/torso.cpp), BTPlayerAdvancedDamageOn (btplayer.cpp).
Verified: bhk1 wall test -- 94k slam = 4.2 rattle pts in 8 sub-hits, taps
free (0.049 < 0.5), armor untouched. A/B: arena wall-grind now 0 deaths,
27 rattle events, the limper STAYS GIMPED and peers' replicants re-enter the
gimp cycle between bounded staggers; grass circling unchanged (198 replicant
gimp entries). [crashdmg]/[colldmg] probes document the pricing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9c83a468db
commit
14ff3519ac
@@ -872,6 +872,23 @@ its decomp writers (4668/10512) read as a per-frame state toggle, not a clean co
|
||||
port's `showDamageInflicted` label is itself a guess; port treats authored `SplashRadius>0` as the
|
||||
enable. See [[open-questions]].
|
||||
|
||||
## Collision damage — the type-0 DIVERT + rattle distributor (#83, 2026-07-30) [T1 disasm/T2]
|
||||
`Mech::TakeDamageMessageHandler` diverts `damageType==0` (@0x4a0368) into
|
||||
`DistributeCollisionDamage` (FUN_0049ffcc, export gap, raw disasm `scratchpad/night6/
|
||||
gap_49ffcc.txt`): collision damage **never reaches the zone/armor loop**. Gate: the owning
|
||||
player's advancedDamage copy (+0x268, `BTPlayerAdvancedDamageOn` bridge) — the manual's
|
||||
"splash/collision damage" technician setting. Pricing: `raw × (2000/moverMass)/(100·(1/3.6))²/
|
||||
(1−elasticity²)` (constants @0x4a0148=1/3.6 tbyte, 2000f, 0.5f threshold; mass@+0x20c,
|
||||
elasticity@+0x244 by Mover-layout walk); scaled <0.5 = FREE. Above: `n=Round(2×amount)`
|
||||
sub-hits of amount/n, each landed on ONE roster subsystem drawn by cumulative
|
||||
`collisionCriticalHitWeight` (@0x10C, MechSubsystem) vs a [0,1) roll, eligibility =
|
||||
IsDerivedFrom HeatSink-family/Gyroscope/Torso (GUIDs 0x50e590/0x50fdc0/0x510b08; all
|
||||
MechSubsystem-based, so +0x10C is valid), applied via `ApplyDamageAndMeasure` (@0x4ac07c —
|
||||
the subsystem TakeDamage virtual into its PRIVATE crit zone). Un-won rolls land nowhere
|
||||
(weights un-normalized — faithful). Mech-vs-mech ram damage arriving as type 0 prices the
|
||||
same way. Measured on bhk1 (mass 60000, e=0.2): scale 4.5e-5; a 94k spawn-slam = 4.2 rattle
|
||||
points; taps free. `[colldmg]` (BT_DMG_LOG) + `[crashdmg]` (always-on, rare) are the probes.
|
||||
|
||||
## Key Relationships
|
||||
- Weapons/roster: [[subsystems]]. Aim source: [[locomotion]] (drive/facing). Effects: [[rendering]].
|
||||
- P5 forensics: `docs/HARD_PROBLEMS.md`. Data: [[decomp-reference]] §4-5.
|
||||
|
||||
+15
-8
@@ -223,14 +223,21 @@ churn — gliding + trn leg-lifts = "skating". 4-config A/B (`scratchpad/night6/
|
||||
`[animind]` inst=1 verdict): grass straight/circle clean (198 gimp entries; **17 car crunches
|
||||
during it — crushable icons are the `0.00123f` sentinel path, gyro kick only, NO broadcast**);
|
||||
arena1 single strike recovers (196); arena1 wall-grind = 0 gimp entries.
|
||||
**What actually bounds the loop in the binary — and what the port was missing — is the crash
|
||||
SELF-DAMAGE**: the blocking branch (export gap @4aa89f-4aaab4, raw disasm
|
||||
`scratchpad/night6/gap_4a9770.txt`) fills `throttleState`=surface material,
|
||||
`fallDirection`=worldToLocal(dmg.damageForce) (FUN_0040879c = Mᵀv, un-normalized),
|
||||
`fallScalar`=−(fallDirection·localVelocity.linearMotion), then **Dispatches
|
||||
`TakeDamageMessage{0x64, zone=−1, the engine-computed collision Damage verbatim}` at its own
|
||||
mech** — wall crashes hurt, grinding degrades the mech, the storm self-limits. That dispatch was
|
||||
the port's long-standing "DEFERRED" note; now reconstructed (mech4.cpp blocking branch).
|
||||
**What the port was missing is the crash SELF-DAMAGE *and its own pricing path*** (two halves;
|
||||
the first alone one-shot mechs on wall taps — corrected same day): the blocking branch (export
|
||||
gap @4aa89f-4aaab4, `scratchpad/night6/gap_4a9770.txt`) fills `fallDirection`=worldToLocal(
|
||||
dmg.damageForce) (FUN_0040879c = Mᵀv, un-normalized), `fallScalar`=−(fallDirection·localVelocity
|
||||
.linearMotion), then **Dispatches `TakeDamageMessage{0x64, zone=−1, the collision Damage
|
||||
verbatim}` at its own mech** (was the long-standing "DEFERRED" note; mech4.cpp). CRUCIALLY the
|
||||
TakeDamage hub then **DIVERTS damageType 0 (@0x4a0368 → FUN_0049ffcc, gap disasm
|
||||
`gap_49ffcc.txt`) — collision damage NEVER touches zone armor.** It is the manual's
|
||||
"splash/collision damage" technician setting: gated on the player's advancedDamage copy
|
||||
(+0x268), priced `raw × (2000/mass)/(100/3.6)²/(1−elasticity²)` (a 60-ton mech: ~4.5e-5 — a
|
||||
wall tap prices ~0.05, and <0.5 is FREE), then split into 0.5-point RATTLE CRITS applied to
|
||||
random internal subsystems (HeatSink family/Gyroscope/Torso, drawn by
|
||||
`collisionCriticalHitWeight`@0x10C). See [[combat-damage]]. Verified: wall-grinding no longer
|
||||
kills or heals the limper (0 deaths, 27 rattle events, mech stays gimped) and the peer's
|
||||
replicant re-enters the gimp cycle between bounded staggers; grass circling unchanged (198).
|
||||
**Falsified en route (do not revive):** (a) "the stagger's action-request flags feed a drive
|
||||
suppressor" — image-wide + full-gap sweep shows `word[this+0x18]` is read ONLY by the net record
|
||||
emitter; (b) "the bmp clip's ~6.5 u/s root motion presses back into the wall" — measured `adv=0
|
||||
|
||||
Reference in New Issue
Block a user