re: where .prt screen parts live; the five mission banners are a real exception
Read first, as the rule now requires: ui-prm-primitives.md, ui-rat-layout.md, ui-screen-runtime.md -- they own the .prt/RATC/T8aD stack but describe element names inside bundles, not where parts live. A .prt IS a pak entry, under a LANGUAGE directory. Of 376 distinct .prt names referenced on the disc, 241 resolve as archive entries -- 220 under eng\ and jpn\, 38 under each of the other four. prbase.prt resolves under all six; palogo1.prt under two. All five pgmsg_*.prt resolve under nothing, across 15 prefixes that include every language dir, so this is not the missing-prefix mistake again. A lead, refuted by its own control: four of the five have a same-stem _sub.rat sub-bundle inside every per-language 2D pak, and pgmsg_update has none -- but only 4 of 376 .prt stems have a _sub.rat, and prbase.prt, which does ship as an entry, has none. Not the container convention, not adopted. An intermediate pass nearly reported 'the five appear only in the manifest'; that was wrong because the token census was truncated by a slice and the RATC hits were pgmsg_start_sub.rat, a longer token. New artefact and regenerator; the other six regenerate byte-identical.
This commit is contained in:
@@ -827,6 +827,35 @@ 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) WHERE `.prt` SCREEN PARTS LIVE — and the five mission
|
||||
banners are a real exception.**
|
||||
[structures/mission-script-manifest](structures/mission-script-manifest.md),
|
||||
artefact `data/prt-parts.txt`, regenerator `tools/re-capture/prt_parts.py`.
|
||||
Read first, as the rule now requires: `ui-prm-primitives.md`,
|
||||
`ui-rat-layout.md`, `ui-screen-runtime.md` — they own the `.prt`/RATC/T8aD
|
||||
stack but describe element names INSIDE bundles, not where parts live.
|
||||
✅ **A `.prt` IS a pak entry, under a LANGUAGE directory.** Of **376** distinct
|
||||
`.prt` names referenced on the disc, **241 resolve** as archive entries — 220
|
||||
under `eng\` and `jpn\`, 38 under each of the other four. `prbase.prt`
|
||||
resolves under all six; `palogo1.prt` under two.
|
||||
❌ **All five `pgmsg_*.prt` resolve under NOTHING**, across 15 prefixes that
|
||||
include every language dir — so this is not the missing-prefix mistake again.
|
||||
🟡 **A lead, refuted by its own control.** Four of the five have a same-stem
|
||||
**`_sub.rat` sub-bundle** inside every per-language 2D pak
|
||||
(`pgmsg_{start,end,failed,restart}_sub.rat`, 6 archives each); **`pgmsg_update`
|
||||
has none.** Tempting as "the parts live as RATC sub-bundles" — but **only 4 of
|
||||
376 `.prt` stems have a `_sub.rat`** (the other 7 belong to `GP_BUNK`,
|
||||
`GP_SYSTEM`, `GP_MISSION_LOG`), and `prbase.prt`, which does ship as an entry,
|
||||
has none. Not the container convention. **Not adopted.**
|
||||
🟡 Still open: where the five actually are. What is settled is that they are
|
||||
not pak entries while 241 siblings are, and that `pgmsg_update` is the odd one
|
||||
out even among the five.
|
||||
⚠️ Method note: an intermediate pass of this iteration nearly reported "the
|
||||
five appear only in the manifest" — wrong, because the token census was
|
||||
truncated by a `[:20]` slice and the RATC hits were `pgmsg_start_sub.rat`, a
|
||||
LONGER token. **A truncated listing is not a distribution**, and a prefix match
|
||||
is not an exact match.
|
||||
|
||||
* ❌ **(2026-08-27) CORRECTION — the mission dialogue table was ALREADY IN THE
|
||||
CORPUS, and my headline negative was a FALSE NEGATIVE.**
|
||||
[structures/mission-script-manifest](structures/mission-script-manifest.md),
|
||||
|
||||
39
docs/re/data/prt-parts.txt
Normal file
39
docs/re/data/prt-parts.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
# Where `.prt` screen parts live
|
||||
# Regenerate: python3 tools/re-capture/prt_parts.py
|
||||
# See docs/re/structures/mission-script-manifest.md
|
||||
|
||||
## `.prt` IS a pak entry name -- under a LANGUAGE directory
|
||||
distinct .prt names referenced anywhere : 376
|
||||
resolving as a pak entry : 241
|
||||
prefix 'eng\\' 220
|
||||
prefix 'jpn\\' 220
|
||||
prefix 'fra\\' 38
|
||||
prefix 'deu\\' 38
|
||||
prefix 'ita\\' 38
|
||||
prefix 'esp\\' 38
|
||||
prefix '' 21
|
||||
|
||||
## the five mission-banner parts
|
||||
pgmsg_start.prt resolves under: NOTHING
|
||||
pgmsg_end.prt resolves under: NOTHING
|
||||
pgmsg_update.prt resolves under: NOTHING
|
||||
pgmsg_failed.prt resolves under: NOTHING
|
||||
pgmsg_restart.prt resolves under: NOTHING
|
||||
prbase.prt resolves under: ['eng\\', 'jpn\\', 'fra\\', 'deu\\', 'ita\\', 'esp\\']
|
||||
palogo1.prt resolves under: ['eng\\', 'jpn\\']
|
||||
|
||||
## `<stem>_sub.rat` sub-bundles inside RATC
|
||||
distinct _sub.rat names: 11
|
||||
pgmsg_end_sub.rat in 6 archives ['GP_MAIN_GAME_D2D.pak', 'GP_MAIN_GAME_E2D.pak']
|
||||
pgmsg_failed_sub.rat in 6 archives ['GP_MAIN_GAME_D2D.pak', 'GP_MAIN_GAME_E2D.pak']
|
||||
pgmsg_restart_sub.rat in 6 archives ['GP_MAIN_GAME_D2D.pak', 'GP_MAIN_GAME_E2D.pak']
|
||||
pgmsg_start_sub.rat in 6 archives ['GP_MAIN_GAME_D2D.pak', 'GP_MAIN_GAME_E2D.pak']
|
||||
piface_sub.rat in 1 archives ['GP_MISSION_LOG.pak']
|
||||
pjeff03_sub.rat in 2 archives ['GP_BUNK.pak', 'GP_DEBRIEFING_PILOTLOG.pak']
|
||||
pjex_eff07_sub.rat in 4 archives ['GP_BUNK.pak', 'GP_DEBRIEFING_PILOTLOG.pak']
|
||||
pjex_eff08_sub.rat in 4 archives ['GP_BUNK.pak', 'GP_DEBRIEFING_PILOTLOG.pak']
|
||||
pqeff20_sub.rat in 1 archives ['GP_SYSTEM.pak']
|
||||
pqeff21_sub.rat in 1 archives ['GP_SYSTEM.pak']
|
||||
pqeff22_sub.rat in 1 archives ['GP_SYSTEM.pak']
|
||||
CONTROL .prt stems that have a _sub.rat: 4 / 376 -- so this is NOT the general
|
||||
container convention; `prbase` has a .prt entry and no _sub.rat.
|
||||
@@ -97,8 +97,42 @@ read, and closes them the same way.
|
||||
in [sound-pak-contents](sound-pak-contents.md); worth repeating because it
|
||||
doubles the apparent hit count of any prefix sweep.
|
||||
|
||||
## 🔎 Where `.prt` parts live — and why these five are the exception
|
||||
|
||||
Followed up the next iteration. Read first: `ui-prm-primitives.md`,
|
||||
`ui-rat-layout.md`, `ui-screen-runtime.md` — they own the `.prt`/RATC/T8aD UI
|
||||
stack and describe element names *inside* bundles, not where the parts live.
|
||||
Artefact `../data/prt-parts.txt`, regenerator `tools/re-capture/prt_parts.py`.
|
||||
|
||||
**A `.prt` IS a pak entry — under a LANGUAGE directory.** Of the **376** distinct
|
||||
`.prt` names referenced anywhere on the disc, **241 resolve** as an archive
|
||||
entry: 220 under `eng\` and `jpn\`, 38 under each of the other four. My earlier
|
||||
sweep had `eng\`…`esp\` in the list, so this is not the missing-prefix mistake
|
||||
again — the five simply are not there.
|
||||
|
||||
| name | resolves under |
|
||||
|---|---|
|
||||
| `prbase.prt` | all six language dirs |
|
||||
| `palogo1.prt` | `eng\`, `jpn\` |
|
||||
| **all five `pgmsg_*.prt`** | **nothing, under any of 15 prefixes** |
|
||||
|
||||
🟡 **A partial lead, and its own refutation.** Four of the five have a
|
||||
same-stem **`_sub.rat` sub-bundle** inside every per-language *2D* pak
|
||||
(`pgmsg_start_sub.rat`, `_end_`, `_failed_`, `_restart_` — 6 archives each);
|
||||
**`pgmsg_update` has none**. Tempting as "the parts live as RATC sub-bundles",
|
||||
but the control kills the generalisation: **only 4 of 376 `.prt` stems have a
|
||||
`_sub.rat` at all** (the other 7 belong to `GP_BUNK`, `GP_SYSTEM`,
|
||||
`GP_MISSION_LOG`), and `prbase.prt` — which *does* ship as an entry — has no
|
||||
`_sub.rat`. So `_sub.rat` is not the container convention; it is something these
|
||||
four happen to have.
|
||||
|
||||
**Still not settled**: where the five mission-banner parts actually are. What is
|
||||
now settled is that they are **not** pak entries while 241 of their siblings are,
|
||||
and that `pgmsg_update` is the odd one out even among them.
|
||||
|
||||
## 🟡 Not settled
|
||||
|
||||
* Where the five `pgmsg_*.prt` screen parts live.
|
||||
* Where the five `pgmsg_*.prt` screen parts live — see the section above for
|
||||
how far that got.
|
||||
* `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.
|
||||
|
||||
64
tools/re-capture/prt_parts.py
Normal file
64
tools/re-capture/prt_parts.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Where `.prt` screen parts live, and why the five mission banners do not.
|
||||
|
||||
Regenerates docs/re/data/prt-parts.txt.
|
||||
"""
|
||||
import sys, os, glob, re, collections
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
import unitgroup as U
|
||||
from unit_substructures import pak_entries
|
||||
|
||||
FIVE = ['pgmsg_start.prt', 'pgmsg_end.prt', 'pgmsg_update.prt',
|
||||
'pgmsg_failed.prt', 'pgmsg_restart.prt']
|
||||
PRE = ['', 'Stage\\', 'stage\\', 'message\\', 'language\\', '2d\\', 'ui\\', 'prt\\',
|
||||
'view\\'] + [l + '\\' for l in ('eng', 'jpn', 'fra', 'deu', 'ita', 'esp')]
|
||||
|
||||
def main():
|
||||
H = collections.defaultdict(set)
|
||||
names = set()
|
||||
rat = collections.defaultdict(set)
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
|
||||
base = os.path.basename(pk)
|
||||
for h, b in pak_entries(pk):
|
||||
H[h].add(base)
|
||||
for m in re.finditer(rb'[A-Za-z0-9_]{3,40}\.prt', b):
|
||||
names.add(m.group(0).decode())
|
||||
if b[:4] == b'RATC':
|
||||
for m in re.finditer(rb'[A-Za-z0-9_]{3,40}_sub\.rat', b):
|
||||
rat[m.group(0).decode()].add(base)
|
||||
|
||||
print("# Where `.prt` screen parts live")
|
||||
print("# Regenerate: python3 tools/re-capture/prt_parts.py")
|
||||
print("# See docs/re/structures/mission-script-manifest.md")
|
||||
|
||||
byp = collections.Counter()
|
||||
hit = set()
|
||||
for n in names:
|
||||
for p in PRE:
|
||||
if U.name_hash(p + n) in H:
|
||||
byp[p] += 1; hit.add(n)
|
||||
print("\n## `.prt` IS a pak entry name -- under a LANGUAGE directory")
|
||||
print(" distinct .prt names referenced anywhere : %d" % len(names))
|
||||
print(" resolving as a pak entry : %d" % len(hit))
|
||||
for p, c in byp.most_common():
|
||||
print(" prefix %-8s %3d" % (repr(p), c))
|
||||
|
||||
print("\n## the five mission-banner parts")
|
||||
for n in FIVE + ['prbase.prt', 'palogo1.prt']:
|
||||
ok = [p or '<bare>' for p in PRE if U.name_hash(p + n) in H]
|
||||
print(" %-20s resolves under: %s" % (n, ok if ok else 'NOTHING'))
|
||||
|
||||
print("\n## `<stem>_sub.rat` sub-bundles inside RATC")
|
||||
print(" distinct _sub.rat names: %d" % len(rat))
|
||||
for k in sorted(rat):
|
||||
print(" %-26s in %d archives %s" % (k, len(rat[k]), sorted(rat[k])[:2]))
|
||||
stems_prt = {n[:-4] for n in names}
|
||||
stems_rat = {k[:-8] for k in rat}
|
||||
print(" CONTROL .prt stems that have a _sub.rat: %d / %d -- so this is NOT the general"
|
||||
% (len(stems_prt & stems_rat), len(stems_prt)))
|
||||
print(" container convention; `prbase` has a .prt entry and no _sub.rat.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user