Close RTINIT movement provider semantics

This commit is contained in:
gamer147
2026-07-23 17:11:14 -04:00
parent 1168535f1b
commit 98c7b8aba7
10 changed files with 210 additions and 69 deletions

View File

@@ -1,7 +1,7 @@
<!-- DO NOT EDIT -- generated from vm-map/globals.toml by tools/globals_build.py --build --> <!-- DO NOT EDIT -- generated from vm-map/globals.toml by tools/globals_build.py --build -->
# Global Variable Reference (generated) # Global Variable Reference (generated)
5039 globals (252 curated, 4787 auto shape-inferred). Source of truth: `vm-map/globals.toml`. 5039 globals (256 curated, 4783 auto shape-inferred). Source of truth: `vm-map/globals.toml`.
## choice-output ## choice-output
@@ -13,6 +13,7 @@
| `0x62ccc` | scjump_decision_out2 | low | inference | Adjacent to scjump_decision_out (0x62ccf) in the 0x62ccc-0x62ccf progression decision-output cluster; same 136-scene reach, written by CAMP/CLOSE/DEBUGADV. INFERENCE from adjacency — confirm meaning before relying on it. | | `0x62ccc` | scjump_decision_out2 | low | inference | Adjacent to scjump_decision_out (0x62ccf) in the 0x62ccc-0x62ccf progression decision-output cluster; same 136-scene reach, written by CAMP/CLOSE/DEBUGADV. INFERENCE from adjacency — confirm meaning before relying on it. |
| `0x62ccf` | scjump_decision_out | high | investigation | SCJUMP's selected progression decision id. Its chapter/flag decision tree writes one of 847 distinct values across 1,755 sites; SYSTEM4, FIELD, SALLY, and TRAIN use it to index scjump_scene_script_resource_ids and dispatch the corresponding SCxxxx scene script. | | `0x62ccf` | scjump_decision_out | high | investigation | SCJUMP's selected progression decision id. Its chapter/flag decision tree writes one of 847 distinct values across 1,755 sites; SYSTEM4, FIELD, SALLY, and TRAIN use it to index scjump_scene_script_resource_ids and dispatch the corresponding SCxxxx scene script. |
| `0xcc9f1` | movement_search_mode | high | investigation | Transient MVSEEK mode. Zero replaces the caller-supplied origin with the current entity tile and uses movement+1 as the search allowance; nonzero modes retain the caller coordinate and use a broad allowance of 9999. Mode 2 additionally masks the doubled-coordinate terrain cells occupied by active entities of another faction before the flood fill. MVSEEK resets the mode to zero on exit. | | `0xcc9f1` | movement_search_mode | high | investigation | Transient MVSEEK mode. Zero replaces the caller-supplied origin with the current entity tile and uses movement+1 as the search allowance; nonzero modes retain the caller coordinate and use a broad allowance of 9999. Mode 2 additionally masks the doubled-coordinate terrain cells occupied by active entities of another faction before the flood fill. MVSEEK resets the mode to zero on exit. |
| `0xeff77` | routine_execution_state | high | investigation | Shared movement/battle routine result state. MVRTN and BTRTN clear it before scanning steps; a nonzero provider result stops the scan. Movement providers use state 1 for ordinary field movement/progress, state 2 for an immediate offensive battle action, and state 3 for an immediate healing/support action; MVRTN supplies state 1 when no provider produced another result. |
## counter ## counter
@@ -20,8 +21,8 @@
|---|---|---|---|---| |---|---|---|---|---|
| `0x2052e` | scjump_progress_b | med | inference | Second SCJUMP switch input (1223 comparison reads) — progression counter/position. INFERENCE from SCJUMP usage. | | `0x2052e` | scjump_progress_b | med | inference | Second SCJUMP switch input (1223 comparison reads) — progression counter/position. INFERENCE from SCJUMP usage. |
| `0x4dfbc` | scjump_progress_a | med | inference | Dominant SCJUMP switch input (1609 comparison reads) — a per-chapter story-progress counter/position the progression machine branches on. INFERENCE from SCJUMP usage; confirm exact meaning via a listing/playthrough. | | `0x4dfbc` | scjump_progress_a | med | inference | Dominant SCJUMP switch input (1609 comparison reads) — a per-chapter story-progress counter/position the progression machine branches on. INFERENCE from SCJUMP usage; confirm exact meaning via a listing/playthrough. |
| `0xcc9f2` | offensive_action_min_range | high | investigation | CALCSCOPE initializes this from the equipped/default attack's minimum range and widens it for usable offensive skills. It is the lower bound used while populating offensive_action_scope_masks. | | `0xcc9f2` | usable_action_min_range | high | investigation | CALCSCOPE initializes this from the equipped/default attack's minimum range and widens it for usable offensive and healing skills. It is the lower bound shared by the offensive and healing action-scope tables. |
| `0xcc9f3` | offensive_action_max_range | high | investigation | CALCSCOPE initializes this from the equipped/default attack's maximum range and widens it for usable offensive skills. ATSEEK bounds its attack-range flood fill with this value; RTN_M051/052 use it as the upper scan bound. | | `0xcc9f3` | usable_action_max_range | high | investigation | CALCSCOPE initializes this from the equipped/default attack's maximum range and widens it for usable offensive and healing skills. ATSEEK bounds its action-range flood fill with this value; RTN_M051/052 and RTN_M061 use it as their upper scan bound. |
| `0xe6c5d` | scjump_progress_d | med | inference | SCJUMP switch input (168 comparison reads) — progression counter/position. INFERENCE from SCJUMP usage. | | `0xe6c5d` | scjump_progress_d | med | inference | SCJUMP switch input (168 comparison reads) — progression counter/position. INFERENCE from SCJUMP usage. |
| `0x152618` | scjump_progress_c | med | inference | Third SCJUMP switch input (530 comparison reads) — progression counter/position. INFERENCE from SCJUMP usage. | | `0x152618` | scjump_progress_c | med | inference | Third SCJUMP switch input (530 comparison reads) — progression counter/position. INFERENCE from SCJUMP usage. |
| `0x152619` | battle_exchange_step | high | investigation | BTL's six-step alternating exchange counter. Dividing it by two selects the first, second, or third ordinary-attack/skill voice variant and related animation slots. | | `0x152619` | battle_exchange_step | high | investigation | BTL's six-step alternating exchange counter. Dividing it by two selects the first, second, or third ordinary-attack/skill voice variant and related animation slots. |
@@ -44,14 +45,17 @@
| `0x4e021` | entity_runtime_flags | high | investigation | Per-runtime-entity state flags. RTN_M007 requires bit 0 when selecting an injured ally, and MVSEEK mode 2 requires it before masking a foreign entity's occupied terrain cell. | | `0x4e021` | entity_runtime_flags | high | investigation | Per-runtime-entity state flags. RTN_M007 requires bit 0 when selecting an injured ally, and MVSEEK mode 2 requires it before masking a foreign entity's occupied terrain cell. |
| `0x4e085` | entity_current_resources | high | investigation | Per-runtime-entity current resources. DRAWCHP/DRAWENP render columns 0..2 against max-stat columns 11..13, skill/item resource deltas modify the same three columns, and movement search compares path cost with current_fs. Columns: 0=current_hp, 1=current_sp, 2=current_fs. | | `0x4e085` | entity_current_resources | high | investigation | Per-runtime-entity current resources. DRAWCHP/DRAWENP render columns 0..2 against max-stat columns 11..13, skill/item resource deltas modify the same three columns, and movement search compares path cost with current_fs. Columns: 0=current_hp, 1=current_sp, 2=current_fs. |
| `0x4e11b` | entity_effective_stats | high | investigation | Per-runtime-entity effective fourteen-stat row after CALCREVISE applies base data, equipment, skills, and conditions. Combat/UI consumers use columns 0..10 directly; columns 11..13 are the maxima paired with entity_current_resources HP/SP/FS. Columns: 0=accuracy, 1=evasion, 2=physical_attack, 3=physical_defense, 4=magic_attack, 5=magic_defense, 6=speed, 7=luck, 8=critical_chance, 9=capture_power, 10=movement, 11=max_hp, 12=max_sp, 13=max_fs. | | `0x4e11b` | entity_effective_stats | high | investigation | Per-runtime-entity effective fourteen-stat row after CALCREVISE applies base data, equipment, skills, and conditions. Combat/UI consumers use columns 0..10 directly; columns 11..13 are the maxima paired with entity_current_resources HP/SP/FS. Columns: 0=accuracy, 1=evasion, 2=physical_attack, 3=physical_defense, 4=magic_attack, 5=magic_defense, 6=speed, 7=luck, 8=critical_chance, 9=capture_power, 10=movement, 11=max_hp, 12=max_sp, 13=max_fs. |
| `0x5212b` | entity_equipped_active_skill_ids | high | investigation | Four equipped active-skill slots per runtime entity. CALCSCOPE maps each usable offensive skill into an action bit and range band; RTN_M051 turns the selected nonzero action bit back into its skill id. | | `0x4e693` | entity_skill_flags | high | investigation | Per-runtime-entity skill-state row. CALCREVISE and CALCSCOPE mark equipped skills, combat/field consumers test specific skill ids, and RTN_M009 requires skill 22 (Unlock) before treating an unopened type-7 chest as a treasure target. |
| `0x52289` | entity_selected_action_ids | high | investigation | Per-entity selected battle action. RTN_M051/052 write either zero for the normal attack or an id from entity_equipped_active_skill_ids, then return routine execution state 2 so FIELD enters battle. BTRTN may replace the value through a battle-provider decision. | | `0x5212b` | entity_equipped_active_skill_ids | high | investigation | Four equipped active-skill slots per runtime entity. CALCSCOPE maps each usable offensive or healing skill into the corresponding action bit and range band; RTN_M051/052 select offensive skills and RTN_M061 selects a healing skill from these slots. |
| `0x52289` | entity_selected_action_ids | high | investigation | Per-entity selected action. RTN_M051/052 write either zero for the normal attack or an offensive equipped skill and return routine execution state 2; RTN_M061 writes a healing skill and returns state 3. BTRTN may replace the value through a battle-provider decision. |
| `0x522ed` | entity_faction_ids | high | investigation | Per-runtime-entity faction id. RTN_M007 restricts its injured-unit target to the acting entity's faction; MVSEEK mode 2 compares this value while masking active foreign-entity cells, and ordinary movement checks the acting faction's bit in tile passability masks. | | `0x522ed` | entity_faction_ids | high | investigation | Per-runtime-entity faction id. RTN_M007 restricts its injured-unit target to the acting entity's faction; MVSEEK mode 2 compares this value while masking active foreign-entity cells, and ordinary movement checks the acting faction's bit in tile passability masks. |
| `0x5231f` | entity_tile_x | high | investigation | Per-runtime-entity map X coordinate. FIELD movement and occupancy logic maintain it; movement providers pair it with entity_tile_y and compare or route from the current tile. | | `0x5231f` | entity_tile_x | high | investigation | Per-runtime-entity map X coordinate. FIELD movement and occupancy logic maintain it; movement providers pair it with entity_tile_y and compare or route from the current tile. |
| `0x52351` | entity_tile_y | high | investigation | Per-runtime-entity map Y coordinate paired with entity_tile_x. Values use the same stage map-space cell keys as STINIT object and enemy coordinates. | | `0x52351` | entity_tile_y | high | investigation | Per-runtime-entity map Y coordinate paired with entity_tile_x. Values use the same stage map-space cell keys as STINIT object and enemy coordinates. |
| `0x53517` | entity_movement_routine_set_ids | high | investigation | Per-runtime-entity movement routine set for easy/normal/hard. SETEN copies a stage-specific override or the EBINIT default into this row; MVRTN selects the current difficulty column and stores it in current_routine_set_id. | | `0x53517` | entity_movement_routine_set_ids | high | investigation | Per-runtime-entity movement routine set for easy/normal/hard. SETEN copies a stage-specific override or the EBINIT default into this row; MVRTN selects the current difficulty column and stores it in current_routine_set_id. |
| `0x535ad` | entity_battle_routine_set_ids | high | investigation | Per-runtime-entity battle routine set for easy/normal/hard. SETEN copies a stage-specific override or the EBINIT default into this row; BTRTN selects the current difficulty column and stores it in current_routine_set_id. | | `0x535ad` | entity_battle_routine_set_ids | high | investigation | Per-runtime-entity battle routine set for easy/normal/hard. SETEN copies a stage-specific override or the EBINIT default into this row; BTRTN selects the current difficulty column and stores it in current_routine_set_id. |
| `0x53643` | entity_movement_routine_progress | high | investigation | Per-runtime-entity movement-routine progress counters. FIELD clears all fifty rows, movement providers increment the current step, and MVRTN compares it with movement_routine_minimum_progress_counts before enabling a step. | | `0x53643` | entity_movement_routine_progress | high | investigation | Per-runtime-entity movement-routine progress counters. FIELD clears all fifty rows, movement providers increment the current step, and MVRTN compares it with movement_routine_minimum_progress_counts before enabling a step. |
| `0x53e13` | entity_carried_item_ids | high | investigation | Two carried/drop-item slots per runtime entity. SETEN initializes slot 0 from the unit's starting equipment item, FIELD fills an empty or matching slot when treasure is collected, and RTN_M009 requires an empty slot or an item-id match before approaching a chest/treasure object. Columns: 0=slot_0, 1=slot_1. |
| `0x53e77` | entity_carried_item_counts | high | investigation | Quantities for the two per-entity carried/drop-item slots. SETEN seeds a starting item with quantity one; FIELD adds treasure quantities to the matching slot and caps the result at 999. Columns: 0=slot_0, 1=slot_1. |
| `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. | | `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. |
| `0x56738` | entity_battle_routine_random_rolls | high | investigation | Per-runtime-entity battle-step random rolls. FIELD and BTL fill every active entity's twenty cells with random-modulo-100; BTRTN executes a step when the matching roll is below battle_routine_activation_percents. | | `0x56738` | entity_battle_routine_random_rolls | high | investigation | Per-runtime-entity battle-step random rolls. FIELD and BTL fill every active entity's twenty cells with random-modulo-100; BTRTN executes a step when the matching roll is below battle_routine_activation_percents. |
| `0x56b20` | entity_patrol_waypoint_indices | high | investigation | RTN_M011 compares each step's one-based waypoint_ordinal minus one with the current entity's value. Reaching the selected destination advances this value modulo the largest RTN_M011 waypoint ordinal in the routine set. | | `0x56b20` | entity_patrol_waypoint_indices | high | investigation | RTN_M011 compares each step's one-based waypoint_ordinal minus one with the current entity's value. Reaching the selected destination advances this value modulo the largest RTN_M011 waypoint ordinal in the routine set. |
@@ -135,9 +139,10 @@
| `0xaba64` | stage_object_runtime_flags | high | investigation | Per-current-stage object flags. RTN_M010 and RTN_M015 require bit 1 before considering Healing Feathers or Magic Pillars as movement targets; FIELD and object rendering maintain the broader type-dependent bitfield. | | `0xaba64` | stage_object_runtime_flags | high | investigation | Per-current-stage object flags. RTN_M010 and RTN_M015 require bit 1 before considering Healing Feathers or Magic Pillars as movement targets; FIELD and object rendering maintain the broader type-dependent bitfield. |
| `0xaba96` | pathfinding_remaining_route_steps | high | investigation | MVSEEK's row-major reachability grid. Mode 0 searches from the current entity with movement+1 at the origin; modes 1/2 search from the caller-supplied coordinate with 9999 at the origin. Each traversed edge decrements the value, so a larger positive value is nearer to the origin. RTN_M006/007/015 use origin-minus-target values as route-step radii; RTN_M010 ranks Healing Feathers by the negated value. | | `0xaba96` | pathfinding_remaining_route_steps | high | investigation | MVSEEK's row-major reachability grid. Mode 0 searches from the current entity with movement+1 at the origin; modes 1/2 search from the caller-supplied coordinate with 9999 at the origin. Each traversed edge decrements the value, so a larger positive value is nearer to the origin. RTN_M006/007/015 use origin-minus-target values as route-step radii; RTN_M010 ranks Healing Feathers by the negated value. |
| `0xb240e` | pathfinding_movement_costs | high | investigation | MVSEEK's row-major movement-cost work grid, indexed as [tile_y][tile_x] with stride 27. FIELD and RTN_M providers accept candidate destinations only when this cost is within the acting entity's current FS or a provider-specific override. | | `0xb240e` | pathfinding_movement_costs | high | investigation | MVSEEK's row-major movement-cost work grid, indexed as [tile_y][tile_x] with stride 27. FIELD and RTN_M providers accept candidate destinations only when this cost is within the acting entity's current FS or a provider-specific override. |
| `0xb8d86` | attack_range_distance_grid | high | investigation | ATSEEK's row-major attack-range flood-fill grid. It starts from the acting entity, expands through map-valid doubled-coordinate neighbors up to offensive_action_max_range, and stores 1 for the first range band, 2 for the next, and so on. RTN_M051/052 use the value at an enemy tile to select an offensive_action_scope_masks band. | | `0xb8d86` | action_range_distance_grid | high | investigation | ATSEEK's row-major action-range flood-fill grid. It starts from the acting entity, expands through map-valid doubled-coordinate neighbors up to usable_action_max_range, and stores 1 for the first range band, 2 for the next, and so on. RTN_M051/052 select offensive targets from it; RTN_M061 selects in-range healing targets. |
| `0xbf6fe` | pathfinding_filtered_route_scores | high | investigation | SETMVWORK begins by copying pathfinding_remaining_route_steps, then filters occupied entity cells according to faction and the acting entity's usable offensive-action mask/effectiveness. RTN_M providers combine this target-proximity score with a movement-limited MVSEEK grid to select a reachable tile nearest an entity or stage object. | | `0xbf6fe` | pathfinding_filtered_route_scores | high | investigation | SETMVWORK begins by copying pathfinding_remaining_route_steps, then filters occupied entity cells according to faction and the acting entity's usable offensive-action mask/effectiveness. RTN_M providers combine this target-proximity score with a movement-limited MVSEEK grid to select a reachable tile nearest an entity or stage object. |
| `0xcc9f4` | offensive_action_scope_masks | high | investigation | CALCSCOPE clears ten encoded-range cells, sets bit 0 over the equipped/default attack's range, and sets bits 1..4 over each usable offensive skill's range. SETMVWORK uses the range-0 mask and paired attack elements when filtering target cells; RTN_M003/006/016/017/018 require its normal-attack bit. Columns: 0=range_0, 1=range_1, 2=range_2, 3=range_3, 4=range_4, 5=range_5, 6=range_6, 7=range_7, 8=range_8, 9=range_9. | | `0xcc9f4` | offensive_action_scope_masks | high | investigation | CALCSCOPE clears ten encoded-range cells, sets bit 0 over the equipped/default attack's range, and sets bits 1..4 over each usable offensive skill's range. SETMVWORK uses the range-0 mask and paired attack elements when filtering target cells; RTN_M003/006/016/017/018 require its normal-attack bit. Columns: 0=range_0, 1=range_1, 2=range_2, 3=range_3, 4=range_4, 5=range_5, 6=range_6, 7=range_7, 8=range_8, 9=range_9. |
| `0xcc9fe` | healing_action_scope_masks | high | investigation | CALCSCOPE clears ten encoded-range cells and sets the equipped-slot bit for each usable category-7 healing skill over its applicable range. RTN_M061 uses the masks to restrict ally targets and to select the range-enabled healing skill. Columns: 0=range_0, 1=range_1, 2=range_2, 3=range_3, 4=range_4, 5=range_5, 6=range_6, 7=range_7, 8=range_8, 9=range_9. |
| `0xcca08` | offensive_action_attack_elements | high | investigation | CALCSCOPE stores the normal attack element in action column 0 and each usable equipped skill's attack element in columns 1..4 for every applicable range band. SETMVWORK and RTN_M051/052 test these elements against attack_element_effectiveness_percent. | | `0xcca08` | offensive_action_attack_elements | high | investigation | CALCSCOPE stores the normal attack element in action column 0 and each usable equipped skill's attack element in columns 1..4 for every applicable range band. SETMVWORK and RTN_M051/052 test these elements against attack_element_effectiveness_percent. |
| `0xe6dee` | object_sprite_state_row_mode | high | investigation | OBINIT metadata indexed by object type. FIELD copies the type-tagged initial payload into stage_object_runtime_state only for mode 1; DRAWOBJ likewise multiplies that runtime state by the object sprite height to select source Y only for mode 1. | | `0xe6dee` | object_sprite_state_row_mode | high | investigation | OBINIT metadata indexed by object type. FIELD copies the type-tagged initial payload into stage_object_runtime_state only for mode 1; DRAWOBJ likewise multiplies that runtime state by the object sprite height to select source Y only for mode 1. |
| `0xe7302` | stage_bgm_id | high | investigation | STINIT's per-stage scalar loaded for all 74 records. FIELD passes the value directly to play-bgm when starting the stage. | | `0xe7302` | stage_bgm_id | high | investigation | STINIT's per-stage scalar loaded for all 74 records. FIELD passes the value directly to play-bgm when starting the stage. |
@@ -286,7 +291,6 @@
| `0xaba4b` | — | low | auto-shape | array | | `0xaba4b` | — | low | auto-shape | array |
| `0xaba53` | — | low | auto-shape | array | | `0xaba53` | — | low | auto-shape | array |
| `0xaba5f` | — | low | auto-shape | array | | `0xaba5f` | — | low | auto-shape | array |
| `0xcc9fe` | — | low | auto-shape | array |
| `0xcca3a` | — | low | auto-shape | array | | `0xcca3a` | — | low | auto-shape | array |
| `0xccb66` | — | low | auto-shape | array | | `0xccb66` | — | low | auto-shape | array |
| `0xccbcf` | — | low | auto-shape | array | | `0xccbcf` | — | low | auto-shape | array |
@@ -452,7 +456,6 @@
| `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']. | | `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']. | | `0xaba5e` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [2]; writers=['DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']. |
| `0xccc21` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['CHMENU.BIN']. | | `0xccc21` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['CHMENU.BIN']. |
| `0xeff77` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0, 2, 3]; writers=['BTRTN.BIN', 'MVRTN.BIN', 'RTN_B001.BIN', 'RTN_B002.BIN']. |
| `0x1560e7` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0, 1, 2, 3, 4, 5, 6, 7]; writers=['MAGIC.BIN', 'SELACT.BIN', 'SUMMON.BIN']. | | `0x1560e7` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0, 1, 2, 3, 4, 5, 6, 7]; writers=['MAGIC.BIN', 'SELACT.BIN', 'SUMMON.BIN']. |
| `0x15a094` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0]; writers=['ALCHEMY.BIN', 'EVOLVE.BIN', 'SELSTAGE.BIN', 'STUDY.BIN']. | | `0x15a094` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0]; writers=['ALCHEMY.BIN', 'EVOLVE.BIN', 'SELSTAGE.BIN', 'STUDY.BIN']. |
| `0x15a095` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0]; writers=['INFO.BIN', 'INFOCH.BIN', 'MENU.BIN']. | | `0x15a095` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0]; writers=['INFO.BIN', 'INFOCH.BIN', 'MENU.BIN']. |
@@ -3710,13 +3713,10 @@
| `0x7e54` | — | med | auto-shape | record-table[stride 50] | | `0x7e54` | — | med | auto-shape | record-table[stride 50] |
| `0x341ab` | — | med | auto-shape | record-table[stride 53] | | `0x341ab` | — | med | auto-shape | record-table[stride 53] |
| `0x4e3d7` | — | med | auto-shape | record-table[stride 14] | | `0x4e3d7` | — | med | auto-shape | record-table[stride 14] |
| `0x4e693` | — | med | auto-shape | record-table[stride 300] |
| `0x52383` | — | med | auto-shape | record-table[stride 30] | | `0x52383` | — | med | auto-shape | record-table[stride 30] |
| `0x5295f` | — | med | auto-shape | record-table[stride 30] | | `0x5295f` | — | med | auto-shape | record-table[stride 30] |
| `0x52f3b` | — | med | auto-shape | record-table[stride 30] | | `0x52f3b` | — | med | auto-shape | record-table[stride 30] |
| `0x53a2b` | — | med | auto-shape | record-table[stride 20] | | `0x53a2b` | — | med | auto-shape | record-table[stride 20] |
| `0x53e13` | — | med | auto-shape | record-table[stride 2] |
| `0x53e77` | — | med | auto-shape | record-table[stride 2] |
| `0x53edd` | — | low | auto-shape | index/counter? | | `0x53edd` | — | low | auto-shape | index/counter? |
| `0x53ef5` | — | low | auto-shape | index/counter? | | `0x53ef5` | — | low | auto-shape | index/counter? |
| `0x53ef7` | — | med | auto-shape | record-table[stride 8] | | `0x53ef7` | — | med | auto-shape | record-table[stride 8] |

