From d9ffc223bc0ac479b1efe7a398588866f552e0bc Mon Sep 17 00:00:00 2001 From: "Claude (auto-RE)" Date: Tue, 11 Aug 2026 22:44:19 +0000 Subject: [PATCH] re: RATC "one level deep" is not a limitation -- measured, plus a second dangling asset INDEX read as if the parser stopped at one level. Measurement says there is nothing deeper: 2859 top-level bundles hold 18002 children at depth 1 and ZERO at depth 2, with no blob failing to parse. The children that are themselves RATC -- the .rat layout records -- are leaves. They carry no child list and reference their siblings BY NAME (the sprite they place, and via "opt " their focused variant): 3311 such leaves, every one embedding sibling names, and 10144 of 10148 references resolve within the same bundle. That is the same by-name convention used one level up (a screen config naming .prt components) and one level up again (the movie table naming .pak+). The 4 unresolved references are a disc defect, not a parse gap: pmbase.rat in GP_STAGE_CLEAR.pak's four language builds places pmbase.t32, and that sprite exists nowhere -- not a pak member, not a child of those bundles. Second such dangling asset after SUBTITLE_S12B.tbl, so a reimplementation should skip a missing sprite rather than call it a decode failure. Co-Authored-By: Claude Opus 5 (1M context) --- docs/re/INDEX.md | 2 +- docs/re/structures/ui-rat-layout.md | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/re/INDEX.md b/docs/re/INDEX.md index a25bf8b..e20ad44 100644 --- a/docs/re/INDEX.md +++ b/docs/re/INDEX.md @@ -15,7 +15,7 @@ Promote to a prose `structures/…md` file when a format needs behavioural notes | IDXD object/table | βœ… | `sylpheed-formats/src/idxd.rs` | self-describing; ship/weapon stats verified vs known values | | XPR2 texture + cubemap | 🟑/βœ… | `sylpheed-formats/src/texture.rs` + [colour check](xpr2-colour-check.md) | de-tile + A8R8G8B8 and DXT1. **Channel order βœ… confirmed against the running game**: the Delta Saber's decoded atlas is orange-dominant (median saturated hue 23.3Β°, *zero* cool pixels) and the game renders the same hull at 9.3Β° β€” a red↔blue swap would sit at β‰ˆ200Β°. Exact fidelity (gamma/sRGB curve, premultiplied alpha, per-channel scale) is 🟑 untested, since a hue comparison cannot see it; cubemap face ordering ❔ | | T8aD 2D texture | βœ… | `sylpheed-formats/src/t8ad.rs` | **100 % of the disc decodes** (19 216/19 216, measured). The "~15 % deferred variants" were a wrong model, not a variant: a surface is a list of **arbitrary sub-rectangles**, each with a 16-byte header of `dst X, dst Y, width, height`, not a 256Γ—256 grid β€” `0x1c` is the **rectangle count**. Uncovered area stays transparent. **Colours βœ… CONFIRMED** ([k8888](structures/texture-color-k8888.md)) | -| RATC bundle | 🟑 | `sylpheed-formats/src/ratc.rs` | child listing confirmed; one level deep | +| RATC bundle | βœ… | `sylpheed-formats/src/ratc.rs` | child listing confirmed. **"One level deep" is not a limitation β€” there is nothing deeper**: 2 859 bundles hold 18 002 children at depth 1 and **0 at depth 2**, with no parse failures. Nested RATC blobs are **leaf records that reference siblings by name** (`opt `, the sprite name): 3 311 leaves, all embedding sibling names, **10 144 of 10 148 references resolve**. The 4 that do not are one dangling asset β€” `pmbase.rat` β†’ `pmbase.t32` in `GP_STAGE_CLEAR.pak`'s four language builds, and `pmbase.t32` is **on the disc nowhere** | | LSTA sprite list | 🟑 | `sylpheed-formats/src/lsta.rs` | inline T8aD frames | | IXUD subtitle | 🟑/βœ… | `sylpheed-formats/src/ixud.rs` + [movie link](movie-subtitle-link.md) | timed cues. **The movie↔subtitle↔voice link is solved β€” statically**, from the movie config record in `tables.pak` (schema `0x067025b9`), not from the running game as this row previously assumed: [101 movies mapped](captures/movie-subtitle-voice-map.csv), 94 with subtitles, 83 with voice, 21 with a telop overlay. 93 of 94 subtitle refs resolve in the language paks; **`SUBTITLE_S12B.tbl` is missing from all six languages** β€” a dangling reference on the disc. Naming is `SUBTITLE_.tbl` / `VOICE_` with six documented exceptions. The record's ~104 **script ids** are ❔ β€” positional pairing drifts by three because the IDXD pool dedupes repeated values | | Fonts (ttf/otf/ttc) | βœ… | `sylpheed-formats/src/font.rs` | standard OpenType, parsed via ttf-parser | diff --git a/docs/re/structures/ui-rat-layout.md b/docs/re/structures/ui-rat-layout.md index 08a01c9..785ee49 100644 --- a/docs/re/structures/ui-rat-layout.md +++ b/docs/re/structures/ui-rat-layout.md @@ -314,3 +314,27 @@ buttons are static (every keyframe identical), which is precisely why they make clean ruler. Validating the animation rule needs an element captured mid-slide. Evidence: [`captures/arsenal-layout-validation.png`](../captures/arsenal-layout-validation.png). + +## RATC nesting, measured + +`INDEX` carried the bundle format as 🟑 "one level deep", which reads like a +parser limitation. It is not β€” **there is nothing deeper on the disc**: + +- **2 859** top-level RATC bundles hold **18 002** children at depth 1 and + **0** at depth 2, with **no** blob failing to parse. +- The children that are themselves RATC (the `.rat` layout records) are **leaf + records**: they carry no child list and instead **reference their siblings by + name** β€” the sprite they place and, via `opt `, their focused variant. + **3 311** such leaves, every one embedding sibling names, and **10 144 of + 10 148** references resolve to a sibling of the same bundle. + +That is the same by-name convention used one level up, where a screen's config +names `.prt` components, and one level up again, where the movie table names +`.pak+`. + +**The 4 unresolved references are a real defect on the disc**, not a parse gap: +`pmbase.rat` in `GP_STAGE_CLEAR.pak` (four language builds) places `pmbase.t32`, +and that sprite exists **nowhere** β€” not as a pak member, not as a child of those +bundles. It is the second such dangling asset found, after +[`SUBTITLE_S12B.tbl`](../movie-subtitle-link.md); a reimplementation should skip +a missing sprite rather than treat it as a decode failure.