re: all 277 base-solver rows classified objectively; 53 are data-table schemas

name_block_bases.py extended with a per-row data-table test; artefact +57/-0,
byte-identical across two runs (now ~2 min 12 s -- it adds a disc-wide pak scan).

The test is objective, not by eye: a row is a data-table schema if its names are
IDXD record/field names on the disc (13450 such names disc-wide).  53 of 277 rows
are >=50 % disc names with >=8 names; the other 224 are engine/XDK vocabulary,
compiled key lists, or noise.

The two axes are independent: against base confidence, solved bases split 34
table / 136 not, round bases 16 / 91.  "Round base" and "not a table" are
different questions.

The 53 contain every loader already known -- that is the control.  Five rows in
the 53 are unowned, each noun grepped and appearing in no docs/re/ file:
sub_823BDAA8 r11 (33) = the S16 boss's muzzle/attach frames (GN_MainGun_*_Muz*);
sub_823BDAA8 r10 (25) = motion names (Motion_stand, Motion_attackA_start), the
EnumMotions family DefTables declares; sub_82315AE8 r11 (20) = the Guardian
record's own fields, i.e. the S16 boss loader; sub_8219E560 r11 (18) = the
leaderboard screen keys; sub_825F2CF0 + sub_825F2F88 r0 (30 each, same base) =
post-processing (FinalPassBG, FogMin/MaxDistance).

Four rows that look new are not, and their disc-overlap says so -- 53-70 % rather
than ~100 %, because they mix arsenal fields the corpus owns (ConditionToDevelop,
WeaponDesc, SilhouetteModel) with literal screen coordinates as strings.

Not settled: none of the five was opened -- this iteration produced the shortlist,
not the findings.

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 23:09:57 +00:00
parent 005023987e
commit 187b10418e
4 changed files with 177 additions and 1 deletions

View File

@@ -5339,3 +5339,47 @@ with no mesh, and the one gear mesh carries three gear names.
`CollisionSet` library (its 18 blobs are byte-identical, so a name join was not
attempted); why `Body01` has no mesh; and none of the shader slots was traced to
a shipped shader.
---
## ✅ 2026-08-27 — all 277 base-solver rows classified objectively; 53 are data-table schemas
Item (a). `name_block_bases.py` extended with a per-row data-table test; artefact
**+57/0**, byte-identical across two runs (~2 min 12 s now — it adds a disc-wide
pak scan).
🔑 **The test is objective, not by eye:** a row is a *data-table schema* if its
names are **IDXD record/field names on the disc** (13 450 such names disc-wide).
**53 of 277 rows** are ≥50 % disc names with ≥8 names; the other 224 are engine
/ XDK vocabulary, compiled key lists, or noise.
⚠️ **The two axes are independent.** Against base confidence: `solved` bases
split 34 table / 136 not, `round` bases 16 / 91. So "round base" and "not a
table" are different questions — the earlier round-base warning was about
*where* the base is, this is about *what the names are*.
✅ The 53 contain every loader already known (the control): unit definitions,
stage settings, `PlayerParams`, hangar, `AIParams`, the weapon datasheet, the
`PG*` roster, the three screen key lists.
❔ **Five rows in the 53 are unowned — each noun grepped, appearing in no
`docs/re/` file:**
* `sub_823BDAA8` r11 (33) — `rou_e901` + `GN_MainGun_01_MuzC`, `GN_MainGun_02_Muz01…`:
the **S16 boss's muzzle/attach frames**, sitting beside the collision table.
* `sub_823BDAA8` r10 (25) — `Motion_stand`, `Motion_stand_b1`, `Motion_attackA_start`…:
**motion names**, the `EnumMotions` family that `DefTables` declares.
* `sub_82315AE8` r11 (20) — `InitRotation`, `MaxRotationSpeed`, `RotationAccel`,
`MaxVerticalSpeed`: the **`Guardian` record's own fields** — the S16 boss loader.
* `sub_8219E560` r11 (18) — `Detail_Rank`, `MISSIONS`, `Detail_Board_Permanent`:
the **leaderboard screen** keys.
* `sub_825F2CF0` + `sub_825F2F88` r0 (30 each, same base) — `FinalPassBG`,
`FinalPassToneRatio`, `FogMin/MaxDistance`: **post-processing**.
⚠️ **Four rows that look new are not**, and their disc-overlap says so: 5370 %
rather than ~100 %, because they mix arsenal fields the corpus owns
(`ConditionToDevelop`, `WeaponDesc`, `SilhouetteModel`) with **literal screen
coordinates as strings** (`757,228`, `903,343`, `1092,457`).
🟡 Not settled: none of the five was opened — this iteration produced the
shortlist, not the findings. The 224 non-table rows were not partitioned further
(XDK vs game engine vs noise).

