diff --git a/docs/formats/core-data-regions.md b/docs/formats/core-data-regions.md index 5819596..bcc54cf 100644 --- a/docs/formats/core-data-regions.md +++ b/docs/formats/core-data-regions.md @@ -3469,6 +3469,28 @@ intra-span offset. Distinguishing them needs either the engine's class loader (readable now, in the same overlay's `.text`) or a class whose animation is known from outside, and neither has been done. -So `moby_anim` is **not** unblocked. What the attempt establishes is that the -search has a specific place to look, a specific field count to classify, and a -specific reason the obvious discriminator fails -- which is more than it had. +### And the discriminator fails for a sharper reason than "they are small" + +Two tests, both cheap: + +**No header `u32` equals the span's own table offset** on any of the 187 classes. +So the varying fields are not self-relative pointers to the part table. + +**The largest value in any header `u32` is 3,332,678,933.** Some of these fields +are not offsets at all -- at `+0x0c` the value is 16,711,748 across classes, which +is packed data or an identifier, not a displacement. + +So the header's varying fields are a **mixture**: some hold in-span offsets +(`+0x10..+0x1c` run 192 to 10,800, comfortably inside the spans) and some hold +packed values far too large to be offsets. There is no single "the field that +points to the animation" to find, because not all of them point anywhere. + +That is a real narrowing even though it is a negative: **if per-class animation +data exists on the disc, it is inside the class span**, not at a separate pointer +target. The search therefore stops looking for a pointer and starts looking for a +region *within* the span that the geometry parser does not already account for -- +which is a bounded question with the parser as its control. + +So `moby_anim` is still **not** unblocked, but the question is now bounded rather +than open-ended, and the next step is to subtract the parsed geometry from the +span and look at what remains.