re: why each archive is low-coverage -- two different reasons, cleanly separated

Splitting every unnamed entry by magic turns the coverage percentages into an
explanation.

The three low-coverage UI archives have ZERO unnamed IDXD.  GP_HANGAR_ARSENAL
is 180 IDXD, 180 named, 0 unnamed -- its 1191 unnamed entries are 1149 T8aD/RATC
plus 42 LSTA, i.e. sprites.  GP_MISSION_SELECT and GP_DEBRIEFING_PILOTLOG hold
no IDXD objects at all.  So "22.6 % named" is misleading: every data table in
that pak is named, and these three are the same artwork-naming phenomenon as the
blocked 2D and READY_ROOM archives.

DefTables is the only genuine data gap: 1425 IDXD, 130 named, 1295 unnamed, in
17 record-name shapes -- Generic + Level_0..Level_3 (807, LOD sets) and Default +
EnumMotions + Generic + ReferenceFrames +/- Motion_break/dead/down (463, motion
sets).  One LOD and one motion table per model.  Level_0, EnumMotions and
ReferenceFrames appear in no document.

Control: the 100 % archives have no unnamed entry of any kind, and GP_MAIN_GAME_E
is 667/337 IDXD with zero unnamed artwork -- two failure modes, not a gradient.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
Claude (auto)
2026-08-27 19:41:29 +00:00
parent 3a5904b584
commit cade6bc1a5
5 changed files with 524 additions and 1 deletions

View File

@@ -62,6 +62,41 @@ def main():
for k, c in sorted(fam.items(), key=lambda kv: (-kv[1], kv[0])):
print(" x%-4d %s" % (c, k))
# WHY an archive is low-coverage: split its UNNAMED entries by content.
print("\n## What the UNNAMED entries are (magic of every entry not resolved above)")
print(" %-28s %6s %6s %8s %9s %6s" % (
'archive', 'IDXD', 'named', 'unnamedI', 'unnamedUI', 'LSTA'))
for nm, _ in rows:
e = pak_entries(os.path.join(os.path.dirname(
[p for p in paks if os.path.basename(p) == nm][0]), nm))
idx = [(h, b) for h, b in e if b[:4] == b'IDXD']
ui = [(h, b) for h, b in e if b[:4] in (b'T8aD', b'RATC')]
ls = [(h, b) for h, b in e if b[:4] == b'LSTA']
ui_un = sum(1 for h, _b in ui if h not in NAMES)
ls_un = sum(1 for h, _b in ls if h not in NAMES)
ix_un = sum(1 for h, _b in idx if h not in NAMES)
if not (ix_un or ui_un or ls_un):
continue
print(" %-28s %6d %6d %8d %9d %6d" % (
nm, len(idx), sum(1 for h, _b in idx if h in NAMES), ix_un, ui_un, ls_un))
print("\n record-name sets of the UNNAMED IDXD entries, per archive:")
for nm, _ in rows:
e = pak_entries(os.path.join(os.path.dirname(
[p for p in paks if os.path.basename(p) == nm][0]), nm))
un = [b for h, b in e if b[:4] == b'IDXD' and h not in NAMES]
if not un:
continue
sh = collections.Counter()
for b in un:
try:
sh[tuple(sorted({r['squadron'] for r in U.parse(b)}))] += 1
except Exception:
sh[('<parse fail>',)] += 1
print(" %s %d unnamed IDXD in %d shapes" % (nm, len(un), len(sh)))
for shape, c in sorted(sh.items(), key=lambda kv: (-kv[1], kv[0])):
print(" x%-5d %s" % (c, ' '.join(shape)[:96]))
def _ix(t): return U.ixud_hash([ord(c) for c in t])
FN = [('name_hash', U.name_hash), ('tag_hash', U.tag_hash), ('ixud_hash', _ix)]
SUB = ['', '2d\\', 'eng\\', 'Data\\', 'ArmsSt\\', 'Marker\\']