re: which challenge stage is which leaderboard mode - CLOSED from the record's own fields

challenge-mission-gate.md section 5.3 left a marked 🟡 on the exact pairing and named
the right route: read the record's binary index section rather than the string pool.
Running that with the corpus's own reader settles all six missions at once.

  TimeAttack    MISSION_ID 24  REQUIREMENT 16  RECORD_TYPE Time
  ScoreAttack   MISSION_ID 25  REQUIREMENT 24  RECORD_TYPE Points
  Extra01       MISSION_ID 26  REQUIREMENT 25  RECORD_TYPE Points
  Extra02       MISSION_ID 27  REQUIREMENT 26  RECORD_TYPE Time
  Extra03       MISSION_ID 28  REQUIREMENT 27  RECORD_TYPE Time
  Extra04       MISSION_ID 29  REQUIREMENT 28  RECORD_TYPE Points

Control: the table appears in 6 pak entries, all in tables.pak, and all six are the
same table byte for byte - one per language, i.e. one user under the per-pak copy
rule. Zero variants.

Three things fall out, none of them assumed. MISSION_ID is the stage number: the six
IDs are 24-29 in slot order, exactly the six challenge stages S24-S29, bijectively -
so the "four Extra0n modes against five _EXn stages" worry dissolves, because _EXn is
a unit-variant suffix that indexes nothing here. REQUIREMENT is a strict chain, 16,
24, 25, 26, 27, 28, each mission requiring the previous one's stage with TimeAttack
anchored on stage 16, the final story mission; 5.3 inferred a chain from the shape of
the string pool, and it is now exact and branchless. RECORD_TYPE is the leaderboard
metric and it is per-stage, not per-name: 3 Time (S24, S27, S28) and 3 Points (S25,
S26, S29), so the tempting reading that the Extra0n family shares one metric is
wrong - Extra01 and Extra04 are Points while Extra02 and Extra03 are Time.

Withdrawn from 5.3: the string-pool reading listed the numeric tokens as 16, 25, 26,
27, 29 with 24 and 28 deduped away. The real REQUIREMENT set is 16, 24, 25, 26, 27,
28 - 29 is a MISSION_ID, never a requirement. A value pulled from a deduped pool by
adjacency got one member wrong; the indexed read has no such failure mode.

Left as an association rather than a proof: RECORD_TYPE takes exactly the two values
Points and Time, and result-screens names two ranking screens POINT_RANKING and
CLEAR_TIME_RANKING, but no code path has been shown selecting one screen from that
field.

All seventeen artefacts byte-identical.
This commit is contained in:
Sylpheed RE agent
2026-08-28 12:15:48 +00:00
parent 302cc9dda9
commit 64ea85ee7f
2 changed files with 82 additions and 0 deletions

View File

