#94: replicant un-wreck now rides the DEATH-STATE EXIT edge -- the zone

falling-edge latch was blind to zone-less (collision) deaths

The peer wreck lifecycle listened to two different signals: wreck ON came
from the replicated death explosion (unconditional), wreck OFF from a
damage-zone falling edge (wasWrecked latch, armed only when a zone crossed
>= 1.0 on the observer).  The #83 collision damage prices as internal
rattle and never moves a zone, so a fresh mech killed by ramming could
NEVER un-wreck on peers -- the live respawned mech drove around wearing
the hulk (night-7 field report: SAURON's Loki, screenshotted by both
observers at the exact minute the log analysis places the ram death).

MechDeathHandler::Tick now tracks prevMode and fires the rebuild + warp
when the replicated MovementMode leaves the death modes {2,9} -- only
Mech::Reset ever does that, and the state rides every record header, so
the trigger is cause-agnostic.  The zone falling edge just refreshes the
cache.  Side effect fixed for free: the peer respawn warp vortex now
plays for zone-less deaths too (same gate).

Bench (scratchpad/night7/mp_zoneless.sh + the new
BT_SELF_DAMAGE_TYPE=collision harness option, which dispatches type-0
through the real TakeDamage divert): 14/14 zone-less deaths un-wrecked
(mode 9->1) with zero zone rises on the observer; explosive regression
leg 12/12 with zone destruction active.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Zh7PTkFy4KwTzVighLR9J
This commit is contained in:
Joe DiPrima
2026-07-31 02:10:04 -05:00
co-authored by Claude Fable 5
parent e91d447405
commit 054c3f2eee
6 changed files with 132 additions and 36 deletions
+9
View File
@@ -5786,6 +5786,15 @@ void
++s_sdTicks;
Damage dmg;
dmg.damageType = Damage::ExplosiveDamageType;
// BT_SELF_DAMAGE_TYPE=collision: dispatch as type-0 instead, so
// the TakeDamage hub's collision divert prices it as INTERNAL
// rattle (armor/zones never move) -- the deterministic bench for
// a ZONE-LESS death (#94: the field ram-kill, without the ram).
{
const char *ty = getenv("BT_SELF_DAMAGE_TYPE");
if (ty != 0 && !stricmp(ty, "collision"))
dmg.damageType = Damage::CollisionDamageType;
}
float want = (float)atof(getenv("BT_SELF_DAMAGE"));
dmg.damageAmount = (want > 0.0f) ? want : 20.0f;
dmg.burstCount = 1;