From 4776db199b3fbecb6617e672b09ffbac84887f34 Mon Sep 17 00:00:00 2001 From: ReaperOfVeriod Date: Wed, 14 Oct 2026 03:56:50 +0200 Subject: [PATCH] Attempt the moby_anim unblock: a location and a failure, not a result Asked whether the blocked items could be unblocked, and tried the one that looked tractable. It did not work, and this records where and why rather than leaving the attempt implicit. VERDICT PER ITEM moby_anim probably -- disc-side work. TRIED, stalled, see below tfrag morph maybe -- would need the engine's own morph code volumes no -- needs a count of level 0's trigger volumes from a map collision no -- needs a debug build or an external format description THE ATTEMPT MobyInstance names animSeq, animLayers, jointCnt and jointCache. Those are RAM pointers and useless on the disc, so the search moved to what they point AT, reached from the moby class blob. Level 0, 187 moby classes. The span opens with the part-table offset: 0x80 on 69 classes, 0x90 on 34, ranging 0 to 229,184 across the rest. So each class carries roughly a 0x40-byte header before its parts, and that header is unexplored. Per byte over +0x00..+0x40, how many of the 187 classes are non-zero: +0x00 177 the part-table offset +0x07 185 8 distinct values, 1..3 +0x26 181 100 distinct -- varies per class +0x27 187 8 distinct +0x2d 187 8 distinct +0x30 170 120 distinct +0x3c 184 120 distinct +0x3e 187 110 distinct Six or seven fields are constant across every class and about a dozen vary. None is identifiable. The obvious discriminator -- find the field that points OUTSIDE the span -- does not resolve, because every varying field holds values in the tens of thousands, the same order as the span offsets themselves. They may be intra-span pointers or they may be sizes, and nothing here separates them. WHERE IT STALLS Distinguishing them needs one of: the class loader in the overlay's .text, which is now readable with the fixed disassembler, or a class whose animation is known from outside the disc. Neither has been done, and the first is the obvious next step rather than a dead end. So moby_anim is NOT unblocked. What the attempt does establish is a location, a field count to classify, and a specific reason the easy discriminator fails -- which is more than the item had, and considerably more than "still open". The other three are unchanged and I do not think they are reachable from here. Collision needs the assert, which is unreferenced in retail, or an external description of R&C2's collision cell. Volumes needs ground truth nobody in this repo can supply. Both are written up with those conditions attached. --- docs/formats/core-data-regions.md | 43 +++++++++++++++++++++++++++++++ docs/roadmap.md | 11 +++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/docs/formats/core-data-regions.md b/docs/formats/core-data-regions.md index 079a97c..5819596 100644 --- a/docs/formats/core-data-regions.md +++ b/docs/formats/core-data-regions.md @@ -3429,3 +3429,46 @@ is still unknown, and the tie vertex layout remains open. What is settled is tha **16 is not it** -- only 3 of 1,844 regions show a constant byte at 16 -- which is the quantitative version of the retraction, and a third independent measurement now agreeing with it. + + +## Attempting the moby_anim unblock: the class header, and where it stalls + +`MobyInstance` names `animSeq`, `animLayers`, `jointCnt` and `jointCache` as +runtime pointers. Those pointers are useless on the disc -- they are RAM +addresses. What is *on* the disc is whatever they point at, reached from the moby +class blob, so that blob's header is where the unblock has to happen. + +Level 0, 187 moby classes. The span opens with the part-table offset, which is +`0x80` on 69 classes, `0x90` on 34, and ranges from 0 to 229,184 across the rest -- +so a class carries a header of roughly `0x40` bytes before its parts, and that +header is unexplored. + +Per byte over `+0x00..+0x40`, how many of the 187 classes are non-zero: + + +0x00 177 the part-table offset (0, 128, 144, ...) + +0x07 185 8 distinct values, 1..3 + +0x26 181 100 distinct -- varies per class + +0x27 187 8 distinct + +0x2d 187 8 distinct + +0x2e 12 + +0x30 170 120 distinct + +0x3c 184 120 distinct + +0x3e 187 110 distinct + +0x3f 187 5 distinct + +Six or seven fields there are constant across every class, and about a dozen +vary. None is yet identifiable: nothing has the shape of "pointer to a separate +region" -- the varying fields hold values in the tens of thousands, which is the +same order as the span offsets themselves, so they may be intra-span pointers or +may be sizes. + +**This is where it stalls, and the stall is honest.** The header is dense with +unexplained fields and the obvious move -- find the one that points outside the +span -- does not resolve, because every varying field is small enough to be an +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. diff --git a/docs/roadmap.md b/docs/roadmap.md index d675e43..0304e80 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -439,7 +439,16 @@ Phase 1 hands over the extents; this phase works out what each one contains. nothing of that shape is in the container; the test asserts what can be asserted without them (offsets ascend, do not overlap, land exactly on 0x100). Layout claim from a third party, attributed as such. -- [ ] `moby_anim` — **still open, and the obvious reading is ruled out.** An +- [ ] `moby_anim` — **unblock attempted and not achieved.** The unblock was "the + data behind those pointers", and the pointers are RAM addresses, so the + search moved to the moby class blob: 187 classes on level 0, part-table + offset `0x80` on 69 and `0x90` on 34, so each carries a `~0x40`-byte header + before its parts. That header has ~6 constant and ~12 per-class-varying + fields and **none is yet identifiable** — the varying ones hold values of + the same order as the span offsets, so the obvious discriminator ("the field + that points outside the span") does not resolve. Needs the class loader in + the overlay's `.text`, which is now readable, or a class whose animation is + known externally. Recorded as a stall with a location, not as progress. An instance table would have to scale with the level's moby class count, but **per-chunk-type record counts are level-independent** -- the same types report 90, 77, 50 and 47 on every level tried, and the largest type