archive_naming.py already harvests 6027 candidate names under 16 prefixes, and testing its candidate set directly shows it names all 24 StageParameter_S<NN> objects, 24/24. The previous entry presented that naming as new -- it is not. What was new was the identification (which object is which stage, the shared _Tutorial table, IsBoss16Enable = S16), not the method. The real gap, now closed: the sweep reported only per-archive percentages and never emitted WHICH entry got which name, which is exactly why nobody could say the settings objects were StageParameter_*. It now prints the resolved name families per archive -- 6573 named entries, 1631 families disc-wide. Determinism caught again by the verify loop: the resolved map was built by iterating a set, so collided hashes picked a different winner each run. Now iterated sorted(). Second time in two iterations -- any map built from a set needs a sort. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
6.7 KiB
✅ Which archives the disc can name — and the two it cannot
The previous pass found that 0 of 419 in-game HUD config paths hash to a pak entry (hud-config). Chasing more prefixes would have been the same mistake twice, so this censuses the whole disc instead: harvest every plausible asset-name string from every archive, hash each under the 16 known path prefixes, and ask per archive what fraction of its TOC that explains.
idxd-container.md and idxd-tag-hash.md own the hash (name_hash = a
checksum byte over a 24-bit modular value, case-insensitive, distinct from
tag_hash); neither says which archives are reachable by it. Artefact
../data/archive-naming.txt, regenerator tools/re-capture/archive_naming.py
(6 027 candidate names × 16 prefixes).
The result is bimodal
| archive | entries | named | |
|---|---|---|---|
GP_TITLE, GP_PAUSE_MENU, GP_STAGE_CLEAR, GP_CHALLENGE, GP_MOVIE_THEATER, GP_GAMEOVER, GP_BUNK, GP_SYSTEM, GP_TUTORIAL, MiscBin, fonts |
2–151 | all | 100 % |
tables.pak |
79 | 78 | 98.7 % |
GP_DIALOG |
140 | 139 | 99.3 % |
deu/eng/esp/fra/ita/jpn.pak |
117 | 115 | 98.3 % |
GP_SAVE_LOAD / GP_LEADERBOARD / GP_OPTIONS / GP_MISSION_LOG |
24–108 | 91–94 % | |
GP_MAIN_GAME_{D,E,F,I,J,S} |
1 119 | 751 | 67.1 % |
GP_DEBRIEFING_PILOTLOG |
234 | 78 | 33.3 % |
GP_HANGAR_ARSENAL |
1 538 | 347 | 22.6 % |
DefTables |
1 465 | 130 | 8.9 % |
GP_MISSION_SELECT |
88 | 22 | 25.0 % |
GP_READY_ROOM |
1 106 | 6 | 0.5 % |
GP_MAIN_GAME_{D,E,F,I,J,S}2D |
711 each | 0 | 0.0 % |
sound.pak |
9 519 | 1 | 0.0 % (a separate format — sound-pak-contents) |
🔑 The six 2D paks are at exactly 0.0 %, all six, 711 entries each — while eleven menu paks are at 100 % by the same method in the same run. That is the control that makes it a finding rather than a failed guess: the method works, and these archives are outside it.
🔑 GP_READY_ROOM is a second such archive — 1 106 entries, 6 named.
Not previously noted anywhere in docs/re/; it is the largest UI pak on the
disc and its names are as unreachable as the 2D paks'.
✅ The sweep now says WHICH entry, not just how many (2026-08-27)
The percentages above were the whole output for a long time, and that hid
something: the sweep had already named the 24 StageParameter_S<NN>.tbl
objects that a later iteration "discovered" — they were in the 6 027-candidate
set from the start. Nobody could tell, because the artefact only reported
GP_MAIN_GAME_E … 751 named, 67.1 %.
archive_naming.py now also emits, per archive, the resolved name families
(digits collapsed to #) with counts — 6 573 named entries, 1 631 families
across the disc. That turns the statistic into a content index; the
GP_MAIN_GAME_E head is
x28 EnumUnit_S#.tbl x28 StageResource_S#.tbl
x28 FormationSet_S#.tbl x28 UnitGroup_S#.tbl
x28 Route_S#.tbl x22 AIParams_S#.tbl
x22 StageParameter_S#.tbl x22 UnitMessageSet_S#.tbl …212 families
Method lesson, paid for twice now: a coverage percentage is not a name table. If a sweep can name a thing, make it say the name, or the next reader will redo the work.
⚠️ Determinism: the resolved map is built by iterating the candidate set, so it
is now iterated sorted — a plain set gave a different winner for collided
hashes on each run and the artefact failed its own byte-identical check.
What that means for the 419
The in-game HUD's asset paths are not "missing". Nothing in the 2D paks is reachable by name from the disc's own strings, whatever the extension. So the 2D and READY_ROOM TOC keys are hashes of names that are not written anywhere we can read — built by the tool chain, or from a string the executable composes, or from a name list held outside these archives.
🧪 Also refuted here — 13 name transformations
Before the census, the 419 config values were re-hashed under 13 rewrites:
as-is, forward slashes, basename, basename without extension, without extension,
uppercased, .rat substituted, 2d\/eng\/hud\/GP_MAIN_GAME_2D\ prefixed,
and first-directory stripped. Every one scored 0, both against the E2D pak's
711 entries and against all 16 630 entries on the disc.
🔴 BLOCKED — three routes to those names, all closed
Followed up the next iteration. Every avenue the container can reach is now tried, each with a positive control in the same run:
1. A different hash family. The corpus knows three
(idxd-tag-hash): name_hash (pak TOC), tag_hash (IDXD
keys) and ixud_hash. Scoring all 5 977 harvested names × 6 prefixes:
| archive | name_hash |
tag_hash |
ixud_hash |
|---|---|---|---|
GP_TITLE (control) |
8 / 16 | 0 | 0 |
GP_PAUSE_MENU (control) |
6 / 11 | 0 | 0 |
GP_MAIN_GAME_E2D |
0 / 711 | 0 | 0 |
GP_READY_ROOM |
6 / 1 106 | 0 | 0 |
tag_hash and ixud_hash explain nothing anywhere, including the paks
name_hash does explain — so they are not the TOC function, and the two
unnameable archives are not simply keyed by a different one.
2. The executable. sylpheed.db's strings table holds 7 140 rows, of
which exactly two look like asset paths — Data\gmicon002_2.t32 and
Data\gmicon006_2.t32, in a Data\ directory nothing else on the disc uses.
Neither resolves in any archive. So the binary is not the name source
either; it holds two strays and no table.
3. Name transformations of the config paths — 13 of them, all 0 (above).
🔴 This is where the container runs out. The 2D and GP_READY_ROOM TOC keys
hash names that are on neither the disc nor the executable in readable form. The
remaining lever is a dictionary attack using name_hash's shape — the top byte
is the character-sum checksum, so candidates are cheap to reject — but that needs
a plausible name corpus, and this disc does not contain one. Noted as blocked
rather than improvised around.
⚠️ The port does not need these names: the sprites and bundles are readable by content (T8aD, RATC), and the config records already say which asset each HUD element uses. Only the archive-key ↔ name mapping is missing.
🟡 Not settled
- What names the 2D and
GP_READY_ROOMTOCs actually hash. The one lever left is the hash's own shape — the top byte is the character-sum checksum, so any candidate is cheap to reject — but that needs a name corpus this disc does not contain. - Why
DefTables(8.9 %) andGP_HANGAR_ARSENAL(22.6 %) sit in the middle; probably just that most of their entries are tables referenced by records this harvest does not treat as filenames. Not chased.