42b532dc24
A unit event's listener read the unit as the frame ended: two `UNIT_HEALTH` listeners for a 100→70→40 target both read 40. In 1.12.1 a packet's handler writes every block (`0x4651a0`, `0x46520e`, `0x465222`), then calls its watchers synchronously (`0x465570`). `UnitHealth` and `UnitMana` read the live object (`0x517553`, `0x5176f7`). So a listener sees its own packet's state. Each update packet now logs the dwords it moved, along with its destroys and teardowns. A "unit views" lane rewinds the player, target, targettarget and npc stores to frame start, then replays the log in stamp order between the other lanes' items. A debug check compares the rewind with a frame-start snapshot. `READS_FRAME_FINAL` lists every view push still reading frame-final state. Tests: per-packet `UnitHealth`/`UnitMana`, `UNIT_COMBAT` ahead of its update, coalescing, an unlogged write, a worldport, and a stalled drain. Part of #2217 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>