Close RTINIT movement provider semantics
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)
|
||||
|
||||
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
|
||||
|
||||
@@ -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. |
|
||||
| `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. |
|
||||
| `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
|
||||
|
||||
@@ -20,8 +21,8 @@
|
||||
|---|---|---|---|---|
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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` | 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. |
|
||||
| `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. |
|
||||
@@ -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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
@@ -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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
@@ -286,7 +291,6 @@
|
||||
| `0xaba4b` | — | low | auto-shape | array |
|
||||
| `0xaba53` | — | low | auto-shape | array |
|
||||
| `0xaba5f` | — | low | auto-shape | array |
|
||||
| `0xcc9fe` | — | low | auto-shape | array |
|
||||
| `0xcca3a` | — | low | auto-shape | array |
|
||||
| `0xccb66` | — | 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']. |
|
||||
| `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']. |
|
||||
| `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']. |
|
||||
| `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']. |
|
||||
@@ -3710,13 +3713,10 @@
|
||||
| `0x7e54` | — | med | auto-shape | record-table[stride 50] |
|
||||
| `0x341ab` | — | med | auto-shape | record-table[stride 53] |
|
||||
| `0x4e3d7` | — | med | auto-shape | record-table[stride 14] |
|
||||
| `0x4e693` | — | med | auto-shape | record-table[stride 300] |
|
||||
| `0x52383` | — | med | auto-shape | record-table[stride 30] |
|
||||
| `0x5295f` | — | med | auto-shape | record-table[stride 30] |
|
||||
| `0x52f3b` | — | med | auto-shape | record-table[stride 30] |
|
||||
| `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? |
|
||||
| `0x53ef5` | — | low | auto-shape | index/counter? |
|
||||
| `0x53ef7` | — | med | auto-shape | record-table[stride 8] |
|
||||
|
||||
@@ -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.
|
||||
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
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
|
||||
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;
|
||||
@@ -547,17 +567,19 @@ by M006/007/015.
|
||||
`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
|
||||
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
|
||||
populated parameter cells, so their remaining work is behavior decoding rather than column semantics.
|
||||
three explicit residue cells. All nineteen providers used by the shipped table now have behavior
|
||||
schemas; the three additionally dispatchable but unused providers remain outside the generated join.
|
||||
The supporting runtime joins are now curated too:
|
||||
`entity_runtime_flags`,
|
||||
`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`,
|
||||
`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
|
||||
`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.
|
||||
|
||||
### 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,
|
||||
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
|
||||
banks are structurally decoded with every populated movement-parameter cell classified and 1,027 of
|
||||
1,043 movement steps joined to provider behavior. Next close the tiny behavior-only RTN_M002/009/061
|
||||
tail; never assign one universal meaning to a parameter bank whose meaning varies by provider
|
||||
selector.
|
||||
banks are structurally decoded with every populated movement-parameter cell classified and all 1,043
|
||||
shipped movement steps joined to provider behavior. With RTINIT's used-provider surface closed,
|
||||
resume the remaining `*MES` writers and other reader-proven 2D tables; never assign one universal
|
||||
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, …)
|
||||
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
|
||||
|
||||
@@ -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
|
||||
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,
|
||||
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
|
||||
selection, cyclic waypoints, faction-traversable terrain, retreat, normal-attack routing, and immediate
|
||||
element-effective target/action selection, including low-current-HP variants of both attack paths. This
|
||||
covers 1,027 steps and classifies every one of the 977
|
||||
selection, collectible-treasure seeking, cyclic waypoints, faction-traversable terrain, retreat,
|
||||
normal-attack routing, immediate element-effective target/action selection, and immediate allied
|
||||
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
|
||||
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
|
||||
only sixteen movement steps. Close that tiny tail next.
|
||||
three dispatchable providers absent from the shipped RTINIT table remain outside the generated join.
|
||||
|
||||
Once the natural spine and first gameplay loop are trustworthy, broaden in independent tracks:
|
||||
|
||||
|
||||
@@ -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
|
||||
provider selectors to script names, retain all 29 overwritten cells, and keep the six reserved empty
|
||||
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,
|
||||
coordinate destinations, enemy/ally and Magic Pillar searches, resource-threshold Healing Feather
|
||||
search, cyclic waypoints, faction-traversable terrain, retreat, reachable normal-attack routing, and
|
||||
immediate element-effective target/action selection, including low-current-HP variants of both attack
|
||||
paths. The generated join covers 1,027 steps and accounts for all 977 authored movement parameters:
|
||||
all nineteen used providers,
|
||||
RTN_M001/002/003/004/005/006/007/008/009/010/011/012/013/014/015/017/051/052/061:
|
||||
progress-only steps, randomized roaming, stage-object slots, coordinate destinations, enemy/ally and
|
||||
Magic Pillar searches, resource-threshold Healing Feather search, collectible-treasure seeking, cyclic
|
||||
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
|
||||
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
|
||||
cells and therefore need behavior decoding, not additional column semantics.
|
||||
The three additionally dispatchable providers which are absent from the shipped table have no
|
||||
instantiated steps to join.
|
||||
|
||||
### 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 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}` |
|
||||
| `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}` |
|
||||
|
||||
@@ -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.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.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`.
|
||||
- [ ] **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)*
|
||||
|
||||
|
||||
@@ -109,6 +109,21 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
|
||||
"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: {
|
||||
"behavior": "route_toward_reachable_normal_attack_target",
|
||||
"parameter_fields": {},
|
||||
@@ -228,6 +243,21 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
|
||||
"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: {
|
||||
"behavior": "approach_healing_feather",
|
||||
"parameter_fields": {
|
||||
@@ -432,6 +462,28 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
|
||||
"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 = (
|
||||
|
||||
@@ -371,8 +371,8 @@ def test_real_routine_banks() -> None:
|
||||
and len(meta["used_battle_provider_selectors"]) == 4
|
||||
and len(meta["record_field_columns"]) == 117,
|
||||
"RTINIT assembles every populated movement and battle step")
|
||||
check(meta["decoded_movement_provider_count"] == 16
|
||||
and meta["decoded_movement_step_count"] == 1027
|
||||
check(meta["decoded_movement_provider_count"] == 19
|
||||
and meta["decoded_movement_step_count"] == 1043
|
||||
and meta["decoded_movement_parameter_count"] == 974
|
||||
and meta["decoded_movement_defaulted_parameter_count"] == 13
|
||||
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"
|
||||
and "movement_parameter_1" not in provider_52,
|
||||
"RTINIT joins RTN_M052's low-HP attack-selection behavior")
|
||||
undecoded_movement = by_id[2]["movement_steps"][1]
|
||||
check(undecoded_movement["movement_provider_selector"] == 2
|
||||
and "provider_behavior" not in undecoded_movement
|
||||
and "destination_tile_x" not in undecoded_movement,
|
||||
"RTINIT does not leak provider-specific meanings onto undecoded selectors")
|
||||
provider_2 = by_id[2]["movement_steps"][1]
|
||||
check(provider_2["movement_provider_selector"] == 2
|
||||
and provider_2["provider_behavior"]
|
||||
== "roam_to_random_reachable_tile"
|
||||
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(
|
||||
meta["movement_provider_parameter_schemas"]["11"]["parameter_fields"]
|
||||
== {
|
||||
|
||||
@@ -28,6 +28,14 @@ def test_load_and_lint():
|
||||
check(entries[0x4e021]["name"] == "entity_runtime_flags"
|
||||
and entries[0x522ed]["name"] == "entity_faction_ids",
|
||||
"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",
|
||||
"RTN_M011 waypoint state is curated")
|
||||
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"
|
||||
and entries[0xcc9f4]["name"] == "offensive_action_scope_masks",
|
||||
"movement target filtering and offensive scope are curated")
|
||||
check(entries[0xb8d86]["name"] == "attack_range_distance_grid"
|
||||
and entries[0xcc9f3]["name"] == "offensive_action_max_range",
|
||||
"attack-range search state is curated")
|
||||
check(entries[0xb8d86]["name"] == "action_range_distance_grid"
|
||||
and entries[0xcc9f2]["name"] == "usable_action_min_range"
|
||||
and entries[0xcc9f3]["name"] == "usable_action_max_range",
|
||||
"action-range search state is curated")
|
||||
check(entries[0x66713]["name"] == "acting_entity_index"
|
||||
and entries[0x66714]["name"] == "target_entity_index"
|
||||
and entries[0x52289]["name"] == "entity_selected_action_ids",
|
||||
@@ -47,6 +56,8 @@ def test_load_and_lint():
|
||||
and entries[0xab5ba]["name"]
|
||||
== "attack_element_effectiveness_percent",
|
||||
"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",
|
||||
"faction-specific tile traversal masks are curated")
|
||||
check(entries[0xaba64]["name"] == "stage_object_runtime_flags",
|
||||
|
||||
@@ -1147,7 +1147,7 @@ name = "routine_execution_state"
|
||||
category = "choice-output"
|
||||
type = "int"
|
||||
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"
|
||||
confidence = "high"
|
||||
depends_on = ["0xeff75", "0xeff76"]
|
||||
@@ -1187,6 +1187,17 @@ source = "investigation"
|
||||
confidence = "high"
|
||||
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]]
|
||||
address = "0x522ed"
|
||||
name = "entity_faction_ids"
|
||||
@@ -1220,6 +1231,30 @@ source = "investigation"
|
||||
confidence = "high"
|
||||
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]]
|
||||
address = "0x53517"
|
||||
name = "entity_movement_routine_set_ids"
|
||||
@@ -1288,14 +1323,14 @@ depends_on = ["0x4e085"]
|
||||
|
||||
[[global]]
|
||||
address = "0xb8d86"
|
||||
name = "attack_range_distance_grid"
|
||||
name = "action_range_distance_grid"
|
||||
category = "data-table"
|
||||
type = "int[][27]"
|
||||
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"
|
||||
confidence = "high"
|
||||
depends_on = ["0x5231f", "0x52351", "0xcc9f3", "0xcc9f4"]
|
||||
depends_on = ["0x5231f", "0x52351", "0xcc9f3", "0xcc9f4", "0xcc9fe"]
|
||||
|
||||
[[global]]
|
||||
address = "0x20543"
|
||||
@@ -1347,7 +1382,7 @@ name = "entity_equipped_active_skill_ids"
|
||||
category = "data-table"
|
||||
type = "int[50][4]"
|
||||
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"
|
||||
confidence = "high"
|
||||
depends_on = ["0xa6f86", "0xa71de", "0xa730a", "0xa7436"]
|
||||
@@ -1358,18 +1393,18 @@ name = "entity_selected_action_ids"
|
||||
category = "data-table"
|
||||
type = "int[50]"
|
||||
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"
|
||||
confidence = "high"
|
||||
depends_on = ["0x5212b", "0x66713", "0x66714", "0xeff77"]
|
||||
|
||||
[[global]]
|
||||
address = "0xcc9f2"
|
||||
name = "offensive_action_min_range"
|
||||
name = "usable_action_min_range"
|
||||
category = "counter"
|
||||
type = "int"
|
||||
value_domain = "encoded attack-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."
|
||||
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 and healing skills. It is the lower bound shared by the offensive and healing action-scope tables."
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0x8d431", "0xa71de"]
|
||||
@@ -1408,6 +1443,18 @@ source = "investigation"
|
||||
confidence = "high"
|
||||
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]]
|
||||
address = "0x152616"
|
||||
name = "current_entity_index"
|
||||
@@ -2158,11 +2205,11 @@ depends_on = []
|
||||
|
||||
[[global]]
|
||||
address = "0xcc9f3"
|
||||
name = "offensive_action_max_range"
|
||||
name = "usable_action_max_range"
|
||||
category = "counter"
|
||||
type = "int"
|
||||
value_domain = "encoded attack-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."
|
||||
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 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"
|
||||
confidence = "high"
|
||||
depends_on = ["0x8d819", "0xa730a"]
|
||||
@@ -2178,17 +2225,6 @@ source = "auto-shape"
|
||||
confidence = "med"
|
||||
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]]
|
||||
address = "0x152617"
|
||||
name = ""
|
||||
|
||||
Reference in New Issue
Block a user