re: the develop blob's index space is SOLVED -- it follows strings.tbl, cut items and all
Three hand-written probe saves settled what a mission payout could not.
all 54 owned -> every tab fills and the lists WRAP, giving exact counts
(GUN 8, BEAM 8, LASER 4, MPM 5, ASM 5, B/R 7, CANNON 6,
SPECIAL 6 = 43 displayed) and confirming the display order is
weapon.tbl's order item-for-item. It also killed the idea
that gate-unmet owned flags are suppressed: Maelstrom Bomb
(Stage 6) and Grav Cannon XGS (Stage 12) both rendered at a
Stage-2 save.
only 9 + 39 -> STILETTO BG1 Developed (control) AND TOMAHAWK ALPHA RAIL GUN
Developed. The CANNON block starts at 39, not 38.
only 39 + 48 -> JAMMING SYSTEM Developed. SPECIAL starts at 48, and with six
SPECIAL items the array closes exactly at 53, nothing spare.
So the blob is indexed by strings.tbl's item order -- the display order PLUS the
items only the localisation file carries (Adhesive Mine B2A, and three of
Ballista GSH / Designator LH / Smoke Marker Launcher / Bumble UV). They never
appear in the Arsenal but they hold slots, which is the entire reason the tail
looked broken. It also explains the retail save's five "unexplained" owned
entries at 33 and 45/46/47: cut items, shipped flagged owned, never rendered.
That weapon.tbl's No_Equipment..Wep_83 run is ALSO 54 long is a coincidence, and
it cost real time -- the two orders agree only to index 32. Recorded as such.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,7 +23,7 @@ Promote to a prose `structures/…md` file when a format needs behavioural notes
|
|||||||
| Capital-ship part placement | 🟡 | `sylpheed-formats/src/ship.rs` (static) + [runtime capture](ship-placement-runtime-capture.md) | hull placement static-exact; external parts approximate statically. **Runtime capture** (Canary F10 → VS-constant WorldView) gives ground truth — validated on `e106` destroyer; not yet baked into the viewer |
|
| Capital-ship part placement | 🟡 | `sylpheed-formats/src/ship.rs` (static) + [runtime capture](ship-placement-runtime-capture.md) | hull placement static-exact; external parts approximate statically. **Runtime capture** (Canary F10 → VS-constant WorldView) gives ground truth — validated on `e106` destroyer; not yet baked into the viewer |
|
||||||
| Weapon fields defaulted on disc | ✅ | [runtime struct](structures/weapon-struct-runtime.md) · [DATA SHEET route](weapon-datasheet-runtime.md) | **Solved.** Canary maps guest RAM into `/dev/shm`, so the parsed `Weapon`/`Shell` objects are readable live; their layout is solved against disc ground truth (zero contradictions over 100+ records). All 126 weapons, exact numbers, no story progress needed — [4 393 values](captures/weapon-runtime-fields.csv) the disc does not carry. Supersedes the letter-bucket limit of the DATA SHEET route, which now serves as the independent cross-check |
|
| Weapon fields defaulted on disc | ✅ | [runtime struct](structures/weapon-struct-runtime.md) · [DATA SHEET route](weapon-datasheet-runtime.md) | **Solved.** Canary maps guest RAM into `/dev/shm`, so the parsed `Weapon`/`Shell` objects are readable live; their layout is solved against disc ground truth (zero contradictions over 100+ records). All 126 weapons, exact numbers, no story progress needed — [4 393 values](captures/weapon-runtime-fields.csv) the disc does not carry. Supersedes the letter-bucket limit of the DATA SHEET route, which now serves as the independent cross-check |
|
||||||
| Unit (craft/vessel) fields defaulted on disc | ✅/🟡 | [runtime struct](structures/unit-struct-runtime.md) | The parsed `unit\UN_*.tbl` definition object, vtable `0x820af844`, ≥`0x380` bytes, one per unit — **discovered, not assumed** (`unit_discover.py`), and distinguished from the spawned-entity class `0x820af030` by being one-per-ID and byte-constant within a run. Across runs only pointer words move — `--crosscheck` proves **no reported field offset is run-dependent** (two words, `+0x2c8`/`+0x2d0`, are stage-dependent and remain unidentified). 27 fields ✅ (21 units, 7 runs); the `Maneuver` block is **schema declaration order, 4 bytes/field, base `0x9c` with a two-slot gap after `AA_Roll_Min`** (29 anchors, 0 conflicts), which also pins 5 fields *no* disc record ever values. Angles are **radians at runtime, degrees on disc**. Unlike weapons, unit definitions are instantiated **per stage**, so coverage (21/110) grows by visiting missions — but a defaulted field is **not** a global constant: `Size_Y` provably inherits `Size_X` (7 independent units, 6 distinct values), and three more sibling rules are recorded ❔, recovering 65 values in units never visited — [values](captures/unit-runtime-fields.csv) |
|
| Unit (craft/vessel) fields defaulted on disc | ✅/🟡 | [runtime struct](structures/unit-struct-runtime.md) | The parsed `unit\UN_*.tbl` definition object, vtable `0x820af844`, ≥`0x380` bytes, one per unit — **discovered, not assumed** (`unit_discover.py`), and distinguished from the spawned-entity class `0x820af030` by being one-per-ID and byte-constant within a run. Across runs only pointer words move — `--crosscheck` proves **no reported field offset is run-dependent** (two words, `+0x2c8`/`+0x2d0`, are stage-dependent and remain unidentified). 27 fields ✅ (21 units, 7 runs); the `Maneuver` block is **schema declaration order, 4 bytes/field, base `0x9c` with a two-slot gap after `AA_Roll_Min`** (29 anchors, 0 conflicts), which also pins 5 fields *no* disc record ever values. Angles are **radians at runtime, degrees on disc**. Unlike weapons, unit definitions are instantiated **per stage**, so coverage (21/110) grows by visiting missions — but a defaulted field is **not** a global constant: `Size_Y` provably inherits `Size_X` (7 independent units, 6 distinct values), and three more sibling rules are recorded ❔, recovering 65 values in units never visited — [values](captures/unit-runtime-fields.csv) |
|
||||||
| Arsenal develop economy | ✅/❔ | [arsenal-develop-economy](arsenal-develop-economy.md) + [conditions](captures/arsenal-develop-conditions.csv) | The Arsenal reads `weapon.tbl` (item ids, in the 8-category display order — the `No_Equipment … Wep_83` run is exactly **54**, the save blob's length) and `strings.tbl` (names, descriptions, and a **"Conditions to obtain"** block per item) out of `GP_HANGAR_ARSENAL.pak`. All **60** conditions are extracted: gates are stage completion, a predecessor item, or an **ace kill**; costs run 3 000–350 000 P and **20 items are free** once gated. `weapon.tbl`'s first record reproduces the in-game DATA SHEET exactly (Range D / Power E / Speed – / Weight 0.3 = Light / 4000 P) — later records are unreadable from the string pool alone because IDXD **dedupes repeated values**. Used to identify the save blob's index space: **0–31 confirmed** by twelve concordances, tail ❔ |
|
| Arsenal develop economy | ✅/❔ | [arsenal-develop-economy](arsenal-develop-economy.md) + [conditions](captures/arsenal-develop-conditions.csv) | The Arsenal reads `weapon.tbl` (item ids, in the 8-category display order — the `No_Equipment … Wep_83` run is exactly **54**, the save blob's length) and `strings.tbl` (names, descriptions, and a **"Conditions to obtain"** block per item) out of `GP_HANGAR_ARSENAL.pak`. All **60** conditions are extracted: gates are stage completion, a predecessor item, or an **ace kill**; costs run 3 000–350 000 P and **20 items are free** once gated. `weapon.tbl`'s first record reproduces the in-game DATA SHEET exactly (Range D / Power E / Speed – / Weight 0.3 = Light / 4000 P) — later records are unreadable from the string pool alone because IDXD **dedupes repeated values**. Used to identify the save blob's index space, now **solved**: the blob follows **`strings.tbl`'s** order — the display order *plus* the cut items only the localisation file lists (`Adhesive Mine B2A`, `Ballista GSH`, …) — pinned by four hand-written probe saves (9 Stiletto, 21 Falcon, 39 Tomahawk, 48 Jamming System) and closing exactly at index 53. `weapon.tbl`'s id list is **not** the index space; that it is also 54 long is a coincidence, and the two agree only to index 32. The retail save's five unexplained owned entries are the cut items, shipped owned and never rendered |
|
||||||
| UI screen layout (`.rat`) | ✅/🟡 | [ui-rat-layout](structures/ui-rat-layout.md) | One pak per UI screen; each RATC = one (context × language) build; every `<name>.t32` sprite has a `<name>.rat` **layout record** (BE u32; 1280×720 design space; scale/tint/X/Y, keyframes for animated elements, `opt ` link to the focused state). **The tutorial PAUSE menu and the title main menu both rebuild pixel-accurately from the disc.** `loop1.rat` (screen-level draw order) not yet decoded |
|
| UI screen layout (`.rat`) | ✅/🟡 | [ui-rat-layout](structures/ui-rat-layout.md) | One pak per UI screen; each RATC = one (context × language) build; every `<name>.t32` sprite has a `<name>.rat` **layout record** (BE u32; 1280×720 design space; scale/tint/X/Y, keyframes for animated elements, `opt ` link to the focused state). **The tutorial PAUSE menu and the title main menu both rebuild pixel-accurately from the disc.** `loop1.rat` (screen-level draw order) not yet decoded |
|
||||||
| Save file (`savedata`) | ✅/❔ | [savegame-format](structures/savegame-format.md) + [`tools/re-capture/savegame.py`](../../tools/re-capture/savegame.py) | `GDHA` container, zlib payload, chunk stream (`GDAA` / phase name / `GHAD` 122 B progress block / 16×20 B slot table / trailer). **Container and layout read off the title's own serializer `0x822C00E8` and verified by a byte-identical round-trip**; the whole save is 545 B. Payload offsets are also the live save object's offsets (`save+8` GHAD, `save+136` slots). A second save made in-game names **Points** (+24), **flight time in ms** (+4) and **clear ratio %** (+8) off the game's own Details panel; the payload is a **pure function of game state** (same state saved twice = byte-identical, only the header FILETIME and its uninitialised pointer padding move), and the 16 `SHAB` records are **not** the UI's 20 save slots. Difficulty vs stage is undecided — three fields hold 2. **A third save, taken after developing exactly one Arsenal weapon** (Light Machine Gun MG I, 4000 P), moves exactly three things: `+24` Points 4101→101 (which **separates it from `+28`**, that did not move), `+8` clear ratio 5→6 (so the ratio counts *collection*, not only stages), and two entries of the 54-byte blob — `2→4` for the item bought and `0→2` for the successor the game announced as newly developable, giving the blob its alphabet 🟡 *0 locked / 2 developable / 4 developed*. Which item each index is remains open |
|
| Save file (`savedata`) | ✅/❔ | [savegame-format](structures/savegame-format.md) + [`tools/re-capture/savegame.py`](../../tools/re-capture/savegame.py) | `GDHA` container, zlib payload, chunk stream (`GDAA` / phase name / `GHAD` 122 B progress block / 16×20 B slot table / trailer). **Container and layout read off the title's own serializer `0x822C00E8` and verified by a byte-identical round-trip**; the whole save is 545 B. Payload offsets are also the live save object's offsets (`save+8` GHAD, `save+136` slots). A second save made in-game names **Points** (+24), **flight time in ms** (+4) and **clear ratio %** (+8) off the game's own Details panel; the payload is a **pure function of game state** (same state saved twice = byte-identical, only the header FILETIME and its uninitialised pointer padding move), and the 16 `SHAB` records are **not** the UI's 20 save slots. Difficulty vs stage is undecided — three fields hold 2. **A third save, taken after developing exactly one Arsenal weapon** (Light Machine Gun MG I, 4000 P), moves exactly three things: `+24` Points 4101→101 (which **separates it from `+28`**, that did not move), `+8` clear ratio 5→6 (so the ratio counts *collection*, not only stages), and two entries of the 54-byte blob — `2→4` for the item bought and `0→2` for the successor the game announced as newly developable, giving the blob its alphabet 🟡 *0 locked / 2 developable / 4 developed*. Which item each index is remains open |
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,11 @@ Wep_84, Wep_85, NullWeapon_Arm1, NullWeapon_Arm2, NullWeapon_Arm3
|
|||||||
```
|
```
|
||||||
|
|
||||||
The ids are grouped by the eight categories in the same order the screen shows
|
The ids are grouped by the eight categories in the same order the screen shows
|
||||||
them, which is why `No_Equipment … Wep_83` is exactly **54** entries — the blob's
|
them — verified item-for-item against the running game (see the all-owned probe
|
||||||
length.
|
below). Note one **coincidence that cost time**: the run `No_Equipment … Wep_83`
|
||||||
|
is also 54 entries, the save blob's length, which invites the conclusion that this
|
||||||
|
list *is* the blob's index space. It is not — the two agree only up to index 32.
|
||||||
|
The blob follows `strings.tbl`'s order, which carries items this list omits.
|
||||||
|
|
||||||
Each item then has a record: `Size, Weight, Range, Power, Speed, Stage,
|
Each item then has a record: `Size, Weight, Range, Power, Speed, Stage,
|
||||||
MissionObjective, Dependency, Points`. For the **first** record all of it reads
|
MissionObjective, Dependency, Points`. For the **first** record all of it reads
|
||||||
@@ -88,7 +91,7 @@ economy:
|
|||||||
`Spitfire BX`) have a conditions *header* and no conditions — ❔ cut content or
|
`Spitfire BX`) have a conditions *header* and no conditions — ❔ cut content or
|
||||||
non-player weapons.
|
non-player weapons.
|
||||||
|
|
||||||
## What the blob indexes: the first 32 entries, confirmed
|
## How the first 32 entries were confirmed
|
||||||
|
|
||||||
Predicting the save state from the conditions and comparing against the actual
|
Predicting the save state from the conditions and comparing against the actual
|
||||||
blob is a strong test, because it is made **before** looking at the blob. At the
|
blob is a strong test, because it is made **before** looking at the blob. At the
|
||||||
@@ -98,7 +101,10 @@ Dagger BG2, Pilum BP, Hound SMH, Dart 23 Rocket — and the blob's **six** `2`s
|
|||||||
at WEAPONS-order indices **1, 5, 10, 12, 27, 31**, which are those six items, in
|
at WEAPONS-order indices **1, 5, 10, 12, 27, 31**, which are those six items, in
|
||||||
order. Nothing had to be fitted.
|
order. Nothing had to be fitted.
|
||||||
|
|
||||||
| blob | value | item (WEAPONS order) | confirmed by |
|
Indices 0–32 are the same item in either order, so this table stands unchanged
|
||||||
|
under the final mapping.
|
||||||
|
|
||||||
|
| blob | value | item | confirmed by |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| 0 | 4 | `No_Equipment` | always available |
|
| 0 | 4 | `No_Equipment` | always available |
|
||||||
| 1 | 2→4 | `Machiene_Cannon_MG1` | the differential: bought for 4000 P |
|
| 1 | 2→4 | `Machiene_Cannon_MG1` | the differential: bought for 4000 P |
|
||||||
@@ -115,10 +121,50 @@ order. Nothing had to be fitted.
|
|||||||
|
|
||||||
Twelve concordances, no contradiction, over indices 0–31.
|
Twelve concordances, no contradiction, over indices 0–31.
|
||||||
|
|
||||||
## What the blob does **not** index: the tail is unexplained
|
## The full index space ✅ — it is the **localisation** order, cut items included
|
||||||
|
|
||||||
Past index 31 the same alignment fails, and it fails against the screen, not
|
Written after the probes below, which settled it. The blob is **not** indexed by
|
||||||
against a theory:
|
`weapon.tbl`'s `WEAPONS` id list. It is indexed by the order the items appear in
|
||||||
|
`strings.tbl` — the same order, *plus* the handful of items that exist only there:
|
||||||
|
`Adhesive Mine B2A` (a "Conditions to obtain" block whose cost is missing) and the
|
||||||
|
four late entries with a conditions *header* and no conditions. Those never appear
|
||||||
|
in the Arsenal, but they **hold slots in the save**, and that is the whole reason
|
||||||
|
the tail looked broken.
|
||||||
|
|
||||||
|
| blob | block | items (display names, in order) |
|
||||||
|
|---|---|---|
|
||||||
|
| 0 | — | `No_Equipment` |
|
||||||
|
| 1–8 | GUN | Light Machine Gun MG1, Light Swivel MG2H, Heavy MG3, Heavy Swivel MG5H, Broad Sword SG1, Swing Sword SG2H, Twin Sword SG3II, Flail GP37 |
|
||||||
|
| 9–16 | BEAM | **Stiletto BG1** ⌾, Dagger BG2, Rapier BG4H, Pilum BP, Multi Pike BP, Spear HBP, Long Spear HBP, Gray Head T76H |
|
||||||
|
| 17–20 | LASER | Saber LG1, Twin Saber LG2H, Needle L1GP, Fire Arrow L2GP |
|
||||||
|
| 21–25 | MPM | **Falcon 9AM** ⌾, Buzzard 10AM, Hawk 75AM, Condor 105AM, Eagle 120AM |
|
||||||
|
| 26–30 | ASM | Terrier SMH, Hound SMH, Pointer SM, Piranha T53, White Shark T53R |
|
||||||
|
| 31–38 | BOMB/ROCKET | **Dart 23 Rocket** ⌾, Arrow 27 Rocket, *Adhesive Mine B2A — never displayed*, EMP Mine B8E, Laser Mine B9L, Cauldron 50 Rocket, Cluster Mine B10, Maelstrom Bomb |
|
||||||
|
| 39–47 | CANNON | **Tomahawk Alpha Rail Gun** ⌾, Sling 75KG, Glaive 120mm Cannon, Arbalest 155KG, Monoceros Long Cannon, Grav Cannon XGS, *+ three never-displayed slots* |
|
||||||
|
| 48–53 | SPECIAL | **Jamming System** ⌾, Shield Doubler, Booster, Fire Control System, Regenerator, Cartridge Holder |
|
||||||
|
|
||||||
|
⌾ = pinned by an anchor: `9`, `21`, `39` and `48` were each **written into a save by
|
||||||
|
hand** and read back off the screen; `31` is the Dart 23 Rocket's price row in the
|
||||||
|
untouched save. The array ends exactly at 53 with the last SPECIAL item, with
|
||||||
|
nothing left over — 8+8+4+5+5+8+9+6 plus `No_Equipment` is 54.
|
||||||
|
|
||||||
|
The three never-displayed CANNON-block slots are three of `Ballista GSH`,
|
||||||
|
`Designator LH`, `Smoke Marker Launcher`, `Bumble UV` — the four cut entries
|
||||||
|
`strings.tbl` lists between Grav Cannon XGS and Jamming System. **Which three** is
|
||||||
|
🟡 undetermined and does not matter for reading a save; nothing displays them.
|
||||||
|
|
||||||
|
**This explains every anomaly in the retail save.** Its `4`s at 33 and at 45/46/47
|
||||||
|
are the cut items — `Adhesive Mine B2A` and three of the four above — shipped
|
||||||
|
flagged as owned. They never render, so no player ever sees them, and they are
|
||||||
|
exactly the five "unexplained" owned entries that made the tail look wrong. The
|
||||||
|
Tomahawk reading `Developed` at `blob[39]` while `weapon.tbl` puts it at 38 was
|
||||||
|
the same off-by-N, seen from the other side.
|
||||||
|
|
||||||
|
## How the tail was actually settled (and what was wrong first)
|
||||||
|
|
||||||
|
Past index 31 the `weapon.tbl` alignment fails, and it fails against the screen,
|
||||||
|
not against a theory — this is the evidence that sent the investigation to the
|
||||||
|
localisation order above:
|
||||||
|
|
||||||
- `Tomahawk_a_Rail_Gun` is WEAPONS index **38** and the CANNON list shows it
|
- `Tomahawk_a_Rail_Gun` is WEAPONS index **38** and the CANNON list shows it
|
||||||
`Developed` (it is free once Stage 1 is complete) — but **blob[38] = 0**.
|
`Developed` (it is free once Stage 1 is complete) — but **blob[38] = 0**.
|
||||||
@@ -164,10 +210,28 @@ What it showed:
|
|||||||
under it the real save's `45/46/47` are Chaff Flare Dispencer / Shield Doubler
|
under it the real save's `45/46/47` are Chaff Flare Dispencer / Shield Doubler
|
||||||
/ Booster, and the SPECIAL tab is empty in that same save.
|
/ Booster, and the SPECIAL tab is empty in that same save.
|
||||||
|
|
||||||
So the tail is not a shifted copy of the list either. **Status: ❔** — the value
|
Three further probes settled it, and the reasoning is worth keeping because the
|
||||||
alphabet and indices 0–31 are settled; indices ≥32 are not, and must not go into
|
first read of the same evidence was wrong.
|
||||||
the reimplementation. The next probe is cheap now that saves can be written: set
|
|
||||||
one tail index at a time and read which row changes.
|
1. **Every slot owned.** With all 54 entries set to `4`, every tab filled and the
|
||||||
|
lists **wrap**, which gives exact counts: GUN 8, BEAM 8, LASER 4, MPM 5, ASM 5,
|
||||||
|
BOMB/ROCKET **7**, CANNON 6, SPECIAL 6 — 43 items — and the display order is
|
||||||
|
`weapon.tbl`'s order, item for item. Note what this probe *cannot* do: with
|
||||||
|
everything owned, any surjective mapping looks the same. It bounds, it does not
|
||||||
|
pin. It also killed the "gate-unmet flags are suppressed" idea outright —
|
||||||
|
Maelstrom Bomb (Stage 6) and Grav Cannon XGS (Stage 12) both rendered
|
||||||
|
`Developed` at a Stage-2 save.
|
||||||
|
2. **One slot owned: `39`.** `blob = 0` except `9` (control) and `39` → BEAM showed
|
||||||
|
`STILETTO BG1 Developed` **and CANNON showed `TOMAHAWK ALPHA RAIL GUN
|
||||||
|
Developed`**. So the CANNON block starts at 39, not 38: exactly one slot more
|
||||||
|
than the display between Dart 23 (31) and the Tomahawk.
|
||||||
|
3. **One slot owned: `48`.** `blob = 0` except `39` and `48` → SPECIAL showed
|
||||||
|
`JAMMING SYSTEM Developed`. That fixes the SPECIAL base, and with six SPECIAL
|
||||||
|
items the array closes exactly at 53.
|
||||||
|
|
||||||
|
The earlier probe's `45 = 4` leaving SPECIAL empty — which had looked like the
|
||||||
|
mapping failing — is simply a cut item: 45 is in the CANNON block's
|
||||||
|
never-displayed tail, not in SPECIAL at all.
|
||||||
|
|
||||||
### Two behaviours the probe exposed
|
### Two behaviours the probe exposed
|
||||||
|
|
||||||
|
|||||||
BIN
docs/re/captures/arsenal-all-owned-br-cannon.png
Normal file
BIN
docs/re/captures/arsenal-all-owned-br-cannon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 590 KiB |
BIN
docs/re/captures/arsenal-probe-blob39-tomahawk.png
Normal file
BIN
docs/re/captures/arsenal-probe-blob39-tomahawk.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 430 KiB |
BIN
docs/re/captures/arsenal-probe-blob48-jamming.png
Normal file
BIN
docs/re/captures/arsenal-probe-blob48-jamming.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 148 KiB |
@@ -89,7 +89,7 @@ photographed against this exact save (see "Naming the fields", further down).
|
|||||||
| +56 | 2 | 🟡 see +36 |
|
| +56 | 2 | 🟡 see +36 |
|
||||||
| +60 | 0 | ❔ |
|
| +60 | 0 | ❔ |
|
||||||
| +64 (raw 4) | `09 15 00 00` | ❔ the trailer's u32 is the **same** value |
|
| +64 (raw 4) | `09 15 00 00` | ❔ the trailer's u32 is the **same** value |
|
||||||
| +68 (raw 54) | see below | 🟡 **per-item Arsenal development state**, 54 one-byte entries, values only ∈ {0, 2, 4} — histogram `{4: 10, 2: 6, 0: 38}`. `4` = developed, `2` = developable now, `0` = still locked ([evidence](#the-develop-differential-one-weapon-three-fields)) |
|
| +68 (raw 54) | see below | ✅ **per-item Arsenal development state**, one byte per item, `4` = owned, `2` = developable now, `0` = locked ([evidence](#the-develop-differential-one-weapon-three-fields)). Only the `4`s are stored state — `2` is re-derived at load. The index space is **solved**: it is `strings.tbl`'s item order, cut items included ([mapping](../arsenal-develop-economy.md)) |
|
||||||
|
|
||||||
The 54-byte blob is the interesting one — a fixed-length array of small
|
The 54-byte blob is the interesting one — a fixed-length array of small
|
||||||
enumerated states, **16 of the 54 non-zero** (ten 4s, six 2s):
|
enumerated states, **16 of the 54 non-zero** (ten 4s, six 2s):
|
||||||
@@ -131,13 +131,13 @@ three-state progression *locked → developable → developed*, and the blob is
|
|||||||
Arsenal's development state, not a bitmask of owned weapons (a bitmask could not
|
Arsenal's development state, not a bitmask of owned weapons (a bitmask could not
|
||||||
represent the middle state).
|
represent the middle state).
|
||||||
|
|
||||||
**Which item each index is** was chased separately and is **half settled** — see
|
**Which item each index is** was chased separately and is **solved** — see
|
||||||
[the Arsenal develop economy](../arsenal-develop-economy.md). In short: the index
|
[the Arsenal develop economy](../arsenal-develop-economy.md). The index space is
|
||||||
space is the `WEAPONS` id list in `GP_HANGAR_ARSENAL.pak :: eng\weapon.tbl`, whose
|
the item order in `GP_HANGAR_ARSENAL.pak :: eng\strings.tbl`, i.e. the display
|
||||||
`No_Equipment … Wep_83` run is exactly 54 long; twelve independent concordances
|
order **plus the cut items that only the localisation file lists**, pinned by four
|
||||||
confirm indices **0–31** (including all six `2`s, predicted from the disc's own
|
hand-written probe saves (indices 9, 21, 39, 48) and closing exactly at 53. The
|
||||||
"Conditions to obtain" text before the blob was looked at), while the tail from
|
retail save's five otherwise-unexplained owned entries are those cut items,
|
||||||
index 33 on contradicts the screen and is left ❔.
|
shipped flagged as owned and never rendered.
|
||||||
|
|
||||||
One more thing this does **not** settle, and should not be written as if it did:
|
One more thing this does **not** settle, and should not be written as if it did:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user