re: every AIParams object mapped to its stage, zero residual
StageResource.EnumerateAIParams names the table, and every name resolves. 29 StageResource records; 28 carry EnumerateAIParams (the one without it is the _Test template); 23 distinct table names declared; 23/23 hash to an AIParams object key under the prefix "stage\"; 0 objects left unnamed; 0 declared names with no object. AIParams_S01..S16 (16) + AIParams_S24..S29 (6) + AIParams_Tutorial.tbl shared by six (UnitGroup_S18..S23, the tutorials) = 23 tables over 16 + 6 + 6 = 28 records. The arithmetic closes both ways and matches the 23-object count found last iteration. Same sharing shape as the settings family (stage-settings-table.md: 24 objects, StageParameter_Tutorial shared by six tutorials). Two independent families agree on how the tutorials are handled -- n=2, a pattern rather than a rule. aiparams_census.py extended with the stage mapping; artefact +7/-0, byte-identical across two runs; the other fourteen verify unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
@@ -5166,3 +5166,35 @@ the field set above and nothing else.
|
||||
🟡 Not settled: which of the 23 objects belongs to which stage (only
|
||||
`AIParams_S02.tbl` is named by the corpus; the disc-wide harvest was not re-run
|
||||
against the other 22), and what consumes an `AIID` at runtime.
|
||||
|
||||
---
|
||||
|
||||
## ✅ 2026-08-27 — every `AIParams` object mapped to its stage, zero residual
|
||||
|
||||
Item (a). `aiparams_census.py` extended with the stage mapping; artefact
|
||||
**+7/−0**, byte-identical across two runs.
|
||||
|
||||
✅ **`StageResource.EnumerateAIParams` names the table, and every name resolves.**
|
||||
|
||||
| | |
|
||||
|---|---:|
|
||||
| `StageResource` records | 29 |
|
||||
| carrying `EnumerateAIParams` | **28** (the one without it is the `_Test` template) |
|
||||
| distinct table names declared | **23** |
|
||||
| names that hash to an `AIParams` object key | **23 / 23**, prefix `stage\` |
|
||||
| objects left unnamed | **0** |
|
||||
| declared names with no object | **0** |
|
||||
|
||||
`AIParams_S01…S16` (16) + `AIParams_S24…S29` (6) + **`AIParams_Tutorial.tbl`
|
||||
shared by six** (`UnitGroup_S18…S23`, the tutorials) = 23 tables over
|
||||
`16 + 6 + 6 = 28` records. **The arithmetic closes both ways** and matches the
|
||||
23-object count found last iteration.
|
||||
|
||||
🔑 Same sharing shape as the settings family (`stage-settings-table.md`: 24
|
||||
objects, `StageParameter_Tutorial` shared by six tutorials). Two independent
|
||||
families agree on how the tutorials are handled — n=2, a pattern rather than a
|
||||
rule, but a consistent one.
|
||||
|
||||
🟡 Not settled: what consumes an `AIID` at runtime (unchanged — the link from
|
||||
`UnitGroup.AIID` to a profile record is documented, the code that acts on the
|
||||
20 parameters is not).
|
||||
|
||||
@@ -15,6 +15,13 @@
|
||||
declared names with no record in their own object: 0
|
||||
profile records total: 782 (= 23 objects x 34)
|
||||
|
||||
## Which object is which stage
|
||||
StageResource records: 29 carrying EnumerateAIParams: 28
|
||||
distinct table names declared: 23 AIParams objects: 23
|
||||
names that hash to an object key: 23 / 23 (prefix `stage\`, name_hash is case-insensitive)
|
||||
objects left unnamed: 0 declared names with no object: 0
|
||||
shared: AIParams_Tutorial.tbl by 6 -> ['UnitGroup_S18.tbl', 'UnitGroup_S19.tbl', 'UnitGroup_S20.tbl', 'UnitGroup_S21.tbl', 'UnitGroup_S22.tbl', 'UnitGroup_S23.tbl']
|
||||
|
||||
## Does `Type` predict the field count?
|
||||
Fleet 6 fields x253
|
||||
Squad 6 fields x46
|
||||
|
||||
@@ -152,6 +152,28 @@ profiles and only the values move.** 🔑 The roster is declared the same way
|
||||
`DefTables` names its tables: an **`Enumerate_AIs` record whose field names are
|
||||
the profile names** (see [[archive-naming]] route 2).
|
||||
|
||||
### ✅ Which object is which stage — all 23 named, zero residual
|
||||
|
||||
`StageResource.EnumerateAIParams` names the table, and the names resolve:
|
||||
|
||||
| | |
|
||||
|---|---:|
|
||||
| `StageResource` records | 29 |
|
||||
| carrying `EnumerateAIParams` | **28** (the one without it is the `_Test` template) |
|
||||
| distinct table names declared | **23** |
|
||||
| names that hash to an `AIParams` object key | **23 / 23** |
|
||||
| objects left unnamed | **0** |
|
||||
| declared names with no object | **0** |
|
||||
|
||||
The names are `AIParams_S01…S16` (16), `AIParams_S24…S29` (6) and
|
||||
**`AIParams_Tutorial.tbl`, shared by six records** — `UnitGroup_S18…S23`, the six
|
||||
tutorials. `16 + 6 + 1 = 23` tables over `16 + 6 + 6 = 28` records; the arithmetic
|
||||
closes both ways.
|
||||
|
||||
🔑 That is the **same sharing shape as the settings family**
|
||||
([[stage-settings-table]]: 24 objects, `StageParameter_Tutorial` shared by six).
|
||||
The prefix is `stage\` — `name_hash` is case-insensitive, so its case is free.
|
||||
|
||||
### ⚠️ `Type` predicts the field count — with exactly two exceptions
|
||||
|
||||
| | |
|
||||
|
||||
@@ -58,6 +58,47 @@ def main():
|
||||
% (sum(len(p) for _h, _d, p in objs), len(objs),
|
||||
len(objs[0][2]) if objs else 0))
|
||||
|
||||
# Which object is which stage? `StageResource.EnumerateAIParams` names it.
|
||||
stageres = []
|
||||
for h, b in pak_entries(paks[0]):
|
||||
if b[:4] != b'IDXD':
|
||||
continue
|
||||
try:
|
||||
recs = U.parse(b)
|
||||
except Exception:
|
||||
continue
|
||||
for r in recs:
|
||||
if r['squadron'] == 'StageResource':
|
||||
stageres.append(dict((n, v) for _t, n, v in r['fields'] if n))
|
||||
named = sorted({d['EnumerateAIParams'] for d in stageres
|
||||
if d.get('EnumerateAIParams')})
|
||||
keys = {h for h, _d, _p in objs}
|
||||
resolved = {}
|
||||
for n in named:
|
||||
for pre in ('', 'stage\\', 'table\\'):
|
||||
k = U.name_hash(pre + n)
|
||||
if k in keys:
|
||||
resolved[n] = (pre + n, k)
|
||||
break
|
||||
print("\n## Which object is which stage")
|
||||
print(" StageResource records: %d carrying EnumerateAIParams: %d"
|
||||
% (len(stageres), sum(1 for d in stageres if d.get('EnumerateAIParams'))))
|
||||
print(" distinct table names declared: %d AIParams objects: %d"
|
||||
% (len(named), len(objs)))
|
||||
print(" names that hash to an object key: %d / %d (prefix `stage\\`,"
|
||||
" name_hash is case-insensitive)" % (len(resolved), len(named)))
|
||||
print(" objects left unnamed: %d declared names with no object: %d"
|
||||
% (len(keys - {v[1] for v in resolved.values()}),
|
||||
len([n for n in named if n not in resolved])))
|
||||
share = collections.defaultdict(list)
|
||||
for d in stageres:
|
||||
v = d.get('EnumerateAIParams')
|
||||
if v:
|
||||
share[v].append(d.get('EnumerateSquadron', '?'))
|
||||
for v, who in sorted(share.items()):
|
||||
if len(who) > 1:
|
||||
print(" shared: %-24s by %d -> %s" % (v, len(who), sorted(who)))
|
||||
|
||||
ct = collections.Counter()
|
||||
byname = collections.defaultdict(set)
|
||||
for _h, _d, p in objs:
|
||||
|
||||
Reference in New Issue
Block a user