View File

@@ -445,7 +445,9 @@ empty reserved banks. Structural and consumer-proven meanings live in `vm-map/gl
parameter names remain as raw provenance while each RTN_M/RTN_B consumer proves its tagged schema. parameter names remain as raw provenance while each RTN_M/RTN_B consumer proves its tagged schema.
The provider-specific join now covers The provider-specific join now covers
RTN_M001/003/004/005/006/007/008/010/011/012/013/014/015/017/051/052: 1,027 movement steps, 974 semantically all nineteen used providers,
RTN_M001/002/003/004/005/006/007/008/009/010/011/012/013/014/015/017/051/052/061:
all 1,043 movement steps, 974 semantically
consumed populated parameters, thirteen explicit zero defaults, and three authored-but-unread consumed populated parameters, thirteen explicit zero defaults, and three authored-but-unread
parameter cells. RTN_M005/011/012 read banks 2/3 as parameter cells. RTN_M005/011/012 read banks 2/3 as
`destination_tile_x` / `destination_tile_y` and approach that exact map tile, incrementing the current `destination_tile_x` / `destination_tile_y` and approach that exact map tile, incrementing the current
@@ -509,6 +511,17 @@ movement-unreachable tiles, and randomly chooses among the lowest-positive-score
destination the reachable tile farthest from the nearby threat set rather than merely farthest from one destination the reachable tile farthest from the nearby threat set rather than merely farthest from one
enemy. enemy.
RTN_M002 is the parameterless randomized-roaming provider. It builds the actor's movement-limited
reachability grid, applies SETMVWORK, retains tiles with positive filtered route scores whose movement
cost fits current FS, randomizes their order, and accepts the first destination for which SETROUTE
constructs a path. Success advances progress and returns ordinary movement state 1.
RTN_M009 is the parameterless treasure seeker. It considers active unopened OBINIT type-7 chests only
when the actor has SKINIT skill 22 (`開錠`, Unlock), while type-8 treasure has no skill gate. A target
also requires one of the actor's two carried-item slots to be empty or already hold the object's item
id. M009 selects the nearest eligible object, then uses the same filtered reachability/cost pipeline to
approach a reachable tile nearest it; success advances progress and returns movement state 1.
RTN_M003 is a parameterless normal-attack routing provider. It requires the normal-attack bit, builds RTN_M003 is a parameterless normal-attack routing provider. It requires the normal-attack bit, builds
the actor's movement-limited MVSEEK grid, and runs SETMVWORK so active foreign-faction entity tiles the actor's movement-limited MVSEEK grid, and runs SETMVWORK so active foreign-faction entity tiles
remain eligible only when the normal attack's element has positive effectiveness. It then requires the remain eligible only when the normal attack's element has positive effectiveness. It then requires the
@@ -536,6 +549,13 @@ lowest current HP and randomizes among those ties. After choosing the target, it
actual ATSEEK range band, randomizes among the effective normal attack/equipped skills enabled at that actual ATSEEK range band, randomizes among the effective normal attack/equipped skills enabled at that
band, stores the target and action, and returns immediate-battle state 2 without movement. band, stores the target and action, and returns immediate-battle state 2 without movement.
RTN_M061 is the parameterless immediate-healing provider. CALCSCOPE places usable category-7 healing
skills in a separate range-band mask. M061 keeps active same-faction entities inside ATSEEK whose band
enables healing, retains only allies tied at the lowest current-HP percentage, and randomizes among
those ties. It then compares the chosen ally's current HP plus each range-enabled equipped spell's
recovery against max HP, stores the selected ally and healing skill, advances progress, and returns
support-action state 3 without movement. FIELD handles that state through its dedicated healing path.
MVSEEK's mode contract is also now explicit. Mode 0 replaces the input coordinate with the current MVSEEK's mode contract is also now explicit. Mode 0 replaces the input coordinate with the current
entity tile and seeds the origin with movement+1, producing the movement-limited reachability grid. entity tile and seeds the origin with movement+1, producing the movement-limited reachability grid.
Modes 1/2 retain the caller coordinate and seed it with 9999, producing a broad target-distance grid; Modes 1/2 retain the caller coordinate and seed it with 9999, producing a broad target-distance grid;
@@ -547,17 +567,19 @@ by M006/007/015.
`movement_parameter_1..4`, and top-level `movement_provider_parameter_schemas` records the reusable `movement_parameter_1..4`, and top-level `movement_provider_parameter_schemas` records the reusable
mapping, target-selection rules, zero/unwritten behavior, and authored fields proven unread by their mapping, target-selection rules, zero/unwritten behavior, and authored fields proven unread by their
provider. All 977 populated movement-parameter cells are now accounted for: 974 semantic inputs and provider. All 977 populated movement-parameter cells are now accounted for: 974 semantic inputs and
three explicit residue cells. The three used providers still without schemas (M002/009/061) have no three explicit residue cells. All nineteen providers used by the shipped table now have behavior
populated parameter cells, so their remaining work is behavior decoding rather than column semantics. schemas; the three additionally dispatchable but unused providers remain outside the generated join.
The supporting runtime joins are now curated too: The supporting runtime joins are now curated too:
`entity_runtime_flags`, `entity_runtime_flags`,
`entity_faction_ids`, `entity_tile_x`/`entity_tile_y`, the fourteen-column `entity_effective_stats`, `entity_faction_ids`, `entity_tile_x`/`entity_tile_y`, the fourteen-column `entity_effective_stats`,
current HP/SP/FS, `stage_object_runtime_flags`, `movement_search_mode`, current HP/SP/FS, `entity_skill_flags`, the paired carried-item id/count slots,
`stage_object_runtime_flags`, `movement_search_mode`,
`offensive_action_scope_masks`, `pathfinding_remaining_route_steps`, `offensive_action_scope_masks`, `pathfinding_remaining_route_steps`,
`pathfinding_filtered_route_scores`, `pathfinding_movement_costs`, and the per-entity patrol waypoint `pathfinding_filtered_route_scores`, `pathfinding_movement_costs`, and the per-entity patrol waypoint
index. The faction-specific terrain masks used by M013 are curated as index. The faction-specific terrain masks used by M013 are curated as
`tile_faction_traversal_masks`. M051's shared action-selection ABI also names `acting_entity_index`, `tile_faction_traversal_masks`. M051's shared action-selection ABI also names `acting_entity_index`,
`target_entity_index`, `attack_range_distance_grid`, the offensive range/mask/element tables, `target_entity_index`, `action_range_distance_grid`, the shared usable-action range bounds, the
offensive and healing range masks, the offensive element tables,
`attack_element_effectiveness_percent`, equipped active-skill slots, and the per-entity selected action. `attack_element_effectiveness_percent`, equipped active-skill slots, and the per-entity selected action.
### The curated registry — `vm-map/globals.toml` (2026-07-07) ### The curated registry — `vm-map/globals.toml` (2026-07-07)
@@ -608,10 +630,10 @@ The v1 map labels *shapes and tables*; the next increments add *meaning*, cheape
machine-readable investigation surfaces and semantic joins; EBINIT's populated schema is fully named, machine-readable investigation surfaces and semantic joins; EBINIT's populated schema is fully named,
STINIT's joined object/enemy payloads are decoded, and CCINIT's 71 class-change rules expose predicates STINIT's joined object/enemy payloads are decoded, and CCINIT's 71 class-change rules expose predicates
and effects. SCINIT closes the progression decision-to-scene join, and RTINIT's twenty movement/battle and effects. SCINIT closes the progression decision-to-scene join, and RTINIT's twenty movement/battle
banks are structurally decoded with every populated movement-parameter cell classified and 1,027 of banks are structurally decoded with every populated movement-parameter cell classified and all 1,043
1,043 movement steps joined to provider behavior. Next close the tiny behavior-only RTN_M002/009/061 shipped movement steps joined to provider behavior. With RTINIT's used-provider surface closed,
tail; never assign one universal meaning to a parameter bank whose meaning varies by provider resume the remaining `*MES` writers and other reader-proven 2D tables; never assign one universal
selector. meaning to a parameter bank whose meaning varies by provider selector.
2. **Extend message-table joins beyond the completed ITMES/SKMES pair** (`VIMES`, other id dispatchers, …) 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. 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 3. **Label 2D record tables by their readers** — cross-reference which scripts read each

View File

@@ -788,15 +788,15 @@ resolved and the full overwrite history retained. RTINIT is now the seventh shap
1000-by-20 banks produce 172 routine sets, 1,043 movement steps, and fourteen battle steps with RTN_M/RTN_B 1000-by-20 banks produce 172 routine sets, 1,043 movement steps, and fourteen battle steps with RTN_M/RTN_B
provider joins, activation/progress/story gates, six explicit reserved banks, and complete overwrite provider joins, activation/progress/story gates, six explicit reserved banks, and complete overwrite
history. Provider-tagged decoding now covers movement providers 1, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, history. Provider-tagged decoding now covers movement providers 1, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13,
14, 15, 17, 51, and 52: progress-only steps, stage-object slots, coordinate destinations (including M012's 14, 15, 17, 51, and 52, plus providers 2, 9, and 61: progress-only steps, randomized roaming,
stage-object slots, coordinate destinations (including M012's
foreign-entity route mask), enemy/ally and Magic Pillar searches, resource-gated Healing Feather foreign-entity route mask), enemy/ally and Magic Pillar searches, resource-gated Healing Feather
selection, cyclic waypoints, faction-traversable terrain, retreat, normal-attack routing, and immediate selection, collectible-treasure seeking, cyclic waypoints, faction-traversable terrain, retreat,
element-effective target/action selection, including low-current-HP variants of both attack paths. This normal-attack routing, immediate element-effective target/action selection, and immediate allied
covers 1,027 steps and classifies every one of the 977 healing. This covers all 1,043 steps across all nineteen used providers and classifies every one of the 977
authored movement-parameter cells: 974 are semantic inputs, while the three cells attached to M001/M008 authored movement-parameter cells: 974 are semantic inputs, while the three cells attached to M001/M008
are retained as provider-unread residue; thirteen unwritten zero defaults are projected separately. The are retained as provider-unread residue; thirteen unwritten zero defaults are projected separately. The
three remaining used providers (M002/009/061) are behavior-only in the shipped table and account for three dispatchable providers absent from the shipped RTINIT table remain outside the generated join.
only sixteen movement steps. Close that tiny tail next.
Once the natural spine and first gameplay loop are trustworthy, broaden in independent tracks: Once the natural spine and first gameplay loop are trustworthy, broaden in independent tracks:

View File

@@ -100,15 +100,17 @@ movement banks consumed by MVRTN/RTN_M providers and ten battle banks consumed b
The generated 172 routine-set records assemble 1,043 movement steps and fourteen battle steps, join The generated 172 routine-set records assemble 1,043 movement steps and fourteen battle steps, join
provider selectors to script names, retain all 29 overwritten cells, and keep the six reserved empty provider selectors to script names, retain all 29 overwritten cells, and keep the six reserved empty
banks visible. Selector-specific schemas now cover banks visible. Selector-specific schemas now cover
RTN_M001/003/004/005/006/007/008/010/011/012/013/014/015/017/051/052: progress-only steps, stage-object slots, all nineteen used providers,
coordinate destinations, enemy/ally and Magic Pillar searches, resource-threshold Healing Feather RTN_M001/002/003/004/005/006/007/008/009/010/011/012/013/014/015/017/051/052/061:
search, cyclic waypoints, faction-traversable terrain, retreat, reachable normal-attack routing, and progress-only steps, randomized roaming, stage-object slots, coordinate destinations, enemy/ally and
immediate element-effective target/action selection, including low-current-HP variants of both attack Magic Pillar searches, resource-threshold Healing Feather search, collectible-treasure seeking, cyclic
paths. The generated join covers 1,027 steps and accounts for all 977 authored movement parameters: waypoints, faction-traversable terrain, retreat, reachable normal-attack routing, immediate
element-effective target/action selection, and immediate allied healing. The generated join covers all
1,043 steps and accounts for all 977 authored movement parameters:
974 semantic inputs plus three M001/M008 cells proven unread by their providers. Thirteen 974 semantic inputs plus three M001/M008 cells proven unread by their providers. Thirteen
unwritten zero defaults are projected separately while the structurally named raw banks remain intact. unwritten zero defaults are projected separately while the structurally named raw banks remain intact.
The remaining three used providers (M002/009/061, sixteen steps total) have no populated parameter The three additionally dispatchable providers which are absent from the shipped table have no
cells and therefore need behavior decoding, not additional column semantics. instantiated steps to join.
### Message/string tables (`*MES`) ### Message/string tables (`*MES`)
`ITMES` (64 KB — item text), `VIMES` (43 KB), `EIMES` (37 KB), `SKMES` (31 KB — skill `ITMES` (64 KB — item text), `VIMES` (43 KB), `EIMES` (37 KB), `SKMES` (31 KB — skill

View File

@@ -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_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_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 source (auto-detects name / numeric / footer / mixed / rules / dispatch / banked 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`; when flat global ranges overlap, a parallel base established by other records wins over a coincidental row-table cell calculation. 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`, joins object type names and available descriptions from OBINIT, and exposes consumer-proven tagged payloads (teleport, treasure, card, initial faction, non-triggering hazard/barrier faction, and OBINIT-gated initial object state), preserves engine-dead type-27 writes under `ignored_payload_fields`, and exposes reinforcement schedules and first-clear-only enemy gates. Rules mode decodes CCINIT's source-ordered class-change predicates and output accumulators, joining EBINIT unit names, SKINIT skill names, titles, named stat bonuses, cost deltas, and applied-state slots. Dispatch mode decodes SCINIT's paired decision-to-packed-scene and authored-chapter arrays, preserving source-order overwrites, resolving SYS4INI script names, and cross-checking chapter tags against decoded SCJUMP paths. Banked mode decodes RTINIT's twenty parallel 1000-by-20 movement/battle routine banks, retains all assignments and overwrites, assembles final per-slot steps, resolves provider selectors to RTN_M/RTN_B scripts, and applies selector-scoped schemas where proven. Current schemas cover RTN_M001/003/004/005/006/007/008/010/011/012/013/014/015/017/051/052, including progress-only, object-slot, coordinate, enemy/ally and Magic Pillar search, Healing Feather, waypoint, faction-terrain, retreat, reachable normal-attack routing, and immediate target/action-selection behavior, with low-current-HP variants of both attack paths. Behavior-only schemas such as M003/M017/M051/M052 publish an empty `parameter_fields` mapping while still joining `provider_behavior`, target selection, action selection, and completion rules. Provider defaults such as M004's unwritten slot 0, M010's zero/HP resource index, and M013's any-foreign-faction filter are projected explicitly and counted separately from populated source cells. Authored cells proven unread by M001/M008 remain under per-step `ignored_movement_parameters` and contribute to top-level `ignored_movement_parameter_count`; they are not silently discarded or assigned invented meanings. Raw provider banks remain intact, and top-level `movement_provider_parameter_schemas` documents the projection. 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 EBINIT/SKINIT for CCINIT, OBINIT for STINIT, `build/callscript-names.json` for RTINIT/SCINIT, `build/scjump-decisions.json` for SCINIT, matching `<MES>.BIN` when supported, and `build/globals.json``build/data/<OUTNAME>.json`, `build/data/README.md` | | `extract_init.py` | Parse a `*INIT` data source (auto-detects name / numeric / footer / mixed / rules / dispatch / banked 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`; when flat global ranges overlap, a parallel base established by other records wins over a coincidental row-table cell calculation. 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`, joins object type names and available descriptions from OBINIT, and exposes consumer-proven tagged payloads (teleport, treasure, card, initial faction, non-triggering hazard/barrier faction, and OBINIT-gated initial object state), preserves engine-dead type-27 writes under `ignored_payload_fields`, and exposes reinforcement schedules and first-clear-only enemy gates. Rules mode decodes CCINIT's source-ordered class-change predicates and output accumulators, joining EBINIT unit names, SKINIT skill names, titles, named stat bonuses, cost deltas, and applied-state slots. Dispatch mode decodes SCINIT's paired decision-to-packed-scene and authored-chapter arrays, preserving source-order overwrites, resolving SYS4INI script names, and cross-checking chapter tags against decoded SCJUMP paths. Banked mode decodes RTINIT's twenty parallel 1000-by-20 movement/battle routine banks, retains all assignments and overwrites, assembles final per-slot steps, resolves provider selectors to RTN_M/RTN_B scripts, and applies selector-scoped schemas where proven. Current schemas cover all nineteen used providers, RTN_M001/002/003/004/005/006/007/008/009/010/011/012/013/014/015/017/051/052/061, including progress-only, randomized roaming, object-slot, coordinate, enemy/ally, treasure and Magic Pillar search, Healing Feather, waypoint, faction-terrain, retreat, reachable normal-attack routing, immediate offensive target/action selection, and immediate allied healing. Parameterless behavior schemas publish an empty `parameter_fields` mapping while still joining `provider_behavior`, target selection, action selection, and completion rules. Provider defaults such as M004's unwritten slot 0, M010's zero/HP resource index, and M013's any-foreign-faction filter are projected explicitly and counted separately from populated source cells. Authored cells proven unread by M001/M008 remain under per-step `ignored_movement_parameters` and contribute to top-level `ignored_movement_parameter_count`; they are not silently discarded or assigned invented meanings. Raw provider banks remain intact, and top-level `movement_provider_parameter_schemas` documents the projection. 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 EBINIT/SKINIT for CCINIT, OBINIT for STINIT, `build/callscript-names.json` for RTINIT/SCINIT, `build/scjump-decisions.json` for SCINIT, matching `<MES>.BIN` when supported, and `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/rules/dispatch/banked table: per-scalar/string/array-cell/footer-array population and value distributions, representative records, and direct opcode/script consumers. Name tables also report message coverage; rule tables summarize covered units, titled and level-independent rules, threshold/slot distributions, and skill awards; dispatch tables summarize assignments, overwrites, script-name resolution, and SCJUMP chapter agreement; banked tables summarize populated/reserved banks, movement/battle steps and providers, selector-specific semantic coverage, and overwrite conflicts. `--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}` | | `init_table_profile.py` | Build the static investigation surface for an extracted name/numeric/mixed/rules/dispatch/banked table: per-scalar/string/array-cell/footer-array population and value distributions, representative records, and direct opcode/script consumers. Name tables also report message coverage; rule tables summarize covered units, titled and level-independent rules, threshold/slot distributions, and skill awards; dispatch tables summarize assignments, overwrites, script-name resolution, and SCJUMP chapter agreement; banked tables summarize populated/reserved banks, movement/battle steps and providers, selector-specific semantic coverage, and overwrite conflicts. `--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, mixed selector-dispatched, CCINIT rule, SCINIT dispatch, and RTINIT banked extraction; MES reconstruction/joins; footer-array accounting and semantic projection; EBINIT/SKINIT/OBINIT definition joins; STINIT object/enemy joins and tagged-payload behavior; overwrite/provider joins; and field/message/rule/dispatch/banked profiling. | run each directly | — | | `test_extract_init.py`, `test_init_table_profile.py` | Regression checks for sparse one-based, mixed selector-dispatched, CCINIT rule, SCINIT dispatch, and RTINIT banked extraction; MES reconstruction/joins; footer-array accounting and semantic projection; EBINIT/SKINIT/OBINIT definition joins; STINIT object/enemy joins and tagged-payload behavior; overwrite/provider joins; and field/message/rule/dispatch/banked 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}` | | `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}` |

