re: AA_/AV_ are one interleaved block; the selection is still unfound

sub_822F9498 (the unit-definition loader, called only from sub_821A6CF0) is the
only function referencing the AA_/AV_ name strings.  Mapping each name to the
stfs that follows gives an exact interleave: AV_ at X, AA_ at X+8, for all five
axes -- PitchPlus 196/204, PitchMinus 212/220, Yaw 228/236, Roll 244/252,
AxisMode 320/328.  A selector is an offset of 0 or 8, not two lookups.

The 20 strings exist twice in the image; the first block is referenced by
nothing.  Data control: the ten suffixes match exactly between families.

The selection stays a reading: functions loading two or more of 196/204/320/328
number 39 image-wide, and only two are call-graph-reachable from the loader.

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 17:54:53 +00:00
parent 7d34428bec
commit fb0b5fbb28
3 changed files with 88 additions and 3 deletions

View File

@@ -4432,3 +4432,47 @@ was designed, not before. The rule says grep the doc that owns the DATA first;
here the data was "wingman", the owning doc was `isl-condition-builtins.md`, and
reading it first would have reframed the iteration rather than corrected it
afterwards.
---
## ✅🔴 2026-08-27 — `AA_`/`AV_` are one interleaved block; the selection is still unfound
**Docs greped BEFORE designing the experiment** (the rule that cost me last
iteration): `unit-datasheet-static.md` **owns the field family** and already says
🟡 "anti-air vs anti-vessel is the obvious reading — **not adopted**, nothing here
shows the selection"; `live-unit-definitions.md` owns the runtime field map and
records that `AA_AxisMode_*`/`AV_AxisMode_*` default to 0;
`unit-struct-runtime.md` owns the `Maneuver` declaration-order result;
`flight-speed-law.md` and `isl-builtins.md` mention the prefixes in passing.
**What none of them says is which code reads them.**
✅ **Exactly one function references the names.** `sub_822F9498` — the
unit-definition loader, called only from `sub_821A6CF0` — reads 78 named float
fields; nothing else in the image touches an `AA_`/`AV_` string.
✅ **The layout is an exact interleave: `AV_` at `X`, `AA_` at `X+8`.**
PitchPlus `+196/+200` vs `+204/+208`; PitchMinus `+212/+216` vs `+220/+224`;
Yaw `+228/+232` vs `+236/+240`; Roll `+244/+248` vs `+252/+256`; AxisMode
`+320/+324` vs `+328/+332`. **The constant +8 is the finding** — a selector is an
offset of 0 or 8, not two lookups.
✅ **Data control:** the ten suffixes match **exactly** between families (list
equality, not a count); 690 records each for the eight rate fields, 36 each for
`AxisMode`. `AA_` is usually the larger value (`AA_AxisMode_Min` 100 vs 35;
`AA_Yaw_Max` 50 vs 25) — but `AA_PitchPlus_Min` 100 vs `AV_` 200 goes the other
way, so that is a description, not a rule.
⚠️ **The 20 strings exist twice** (`0x82085B98…` and `0x8209F674…`); the loader
uses the second block and **the first 20 are referenced by nothing**.
🔴 **The selection is NOT settled, and the offset route failed again.** Functions
loading two or more of `+196`/`+204`/`+320`/`+328` number **39** across the image
— those offsets are far too common to identify a consumer. Only two are
call-graph-reachable from the loader's owner (`sub_821A6CF0`, `sub_821AB650`);
that is the next handle. **"Anti-air vs anti-vessel" stays a reading**, exactly as
`unit-datasheet-static.md` had it.
**Method slip to record:** I dumped ~1 100 disassembled instructions to find the
name→offset mapping when a scripted `addi`→`stfs` pairing (which I then wrote
anyway) gave the same 20 lines. Script the extraction first; never eyeball a
4.5 KB function.

View File

