Decode RTINIT movement providers 7 10 and 12
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)
|
||||
|
||||
5037 globals (237 curated, 4800 auto shape-inferred). Source of truth: `vm-map/globals.toml`.
|
||||
5038 globals (241 curated, 4797 auto shape-inferred). Source of truth: `vm-map/globals.toml`.
|
||||
|
||||
## choice-output
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
| `0xa68` | — | med | auto-shape | TODO: confirm. Branch-read in 11 scenes / 12 scripts; compared against [0, 1]; writers=['SC0740.BIN', 'SC1580.BIN', 'SC1590.BIN']. |
|
||||
| `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 keeps the caller-supplied origin and broad search allowance; nonzero modes replace them with the current entity tile and movement+1. 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. |
|
||||
|
||||
## counter
|
||||
|
||||
@@ -37,8 +38,10 @@
|
||||
| `0x74e8` | unit_skill_ids | high | investigation | Persistent four-skill row for each playable unit. CALCCC copies positive class_change_skill_awards into the first three slots after a promotion; ADDEXP compares the before/after row to report learned or replaced skills. Columns: 0=skill_slot_1, 1=skill_slot_2, 2=skill_slot_3, 3=skill_slot_4. |
|
||||
| `0x7684` | stage_clear_state | high | investigation | Persistent per-stage completion state indexed by stage id. STAGECLEAR sets the current stage cell to 1, while FORT, SELSTAGE, and FIELD use zero versus one to distinguish an uncleared mission from a cleared replay. |
|
||||
| `0x141a4` | stage_object_runtime_state | high | investigation | Per-stage, per-object-slot runtime state. FIELD initializes mode-1 objects from STINIT's first tagged payload on a fresh stage and updates capturable-object ownership; DRAWOBJ uses it as the vertical sprite-row index. Other consumers interpret it by object type. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
@@ -123,6 +126,7 @@
|
||||
| `0xaaa1e` | skill_battle_animation_id | high | investigation | Populated for 101 combat skills. BTL and CALCDMG place this value in the battle-animation selector before calling BTANINIT; most skills reuse their own id, while related skills deliberately share an animation and passive reactions use ids 801..808. |
|
||||
| `0xaab4a` | skill_handler_script_id | high | investigation | SKINIT field for all 131 skills. CHMENU and INFOIT look it up and pass it directly to call-script; packed id 0x31ca resolves to SKMES.BIN, the shared per-skill text/behavior dispatcher. |
|
||||
| `0xab8c7` | class_change_rule_script_ids | high | investigation | CALCCC iterates these 32 cells and call-scripts every positive entry to evaluate class-change providers. CCINIT is the shipped rule program decoded into build/data/CCINIT.json. |
|
||||
| `0xaba96` | pathfinding_remaining_route_steps | high | investigation | MVSEEK's row-major reachability grid. The origin receives movement+1 and each traversed edge decrements the value, so a larger positive value is nearer to the origin. RTN_M007 uses the difference from the origin value as its ally-search radius; RTN_M010 ranks Healing Feathers by the negated value to choose the nearest reachable object. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
@@ -157,8 +161,8 @@
|
||||
| `0xe7a0f` | stage_enemy_forbidden_story_flags | high | investigation | Five negative prerequisites per stage enemy. FIELD subtracts one from every populated id and suppresses the spawn when the corresponding story_event_flags cell equals 1. Columns: 0=forbidden_flag_1, 1=forbidden_flag_2, 2=forbidden_flag_3, 3=forbidden_flag_4, 4=forbidden_flag_5. |
|
||||
| `0xeff78` | movement_routine_provider_selectors | high | investigation | RTINIT movement bank 0. MVRTN indexes it by current_routine_set_id and routine_step_index, resolves the selector through its RTN_M001..018/051..053/061 provider table, and call-scripts the selected movement routine. |
|
||||
| `0xf4d98` | movement_routine_activation_percents | high | investigation | RTINIT movement bank 1. After all other step gates pass, MVRTN executes the provider only when random-modulo-100 is below this value. |
|
||||
| `0xf9bb8` | movement_routine_parameter_1 | high | investigation | RTINIT movement bank 2. Its meaning is tagged by movement_routine_provider_selectors: RTN_M005 and RTN_M011 use it as destination_tile_x; other consuming providers remain provider-specific. |
|
||||
| `0xfe9d8` | movement_routine_parameter_2 | high | investigation | RTINIT movement bank 3. RTN_M005 and RTN_M011 use it as destination_tile_y; RTN_M007/010/012 meanings remain provider-specific. |
|
||||
| `0xf9bb8` | movement_routine_parameter_1 | high | investigation | RTINIT movement bank 2. Its meaning is tagged by movement_routine_provider_selectors: RTN_M005/012 use destination_tile_x, RTN_M007 uses maximum_target_route_steps, RTN_M010 uses resource_index (0=HP, 1=SP, 2=FS; shipped cells are unwritten/default zero), and RTN_M011 uses destination_tile_x. |
|
||||
| `0xfe9d8` | movement_routine_parameter_2 | high | investigation | RTINIT movement bank 3. Its meaning is tagged by movement_routine_provider_selectors: RTN_M005/011/012 use destination_tile_y, RTN_M007 uses maximum_target_hp_percent, and RTN_M010 uses maximum_resource_percent. |
|
||||
| `0x1037f8` | movement_routine_parameter_3 | high | investigation | RTINIT movement bank 4. RTN_M011 uses it as a one-based waypoint_ordinal, executing only the step whose ordinal matches the entity's current zero-based waypoint index. |
|
||||
| `0x108618` | movement_routine_parameter_4 | high | investigation | RTINIT movement bank 5. RTN_M011 uses a nonzero value as path_cost_limit_override; zero or an unwritten cell falls back to the entity's current FS. |
|
||||
| `0x112258` | movement_routine_minimum_progress_counts | high | investigation | RTINIT movement bank 7. MVRTN requires the current entity's matching movement-step progress counter to reach this value; movement providers increment those counters as their steps execute. |
|
||||
@@ -219,14 +223,12 @@
|
||||
| `0x2053f` | — | low | auto-shape | array |
|
||||
| `0x4dfbd` | — | low | auto-shape | array |
|
||||
| `0x4dfef` | — | low | auto-shape | array |
|
||||
| `0x4e021` | — | low | auto-shape | array |
|
||||
| `0x4e053` | — | low | auto-shape | array |
|
||||
| `0x521f3` | — | low | auto-shape | array |
|
||||
| `0x52225` | — | low | auto-shape | array |
|
||||
| `0x52257` | — | low | auto-shape | array |
|
||||
| `0x52289` | — | low | auto-shape | array |
|
||||
| `0x522bb` | — | low | auto-shape | array |
|
||||
| `0x522ed` | — | low | auto-shape | array |
|
||||
| `0x53ede` | — | low | auto-shape | array |
|
||||
| `0x55e3b` | — | low | auto-shape | array |
|
||||
| `0x56223` | — | low | auto-shape | array |
|
||||
@@ -5033,7 +5035,6 @@
|
||||
| `0xab6fa` | — | med | auto-shape | record-table[stride 11] |
|
||||
| `0xab7d6` | — | med | auto-shape | record-table[stride 11] |
|
||||
| `0xab8b2` | — | med | auto-shape | record-table[stride 7] |
|
||||
| `0xaba96` | — | med | auto-shape | record-table[stride 27] |
|
||||
| `0xb8d86` | — | med | auto-shape | record-table[stride 27] |
|
||||
| `0xbf6fe` | — | med | auto-shape | record-table[stride 27] |
|
||||
| `0xc6077` | — | med | auto-shape | record-table[stride 27] |
|
||||
|
||||
@@ -444,22 +444,40 @@ keeps its raw `base/20/slot` fields and complete offset-tagged assignment histor
|
||||
empty reserved banks. Structural and consumer-proven meanings live in `vm-map/globals.toml`; the generic
|
||||
parameter names remain as raw provenance while each RTN_M/RTN_B consumer proves its tagged schema.
|
||||
|
||||
The first provider-specific join covers RTN_M005 and RTN_M011, 252 movement steps and 685 populated
|
||||
parameters in total. Both providers read banks 2/3 as `destination_tile_x` / `destination_tile_y` and
|
||||
approach that exact map tile, incrementing the current step's progress counter after arrival. Their
|
||||
alternate completion test recognizes a type-6 stage object at the authored destination and also accepts
|
||||
the object's linked exit tile.
|
||||
The provider-specific join now covers RTN_M005/007/010/011/012: 292 movement steps, 758 populated
|
||||
parameters, and seven explicit zero defaults. RTN_M005/011/012 read banks 2/3 as
|
||||
`destination_tile_x` / `destination_tile_y` and approach that exact map tile, incrementing the current
|
||||
step's progress counter after arrival. Their alternate completion test recognizes a type-6 stage object
|
||||
at the authored destination and also accepts the object's linked exit tile. RTN_M012 is byte-for-byte
|
||||
equivalent to M005 except for its MVSEEK mode: mode 2 masks the doubled-coordinate terrain cell of every
|
||||
active foreign-faction entity before the flood fill, so the generated behavior distinguishes this
|
||||
foreign-entity-avoiding route from ordinary M005.
|
||||
|
||||
RTN_M011 is the cyclic-waypoint form. Bank 4 is a one-based `waypoint_ordinal`; only the step whose
|
||||
ordinal minus one matches `entity_patrol_waypoint_indices[current_entity]` executes. Arrival advances
|
||||
that runtime index modulo the largest RTN_M011 ordinal in the selected routine set. Bank 5 is an optional
|
||||
`path_cost_limit_override`; zero or an unwritten cell falls back to the entity's current FS.
|
||||
|
||||
RTN_M007 is the injured-ally form. Bank 2 is `maximum_target_route_steps` (authored as 5 or 10) and bank
|
||||
3 is an inclusive `maximum_target_hp_percent` (50, 70, or 80). It runs MVSEEK from the acting entity,
|
||||
keeps active non-self entities of the same faction below the HP cutoff and within the route-step radius,
|
||||
selects randomly among the nearest tied allies, then chooses a reachable movement tile nearest that
|
||||
ally. Producing a valid destination increments the step's progress counter.
|
||||
|
||||
RTN_M010 is the Healing Feather form. Bank 2 is a `resource_index` into current HP/SP/FS and their
|
||||
max-stat columns; all seven shipped cells are unwritten, so the generated join explicitly projects the
|
||||
zero/HP default without fabricating a raw assignment. Bank 3 is an inclusive
|
||||
`maximum_resource_percent`, authored as 30 or 50. When the selected current/max percentage passes, the
|
||||
provider chooses the nearest active OBINIT type 15 or 16 object (`治癒の羽`, full status recovery, or its
|
||||
single-use red variant) and approaches a reachable tile nearest it.
|
||||
|
||||
`movement_steps` now carry these selector-scoped semantic fields beside the original
|
||||
`movement_parameter_1..4`, and top-level `movement_provider_parameter_schemas` records the reusable
|
||||
mapping and zero/unwritten behavior. No meaning is projected onto other providers. The supporting
|
||||
runtime joins are now curated too: `entity_tile_x`/`entity_tile_y`, the fourteen-column
|
||||
`entity_effective_stats`, current HP/SP/FS, `pathfinding_movement_costs`, and the per-entity patrol
|
||||
waypoint index.
|
||||
mapping, target-selection rules, and zero/unwritten behavior. No meaning is projected onto other
|
||||
providers. 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, `movement_search_mode`, `pathfinding_remaining_route_steps`,
|
||||
`pathfinding_movement_costs`, and the per-entity patrol waypoint index.
|
||||
|
||||
### The curated registry — `vm-map/globals.toml` (2026-07-07)
|
||||
|
||||
|
||||
@@ -787,10 +787,12 @@ the shared `semantic_fields` join. SCINIT is now the sixth shape: 2,179 paired a
|
||||
resolved and the full overwrite history retained. RTINIT is now the seventh shape: its twenty parallel
|
||||
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 the two high-density movement providers 5 and 11: both join
|
||||
destination X/Y, while provider 11 adds a cyclic waypoint ordinal and optional path-cost limit. This
|
||||
projects 685 populated parameters across 252 steps without assigning those meanings to other providers
|
||||
that share the same raw banks. Continue the remaining parameterized RTN_M consumers by evidence density.
|
||||
history. Provider-tagged decoding now covers movement providers 5, 7, 10, 11, and 12: coordinate
|
||||
destinations (including M012's foreign-entity route mask), injured-ally selection by route radius and HP
|
||||
cutoff, Healing Feather selection gated by current resource percentage, and cyclic waypoints with an
|
||||
optional path-cost limit. This projects 758 populated parameters plus seven explicit zero/HP defaults
|
||||
across 292 steps without assigning those meanings to other providers that share the same raw banks.
|
||||
Continue the remaining parameterized RTN_M consumers by evidence density.
|
||||
|
||||
Once the natural spine and first gameplay loop are trustworthy, broaden in independent tracks:
|
||||
|
||||
|
||||
@@ -99,10 +99,10 @@ RTINIT is a seventh banked shape. Its 3,336 writes populate twenty parallel `100
|
||||
movement banks consumed by MVRTN/RTN_M providers and ten battle banks consumed by BTRTN/RTN_B providers.
|
||||
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. RTN_M005 and RTN_M011 now provide the first selector-specific parameter schemas: both
|
||||
decode destination X/Y, while RTN_M011 adds a one-based cyclic waypoint ordinal and optional path-cost
|
||||
limit. The generated join covers 252 steps and 685 populated parameters while retaining the structurally
|
||||
named raw banks for every provider.
|
||||
banks visible. Selector-specific parameter schemas now cover RTN_M005/012 coordinate destinations,
|
||||
RTN_M007 injured-ally search, RTN_M010 resource-threshold Healing Feather search, and RTN_M011 cyclic
|
||||
waypoints with an optional path-cost limit. The generated join covers 292 steps, 758 populated parameters,
|
||||
and seven explicit zero/HP defaults while retaining the structurally named raw banks for every provider.
|
||||
|
||||
### 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 parameter schemas where proven (currently RTN_M005/011 destination and cyclic-waypoint fields). 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 parameter schemas where proven. Current schemas cover RTN_M005/012 coordinate destinations, RTN_M007 injured-ally search, RTN_M010 resource-threshold Healing Feather search, and RTN_M011 cyclic waypoints; provider defaults such as M010's unwritten zero/HP resource index are projected explicitly and counted separately from populated source cells. 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_M005/011 add selector-specific destination/waypoint semantics to 252 steps and 685 populated parameters while retaining the generic raw banks.
|
||||
- [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_M005/007/010/011/012 add selector-specific coordinate, injured-ally, Healing Feather, and waypoint semantics to 292 steps, 758 populated parameters, and seven explicit defaults while retaining the generic raw banks.
|
||||
- [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: continue RTINIT's provider-tagged parameters after the completed RTN_M005/011 slice, 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: continue RTINIT's provider-tagged parameters after the completed RTN_M005/007/010/011/012 slices, 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`.
|
||||
|
||||
## Phase 3 — Name the unnamed opcodes *(top ~20 BEFORE Phase 4; the rest on demand)*
|
||||
|
||||
|
||||
@@ -102,6 +102,62 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
|
||||
"destination tile (or its linked type-6 stage-object exit tile)"
|
||||
),
|
||||
},
|
||||
7: {
|
||||
"behavior": "approach_injured_ally",
|
||||
"parameter_fields": {
|
||||
"movement_parameter_1": "maximum_target_route_steps",
|
||||
"movement_parameter_2": "maximum_target_hp_percent",
|
||||
},
|
||||
"parameter_notes": {
|
||||
"maximum_target_route_steps": (
|
||||
"maximum flood-fill step distance from the acting entity; "
|
||||
"shipped values are 5 or 10"
|
||||
),
|
||||
"maximum_target_hp_percent": (
|
||||
"inclusive current-HP percentage cutoff; shipped values are "
|
||||
"50, 70, or 80"
|
||||
),
|
||||
},
|
||||
"target_selection": (
|
||||
"nearest active non-self entity of the same faction whose current "
|
||||
"HP percentage is at or below the cutoff; choose randomly among "
|
||||
"ties, then approach a reachable tile nearest that ally"
|
||||
),
|
||||
"completion": (
|
||||
"advance the current step's progress counter after producing a "
|
||||
"valid movement destination toward the selected ally"
|
||||
),
|
||||
},
|
||||
10: {
|
||||
"behavior": "approach_healing_feather",
|
||||
"parameter_fields": {
|
||||
"movement_parameter_1": "resource_index",
|
||||
"movement_parameter_2": "maximum_resource_percent",
|
||||
},
|
||||
"parameter_defaults": {
|
||||
"movement_parameter_1": 0,
|
||||
},
|
||||
"parameter_notes": {
|
||||
"resource_index": (
|
||||
"0=HP, 1=SP, 2=FS; all shipped RTINIT cells are unwritten and "
|
||||
"therefore use the zero/HP default"
|
||||
),
|
||||
"maximum_resource_percent": (
|
||||
"inclusive current/max percentage cutoff; shipped values are "
|
||||
"30 or 50"
|
||||
),
|
||||
},
|
||||
"target_selection": (
|
||||
"nearest active stage object of OBINIT type 15 (Healing Feather) "
|
||||
"or 16 (single-use red Healing Feather), then approach a reachable "
|
||||
"tile nearest that object"
|
||||
),
|
||||
"completion": (
|
||||
"produce a movement result only when the selected resource's "
|
||||
"maximum is nonzero, its current percentage is at or below the "
|
||||
"cutoff, and a reachable Healing Feather exists"
|
||||
),
|
||||
},
|
||||
11: {
|
||||
"behavior": "cycle_destination_waypoints",
|
||||
"parameter_fields": {
|
||||
@@ -125,6 +181,22 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
|
||||
"linked type-6 stage-object exit tile)"
|
||||
),
|
||||
},
|
||||
12: {
|
||||
"behavior": "approach_destination_tile_avoiding_foreign_entities",
|
||||
"parameter_fields": {
|
||||
"movement_parameter_1": "destination_tile_x",
|
||||
"movement_parameter_2": "destination_tile_y",
|
||||
},
|
||||
"routing": (
|
||||
"same destination and completion logic as RTN_M005, but MVSEEK "
|
||||
"mode 2 masks the doubled-coordinate terrain cells occupied by "
|
||||
"active entities of another faction before its flood fill"
|
||||
),
|
||||
"completion": (
|
||||
"advance the current step's progress counter after reaching the "
|
||||
"destination tile (or its linked type-6 stage-object exit tile)"
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
UNIT_STAT_COLUMNS = (
|
||||
@@ -937,19 +1009,24 @@ def _movement_provider_names(names: dict[int, str]) -> dict[int, str]:
|
||||
return providers
|
||||
|
||||
|
||||
def _join_movement_provider_semantics(step: dict) -> int:
|
||||
def _join_movement_provider_semantics(step: dict) -> tuple[int, int]:
|
||||
"""Add selector-specific RTN_M semantics while retaining every raw bank."""
|
||||
selector = step.get("movement_provider_selector")
|
||||
schema = MOVEMENT_PROVIDER_PARAMETER_SCHEMAS.get(selector)
|
||||
if schema is None:
|
||||
return 0
|
||||
return 0, 0
|
||||
step["provider_behavior"] = schema["behavior"]
|
||||
joined = 0
|
||||
defaulted = 0
|
||||
defaults = schema.get("parameter_defaults", {})
|
||||
for raw_field, semantic_field in schema["parameter_fields"].items():
|
||||
if raw_field in step:
|
||||
step[semantic_field] = step[raw_field]
|
||||
joined += 1
|
||||
return joined
|
||||
elif raw_field in defaults:
|
||||
step[semantic_field] = defaults[raw_field]
|
||||
defaulted += 1
|
||||
return joined, defaulted
|
||||
|
||||
|
||||
def extract_banked(scr):
|
||||
@@ -969,6 +1046,7 @@ def extract_banked(scr):
|
||||
bank_cells: dict[int, set[tuple[int, int]]] = collections.defaultdict(set)
|
||||
decoded_movement_step_count = 0
|
||||
decoded_movement_parameter_count = 0
|
||||
decoded_movement_defaulted_parameter_count = 0
|
||||
|
||||
for offset, destination, value, bank_index, record_id, slot in writes:
|
||||
bank_base = ROUTINE_BANK_ROOT + bank_index * ROUTINE_BANK_SPAN
|
||||
@@ -1016,10 +1094,16 @@ def extract_banked(scr):
|
||||
if selector is not None else {}
|
||||
),
|
||||
}
|
||||
joined_parameter_count = _join_movement_provider_semantics(step)
|
||||
(
|
||||
joined_parameter_count,
|
||||
defaulted_parameter_count,
|
||||
) = _join_movement_provider_semantics(step)
|
||||
if selector in MOVEMENT_PROVIDER_PARAMETER_SCHEMAS:
|
||||
decoded_movement_step_count += 1
|
||||
decoded_movement_parameter_count += joined_parameter_count
|
||||
decoded_movement_defaulted_parameter_count += (
|
||||
defaulted_parameter_count
|
||||
)
|
||||
movement_steps.append(step)
|
||||
|
||||
battle = {
|
||||
@@ -1122,6 +1206,9 @@ def extract_banked(scr):
|
||||
),
|
||||
"decoded_movement_step_count": decoded_movement_step_count,
|
||||
"decoded_movement_parameter_count": decoded_movement_parameter_count,
|
||||
"decoded_movement_defaulted_parameter_count": (
|
||||
decoded_movement_defaulted_parameter_count
|
||||
),
|
||||
"battle_provider_scripts": {
|
||||
str(selector): name
|
||||
for selector, name in sorted(battle_providers.items())
|
||||
|
||||
@@ -245,6 +245,9 @@ def profile_banked(data: dict) -> dict:
|
||||
"decoded_movement_parameter_count": data.get(
|
||||
"decoded_movement_parameter_count", 0
|
||||
),
|
||||
"decoded_movement_defaulted_parameter_count": data.get(
|
||||
"decoded_movement_defaulted_parameter_count", 0
|
||||
),
|
||||
"available_battle_provider_count": len(
|
||||
data.get("battle_provider_scripts", {})
|
||||
),
|
||||
@@ -402,7 +405,10 @@ def render_markdown(data: dict, rows: list[dict], limit: int) -> str:
|
||||
f"({banked_profile['available_movement_provider_count']} dispatchable)",
|
||||
f"- selector-specific movement semantics: "
|
||||
f"{banked_profile['decoded_movement_step_count']} steps, "
|
||||
f"{banked_profile['decoded_movement_parameter_count']} parameters "
|
||||
f"{banked_profile['decoded_movement_parameter_count']} populated "
|
||||
f"parameters + "
|
||||
f"{banked_profile['decoded_movement_defaulted_parameter_count']} "
|
||||
f"explicit defaults "
|
||||
f"across {banked_profile['decoded_movement_provider_count']} providers",
|
||||
f"- joined battle steps/used providers: "
|
||||
f"{banked_profile['battle_step_count']}/"
|
||||
|
||||
@@ -371,9 +371,10 @@ 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"] == 2
|
||||
and meta["decoded_movement_step_count"] == 252
|
||||
and meta["decoded_movement_parameter_count"] == 685,
|
||||
check(meta["decoded_movement_provider_count"] == 5
|
||||
and meta["decoded_movement_step_count"] == 292
|
||||
and meta["decoded_movement_parameter_count"] == 758
|
||||
and meta["decoded_movement_defaulted_parameter_count"] == 7,
|
||||
"RTINIT reports selector-specific semantic coverage")
|
||||
check([
|
||||
layout["bank_index"]
|
||||
@@ -413,6 +414,26 @@ def test_real_routine_banks() -> None:
|
||||
and provider_11["waypoint_ordinal"] == 1
|
||||
and provider_11["path_cost_limit_override"] == 2,
|
||||
"RTINIT joins all four RTN_M011 waypoint parameters")
|
||||
provider_7 = by_id[33]["movement_steps"][4]
|
||||
check(provider_7["movement_provider_selector"] == 7
|
||||
and provider_7["provider_behavior"] == "approach_injured_ally"
|
||||
and provider_7["maximum_target_route_steps"] == 5
|
||||
and provider_7["maximum_target_hp_percent"] == 80,
|
||||
"RTINIT joins RTN_M007 injured-ally search semantics")
|
||||
provider_10 = by_id[99]["movement_steps"][0]
|
||||
check(provider_10["movement_provider_selector"] == 10
|
||||
and provider_10["provider_behavior"] == "approach_healing_feather"
|
||||
and provider_10["resource_index"] == 0
|
||||
and provider_10["maximum_resource_percent"] == 50
|
||||
and "movement_parameter_1" not in provider_10,
|
||||
"RTINIT projects RTN_M010's implicit HP default beside the raw banks")
|
||||
provider_12 = by_id[168]["movement_steps"][0]
|
||||
check(provider_12["movement_provider_selector"] == 12
|
||||
and provider_12["provider_behavior"]
|
||||
== "approach_destination_tile_avoiding_foreign_entities"
|
||||
and provider_12["destination_tile_x"] == 11
|
||||
and provider_12["destination_tile_y"] == 68,
|
||||
"RTINIT joins RTN_M012's route-mode destination semantics")
|
||||
check("provider_behavior" not in movement
|
||||
and "destination_tile_x" not in movement,
|
||||
"RTINIT does not leak provider-specific meanings onto undecoded selectors")
|
||||
@@ -426,6 +447,11 @@ def test_real_routine_banks() -> None:
|
||||
},
|
||||
"RTINIT publishes the reusable RTN_M011 parameter schema",
|
||||
)
|
||||
check(
|
||||
meta["movement_provider_parameter_schemas"]["10"]["parameter_defaults"]
|
||||
== {"movement_parameter_1": 0},
|
||||
"RTINIT publishes RTN_M010's implicit resource-index default",
|
||||
)
|
||||
semantics = extract_init.field_semantics(records)
|
||||
check(
|
||||
semantics["0xeff78/20/0"]
|
||||
|
||||
@@ -25,8 +25,14 @@ def test_load_and_lint():
|
||||
check(entries[0x5231f]["name"] == "entity_tile_x"
|
||||
and entries[0x52351]["name"] == "entity_tile_y",
|
||||
"entity map-coordinate arrays are curated")
|
||||
check(entries[0x4e021]["name"] == "entity_runtime_flags"
|
||||
and entries[0x522ed]["name"] == "entity_faction_ids",
|
||||
"entity activity and faction arrays are curated")
|
||||
check(entries[0x56b20]["name"] == "entity_patrol_waypoint_indices",
|
||||
"RTN_M011 waypoint state is curated")
|
||||
check(entries[0xaba96]["name"] == "pathfinding_remaining_route_steps"
|
||||
and entries[0xcc9f1]["name"] == "movement_search_mode",
|
||||
"movement-search reachability state is curated")
|
||||
check(entries[0xb240e]["name"] == "pathfinding_movement_costs",
|
||||
"movement-cost work grid is curated")
|
||||
# lint clean against a permissive address universe (curated addrs are self-consistent)
|
||||
|
||||
@@ -132,6 +132,7 @@ def main() -> int:
|
||||
"decoded_movement_provider_count": 1,
|
||||
"decoded_movement_step_count": 1,
|
||||
"decoded_movement_parameter_count": 2,
|
||||
"decoded_movement_defaulted_parameter_count": 1,
|
||||
"movement_provider_scripts": {"1": "RTN_M001.BIN"},
|
||||
"battle_provider_scripts": {"1": "RTN_B001.BIN"},
|
||||
"used_movement_provider_selectors": [1],
|
||||
@@ -163,6 +164,7 @@ def main() -> int:
|
||||
assert banked_summary["decoded_movement_provider_count"] == 1
|
||||
assert banked_summary["decoded_movement_step_count"] == 1
|
||||
assert banked_summary["decoded_movement_parameter_count"] == 2
|
||||
assert banked_summary["decoded_movement_defaulted_parameter_count"] == 1
|
||||
|
||||
messages = profile.profile_messages(fixture)
|
||||
assert messages["population"] == 1
|
||||
|
||||
@@ -850,7 +850,7 @@ name = "movement_routine_parameter_1"
|
||||
category = "data-table"
|
||||
type = "int[1000][20]"
|
||||
value_domain = "provider-specific integer"
|
||||
usage = "RTINIT movement bank 2. Its meaning is tagged by movement_routine_provider_selectors: RTN_M005 and RTN_M011 use it as destination_tile_x; other consuming providers remain provider-specific."
|
||||
usage = "RTINIT movement bank 2. Its meaning is tagged by movement_routine_provider_selectors: RTN_M005/012 use destination_tile_x, RTN_M007 uses maximum_target_route_steps, RTN_M010 uses resource_index (0=HP, 1=SP, 2=FS; shipped cells are unwritten/default zero), and RTN_M011 uses destination_tile_x."
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0xeff78"]
|
||||
@@ -861,7 +861,7 @@ name = "movement_routine_parameter_2"
|
||||
category = "data-table"
|
||||
type = "int[1000][20]"
|
||||
value_domain = "provider-specific integer"
|
||||
usage = "RTINIT movement bank 3. RTN_M005 and RTN_M011 use it as destination_tile_y; RTN_M007/010/012 meanings remain provider-specific."
|
||||
usage = "RTINIT movement bank 3. Its meaning is tagged by movement_routine_provider_selectors: RTN_M005/011/012 use destination_tile_y, RTN_M007 uses maximum_target_hp_percent, and RTN_M010 uses maximum_resource_percent."
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0xeff78"]
|
||||
@@ -1164,6 +1164,17 @@ source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0x4e085"]
|
||||
|
||||
[[global]]
|
||||
address = "0x4e021"
|
||||
name = "entity_runtime_flags"
|
||||
category = "data-table"
|
||||
type = "int[50]"
|
||||
value_domain = "runtime entity bitfield; bit 0 marks an active entity"
|
||||
usage = "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."
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0x522ed", "0x5231f", "0x52351"]
|
||||
|
||||
[[global]]
|
||||
address = "0x4e085"
|
||||
name = "entity_current_resources"
|
||||
@@ -1176,6 +1187,17 @@ source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0x4e11b"]
|
||||
|
||||
[[global]]
|
||||
address = "0x522ed"
|
||||
name = "entity_faction_ids"
|
||||
category = "data-table"
|
||||
type = "int[50]"
|
||||
value_domain = "runtime faction/side id"
|
||||
usage = "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."
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0x4e021"]
|
||||
|
||||
[[global]]
|
||||
address = "0x5231f"
|
||||
name = "entity_tile_x"
|
||||
@@ -1264,6 +1286,28 @@ source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0x4e085"]
|
||||
|
||||
[[global]]
|
||||
address = "0xaba96"
|
||||
name = "pathfinding_remaining_route_steps"
|
||||
category = "data-table"
|
||||
type = "int[][27]"
|
||||
value_domain = "0 for unreachable; positive remaining flood-fill steps"
|
||||
usage = "MVSEEK's row-major reachability grid. The origin receives movement+1 and each traversed edge decrements the value, so a larger positive value is nearer to the origin. RTN_M007 uses the difference from the origin value as its ally-search radius; RTN_M010 ranks Healing Feathers by the negated value to choose the nearest reachable object."
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0x4e11b", "0x5231f", "0x52351", "0xcc9f1"]
|
||||
|
||||
[[global]]
|
||||
address = "0xcc9f1"
|
||||
name = "movement_search_mode"
|
||||
category = "choice-output"
|
||||
type = "int"
|
||||
value_domain = "0..2"
|
||||
usage = "Transient MVSEEK mode. Zero keeps the caller-supplied origin and broad search allowance; nonzero modes replace them with the current entity tile and movement+1. 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."
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = ["0x4e021", "0x4e11b", "0x522ed", "0x5231f", "0x52351"]
|
||||
|
||||
[[global]]
|
||||
address = "0x152616"
|
||||
name = "current_entity_index"
|
||||
|
||||
Reference in New Issue
Block a user