Files
Sylpheed/docs/re/structures/mission-scoring.md
Claude (auto) 19b6eb3ee6 re: all 24 settings objects named -- stage\StageParameter_S<NN>.tbl
The queued item (the 29-object resource manifest) turned out to be already
settled by challenge-mission-gate.md and stage-mission-tables.md, so the
iteration moved to the open question those docs make answerable.

Hashing EVERY string that appears in any IDXD object on the disc resolves all
24: StageParameter_S01..S16 (story), S24..S29 (challenge), StageParameter_
Tutorial shared by all six tutorials, and StageParameter_Test.  16+6+1+1 = 24,
which is exactly why the settings family is 24 against 29 stage records.

IsBoss16Enable confirmed independently: that object is StageParameter_S16.
GravityFactor is non-zero in S10 (700), S11 (400), S03 (250), S27 (250); the
three unscored objects are S24, S27, S28; the one without SplinterCell is _Test.

Refuted on the way: TOC order is not stage order (the TOC is hash-sorted and the
Boss16 object is 17th, not 16th), and neither the StageResource template nor a
real 19-field record names the settings table.  The AUTO_SETTINGS filenames are
a different scheme -- none of the 28 hashes to any of these 24.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
2026-08-27 19:05:28 +00:00

79 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mission scoring and the S/A/B/C/D rank thresholds
**✅ Settled 2026-08-27** (static; regenerator
`tools/re-capture/mission_scoring.py`, artefact
[`data/mission-scoring.txt`](../data/mission-scoring.txt)).
Found by following `sub_8230D1F8` — the loader that the `AA_`/`AV_` investigation
turned up as a *contaminant*, because it stores at the same object offsets the
unit definition uses. Reading its field names instead of its offsets identified
it as the **stage-settings loader**, and the scoring block is the part of it the
corpus did not have.
**Docs checked:** `isl-condition-builtins.md` owns `AUTO_SETTINGS` — the 28
`stageNN_settings.tbl` / `tutorialNN` / `challengeNN` **filenames**;
`unit-datasheet-static.md` and `unit-struct-runtime.md` own the *per-unit*
`ScorePoint` / `DamageScore` / `MassScore` fields. **What none of them says is how
a mission score is assembled or what earns a rank** — `RankScore`, `TimeBonus`,
`KillBonus`, `FFPenalty`, `Difficulty_*` appear nowhere in `docs/re/`.
## The tables
**24 IDXD objects per language pack × 6 packs = 144.** Each holds exactly three
records — `Score_Easy`, `Score_Normal`, `Score_Hard` — so **72 scoring records
per pack**, and they share **one** 22-field schema with no variants.
| group | fields |
|---|---|
| rank thresholds | `RankScore_S` `_A` `_B` `_C` `_D` |
| score multipliers | `CraftScore_Adjustment`, `VesselScore_Adjustment`, `OtherScore_Adjustment` |
| objective bonus | `MainMissionCount`, `MainMissionBonus` |
| time bonus | `TimeBonus_Maximun` (sic), `TimeBonus_Basis_Minimum`, `TimeBonus_Basis_Maximum` |
| kill / escort bonus | `KillBonus_Maximum`, `FriendlyVesselDamageBonus`, `GettingScoreBasis_Minimum`, `GettingScoreBasis_Maximum` |
| penalties | `LostWingmanPenalty`, `FFPenalty_Craft_Basis`, `FFPenalty_Craft_Maximum`, `FFPenalty_Vessel_Basis`, `FFPenalty_Zessel_Maximum` (sic — "Vessel") |
Two of the game's own misspellings are load-bearing as join keys:
**`TimeBonus_Maximun`** and **`FFPenalty_Zessel_Maximum`**.
## ✅ Difficulty changes the earning rate, not the bar
Comparing the three difficulty records inside each object, **10 of the 22 fields
move and 12 never do** — and the ones that never move include **all five
`RankScore_*` thresholds**:
```
differ between Easy/Normal/Hard CraftScore_Adjustment 21 VesselScore_Adjustment 21
(count = objects out of 24) OtherScore_Adjustment 21 LostWingmanPenalty 21
FFPenalty_Craft_Maximum 21 FFPenalty_Zessel_Maximum 21
KillBonus_Maximum 18 MainMissionBonus 18
TimeBonus_Maximun 18 FriendlyVesselDamageBonus 13
never differ RankScore_S/A/B/C/D, MainMissionCount,
GettingScoreBasis_*, TimeBonus_Basis_*,
FFPenalty_*_Basis
```
So a rank bar is **per stage**, identical on every difficulty; what difficulty
changes is how fast you earn against it (`×0.5` / `×1.0` / `×2.0` on the three
`*Score_Adjustment` multipliers) and how hard the penalties bite. That is a
design statement a port has to reproduce exactly, and it is measured, not read
off the names.
## Per-stage variation
**23 of the 24 objects differ from the commonest `Score_Normal` record**, almost
always in the `RankScore_*` thresholds and the objective count/bonus — as
expected for per-mission tuning. Nine of the 72 records (three objects × three
difficulties) zero the multipliers, the penalties and `TimeBonus_Maximun`
outright: missions that are not scored. Full per-object diffs are in the
artefact.
## ✅ Which object is which stage — settled
All 24 are named `stage\StageParameter_S<NN>.tbl`, plus `_Tutorial` (shared by
all six tutorials) and `_Test`. See
[`stage-settings-table.md`](stage-settings-table.md); that also explains 24
against the 29 stage records, and confirms the `IsBoss16Enable` object is S16.
⚠️ The names are **not** `AUTO_SETTINGS`'s `stageNN_settings.tbl`; none of those
28 hashes to any of these objects.