diff --git a/docs/re/structures/unit-group-table.md b/docs/re/structures/unit-group-table.md index 96cf1495..911af1d8 100644 --- a/docs/re/structures/unit-group-table.md +++ b/docs/re/structures/unit-group-table.md @@ -157,7 +157,32 @@ observation that `n = 9` does not match the `_30` in `Formation_ADAN_Turret07_30` is correct and **not** evidence against `n` being a count: 9 units occupy 9 of that formation's 30 slots. -### ✅ How `FormationID` resolves — the same roster trick +### ❌ WITHDRAWN — "`FormationID` does not hash into the table" + +**It does.** The refutation below used the wrong hash function. A record key is +[`tag_hash`](idxd-tag-hash.md) of the record's own name — *not* the pak-TOC +`name_hash`, which lowercases and uses a different modulus. Checked directly: + +``` +tag_hash("Formation_4_Bird") = 0x22a5eeed <- exactly the record key +name_hash("Formation_4_Bird") = 0x6286edad <- the wrong hash, hence "0 of 16" +``` + +`Formation_4_Bird` **is** a record name in `FormationSet_S02.tbl`, and every +record in that table keys by `tag_hash` of its name. Across all 28 +`UnitGroup_S.tbl` the same holds for field keys: **6960 / 6960** are +`tag_hash(field name)` and **0** are `name_hash`. So `FormationID` resolves by a +direct hash lookup and the roster indirection is **not required** for it. + +This is the exact trap [`idxd-container.md`](idxd-container.md) warns about, and +it cost this file a spurious ❌. + +🟡 The *squadron* half of the original claim still stands: a squadron record's +key is not `tag_hash` of the squadron id either (`tag_hash("TCN001")` = +`0x760cdeaa`, against keys running `0x659aff47…`), because the record's **name** +is not the squadron id. The roster maps id → record, and that indirection is real. + +### The original text, kept `FormationID` does **not** hash into the table: `name_hash("Formation_4_Bird")` = `0x6286edad`, and the record key is `0x22a5eeed` — 0 of 16 resolve that way. @@ -181,5 +206,7 @@ record inside the table, not by hashing the name.** they stand — but the earlier note rejected `n = 387` as *the* craft count on the assumption that everything deploys at once, and that assumption is still untested. -* The **key derivation** stays ❔. The roster makes it unnecessary, but the tag - is not `name_hash`, so a second hash function is still unidentified. +* ✅ The **key derivation is no longer ❔**: the "second hash function" is + [`tag_hash`](idxd-tag-hash.md), recovered since this was written. Record keys + and field keys are both `tag_hash` of their own name — 6960 / 6960 field keys + across all 28 `UnitGroup` tables, 0 matching `name_hash`.