View File

@@ -295,6 +295,63 @@
0x82060000 x1 rows
⚠ the 0x820B0000 cluster is ~60 near-identical functions in 0x8281xxxx-0x8284xxxx that all name the same `rou_e0NN` list.
## Is the row a DATA-TABLE schema? (names that are IDXD record/field names on the disc)
distinct IDXD record+field names disc-wide: 13450
rows that are >=50% disc names and >=8 names: 53 / 277
sub_82341A20 r30 0x82088F94 217 names 89% disc
sub_822215D0 r11 0x820A0000 205 names 98% disc
sub_8230D1F8 r29 0x8209FD28 129 names 97% disc
sub_82338EE0 r30 0x8208583C 97 names 94% disc
sub_822F9498 r29 0x8209FD28 90 names 99% disc
sub_822AE628 r11 0x820B0000 81 names 67% disc
sub_823BDAA8 r11 0x820B0000 33 names 88% disc
sub_82561C70 r11 0x820A90D8 30 names 50% disc
sub_825F2CF0 r0 0x8209EB30 30 names 97% disc
sub_825F2F88 r0 0x8209EB30 30 names 97% disc
sub_82297550 r11 0x820B0000 27 names 67% disc
sub_822A2F00 r11 0x820B0000 27 names 70% disc
sub_823BDAA8 r10 0x820B0000 25 names 100% disc
sub_822215D0 r10 0x820A0000 24 names 75% disc
sub_822814D8 r11 0x820B0000 24 names 100% disc
sub_8230D1F8 r28 0x820978AC 24 names 96% disc
sub_8247DFC0 r31 0x8209E690 23 names 96% disc
sub_821A6CF0 r29 0x820A1630 22 names 100% disc
sub_8227A3A0 r11 0x820B0000 21 names 100% disc
sub_82315AE8 r11 0x820B0000 21 names 90% disc
sub_8233C368 r28 0x8208583C 20 names 100% disc
sub_8236B608 r11 0x820B0000 20 names 100% disc
sub_8221F700 r31 0x820A0E9C 19 names 100% disc
sub_82288028 r11 0x820B0000 19 names 53% disc
sub_822A9C18 r11 0x820B0000 19 names 89% disc
sub_8219E560 r11 0x820A0000 18 names 100% disc
sub_82261F70 r31 0x82086C1C 18 names 89% disc
sub_82286BC8 r11 0x820B0000 18 names 100% disc
sub_821AA1B0 r31 0x820A97CC 16 names 94% disc
sub_82804AD0 r11 0x820A792C 16 names 88% disc
sub_82222E70 r0 0x8209E6D8 15 names 100% disc
sub_8227F8E0 r31 0x820A0E9C 15 names 100% disc
sub_82282DB0 r31 0x820A0E8C 15 names 100% disc
sub_823479B8 r28 0x820864F4 15 names 100% disc
sub_82565C80 r11 0x820A5574 15 names 87% disc
sub_825DA790 r26 0x820A3B4C 15 names 93% disc
sub_8220ED30 r31 0x820A0E9C 14 names 100% disc
sub_8221F700 r11 0x820A0000 14 names 86% disc
sub_822F2E58 r31 0x820A97E4 14 names 100% disc
sub_82338EE0 r11 0x820AA368 14 names 100% disc
sub_823B2620 r31 0x8209E710 14 names 93% disc
sub_825635C8 r31 0x8209E230 14 names 100% disc
sub_8261F2C0 r11 0x8208AB54 14 names 86% disc
sub_8229F018 r11 0x820A4818 13 names 100% disc
sub_823785A0 r31 0x8209E710 13 names 92% disc
sub_8237BB78 r31 0x820AFDA0 13 names 100% disc
sub_824E76D0 r10 0x8209FC64 13 names 92% disc
sub_82193648 r11 0x820A8278 12 names 83% disc
sub_82220FA8 r31 0x820A0E8C 12 names 100% disc
sub_822C7480 r31 0x8209E6D4 12 names 100% disc
sub_82320B48 r10 0x820B0000 12 names 100% disc
sub_823276D0 r31 0x820A97EC 12 names 100% disc
sub_826FA758 r11 0x820A81F0 12 names 92% disc
## The schema each one names, in code order
sub_82341A20 (r30, base 0x82088F94) names 217:

View File