@@ -107,7 +107,7 @@ files, which is how the same ground got covered twice.
| [`structures/hangar-loadout-system.md`](structures/hangar-loadout-system.md) | The Hangar loadout system — loadout → per-slot allow-list → arsenal item | ✅ CONFIRMED — 60/60 slot refs, 70/88 item refs (18 = the `No_Equipment` sentinel) |
| [`structures/arsenal-item-weapon-chain.md`](structures/arsenal-item-weapon-chain.md) | The 59-of-131 arsenal question — an item names a hardpoint slot, not a weapon | ✅✅ CONFIRMED — 0/59 `PlayerWeapon` are a `Weapon.ID`, 59/59 are a `Turret_NNN` slot |
| [`structures/unit-substructure-records.md`](structures/unit-substructure-records.md) | The destructible-subsystem model — a unit's `Turret`/`Bridge`/`Hatch`/`ShieldGenerator`/`Thruster` sub-records | ✅ CONFIRMED — 835 turrets, 835/835 `WeaponID` resolve, `StructureCount` control 667/684 |
| [`structures/unit-datasheet-static.md`](structures/unit-datasheet-static.md) | The static unit datasheet and AI flight model — `Generic`, `Maneuver`, `Effect` | ✅ CONFIRMED — 394 Generic + 114 Maneuver + 114 Effect records read |
| [`structures/unit-datasheet-static.md`](structures/unit-datasheet-static.md) | The static unit datasheet and AI flight model — `Generic`, `Maneuver`, `Effect` | ✅ CONFIRMED — 394 Generic + 114 Maneuver + 114 Effect records read; AA_/AV_ are one interleaved block (AV at X, AA at X+8), selection still unfound |
| [`structures/weapon-datasheet-static.md`](structures/weapon-datasheet-static.md) | The static weapon datasheet — `Weapon`, `Shell`, `AssortMissileParam` | ✅ CONFIRMED — 131 Weapon + 131 Shell + 9 AssortMissileParam records read |
| [`structures/isl-timers.md`](structures/isl-timers.md) | A ScriptPhase owns 32 stopwatches, and they count seconds | ✅ CONFIRMED — the advance is read from `sub_822710D0`, the unit from |
| [`structures/isl-message-dialogue-link.md`](structures/isl-message-dialogue-link.md) | Mission scripts as dialogue — built-in 64 -> message id -> caption text | ✅ CONFIRMED total, 2 683/2 683 call sites across all 28 stages resolve, no residue |

View File

@@ -109,8 +109,49 @@ AA_* and AV_* Pitch/Yaw/Roll Min/Max pairs
```
🟡 The `AA_` / `AV_` prefixes pair with `AttackCraftPoint` / `AttackVesselPoint`,
so *anti-air* vs *anti-vessel* rate limits is the obvious reading — **not
adopted**, nothing here shows the selection.
so *anti-air* vs *anti-vessel* rate limits is the obvious reading — **still not
adopted**. See below for what the executable does say.
### ✅ The two families are one interleaved block (2026-08-27)
Exactly **one** function in the image references the `AA_`/`AV_` name strings:
`sub_822F9498`, the unit-definition loader, itself called only from
`sub_821A6CF0`. Mapping each `addi rN, r29, -offset` (the name) to the `stfs`
that follows gives the definition-object layout, and it is a clean interleave —
**`AV_` at `X`, `AA_` at `X+8`**, for all five axes:
| axis | `AV_Max` / `AV_Min` | `AA_Max` / `AA_Min` |
|---|---|---|
| `PitchPlus` | `+196` / `+200` | `+204` / `+208` |
| `PitchMinus` | `+212` / `+216` | `+220` / `+224` |
| `Yaw` | `+228` / `+232` | `+236` / `+240` |
| `Roll` | `+244` / `+248` | `+252` / `+256` |
| `AxisMode` | `+320` / `+324` | `+328` / `+332` |
The **constant `+8` displacement** is the structural point: whatever selects
between the families does it as an offset of `0` or `8`, not as two separate
lookups. The loader reads 78 named float fields in total.
Data side: the ten suffixes match **exactly** between the two families (checked
as a list equality, not a count), with 690 records each for the eight rate fields
and 36 each for `AxisMode`. Where the values differ, **`AA_` is consistently the
larger** — `AA_AxisMode_Min` 100 vs `AV_` 35, `AA_Yaw_Max` 50 vs `AV_` 25,
`AA_PitchPlus_Min` 100 vs `AV_` 200 being the exception that keeps this a
description, not a rule.
⚠️ **The 20 strings exist twice** in the image, at `0x82085B98…` and
`0x8209F674…`. The loader uses the second block; **the first 20 are referenced by
nothing**.
### 🔴 The selection is still not found
Looking for the consumer by offset does not work here: functions loading two or
more of `+196`/`+204`/`+320`/`+328` number **39** across the image, and those
offsets are far too common to identify anything — the same trap the corpus has
paid for before. Only two of the 39 are call-graph-reachable from the loader's
owner (`sub_821A6CF0` itself, and `sub_821AB650`); that is the next handle, and
it was not followed this iteration. **So "anti-air vs anti-vessel" remains a
reading.**
## `Effect`