Decode STINIT tagged object payloads
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<!-- DO NOT EDIT -- generated from vm-map/globals.toml by tools/globals_build.py --build -->
|
||||
# Global Variable Reference (generated)
|
||||
|
||||
5030 globals (181 curated, 4849 auto shape-inferred). Source of truth: `vm-map/globals.toml`.
|
||||
5030 globals (185 curated, 4845 auto shape-inferred). Source of truth: `vm-map/globals.toml`.
|
||||
|
||||
## choice-output
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
| `0x65ce` | skill_acquired_flags | high | investigation | Persistent acquired-skill flags. ADDSKILL sets the selected skill after resolving the unit's equipped-skill slots; FORT checks the flag before granting a skill; CHMENU combines it with skill_change_catalog_eligible to build the available skill-change catalog. |
|
||||
| `0x673c` | party_slot_flags | high | investigation | Per-party-slot state flags for slots 0..99. UNITECH creates the initial unit by setting slot 2 to 0x13; CALCARR counts slots whose flags intersect 0x6, and CHMENU includes slots with bit 1 set. Exact meanings of the remaining bits are not yet classified. |
|
||||
| `0x67a0` | party_slot_character_id | high | investigation | Character/unit definition id stored for each party slot. UNITECH writes character id 2 into initial slot 2 on a natural New Game; CHMENU reads this table for every active party_slot_flags entry when constructing its roster. |
|
||||
| `0x7684` | stage_clear_state | high | investigation | Persistent per-stage completion state indexed by stage id. STAGECLEAR sets the current stage cell to 1, while FORT, SELSTAGE, and FIELD use zero versus one to distinguish an uncleared mission from a cleared replay. |
|
||||
| `0x5660b` | skill_info_revealed_flags | high | investigation | Persistent skill-information visibility flags. ADDSKILL sets the selected skill, BTL marks every equipped skill when it is observed in combat, and INFOIT suppresses a skill's icon/handler-driven details until this flag is nonzero. This is broader than skill_acquired_flags. |
|
||||
| `0x66716` | unit_voice_asset_ids | high | investigation | EBINIT per-unit voice bank for 116 voiced characters and variants. Resolving the values through SYS4INI yields character OGG clips (for example Lily's row is LILA1381..1406); BTL and FIELD select mostly unresolved battle/map reaction slots, while SHOWGROW proves column 24 is the level-up reaction. Columns: 24=level_up. |
|
||||
| `0x6dc46` | unit_status_art_asset_ids | high | investigation | Three-variant status/menu illustration table for 25 principal characters. The ids resolve to 456x420 CS character art; DRAWCHP selects column 0 above 50% HP, column 1 at 26..50%, and column 2 at 25% or below, then loads the art into the status-panel texture slot. Columns: 0=healthy, 1=wounded, 2=critical. |
|
||||
@@ -112,6 +113,8 @@
|
||||
| `0xe7325` | stage_object_tile_x | high | investigation | X coordinate for each current-stage object slot. DRAWOBJ converts it to centered map-space pixels; FIELD and CALCOCC use it with stage_object_tile_y for object interaction and occupancy. |
|
||||
| `0xe7357` | stage_object_tile_y | high | investigation | Y coordinate for each current-stage object slot. DRAWOBJ converts it to centered map-space pixels; FIELD and CALCOCC use it with stage_object_tile_x for object interaction and occupancy. |
|
||||
| `0xe7389` | stage_object_type_id | high | investigation | Object-definition id for each current-stage object slot. SETOBJ decides whether the slot exists, while DRAWOBJ and FIELD use the id to select shared object graphics, dimensions, animation, collision, and behavior metadata. |
|
||||
| `0xe741f` | stage_object_reinforcement_interval_turns | high | investigation | Per-object reinforcement schedule. FIELD compares the current turn and the object's runtime spawn count against this interval to calculate due weighted enemy spawns; object type 27 uses the same value as its one-shot trigger turn. |
|
||||
| `0xe7451` | stage_object_reinforcement_spawn_limit | high | investigation | Maximum number of scheduled units materialized through a stage object. FIELD stops the object's reinforcement path once its runtime spawn counter reaches this value; object type 27 stores one for its one-shot special spawn. |
|
||||
| `0xe7483` | stage_object_difficulty_mask | high | investigation | Per-object difficulty inclusion mask. SETOBJ uses check-bit with difficulty_index and rejects the object slot when the selected difficulty bit is absent. |
|
||||
| `0xe74b5` | stage_object_required_story_flags | high | investigation | Seven positive prerequisites per stage object. SETOBJ subtracts one from every populated id and suppresses the object unless the corresponding story_event_flags cell equals 1. Columns: 0=required_flag_1, 1=required_flag_2, 2=required_flag_3, 3=required_flag_4, 4=required_flag_5, 5=required_flag_6, 6=required_flag_7. |
|
||||
| `0xe7613` | stage_object_forbidden_story_flags | high | investigation | Five negative prerequisites per stage object. SETOBJ subtracts one from every populated id and suppresses the object when the corresponding story_event_flags cell equals 1. Columns: 0=forbidden_flag_1, 1=forbidden_flag_2, 2=forbidden_flag_3, 3=forbidden_flag_4, 4=forbidden_flag_5. |
|
||||
@@ -120,6 +123,7 @@
|
||||
| `0xe777b` | stage_enemy_spawn_object_slot | high | investigation | Optional object-placement anchor for an enemy spawn. FIELD resolves nonzero entries through stage_object_type_id and uses the matching stage_object_tile_x/Y location; zero selects stage_enemy_spawn_tile_x/Y directly. |
|
||||
| `0xe7799` | stage_enemy_faction_id | high | investigation | Per-spawn faction/team selector. FIELD and ADDEN copy it into the runtime unit's faction field, use it to choose the entity-index band, and test the same value against map occupancy masks. |
|
||||
| `0xe77b7` | stage_enemy_difficulty_mask | high | investigation | Per-spawn difficulty inclusion mask. FIELD uses check-bit with difficulty_index and rejects a slot when the selected difficulty bit is absent. |
|
||||
| `0xe77d5` | stage_enemy_first_clear_only | high | investigation | Per-spawn replay gate. FIELD rejects a populated enemy slot when this value is 2 and stage_clear_state for the current stage is 1; zero/default slots remain eligible on cleared-stage replays. |
|
||||
| `0xe77f3` | stage_enemy_random_selection_weight | high | investigation | Weight for stage-enemy alternatives. FIELD groups eligible nonzero-weight slots by their stage_enemy_spawn_object_slot, sums the weights, makes a weighted random choice within each eligible group, and directly materializes zero-weight slots. |
|
||||
| `0xe7811` | stage_enemy_unit_id | high | investigation | Unit-definition id for each current-stage enemy slot. FIELD rejects zero slots, while FIELD and ADDEN pass populated ids to SETEN to copy the corresponding EBINIT definition into a runtime entity. |
|
||||
| `0xe782f` | stage_enemy_min_level | high | investigation | Scenario-specific minimum level for each stage enemy. After applying party-level auto-scaling, SETEN raises the runtime level to this floor before applying the maximum-level clamp. |
|
||||
@@ -172,7 +176,6 @@
|
||||
| `0x6868` | — | low | auto-shape | array |
|
||||
| `0x6930` | — | low | auto-shape | array |
|
||||
| `0x6994` | — | low | auto-shape | array |
|
||||
| `0x7684` | — | low | auto-shape | array |
|
||||
| `0x7a6c` | — | low | auto-shape | array |
|
||||
| `0x204fb` | — | low | auto-shape | array |
|
||||
| `0x2052f` | — | low | auto-shape | array |
|
||||
@@ -276,10 +279,7 @@
|
||||
| `0xe730e` | — | low | auto-shape | array |
|
||||
| `0xe73bb` | — | low | auto-shape | array |
|
||||
| `0xe73ed` | — | low | auto-shape | array |
|
||||
| `0xe741f` | — | low | auto-shape | array |
|
||||
| `0xe7451` | — | low | auto-shape | array |
|
||||
| `0xe770d` | — | low | auto-shape | array |
|
||||
| `0xe77d5` | — | low | auto-shape | array |
|
||||
| `0xe7e8d` | — | low | auto-shape | array |
|
||||
| `0xe8275` | — | low | auto-shape | array |
|
||||
| `0xebd0d` | — | low | auto-shape | array |
|
||||
|
||||
@@ -269,7 +269,21 @@ the shared fallback. DRAWOBJ converts `0xe7325` and `0xe7357` to map-space coord
|
||||
SETOBJ/DRAWOBJ/FIELD use `0xe7389` to index shared object definitions. They are object tile X, tile Y, and
|
||||
type id. SETOBJ tests the `{3,4,7}` masks in `0xe7483` against GAMESTART's three-way `difficulty_index`,
|
||||
then applies seven required and five forbidden one-based ids from `0xe74b5`/`0xe7613` against the shared
|
||||
`story_event_flags` bank.
|
||||
`story_event_flags` bank. FIELD's turn loop establishes `0xe741f` and `0xe7451` as each object's
|
||||
reinforcement interval and spawn limit. Type 27 uses the same pair for a one-shot special spawn.
|
||||
|
||||
The intervening `0xe73bb`/`0xe73ed` pair is deliberately not assigned one global name: FIELD dispatches it
|
||||
by `stage_object_type_id`, making it a tagged payload. The generated join decodes only consumer-proven
|
||||
variants:
|
||||
|
||||
- types 1--4: `initial_faction_id` in the first cell;
|
||||
- types 6 and 36: teleport `destination_tile_x` / `destination_tile_y`;
|
||||
- types 7 and 8: treasure `item_id` / `item_quantity`, passed to ADDITEM;
|
||||
- type 28: `card_generation_list_id`, passed to CDINIT.
|
||||
|
||||
This accounts for 220 initial-owner values, 229 teleport destinations, 626 treasure pairs, and 246 card
|
||||
list ids. Another 185 placements across object types 11, 17--21, 25--27 retain one raw payload cell because
|
||||
their type-specific meaning is not yet separable from the consumer behavior.
|
||||
|
||||
The enemy pass follows the separate 30-cell family through FIELD, SETEN, ADDEN, MVRTN, and BTRTN. Slot
|
||||
zero is reserved for ADDEN's synthesized special-unit path; the stage table populates slots 1 through 29.
|
||||
@@ -279,21 +293,22 @@ three-bit difficulty mask in `0xe77b7`, uses `0xe77f3` as a weighted-random alte
|
||||
the seven required plus five forbidden story flags in `0xe793d`/`0xe7a0f`. SETEN proves `0xe782f`,
|
||||
`0xe784d`, and `0xe786b` are the scenario level floor, cap, and party-level scaling divisor. Finally,
|
||||
the three-value footer rows in `0xe7889` and optional `0xe78e3` become difficulty-specific movement and
|
||||
battle routine-set ids selected by MVRTN/BTRTN.
|
||||
battle routine-set ids selected by MVRTN/BTRTN. The final `0xe77d5` gate is also resolved:
|
||||
STAGECLEAR writes `stage_clear_state[current_stage] = 1`, and FIELD suppresses a spawn when that state is
|
||||
set and the spawn's cell equals 2. The joined view exposes all 485 populated cases as
|
||||
`first_clear_only: true`.
|
||||
|
||||
Generated INIT records now retain their raw `fields`/`record_fields`/buffer keys and additionally expose a
|
||||
flat `semantic_fields` projection joined through the top-level `field_semantics` map. For STINIT, the four
|
||||
confirmed parallel buffers plus both prerequisite tables are also assembled into 2,312
|
||||
`object_placements` across 66 stages. Each placement contains its slot, type, tile coordinates, difficulty
|
||||
mask, and populated positive/negative story prerequisites. The four still-unresolved object-parameter
|
||||
buffers remain attached under `unknown_fields`, so this convenience view loses no evidence or invents names.
|
||||
mask, populated positive/negative story prerequisites, optional reinforcement schedule, and the decoded
|
||||
type-tagged payload variants above. The remaining 185 undecoded payload cells stay attached under
|
||||
`unknown_fields`, so this convenience view loses no evidence or invents names.
|
||||
The same records now contain 1,378 joined `enemy_spawns` across 66 stages, with unit/faction, direct or
|
||||
object-linked placement data when present, difficulty and story gates, level rules, random-selection
|
||||
weight, and movement/battle routine rows. Raw footer metadata stays in `footer_arrays`, while its
|
||||
`semantic_fields` value is the copied row itself. The one remaining spawn-mode cell (`0xe77d5`, always 2
|
||||
when populated) stays under `unknown_fields`: FIELD ties it to already-cleared-stage state, but the precise
|
||||
player-facing nuance is not yet strong enough to name. The next STINIT batch is the four type-specific
|
||||
object parameters plus that isolated spawn-mode gate.
|
||||
weight, movement/battle routine rows, and `first_clear_only` replay gating. Raw footer metadata stays in
|
||||
`footer_arrays`, while its `semantic_fields` value is the copied row itself.
|
||||
|
||||
### The curated registry — `vm-map/globals.toml` (2026-07-07)
|
||||
|
||||
@@ -341,10 +356,10 @@ The v1 map labels *shapes and tables*; the next increments add *meaning*, cheape
|
||||
|
||||
1. **Continue INIT semantics by evidence density.** ITINIT/SKINIT, the confirmed EBINIT row layouts, and
|
||||
STINIT's mixed stage records now have machine-readable investigation surfaces, including joined object
|
||||
placements and enemy spawns. Next trace STINIT's four remaining specialized object parameters and its
|
||||
isolated spawn-mode gate only where type-specific/runtime branches distinguish them. Isolate EBINIT's
|
||||
remaining voice/action slots under the same rule. Preserve explicit joins and do not infer meaning from
|
||||
column position alone.
|
||||
placements and enemy spawns. STINIT's universal object schedule, four consumer-proven tagged payload
|
||||
variants, and first-clear enemy gate are decoded; next trace the 185 remaining raw object payloads only
|
||||
where their type-specific runtime branches distinguish them. Isolate EBINIT's remaining voice/action
|
||||
slots under the same rule. Preserve explicit joins and do not infer meaning from column position alone.
|
||||
2. **Extend message-table joins beyond the completed ITMES/SKMES pair** (`VIMES`, other id dispatchers, …)
|
||||
and fold in other `set-string`/`copy-to-global` writers not covered by the `*INIT` set.
|
||||
3. **Label 2D record tables by their readers** — cross-reference which scripts read each
|
||||
|
||||
@@ -752,11 +752,12 @@ footer-array copies. AIM/FIELD/DRAWCHP consumers establish the four condition sl
|
||||
and turn-limit outcome. Further passes establish target clear turns, performance reward, replay behavior,
|
||||
the 20-slot map-texture override list, object type/tile/difficulty fields, and seven required plus five
|
||||
forbidden story prerequisites. Generated records now carry a joined `semantic_fields` view and assemble
|
||||
2,312 object placements across 66 stages while retaining four unresolved type-specific parameters by raw
|
||||
address. The separate 30-cell enemy family is also decoded: FIELD/SETEN/ADDEN establish unit/faction,
|
||||
2,312 object placements across 66 stages. FIELD resolves the universal reinforcement interval/limit and
|
||||
type-tagged initial-faction, teleport, treasure, and card-list payloads; 185 payload cells on other object
|
||||
types remain raw. The separate 30-cell enemy family is also decoded: FIELD/SETEN/ADDEN establish unit/faction,
|
||||
direct or object-linked placement, difficulty/story gates, level floor/cap/scaling, weighted selection,
|
||||
and three difficulty-specific movement/battle routine-set ids. The generated view assembles all 1,378
|
||||
populated enemy slots across 66 stages; only one replay-linked spawn-mode field remains raw.
|
||||
populated enemy slots across 66 stages, including 485 enemies suppressed after the stage's first clear.
|
||||
|
||||
Once the natural spine and first gameplay loop are trustworthy, broaden in independent tracks:
|
||||
|
||||
@@ -766,8 +767,8 @@ Once the natural spine and first gameplay loop are trustworthy, broaden in indep
|
||||
- Unit statistics, equipment, inventory, skills, magic, heroine forms, and progression.
|
||||
- Combat resolution presentation, enemy turns/AI services, and win/loss transitions.
|
||||
- A full chapter of ADV and the scene types encountered between gameplay segments.
|
||||
- Remaining STINIT specialized object-parameter semantics and the isolated spawn-mode gate, plus other data
|
||||
schemas when their runtime consumers make them necessary.
|
||||
- Remaining STINIT tagged payloads on object types 11, 17--21, and 25--27, plus other data schemas when
|
||||
their runtime consumers make them necessary.
|
||||
|
||||
The high-level Phase B direction remains canonical in `docs/remake-architecture-and-roadmap.md`; this file
|
||||
only provides the execution framework.
|
||||
|
||||
@@ -72,10 +72,11 @@ buffer rather than parallel per-id arrays. Its generated records preserve four m
|
||||
six scalars, cells in 29 preallocated buffers, and all 1,396 length-prefixed footer-array copies. Confirmed
|
||||
stage field meanings and the evidence workflow live in `docs/name-resolution.md`. The first semantic join
|
||||
now assembles the confirmed type/X/Y/difficulty and story-prerequisite buffers into 2,312 object placements
|
||||
across 66 stages. A second join assembles all 1,378 populated enemy slots across the same 66 stages,
|
||||
including unit/faction, placement, difficulty/story gates, level rules, weighted alternatives, and
|
||||
difficulty-specific movement/battle routine sets. Unknown type-specific object parameters and the isolated
|
||||
enemy spawn-mode field remain raw.
|
||||
across 66 stages. It also exposes 604 reinforcement schedules and consumer-proven tagged payload variants
|
||||
for initial factions, teleport destinations, treasure item/count pairs, and card-generation lists; 185
|
||||
other type-specific payload cells remain raw. A second join assembles all 1,378 populated enemy slots
|
||||
across the same 66 stages, including unit/faction, placement, difficulty/story gates, level rules, weighted
|
||||
alternatives, difficulty-specific movement/battle routine sets, and 485 first-clear-only replay gates.
|
||||
|
||||
### Message/string tables (`*MES`)
|
||||
`ITMES` (64 KB — item text), `VIMES` (43 KB), `EIMES` (37 KB), `SKMES` (31 KB — skill
|
||||
|
||||
@@ -55,7 +55,7 @@ All opcode knowledge (ABI, semantics, provenance, `depends_on`) is hand-edited *
|
||||
|---|---|---|---|
|
||||
| `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_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 / mixed 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`. Mixed tables recover selector-dispatched records, condition strings, scalars, preallocated buffer cells, consumer-confirmed strides, and length-prefixed footer arrays; STINIT additionally assembles confirmed buffers into `object_placements` and `enemy_spawns`. ITINIT and SKINIT join ITMES/SKMES messages. Top-level `field_semantics` maps raw keys to canonical global/column names, while each record's `semantic_fields` is the generated name-keyed join; complete footer copies map to a row and expose its values without the raw provenance wrapper. Raw keys remain provenance. OUTNAME accepts a stem or one `.json` suffix and rejects paths. Refreshes the generated data index. | `extract_init.py <TABLE> [OUTNAME] [--mode …]` | `<TABLE>.BIN` plus matching `<MES>.BIN` when supported + `build/globals.json` → `build/data/<OUTNAME>.json`, `build/data/README.md` |
|
||||
| `extract_init.py` | Parse a `*INIT` data table (auto-detects name / numeric / footer / mixed 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`. Mixed tables recover selector-dispatched records, condition strings, scalars, preallocated buffer cells, consumer-confirmed strides, and length-prefixed footer arrays; STINIT additionally assembles confirmed buffers into `object_placements` and `enemy_spawns`, including type-tagged teleport/treasure/card/initial-faction payloads, reinforcement schedules, and first-clear-only enemy gates. ITINIT and SKINIT join ITMES/SKMES messages. Top-level `field_semantics` maps raw keys to canonical global/column names, while each record's `semantic_fields` is the generated name-keyed join; complete footer copies map to a row and expose its values without the raw provenance wrapper. Raw keys and unresolved tagged payload cells remain provenance. OUTNAME accepts a stem or one `.json` suffix and rejects paths. Refreshes the generated data index. | `extract_init.py <TABLE> [OUTNAME] [--mode …]` | `<TABLE>.BIN` plus matching `<MES>.BIN` when supported + `build/globals.json` → `build/data/<OUTNAME>.json`, `build/data/README.md` |
|
||||
| `init_table_profile.py` | Build the static investigation surface for an extracted name/numeric/mixed table: message coverage, per-scalar/string/array-cell/footer-array population and value distributions, representative records, and direct opcode/script consumers. `--message-query REGEX` shows every matching name/message beside all populated fields for semantic correlation. Findings are evidence only; confirmed meanings go in `vm-map/globals.toml`. | `init_table_profile.py <TABLE> [--build] [--limit N] [--message-query REGEX]` | `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 and mixed selector-dispatched INIT extraction, MES reconstruction/joins, footer-array accounting and semantic projection, STINIT object/enemy 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}` |
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
- [x] **2.0 — Project structure.** Established `docs/`, `build/{disasm,text,data,scripts-json}/`, `godot/`; game install stays read-only in place. Also relaxed the loader magic check to the `SYS4` family (`SYS4424` patch scripts now parse — was silently skipping 5 scripts).
|
||||
- [x] **2.1 — Text corpora.** `tools/extract_phase2.py` → 481/481 scripts: full disassembly (`build/disasm/*.asm`), per-script strings, `build/text/dialogue.jsonl` (**30,057 show-text lines** — the translation corpus), `build/text/strings.jsonl` (38,449 strings tagged by source opcode), `build/manifest.json`.
|
||||
- [x] **2.2 — `*INIT` data tables → JSON.** `tools/extract_init.py` auto-detects table shape (`name`/`numeric`/`footer`/`mixed`) → **SKINIT (131 skills), ITINIT (287 items), EBINIT (277 units)** [name: sparse one-based name/description/fields], **CGINIT (379 CG entries)** [numeric: index-keyed columns], **MPINIT (1472 map records)** [footer: length-prefixed arrays], and **STINIT (74 stages)** [mixed: selector-dispatched strings/scalars/buffer cells/footer arrays]. Validated; see `build/data/README.md`. Raw addresses remain bytecode provenance; confirmed semantics come from `vm-map/globals.toml`.
|
||||
- [x] **2.3 — Extract `STINIT`'s 74 sparse stage records.** The mixed mode identifies the dominant `scjump_progress_a` dispatch, recovers 29 preallocated buffer layouts (including six consumer-confirmed row strides), and keeps four condition strings, six scalars, fixed-buffer writes, and all 1,396 footer-array copies separated by stage id. Profiles supply population/value and direct-consumer evidence. Header/map semantics cover conditions, BGM, turn/replay/clear-reward settings, and map texture overrides; four parallel object fields plus 7 required/5 forbidden story prerequisites assemble into 2,312 object placements. The 30-cell enemy family now contributes 1,378 joined spawns with unit/faction, placement, difficulty/story gates, level scaling, weighted selection, and difficulty-specific movement/battle routine sets. Raw address views remain alongside generated `semantic_fields`.
|
||||
- [x] **2.3 — Extract `STINIT`'s 74 sparse stage records.** The mixed mode identifies the dominant `scjump_progress_a` dispatch, recovers 29 preallocated buffer layouts (including six consumer-confirmed row strides), and keeps four condition strings, six scalars, fixed-buffer writes, and all 1,396 footer-array copies separated by stage id. Profiles supply population/value and direct-consumer evidence. Header/map semantics cover conditions, BGM, turn/replay/clear-reward settings, and map texture overrides. The object join assembles 2,312 placements with type/position/gates, 604 reinforcement schedules, and typed initial-faction, teleport, treasure, and card-list payloads while preserving 185 unresolved tagged cells. The 30-cell enemy family contributes 1,378 joined spawns with unit/faction, placement, difficulty/story gates, level scaling, weighted selection, difficulty-specific movement/battle routine sets, and 485 first-clear-only gates. Raw address views remain alongside generated `semantic_fields`.
|
||||
- [x] **2.4 — Partial global-var map BUILT + wired into the disassembler.** `tools/global_map.py` → `build/global-var-map.{json,md}` (16,354/49,435 globals labelled: string tables, `*INIT` field arrays, 122 record tables w/ strides, current-entity index pointers). `sys4load` renders the labels inline (`=rec[s30]`, `=current-entity-index?`). See `docs/name-resolution.md`.
|
||||
- [ ] **2.5 — Grow the global-var map (future, incremental).** Static first: fold in `*MES` writers; label 2D record tables by their reader scripts. Then Frida to name *which stat* each field is. Full detail: `docs/name-resolution.md` → "Future step — growing the map". Also deferred: `call-script` id→name resolution (engine-level — SCJUMP.BIN decode or Frida; see `docs/name-resolution.md` #1).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user