@@ -204,6 +204,40 @@ HP 42 000 with levels at 25 000 / 10 000 and a lock-on release cycle
One record, `Generic`, one field — the **name** `eff_n0071` with an empty value.
An effect id and nothing else. Not identified.
## ✅ Classifying all 277 rows objectively — 53 are data-table schemas (2026-08-27)
The earlier pass classified by eye and by function. This one is **by row** and
uses an objective test: **are the row's names IDXD record/field names on the
disc?** (13 450 of those disc-wide.) `name_block_bases.py` now prints it.
| | rows |
|---|---:|
| **≥50 % disc names, ≥8 names — a data-table schema** | **53** |
| everything else (engine/XDK vocabulary, key lists, noise) | 224 |
Split against the base-confidence axis: `solved` bases (non-zero low half) split
34 / 136, `round` bases 16 / 91 — so **a round base is not the same question as a
non-table row**, and both axes are needed.
✅ The 53 include every loader the corpus already knows, which is the control.
**What they also include, still unopened** (each grepped: the noun appears in
no `docs/re/` file):
| row | names | what it looks like |
|---|---:|---|
| `sub_823BDAA8` r11 | 33 | `rou_e901` + `GN_MainGun_01_MuzC`, `GN_MainGun_02_Muz01…` — the **S16 boss's muzzle/attach frames**, next to the collision table above |
| `sub_823BDAA8` r10 | 25 | `Motion_stand`, `Motion_stand_b1`, `Motion_attackA_start`… — **motion names**, the `EnumMotions` family `DefTables` declares |
| `sub_82315AE8` r11 | 20 | `InitRotation`, `MaxRotationSpeed`, `RotationAccel`, `MaxVerticalSpeed` — the **`Guardian` record's own fields**, i.e. the S16 boss loader |
| `sub_8219E560` r11 | 18 | `Detail_Rank`, `MISSIONS`, `DETAIL_TITLE`, `Detail_Board_Permanent` — the **leaderboard screen** keys |
| `sub_825F2CF0` / `sub_825F2F88` r0 | 30 each | `FinalPassBG`, `FinalPassToneRatio`, `FogMin/MaxDistance`**post-processing**, two functions with the same base |
⚠️ Four rows that *look* new are not: `sub_82297550`, `sub_822A2F00`,
`sub_822A9C18`, `sub_82288028` mix arsenal fields the corpus owns
(`ConditionToDevelop`, `WeaponDesc` → [[arsenal-develop-economy]];
`SilhouetteModel` → [[arsenal-item-weapon-chain]]) with **literal screen
coordinates as strings** — `757,228`, `903,343`, `1092,457` — which is why their
disc-overlap sits at 5370 % rather than ~100 %.
## ✅ Mining the 277: what the base-solver's index actually contains (2026-08-27)
277 rows over **190 distinct functions** (a function can read more than one

View File

@@ -13,7 +13,7 @@ start. Control: it must recover `r30 = 0x82088F94` for the unit loader
Regenerates docs/re/data/name-block-bases.txt.
"""
import sys, collections, bisect
import sys, os, glob, collections, bisect
DB = '/work/xenia-rs/sylpheed.db'
MIN_GROUP = 8 # displacements needed before a group is worth solving
@@ -99,6 +99,47 @@ def main():
print(" ⚠ the 0x820B0000 cluster is ~60 near-identical functions in"
" 0x8281xxxx-0x8284xxxx that all name the same `rou_e0NN` list.")
# Is a row a DATA-TABLE schema or engine/XDK vocabulary? The objective test
# is whether its names are IDXD record/field names on the disc.
sys.path.insert(0, HERE) if False else None
from unit_substructures import pak_entries
import unitgroup as _U
disc = set()
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
for _h, b in pak_entries(pk):
if b[:4] != b'IDXD':
continue
try:
rs = _U.parse(b)
except Exception:
continue
for r in rs:
disc.add(r['squadron'])
for _t, n, _v in r['fields']:
if n:
disc.add(n)
print("\n## Is the row a DATA-TABLE schema? (names that are IDXD record/field"
" names on the disc)")
print(" distinct IDXD record+field names disc-wide: %d" % len(disc))
scored = []
for name, reg, B, tot, n in rows:
nm, seen = [], set()
for a, d in order[name][reg]:
t = B + d
if t in txt and t not in seen:
seen.add(t)
nm.append(txt[t])
if not nm:
continue
hit = sum(1 for x in nm if x in disc)
scored.append((hit / len(nm), hit, len(nm), name, reg, B))
tab = [r for r in scored if r[0] >= 0.5 and r[2] >= 8]
print(" rows that are >=50%% disc names and >=8 names: %d / %d"
% (len(tab), len(scored)))
for r in sorted(tab, key=lambda r: (-r[2], r[3])):
print(" %-14s %-4s 0x%08X %4d names %3.0f%% disc"
% (r[3], r[4], r[5], r[2], 100 * r[0]))
print("\n## The schema each one names, in code order")
for name, reg, B, tot, n in rows:
seen, names = set(), []