This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/structures/archive-naming.md
Claude (auto) a543b8da96 re: correction -- the naming sweep already covered the 24; it just never said so
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
2026-08-27 19:25:30 +00:00

134 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ✅ 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](hud-config.md)). 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](sound-pak-contents.md)) |
🔑 **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](idxd-tag-hash.md)): `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_ROOM` TOCs 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 %) and `GP_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.