diff --git a/docs/plan/level-assets.md b/docs/plan/level-assets.md index 6410384..462ae44 100644 --- a/docs/plan/level-assets.md +++ b/docs/plan/level-assets.md @@ -1178,3 +1178,48 @@ than a partial list when a table does not tile. have not been decoded, and the VIF reading of a shrub body was already retracted once, so this needs a control, not a pattern match. - The 0x20-byte records the loader points at from `+0x18. + +## Shrub mesh packets: a 16-byte header and 16-byte records + +The packet table decode (commit aa2b14a) left the packet *contents* open, with +a warning that a VIF reading had already been retracted once and so needed a +control rather than a pattern match. This is that measurement. + +**Range measured:** level 0, the 29 packets of the 6 successor-bounded shrub +spans, 26,640 bytes. Per-class and per-packet; nothing pooled. + +**Method:** autocorrelation within the largest packet against a +distribution-matched shuffled control, then per-byte distinct counts across all +29 packets. + +**Result 1 -- the packets tile at 16 bytes.** All 29 packet sizes are exact +multiples of 16, and the internal stride scan peaks at 16 (+0.283) with 32, +48, 64, 80 and 128 all elevated behind it -- the signature of a record array +rather than a single coincidental spacing. + +**Result 2 -- record 0 is a 16-byte header.** Across all 29 packets these bytes +are constant: 0-3 `04 04 00 01`, 4-11 all zero, 12-13 `00 80`, 15 `6c`. Bytes +14 and 16-23 vary. The `04 04 00 01` prefix is constant and looks like a magic +or format version. + +**Result 3 -- header byte 14 is echoed in the body.** Header byte 14 takes +values 06, 07, 0e and 11 across packets, and in every packet the same value +appears at offset 12 of record 1. That correspondence holds on all 29 packets +sampled, so it is a real repeated field rather than a coincidence of two +values happening to be small. + +**Not established.** No header field matches the record count: the packet holds +1056/16 = 66 records, and none of the candidate u32 or u16 header offsets at 8, +10, 12, 14, 16, 18 or 20 equals 66, 65 or 67 on more than half the packets. So +the record count is either computed from a size field elsewhere in the span, or +the records are variable length and merely 16-byte aligned. + +That distinction matters and is unresolved: if records are fixed 16 bytes the +payload is a flat table; if they are variable, the 16-byte alignment is a +coincidence of every record happening to be a multiple of 16 long. The stride +scan cannot separate the two, because both produce a peak at 16. + +**The retracted VIF reading is not being revived.** Nothing here identifies a +VIF stream: the 16-byte tiling is uniform across all 29 packets with no +command-shaped tail, and a VIF packet would show a changing command byte in its +last position rather than the constant `6c` at header byte 15.