@@ -7028,3 +7028,34 @@ menu modes, mission select, and an equip screen carrying the typo
🟡 Open: the 38 bare screens cannot be named by key list. 🟡 Whether the `EX_`
in `EX_MENU_DISABLE_SKIP` / `EX_LETTERS` is the `+184` `EXTRA` word.
---
## ✅ 2026-08-28 — which challenge stage is which leaderboard mode: CLOSED
Read from the mission record's own indexed fields (the route
`challenge-mission-gate.md` §5.3 itself named), with the corpus's reader:
| `TimeAttack` 24/req 16/**Time** | `ScoreAttack` 25/req 24/**Points** | `Extra01` 26/req 25/**Points** |
|---|---|---|
| `Extra02` 27/req 26/**Time** | `Extra03` 28/req 27/**Time** | `Extra04` 29/req 28/**Points** |
**Control: 6 pak entries, all `tables.pak`, all byte-identical — one user.**
**`MISSION_ID` is the stage number** — `24``29`, bijective with challenge stages
S24S29. The "4 `Extra0n` vs 5 `_EXn`" worry dissolves: `_EXn` is a unit-variant
suffix indexing nothing here.
**`REQUIREMENT` is a strict chain** — `16, 24, 25, 26, 27, 28`: each mission needs
the previous one's stage, anchored on stage 16. §5.3 guessed the chain from pool
shape; it is now exact and branchless.
**`RECORD_TYPE` is the metric, per-stage not per-name** — 3 `Time` (S24, S27, S28)
/ 3 `Points` (S25, S26, S29). The `Extra0n` family does **not** share one metric.
⚠️ **Withdrawn**: §5.3's pool reading gave requirements `16,25,26,27,29`; the true set
is `16,24,25,26,27,28`**`29` is a `MISSION_ID`, never a requirement**.
🟡 `RECORD_TYPE`'s two values match the two ranking screens `POINT_RANKING` /
`CLEAR_TIME_RANKING` by vocabulary, but no code path selecting one from that field
has been shown.

View File

@@ -457,3 +457,54 @@ python3 xenia-rs/zq.py dis 0x82184df0 0x82184e30 # the three-way section sw
python3 xenia-rs/zq.py dis 0x82185ed0 0x82185f10 # the same switch, second site
python3 xenia-rs/zq.py dis 0x82189860 0x821899f0 # the challenge availability gate
```
### 5.4 ✅ CLOSED — the exact pairing, read from the record's own fields
§5.3 left 🟡 "the exact pairing (which mission needs which), which needs the
record's binary index section rather than the string pool." That is exactly the
right route, and running it with the corpus's own reader settles all six at once:
| slot | `MISSION_ID` | `REQUIREMENT` | `RECORD_TYPE` |
|---|---:|---:|---|
| `TimeAttack` | **24** | 16 | **Time** |
| `ScoreAttack` | **25** | 24 | **Points** |
| `Extra01` | **26** | 25 | **Points** |
| `Extra02` | **27** | 26 | **Time** |
| `Extra03` | **28** | 27 | **Time** |
| `Extra04` | **29** | 28 | **Points** |
**Control:** the table appears in **6 pak entries, all in `tables.pak`, and all six
are byte-for-byte the same table** — one per language, i.e. **one user** under the
per-pak copy rule. Zero variants.
#### 🔑 Three things fall out, none of them assumed
**`MISSION_ID` *is* the stage number.** The six IDs are `24``29` in slot order —
exactly the six challenge stages `S24``S29` from §1, **bijectively**. The
leaderboard's six modes and the disc's six challenge stages are the same six
things, so the "four `Extra0n` against five `_EXn`" worry dissolves: `_EXn` is a
*unit-variant* suffix and indexes nothing here.
**`REQUIREMENT` is a strict chain, measured not guessed.** `16, 24, 25, 26, 27,
28` — each mission requires **the previous one's stage** cleared, with `TimeAttack`
anchored on stage 16, the final story mission. §5.3 inferred "the challenge missions
chain off each other" from the shape of the pool; the chain is now exact, and it is
a *pure* chain with no branches.
**`RECORD_TYPE` is the leaderboard metric, and it is per-stage, not per-name.**
**3 `Time` (S24, S27, S28) and 3 `Points` (S25, S26, S29).** The tempting reading —
that the `Extra0n` family shares one metric — is **wrong**: `Extra01` and `Extra04`
are ranked by Points while `Extra02` and `Extra03` are ranked by Time. Only the two
self-describing missions match their names.
⚠️ **Withdrawn from §5.3**: the string-pool reading listed the numeric tokens as
`16, 25, 26, 27, 29` with `24`/`28` "deduped away". The real `REQUIREMENT` set is
`16, 24, 25, 26, 27, 28`**`29` is a `MISSION_ID`, never a requirement**. A value
pulled from a deduped string pool by adjacency got one member wrong; the indexed
read has no such failure mode.
🟡 **Still an association, not a proof:** [[result-screens]] names two ranking
screens, `POINT_RANKING` (`sub_8227F6E0`) and `CLEAR_TIME_RANKING` (`sub_82282C28`),
and `RECORD_TYPE` takes exactly the two values `Points` and `Time`. The pairing is
strongly supported by both vocabularies, but no code path has been shown selecting
one screen from that field.