The moby class-id space is known: lvl.vtbl, and the old bound was simply wrong

Used the working section parser to reach something the decomp describes but does
not decode. lvl.vtbl is section 3 of the level program, records of three words:

    [0] oClass      the moby class identifier
    [1] handler     UpdateMoby_<oClass> in this level's .text
    [2] auxiliary   the same value for every record of a level, 26 of 27

Across 27 levels: 5,878 records, 1,163 distinct class ids, range 0..0x13BA (5,050),
median 38 new ids per level. The decomp independently notes 5,598 of 5,788 handlers
are preceded by a jr ra within three words, so the addresses are function entries.

WHY THIS RETIRES THE EARLIER BOUND

moby_classes.count is 238 on level 0. 1,135 of the 1,163 real ids -- 97.6% -- are
at or above that number. So "value < moby_classes.count" was never a test for "this
is a class id". It was a test for "this is a small number".

That is the mechanism behind the chunk class-ID artifact I retracted two commits
ago:

    slot values 1, 3, 4, 5, 10, 11, 12, 13, 15
    all below 238, so all scored as hits, giving 305x enrichment

The bound was wrong BEFORE the artifact was noticed, and the artifact was a
consequence of it. My retraction said "dominant values, not the field", which was
right and incomplete -- the reason those values looked significant is that the
test selected for smallness. Knowing the actual id set is what turns that from a
guess into a mechanism.

RE-SCORED AGAINST THE REAL SET

With the game's own 1,163 ids as the validity test, nothing separates:

    best slot      0.375   (type f2ef4275 slot 34)
    chance rate    0.018   (1,163 ids in 65,536 values)
    a dozen slots  0.25 .. 0.38, no gap between them

Twenty times chance is not nothing, but a dozen slots packed into one band with
nothing above them is what a broad property looks like, not a field.

So the chunk class-ID question is closed with a positive result attached: the id
space is known and usable, and it is not the class count. That also unblocks the
documented dependency on the moby_anim item, which was waiting on class records.

Asserted in moby_class_ids_come_from_lvl_vtbl_not_from_the_class_count.

262 tests.
This commit is contained in:
2026-10-14 03:34:35 +02:00
parent 9f4f4acecb
commit 199ce33dd8
3 changed files with 157 additions and 0 deletions
+8
View File
@@ -399,6 +399,14 @@ Phase 1 hands over the extents; this phase works out what each one contains.
makes the record size fall out of the data rather than being assumed.
1,270,802 vertices over 4,560 class spans; 116 spans carry no geometry.
Vertices are 16-byte VIF-packed half-float quads, handed back raw.
- [x] The **moby class-id space is known**: `lvl.vtbl` (section 3 of the level
program) is records of `{oClass, handler, auxiliary}`, and across 27 levels
that is **1,163 distinct ids** reaching `0x13BA` (5,050), median 38 new per
level. `moby_classes.count` is 238 and **97.6% of real ids are at or above
it**, so the count was never a valid bound -- which is the mechanism behind
the chunk class-ID artifact now retracted. Re-scored against the real set,
no chunk slot separates (best 0.375 against 0.018 chance, a dozen slots in
the same band). Asserted.
- [ ] `moby_anim` — **still open, and the obvious reading is ruled out.** 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