Find the tie LOD block terminator; packets == 0 means no block at that LOD

parse_tie_block walks to a 0xf6 terminator that every real block carries, on
2177 of 2177 across all 27 levels, followed by zero padding. This is what makes
the blocks parseable: packets[1] bounds one on only 461 of 1864 classes, so the
terminator is the only general way to find one.

The terminator was worth a control, because 0xf6 could have been byte-frequency
coincidence. It occurs in payloads at 0.83x the uniform rate -- slightly LESS
often than chance -- while the last non-zero byte is 0xf6 on 909 of 922 blocks in
the first subset, against 17 of 922 for the same blocks cut at a random point. So
it is a terminator, not a common byte.

packets == 0 means the class has NO block at that LOD: of 3,728 (class, LOD)
slots, 2177 point at a block and 1551 are exactly zero.

Corrected header, over all 2177:

  +0x00  count    multiple of 16 on all; 42 distinct; never zero
  +0x02           zero on all
  +0x04           exactly four values: 0x501 (1069), 0xa02 (720), 0xf03 (350),
                  0x1404 (38)
  +0x06           16 distinct, never zero
  +0x08           180 distinct, never zero
  +0x0a           61 distinct, never zero
  +0x0c           125 distinct, never zero, clustered 0x043f..0x0443
  +0x0e           11 distinct, zero on 2162 -- the only non-universal field

+0x0c clusters around 1087-1091, close enough to a block length to be worth
stating, but it is NOT the length: the difference against the true payload length
scatters from -12 to -172.

A correction to the previous commit. It reported 3,728 blocks all terminating and
packed_texture taking 842 distinct values, and on that basis retracted the
four-value claim. Both numbers were wrong the same way: the scan did not skip
packets == 0, so it computed class_base + 0 and walked forward from the CLASS
BODY, finding a terminator there by accident. That contaminated 1551 of the 3728.

With the zeros excluded the slot takes exactly four values on all 2177 blocks.
The four-value claim was right; my retraction of it was wrong; and the retraction
was made on a number from the same contaminated set. A retraction is not
automatically better than the claim it retracts -- it needs its own bounds.

Still open: the payload's records. Established this round: blocks are
self-delimiting, absent LODs are marked by a zero packets word, and the header is
fully characterised. Not established: any record boundary inside the payload,
which stays variable-length.
This commit is contained in:
2026-10-12 04:13:52 +02:00
parent 02342de31b
commit 291153a0d9
3 changed files with 186 additions and 46 deletions
+51
View File
@@ -1221,3 +1221,54 @@ confirming anything.
**Still open: what the payload holds.** Established is that it is variable-length,
float-shaped, non-random, not LZ77, and not VIF1. Not established is any record
boundary.
## tie: the LOD block is self-delimiting, and `packets == 0` means absent
**The terminator.** Every tie LOD block ends with the byte `0xf6` followed by
zeros, on **2,177 of 2,177** real blocks across all 27 levels. That was worth a
control, because `0xf6` could have been a coincidence of byte frequency: it
occurs in payloads at **0.83x** the uniform rate, i.e. slightly *less* often
than chance, while the last non-zero byte is `0xf6` on 909 of 922 blocks in the
first subset tested against **17 of 922** for the same blocks cut at a random
point. So it is a terminator, not a common byte.
This is what makes the blocks parseable at all. `packets[1]` bounds a block on
only 461 of 1,864 classes, so the terminator is the only general way to find one.
**`packets == 0` means no block at that LOD.** Of the 3,728 (class, LOD) slots,
**2,177** point at a block and **1,551** are exactly zero. The zero cases are not
degenerate blocks -- they are absent ones.
### A measurement I got wrong, twice, in opposite directions
The first pass over this header reported **3,728 blocks, all terminating** and
`packed_texture` taking **842** distinct values, contradicting an earlier
four-value result. I retracted the four-value claim on that basis.
Both numbers were wrong, and they were wrong the same way. The scan did not skip
`packets == 0`; it computed `class_base + 0` and walked forward from the **class
body**, finding a terminator there by accident. That contaminated 1,551 of the
3,728.
With the zeros excluded, the slot takes **exactly four** values on all 2,177
blocks -- 0x501 on 1,069, 0xa02 on 720, 0xf03 on 350, 0x1404 on 38 -- and all
2,177 terminate.
So: the four-value claim was right, my retraction of it was wrong, and the
retraction was made on a number from the same contaminated set. A retraction is
not automatically better than the claim it retracts; it needs its own bounds.
### Corrected header, over all 2,177 blocks
+0x00 count multiple of 16 on all; 42 distinct; never zero
+0x02 zero on all
+0x04 exactly four values: 0x501, 0xa02, 0xf03, 0x1404
+0x06 16 distinct, never zero
+0x08 180 distinct, never zero
+0x0a 61 distinct, never zero
+0x0c 125 distinct, never zero, clustered 0x043f..0x0443
+0x0e 11 distinct, zero on 2,162 -- the only non-universal field
`+0x0c` clusters around 1,087 to 1,091, close enough to a block length to be
worth stating, but it is **not** the length: the difference against the true
payload length scatters from -12 to -172.