Join item and skill message semantics
This commit is contained in:
@@ -43,7 +43,9 @@ S:\Game Hacking\Eushully\Himegari\ ← workspace root (three siblings)
|
||||
│ ├── test_globals.py, test_opcodes.py unit tests for the globals / opcode tooling
|
||||
│ ├── vm0.py headless Python VM (Phase A0); `--test` = RECOVER unit test
|
||||
│ ├── extract_phase2.py batch: disasm + text + data extraction
|
||||
│ ├── extract_init.py, global_map.py … *INIT parsers, global-var map builder
|
||||
│ ├── extract_init.py, extract_message_table.py, global_map.py …
|
||||
│ │ *INIT / ID-dispatched message parsers,
|
||||
│ │ global-var map builder
|
||||
│ ├── validate_opcode_table*.py decode-coverage validators
|
||||
│ ├── movie-corpus-gate/ C# full-corpus FFmpeg decode/lifecycle acceptance tool
|
||||
│ └── probe_*.py format reverse-engineering probes (historical)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- DO NOT EDIT -- generated from vm-map/globals.toml by tools/globals_build.py --build -->
|
||||
# Global Variable Reference (generated)
|
||||
|
||||
5023 globals (144 curated, 4879 auto shape-inferred). Source of truth: `vm-map/globals.toml`.
|
||||
5023 globals (145 curated, 4878 auto shape-inferred). Source of truth: `vm-map/globals.toml`.
|
||||
|
||||
## choice-output
|
||||
|
||||
@@ -353,6 +353,8 @@
|
||||
| address | name | conf | source | usage |
|
||||
|---|---|---|---|---|
|
||||
| `0x6718` | selected_party_slot | high | investigation | Current/selected slot in the 100-entry party-unit arrays. UNITECH chooses a free slot here before populating it; CHMENU replaces it with the selected sorted roster slot, then uses it to index party_slot_flags, party_slot_character_id, and companion per-slot tables. A natural New Game enters SC0000 with slot 2 selected. |
|
||||
| `0x8c877` | current_item_id | high | investigation | Shared item-id argument/selection slot. Item menus and gameplay scripts write a chosen item id, use it to index ITINIT arrays, and dispatch through item_handler_script_id; ITMES compares it against all 287 item ids to select the matching player-facing title and description. |
|
||||
| `0xa6e59` | current_skill_id | high | investigation | Shared skill-id argument/selection slot. Skill menus and combat scripts write the chosen skill id and use it to index SKINIT arrays; SKMES compares it against all 131 skill ids to select the matching player-facing title and description. |
|
||||
| `0xeff75` | current_entity_index_hi | med | inference | High-purity current-entity row index (purity 0.95 in the auto shape map); dominant 2D-table row selector. |
|
||||
| `0x152616` | current_entity_index | med | investigation | Primary current-entity row index (RECOVER-confirmed; purity 0.51, 363 row-index uses). |
|
||||
|
||||
@@ -394,7 +396,6 @@
|
||||
| `0x665d6` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against []; writers=['MES.BIN', 'SBUNKI.BIN']. |
|
||||
| `0x665d7` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [1, 3]; writers=['ADDSKILL.BIN', 'SBUNKI.BIN']. |
|
||||
| `0x66714` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against []; writers=['DEBUGBTL.BIN', 'FIELD.BIN', 'RTN_M051.BIN', 'RTN_M052.BIN']. |
|
||||
| `0xa6e59` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [1, 2, 3, 4, 11, 21, 22, 23]; writers=['CALCDMG.BIN', 'CHMENU.BIN', 'FORT.BIN', 'INFOIT.BIN']. |
|
||||
| `0xab8e7` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0, 10, 15, 20, 25, 30, 35, 40]; writers=['CALCCC.BIN', 'CCINIT.BIN']. |
|
||||
| `0xaba5c` | — | med | auto-shape | TODO: confirm. Branch-read in 136 scenes / 149 scripts; compared against [0, 1]; writers=['DEBUGADV.BIN', 'DEBUGADV2.BIN', 'SC0000.BIN', 'SC0010.BIN']. |
|
||||
| `0xaba5e` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [2]; writers=['DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']. |
|
||||
@@ -4986,7 +4987,6 @@
|
||||
| `0x7843e` | — | med | auto-shape | unit-field |
|
||||
| `0x81c96` | — | med | auto-shape | record-table[stride 3] |
|
||||
| `0x8284e` | — | med | auto-shape | record-table[stride 3] |
|
||||
| `0x8c877` | — | low | auto-shape | index/counter? |
|
||||
| `0xa70b2` | — | low | auto-shape | skill-field? |
|
||||
| `0xaac76` | — | low | auto-shape | index/counter? |
|
||||
| `0xaacf0` | — | med | auto-shape | record-table[stride 5] |
|
||||
|
||||
@@ -727,6 +727,15 @@ voice assets, XP/drops, capture and compendium flags, summoning economy, essence
|
||||
Its linked-table shapes are 18 SKINIT and 84 EBINIT populated columns. The next EB tranche identifies roster
|
||||
state flags, per-action unlock requirements, SCJUMP event ids, normal/brainwashed unit variants, and SALLY's
|
||||
per-unit bonus item. Combat tracing also names the shared column-8 item/skill modifier as critical chance.
|
||||
|
||||
The message-table tranche adds a reusable extractor for global-id dispatch chains and joins player-facing
|
||||
ITMES/SKMES text back to INIT records. All 287 item ids and all 131 skill ids match exactly in both
|
||||
directions. Each joined message retains its rendered title, richer description, furigana annotations, and
|
||||
dispatch offset independently of INIT's shorter effect label; generated profiles report complete coverage.
|
||||
The dispatch keys also establish `current_item_id` and `current_skill_id` as high-confidence shared index
|
||||
slots. This makes message/field correlation the next evidence source for the remaining sparse item and skill
|
||||
columns.
|
||||
|
||||
The remaining EBINIT unknowns are now the unread `0x7843e` enum and the signed meaning within boss classes;
|
||||
enemy AI appears to live outside the static EBINIT schema. STINIT's bespoke parser remains a separate
|
||||
extraction task.
|
||||
|
||||
@@ -54,9 +54,10 @@ All opcode knowledge (ABI, semantics, provenance, `depends_on`) is hand-edited *
|
||||
| Tool | Purpose | Run | Reads → Writes |
|
||||
|---|---|---|---|
|
||||
| `extract_phase2.py` | Batch: disassembly + text corpora for every script. | `extract_phase2.py` | corpus → `build/disasm/*.asm`, `build/text/{dialogue.jsonl,strings.jsonl,*.strings.txt}`, `build/manifest.json` |
|
||||
| `extract_init.py` | Parse a `*INIT` data table (auto-detects name / numeric / footer shape). Name tables infer their reserved record span, preserve sparse one-based runtime ids, distinguish lookup bases from first written cells, statically evaluate both direct `mov` writes and the INIT convention `sub destination, 0, magnitude` for negative values, and use corpus-observed 2D consumers to separate parallel `fields` from linked `record_fields` keyed `base/stride/column`. Also refreshes the generated data index. | `extract_init.py <TABLE> [OUTNAME] [--mode …]` | `<TABLE>.BIN` → `build/data/<OUTNAME>.json`, `build/data/README.md` |
|
||||
| `init_table_profile.py` | Build the static investigation surface for an extracted name/numeric table: per-array and per-record-column population/value distributions, representative records, and direct opcode/script consumers. Findings are evidence only; confirmed meanings go in `vm-map/globals.toml`. | `init_table_profile.py <TABLE> [--build] [--limit N]` | `build/data/<TABLE>.json` + corpus → stdout; with `--build`, `build/data/<TABLE>-field-profile.{json,md}` |
|
||||
| `test_extract_init.py`, `test_init_table_profile.py` | Regression checks for sparse one-based INIT extraction and field profiling. | run each directly | — |
|
||||
| `extract_message_table.py` | Discover a repeated global-id dispatch chain such as ITMES/SKMES, reconstruct player-facing title/description lines (including furigana surface text and readings), and emit an ID-keyed message table with bytecode provenance. | `extract_message_table.py <MES> [OUTNAME]` | `<MES>.BIN` → `build/data/<OUTNAME>.json` |
|
||||
| `extract_init.py` | Parse a `*INIT` data table (auto-detects name / numeric / footer shape). Name tables infer their reserved record span, preserve sparse one-based runtime ids, distinguish lookup bases from first written cells, statically evaluate direct and negative-value writes, and separate parallel `fields` from linked row-major `record_fields`. ITINIT and SKINIT also join their matching ITMES/SKMES player-facing messages by runtime id. Refreshes the generated data index. | `extract_init.py <TABLE> [OUTNAME] [--mode …]` | `<TABLE>.BIN` plus matching `<MES>.BIN` when supported → `build/data/<OUTNAME>.json`, `build/data/README.md` |
|
||||
| `init_table_profile.py` | Build the static investigation surface for an extracted name/numeric table: message coverage, per-array and per-record-column population/value distributions, representative records, and direct opcode/script consumers. Findings are evidence only; confirmed meanings go in `vm-map/globals.toml`. | `init_table_profile.py <TABLE> [--build] [--limit N]` | `build/data/<TABLE>.json` + corpus → stdout; with `--build`, `build/data/<TABLE>-field-profile.{json,md}` |
|
||||
| `test_extract_init.py`, `test_init_table_profile.py` | Regression checks for sparse one-based INIT extraction, MES dispatch reconstruction/joins, and field/message profiling. | run each directly | — |
|
||||
| `global_map.py` | Build the partial global-variable name map from static evidence. | `global_map.py` | corpus + `build/data/` → `build/global-var-map.{json,md}` |
|
||||
|
||||
## VM
|
||||
|
||||
Reference in New Issue
Block a user