your corpse answers the mouse, and a cinematic's last holes close

- a corpse is a body you can hover, cursor and click: it enters the same ray pass as units with the winner switched on type at publish (the reference's own shape — one trace over every object), the cursor classifier is transcribed whole (lootable-by-me → the pickup cursor, grayed by range; else the insignia leg behind the learned-skill latch; your own body falls through to the clear), and right-click is "not mounted AND lootable" → CMSG_LOOT; CORPSE_FIELD_FLAGS bit 5 is the PvP insignia flag, not "reclaimable" as an old note had it; the widening also caught that a GameObject anywhere on screen could steal the click from a nearer corpse, and that a left-click on a body cleared your target as if you had clicked ground
- the cinematic sweep closes eleven holes: a shot plays its sequence band's WIDTH, not its end — two shipped fly-bys band away from zero and ran long with their opening frames frozen (the Night Elf intro measured 102333 → 102000 ms); CMSG_NEXT_CINEMATIC_CAMERA announces every shot, the first included — the old "between shots" reading meant it was sent NEVER, since every 1.12 sequence row carries exactly one camera; the ack invariant is stated once (one CMSG_COMPLETE_CINEMATIC per accepted trigger, over-acking tolerated, under-acking never — a dropped ack despawns the world around you until relog); the hardware cursor hides for the shot; and the music cut lands in the frame that starts it — it was one frame late, exactly long enough for a first login's zone fanfare to start under the narration and be stamped as played
- RunBinding exists, and a fly-by stops handing the world its mouse: CinematicFrame's OnKeyDown hands the SCREENSHOT chord back to its binding through RunBinding, a global we never had, so every press during a fly-by raised and took no picture; and the mouse was fully live under a shot — right-drag turned the character, clicks picked targets through the flying camera, both buttons walked the body — so the pointer now reads as over the UI while a shot plays
- AdvanceTime and ReplaceIconTexture are carved off the bytes: AdvanceTime really is a no-op in the reference (its one reachable call is mov eax,1; ret), ReplaceIconTexture is a material swap over a model's type-14 texture slots that stores nothing on the widget, and SetModel(nil) RAISES — the "documented clear" our binding claimed was invented, not read; and the addon roster now says WHOSE package is short when a .toc names files the folder doesn't hold — nine of the corpus's twenty-nine load failures are the addon's own manifest, which the real client also shrugs off ("Couldn't open %s", carry on), so they stop reading as our defects

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-31 19:55:36 +07:00
co-authored by Claude Fable 5
parent f6f2af3da9
commit 6e3a67e039
28 changed files with 1237 additions and 130 deletions
@@ -582,6 +582,71 @@ fn main() {
println!(" {label:>5} {n:>4} {}", "#".repeat(n.min(60)));
}
// **WHOSE package is incomplete** — printed immediately before the ranked blockers, because it
// is the line that stops a session hunting for a client bug that is not one. A `.toc` entry
// whose file the addon does not ship is the ADDON's defect, and the reference client's
// behaviour there is what ours already does: log `Couldn't open %s` and carry on
// (wow-re `ui/scratch/xml-toc-path-resolution.md` §4). Nothing is subtracted from the headline
// — 1213 — so both readings stay available.
let own: Vec<&addon_harness::AddonReport> = reports
.iter()
.filter(|r| !r.absent_own_files.is_empty())
.collect();
let foreign: Vec<&addon_harness::AddonReport> = reports
.iter()
.filter(|r| !r.absent_foreign_files.is_empty())
.collect();
// **"the WHOLE reason" is a claim, and it is checked before it is printed.** An addon can be
// short a file AND raise somewhere else; saying "this is why it fails" on the strength of
// `!loaded` alone would be the same overclaim this column exists to stop. It holds only when
// the absent entries account for every load error the addon has.
let sole_cause = |r: &addon_harness::AddonReport| {
!r.loaded && r.errors.len() == r.absent_own_files.len() + r.absent_foreign_files.len()
};
if !own.is_empty() || !foreign.is_empty() {
println!(
"\n MANIFEST ENTRIES WITH NO FILE — counted in the numbers above, listed here so"
);
println!(" the reader can tell a broken package from a broken client:");
for r in &own {
println!(
" {} — its own .toc lists {} file(s) the package does not contain{}",
r.name,
r.absent_own_files.len(),
if sole_cause(r) {
" [and that is its ONLY load error]"
} else {
""
}
);
for f in r.absent_own_files.iter().take(4) {
println!(" missing: {f}");
}
}
for r in &foreign {
println!(
" {} — wants a folder that is not installed{}",
r.name,
if sole_cause(r) {
" [and that is its ONLY load error]"
} else {
""
}
);
for f in r.absent_foreign_files.iter().take(4) {
println!(" missing: {f}");
}
}
let theirs = own.iter().filter(|r| sole_cause(r)).count();
let ours = foreign.iter().filter(|r| sole_cause(r)).count();
println!(
" ({} with an incomplete package of their own, {theirs} of which fail for that \
alone; {} wanting a neighbour, {ours} for that alone)",
own.len(),
foreign.len()
);
}
// What actually STOPPED them — the ranked first error. Read this before the demand list: a
// wall 60 addons hit is worth more than a verb 60 addons would like (decision 1193).
println!("\n what stopped them (addons whose FIRST load error was each):");