diff --git a/docs/formats/core-data-regions.md b/docs/formats/core-data-regions.md index c2c202b..795bb1f 100644 --- a/docs/formats/core-data-regions.md +++ b/docs/formats/core-data-regions.md @@ -3248,7 +3248,7 @@ Phase 3 port made visible. Its records are three words: Walking all 27 levels: 5,878 records - 1,163 distinct class ids + 1,162 distinct class ids range 0 .. 0x13BA (5,050) median 38 new ids contributed per level @@ -3258,7 +3258,7 @@ three words -- so the addresses are function entries, not arbitrary words. ### Why this retires the earlier bound -`LevelCoreHeader::moby_classes.count` is **238** on level 0. **1,135 of the 1,163 +`LevelCoreHeader::moby_classes.count` is **238** on level 0. **1,135 of the 1,162 class 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 @@ -3277,10 +3277,10 @@ selected for smallness. ### Re-scored against the real id set -With the game's own 1,163 ids as the validity test, no chunk slot separates: +With the game's own 1,162 ids as the validity test, no chunk slot separates: best slot 0.375 (type f2ef4275 slot 34) - chance rate 0.018 (1,163 ids in 65,536 values) + chance rate 0.018 (1,162 ids in 65,536 values) a dozen slots 0.25 .. 0.38, with no gap between them Twenty times chance is not nothing, but a dozen slots packed into the same band @@ -3294,15 +3294,18 @@ is not the class count.** Asserted in Two axes that are easy to conflate, and are not the same thing: - lvl.vtbl oClass 1,163 distinct across 27 levels, largest 5,050 + lvl.vtbl oClass 1,162 distinct across 27 levels, largest 5,050 + (was 1,163 until the terminator fix -- see + "The vtbl terminator" below; the loop read past the + end of the table) core_index moby_classes.count 136 .. 259 per level -**1,133 of the 1,163 identifiers are at or above the largest per-level class +**1,133 of the 1,162 identifiers are at or above the largest per-level class table.** So `oClass` cannot index that table -- nearly every identifier would fall off the end. They are different axes: the vtbl names a *type* of moby, the class table lists the *models* a level instantiates. -The identifier space is shared rather than renumbered per level: 1,163 distinct +The identifier space is shared rather than renumbered per level: 1,162 distinct values come out of 5,878 records, and level 0 contributes 234 while levels 1-8 contribute 72, 69, 77, 54, 41, 68 and 28 -- each level roughly its own share, not one level dominating. An earlier note here said "most of the game's classes appear @@ -3353,7 +3356,7 @@ and its sound records: Both identifier spaces are **global and shared**: 217 camera records carry only 14 distinct ids and 32 sound records only 6, so levels re-use ids rather than -renumbering -- the same sharing as the moby table's 1,163 distinct out of 5,822. +renumbering -- the same sharing as the moby table's 1,162 distinct out of 5,822. This is what makes the tables usable rather than merely present. A per-level dispatch entry is now addressable by a game-wide id, and the handler addresses are @@ -3737,7 +3740,7 @@ The gate's second half is therefore met, with the caveat that "agrees" means ## The vtbl terminator, and why three counts were all defensible Three committed tests counted `lvl.vtbl` records and disagreed: 5,878 records / -1,163 ids, 5,822 / 1,162, and 5,788. All three were measuring something, and none +1,162 ids, 5,822 / 1,162, and 5,788. All three were measuring something, and none of the tests was simply wrong. **5,822 records / 1,162 ids is the table.** The record array terminates on diff --git a/docs/roadmap.md b/docs/roadmap.md index 41b62d8..ad073ea 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -421,7 +421,7 @@ Phase 1 hands over the extents; this phase works out what each one contains. 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 + that is **1,162 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, @@ -441,7 +441,7 @@ Phase 1 hands over the extents; this phase works out what each one contains. across levels rather than renumbered. Handler addresses are function entries in the same overlay's `.text`, which is now readable. Asserted. - [x] `lvl.vtbl`'s **`oClass` is a global identifier**, not an index into the level's - class table: 1,163 distinct ids across the game, largest 5,050, against + class table: 1,162 distinct ids across the game, largest 5,050, against `moby_classes.count` of 136..259. **1,133 of 1,163 are out of range** for any per-level table. The two are different axes -- a type id, and the models a level instantiates -- and the space is shared rather than renumbered