Two exhaustive probes agree on the same 15 records. The six Shift-JIS type words occur in the six GP_MAIN_GAME_* paks and nowhere else, and a disc-wide sweep of every parsed record name for a wildcard shape (???, *, ###, NNN, <...>) returns 7 distinct names - exactly the seven already in the schema: Turret_???, Hatch_???, Bridge_???, Thruster_???, ShieldGenerator_???, Versatile_???, NS_*, each x6. So the weapon datasheet, the arsenal item and StageResource ship NO schema; the unit datasheet is the only structure the disc describes to itself. Wildcard field names are confined to the schema records too - NozzleSpec_???, NozzleFrame_???, CannonFrame_???, MuzzleFrame_???. No untyped gaps either. The full residual is 30 slots and every one holds a sample value rather than a missing type: 28 booleans spelled Yes, plus Generic.ID = Ship_ and Generic.Type = Vessel. The booleans follow one pattern - the six destructible part types each carry the same four-boolean core (IsDestructible, IsInvolved, IsRadarVisible, IsShielded), Turret_??? adds IsAuto, Generic carries only IsDestructible, and NS_* has its own pair AttenuationAlpha / AttenuationVolume. 28 + 2 = 30; 7 fully-typed records + 8 with examples = 15. The third result is a refutation of my own instrument. Testing the four genuinely-undeclared effects against the 166 .xpr packages put eff_f0002 and eff_f0002_barn in Base.xpr and found nothing for eff_e0044 or eff_h308 - but the control kills the negative: eff_n0071, which we measured LIVE as an Explosion record's ExplosionFxModel, also returns nothing from the same search. A known-live name the test cannot find means the test has no power here. Only the positive half counts: eff_f0002/_barn do ship. Nothing follows about eff_e0044 or eff_h308, and the earlier "no mesh" remarks about eff_e0058/_e0059/_e0060 are weaker than written - absent from a byte search over .xpr is not absent from the disc. How an effect mesh is actually reached is now the open question, since eff_n0071 is not a plain name string in any of the 166 packages. All sixteen artefacts byte-identical.
120 lines
5.5 KiB
Markdown
120 lines
5.5 KiB
Markdown
# ✅ The unit datasheet ships its own schema
|
||
|
||
Chasing the previous iteration's Shift-JIS value turned up something much larger
|
||
than the placeholder I called it. **Correction to that entry: `文字列` is not a
|
||
developer's leftover — it is one member of a six-word *type* vocabulary, and the
|
||
records carrying it are a machine-readable schema for the unit datasheet.**
|
||
|
||
## The whole non-ASCII population is six words
|
||
|
||
Across every parsed IDXD string on the disc:
|
||
|
||
| | distinct | non-ASCII |
|
||
|---|---|---|
|
||
| values | 99 328 | **6** |
|
||
| record names | 3 496 | 0 |
|
||
| field names | 12 173 | 0 |
|
||
|
||
All six decode cleanly as Shift-JIS, and all six are type names:
|
||
|
||
| bytes | Shift-JIS | meaning | uses |
|
||
|---|---|---|---|
|
||
| `95B68E9A97F1` | `文字列` | string | 366 |
|
||
| `4E535F22…22` | `NS_"文字列"` | NS_ string | 12 |
|
||
| `90AE9094` | `整数` | integer | 66 |
|
||
| `90AE9094926C` | `整数値` | integer value | 6 |
|
||
| `958293AE8FAC9094926C` | `浮動小数値` | floating-point value | 504 |
|
||
| `…5B308160315D` | `浮動小数値[0〜1]` | float in [0,1] | 36 |
|
||
|
||
990 type-valued fields in total. So the reader defect noted last time is real but
|
||
**bounded to these six strings** — nothing else on the disc is non-ASCII, and
|
||
`name_hash` re-encodes Latin-1 byte-for-byte, so hashing was never affected.
|
||
|
||
## 15 wildcard schema records, one per substructure
|
||
|
||
The 990 fields sit in **15 records × 6 `GP_MAIN_GAME_*` paks = 90 instances**,
|
||
i.e. **15 records with one user** under the per-pak-copy rule. Their names are
|
||
exactly the unit substructure family — and six of them carry a literal wildcard:
|
||
|
||
`Generic`, `Maneuver`, `Effect`, `Shield`, `Mass`, `SE`, `Explosion`,
|
||
`StructureCount`, plus `Turret_???`, `Hatch_???`, `Bridge_???`, `Thruster_???`,
|
||
`ShieldGenerator_???`, `Versatile_???` and `NS_*`.
|
||
|
||
🔑 **`???` is the numeric-suffix wildcard**, at record *and* field level:
|
||
`Turret_???` is the schema for `Turret_000…00N`, and inside it
|
||
`CannonFrame_???` / `MuzzleFrame_???` stand for the numbered frame slots.
|
||
|
||
⚠️ The control separates schema from data cleanly. The six `_???` records and
|
||
`NS_*` exist **only** as schema — 6 of 6 instances typed. The eight real
|
||
substructure names are typed in 6 instances and untyped in the rest:
|
||
`Generic` 6 of 3 651, `Maneuver`/`Shield`/`Mass`/`SE`/`Explosion`/`Effect`/
|
||
`StructureCount` 6 of 684 each. A schema record is one extra instance of a name
|
||
the datasheets already use.
|
||
|
||
## Where the type is an enum, the schema holds an example
|
||
|
||
Not every field is typed — `Generic` is 20 typed of 23, `Turret_???` 20 of 25.
|
||
The untyped slots hold a **sample value** instead, which names the enum:
|
||
|
||
| field | schema slot | reading |
|
||
|---|---|---|
|
||
| `IsDestructible`, `IsAuto`, `IsShielded`, `IsRadarVisible`, `IsInvolved` | `Yes` | boolean |
|
||
| `Generic.Type` | `Vessel` | the Craft/Vessel enum (43 + 71) |
|
||
| `Generic.ID` | `Ship_` | the ID *prefix* convention |
|
||
|
||
`Maneuver` is the one fully-typed record: **34 of 34**.
|
||
|
||
Two readings worth keeping for the port:
|
||
|
||
* every `ResistanceTo*` (`Shell`, `Explosion`, `Optics`) and every `Color_*`
|
||
channel is **`FLOAT[0..1]`** — declared normalised, matching the sampled
|
||
values (`ResistanceToShell 0.1`, `ResistanceToExplosion 0.5`) in
|
||
[[unit-datasheet-static]];
|
||
* `Generic.NozzleSpec_???` has its own type `NS_"文字列"`, and `NS_*` is a
|
||
record — the nozzle spec is a nested sub-schema, not a plain string.
|
||
|
||
⚠️ `Turret_???` carries the game's own typo **`NomalModel`** (beside
|
||
`DamagedModel`), which is a join key in the usual way.
|
||
|
||
This is the authoritative field-type table for the unit datasheet: types the
|
||
disc declares, rather than types inferred from sampled values.
|
||
|
||
Regenerate with `tools/re-capture/datasheet_schema.py` →
|
||
[`docs/re/data/datasheet-schema.txt`](../data/datasheet-schema.txt).
|
||
|
||
## ✅ The unit family is the only schema on the disc
|
||
|
||
Two independent probes, both exhaustive, both landing on the same 15 records:
|
||
|
||
* **the type words** — the six Shift-JIS type names occur in the six
|
||
`GP_MAIN_GAME_*` paks and nowhere else;
|
||
* **the wildcard names** — sweeping every parsed record name disc-wide for a
|
||
`???`, `*`, `###`, `NNN` or `<…>` shape returns **7 distinct names**, and they
|
||
are *exactly* the seven already in the schema (`Turret_???`, `Hatch_???`,
|
||
`Bridge_???`, `Thruster_???`, `ShieldGenerator_???`, `Versatile_???`, `NS_*`),
|
||
each ×6.
|
||
|
||
So the weapon datasheet, the arsenal item and `StageResource` ship **no**
|
||
schema — the unit datasheet is the only structure the disc describes to itself.
|
||
The wildcard *field* names are likewise confined to the schema records:
|
||
`NozzleSpec_???`, `NozzleFrame_???`, `CannonFrame_???`, `MuzzleFrame_???`.
|
||
|
||
## ✅ Every untyped slot is an example — 30 of 30, no gaps
|
||
|
||
The full untyped residual across all 15 schema records is **30 slots**, and
|
||
every one holds a sample value rather than a missing type:
|
||
|
||
* **28 booleans** spelled `Yes`, and they follow one pattern — the six
|
||
destructible part types (`Turret_???`, `Hatch_???`, `Bridge_???`,
|
||
`Thruster_???`, `ShieldGenerator_???`, `Versatile_???`) each carry the same
|
||
four-boolean core **`IsDestructible`, `IsInvolved`, `IsRadarVisible`,
|
||
`IsShielded`**; `Turret_???` adds `IsAuto`; `Generic` carries only
|
||
`IsDestructible`; `NS_*` has its own pair `AttenuationAlpha` /
|
||
`AttenuationVolume`;
|
||
* `Generic.ID` = `Ship_` (the prefix) and `Generic.Type` = `Vessel` (the enum).
|
||
|
||
`28 + 2 = 30`. **Seven of the fifteen records are fully typed** (`Maneuver`,
|
||
`Shield`, `Mass`, `SE`, `Explosion`, `Effect`, `StructureCount`) and eight carry
|
||
examples: `7 + 8 = 15`. There is no field anywhere in the schema whose type the
|
||
disc leaves unstated.
|