Most of the chunk container is level-independent: 65 of 74 signatures
Comparing every chunk record against the same record index in the other 26
levels, across all 74 signatures:
65 of 74 every record byte-identical in all 27 levels
9 of 74 level-specific
0 ragged no signature appeared with different record counts per level
The nine that vary:
[5d 44 13] [75 42 ef] [7f 44 ee] [82 c4 2f] [96 c3 37]
[a2 44 a5] [c6 c3 ef] [df c3 ea] [f3 c4 b9]
This reframes the container. 65 of 74 chunk types are static tables the game ships
unchanged in every level -- constants and lookups, not level content. The largest
by record count are all in that group: [38 c4 7e] stride 328 with 90 records per
level, [a9 c4 d8] stride 308 with 90, [3d c4 9e] stride 368 with 77.
The consequence is about method, and it is worth being blunt about. For a
level-specific type, comparing levels is the strongest lever available: a field
that moves with the level is identifiable by correlating it with something known.
For the other 65 there is nothing to compare -- one copy of the data, repeated 27
times -- so they must be decoded structurally, from what the bytes are. A future
decoder that reaches for per-level comparison as its first tool will find it
useless on the majority of the container.
[75 42 ef] is both level-specific AND the one signature with three strides. A
type that is both variable-length and level-varying is the most informative one
here, and is where per-type field decoding should start.
How this was found, including the wrong turn:
The first look at [53 c4 6c d7 9a 43] (stride 108) showed 45 of 108 byte positions
varying WITHIN a chunk and 810 records all distinct -- which reads like per-record
data. Counting distinct values per u32 slot across all 810 records contradicted
that: 29 to 30 distinct values across 27 levels, i.e. about one per level.
Both readings were wrong because they measure different things. The 45 positions
vary between records within a level; the u32 counts were low because the same 30
values recur in every level. Comparing record i across levels settled it: all 30
records are byte-identical in all 27 levels, and zero byte positions vary across
levels.
Had the u32 distinct counts been the only measurement, the conclusion would have
been "one value per level" -- the opposite of the truth, describing a per-level
parameter table that does not exist. The within-chunk and across-level views had
to be taken together to get a true one.
Asserted in most_chunk_signatures_are_level_independent. 242 tests, clippy clean.
This commit is contained in:
+7
-1
@@ -471,7 +471,13 @@ Phase 1 hands over the extents; this phase works out what each one contains.
|
||||
The exception is pinned: `[75 42 ef f2 71 b5]` at strides `{76, 92, 104}`.
|
||||
Asserted including the exception, so "every type is uniform" cannot rot.
|
||||
A per-type layout found for one type (48 bytes of data then 60 permanently
|
||||
zero) does **not** generalise -- 0 of 9 types fit that shape. The body
|
||||
zero) does **not** generalise -- 0 of 9 types fit that shape.
|
||||
**65 of the 74 signatures are byte-identical in all 27 levels** (9 are
|
||||
level-specific, 0 ragged), so most of the container is static game tables
|
||||
rather than level content -- asserted. Consequence for method: the 65
|
||||
cannot be decoded by comparing levels, because there is nothing to compare.
|
||||
`[75 42 ef]` is both level-specific *and* the three-stride type, so it is
|
||||
where per-type decoding should start. The body
|
||||
is dense (74% of `f32` reads plausible against a 49% random control) with
|
||||
an index-like tail -- 12 of 163 `u16` slots in the largest type stay below
|
||||
`0x1000` -- but **no count field** exists in the first 64 body bytes at any
|
||||
|
||||
Reference in New Issue
Block a user