# ✅ The in-game HUD configuration — 16 records, and a per-stage resource table The `GP_MAIN_GAME_*2D.pak` archives carry **six IDXD entries** that are the in-game counterpart of `tables.pak`'s menu configs. Only `HudResource` had been opened ([mission-script-manifest](mission-script-manifest.md)); the other **fifteen** records had not. No `docs/re/` file mentions `ArmsStatus`, `RangeFinder`, `Radar`, `Sight`, `Wing`, `NamePlate` or `ResourceTable` — checked before writing this. Artefact `../data/hud-config.txt` (697 lines), regenerator `tools/re-capture/hud_config.py`. | entry | records | |---|---| | `0x10b9d584`, `0x4abcfc43` | **16** — `ArmsStatus`, `Map`, `ArmsItem`, `RangeFinder`, `Marker`, `Manuva`, `Number`, `HudResource`, `NamePlate`, `ActiveArm`, `Information`, `Wing`, `ArmsItemFile`, `Radar`, `Speed`, `Sight` | | `0x927b29f8`, `0xccb12a6b` | **13** — `ObjectiveMarker_{Acropolis,SubObjective,Guard,WayPoint,Tanker,Target}`, `TutorialMarker_{…}`, `Enumerate_ObjectiveMarkers`, `Parameters` | | `0x59ecbedd` | `Face` — 52 positional `pjf001_*.t32` portrait sprites | | `0x87fd28c0` | `ResourceTable` — 58 positional entries | Between them these name **419** distinct asset paths. That is the whole flight HUD: the arms panel (`ArmsStatus` 16, `ActiveArm` 13, `ArmsItemFile` 59), the range finder (10), the target/lock markers and their HP-gauge strips (`Marker` 27), the manoeuvre gauge (`Manuva` 15), the radar (29), the reticle (`Sight` 35), the wingman panel (`Wing` 23), nameplates (60), speed (9), and the digit strips (`Number`, `%d`-templated: `pghud_speed_num%d.t32`, `pgtimer_num%d.t32`, `pglockon_%d.t32`). 🔑 The values carry **subdirectory prefixes** the corpus had not seen — `ArmsSt\`, `ActvArm\`, `RangeF\`, `Marker\`, `Manuva\`, `Map\`, `Speed\`, `Radar\`, `Sight\`, `Wing\`, `Hitmark\`, `Lockon\`, `Info\`. ## 🧪 The whole in-game HUD is NOT name-hash addressed Taking the config's **own exact path strings** — no guessing left in the loop: > **419 distinct `.prt` / `.t32` / `.tbl` values; 0 resolve as a pak entry** > under 10 prefixes. The four config FILENAMES (`HudResource.tbl`, > `HudMarkerResource.tbl`, and their `_S26` overrides) resolve to nothing > either. The `.t32` sprites certainly exist — the E2D pak holds **574 T8aD** entries. So the 2D pak's contents are simply **not addressed by `name_hash` of the name the config uses**, and that closes the previous iteration's puzzle properly: the 28 "dangling" `.prt` names were never a missing-asset story, they are 28 of a set where **none** of the 419 resolves. ⚠️ This supersedes the framing in [mission-script-manifest](mission-script-manifest.md#-the-other-six-values-do-not-resolve--with-a-working-control): the right statement is not "these five/28 are absent" but "**the in-game asset namespace is not the archive namespace**". ## ✅ `ResourceTable` — a per-stage HUD config table 58 positional fields = **29 pairs**, alternating `HudResource.tbl` / `HudMarkerResource.tbl`. Exactly one pair differs — index **25**, which reads `HudResource_S26.tbl` / `HudMarkerResource_S26.tbl`. **Identical in all six language paks.** 🟡 The reading: the table is indexed by **stage number − 1**, so 29 entries cover S1…S29 (the numbering [that runs to S29 with S17 absent](stage-numbering-and-player-craft.md)), and index 25 is **S26 — the one stage with its own HUD configuration**. The arithmetic is exact and the `_S26` suffix names the same stage, but nothing here proves the indexing, so this is **a reading, not adopted**. ## ✅ The objective / tutorial MARKER records `hud-config.md` listed these as "in the artefact but unread". Opened now — and they are portable HUD data, 11 records of **12 named fields** each: ``` ObjectiveMarker_Target ColorNormal 0xFFFF0000 Emph1 0xFFFF0000 Emph2 0xFF800000 Normal pgmark_ob.t32 NormalSub pgmark_ob_s.t32 Emphasis pgmark_em_ob.prt EmphasisSub pgmark_em_ob_s.prt HPGauge 2 HPGaugeSub 0 BlinkCycle 0x800 RadarCursorType (blank) TutorialTarget No ``` * **Colour is ARGB**, three per marker: `ColorNormal`, `ColorEmphasis1`, `ColorEmphasis2`. Objectives are **red** `0xFFFF0000`, guard/waypoint **green** `0xFF20FF20`, Acropolis/tanker **cyan** `0xFF00FFFF`, sub-objective **yellow** `0xFFFFFF00`, and every `TutorialMarker_*` is **amber** `0xFFFFA010`. * Each marker carries a `Normal` sprite and an `Emphasis` part, optionally with `…Sub` companions; `HPGauge` is 0 / 1 / 2; `RadarCursorType` is `Circle` (Acropolis, tanker), `Rectangle` (guard) or blank; `BlinkCycle` is `0x800` on all eleven. * `TutorialTarget` is `Yes` on exactly the five `TutorialMarker_*` records and `No` on the six `ObjectiveMarker_*` — the two families are otherwise the same shape. **`Parameters` (4 fields) binds the roles**: ``` TargetMarker ObjectiveMarker_Target HelpMarker ObjectiveMarker_SubObjective TutoTargetMarker TutorialMarker_Target ReloadDispTime 0.1 ``` **`Enumerate_ObjectiveMarkers`** is the 11-name roster of the set — the same shape as the `Enumerate_Squadrons` record [unit-group-table](unit-group-table.md) uses. ⚠️ `pgmark_em_ob_s.prt` here is one of the 28 names [archive-naming](archive-naming.md) shows resolving nowhere — consistent with the namespace finding, not a missing asset. ## 🟡 Not settled * How the 2D pak's 574 T8aD and 130 RATC entries *are* addressed, if not by `name_hash` of the config path. That is now the question. * What `HudMarkerResource.tbl` is — presumably the 13-record marker entry, but the filename does not resolve, so the pairing is by content, not by hash. * ~~`Parameters` and `Enumerate_ObjectiveMarkers` unread.~~ **Opened above.** ## ✅ The executable's own `PG*` block — `sub_822215D0` (2026-08-27) Found by the base-solver ([[player-tuning-tables]]); reproduce from [`../data/name-block-bases.txt`](../data/name-block-bases.txt) (the `sub_822215D0` section) against `hud_config.py`'s record dump. ✅ **The disc side above is confirmed independently.** Counting `PG*`-prefixed field names straight off the paks gives `Sight` 35, `Radar` 29, `Marker` 27, `Wing` 23, `Manuva` 15 — **the same numbers this document already states**, and `HudResource` 23 `PG*` + `HUD_RES_FONT` = its documented 24. A re-derivation that lands on the same counts is the control for what follows. 🔑 **What this document did not say: the executable carries its own roster.** `sub_822215D0` reads a **205-name** block at base `0x820A0000` — **205/205 are `PG*`-prefixed, zero partials** — led by `PGHUD` 77, `PGTARGET` 31, `PGGAUGE` 25, `PGMANUVA` 16, `PGMARK` 12, `PGWARNING` 10, `PGMARKTGT` 9. | | | |---|---:| | distinct `PG*` names **on the disc** (across all 16 records) | **228** | | the code block | **205** | | in both | **200** | | code-only | **5** | | disc-only | **28** | `200 + 5 = 205` and `200 + 28 = 228` — the arithmetic closes both ways. ⚠️ **Four of the five "code-only" names are printf families whose stem is a disc field**: `PGHUD_HIT_NUM_EFF%d`, `PGHUD_HIT_NUM_RED%d`, `PGREMAIN_NUM%d`, `PGTIMER_NUM%d` — and `PGHUD_HIT_NUM_EFF`, `PGHUD_HIT_NUM_RED`, `PGREMAIN_NUM`, `PGTIMER_NUM` are all four sitting in the disc-only 28. **The code builds indexed instance names from a base name the table declares.** Pair them off and the real residual is **one** code-only name — `PGMANUVA_EFF0` — and **24** disc-only ones (`PGHUD_LOCATOR`, `PGHUD_CAMERA`, `PGHUD_PITCH_*`, `PGHUD_YAW*`, `PGLOCKON`, …), i.e. elements the table names that this particular function never mentions. 🟡 What the block is *for* is not settled: whether it is a lookup table, a registration order, or a paint list. The function was not read.