re: Stage\script.tbl's 11 non-MISSION fields, and the mission dialogue table
structures/mission-script-ssb.md owns this manifest and names its 40 fields but never read the 11 that are not MISSION<n> = StageNN.ssb. They are DIALOG_MESSAGE, DIALOG_LOCAL_STRING, FONT (+size), TEXT_POS, TEXT_LINES and the five pgmsg_*.prt. Two sibling records were also unread: GP_TEST (PATH = dat\GP_TEST\, a debug archive not on the disc) and TEXTS (a second text style). Probed 7 values x 33 prefixes x 41 archives. One resolves: message\MissionDialogMessage.tbl, in all six GP_MAIN_GAME_* paks -- 200 records, 25280 bytes, every name S<NN>_P<n>_<KIND> with five kinds 40 each (HINT_PAUSE, HINT, OBJECTIVE, GRAPH, LOSE), fields positional and tagged 0..3, each value a message key. An index from (stage, phase, kind) to the localised strings, on the same S<NN>_P<n> keying the ISL corpus already uses. Control: the 40 stage-phases span stages 1-16 and 24-29 -- a subset of the 28 shipped, and the six with no hints are exactly 18-23, the tutorials. A fifth independent route to the story/tutorial split, and it gives the phase count per stage. The other six do not resolve, with the control in the same sweep: MissionDialog_local_string.tbl and all five pgmsg_*.prt are not a pak entry under any of the 33 prefixes, while message\MissionDialogMessage.tbl and Stage\script.tbl both resolve in 6 archives. name_hash is CASE-INSENSITIVE (message\ == Message\); tag_hash is not. New structure doc, artefact and regenerator; the other five artefacts regenerate byte-identical.
This commit is contained in:
@@ -827,6 +827,41 @@ 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) `Stage\script.tbl`'s 11 NON-`MISSION` FIELDS, READ AT LAST —
|
||||
and one of them lands on the mission DIALOGUE table.**
|
||||
[structures/mission-script-manifest](structures/mission-script-manifest.md),
|
||||
artefact `data/script-manifest.txt`, regenerator
|
||||
`tools/re-capture/script_manifest.py`.
|
||||
`structures/mission-script-ssb.md` owns this manifest and names its 40 fields
|
||||
but never read the 11 that are not `MISSION<n> = StageNN.ssb`. They are
|
||||
`DIALOG_MESSAGE = MissionDialogMessage.tbl`, `DIALOG_LOCAL_STRING =
|
||||
MissionDialog_local_string.tbl`, `FONT = dat\fonts.pak+HGRGE00.TTF`,
|
||||
`FONT_SIZE 15`, `TEXT_POS 128,128,16`, `TEXT_LINES 30`, and the five
|
||||
`pgmsg_{start,end,update,failed,restart}.prt`. Two sibling records were also
|
||||
unread: **`GP_TEST` (`PATH = dat\GP_TEST\`, a debug archive NOT on the disc)**
|
||||
and `TEXTS` (a second text style, 33/3/`296,565,39`).
|
||||
🔑 Probed 7 values x 33 prefixes x 41 archives. **One resolves:
|
||||
`message\MissionDialogMessage.tbl`**, in all six `GP_MAIN_GAME_*` paks —
|
||||
**200 records, 25 280 bytes**, every name `S<NN>_P<n>_<KIND>` with five kinds
|
||||
40 each (`HINT_PAUSE`, `HINT`, `OBJECTIVE`, `GRAPH`, `LOSE`), fields
|
||||
**positional, tagged 0..3**, each value a message key
|
||||
(`S10_P1_HINT_PAUSE` -> `S10_P1_Hint_Pause_00.._03`). An index from
|
||||
(stage, phase, kind) to the localised strings, on the same `S<NN>_P<n>` keying
|
||||
the ISL corpus already uses.
|
||||
🧪 **Control**: the 40 stage-phases span stages **1-16 and 24-29** — a subset
|
||||
of the 28 shipped, and the six with NO hints are exactly **18-23, the
|
||||
tutorials**. A fifth independent route to the story/tutorial split, and it
|
||||
hands over the **phase count per stage** (1 to 3; S02/S03/S06/S09 have 3,
|
||||
S10/S13 and all of S24-S29 have 1).
|
||||
🟡 **The other six do not resolve**, with the control in the same sweep:
|
||||
`MissionDialog_local_string.tbl` and all five `pgmsg_*.prt` are not a pak entry
|
||||
under any of the 33 prefixes, while `message\MissionDialogMessage.tbl` and
|
||||
`Stage\script.tbl` both resolve in 6 archives. Same wall
|
||||
`mission-phase-advance.md` hit for the manifest's KEYS; this closes the VALUES.
|
||||
⚠️ **`name_hash` is CASE-INSENSITIVE** (`message\` == `Message\`); `tag_hash`
|
||||
is not. Already noted in `sound-pak-contents.md`; repeated because it doubles
|
||||
the apparent hit count of a prefix sweep.
|
||||
|
||||
* ✅ **(2026-08-27) THE STAGE NUMBERING IS CONSISTENT EVERYWHERE — and the
|
||||
manifest still declares the cut S17.** Also a **correction to my own claim**
|
||||
in the entry below.
|
||||
|
||||
@@ -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/mission-script-manifest.md`](structures/mission-script-manifest.md) | `Stage\script.tbl`'s 11 non-`MISSION` fields, and the mission dialogue table they name | ✅ CONFIRMED — 1 of 7 values resolves (`message\MissionDialogMessage.tbl`, 200 records), controls in the same sweep |
|
||||
| [`structures/stage-numbering-and-player-craft.md`](structures/stage-numbering-and-player-craft.md) | The disc's stage numbering (S01–S16, S18–S29) and the player's craft per stage | ✅✅ CONFIRMED — two independent files close on 6 + 15 + 1 + 6 = 28 |
|
||||
| [`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 |
|
||||
|
||||
49
docs/re/data/script-manifest.txt
Normal file
49
docs/re/data/script-manifest.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
# Stage\script.tbl -- the mission-script manifest
|
||||
# Regenerate: python3 tools/re-capture/script_manifest.py
|
||||
# See docs/re/structures/mission-script-manifest.md
|
||||
|
||||
## the three records
|
||||
SCRIPTS 40 fields
|
||||
GP_TEST 1 fields
|
||||
PATH 'dat\\GP_TEST\\'
|
||||
TEXTS 3 fields
|
||||
FONT_SIZE '33'
|
||||
TEXT_LINES '3'
|
||||
TEXT_POS '296,565,39'
|
||||
|
||||
## SCRIPTS -- the 11 non-MISSION fields, read for the first time
|
||||
DIALOG_LOCAL_STRING 'MissionDialog_local_string.tbl'
|
||||
DIALOG_MESSAGE 'MissionDialogMessage.tbl'
|
||||
FONT 'dat\\fonts.pak+HGRGE00.TTF'
|
||||
FONT_SIZE '15'
|
||||
MISSION_END_PRT 'pgmsg_end.prt'
|
||||
MISSION_FAILED_PRT 'pgmsg_failed.prt'
|
||||
MISSION_RESTART_PRT 'pgmsg_restart.prt'
|
||||
MISSION_START_PRT 'pgmsg_start.prt'
|
||||
MISSION_UPDATE_PRT 'pgmsg_update.prt'
|
||||
TEXT_LINES '30'
|
||||
TEXT_POS '128,128,16'
|
||||
|
||||
## do those values resolve as pak entries? (33 prefixes x 41 archives)
|
||||
MissionDialogMessage.tbl FOUND as message\MissionDialogMessage.tbl in 6 archives
|
||||
MissionDialog_local_string.tbl not found
|
||||
pgmsg_start.prt not found
|
||||
pgmsg_end.prt not found
|
||||
pgmsg_update.prt not found
|
||||
pgmsg_failed.prt not found
|
||||
pgmsg_restart.prt not found
|
||||
CONTROL Stage\script.tbl resolves in 6 archives
|
||||
NOTE name_hash is CASE-INSENSITIVE (message\ == Message\); tag_hash is not.
|
||||
|
||||
## message\MissionDialogMessage.tbl -- 200 records, 25280 bytes
|
||||
name families S<NN>_P<n>_<KIND>: {'HINT_PAUSE': 40, 'HINT': 40, 'LOSE': 40, 'GRAPH': 40, 'OBJECTIVE': 40}
|
||||
field counts: {4: 120, 3: 40, 1: 40}
|
||||
stages present (22): [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 25, 26, 27, 28, 29]
|
||||
phases per stage: {1: 2, 2: 3, 3: 3, 4: 2, 5: 2, 6: 3, 7: 2, 8: 2, 9: 3, 10: 1, 11: 2, 12: 2, 13: 1, 14: 2, 15: 2, 16: 2, 24: 1, 25: 1, 26: 1, 27: 1, 28: 1, 29: 1}
|
||||
CONTROL subset of the 28 shipped stages: True ; shipped with NO hints: [18, 19, 20, 21, 22, 23]
|
||||
|
||||
sample S10_P1_HINT_PAUSE:
|
||||
tag 0 <none> 'S10_P1_Hint_Pause_00'
|
||||
tag 1 <none> 'S10_P1_Hint_Pause_01'
|
||||
tag 2 <none> 'S10_P1_Hint_Pause_02'
|
||||
tag 3 <none> 'S10_P1_Hint_Pause_03'
|
||||
77
docs/re/structures/mission-script-manifest.md
Normal file
77
docs/re/structures/mission-script-manifest.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# ✅ `Stage\script.tbl` — the 11 non-`MISSION` fields, and where they point
|
||||
|
||||
[mission-script-ssb](mission-script-ssb.md) owns this manifest and names its
|
||||
40 fields; **it never read the 11 that are not `MISSION<n> = StageNN.ssb`.**
|
||||
This does, and follows each value into the archives. Artefact
|
||||
`../data/script-manifest.txt`, regenerator `tools/re-capture/script_manifest.py`.
|
||||
|
||||
```
|
||||
DIALOG_MESSAGE MissionDialogMessage.tbl
|
||||
DIALOG_LOCAL_STRING MissionDialog_local_string.tbl
|
||||
FONT dat\fonts.pak+HGRGE00.TTF FONT_SIZE 15
|
||||
TEXT_POS 128,128,16 TEXT_LINES 30
|
||||
MISSION_START_PRT pgmsg_start.prt MISSION_END_PRT pgmsg_end.prt
|
||||
MISSION_UPDATE_PRT pgmsg_update.prt MISSION_FAILED_PRT pgmsg_failed.prt
|
||||
MISSION_RESTART_PRT pgmsg_restart.prt
|
||||
```
|
||||
|
||||
Two sibling records in the same file, also unread until now:
|
||||
`GP_TEST` (`PATH = dat\GP_TEST\` — a debug archive that is **not on the disc**)
|
||||
and `TEXTS` (`FONT_SIZE 33`, `TEXT_LINES 3`, `TEXT_POS 296,565,39` — a second,
|
||||
larger text style beside `SCRIPTS`'s own 15/30/`128,128,16`).
|
||||
|
||||
## 🔑 `message\MissionDialogMessage.tbl` — found, and it is keyed by stage AND phase
|
||||
|
||||
Probed 7 values × 33 prefixes × 41 archives. **One resolves**:
|
||||
`message\MissionDialogMessage.tbl`, in all six `GP_MAIN_GAME_*` paks.
|
||||
**200 records, 25 280 bytes**, every name of the form
|
||||
`S<NN>_P<n>_<KIND>` with five kinds, 40 each:
|
||||
|
||||
| kind | fields | reading |
|
||||
|---|---:|---|
|
||||
| `HINT_PAUSE` | 4 | the pause menu's hint lines |
|
||||
| `HINT` | 4 | 🟡 in-mission hint |
|
||||
| `OBJECTIVE` | 4 | 🟡 the objective text |
|
||||
| `GRAPH` | 3 | 🟡 |
|
||||
| `LOSE` | 1 | 🟡 the failure line |
|
||||
|
||||
The fields are **positional, tagged 0…3**, and each value is a message key:
|
||||
`S10_P1_HINT_PAUSE` → `S10_P1_Hint_Pause_00 … _03`. So this is an index from
|
||||
(stage, phase, kind) to the localised strings — the same `S<NN>_P<n>` keying the
|
||||
ISL corpus uses for [mission phases](isl-phase-guards.md).
|
||||
|
||||
🧪 **Control — the 22 stages are exactly the STORY stages.** The 40 stage-phases
|
||||
span stages **1–16 and 24–29**; that is a subset of the 28 shipped, and the six
|
||||
with no hints at all are **18–23**, the tutorials
|
||||
([stage-numbering-and-player-craft](stage-numbering-and-player-craft.md)). A
|
||||
fifth independent route to the same story/tutorial split, and it also gives the
|
||||
**phase count per stage** — 1 to 3, e.g. S02 and S03 have 3, S10 and S13 have 1.
|
||||
|
||||
## 🟡 The other six values do not resolve — with a working control
|
||||
|
||||
`MissionDialog_local_string.tbl` and all five `pgmsg_*.prt` are **not a pak
|
||||
entry** under any of the 33 prefixes tried (`message\`, `Stage\`, `2d\`, `ui\`,
|
||||
`prt\`, six language dirs, and the language dirs under `Stage\` and `message\`).
|
||||
The control is in the same loop and in the same sweep:
|
||||
`message\MissionDialogMessage.tbl` **does** resolve, and so does
|
||||
`Stage\script.tbl` itself, both in 6 archives.
|
||||
|
||||
This is the same wall [mission-phase-advance](../mission-phase-advance.md) hit
|
||||
for the manifest's KEYS — but that sweep probed `MISSION1..33` and
|
||||
`MISSION_*_PRT` as names. This one probes the **values**, which had never been
|
||||
read, and closes them the same way.
|
||||
|
||||
## ⚠️ `name_hash` is CASE-INSENSITIVE
|
||||
|
||||
`name_hash("message\\a.tbl") == name_hash("Message\\A.TBL")`. `tag_hash` is
|
||||
**not** (`tag_hash("Abc") != tag_hash("abc")`). Already noted for archive lookup
|
||||
in [sound-pak-contents](sound-pak-contents.md); worth repeating because it
|
||||
doubles the apparent hit count of any prefix sweep.
|
||||
|
||||
## 🟡 Not settled
|
||||
|
||||
* Where the five `pgmsg_*.prt` screen parts and
|
||||
`MissionDialog_local_string.tbl` actually live.
|
||||
* What `GRAPH` selects, and why `LOSE` carries exactly one entry.
|
||||
* `dat\GP_TEST\` is named by the manifest and is not on the disc — a debug path
|
||||
left in, not a missing asset. Not chased.
|
||||
Reference in New Issue
Block a user