re: the destructible-subsystem model -- a unit's sub-records

The corpus has named these since unit-struct-runtime.md but never
opened them.  Per unit table: Turret_NNN 835 records (max 63 on one
unit), ShieldGenerator_NNN 46, Thruster_NNN 38, Hatch_NNN 26,
Bridge_NNN 25, plus one each of Shield/Mass/SE/Explosion/
StructureCount and NS_Body on 68 of 114.

Turret/ShieldGenerator/Thruster/Hatch/Bridge are ONE record shape: a
shared 19-field destructible-part base (ID, Name, ParentStructureID,
Frame = a mesh NODE name, NomalModel, CollisionModel, Radius, HP, the
four Is* flags, SpreadDamage, damaged/destroy motion + time, and the
three Effect_*), with per-kind extras.  Turrets add WeaponID,
AngularVelocity, YawLimit, PitchLimit_Elevation/_Depression, CoverArea,
IsAuto, HasBarrel and up to 80 CannonModel_NNN/CannonFrame_NNN.  Shield
generators, thrusters and bridges add PowerRatio.  Hatches add
SquadronID, LoadedCount, MaxAvailableCount, TakeoffInterval -- a
carrier's launch bay.

Control 1: StructureCount.<Kind>Count == #<Kind>_NNN records, over 684
comparisons -- 612 equal, 55 "0 declared, one blank placeholder"
(55/55 blank in Name AND NomalModel AND Frame), 11 differ, 6 kind
absent.  All 11 exceptions are Turret and all are declared < records.

Control 2: 835/835 Turret_NNN.WeaponID resolve to an ID in the
131-record Weapon datasheet, zero unresolved; 26 weapons are never
mounted on a turret.

Refuted in the same pass: "the DeltaSaber's 59 non-NULL hardpoints are
the 59-name WEAPONS arsenal roster".  The counts match exactly and the
sets overlap in 0 values -- two namespaces, one coincidence.

New structure doc, artefact and regenerator; other artefacts unchanged.
This commit is contained in:
Sylpheed RE agent
2026-08-27 12:39:50 +00:00
parent 9abed411ce
commit 9281aa7456
5 changed files with 697 additions and 0 deletions

View File

@@ -827,6 +827,48 @@ unknown, what evidence exists, and what the first step would be. Move an item in
field; the stat keys in records not opened here (`MegaTons`, `BulletLimit`,
`CrewCount`, `HP_CLASS`); why the roster lists 59 of 131.
***(2026-08-27) THE DESTRUCTIBLE-SUBSYSTEM MODEL — a unit's sub-records,
opened at last. 835 turrets, and every turret's weapon resolves.**
[structures/unit-substructure-records](structures/unit-substructure-records.md),
artefact `data/unit-substructures.txt`, regenerator
`tools/re-capture/unit_substructures.py`.
The corpus has *named* these since `unit-struct-runtime.md` but never opened
them. Per unit table: `Turret_NNN` **835** records (max 63 on one unit),
`ShieldGenerator_NNN` 46, `Thruster_NNN` 38, `Hatch_NNN` 26, `Bridge_NNN` 25,
plus one each of `Shield`/`Mass`/`SE`/`Explosion`/`StructureCount` and
`NS_Body` on 68 of 114.
🔑 **`Turret`/`ShieldGenerator`/`Thruster`/`Hatch`/`Bridge` are ONE record
shape** — a shared 19-field destructible-part base (`ID`, `Name`,
`ParentStructureID`, **`Frame`** = a mesh NODE name, `NomalModel`,
`CollisionModel`, `Radius`, `HP`, `IsDestructible`, `IsShielded`,
`IsInvolved`, `IsRadarVisible`, `SpreadDamage`, damaged/destroy motion +
time, `Effect_Explosion`/`_Flare`/`_Paralyze`) with per-kind extras:
turrets add `WeaponID`, `AngularVelocity`, `YawLimit`,
`PitchLimit_Elevation`/`_Depression`, `CoverArea`, `IsAuto`, `HasBarrel` and
up to 80 `CannonModel_NNN`/`CannonFrame_NNN`; shield generators, thrusters
and bridges add **`PowerRatio`** (what the parent loses when the part dies);
hatches add `SquadronID`, `LoadedCount`, `MaxAvailableCount`,
`TakeoffInterval`**a carrier's launch bay**.
🧪 **Control 1**`StructureCount.<Kind>Count == #<Kind>_NNN records`:
**612 equal / 55 "0 declared, one blank placeholder" / 11 differ / 6 kind
absent**, over 684 comparisons. The 55 are a real sub-rule (a zero count
still emits exactly one record, blank in `Name` *and* `NomalModel` *and*
`Frame`, 55/55). All 11 exceptions are `Turret` and all are
`declared < records`; nine are the player DeltaSaber family (4 declared,
63 slots — 🟡 reads as a hardpoint catalogue, **not adopted**).
🧪 **Control 2** — **835 / 835 `Turret_NNN.WeaponID` values resolve to an
`ID` in the 131-record `Weapon` datasheet, zero unresolved**; 105 distinct
used, **26 weapons never mounted on a turret**. A hard cross-table link.
**Refuted in the same pass**: "the DeltaSaber's 59 non-NULL hardpoints are
the 59-name `WEAPONS` arsenal roster". The counts match exactly and the sets
**overlap in 0 values** — the roster is display names
(`Machiene_Cannon_MG1`), the hardpoints reference `Weapon.ID`
(`Weapon_TCAF_DeltaSaber_Gun`), and the 59 slots carry only **10 distinct**
weapon IDs. So the 59-of-131 question stays open, minus one wrong answer.
🟡 Not settled: `CoverArea` is a hex bit mask with unknown bits;
`Versatile_NNN` has only its `???` template row in this pak; the two `+1`
turret cases (`Elan_EX4`, `AAFrigate_EX4`).
***(2026-08-27) CORRECTION — `Generic` is a per-FILE HEADER record, not a
table. Only **114** of the 394 are unit datasheets.**
[structures/unit-datasheet-static](structures/unit-datasheet-static.md),

