Identify the tie record as RAC1's TiePacketHeader, and retract a formula

The 16-byte tie record is R&C1's TiePacketHeader offset for offset: a data
pointer at +0, then R&C1's byte fields at +4 through +0x10. The identification
is not a resemblance but R&C1's own rule -- bfc_distance == 5 * shader_count --
holding on all 15,219 records of all 2,177 blocks on all 27 levels.

Measured over the same set, and reported rather than asserted where it is not
universal:

  bfc_distance == 5 * shader_count      15219 / 15219
  vert_ofs <= vert_size                 all
  scissor_size <= scissor_ofs           all
  control_size <= control_count         all
  color_ofs == vert_size                12640 / 15219
  color_ofs == vert_ofs + vert_size    0 / 15219
  color_count, strip_count, strip_vertex_count zero  15089 / 15077 / 15078

R&C1's rule for the colour offset holding on none of them is the interesting
line: the two games use that field differently, so it is named color_ofs for
what this game's majority reads as and the 2,579 exceptions are counted rather
than averaged away. TieRecord parses all twelve fields, invariants_hold asserts
only the universal four, and the disc test counts the rest.

A packet-length formula is withdrawn rather than softened. (vert_ofs +
vert_size + scissor_ofs + scissor_size) * 16 was measured at 61 of 61 pairs and
is not reproduced on the correct blocks -- 0 of 13,042. The block set was the
error, not the arithmetic: the script that produced the 61 read packets[2]
where packets[1] was meant, so it measured 461 blocks instead of the 2,177 the
class tables define, and the formula agreed perfectly with a population that
was not the tie blocks. TieRecord::packet_bytes goes with it, and the
retraction is recorded in the format doc and in the struct.

That misread also explains why the earlier RAM verification saw different
numbers for the two inputs -- same lesson as rule 3, arriving through a wrong
subscript instead of a wrong span.
This commit is contained in:
2026-10-13 04:22:38 +02:00
parent 4e90c282ad
commit 54862b64ee
5 changed files with 272 additions and 19 deletions
+36
View File
@@ -1229,6 +1229,42 @@ payload starts. A count of what follows a pointer is not the pointer.
`TieBlockHeader::data_offset` and `TieBlockHeader::records` carry it, bound by
the offset, and the disc test asserts the table is bounded on every block.
### The records are R&C1's `TiePacketHeader` (2026-10-11)
With the record table located and the fields isolated, the reference settles
what they are. **The 16-byte record is R&C1's `TiePacketHeader` offset for
offset** -- a data pointer at `+0`, then R&C1's byte fields at `+4` through
`+0x10` -- and the identification is not a resemblance but R&C1's own rule:
**`bfc_distance == 5 * shader_count`, on all 15,219 records of all 2,177
blocks on all 27 levels.**
Measured over the same set:
| relation | holds |
|---|---|
| `bfc_distance == 5 * shader_count` | **15,219 / 15,219** |
| `vert_ofs <= vert_size` | all |
| `scissor_size <= scissor_ofs` | all |
| `control_size <= control_count` | all |
| `color_ofs == vert_size` | 12,640 / 15,219 |
| `color_ofs == vert_ofs + vert_size` (R&C1's rule) | **0 / 15,219** |
| `color_count`, `strip_count`, `strip_vertex_count` zero | 15,089 / 15,077 / 15,078 |
`TieRecord` parses all twelve fields; `invariants_hold` asserts only the
universal four, and the disc test counts the rest. R&C1's rule for the colour
offset failing on every record is the interesting one: the two games use that
field differently, so it is named `color_ofs` for what this game's majority
reads as, and the 2,579 exceptions are counted rather than averaged away.
**A packet-length formula is retracted.** `(vert_ofs + vert_size +
scissor_ofs + scissor_size) * 16` was measured at 61 of 61 pairs and is not
reproduced on the correct blocks -- 0 of 13,042. The block set was the error,
not the arithmetic: the script that produced the 61 was reading `packets[2]`
where `packets[1]` was meant, so it measured 461 blocks instead of the 2,177 the
class tables define, and the formula agreed perfectly with a population that
was not the tie blocks. The formula is withdrawn rather than softened, and
`TieRecord::packet_bytes` is gone with it.
### It is now a command, and it verifies two levels
The check above was a script; it is now `gc-trace verify-tie-records