From 169075fe373802977c8000387e6e6fda345e5827 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Tue, 7 Jul 2026 08:33:51 -0400 Subject: [PATCH] feat: curate story-flags into registry + docs (Task 6) Bootstrap 56 high-signal skeletons; name game_mode/route_branch/scjump_decision_out2, recategorize CONFIG-written globals as non-story. Docs: name-resolution.md registry section, CLAUDE.md canonical+SoT tables + trigger (root, untracked), tools-reference rows. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/global-reference.md | 63 +++- docs/name-resolution.md | 40 +++ docs/tools-reference.md | 3 + tools/story_flags.py | 8 +- tools/test_globals.py | 7 +- vm-map/globals.toml | 616 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 727 insertions(+), 10 deletions(-) diff --git a/docs/global-reference.md b/docs/global-reference.md index e897065..7ed72bf 100644 --- a/docs/global-reference.md +++ b/docs/global-reference.md @@ -1,19 +1,20 @@ # Global Variable Reference (generated) -16363 globals (12 curated, 16351 auto shape-inferred). Source of truth: `vm-map/globals.toml`. +16414 globals (68 curated, 16346 auto shape-inferred). Source of truth: `vm-map/globals.toml`. ## choice-output | address | name | conf | source | usage | |---|---|---|---|---| +| `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 | low | inference | One of SCJUMP's output/decision globals (progression state machine writes it). Related to chapter_mode. | ## data-table | address | name | conf | source | usage | |---|---|---|---|---| -| `0x0` | — | low | auto-shape | array | | `0x5` | — | low | auto-shape | array | | `0xd2` | — | low | auto-shape | array | | `0xd7` | — | low | auto-shape | array | @@ -332,10 +333,60 @@ | address | name | conf | source | usage | |---|---|---|---|---| +| `0x0` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 21 scripts; compared against [0, 1, 2, 3, 4, 5]; writers=['BTL.BIN', 'CAMP.BIN', 'DEBUGADV.BIN', 'DEBUGADV2.BIN']. | +| `0x699` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['CAMP.BIN', 'EVOLVE.BIN', 'SALLY.BIN', 'SYSTEM4.BIN']. | +| `0x6be` | — | med | auto-shape | TODO: confirm. Branch-read in 146 scenes / 150 scripts; compared against [0]; writers=none (external/native?). | +| `0x6c3` | — | med | auto-shape | TODO: confirm. Branch-read in 136 scenes / 138 scripts; compared against []; writers=['DEBUGADV.BIN', 'DEBUGADV2.BIN', 'SC0000.BIN', 'SC0010.BIN']. | | `0xa57` | lily_form_a | high | investigation | Lily current-form flag A. Exactly one of form A/B/C is 1; gates form-specific voiced dialogue (seeding 0xa57=1 -> SC0000 186->229 lines). Set externally (menu/save), no static writer. | | `0xa58` | lily_form_b | high | investigation | Lily current-form flag B. See lily_form_a. | | `0xa59` | lily_form_c | high | investigation | Lily current-form flag C. See lily_form_a. | +| `0xa99` | — | med | auto-shape | TODO: confirm. Branch-read in 2 scenes / 3 scripts; compared against [1]; writers=['GAMESTART.BIN']. | +| `0xd92` | — | med | auto-shape | TODO: confirm. Branch-read in 29 scenes / 29 scripts; compared against [1]; writers=none (external/native?). | +| `0x3231` | game_mode | med | inference | Game-mode/phase selector in the 0x3231-0x3234 progression-state cluster (chapter_mode is 0x3234). Enum 1..9, written by the gameplay scripts (AIM/ALCHEMY/BTL/BUNKI), branch-read in 136 scenes. Distinct from chapter; likely current sub-mode/screen. INFERENCE — confirm with a listing/sweep before relying on the exact meaning. | | `0x3234` | chapter_mode | high | investigation | Progression chapter/mode selector. SCJUMP's top-level switch keys on it; branch-read by progression scripts (FIELD etc.), not directly by SC/SP scenes. | +| `0x3275` | — | med | auto-shape | TODO: confirm. Branch-read in 136 scenes / 143 scripts; compared against [0]; writers=['CAMP.BIN', 'DEBUGADV.BIN', 'DEBUGADV2.BIN', 'FIELD.BIN']. | +| `0x6718` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0, 2]; writers=['ADDSKILL.BIN', 'CHMENU.BIN', 'DELCH.BIN', 'DRAWCHP.BIN']. | +| `0x671b` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [999]; writers=['ALCHEMY.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']. | +| `0x671e` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [5, 6]; writers=['USEMAGIC.BIN']. | +| `0x6722` | — | med | auto-shape | TODO: confirm. Branch-read in 13 scenes / 18 scripts; compared against [0, 1, 5, 99]; writers=['GAMESTART.BIN', 'SALLY.BIN', 'SC0010.BIN', 'SC0140.BIN']. | +| `0x6724` | — | med | auto-shape | TODO: confirm. Branch-read in 4 scenes / 10 scripts; compared against [0, 25, 50, 99]; writers=['DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']. | +| `0x7679` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0, 1, 4, 8, 16, 256, 512, 1024]; writers=['FIELD.BIN']. | +| `0x767a` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN', 'FIELD.BIN']. | +| `0x767b` | — | med | auto-shape | TODO: confirm. Branch-read in 136 scenes / 150 scripts; compared against [0, 1]; writers=['DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']. | +| `0x767d` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 9 scripts; compared against [0, 1, 2, 3]; writers=['CAMP.BIN', 'DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN']. | +| `0x204f4` | — | med | auto-shape | TODO: confirm. Branch-read in 2 scenes / 4 scripts; compared against [1, 3, 4, 5, 10, 15, 20, 25]; writers=['FIELD.BIN']. | +| `0x204f5` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [1, 2, 4, 8, 16, 32, 64]; writers=['FIELD.BIN']. | +| `0x204f7` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [1, 2, 4, 6]; writers=['DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN', 'GAMESTART.BIN']. | +| `0x2052e` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0, 1, 2, 3]; writers=['FIELD.BIN']. | +| `0x20530` | — | med | auto-shape | TODO: confirm. Branch-read in 14 scenes / 22 scripts; compared against [0]; writers=['DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']. | +| `0x20534` | — | med | auto-shape | TODO: confirm. Branch-read in 14 scenes / 24 scripts; compared against [0, 10, 100, 999]; writers=['DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']. | +| `0x53ef4` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0]; writers=['CAMP.BIN']. | +| `0x55e37` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0]; writers=['EVOLVE.BIN', 'STUDY.BIN']. | +| `0x55e38` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 9 scripts; compared against [0, 1, 2]; writers=['CHMENU.BIN', 'INFO.BIN', 'INFOAF.BIN', 'INFOCH.BIN']. | +| `0x55e39` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 8 scripts; compared against [0, 1, 4]; writers=['ALCHEMY.BIN', 'EVOLVE.BIN', 'MAGIC2.BIN', 'SELSTAGE.BIN']. | +| `0x55e3a` | — | med | auto-shape | TODO: confirm. Branch-read in 136 scenes / 143 scripts; compared against [0]; writers=['FORT.BIN']. | +| `0x617fd` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0, 25, 50]; writers=['GAMESTART.BIN', 'TUNE.BIN']. | +| `0x62428` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0]; writers=['CALLBACK_WINDOW.BIN', 'DEBUG.BIN', 'DEBUGADV.BIN', 'DEBUGADV2.BIN']. | +| `0x62439` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0]; writers=['CHMENU.BIN', 'INFOAF.BIN', 'INFOCH.BIN', 'INFOEN.BIN']. | +| `0x6249e` | — | med | auto-shape | TODO: confirm. Branch-read in 78 scenes / 81 scripts; compared against [0, 1, 2, 3, 4, 5, 6, 7]; writers=['DEBUGADV.BIN', 'DEBUGADV2.BIN', 'SC0000.BIN', 'SC0010.BIN']. | +| `0x624be` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 8 scripts; compared against [0]; writers=['MENU.BIN']. | +| `0x6642c` | route_branch | med | inference | Route/branch selector: sole writer is BUNKI.BIN (分岐 = branching), enum 0..7, branch-read in 36 scenes. Selects a story branch/route. INFERENCE from the BUNKI writer + enum — confirm exact routes via a listing/sweep. | +| `0x665d3` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [1, 2, 4, 8, 32, 64, 128, 65536]; writers=['ALCHEMY.BIN', 'BUNKI.BIN', 'DEBUGADV.BIN', 'EVOLVE.BIN']. | +| `0x665d6` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against []; writers=['MES.BIN', 'SBUNKI.BIN']. | +| `0x665d7` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [1, 3]; writers=['ADDSKILL.BIN', 'SBUNKI.BIN']. | +| `0x66714` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against []; writers=['DEBUGBTL.BIN', 'FIELD.BIN', 'RTN_M051.BIN', 'RTN_M052.BIN']. | +| `0xa6e59` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [1, 2, 3, 4, 11, 21, 22, 23]; writers=['CALCDMG.BIN', 'CHMENU.BIN', 'FORT.BIN', 'INFOIT.BIN']. | +| `0xab8e7` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0, 10, 15, 20, 25, 30, 35, 40]; writers=['CALCCC.BIN', 'CCINIT.BIN']. | +| `0xaba5c` | — | med | auto-shape | TODO: confirm. Branch-read in 136 scenes / 149 scripts; compared against [0, 1]; writers=['DEBUGADV.BIN', 'DEBUGADV2.BIN', 'SC0000.BIN', 'SC0010.BIN']. | +| `0xaba5e` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [2]; writers=['DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']. | +| `0xcc9f3` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against []; writers=['CALCSCOPE.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']. | +| `0x152617` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['CLOSE.BIN', 'FIELD.BIN', 'INFOEN.BIN', 'READY.BIN']. | +| `0x152618` | — | med | auto-shape | TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [1, 2, 4, 7]; writers=['FIELD.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']. | ## string-table @@ -3477,6 +3528,10 @@ | address | name | conf | source | usage | |---|---|---|---|---| +| `0x3238` | — | low | inference | Config/settings global (CONFIG.BIN/INITCONFIG.BIN writer, scene-reach 0) — NOT a scene story flag; miner over-tagged it. Branch-read in 5 scripts; compared against [1]. | +| `0x3301` | — | low | inference | Config/settings global (INITCONFIG.BIN writer, scene-reach 0) — NOT a scene story flag; miner over-tagged it. Branch-read in 6 scripts; compared against [1, 2]. | +| `0x3303` | — | low | inference | Config/settings global (CONFIG.BIN/INITCONFIG.BIN writer, scene-reach 0) — NOT a scene story flag; miner over-tagged it. Branch-read in 8 scripts; compared against [1]. | +| `0x3304` | — | low | inference | Config/settings global (CONFIG.BIN/INITCONFIG.BIN writer, scene-reach 0) — NOT a scene story flag; miner over-tagged it. Branch-read in 13 scripts; compared against [1]. | | `0x84b` | — | high | auto-shape | unit-name-table | | `0xc33` | — | high | auto-shape | unit-desc-table | | `0x101b` | — | high | auto-shape | unit-desc1-table | @@ -4897,7 +4952,6 @@ | `0x64cde` | — | med | auto-shape | cg-gallery-field | | `0x6638b` | — | med | auto-shape | record-table[stride 15] | | `0x66713` | — | low | auto-shape | index/counter? | -| `0x66714` | — | low | auto-shape | index/counter? | | `0x66715` | — | med | auto-shape | current-entity-index? | | `0x66716` | — | med | auto-shape | record-table[stride 30] | | `0x66751` | — | low | auto-shape | unit-field? | @@ -16104,7 +16158,6 @@ | `0xa6ace` | — | low | auto-shape | item-field? | | `0xa6acf` | — | low | auto-shape | item-field? | | `0xa6ad6` | — | low | auto-shape | item-field? | -| `0xa6e59` | — | low | auto-shape | index/counter? | | `0xa6e5b` | — | med | auto-shape | skill-field | | `0xa6e5d` | — | low | auto-shape | skill-field? | | `0xa6f87` | — | med | auto-shape | skill-field | @@ -16338,7 +16391,6 @@ | `0xcca08` | — | med | auto-shape | record-table[stride 5] | | `0xccbdc` | — | med | auto-shape | record-table[stride 14] | | `0xccc0b` | — | low | auto-shape | index/counter? | -| `0xccc21` | — | low | auto-shape | index/counter? | | `0xccc33` | — | med | auto-shape | record-table[stride 3] | | `0xccc93` | — | med | auto-shape | record-table[stride 53] | | `0xe6afe` | — | med | auto-shape | record-table[stride 10] | @@ -16376,7 +16428,6 @@ | `0x152101` | — | med | auto-shape | record-table[stride 3] | | `0x15222d` | — | med | auto-shape | record-table[stride 3] | | `0x152486` | — | med | auto-shape | record-table[stride 3] | -| `0x152617` | — | low | auto-shape | index/counter? | | `0x15261a` | — | low | auto-shape | index/counter? | | `0x15261b` | — | low | auto-shape | index/counter? | | `0x15261f` | — | med | auto-shape | record-table[stride 300] | diff --git a/docs/name-resolution.md b/docs/name-resolution.md index 3f962ca..9fe039a 100644 --- a/docs/name-resolution.md +++ b/docs/name-resolution.md @@ -102,6 +102,46 @@ Labels are prefixed `=` to mark them as inferred aliases. Regenerate the `.asm` Confidence is marked per entry; labels ending `?` are low-confidence guesses. +### The curated registry — `vm-map/globals.toml` (2026-07-07) + +The v1 auto map (`build/global-var-map.json`) infers *shapes* but cannot recover branch-flag +*meaning* — and is sometimes wrong (it labels `0xa57`, the Lily form-A story flag, as a +"string-table"). The curated registry fixes this, modelled exactly on `vm-map/opcodes.toml`: + +- **`vm-map/globals.toml`** — the only hand-edited source. One `[[global]]` per known address: + `name`, `category` (`story-flag`/`index-pointer`/`data-table`/`string-table`/`ui-toggle`/ + `choice-output`/`counter`/`unknown`), `type`, `value_domain`, `usage`, and provenance + (`source`/`confidence`/`depends_on`). +- **`tools/globals_build.py --build`** merges curated entries *over* the auto map → + `build/globals.json` (machine) + `docs/global-reference.md` (generated human view). `--lint` + checks vocabulary, the auto-shape≠high rule, and dangling `depends_on`. `sys4load` reads + `build/globals.json` for operand labels (curated names win, shown as `name(category)`; the auto + tail is kept only at high/med confidence). Regenerate the `.asm` corpus with + `tools/extract_phase2.py` to pick up new labels. + +#### Story-state flags (the first populated category) + +Story flags are scalar globals that ADV/progression logic *branches on* (chapter, character +forms, choices, routes) — a category the auto shape map never enumerated. **`tools/story_flags.py`** +is a 100% static miner: it flags a global as a candidate when it feeds a comparison (`eq`/`ne`/ +`lt`/`lte`/`gr`/`gre`), a logical (`and`/`or`), or a `jcc` condition, and is not a genuine table/ +index in the shape map. Per candidate it records compared-against constants (→ value domain), the +writer set (progression-written but scene-read = strong story flag), total- and scene-reach, and +near-universal (ADV-chrome) status → an auto category + confidence. Output: +`build/story-flags-candidates.json` (review surface: 1261 branch-read globals, **205 story-flag +candidates**); `--bootstrap` seeds high-signal skeletons (med-confidence, non-chrome) into +`globals.toml` for human naming. Dynamic confirmation of a flag's reach stays separate — +`Age.Cli sweep 0xADDR=VAL`. + +**Reading the catalog:** `reach_scenes > 0` = the flag changes SC/SP scene dialogue directly (e.g. +`0xa57` Lily form, scene-reach 78). `reach_scenes = 0` with progression writers = a +progression/menu-layer flag read by the game-flow scripts, not scenes (e.g. `0x3234` chapter, read +by SCJUMP/FIELD). **Known/named anchors:** `0x3234` `chapter_mode` (enum 1..9), `0x3231` +`game_mode` (adjacent mode selector), `0xa57/8/9` Lily forms A/B/C (boolean, externally set), +`0x62ccf/0x62ccc` SCJUMP decision outputs, `0x6642c` `route_branch` (BUNKI = 分岐 writer), +`0x6c9–0x6cd` UI toggles. Config/settings globals written by `CONFIG`/`INITCONFIG` (scene-reach 0) +are *not* story flags — the miner over-tags them; they are recategorized `unknown` when curated. + ### Future step — growing the map (planned, not yet done) The v1 map labels *shapes and tables*; the next increments add *meaning*, cheapest first: diff --git a/docs/tools-reference.md b/docs/tools-reference.md index e7a6a0c..014c920 100644 --- a/docs/tools-reference.md +++ b/docs/tools-reference.md @@ -43,6 +43,9 @@ All opcode knowledge (ABI, semantics, provenance, `depends_on`) is hand-edited * | `validate_opcode_table.py` | Definitive decode-coverage validator (replicates Kelebek's `data_array_end` code/data split). | `validate_opcode_table.py` | corpus → stdout | | `validate_opcode_table_naive.py` | Naïve variant of the above (baseline comparison). | `validate_opcode_table_naive.py` | corpus → stdout | | `age_opcodes_himegari.py` | ⚙ Inferred Himegari opcode semantics — **generated; do not hand-edit.** | *Imported by `sys4load.py`.* | — | +| `globals_build.py` | Merge curated `globals.toml` over the auto shape map; generate the global registry + linter. | `--build` · `--lint` | `vm-map/globals.toml`, `build/global-var-map.json` → ⚙ `build/globals.json`, ⚙ `docs/global-reference.md` | +| `story_flags.py` | Static story-flag miner (branch-condition mining) + `--bootstrap` skeleton seeding. | `story_flags.py` · `--bootstrap` | corpus, `build/global-var-map.json` → ⚙ `build/story-flags-candidates.json`, appends `vm-map/globals.toml` | +| `test_globals.py` | Unit tests for the globals registry + story-flag miner. | `test_globals.py` | — | ## Extraction / data corpora diff --git a/tools/story_flags.py b/tools/story_flags.py index f43e4cc..a5f893e 100644 --- a/tools/story_flags.py +++ b/tools/story_flags.py @@ -151,9 +151,13 @@ def skeleton_toml(ev: dict) -> str: def bootstrap(cands: dict[int, dict], toml_path=None) -> int: toml_path = Path(toml_path) if toml_path else (paths.VM_MAP / "globals.toml") present = set(_gb.load_toml(toml_path)[0]) if toml_path.exists() else set() - # only story-flag / ui-toggle / choice-output candidates are worth seeding for curation + # Seed only high-signal candidates worth hand-curating: story-flag / choice-output at med + # confidence that are NOT near-universal ADV-chrome (those 297-scene globals are engine + # scratch, not story state). The low-confidence long tail stays in the candidates JSON. seedable = {a: e for a, e in cands.items() - if e["category"] in ("story-flag", "ui-toggle", "choice-output") and a not in present} + if e["category"] in ("story-flag", "choice-output") + and e["confidence"] == "med" and not e["near_universal"] + and a not in present} if not seedable: print(f"bootstrap: nothing new to add ({len(present)} already present).") return 0 diff --git a/tools/test_globals.py b/tools/test_globals.py index f7bc9de..bbee05e 100644 --- a/tools/test_globals.py +++ b/tools/test_globals.py @@ -60,8 +60,11 @@ def test_miner_finds_known_flags(): def test_bootstrap_is_additive_and_idempotent(): import tempfile, pathlib, story_flags - # start from a copy of the real toml so curated entries are present - src = (paths.VM_MAP / "globals.toml").read_text(encoding="utf-8") + # Minimal fixture (one curated entry) so bootstrap always has candidates to add, independent + # of how many the real globals.toml already holds. + src = ('[meta]\nnote = "fixture"\n\n[[global]]\naddress = "0xa57"\nname = "lily_form_a"\n' + 'category = "story-flag"\ntype = "int"\nvalue_domain = "{0,1}"\nusage = "curated"\n' + 'source = "investigation"\nconfidence = "high"\ndepends_on = []\n') with tempfile.TemporaryDirectory() as d: tp = pathlib.Path(d) / "globals.toml" tp.write_text(src, encoding="utf-8") diff --git a/vm-map/globals.toml b/vm-map/globals.toml index c7a70f8..b087d87 100644 --- a/vm-map/globals.toml +++ b/vm-map/globals.toml @@ -137,3 +137,619 @@ usage = "Primary current-entity row index (RECOVER-confirmed; purity 0.51, 363 r source = "investigation" confidence = "med" depends_on = [] + +[[global]] +address = "0x0" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 2, 3, 4, 5}" +usage = "TODO: confirm. Branch-read in 0 scenes / 21 scripts; compared against [0, 1, 2, 3, 4, 5]; writers=['BTL.BIN', 'CAMP.BIN', 'DEBUGADV.BIN', 'DEBUGADV2.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x699" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['CAMP.BIN', 'EVOLVE.BIN', 'SALLY.BIN', 'SYSTEM4.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x6be" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 146 scenes / 150 scripts; compared against [0]; writers=none (external/native?)." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x6c3" +name = "" +category = "story-flag" +type = "int" +value_domain = "?" +usage = "TODO: confirm. Branch-read in 136 scenes / 138 scripts; compared against []; writers=['DEBUGADV.BIN', 'DEBUGADV2.BIN', 'SC0000.BIN', 'SC0010.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xa68" +name = "" +category = "choice-output" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 11 scenes / 12 scripts; compared against [0, 1]; writers=['SC0740.BIN', 'SC1580.BIN', 'SC1590.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xa99" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 2 scenes / 3 scripts; compared against [1]; writers=['GAMESTART.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xd92" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 29 scenes / 29 scripts; compared against [1]; writers=none (external/native?)." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x3231" +name = "game_mode" +category = "story-flag" +type = "int" +value_domain = "1..9" +usage = "Game-mode/phase selector in the 0x3231-0x3234 progression-state cluster (chapter_mode is 0x3234). Enum 1..9, written by the gameplay scripts (AIM/ALCHEMY/BTL/BUNKI), branch-read in 136 scenes. Distinct from chapter; likely current sub-mode/screen. INFERENCE — confirm with a listing/sweep before relying on the exact meaning." +source = "inference" +confidence = "med" +depends_on = ["0x3234"] + +[[global]] +address = "0x3238" +name = "" +category = "unknown" +type = "int" +value_domain = "{0,1}" +usage = "Config/settings global (CONFIG.BIN/INITCONFIG.BIN writer, scene-reach 0) — NOT a scene story flag; miner over-tagged it. Branch-read in 5 scripts; compared against [1]." +source = "inference" +confidence = "low" +depends_on = [] + +[[global]] +address = "0x3275" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 136 scenes / 143 scripts; compared against [0]; writers=['CAMP.BIN', 'DEBUGADV.BIN', 'DEBUGADV2.BIN', 'FIELD.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x3301" +name = "" +category = "unknown" +type = "int" +value_domain = "one of {1, 2}" +usage = "Config/settings global (INITCONFIG.BIN writer, scene-reach 0) — NOT a scene story flag; miner over-tagged it. Branch-read in 6 scripts; compared against [1, 2]." +source = "inference" +confidence = "low" +depends_on = [] + +[[global]] +address = "0x3303" +name = "" +category = "unknown" +type = "int" +value_domain = "{0,1}" +usage = "Config/settings global (CONFIG.BIN/INITCONFIG.BIN writer, scene-reach 0) — NOT a scene story flag; miner over-tagged it. Branch-read in 8 scripts; compared against [1]." +source = "inference" +confidence = "low" +depends_on = [] + +[[global]] +address = "0x3304" +name = "" +category = "unknown" +type = "int" +value_domain = "{0,1}" +usage = "Config/settings global (CONFIG.BIN/INITCONFIG.BIN writer, scene-reach 0) — NOT a scene story flag; miner over-tagged it. Branch-read in 13 scripts; compared against [1]." +source = "inference" +confidence = "low" +depends_on = [] + +[[global]] +address = "0x6718" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 2}" +usage = "TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0, 2]; writers=['ADDSKILL.BIN', 'CHMENU.BIN', 'DELCH.BIN', 'DRAWCHP.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x671b" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {999}" +usage = "TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [999]; writers=['ALCHEMY.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x671e" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {5, 6}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [5, 6]; writers=['USEMAGIC.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x6722" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 5, 99}" +usage = "TODO: confirm. Branch-read in 13 scenes / 18 scripts; compared against [0, 1, 5, 99]; writers=['GAMESTART.BIN', 'SALLY.BIN', 'SC0010.BIN', 'SC0140.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x6724" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 25, 50, 99}" +usage = "TODO: confirm. Branch-read in 4 scenes / 10 scripts; compared against [0, 25, 50, 99]; writers=['DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x7679" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 4, 8, 16, 256, 512, 1024}" +usage = "TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0, 1, 4, 8, 16, 256, 512, 1024]; writers=['FIELD.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x767a" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN', 'FIELD.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x767b" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 136 scenes / 150 scripts; compared against [0, 1]; writers=['DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x767d" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 2, 3}" +usage = "TODO: confirm. Branch-read in 0 scenes / 9 scripts; compared against [0, 1, 2, 3]; writers=['CAMP.BIN', 'DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x204f4" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {1, 3, 4, 5, 10, 15, 20, 25}" +usage = "TODO: confirm. Branch-read in 2 scenes / 4 scripts; compared against [1, 3, 4, 5, 10, 15, 20, 25]; writers=['FIELD.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x204f5" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {1, 2, 4, 8, 16, 32, 64}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [1, 2, 4, 8, 16, 32, 64]; writers=['FIELD.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x204f7" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {1, 2, 4, 6}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [1, 2, 4, 6]; writers=['DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN', 'GAMESTART.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x2052e" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 2, 3}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0, 1, 2, 3]; writers=['FIELD.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x20530" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 14 scenes / 22 scripts; compared against [0]; writers=['DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x20534" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 10, 100, 999}" +usage = "TODO: confirm. Branch-read in 14 scenes / 24 scripts; compared against [0, 10, 100, 999]; writers=['DEBUGADV2.BIN', 'DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x53ef4" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0]; writers=['CAMP.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x55e37" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0]; writers=['EVOLVE.BIN', 'STUDY.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x55e38" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 2}" +usage = "TODO: confirm. Branch-read in 0 scenes / 9 scripts; compared against [0, 1, 2]; writers=['CHMENU.BIN', 'INFO.BIN', 'INFOAF.BIN', 'INFOCH.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x55e39" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 4}" +usage = "TODO: confirm. Branch-read in 0 scenes / 8 scripts; compared against [0, 1, 4]; writers=['ALCHEMY.BIN', 'EVOLVE.BIN', 'MAGIC2.BIN', 'SELSTAGE.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x55e3a" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 136 scenes / 143 scripts; compared against [0]; writers=['FORT.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x617fd" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 25, 50}" +usage = "TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0, 25, 50]; writers=['GAMESTART.BIN', 'TUNE.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x62428" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0]; writers=['CALLBACK_WINDOW.BIN', 'DEBUG.BIN', 'DEBUGADV.BIN', 'DEBUGADV2.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x62439" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0]; writers=['CHMENU.BIN', 'INFOAF.BIN', 'INFOCH.BIN', 'INFOEN.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x6249e" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 2, 3, 4, 5, 6, 7}" +usage = "TODO: confirm. Branch-read in 78 scenes / 81 scripts; compared against [0, 1, 2, 3, 4, 5, 6, 7]; writers=['DEBUGADV.BIN', 'DEBUGADV2.BIN', 'SC0000.BIN', 'SC0010.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x624be" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 8 scripts; compared against [0]; writers=['MENU.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x62ccc" +name = "scjump_decision_out2" +category = "choice-output" +type = "int" +value_domain = "small enum" +usage = "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." +source = "inference" +confidence = "low" +depends_on = ["0x62ccf"] + +[[global]] +address = "0x6642c" +name = "route_branch" +category = "story-flag" +type = "int" +value_domain = "0..7" +usage = "Route/branch selector: sole writer is BUNKI.BIN (分岐 = branching), enum 0..7, branch-read in 36 scenes. Selects a story branch/route. INFERENCE from the BUNKI writer + enum — confirm exact routes via a listing/sweep." +source = "inference" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x665d3" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {1, 2, 4, 8, 32, 64, 128, 65536}" +usage = "TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [1, 2, 4, 8, 32, 64, 128, 65536]; writers=['ALCHEMY.BIN', 'BUNKI.BIN', 'DEBUGADV.BIN', 'EVOLVE.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x665d6" +name = "" +category = "story-flag" +type = "int" +value_domain = "?" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against []; writers=['MES.BIN', 'SBUNKI.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x665d7" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {1, 3}" +usage = "TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [1, 3]; writers=['ADDSKILL.BIN', 'SBUNKI.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x66714" +name = "" +category = "story-flag" +type = "int" +value_domain = "?" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against []; writers=['DEBUGBTL.BIN', 'FIELD.BIN', 'RTN_M051.BIN', 'RTN_M052.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xa6e59" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {1, 2, 3, 4, 11, 21, 22, 23}" +usage = "TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [1, 2, 3, 4, 11, 21, 22, 23]; writers=['CALCDMG.BIN', 'CHMENU.BIN', 'FORT.BIN', 'INFOIT.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xab8e7" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 10, 15, 20, 25, 30, 35, 40}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [0, 10, 15, 20, 25, 30, 35, 40]; writers=['CALCCC.BIN', 'CCINIT.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xaba5c" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 136 scenes / 149 scripts; compared against [0, 1]; writers=['DEBUGADV.BIN', 'DEBUGADV2.BIN', 'SC0000.BIN', 'SC0010.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xaba5e" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {2}" +usage = "TODO: confirm. Branch-read in 0 scenes / 5 scripts; compared against [2]; writers=['DEBUGMAP.BIN', 'DEBUGMAP2.BIN', 'DEBUGMAP3.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xcc9f3" +name = "" +category = "story-flag" +type = "int" +value_domain = "?" +usage = "TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against []; writers=['CALCSCOPE.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0xccc21" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['CHMENU.BIN']." +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 = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 4 scripts; compared against [0]; writers=['CLOSE.BIN', 'FIELD.BIN', 'INFOEN.BIN', 'READY.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x152618" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {1, 2, 4, 7}" +usage = "TODO: confirm. Branch-read in 0 scenes / 3 scripts; compared against [1, 2, 4, 7]; writers=['FIELD.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x1560e7" +name = "" +category = "story-flag" +type = "int" +value_domain = "one of {0, 1, 2, 3, 4, 5, 6, 7}" +usage = "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']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x15a094" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0]; writers=['ALCHEMY.BIN', 'EVOLVE.BIN', 'SELSTAGE.BIN', 'STUDY.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = [] + +[[global]] +address = "0x15a095" +name = "" +category = "story-flag" +type = "int" +value_domain = "{0,1}" +usage = "TODO: confirm. Branch-read in 0 scenes / 6 scripts; compared against [0]; writers=['INFO.BIN', 'INFOCH.BIN', 'MENU.BIN']." +source = "auto-shape" +confidence = "med" +depends_on = []