View File

@@ -99,6 +99,7 @@ files, which is how the same ground got covered twice.
| [`structures/sound-cue-table.md`](structures/sound-cue-table.md) | The cue index in `tables.pak` — message id -> cue -> sound id -> `.slb` bank | ✅ CONFIRMED, 1 326/1 338 script message ids bind to a bank; SOUNDS and FILES agree on the same 12 absentees, 0 orphan files |
| [`structures/cutscene-message-table.md`](structures/cutscene-message-table.md) | Cutscene dialogue — speaker, portrait, on-screen seconds, audio cue per page | ✅ CONFIRMED, field count = 9·PageCount+2 for all 7 PageCounts, 1 252/1 252 caption keys match, 138 ids close both ways |
| [`structures/isl-mission-timer.md`](structures/isl-mission-timer.md) | The mission timer — two sequential countdowns, not a limit and a warning | ✅ CONFIRMED — read from `sub_822639B8`; the threshold reading is |
| [`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/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 |

View File

@@ -0,0 +1,402 @@
# Sub-records inside the 114 unit tables of GP_MAIN_GAME_E.pak
# Regenerate: python3 tools/re-capture/unit_substructures.py
# See docs/re/structures/unit-substructure-records.md
## families (records, max per unit, distinct non-indexed field names)
Turret_NNN 835 max/unit 63 fields 38
Maneuver 114 max/unit 1 fields 101
Effect 114 max/unit 1 fields 9
Shield 114 max/unit 1 fields 4
Mass 114 max/unit 1 fields 2
SE 114 max/unit 1 fields 8
Generic 114 max/unit 1 fields 37
Explosion 114 max/unit 1 fields 9
StructureCount 114 max/unit 1 fields 6
NS_Body 68 max/unit 1 fields 12
ShieldGenerator_NNN 46 max/unit 4 fields 21
Thruster_NNN 38 max/unit 4 fields 21
Hatch_NNN 26 max/unit 4 fields 23
Bridge_NNN 25 max/unit 2 fields 20
NS_Body_2 1 max/unit 1 fields 12
Hatch_??? 1 max/unit 1 fields 19
ShieldGenerator_??? 1 max/unit 1 fields 16
NS_* 1 max/unit 1 fields 10
Bridge_??? 1 max/unit 1 fields 16
Thruster_??? 1 max/unit 1 fields 19
Turret_??? 1 max/unit 1 fields 25
Versatile_??? 1 max/unit 1 fields 15
## Turret_NNN -- non-indexed fields (records carrying it, of 835)
AngularVelocity 835
CoverArea 835
Effect_Explosion 835
Effect_Flare 835
Frame 835
HP 835
ID 835
IsAuto 835
IsDestructible 835
IsInvolved 835
IsRadarVisible 835
IsShielded 835
Name 835
NomalModel 835
ParentStructureID 835
PitchLimit_Depression 835
PitchLimit_Elevation 835
Radius 835
SequencingCount 835
SequencingInterval 835
SpreadDamage 835
WeaponID 835
YawLimit 835
CollisionModel 831
CommonCannonFrame 831
CommonCannonModel 831
HasBarrel 831
DamagedMotionName 829
DestroyMotionName 829
DestroyMotionTime 829
Effect_Paralyze 824
DisableCollision_Lost 240
CurveAngle 120
FCSAngle 120
FollowView 40
ShellModel 40
CoverModel 26
DamagedModel 6
## Effect -- non-indexed fields (records carrying it, of 114)
FadeIn 113
FadeOut 113
JumpIn 113
JumpOut 113
Shield 79
Effect_Paralyze 74
ShieldHitEffectName 35
ShieldRecoverEffectName 35
Thruster 1
## Shield -- non-indexed fields (records carrying it, of 114)
ChargeDelay 114
ChargeDelay_Break 114
ChargeSpeed 114
MaxValue 114
## Mass -- non-indexed fields (records carrying it, of 114)
DryMass 114
GrossMass 114
## SE -- non-indexed fields (records carrying it, of 114)
ExplosionSE 114
Thruster 114
JumpIn 113
JumpOut 113
LowerHPSE 113
LowerHPThresholdRatio 113
ShipEnvironmentSE 113
SideThruster 113
## Explosion -- non-indexed fields (records carrying it, of 114)
Delay 114
DelayAdjustment 114
ExplosionFxModel 113
LowerHPFxModel 113
DestroyMotionTime 112
DestroyMotionName 109
ExplosionMotionName 109
ExplosionFxMotion 3
LowerHPFxMotion 3
## StructureCount -- non-indexed fields (records carrying it, of 114)
BridgeCount 114
HatchCount 114
ShieldGeneratorCount 114
ThrusterCount 114
TurretCount 114
VersatileCount 114
## NS_Body -- non-indexed fields (records carrying it, of 68)
AttenuationAlpha 68
AttenuationVolume 68
Color_B 68
Color_G 68
Color_R 68
Deceleration 68
DeleteFadeSpeed 68
Interval 68
Model 68
NodeCount 68
StartingVelocity 68
Volume 68
## ShieldGenerator_NNN -- non-indexed fields (records carrying it, of 46)
CollisionModel 46
DamagedMotionName 46
DestroyMotionName 46
DestroyMotionTime 46
Effect_Explosion 46
Effect_Flare 46
Effect_Paralyze 46
Frame 46
HP 46
ID 46
IsDestructible 46
IsInvolved 46
IsRadarVisible 46
IsShielded 46
Name 46
NomalModel 46
ParentStructureID 46
PowerRatio 46
Radius 46
SpreadDamage 46
DisableCollision_Lost 25
## Thruster_NNN -- non-indexed fields (records carrying it, of 38)
CollisionModel 38
DamagedMotionName 38
DestroyMotionName 38
DestroyMotionTime 38
Effect_Explosion 38
Effect_Flare 38
Effect_Paralyze 38
Frame 38
HP 38
ID 38
IsDestructible 38
IsInvolved 38
IsRadarVisible 38
IsShielded 38
Name 38
NomalModel 38
NozzleCount 38
ParentStructureID 38
PowerRatio 38
Radius 38
SpreadDamage 38
## Hatch_NNN -- non-indexed fields (records carrying it, of 26)
CollisionModel 26
DamagedMotionName 26
DestroyMotionName 26
DestroyMotionTime 26
Effect_Explosion 26
Effect_Flare 26
Effect_Paralyze 26
Frame 26
HP 26
ID 26
IsDestructible 26
IsInvolved 26
IsRadarVisible 26
IsShielded 26
LoadedCount 26
MaxAvailableCount 26
Name 26
NomalModel 26
ParentStructureID 26
Radius 26
SpreadDamage 26
SquadronID 26
TakeoffInterval 26
## Bridge_NNN -- non-indexed fields (records carrying it, of 25)
CollisionModel 25
DamagedMotionName 25
DestroyMotionName 25
DestroyMotionTime 25
Effect_Explosion 25
Effect_Flare 25
Effect_Paralyze 25
Frame 25
HP 25
ID 25
IsDestructible 25
IsInvolved 25
IsRadarVisible 25
IsShielded 25
Name 25
NomalModel 25
ParentStructureID 25
PowerRatio 25
Radius 25
SpreadDamage 25
## NS_Body_2 -- non-indexed fields (records carrying it, of 1)
AttenuationAlpha 1
AttenuationVolume 1
Color_B 1
Color_G 1
Color_R 1
Deceleration 1
DeleteFadeSpeed 1
Interval 1
Model 1
NodeCount 1
StartingVelocity 1
Volume 1
## Hatch_??? -- non-indexed fields (records carrying it, of 1)
DamagedModel 1
Effect_Explosion 1
Effect_Flare 1
Frame 1
HP 1
ID 1
IsDestructible 1
IsInvolved 1
IsRadarVisible 1
IsShielded 1
LoadedCount 1
MaxAvailableCount 1
Name 1
NomalModel 1
ParentStructureID 1
Radius 1
SpreadDamage 1
SquadronID 1
TakeoffInterval 1
## ShieldGenerator_??? -- non-indexed fields (records carrying it, of 1)
DamagedModel 1
Effect_Explosion 1
Effect_Flare 1
Frame 1
HP 1
ID 1
IsDestructible 1
IsInvolved 1
IsRadarVisible 1
IsShielded 1
Name 1
NomalModel 1
ParentStructureID 1
PowerRatio 1
Radius 1
SpreadDamage 1
## NS_* -- non-indexed fields (records carrying it, of 1)
AttenuationAlpha 1
AttenuationVolume 1
Color_B 1
Color_G 1
Color_R 1
Deceleration 1
DeleteFadeSpeed 1
Interval 1
NodeCount 1
StartingVelocity 1
## Bridge_??? -- non-indexed fields (records carrying it, of 1)
DamagedModel 1
Effect_Explosion 1
Effect_Flare 1
Frame 1
HP 1
ID 1
IsDestructible 1
IsInvolved 1
IsRadarVisible 1
IsShielded 1
Name 1
NomalModel 1
ParentStructureID 1
PowerRatio 1
Radius 1
SpreadDamage 1
## Thruster_??? -- non-indexed fields (records carrying it, of 1)
DamagedModel 1
Effect_Explosion 1
Effect_Flare 1
Frame 1
HP 1
ID 1
IsDestructible 1
IsInvolved 1
IsRadarVisible 1
IsShielded 1
Name 1
NomalModel 1
NozzleCount 1
NozzleFrame_??? 1
NozzleSpec_??? 1
ParentStructureID 1
PowerRatio 1
Radius 1
SpreadDamage 1
## Turret_??? -- non-indexed fields (records carrying it, of 1)
AngularVelocity 1
CannonFrame_??? 1
DamagedModel 1
Effect_Explosion 1
Effect_Flare 1
Frame 1
HP 1
ID 1
IsAuto 1
IsDestructible 1
IsInvolved 1
IsRadarVisible 1
IsShielded 1
MuzzleFrame_??? 1
Name 1
NomalModel 1
ParentStructureID 1
PitchLimit_Depression 1
PitchLimit_Elevation 1
Radius 1
SequencingCount 1
SequencingInterval 1
SpreadDamage 1
WeaponID 1
YawLimit 1
## Versatile_??? -- non-indexed fields (records carrying it, of 1)
DamagedModel 1
Effect_Explosion 1
Effect_Flare 1
Frame 1
HP 1
ID 1
IsDestructible 1
IsInvolved 1
IsRadarVisible 1
IsShielded 1
Name 1
NomalModel 1
ParentStructureID 1
Radius 1
SpreadDamage 1
## CONTROL StructureCount.<Kind>Count == #<Kind>_NNN records
## (a 0 count still emits one blank slot)
684 comparisons (114 units x 6 kinds)
equal 612
0 declared, 1 blank placeholder 55
DIFFERS 11
no field 6
exceptions:
kind=Turret declared=4 records=63 x7
UN_f001_TCAF_DeltaSaber_T
UN_f001_TCAF_DeltaSaber_T_EX5
UN_f001_TCAF_DeltaSaber_T_EX5_el
UN_f001_TCAF_DeltaSaber_T_Player
UN_f002_TCAF_DeltaSaber_W
UN_f002_TCAF_DeltaSaber_W_Player
UN_f004_TCAF_DeltaSaber_A_Player
kind=Turret declared=4 records=5 x2
UN_f001_TCAF_DeltaSaber_T_Player_Ttrl1
UN_f001_TCAF_DeltaSaber_T_Player_Ttrl2
kind=Turret declared=1 records=2 x1
UN_e001_ADAN_Elan_EX4
kind=Turret declared=8 records=9 x1
UN_e107_ADAN_AAFrigate_EX4
## CONTROL Turret_NNN.WeaponID resolves into the Weapon datasheet
Weapon.ID values: 131
turrets: 835, distinct WeaponID: 105
resolve: 835 do NOT resolve: 0
weapons never mounted on a turret: 26

View File

@@ -0,0 +1,131 @@
# ✅ The destructible-subsystem model — a unit's sub-records
The corpus has named the sub-records of a unit `.tbl` since
[unit-struct-runtime](unit-struct-runtime.md) ("`Generic`, `Maneuver`,
`Shield`, `Explosion`, `Mass`, `Effect`, `SE`, `Turret_00N` … all flattened
into that single object") but has never **opened** them. This does.
One unit = one IDXD pak entry. 114 of them
([the `Generic` partition](unit-datasheet-static.md)). Artefact
`../data/unit-substructures.txt`, regenerator
`tools/re-capture/unit_substructures.py`.
| family | records | max/unit | non-indexed fields |
|---|---:|---:|---:|
| `Turret_NNN` | **835** | 63 | 38 |
| `Generic` / `Maneuver` / `Effect` / `Shield` / `Mass` / `SE` / `Explosion` / `StructureCount` | 114 each | 1 | — |
| `NS_Body` | 68 | 1 | 12 |
| `ShieldGenerator_NNN` | 46 | 4 | 21 |
| `Thruster_NNN` | 38 | 4 | 21 |
| `Hatch_NNN` | 26 | 4 | 23 |
| `Bridge_NNN` | 25 | 2 | 20 |
Seven singletons named with a literal `???` (`Turret_???`, `Versatile_???`, …)
are the schema's own template rows.
## The shared destructible-part base
`Turret`, `ShieldGenerator`, `Thruster`, `Hatch` and `Bridge` are the **same
record shape** with per-kind extras. Every one of the 970 part records carries:
```
ID Name ParentStructureID Frame NomalModel CollisionModel Radius
HP IsDestructible IsShielded IsInvolved IsRadarVisible SpreadDamage
DamagedMotionName DestroyMotionName DestroyMotionTime
Effect_Explosion Effect_Flare Effect_Paralyze
```
(`NomalModel` is the game's own spelling.) `Frame` is a **mesh node name**
`GN_mnt` on the player craft — so a part is bolted to a named bone of the
`Generic.Model` mesh the corpus already decodes.
Per-kind, on top of that base:
| kind | extra fields |
|---|---|
| `Turret` | `WeaponID`, `AngularVelocity`, `YawLimit`, `PitchLimit_Elevation`, `PitchLimit_Depression`, `CoverArea`, `IsAuto`, `HasBarrel`, `CommonCannonModel`/`Frame`, `CannonModel_NNN`/`CannonFrame_NNN` (up to 80), `SequencingCount`, `SequencingInterval`, and on a few: `CurveAngle`, `FCSAngle`, `FollowView`, `ShellModel`, `CoverModel` |
| `ShieldGenerator` / `Thruster` / `Bridge` | `PowerRatio` — losing the part degrades the parent |
| `Thruster` | `NozzleCount` |
| `Hatch` | `SquadronID`, `LoadedCount`, `MaxAvailableCount`, `TakeoffInterval`**a carrier's launch bay** |
🔑 That is a complete component model: named bone, own mesh and collision mesh,
own HP and destruction motion + effects, and a `PowerRatio` saying what the
parent loses when it dies.
## The one-record blocks
| record | fields |
|---|---|
| `Shield` | `MaxValue`, `ChargeSpeed`, `ChargeDelay`, `ChargeDelay_Break` |
| `Mass` | `DryMass`, `GrossMass` |
| `SE` | `ExplosionSE`, `Thruster`, `SideThruster`, `JumpIn`, `JumpOut`, `ShipEnvironmentSE`, `LowerHPSE`, `LowerHPThresholdRatio` |
| `Explosion` | `Delay`, `DelayAdjustment`, `ExplosionFxModel`, `ExplosionMotionName`, `LowerHPFxModel`, `DestroyMotionName`, `DestroyMotionTime` |
| `StructureCount` | `TurretCount`, `BridgeCount`, `HatchCount`, `ShieldGeneratorCount`, `ThrusterCount`, `VersatileCount` |
| `NS_Body` | `Model`, `NodeCount`, `Interval`, `StartingVelocity`, `Deceleration`, `Volume`, `Color_R/G/B`, `AttenuationVolume`, `AttenuationAlpha`, `DeleteFadeSpeed` — an engine-trail ribbon, on 68 of 114 |
Every field the runtime doc reached for `Shield` (`MaxValue +0x238`,
`ChargeSpeed +0x244`) and `Mass` (`DryMass +0x274`, `GrossMass +0x278`) is
here, at the same names.
## 🧪 Control 1 — `StructureCount` counts the part records
`declared == #<Kind>_NNN records`, over 114 units × 6 kinds = 684:
| | |
|---|---:|
| equal | **612** |
| declared 0, one blank placeholder record | 55 |
| differs | **11** |
| kind absent from `StructureCount` | 6 |
The 55 are a real sub-rule, not slack: a kind with a count of **0 still emits
exactly one record**, and all 55 have empty `Name`, `NomalModel` *and* `Frame`.
So the file always carries at least one slot per kind.
Every one of the 11 exceptions is a **`Turret`**, and every one has
`declared < records` — never the other way round. Nine are the player's
DeltaSaber family:
```
declared=4 records=63 x7 f001_T, f001_T_EX5, f001_T_EX5_el, f001_T_Player,
f002_W, f002_W_Player, f004_A_Player
declared=4 records=5 x2 f001_T_Player_Ttrl1 / _Ttrl2
declared=1 records=2 x1 UN_e001_ADAN_Elan_EX4
declared=8 records=9 x1 UN_e107_ADAN_AAFrigate_EX4
```
🟡 The reading — **not adopted**: on the player craft the `Turret_NNN` list is
a *hardpoint catalogue* and `TurretCount 4` is how many mount at once. It fits
(63 slots, all `Frame=GN_mnt`, all `IsAuto=No`, 10 distinct `WeaponID`s across
them, and the tutorial variants carry a cut-down 5) but nothing here shows the
selection. The two `+1` warship/craft cases are unexplained.
## 🧪 Control 2 — turret weapons resolve into the weapon datasheet
**835 / 835 `Turret_NNN.WeaponID` values are an `ID` in the 131-record
`Weapon` table. Zero unresolved.** 105 distinct values are used; **26 of the
131 weapons are never mounted on a turret** — the player-only arsenal.
That is a hard cross-table link: [the weapon
datasheet](weapon-datasheet-static.md) is what arms every gun on every ship.
## ❌ Refuted in the same pass — "the 59 hardpoints are the 59-name arsenal roster"
The DeltaSaber's 63 turret slots hold **59 non-`Weapon_NULL`** entries, and the
`WEAPONS` roster in `GP_HANGAR_ARSENAL.pak` has exactly **59** names. Tempting,
and wrong: the two sets **overlap in 0 values**, and the 59 slots carry only
**10 distinct** `WeaponID`s. The roster is display names
(`Machiene_Cannon_MG1` — the game's spelling); the hardpoints reference
`Weapon.ID` (`Weapon_TCAF_DeltaSaber_Gun`). Two namespaces, one coincidence of
count.
## 🟡 Not settled
* What links a roster entry to a `Weapon.ID` — the 59-of-131 question is still
open, and this pass shows the answer is **not** the hardpoint list.
* `Versatile_NNN` has 0 populated records in this pak; only the `???` template
row exists, so its schema is known and its instances are not.
* `CoverArea` reads as a hex word (`0x00000000` / `0x00000001`) — a bit mask,
bits unknown.
* The 6 `no field` comparisons are one unit whose `StructureCount` omits every
count.