#87 root cause: the level-crossing zone-record send was missing -- observers never saw damage
The binary's effect watcher (FUN_0042aa2c) raises ForceUpdate(DamageZoneUpdateModelFlag) when a zone's damageLevel CROSSES a band-descriptor threshold (FUN_0042a5f4, master-gated on entity+0x28 & 0xc) -- that send is how every other pod's replicant learns zone levels mid-fight. The port's band hub kept only the graphic-state branch, so an observer's copy sat at 0.0 until destruction: no enemy hull darkening, no doll movement, ever (the night-10 "no armour discoloration" report). Restored the level branch with the already-reconstructed DescriptorCrossed (@0042a5f4) + the master gate on both branches (mesh swap still runs on every instance). 2-node verified: A-side armour watcher pushed 114 level changes; every replicant peak matched the master's finals to 4 decimals (dtorso 0.9321 == 0.9321). Render path cleared separately (gotcha #23 discharged): BT_ARMOR_FORCE 0/1 A/B captures prove the tint renders (hull -> charcoal at 1.0). Solo perception is the authentic economy: 2-25 pt lasers vs 68-185 pt pools. Bench: zonewalk.sh node A now carries BT_ARMOR_LOG + BT_SHOT_EVERY (the standing zone-replication receipt) + digest_walk.py; armorpx.sh is the force-pair pixel rig. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
cb5426cc7f
commit
fe48accb6b
@@ -1275,6 +1275,20 @@ void
|
||||
continue;
|
||||
lastLevel[i] = level;
|
||||
|
||||
// AUTHENTIC (FUN_0042aa2c @0042aa2c, the binary's effect-watcher level
|
||||
// branch): when the rise CROSSES a band-descriptor threshold
|
||||
// (FUN_0042a5f4) and this node owns the master, raise the entity's
|
||||
// damage-zone update flag (*(entity+0x18) |= 2, master-gated on
|
||||
// (entity+0x28 & 0xc) == 0) -- the zone update records ship this
|
||||
// zone's damageLevel to every observer, so replicant dolls/hull tint
|
||||
// track the fight at band granularity. This send was MISSING from
|
||||
// the port (only the graphic-state branch below raised it): masters
|
||||
// consumed damage correctly while every observer's copy sat at 0.0
|
||||
// until destruction (the "no discoloration in MP" report, #87).
|
||||
if (zone->DescriptorCrossed(prev, level)
|
||||
&& owner->GetInstance() == Entity::MasterInstance)
|
||||
owner->ForceUpdate(Entity::DamageZoneUpdateModelFlag);
|
||||
|
||||
// AUTHENTIC GATE (decomp re-verified 2026-07-12, workflow): the binary
|
||||
// fires the CURRENT band descriptor's effect whenever the zone's
|
||||
// damage-CHANGED flag is set (+0xb8 & 4, set by DamageZone::TakeDamage,
|
||||
@@ -1326,7 +1340,12 @@ void
|
||||
// The single-threaded frame loop makes the immediate swap safe.
|
||||
if (d->graphicState != DamageZone::ExistsGraphicState)
|
||||
{
|
||||
owner->ForceUpdate(Entity::DamageZoneUpdateModelFlag);
|
||||
// Master-gated like the binary's gstate branch (@0042aa2c:
|
||||
// (entity+0x28 & 0xc) == 0 guards the |= 2); the mesh swap
|
||||
// runs on EVERY instance -- an observer node executes this
|
||||
// same path when the replicated level/gstate lands.
|
||||
if (owner->GetInstance() == Entity::MasterInstance)
|
||||
owner->ForceUpdate(Entity::DamageZoneUpdateModelFlag);
|
||||
BTRemakeMechModel(owner); // RemakeEntity: swap in the destroyed mesh
|
||||
}
|
||||
if (getenv("BT_DEATH_LOG"))
|
||||
|
||||
Reference in New Issue
Block a user