#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:
Joe DiPrima
2026-08-03 12:24:36 -05:00
co-authored by Claude Fable 5
parent cb5426cc7f
commit fe48accb6b
8 changed files with 162 additions and 1 deletions
+1
View File
@@ -183,6 +183,7 @@ rows until sanity fails (`python + struct`, see the session commits `cc2b109`/`2
- `class Damage { damageType(enum Collision/Ballistic/Explosive/Laser/Energy), damageAmount, damageForce, surfaceNormal, impactPoint, burstCount }`. [T1]
- Weapon effect id: **"explode" = 13** (`Explosion::Make`). [T2]
- `DestroyEntityMessage(id,size)` removes an entity — but a killed mech STAYS (a WRECK); death = a STATE transition (`SetGraphicState(DestroyedGraphicState)`), NOT removal. Issuing removal-on-death is the P5 teardown bug (do not). [T2]
- **BT effect watcher (zone replication + band effects)** [T1, 2026-08-03]: ctor `FUN_0042a984 @0042a984` (hooks entity+0xbc, allocs oldLevel[damageZoneCount@+0x11c]); Execute `FUN_0042aa2c @0042aa2c` — per zone: flag&4 → `FUN_0042a664` DescriptorForLevel + `FUN_0042a5f4` DescriptorCrossed(old,new) → **crossed && master (`(entity+0x28 & 0xc)==0`) → `*(ushort*)(entity+0x18) |= 2`** (= `ForceUpdate(DamageZoneUpdateModelFlag)`, the zone-record send); flag&8 → `FUN_0042a6c4` DescriptorForGraphicState + the same master-gated ForceUpdate; descriptor → effect via `FUN_0043663c/FUN_004364e4` (renderer mgr @`DAT_004efc94+0x38`); changedFlags reset when (master && !pending-update) or replicant. Zone band table @ zone+0xd4; level @+0x158; gstate @+0x78. Engine `EntityEffectWatcher`/`ExplosionTable` are DEAD for mechs (table NULL, watcher never constructed — band descriptors replace them). Port: mechdmg.cpp band hub. See [[combat-damage]] §Zone-LEVEL replication.
---