diff --git a/docs/re/BACKLOG.md b/docs/re/BACKLOG.md index 19d13ba..714211c 100644 --- a/docs/re/BACKLOG.md +++ b/docs/re/BACKLOG.md @@ -5082,3 +5082,46 @@ noise floor (stack frames) and are excluded. 🟡 Not settled: how the 11 curve samples are *applied* (the loader names the records; the interpolation is downstream); the remaining 255 of the 277 solved functions are listed but unexamined; what selects `Booster` (unchanged). + +--- + +## ✅ 2026-08-27 — mining the base-solver index: a false-positive mode named, and the AI-table reader found + +Item (a). 277 rows over **190 distinct functions** (a function can read several +blocks). `name_block_bases.py` extended with a confidence split; artefact +**+11/−0**, byte-identical across two runs. + +🔴 **The tool's false-positive mode, now measured and named.** **107 of 277** rows +solve to a base on a **64K boundary** — a bare `addis rX, r0, 0xHHHH` with no +`addi`, so any scatter of displacements votes for it. **82 are `0x820B0000`**: +~60 near-identical functions in `0x8281xxxx–0x8284xxxx` all "naming" the same +`rou_e007 rou_e010 …` list. **The 170 rows with a non-zero low half are the +trustworthy set.** ⚠️ A round base is not automatically wrong — `sub_822215D0` +sits on `0x820A0000` and resolves 205/206 — so read the ratio, not the base. + +✅ **Already owned, and the index re-derives them** (that is the control): the +unit loader (217), stage settings (129), `PlayerParams` (90), hangar (81), +squadron orders, missile guidance, shell movement, substructures, six camera/fog +readers. + +🔑 **The find: `sub_8233C368` reads the AI behaviour table** — `r28`, base +`0x8208583C`, 20 names: **`Enumerate_AIs`**, `FiringLength`, `GuardLength`, +`AutoGuardLength`, `CounterLength`, `MusterLength`, … `stage-mission-tables.md` +owns those *field* names on the data side; **`Enumerate_AIs` appears in no +document and no reader was known** — the corpus carries the AI tail of `Maneuver` +as 🟡 NEEDS-HUMAN/runtime. **It is statically reachable after all.** The same base +also serves `sub_82338EE0` (97 names, `Weapon TargetType SpecialWeaponType +ReticleType IsCharging …`) — the weapon datasheet loader, also not previously +named. + +❔ **Five unowned blocks surfaced, none opened:** `sub_822215D0` (205/206, +`PGHUD_*`/`PGREMAIN_NUM%d` HUD part names), `sub_822814D8` + `sub_8227A3A0` +(`STAGE_RESULT`, `stage_num_shoot_down_aircrafts`, `EX_OVERVIEW`), +`sub_822E3EC8` (`g_mWorldViewProjection`, `NormalMap`, `GlossinessMap` — engine +material slots), `sub_823C0260` + `sub_823AE908` (`Boss16Collision*`, +cross-linking the S16 `Guardian` object), `sub_822AFA50` +(`roh_n001_menu1_cam_pos` — menu camera tags). + +🟡 Not settled: the index says what each function *names*, not what each *means* +— nothing above was opened. And the 107 low-confidence rows were flagged, not +re-solved with a stricter method. diff --git a/docs/re/data/name-block-bases.txt b/docs/re/data/name-block-bases.txt index 6178006..cd91d09 100644 --- a/docs/re/data/name-block-bases.txt +++ b/docs/re/data/name-block-bases.txt @@ -284,6 +284,17 @@ sub_82766DB0 r11 0x82050000 12 / 29 sub_827D7C00 r11 0x82060000 12 / 14 +## Confidence split + bases with a non-zero low half (a real `addis`+`addi` pair): 170 + bases on a 64K boundary (LOW CONFIDENCE, see below) : 107 + 0x820B0000 x82 rows + 0x82030000 x10 rows + 0x82050000 x7 rows + 0x820A0000 x5 rows + 0x82040000 x2 rows + 0x82060000 x1 rows + ⚠ the 0x820B0000 cluster is ~60 near-identical functions in 0x8281xxxx-0x8284xxxx that all name the same `rou_e0NN` list. + ## The schema each one names, in code order sub_82341A20 (r30, base 0x82088F94) names 217: diff --git a/docs/re/structures/player-tuning-tables.md b/docs/re/structures/player-tuning-tables.md index 44112c3..22ce18a 100644 --- a/docs/re/structures/player-tuning-tables.md +++ b/docs/re/structures/player-tuning-tables.md @@ -203,3 +203,48 @@ 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. + +## ✅ 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 +block). Classified: + +**🔴 The tool's false-positive mode, now named.** 107 rows solve to a base on a +**64K boundary** — a bare `addis rX, r0, 0xHHHH` with no `addi` of its own, so any +scatter of displacements votes for it. **82 of them are `0x820B0000`**, and they +are ~60 near-identical functions in `0x8281xxxx–0x8284xxxx` all "naming" the same +`rou_e007 rou_e010 rou_e015 …` list. Read a round base with its resolution ratio, +never on its own. The 170 rows with a non-zero low half are the trustworthy set. + +**Already owned** (the index re-derives them, which is the point): the unit +loader `sub_82341A20` (217), stage settings `sub_8230D1F8` (129), `PlayerParams` +`sub_822F9498` (90), the hangar `sub_822AE628` (81), squadron orders +(`sub_82320B48` → `ORDER_WINGMAN_*`), missile guidance (`sub_8236B608`, +`sub_8237BB78` → `st1_up_aperture` etc., [[weapon-datasheet-static]]), shell +movement (`sub_82261F70` → `Spiral_BeginTime`, [[weapon-struct-runtime]]), +substructures (`sub_823479B8` → `ParentStructureID`), and six camera/fog readers +(`sub_825F2CF0`, `sub_825F2F88`, `sub_8247DFC0`, `sub_823B2620`, `sub_82222E70`, +`sub_822C7480`). + +**🔑 The find: `sub_8233C368` reads the AI behaviour table.** `r28`, base +`0x8208583C`, 20 names — **`Enumerate_AIs`**, `FiringLength`, `GuardLength`, +`AutoGuardLength`, `CounterLength`, `MusterLength`, … [[stage-mission-tables]] +owns those *field* names on the data side; **`Enumerate_AIs` appears in no +document, and no reader was known** — the corpus carries the AI tail of +`Maneuver` as 🟡 NEEDS-HUMAN/runtime. It is statically reachable after all. +The same base `0x8208583C` also serves `sub_82338EE0` (97 names, +`Weapon TargetType SpecialWeaponType ReticleType IsCharging …`) — the **weapon** +datasheet loader, likewise not previously named. + +**Other unowned blocks the index surfaces** (measured, not investigated): +`sub_822215D0` (205/206, `PGHUD_*` / `PGREMAIN_NUM%d` / `PGTIMER_NUM%d` — HUD +part names; [[mission-script-manifest]] mentions `PGHUD_SUBTARGET` only), +`sub_822814D8` + `sub_8227A3A0` (`STAGE_RESULT`, `stage_num_shoot_down_aircrafts`, +`EX_OVERVIEW` — results/leaderboard fields), `sub_822E3EC8` +(`g_mWorldViewProjection`, `NormalMap`, `GlossinessMap` — engine shader/material +slots), `sub_823C0260` + `sub_823AE908` (`Boss16CollisionBody01…`, +`rou_e901_body_02_c` — the S16 boss collision parts, cross-linking the `Guardian` +object above), and `sub_822AFA50` (`roh_n001_menu1_cam_pos` — menu camera tags). + +🟡 None of those five were opened; the index says what each names, not what each +means. diff --git a/tools/re-capture/name_block_bases.py b/tools/re-capture/name_block_bases.py index ad1d62d..0b04afc 100644 --- a/tools/re-capture/name_block_bases.py +++ b/tools/re-capture/name_block_bases.py @@ -84,6 +84,21 @@ def main(): for name, reg, B, tot, n in rows: print(" %-18s %-5s 0x%08X %d / %d" % (name, reg, B, tot, n)) + # Confidence. A base whose low half is 0x0000 is a bare `addis` with no + # `addi` of its own -- any scatter of displacements votes for it, so those + # rows are the tool's false-positive mode and must be read with the + # resolution ratio, not on their own. + round_rows = [r for r in rows if (r[2] & 0xFFFF) == 0] + solved_rows = [r for r in rows if (r[2] & 0xFFFF) != 0] + print("\n## Confidence split") + print(" bases with a non-zero low half (a real `addis`+`addi` pair): %d" % len(solved_rows)) + print(" bases on a 64K boundary (LOW CONFIDENCE, see below) : %d" % len(round_rows)) + rb = collections.Counter(r[2] for r in round_rows) + for B, c in sorted(rb.items(), key=lambda kv: (-kv[1], kv[0])): + print(" 0x%08X x%d rows" % (B, c)) + print(" ⚠ the 0x820B0000 cluster is ~60 near-identical functions in" + " 0x8281xxxx-0x8284xxxx that all name the same `rou_e0NN` list.") + print("\n## The schema each one names, in code order") for name, reg, B, tot, n in rows: seen, names = set(), []