docs: the UI decode's own evidence images were unreachable -- 11 links repaired
The brief's rule is to commit reference data beside the finding so the port can be built without a disc. Nothing had ever checked that the docs' cited artifacts actually exist. doc_link_check.py walks every markdown file under docs/, resolves each relative link, and reports targets that are missing -- and separately targets that resolve to a ZERO-BYTE file, which looks fine in any listing. links resolving 1038 -> 1049 missing targets 16 -> 5 empty targets 0 -> 0 +11 resolving and -11 missing against 11 edits: the counts pair, which is the confirmation the pass did what it claimed and touched nothing else. Two of the sixteen were the evidence for the UI layout decode itself. structures/ui-rat-layout.md is what the port is built on, and its two figures -- backing "the tutorial PAUSE menu rebuilds pixel-accurately from its sprites" and "the same method reproduces the main menu" -- were written as captures/ui-layout/... from a file in structures/, one directory too shallow. The headline evidence for the decode could not be opened from its own document. Eleven links had the wrong relative depth with the target present. Each was rewritten only where exactly one candidate path resolved, so nothing was guessed; the first pass left three alone because equivalent spellings (captures/../captures/x) failed to collapse, and a second pass normalised them. Five remain genuinely absent and are left rather than invented: two point at MEMORY.md outside the repo, one at a header in the separate xenia-canary-native tree, and two name documents that were never written (weapon-datasheet-runtime.md, canary-build-verified-env-confound.md). None is port-relevant. A missing document is a different problem from a bad path and is not something a link fix should paper over.
This commit is contained in:
@@ -82,7 +82,7 @@ names had no text to resolve *to*, and the 100 % figure was unreachable.
|
||||
|
||||
* **Which recording plays.** The caption is the *text*; the voice bank binding
|
||||
is a separate and still-unresolved question — see
|
||||
[voice-bank-leading-region.md](voice-bank-leading-region.md) and the
|
||||
[voice-bank-leading-region.md](../voice-bank-leading-region.md) and the
|
||||
known case of a generic line playing against a specific subtitle.
|
||||
* **Which page a `MSG_DEMO_*` id belongs to.** The `DEMO` family is not called
|
||||
from the stage scripts at all — 78 of its ids are multi-page, so something
|
||||
|
||||
@@ -270,7 +270,7 @@ result of the two.
|
||||
## ✅ 2026-08-23 (third pass) — the counter is at `0xbdb59668` again, and the refutation above is *refined*, not reversed
|
||||
|
||||
Run 4, with the hunt automated end to end
|
||||
([`ob_hunt.py`](../../tools/re-capture/ob_hunt.py) + the HUD reader), produced
|
||||
([`ob_hunt.py`](../../../tools/re-capture/ob_hunt.py) + the HUD reader), produced
|
||||
**exactly one** surviving address:
|
||||
|
||||
```
|
||||
@@ -322,7 +322,7 @@ With the per-entity searches refuted at both word and bit level
|
||||
counter. It sits at `0xbdb59668`, inside the entity-heap window, so the answer is
|
||||
readable directly: sample ±0x200 around it across one transition and keep the
|
||||
words that move **with** it
|
||||
([`ob_neighbourhood.py`](../../tools/re-capture/ob_neighbourhood.py),
|
||||
([`ob_neighbourhood.py`](../../../tools/re-capture/ob_neighbourhood.py),
|
||||
[`captures/ob-counter-neighbourhood-stage02.json`](../captures/ob-counter-neighbourhood-stage02.json)).
|
||||
|
||||
Control first: over an 8-second interval while the counter sat still, **0 of the
|
||||
|
||||
@@ -40,7 +40,7 @@ resolves all twenty-four:
|
||||
| `stage\StageParameter_Test.tbl` | 1 — the developer stage |
|
||||
|
||||
**That is exactly the 24, and it explains 24 against the 29 stage records**
|
||||
([`challenge-mission-gate.md`](challenge-mission-gate.md) counts 29:
|
||||
([`challenge-mission-gate.md`](../challenge-mission-gate.md) counts 29:
|
||||
16 story + 6 tutorial + 6 challenge + `Test`): the six tutorials do not get one
|
||||
table each, they **share a single `_Tutorial` table**, and `_Test` accounts for
|
||||
the last. 16 + 6 + 1 + 1 = 24.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
**reassembled from the disc**: the tutorial PAUSE menu rebuilds pixel-accurately from its
|
||||
sprites placed at the coordinates in their `.rat` records — no fitting, no manual nudging.
|
||||
|
||||

|
||||

|
||||
|
||||
*Left: the running game (Canary screenshot). Right: rebuilt from `GP_PAUSE_MENU.pak` alone.
|
||||
The remaining differences are the animated frame/glow sprites (`*eff*`) that were not
|
||||
@@ -157,7 +157,7 @@ game, twice, in that order — the records were never fitted to the picture.
|
||||
The same method run against `GP_TITLE.pak` reproduces the **main menu**, which is a
|
||||
different screen with a different item count and a different pitch:
|
||||
|
||||

|
||||

|
||||
|
||||
`ptbtn01..05.rat` give X = 542 for all five and Y = 162 / 242 / 322 / 402 / 482 — an
|
||||
**80 px** pitch, where the pause menu used 70. Measured against the screenshot, the sprite
|
||||
|
||||
@@ -507,7 +507,7 @@ run scan that builds the candidate list — which does not emit a start for thes
|
||||
resources' real vertex buffers. That is where the remaining 51 live.
|
||||
|
||||
The ignored test
|
||||
[`mesh_consistency_disc.rs`](../../crates/sylpheed-formats/tests/mesh_consistency_disc.rs)
|
||||
[`mesh_consistency_disc.rs`](../../../crates/sylpheed-formats/tests/mesh_consistency_disc.rs)
|
||||
still asserts the target state and now records 63 rather than 125; the remaining
|
||||
cases are where the neighbourhood is itself wrong or absent.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user