View File

@@ -57,9 +57,9 @@
- [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, OBINIT names and available descriptions, 604 reinforcement schedules, and typed initial-faction, teleport, treasure, card-list, non-triggering-faction, and initial-object-state payloads; FIELD's dedicated special-spawn path proves the final three populated type-27 tagged writes are engine-dead, so they remain visible as ignored provenance rather than unresolved semantics. 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.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, OBINIT names and available descriptions, 604 reinforcement schedules, and typed initial-faction, teleport, treasure, card-list, non-triggering-faction, and initial-object-state payloads; FIELD's dedicated special-spawn path proves the final three populated type-27 tagged writes are engine-dead, so they remain visible as ignored provenance rather than unresolved semantics. 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.3a — Extract `CCINIT`'s 71 class-change rules.** Rules mode preserves source-order guards and detects the unit id, minimum level, clear applied-state slot, selected title/level, deployment-cost delta, named fourteen-stat bonuses, awarded SKINIT skills, and state slot set by each rule. EBINIT/SKINIT definition joins and the common global semantic projection coexist with raw addresses. CALCCC/ADDEXP establish the apply/report ABI; EVOLVE explains the two level-independent empty-title Lily rules. The generated profile covers 33 units, 69 titled rules, 30 skill awards, three used promotion slots, and 19 populated output fields. - [x] **2.3a — Extract `CCINIT`'s 71 class-change rules.** Rules mode preserves source-order guards and detects the unit id, minimum level, clear applied-state slot, selected title/level, deployment-cost delta, named fourteen-stat bonuses, awarded SKINIT skills, and state slot set by each rule. EBINIT/SKINIT definition joins and the common global semantic projection coexist with raw addresses. CALCCC/ADDEXP establish the apply/report ABI; EVOLVE explains the two level-independent empty-title Lily rules. The generated profile covers 33 units, 69 titled rules, 30 skill awards, three used promotion slots, and 19 populated output fields.
- [x] **2.3b — Extract `SCINIT`'s scene-dispatch registry.** Dispatch mode recognizes 2,179 alternating writes to two 10,000-cell arrays, preserves all 710 overwritten decision ids, and emits 1,209 final rows. The primary column maps decisions to 135 packed SYS4INI ids, all resolved to numbered SC scripts; the parallel column is authored chapter metadata. All 847 live SCJUMP decisions join to rows and 844 final chapter tags agree with the independently decoded paths; three legacy/stale mismatches remain explicit. - [x] **2.3b — Extract `SCINIT`'s scene-dispatch registry.** Dispatch mode recognizes 2,179 alternating writes to two 10,000-cell arrays, preserves all 710 overwritten decision ids, and emits 1,209 final rows. The primary column maps decisions to 135 packed SYS4INI ids, all resolved to numbered SC scripts; the parallel column is authored chapter metadata. All 847 live SCJUMP decisions join to rows and 844 final chapter tags agree with the independently decoded paths; three legacy/stale mismatches remain explicit.
- [x] **2.3c — Extract `RTINIT`'s routine-step banks.** Banked mode recognizes twenty parallel 1000-by-20 tables and emits 172 sparse routine-set rows with all 3,336 source assignments and 3,307 final cells. Movement banks join 1,043 steps to 19 used RTN_M providers (22 dispatchable); battle banks join fourteen steps to all four RTN_B providers. Activation percentages, progress gates, and required/forbidden story flags are consumer-proven; six empty banks remain explicit. RTN_M001/003/004/005/006/007/008/010/011/012/013/014/015/017/051/052 add selector-specific progress, object-slot, coordinate, enemy/ally and object search, Healing Feather, waypoint, faction-terrain, retreat, normal-attack routing, and target/action selection semantics—including low-current-HP variants of both attack paths—to 1,027 steps. All 977 populated movement-parameter cells are classified: 974 semantic inputs and three M001/M008 cells proven unread; thirteen unwritten defaults are projected separately while the generic raw banks remain intact. - [x] **2.3c — Extract `RTINIT`'s routine-step banks.** Banked mode recognizes twenty parallel 1000-by-20 tables and emits 172 sparse routine-set rows with all 3,336 source assignments and 3,307 final cells. Movement banks join all 1,043 steps to all 19 used RTN_M providers (22 dispatchable); battle banks join fourteen steps to all four RTN_B providers. Activation percentages, progress gates, and required/forbidden story flags are consumer-proven; six empty banks remain explicit. RTN_M001/002/003/004/005/006/007/008/009/010/011/012/013/014/015/017/051/052/061 add selector-specific progress, randomized roaming, object-slot, coordinate, enemy/ally, treasure and object search, Healing Feather, waypoint, faction-terrain, retreat, normal-attack routing, offensive target/action selection, and immediate allied-healing semantics. All 977 populated movement-parameter cells are classified: 974 semantic inputs and three M001/M008 cells proven unread; thirteen unwritten defaults are projected separately while the generic raw banks remain intact.
- [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`. - [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: with RTINIT's populated movement-parameter tail plus M003/M017/M051/M052 attack behavior now closed, decode the tiny behavior-only M002/009/061 tail (sixteen used steps total), fold in remaining `*MES` writers, and label other 2D record tables by their reader scripts. Then Frida to name *which stat* each unresolved field is. Full detail: `docs/name-resolution.md` → "Future step — growing the map". Packed `call-script` ids and SCJUMP decision-to-scene dispatch are resolved; see `docs/name-resolution.md` #1 and `docs/scjump-progression.md`. - [ ] **2.5 — Grow the global-var map (future, incremental).** Static first: with RTINIT's entire used-provider surface now closed at 1,043/1,043 movement steps, fold in remaining `*MES` writers and label other 2D record tables by their reader scripts. Then Frida to name *which stat* each unresolved field is. Full detail: `docs/name-resolution.md` → "Future step — growing the map". Packed `call-script` ids, SCJUMP decision-to-scene dispatch, and the shipped RTINIT movement-provider join are resolved; see `docs/name-resolution.md` #1 and `docs/scjump-progression.md`.
## Phase 3 — Name the unnamed opcodes *(top ~20 BEFORE Phase 4; the rest on demand)* ## Phase 3 — Name the unnamed opcodes *(top ~20 BEFORE Phase 4; the rest on demand)*

View File

@@ -109,6 +109,21 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
"produce movement result state 1 without selecting a destination" "produce movement result state 1 without selecting a destination"
), ),
}, },
2: {
"behavior": "roam_to_random_reachable_tile",
"parameter_fields": {},
"target_selection": (
"build the acting entity's movement-limited reach grid, apply "
"SETMVWORK filtering, and retain map tiles with a positive "
"filtered route score whose movement cost is no greater than "
"current FS; randomize the candidate order and use the first tile "
"for which SETROUTE produces a route"
),
"completion": (
"advance the current step's progress counter and produce movement "
"result state 1 after routing to a randomized reachable tile"
),
},
3: { 3: {
"behavior": "route_toward_reachable_normal_attack_target", "behavior": "route_toward_reachable_normal_attack_target",
"parameter_fields": {}, "parameter_fields": {},
@@ -228,6 +243,21 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
"Magic Pillar exists" "Magic Pillar exists"
), ),
}, },
9: {
"behavior": "approach_collectible_treasure",
"parameter_fields": {},
"target_selection": (
"select the nearest active unopened OBINIT type-7 chest when the "
"acting entity has skill 22 (Unlock), or type-8 treasure without "
"that skill gate; require at least one of the entity's two carried-"
"item slots to be empty or already contain the object's item id, "
"then approach a reachable tile nearest the selected object"
),
"completion": (
"advance the current step's progress counter and produce movement "
"result state 1 after routing toward collectible treasure"
),
},
10: { 10: {
"behavior": "approach_healing_feather", "behavior": "approach_healing_feather",
"parameter_fields": { "parameter_fields": {
@@ -432,6 +462,28 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
"movement route is produced" "movement route is produced"
), ),
}, },
61: {
"behavior": "select_lowest_hp_ally_and_healing_skill",
"parameter_fields": {},
"target_selection": (
"require at least one range-enabled healing skill, scan active "
"same-faction entities inside the ATSEEK range grid, retain only "
"targets tied at the lowest current-HP percentage whose range band "
"enables a healing action, and choose randomly among those ties"
),
"action_selection": (
"among equipped healing skills enabled at the chosen target's "
"range, compare current HP plus each skill's HP recovery against "
"max HP, maximizing the projected result while it remains below "
"max and minimizing it after reaching or exceeding max; store the "
"chosen target entity and healing skill id"
),
"completion": (
"advance the current step's progress counter and produce immediate-"
"support result state 3 when a target/healing-skill pair is "
"selected; no movement route is produced"
),
},
} }
UNIT_STAT_COLUMNS = ( UNIT_STAT_COLUMNS = (

View File

@@ -371,8 +371,8 @@ def test_real_routine_banks() -> None:
and len(meta["used_battle_provider_selectors"]) == 4 and len(meta["used_battle_provider_selectors"]) == 4
and len(meta["record_field_columns"]) == 117, and len(meta["record_field_columns"]) == 117,
"RTINIT assembles every populated movement and battle step") "RTINIT assembles every populated movement and battle step")
check(meta["decoded_movement_provider_count"] == 16 check(meta["decoded_movement_provider_count"] == 19
and meta["decoded_movement_step_count"] == 1027 and meta["decoded_movement_step_count"] == 1043
and meta["decoded_movement_parameter_count"] == 974 and meta["decoded_movement_parameter_count"] == 974
and meta["decoded_movement_defaulted_parameter_count"] == 13 and meta["decoded_movement_defaulted_parameter_count"] == 13
and meta["ignored_movement_parameter_count"] == 3, and meta["ignored_movement_parameter_count"] == 3,
@@ -510,11 +510,29 @@ def test_real_routine_banks() -> None:
== "select_lowest_hp_effective_attack_target_and_action" == "select_lowest_hp_effective_attack_target_and_action"
and "movement_parameter_1" not in provider_52, and "movement_parameter_1" not in provider_52,
"RTINIT joins RTN_M052's low-HP attack-selection behavior") "RTINIT joins RTN_M052's low-HP attack-selection behavior")
undecoded_movement = by_id[2]["movement_steps"][1] provider_2 = by_id[2]["movement_steps"][1]
check(undecoded_movement["movement_provider_selector"] == 2 check(provider_2["movement_provider_selector"] == 2
and "provider_behavior" not in undecoded_movement and provider_2["provider_behavior"]
and "destination_tile_x" not in undecoded_movement, == "roam_to_random_reachable_tile"
"RTINIT does not leak provider-specific meanings onto undecoded selectors") and "movement_parameter_1" not in provider_2,
"RTINIT joins RTN_M002's randomized roaming behavior")
provider_9 = by_id[98]["movement_steps"][1]
check(provider_9["movement_provider_selector"] == 9
and provider_9["provider_behavior"]
== "approach_collectible_treasure"
and "movement_parameter_1" not in provider_9,
"RTINIT joins RTN_M009's collectible-treasure behavior")
provider_61 = by_id[33]["movement_steps"][0]
check(provider_61["movement_provider_selector"] == 61
and provider_61["provider_behavior"]
== "select_lowest_hp_ally_and_healing_skill"
and "movement_parameter_1" not in provider_61,
"RTINIT joins RTN_M061's immediate healing behavior")
check(all(
"provider_behavior" in step
for record in records
for step in record.get("movement_steps", [])
), "RTINIT joins behavior semantics onto every shipped movement step")
check( check(
meta["movement_provider_parameter_schemas"]["11"]["parameter_fields"] meta["movement_provider_parameter_schemas"]["11"]["parameter_fields"]
== { == {

View File

@@ -28,6 +28,14 @@ def test_load_and_lint():
check(entries[0x4e021]["name"] == "entity_runtime_flags" check(entries[0x4e021]["name"] == "entity_runtime_flags"
and entries[0x522ed]["name"] == "entity_faction_ids", and entries[0x522ed]["name"] == "entity_faction_ids",
"entity activity and faction arrays are curated") "entity activity and faction arrays are curated")
check(entries[0x4e693]["name"] == "entity_skill_flags",
"per-entity skill flags are curated")
check(entries[0x53e13]["name"] == "entity_carried_item_ids"
and entries[0x53e77]["name"] == "entity_carried_item_counts",
"per-entity carried-item slots are curated")
check(entries[0xeff77]["name"] == "routine_execution_state"
and entries[0xeff77]["value_domain"] == "0..3",
"movement routine result states are curated")
check(entries[0x56b20]["name"] == "entity_patrol_waypoint_indices", check(entries[0x56b20]["name"] == "entity_patrol_waypoint_indices",
"RTN_M011 waypoint state is curated") "RTN_M011 waypoint state is curated")
check(entries[0xaba96]["name"] == "pathfinding_remaining_route_steps" check(entries[0xaba96]["name"] == "pathfinding_remaining_route_steps"
@@ -36,9 +44,10 @@ def test_load_and_lint():
check(entries[0xbf6fe]["name"] == "pathfinding_filtered_route_scores" check(entries[0xbf6fe]["name"] == "pathfinding_filtered_route_scores"
and entries[0xcc9f4]["name"] == "offensive_action_scope_masks", and entries[0xcc9f4]["name"] == "offensive_action_scope_masks",
"movement target filtering and offensive scope are curated") "movement target filtering and offensive scope are curated")
check(entries[0xb8d86]["name"] == "attack_range_distance_grid" check(entries[0xb8d86]["name"] == "action_range_distance_grid"
and entries[0xcc9f3]["name"] == "offensive_action_max_range", and entries[0xcc9f2]["name"] == "usable_action_min_range"
"attack-range search state is curated") and entries[0xcc9f3]["name"] == "usable_action_max_range",
"action-range search state is curated")
check(entries[0x66713]["name"] == "acting_entity_index" check(entries[0x66713]["name"] == "acting_entity_index"
and entries[0x66714]["name"] == "target_entity_index" and entries[0x66714]["name"] == "target_entity_index"
and entries[0x52289]["name"] == "entity_selected_action_ids", and entries[0x52289]["name"] == "entity_selected_action_ids",
@@ -47,6 +56,8 @@ def test_load_and_lint():
and entries[0xab5ba]["name"] and entries[0xab5ba]["name"]
== "attack_element_effectiveness_percent", == "attack_element_effectiveness_percent",
"AI action-element eligibility state is curated") "AI action-element eligibility state is curated")
check(entries[0xcc9fe]["name"] == "healing_action_scope_masks",
"AI healing-action eligibility state is curated")
check(entries[0x20543]["name"] == "tile_faction_traversal_masks", check(entries[0x20543]["name"] == "tile_faction_traversal_masks",
"faction-specific tile traversal masks are curated") "faction-specific tile traversal masks are curated")
check(entries[0xaba64]["name"] == "stage_object_runtime_flags", check(entries[0xaba64]["name"] == "stage_object_runtime_flags",

View File

@@ -1147,7 +1147,7 @@ name = "routine_execution_state"
category = "choice-output" category = "choice-output"
type = "int" type = "int"
value_domain = "0..3" value_domain = "0..3"
usage = "Shared movement/battle routine result state. MVRTN and BTRTN clear it before scanning steps; RTN_M/RTN_B providers set a nonzero result to stop the scan, and the dispatcher supplies state 1 when no provider produced another result. Exact distinctions between provider-written states 1..3 remain unresolved." usage = "Shared movement/battle routine result state. MVRTN and BTRTN clear it before scanning steps; a nonzero provider result stops the scan. Movement providers use state 1 for ordinary field movement/progress, state 2 for an immediate offensive battle action, and state 3 for an immediate healing/support action; MVRTN supplies state 1 when no provider produced another result."
source = "investigation" source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0xeff75", "0xeff76"] depends_on = ["0xeff75", "0xeff76"]
@@ -1187,6 +1187,17 @@ source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0x4e11b"] depends_on = ["0x4e11b"]
[[global]]
address = "0x4e693"
name = "entity_skill_flags"
category = "data-table"
type = "int[50][300]"
value_domain = "zero absent; nonzero skill state indexed by SKINIT skill id"
usage = "Per-runtime-entity skill-state row. CALCREVISE and CALCSCOPE mark equipped skills, combat/field consumers test specific skill ids, and RTN_M009 requires skill 22 (Unlock) before treating an unopened type-7 chest as a treasure target."
source = "investigation"
confidence = "high"
depends_on = ["0x5212b", "0xa6f86"]
[[global]] [[global]]
address = "0x522ed" address = "0x522ed"
name = "entity_faction_ids" name = "entity_faction_ids"
@@ -1220,6 +1231,30 @@ source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0x5231f"] depends_on = ["0x5231f"]
[[global]]
address = "0x53e13"
name = "entity_carried_item_ids"
category = "data-table"
type = "int[50][2]"
columns = { "0" = "slot_0", "1" = "slot_1" }
value_domain = "zero for empty; otherwise ITINIT item id"
usage = "Two carried/drop-item slots per runtime entity. SETEN initializes slot 0 from the unit's starting equipment item, FIELD fills an empty or matching slot when treasure is collected, and RTN_M009 requires an empty slot or an item-id match before approaching a chest/treasure object."
source = "investigation"
confidence = "high"
depends_on = ["0x53e77", "0x78c0e"]
[[global]]
address = "0x53e77"
name = "entity_carried_item_counts"
category = "data-table"
type = "int[50][2]"
columns = { "0" = "slot_0", "1" = "slot_1" }
value_domain = "0..999 quantity paired with entity_carried_item_ids"
usage = "Quantities for the two per-entity carried/drop-item slots. SETEN seeds a starting item with quantity one; FIELD adds treasure quantities to the matching slot and caps the result at 999."
source = "investigation"
confidence = "high"
depends_on = ["0x53e13"]
[[global]] [[global]]
address = "0x53517" address = "0x53517"
name = "entity_movement_routine_set_ids" name = "entity_movement_routine_set_ids"
@@ -1288,14 +1323,14 @@ depends_on = ["0x4e085"]
[[global]] [[global]]
address = "0xb8d86" address = "0xb8d86"
name = "attack_range_distance_grid" name = "action_range_distance_grid"
category = "data-table" category = "data-table"
type = "int[][27]" type = "int[][27]"
value_domain = "0 outside attack range; otherwise one-based encoded range band" value_domain = "0 outside attack range; otherwise one-based encoded range band"
usage = "ATSEEK's row-major attack-range flood-fill grid. It starts from the acting entity, expands through map-valid doubled-coordinate neighbors up to offensive_action_max_range, and stores 1 for the first range band, 2 for the next, and so on. RTN_M051/052 use the value at an enemy tile to select an offensive_action_scope_masks band." usage = "ATSEEK's row-major action-range flood-fill grid. It starts from the acting entity, expands through map-valid doubled-coordinate neighbors up to usable_action_max_range, and stores 1 for the first range band, 2 for the next, and so on. RTN_M051/052 select offensive targets from it; RTN_M061 selects in-range healing targets."
source = "investigation" source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0x5231f", "0x52351", "0xcc9f3", "0xcc9f4"] depends_on = ["0x5231f", "0x52351", "0xcc9f3", "0xcc9f4", "0xcc9fe"]
[[global]] [[global]]
address = "0x20543" address = "0x20543"
@@ -1347,7 +1382,7 @@ name = "entity_equipped_active_skill_ids"
category = "data-table" category = "data-table"
type = "int[50][4]" type = "int[50][4]"
value_domain = "0 for an empty slot; otherwise SKINIT skill id" value_domain = "0 for an empty slot; otherwise SKINIT skill id"
usage = "Four equipped active-skill slots per runtime entity. CALCSCOPE maps each usable offensive skill into an action bit and range band; RTN_M051 turns the selected nonzero action bit back into its skill id." usage = "Four equipped active-skill slots per runtime entity. CALCSCOPE maps each usable offensive or healing skill into the corresponding action bit and range band; RTN_M051/052 select offensive skills and RTN_M061 selects a healing skill from these slots."
source = "investigation" source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0xa6f86", "0xa71de", "0xa730a", "0xa7436"] depends_on = ["0xa6f86", "0xa71de", "0xa730a", "0xa7436"]
@@ -1358,18 +1393,18 @@ name = "entity_selected_action_ids"
category = "data-table" category = "data-table"
type = "int[50]" type = "int[50]"
value_domain = "0 for normal attack; otherwise selected skill id" value_domain = "0 for normal attack; otherwise selected skill id"
usage = "Per-entity selected battle action. RTN_M051/052 write either zero for the normal attack or an id from entity_equipped_active_skill_ids, then return routine execution state 2 so FIELD enters battle. BTRTN may replace the value through a battle-provider decision." usage = "Per-entity selected action. RTN_M051/052 write either zero for the normal attack or an offensive equipped skill and return routine execution state 2; RTN_M061 writes a healing skill and returns state 3. BTRTN may replace the value through a battle-provider decision."
source = "investigation" source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0x5212b", "0x66713", "0x66714", "0xeff77"] depends_on = ["0x5212b", "0x66713", "0x66714", "0xeff77"]
[[global]] [[global]]
address = "0xcc9f2" address = "0xcc9f2"
name = "offensive_action_min_range" name = "usable_action_min_range"
category = "counter" category = "counter"
type = "int" type = "int"
value_domain = "encoded attack-range band 0..9" value_domain = "encoded action-range band 0..9"
usage = "CALCSCOPE initializes this from the equipped/default attack's minimum range and widens it for usable offensive skills. It is the lower bound used while populating offensive_action_scope_masks." usage = "CALCSCOPE initializes this from the equipped/default attack's minimum range and widens it for usable offensive and healing skills. It is the lower bound shared by the offensive and healing action-scope tables."
source = "investigation" source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0x8d431", "0xa71de"] depends_on = ["0x8d431", "0xa71de"]
@@ -1408,6 +1443,18 @@ source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0x8d431", "0x8d819", "0xa71de", "0xa730a", "0xcc9f2", "0xcc9f3", "0xcca08"] depends_on = ["0x8d431", "0x8d819", "0xa71de", "0xa730a", "0xcc9f2", "0xcc9f3", "0xcca08"]
[[global]]
address = "0xcc9fe"
name = "healing_action_scope_masks"
category = "data-table"
type = "int[10]"
columns = { "0" = "range_0", "1" = "range_1", "2" = "range_2", "3" = "range_3", "4" = "range_4", "5" = "range_5", "6" = "range_6", "7" = "range_7", "8" = "range_8", "9" = "range_9" }
value_domain = "action-availability bitmask: bits 1..4 are equipped healing skills"
usage = "CALCSCOPE clears ten encoded-range cells and sets the equipped-slot bit for each usable category-7 healing skill over its applicable range. RTN_M061 uses the masks to restrict ally targets and to select the range-enabled healing skill."
source = "investigation"
confidence = "high"
depends_on = ["0x5212b", "0xa6f86", "0xa71de", "0xa730a", "0xcc9f2", "0xcc9f3"]
[[global]] [[global]]
address = "0x152616" address = "0x152616"
name = "current_entity_index" name = "current_entity_index"
@@ -2158,11 +2205,11 @@ depends_on = []
[[global]] [[global]]
address = "0xcc9f3" address = "0xcc9f3"
name = "offensive_action_max_range" name = "usable_action_max_range"
category = "counter" category = "counter"
type = "int" type = "int"
value_domain = "encoded attack-range band 0..9" value_domain = "encoded action-range band 0..9"
usage = "CALCSCOPE initializes this from the equipped/default attack's maximum range and widens it for usable offensive skills. ATSEEK bounds its attack-range flood fill with this value; RTN_M051/052 use it as the upper scan bound." usage = "CALCSCOPE initializes this from the equipped/default attack's maximum range and widens it for usable offensive and healing skills. ATSEEK bounds its action-range flood fill with this value; RTN_M051/052 and RTN_M061 use it as their upper scan bound."
source = "investigation" source = "investigation"
confidence = "high" confidence = "high"
depends_on = ["0x8d819", "0xa730a"] depends_on = ["0x8d819", "0xa730a"]
@@ -2178,17 +2225,6 @@ source = "auto-shape"
confidence = "med" confidence = "med"
depends_on = [] depends_on = []
[[global]]
address = "0xeff77"
name = ""
category = "story-flag"
type = "int"
value_domain = "one of {0, 2, 3}"
usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0, 2, 3]; writers=['BTRTN.BIN', 'MVRTN.BIN', 'RTN_B001.BIN', 'RTN_B002.BIN']."
source = "auto-shape"
confidence = "med"
depends_on = []
[[global]] [[global]]
address = "0x152617" address = "0x152617"
name = "" name = ""