522 lines
46 KiB
Markdown
522 lines
46 KiB
Markdown
## Map and Scenario Content Load
|
|
|
|
- Roots: `shell_map_file_entry_coordinator` at `0x00445ac0`, the larger active-mode profile owner
|
|
`shell_active_mode_run_profile_startup_and_load_dispatch` at `0x00438890`, the shell-mode
|
|
switcher `shell_transition_mode` at `0x00482ec0`, the first grounded world-entry branch
|
|
`world_entry_transition_and_runtime_bringup` at `0x00443a50`,
|
|
`shell_map_file_world_bundle_coordinator` at `0x00445de0`, early reference-package save via
|
|
`map_bundle_open_reference_package_and_serialize_early_world_datasets` at `0x00444dd0`, and narrower tagged collection owners such as
|
|
`geographic_label_database_refresh_records_from_tagged_bundle` and `city_database_entry_collection_refresh_records_from_tagged_bundle`.
|
|
- Trigger/Cadence: shell tutorial launch, editor or detail-panel file actions through `fileopt.win`,
|
|
map-scenario open paths, and scenario-text export batch commands.
|
|
- Key Dispatchers: `shell_map_file_entry_coordinator`,
|
|
`shell_active_mode_run_profile_startup_and_load_dispatch`, `shell_transition_mode`,
|
|
`world_entry_transition_and_runtime_bringup`, `world_runtime_release_global_services`, `shell_map_file_world_bundle_coordinator`,
|
|
`map_bundle_open_reference_package_and_serialize_early_world_datasets`, `geographic_label_database_refresh_records_from_tagged_bundle`,
|
|
`city_database_entry_collection_refresh_records_from_tagged_bundle`, `scenario_text_export_build_language_file`,
|
|
`scenario_text_export_report_language_file`, `scenario_text_export_batch_process_maps`.
|
|
- State Anchors: shell-side file staging buffers at `0x0062bee0` and `0x0062bec4`, shell and mode
|
|
globals at `0x006cec74` and `0x006cec78`, world object root `0x0062c120`, map bundle state
|
|
allocated through `0x00530c80`, and geography tables rooted at `0x0062b2fc` and `0x0062b268`.
|
|
- Subsystem Handoffs: the shared `fileopt.win` dialog rooted at `0x004dc670` now looks like the
|
|
shell-side selector above the two broad file coordinators. Its message handler sets `0x006d07f8`
|
|
for the load or restore side or `0x006d07ec` for the save or package side before the detail-panel
|
|
transition manager routes into `shell_map_file_entry_coordinator` or
|
|
`shell_map_file_world_bundle_coordinator`. The former unresolved third flag at `0x006d07f0` is now
|
|
accounted for too: it escapes into the standalone `SettingsWindow.win` path through
|
|
`shell_open_settings_window` rather than another map or save verb. The broad coordinators now hand
|
|
their interactive work through the shared `filerqst.win` helper at `0x004dd010`, and that helper
|
|
gives the extension split a firmer shape. The paired editor-map path is now grounded as `.gmp`
|
|
through load mode `4` and save mode `3`. The remaining non-editor families are no longer anonymous
|
|
either: `.gmc` is the campaign-scenario branch, backed both by the campaign-screen resignation
|
|
prompt on `0x006cec7c+0xc5` and by the numbered `%s%02d.gmc` save helper at `0x00517c70`; `.gmx`
|
|
is the sandbox branch, backed by the shell-side `The briefing is not available in sandbox games.`
|
|
restriction on `0x006cec7c+0x82`; and the default `.gms` branch is therefore the standalone
|
|
scenario family. When a live runtime world is already active the same helper bypasses those
|
|
non-runtime extensions and forces the `.smp` runtime-state branch instead. The auxiliary save-side
|
|
mode `11` is tighter now too: it still maps to `.gmt`, but instead of looking like another
|
|
gameplay save family it conditionally diverts into the same `.gmt` preview-surface pipeline owned
|
|
by the Multiplayer preview dataset object at `0x006cd8d8`, and only falls back to the normal
|
|
reference-bundle path when that dataset object is absent. That fallback owner is tighter now too:
|
|
`0x00444dd0` is not a generic database opener, but the early package-save prelude that seeds the
|
|
shared stage/progress globals, opens one `0x30d40` bundle through `0x00530c80`, handles the
|
|
localized failure modal `0x0fda`, and then serializes the first direct package band in a fixed
|
|
order: chunks `0x32c8/0x32c9`, direct saves of `[world+0x66be]`, `[world+0x66b2]`, and
|
|
`[world+0x66b6]`, chunk `0x32dc`, the staged `0x108` profile block under `0x3714/0x3715`, then
|
|
`world_serialize_runtime_grid_and_secondary_raster_tables_into_bundle` `0x00449520` for the
|
|
early world-grid and sidecar-table band, then
|
|
`aux_candidate_collection_serialize_records_into_bundle_payload` `0x00416a70` for the direct
|
|
`0x0062b2fc` source-or-auxiliary record family, and only after that the neighboring reference
|
|
and manager families before `shell_map_file_world_bundle_coordinator` continues with the later
|
|
tagged collections. That `0x0062b2fc` seam is tighter now too: `0x00416a70` first builds one
|
|
temporary scored queue from each record's linked chain at `[entry+0x04]`, writes one leading
|
|
`0xbabe` header, and then serializes the fixed fields, counted dword runs, optional byte payload,
|
|
paired one-byte bands, and trailing dword for each queued record; the load-side companion is
|
|
`aux_candidate_collection_construct_stream_load_records_and_refresh_runtime_followons`
|
|
`0x004196c0`, which now clearly tails into
|
|
`aux_candidate_collection_rebank_or_clone_records_by_availability_pass_and_refresh_owner_links`
|
|
`0x00419230` before the later world-load side continues, with destructor
|
|
`aux_candidate_collection_release_templates_queues_and_indexed_storage` `0x00419680`. The fixed
|
|
tail is explicit now too: `0x00444dd0` writes one direct dword from
|
|
`[world+0x19]`, one zeroed `0x1f4`-byte slab under `0x32cf`, closes the package, derives the
|
|
preview path through `0x00442740`, and then conditionally emits the companion-image and
|
|
companion-payload sidecars through `0x00441f70` and `0x00442900` when `[world+0x66c8]` and
|
|
`[world+0x66c9]` are set. The shell-side mode owner above those
|
|
file coordinators is clearer now too. `shell_transition_mode` no longer reads like a generic mode
|
|
switch: its ABI is now grounded as a `thiscall` with two stack arguments because the body reads
|
|
the requested mode from `[esp+0x0c]` and returns with `ret 8`. The grounded world-entry
|
|
load-screen call shape is `(4, 0)`, not a one-arg mode switch. The second stack argument is now
|
|
tighter too: current local evidence reads it as an old-active-mode teardown flag, because the
|
|
`0x482fc6..0x482fff` branch only runs when it is nonzero and then releases the prior active-mode
|
|
world through `0x434300`, falls through the neighboring no-op placeholder `0x433730`, and then
|
|
reaches the common free path before clearing `0x006cec78`. The teardown owner itself is tighter
|
|
now too: `0x434300` first destroys the two indexed world collections at `[world+0x66b2]` and
|
|
`[world+0x66b6]`, then releases the typed global roots `0x0062b244`, `0x006cfcbc`,
|
|
`0x0062be10`, `0x006ceb9c`, `0x0062c120`, `0x0062ba8c`, `0x006ada84`, `0x0062ba88`,
|
|
`0x0062b2fc`, `0x0062b268`, `0x006cea4c`, and `0x006acd34` in that order before it drains the
|
|
shell-helper handle band `[world+0x46a80..+0x46aa0]`, the variable owner band `[world+0x46aa4]`,
|
|
and the linked chains at `[world+0x66a6]` and `[world+0x66aa]`.
|
|
The corresponding world-load allocation branch is tighter now too: inside `0x00438c70`,
|
|
`0x0062b2fc` is allocated as a `0xb8`-byte object and then constructed through
|
|
`aux_candidate_collection_construct_seed_globals_and_helper_bands_then_import_records`
|
|
`0x0041aa50`, which seeds the collection base, resets the neighboring constructor globals, builds
|
|
the helper bands at `[this+0x88/+0x8c/+0x90]` through `0x0041a990`, and only then tails into the
|
|
tagged import owner `0x004196c0`. The next two roots in the same load strip are now explicit
|
|
too: `0x0062ba8c` is allocated and constructed through
|
|
`structure_candidate_collection_construct_and_stream_load_records_then_refresh_counts`
|
|
`0x0041f4e0`, which enters the tagged import owner `0x0041ede0` and then refreshes the aggregate
|
|
filter/year-visible counts through `0x0041e970`; and `0x006ada84` is allocated and constructed
|
|
through `locomotive_collection_construct_and_stream_load_records` `0x00462520`, which enters the
|
|
linked-era locomotive import owner `0x00461f10` and then refreshes the live availability override
|
|
band through `0x00461e00`. The same fan-out now also has explicit constructor ownership for the
|
|
adjacent typed roots: the live company collection `0x0062be10` is constructed through
|
|
`company_collection_construct` `0x00429950`, the live profile/chairman collection `0x006ceb9c`
|
|
is constructed through `profile_collection_construct` `0x00477740`, the live train collection
|
|
`0x006cfcbc` is constructed through `train_collection_construct` `0x004b2340`, the sibling
|
|
indexed collection `0x006acd34` is constructed through
|
|
`runtime_object_collection_construct_vtable_5cae10` `0x00455320`, the support family
|
|
`0x0062b244` is constructed through
|
|
`support_collection_construct_seed_counters_and_clear_large_sideband` `0x0040aeb0`, and the live
|
|
world root `0x0062c120` is published through
|
|
`world_runtime_construct_root_and_seed_global_0x62c120` `0x0044cf70` before the heavier bundle
|
|
load body continues through `0x00449200` and `0x0044cfb0`. The profile-side tagged header
|
|
siblings are explicit too: runtime load re-enters
|
|
`profile_collection_refresh_tagged_header_counts_from_bundle` `0x00477780`, while package save
|
|
later mirrors the same `0x5209/0x520a/0x520b` trio back out through
|
|
`profile_collection_serialize_tagged_header_counts_into_bundle` `0x004777e0`. The same tagged
|
|
symmetry is now bounded for the live company collection too: world-load refresh re-enters
|
|
`company_collection_load_tagged_header_counts_and_refresh_live_records_from_bundle` `0x00429af0`,
|
|
while the package-save path mirrors the same `0x61a9/0x61aa/0x61ab` bracket through
|
|
`company_collection_serialize_tagged_header_counts_and_save_live_records_into_bundle`
|
|
`0x00429b90`, whose per-company callback is currently the no-op stub `0x00424000` while the
|
|
load-side per-company follow-on is `company_refresh_post_load_year_clamp_and_runtime_support_fields`
|
|
`0x004268e0`. The same tagged symmetry is now bounded for the live train collection too:
|
|
world-load refresh re-enters
|
|
`train_collection_load_tagged_header_counts_and_refresh_live_records_from_bundle` `0x004b2700`,
|
|
while the package-save path mirrors the same `0x5209/0x520a/0x520b` header bracket and per-train
|
|
record walk through
|
|
`train_collection_serialize_tagged_header_counts_and_save_live_records_into_bundle`
|
|
`0x004b27a0`; the per-train payload seam itself is now explicit too, with route-list load through
|
|
`train_refresh_tagged_route_list_payload_from_bundle` `0x004a84b0` and route-list save through
|
|
`train_serialize_tagged_route_list_payload_into_bundle` `0x004a7030`.
|
|
The later world-entry reactivation branch correspondingly uses `(1, esi)` rather than `(1, 0)`.
|
|
The current live hook probes now push the remaining auto-load gap much later too: on the
|
|
hook-driven path `shell_transition_mode(4, 0)` returns cleanly, and the full old-mode teardown
|
|
stack under `0x5389c0` now returns too, including `0x5400c0`, the `0x53fe00 -> 0x53f860`
|
|
remove-node sweep over `[object+0x74]`, and the nearby mode-`2` teardown helper `0x00502720`.
|
|
The same live run now also reaches and returns from `shell_load_screen_window_construct`
|
|
`0x004ea620` and the immediate shell publish through `0x00538e50`.
|
|
Its constructor jump table is tighter now too: mode `1` is not the direct `Game.win`
|
|
constructor, but the startup-dispatch arm rooted at `0x483012`; mode `2` enters `Setup.win`,
|
|
mode `3` enters `Video.win`, mode `4` enters the plain `LoadScreen.win` branch at `0x4832e5`,
|
|
mode `5` enters `Multiplayer.win`, mode `6` enters `Credits.win`, and mode `7` enters
|
|
`Campaign.win`. The important static correction is that the startup-runtime slice
|
|
`0x004ea710 -> 0x0053b070(0x46c40) -> 0x004336d0 -> 0x00438890` belongs to mode `1`, not mode
|
|
`4`. Mode `4` only constructs and publishes the `LoadScreen.win` object through `0x004ea620`
|
|
and `0x00538e50`. The older hook-driven `(4, 0)` path therefore was not mysteriously skipping
|
|
the startup-runtime object; it was entering the wrong jump-table arm for that work. The caller
|
|
split above that owner is tighter now too:
|
|
`world_entry_transition_and_runtime_bringup` reaches the same owner at `0x443b57` with `(0, 0)`
|
|
after dismissing the current shell detail panel and servicing `0x4834e0(0, 0)`, while the
|
|
saved-runtime path at `0x446d7f` does the same before immediately building the `.smp` bundle
|
|
payloads through `0x530c80/0x531150/0x531360`. That makes the `LoadScreen.win` startup lane the
|
|
only currently grounded caller that enters `0x438890` with `(1, 0)` instead of `(0, 0)`. The
|
|
remaining runtime uncertainty is narrower now too: the plain-run logs still show the plain
|
|
`LoadScreen.win` state under `(4, 0)`, and the corrected allocator-window run now reinforces the
|
|
same read because the post-construct allocator stream stays empty instead of showing the expected
|
|
`0x46c40` startup-runtime allocation. The first lower allocator probe on `0x005a125d` was not
|
|
trustworthy because that shared cdecl body sits behind the thunk and the initial hook used the
|
|
wrong entry shape, and the first direct thunk hook was also not trustworthy because a copied
|
|
relative-`jmp` thunk cannot be replayed through an ordinary trampoline. But the later corrected
|
|
thunk run plus the jump-table decode now agree: the next meaningful hook-driven test is mode
|
|
`1`, not mode `4`.
|
|
`mode_id = 2`, and it never advanced into `ready gate passed`, staging, or transition. So that
|
|
run did not actually exercise the `0x0053b070 -> 0x004336d0 -> 0x00438890` subchain at all.
|
|
The next runtime pass now lowers the ready-poll defaults to `1` and `0` and adds an explicit
|
|
ready-count log so the mode-`4` startup lane either stages immediately or shows exactly how far
|
|
the gate gets. That adjustment worked on the next run: the hook now stages and completes the
|
|
`shell_transition_mode` path again, with `LoadScreen.win` construction and publish returning
|
|
cleanly. The post-publish startup subchain is no longer unresolved on the static side, though.
|
|
Direct disassembly of the mode-`4` branch at `0x0048302a..0x004830ca` now closes it completely:
|
|
after constructing `LoadScreen.win`, the branch sets shell state `[transition+0x08] = 4`,
|
|
chooses one page scalar `110.0f`, `236.0f`, or `5.0f`, writes that page id through
|
|
`shell_load_screen_window_set_active_page` `0x004ea710`, allocates one `0x46c40`-byte runtime
|
|
object through `0x0053b070`, resets it through
|
|
`world_runtime_reset_startup_dispatch_state_bands` `0x004336d0`, stores the result into
|
|
`0x006cec78`, and then directly enters
|
|
`shell_active_mode_run_profile_startup_and_load_dispatch` `0x00438890` as `(1, 0)` before
|
|
publishing the active-mode object back through `0x005389c0`. So the static startup chain after
|
|
`LoadScreen.win` publish is now explicit rather than inferred from the earlier hook traces. The
|
|
remaining runtime-side question is narrower: why the earlier hook snapshots still showed
|
|
`[LoadScreen.win+0x78] == 0` and `0x006cec78 == 0` immediately after transition return even
|
|
though the static mode-`4` branch does not leave those fields that way once it reaches the
|
|
startup-dispatch path. The internal selector split in `0x438890` is tighter now too:
|
|
`[0x006cec7c+0x01]` is a separate seven-way startup selector, not the shell mode id. Values `1`
|
|
and `7` load `Tutorial_2.gmp` and `Tutorial_1.gmp`, values `3/5/6` collapse into the same
|
|
profile-seeded file-load lane through `0x445ac0([0x006cec7c]+0x11, 4, &out_success)`, value `2`
|
|
is a world-root initialization lane
|
|
that allocates `0x0062c120` and then forces selector `3`, and value `4` is the setup-side world
|
|
reset or regeneration lane that rebuilds `0x0062c120` from `0x006d14cc/0x006d14d0` before later
|
|
world setup continues. The write side is tighter now too: `Campaign.win` writes selector `6`,
|
|
`Multiplayer.win` writes selector `3` on one pending-status path, and the larger `Setup.win`
|
|
dispatcher writes selectors `2`, `3`, `4`, and `5` on its validated launch branches. That makes
|
|
the file-load subfamily read less like one generic save-open branch and more like a shared
|
|
profile-file lane reused by setup, multiplayer, and campaign owners. The world-entry owner
|
|
boundary is tighter now too: `world_entry_transition_and_runtime_bringup` at `0x00443a50` no
|
|
longer stops at the initial shell transition and world allocation head. The same grounded
|
|
function continues through the larger post-load generation tail up to `0x00444dc2`, which means
|
|
the later `Setting up Players and Companies...` and neighboring post-load passes are not
|
|
floating raw callsites after all. That same owner now clearly covers the event-runtime refresh
|
|
through `0x433130`, chairman-profile materialization through `0x437220`, neighboring route and
|
|
tracker refresh families, and the one-shot kind-`8` runtime-effect service through `0x432f40`
|
|
before clearing shell-profile latch `[0x006cec7c+0x97]`. The `Setup.win` dispatcher
|
|
is less opaque now too: the early `0x0bc1..0x0c24` family is mostly fixed submode selection above
|
|
`0x00502c00`, except for the separate `0x0bc2/0x0bc5/0x0bc6/0x0bc7` shell-open quartet above
|
|
`0x00501f20`; `0x0c1f` is the settings-window escape; `0x0c1e/0x0c20/0x0c22` are direct shell
|
|
requests into `0x00482150`; the fixed submode buttons now have concrete lower targets such as
|
|
`0x0bc1/0x0bc8 -> 15`, `0x0bc3 -> 16`, `0x0bc4 -> 1`, `0x0c80 -> 13`, `0x0c1c -> 17`,
|
|
`0x0c1d -> 2`, `0x0c24 -> 14`, `0x0c81 -> 14`, `0x0c82 -> 6`, `0x0c83 -> 10`, and
|
|
`0x0c84 -> 12`; the
|
|
`0x0ce6/0x0ce7/0x0d49/0x0d4a/0x0e82/0x0e83` branches are bounded list or slider adjustments on
|
|
staged setup fields; and the later `0x0dca/0x0dcb/0x0de9/0x0df3/0x0e81/0x0f6f/0x0f70` controls
|
|
are the explicit selector-writing launch buttons rather than one anonymous validated-launch blob.
|
|
The constructor-side callbacks are tighter too: control `0x0ce8` is a table-driven payload-label
|
|
draw callback above `0x00502030`, not another launch root; that callback now clearly sits on top
|
|
of the indexed string-table getter `0x0053de00` before handing the selected text span into the
|
|
world-anchor marker queue path. Controls `0x0e86` and `0x0e87` do not select more setup roots;
|
|
they update the persisted shell-state selector pairs at
|
|
`[0x006cec74+0x233/+0x237]` and `[0x006cec74+0x23b/+0x23f]` through `0x00502160` and
|
|
`0x005021c0`, then immediately save config through `0x00484910(1)`. The constructor body is
|
|
tighter too: it seeds the initial `Setup.win` state by running `0x502910`, `0x502550`, and
|
|
`0x502c00(1)` before the user interacts with the window, installs `0x0c80..0x0c86` and
|
|
`0x0f6f..0x0f71` as homogeneous button bands, and treats `0x0e88` as one separate special
|
|
control with retuned float fields rather than another ordinary launch root. The remaining
|
|
optional constructor child `0x0bd0` is tighter now too: it is built from a separate template
|
|
block and optional owned heap object before registration, not another hidden setup-root button.
|
|
The generic shell helper layer beneath that constructor is tighter now too: `0x53fa50` is the
|
|
shared resource-bind and child-list initialization helper, `0x53f830` is the child-control
|
|
lookup-by-id helper over the intrusive list at `[this+0x70]`, `0x558130` is the child-control
|
|
finalizer that stamps the owner pointer and resolves localized captions before the control goes
|
|
live, and `0x53f9c0` is the ordered child-control registration helper used by the optional
|
|
`0x0bd0` branch and other shell dialogs.
|
|
The submode selector itself is tighter now too because its button-state lane is mostly decoded:
|
|
`0xbc5` tracks submode `15`, `0xbc6` tracks `16`, `0xbba` tracks `2`, `0xbbb` tracks `3`,
|
|
`0xbc3` tracks `13`, `0xbbc` groups `3/4/5`, `0xbbd` tracks `4`, `0xbbe` tracks `5`, `0xbbf`
|
|
groups `6/12/14`, `0xbc0` tracks `7`, `0xbc1` tracks `8`, `0xbc2` tracks `9`, `0xe75` tracks
|
|
`10`, and `0xf6e` tracks `17`. RT3.lng and the setup art families now also make several of those
|
|
top-level roots read less like anonymous ids and more like real menu panels: submode `1` is the
|
|
strongest current landing-panel fit, `2` is the `Single Player` root, `7/8/9` are the
|
|
`Editor` / `New Map` / `Load Map` family, `15` is `Extras`, and `17` is `Tutorial`. By
|
|
elimination against the separate shell `Credits.win` mode, the remaining top-level `Setup.win`
|
|
roots now most safely read as `13 = Multi Player` and `16 = High Scores`.
|
|
The file-backed side is tighter too: `0x502c00` now maps submodes exactly as `4 -> dataset 5`,
|
|
`9 -> 4`, `6 -> 8`, `10 -> 6`, `12 -> 10`, and `14 -> 9`, so the saved-game-backed family is
|
|
no longer one blurred list pane but a small set of stable dataset variants above
|
|
`0x4333f0/0x4336a0`.
|
|
The file-list builder under that pair is tighter too: `0x4333f0` no longer just emits unsorted
|
|
`0x25a`-byte rows with raw names at `+0x0` and normalized labels at `+0x12d`. After the scan it
|
|
now clearly re-enters `0x51dc60`, which is a generic adjacent-swap insertion sort over fixed
|
|
records; in this setup-side caller it receives `record_size = 0x25a` and `key_offset = 0x12d`,
|
|
so the resulting `Setup.win` rows are sorted by display label rather than by the raw filename.
|
|
The file-backed header split is tighter too: `0x5027b0` now maps the top header-control ids as
|
|
`4 -> 0xd4b`, `9 -> 0xde8`, `6/12/14 -> 0xdf2`, and `10 -> 0xe85`. RT3.lng closes one earlier
|
|
mistake here: those values are local setup control or resource ids, not localized text ids.
|
|
The setup art bundle now tightens that family split one step further too: under `rt3_2WIN.PK4`
|
|
the distinct file-backed setup art families are the shared `Setup_Load` lane and the separate
|
|
`Setup_Sandbox` lane, which matches the selector-side evidence that mode `10` is the
|
|
sandbox-backed `new` list while mode `12` is its `load` sibling. Combined with the builder at
|
|
`0x4333f0`, that shows only submodes `4` and `10` using the alternate localized-stem list-label
|
|
path; `6`, `9`, `12`, and `14` keep the direct filename-normalization lane.
|
|
The `rt3_2WIN.PK4` extraction path is grounded a bit more cleanly now too: current `pack4`
|
|
samples use a shared `0x03eb` header, a fixed `0x4a`-byte directory entry stride, and a payload
|
|
base at `8 + entry_count * 0x4a`. In the checked UI bundle the entry table is contiguous and
|
|
`Campaign.win` extracts cleanly at directory index `3` with payload length `0x306a`.
|
|
The extracted `.win` payload family now has one narrow shared shape too: `Campaign.win`,
|
|
`CompanyDetail.win`, and `setup.win` all share the same first `0x50` bytes at offsets
|
|
`0x00`, `0x0c`, `0x10`, `0x14`, `0x34`, `0x38`, `0x40`, and `0x48`, while
|
|
`CompanyDetail.win` and `setup.win` also carry an inline root `.imb` name immediately at
|
|
`0x51`. Current resource scans show `Campaign.win` embedding the `litCamp*/Ribbon*` family,
|
|
`CompanyDetail.win` embedding mainly `CompanyDetail.imb`, `GameWindow.imb`, and `Portrait.imb`,
|
|
and `setup.win` embedding the broader `Setup_Background/Buttons/New_Game/Load/Sandbox` art
|
|
families. The control records between those strings are still undecoded, but the resource-record
|
|
shell itself is tighter now: all checked `.win` samples use the same three-word prelude prefix
|
|
`0x0bb8, 0x0, 0x0bb9`, and the fourth prelude word matches `resource_name_len + 1`. The next
|
|
word after the terminating NUL then behaves like a per-record selector lane. In `setup.win`
|
|
the dominant `Setup_Buttons.imb` family alternates between `0x00040000` and the incrementing
|
|
`0x00010c1c..0x00010c86` series with dominant inter-record strides `0xb7/0xdb`; in
|
|
`Campaign.win` the `litCamp*/Ribbon*` family carries the incrementing `0x0004c372..0x0004c38e`
|
|
selector block with dominant `0x158/0x159` and `0xb2/0xb3` strides. That campaign lane is now
|
|
directly aligned to the executable-side control ids too: the low 16 bits of
|
|
`litCamp1..16` map exactly to `0xc372..0xc381`, and the low 16 bits of `Ribbon1..16` map
|
|
exactly to `0xc382..0xc391`, matching the `Campaign.win` progress and selector control bases
|
|
already grounded from `RT3.exe`. The fuller selector export now tightens the auxiliary families
|
|
too: `litArrows.imb` covers `0xc36c..0xc371` exactly and `litExits.imb` covers
|
|
`0xc397..0xc39a` exactly, matching the constructor-side six-control arrow strip and four-control
|
|
exit strip. The second post-name dword is tighter now too: its middle 16-bit lane groups those
|
|
same `Campaign.win` records under `0xc368`, `0xc369`, `0xc36a`, and `0xc36b`, which matches the
|
|
four page-strip controls and cleanly buckets the first five campaign entries, the next five, the
|
|
next three, and the final three under the same page families. There are still no `.imb`
|
|
selector records for `0xc393..0xc396` or `0xc39b`, which makes those message-side page-write
|
|
controls look more like structural buttons than art-backed repeated resource records.
|
|
The grouped `3/4/5` family is narrower now too: `0x0ce5` is no longer part of it, because that
|
|
control writes selector `3` and then selects submode `9` as the `Load Map` sibling. The nearby
|
|
`0x0dcb` branch instead conditionally selects submode `5` or `3`, which keeps `3` as the
|
|
strongest current `New Game` / `Options` companion and `5` as the strongest current `Sandbox`
|
|
companion. The file-backed single-player side is tighter in the same way now: modes `4` and `10`
|
|
are the only siblings using the alternate localized-stem row-label path, so they now read most
|
|
safely as the two setup-local template or profile list variants rather than ordinary save lists.
|
|
Mode `10` is the stronger one of the pair because neighboring validated launch control `0x0e81`
|
|
both routes into selector `5` and sets sandbox byte `[0x006cec7c+0x82] = 1`, which makes it the
|
|
strongest current fit for the setup-local `New Sandbox` list. The distinct `Setup_Sandbox` art
|
|
family in `rt3_2WIN.PK4` now reinforces that same split one step further, which makes mode `12`
|
|
the strongest closed fit for the paired `Load Sandbox` lane; mode `4` is therefore the strongest
|
|
remaining non-sandbox peer in that same pair and now most safely reads as the setup-local `New
|
|
Scenario`-style chooser. Modes `6`, `12`, and `14` now tighten one step further as the three
|
|
selector-`3` direct-filename setup-local `load` siblings because they stay on the direct
|
|
filename-normalization lane, share the same `0xdf2` header family, and clear the same
|
|
presence-style latch `[0x006cec7c+0x97]`; mode `14` is the strongest current landing panel for
|
|
that cluster because `0x0c24` jumps to it directly while `0x0c82` and `0x0c84` only reach the
|
|
sibling modes `6` and `12` from inside the same load family. Current control-pairing and
|
|
setup-art evidence now make `12 = Load Sandbox` the strongest closed per-submode assignment. The
|
|
remaining non-sandbox pair is closed now too: the deeper bundle filter at `0x433260`
|
|
distinguishes dataset `9` from dataset `8` by one extra nonzero payload-flag family, and the
|
|
editor-side metadata path now grounds `[0x006cec78+0x66de]` as the direct `Campaign Scenario`
|
|
checkbox bit because `editorDetail.win` ties control `0x5b6e` to localized ids `3160/3161`.
|
|
That makes dataset `9` the campaign-designated load family and dataset `8` the ordinary scenario
|
|
load family, so `14 = Load Campaign` and `6 = Load Scenario` now read as grounded rather than
|
|
residual. `0x502910` is
|
|
tighter in a
|
|
corrective way too: it is not a mode-`3`-only helper after all, but the shared non-file-backed
|
|
payload panel that formats
|
|
`0xcf3/0xcf4/0xcf5/0xd4f`, mirrors option byte `[0x006cec7c+0x7d]` into `0x0ce9..0x0ced`,
|
|
rebuilds row host `0x0ce8` from payload bytes `[+0x31b/+0x31c]`, and mirrors live row markers
|
|
into `[0x006cec7c+0x87]`. That makes mode `3` just one user of the shared payload-driven panel,
|
|
not the sole owner of it.
|
|
The payload-helper cluster under that panel is tighter now too: `0x502220` does not just
|
|
republish labels and the preview surface. It first re-enters
|
|
`shell_setup_load_selected_profile_bundle_into_payload_record` `0x442400`, which clears one full
|
|
`0x100f2`-byte setup payload record, builds a rooted path from the staged profile stem, opens the
|
|
selected bundle through `0x530c80`, and then reads either the ordinary saved-profile chunk family
|
|
or the map-style chunk family through `0x531150/0x531360` depending on the selected extension
|
|
shape. Only after that does `0x502220` copy payload fields `+0x14/+0x3b2/+0x3ba/+0x20` into the
|
|
staged runtime profile through `0x47be50`, which in turn normalizes the payload category bytes at
|
|
`[payload+0x31a + row*9]` and the local marker-slot bytes at `[payload+0x2c9..]` through
|
|
`0x47bc80`. The copied-field consumer split is tighter now too: payload `+0x14` becomes staged
|
|
profile `[0x006cec7c+0x77]`, which is the visible setup scalar later formatted into controls
|
|
`0x0e84` and `0x0d4f` and adjusted by the `0x0d49/0x0d4a` pair; payload `+0x3b2` becomes
|
|
`[0x006cec7c+0x79]`, the live-row threshold that the payload-row draw callback uses to choose
|
|
style slot `0x18` versus `0x19`; and payload `+0x3ba` becomes `[0x006cec7c+0x7b]`, the current
|
|
scroll or row-index lane adjusted by the `0x0ce6/0x0ce7` pair. So the known setup-side payload
|
|
consumers still stop well before the later candidate table, but the early copied lanes are no
|
|
longer anonymous. The adjacent region-side worker family is tighter in a negative way too: the setup
|
|
payload path now gives one useful upper bound on the newer candidate-availability source block
|
|
too. The map-style setup loader is definitely pulling chunk families `0x0004/0x2ee0/0x2ee1`
|
|
into one large `0x100f2`-byte payload record, and the fixed `0x6a70..0x73c0` candidate table
|
|
clearly lives inside the same broad file family; but the grounded setup-side consumers we can
|
|
actually name after that load still only touch earlier payload offsets such as `+0x14`,
|
|
`+0x20`, `+0x2c9`, `+0x31a`, `+0x3ae`, `+0x3b2`, and `+0x3ba`. So the current evidence is
|
|
strong enough to carry the candidate table conservatively as a lower setup-side candidate-table
|
|
slab inside the broader setup payload family, even though the current named setup-side consumers
|
|
still land only on earlier payload offsets. The newer fixed-offset compare pass tightens that
|
|
lower setup slice too: across the checked map/save pairs `Alternate USA.gmp -> Autosave.gms`,
|
|
`Southern Pacific.gmp -> p.gms`, and `Spanish Mainline.gmp -> g.gms`, the known setup payload
|
|
lanes `+0x14` and `+0x3b2` are preserved map-to-save on the same scenario-family split as the
|
|
later candidate-table headers (`0x0771/0x0001`, `0x0746/0x0006`, `0x0754/0x0001`), while
|
|
`+0x3ae` stays fixed at `0x0186` and `+0x3ba` stays fixed at `1` across all six files. By
|
|
contrast, `+0x20` does not survive as one shared source value (`0xd3 -> 0xb4`,
|
|
`0x6f -> 0x65`, `0xe3 -> 0x78` across those same pairs). So the current best read is that the
|
|
setup payload mixes preserved scenario metadata and later save-variant state well before the
|
|
`0x6a70` candidate table, rather than acting as one uniformly copied prelude.
|
|
The adjacent region-side worker family is tighter in a negative way too: the setup
|
|
payload loader is now clearly separate from the broader region-building and placement cluster
|
|
around `0x422320..0x423d30`, whose current grounded helpers now include `0x422320`, `0x4228b0`,
|
|
`0x422900`, `0x422a70`, `0x422be0`, `0x422ee0`, `0x4234e0`, `0x4235c0`, and
|
|
`world_region_refresh_cached_category_totals_and_weight_slots` `0x423d30` rather than one hidden
|
|
setup-only panel. The leading region helper is no longer unnamed either: `0x422320` is now
|
|
bounded as the recurring cached-structure-scalar normalization pass that writes
|
|
`[region+0x2e2/+0x2e6/+0x2ea/+0x2ee]`, while `0x422a70` is the shared placement-validation and
|
|
commit gate beneath both the per-region worker and one second world-side placement loop. The
|
|
neighboring `0x4234e0` accessor is tighter too: it is the shared projected structure-count scalar
|
|
query by category that later feeds both the per-region placement family and the map-editor city
|
|
count stats report. So the remaining gap is no longer “what are these setup payload helpers
|
|
doing,” but only how aggressive we want to be when naming the last top-level setup roots from
|
|
mostly RT3.lng and asset-side evidence.
|
|
The adjacent summary helper is tighter too: `0x502550` is not another hidden submode owner. It
|
|
republishes the staged path tail in `0xe7f`, the scalar summary in `0xe84`, the two persisted
|
|
selector lists in `0xe86/0xe87`, and the config toggles in `0xe88/0xe89/0xe8a`.
|
|
The remaining top-level gap is cleaner now too: submode `16` still has no distinct downstream
|
|
helper or launch branch in the local selector/refresh family, but it is no longer a blank bucket.
|
|
Current evidence now bounds it as the `0x0bc3 -> 16` top-level button whose visual-state lane is
|
|
surfaced through control `0xbc6`, and the strongest residual fit is `High Scores` because
|
|
`Credits` already lives in separate shell mode `6`.
|
|
The validated launch lane is tighter now too: it no longer just writes selector `3` or `5` as
|
|
one undifferentiated blob, and it no longer includes `0x0ce5` or `0x0dcb`. `0x0ce5` is the
|
|
`Load Map` selector because it writes selector `3` and then selects submode `9`, while `0x0dcb`
|
|
is the later conditional `5/3` companion-selector sibling rather than a file launch. The actual
|
|
validated staged-profile lane is now bounded more narrowly: `0x0cf6` and `0x0e81` are the
|
|
selector-`5` siblings, while the neighboring selector-`3` validated lane is at least shared by
|
|
`0x0de9` and `0x0df3`; the shared bridge at `0x4425d0` then forces `[0x006cec7c+0xc5] = 1`,
|
|
mirrors payload bytes into `[profile+0xc4]`, `[profile+0x7d]`, and `[profile+0xc6..+0xd5]`, and
|
|
only then issues shell request `0x0cc`. The file-side staging bytes in that bridge are now
|
|
tighter too: across the checked `Alternate USA`, `Southern Pacific`, and `Spanish Mainline`
|
|
map/save pairs, payload `+0x33` stays `0`, but payload `+0x22` and token block `+0x23..+0x32`
|
|
do not preserve the earlier map-to-save pairing seen at `+0x14/+0x3b2`. Instead they split by
|
|
the finer file family, with examples `Alternate USA.gmp = 0x53 / 0131115401...` versus
|
|
`Autosave.gms = 0xae / 01439aae01...`, `Southern Pacific.gmp = 0xeb / 00edeeeb...` versus
|
|
`p.gms = 0x21 / 0100892101...`, and `Spanish Mainline.gmp = 0x5b / 0044f05b...` versus
|
|
`g.gms = 0x7a / 0022907a...`. So the validated launch bridge now looks more like a file-family
|
|
staging lane than a simple copy-forward of the earlier setup summary fields. The destination-side
|
|
consumers are tighter now too: `[profile+0xc4]` is no longer just an unnamed staged byte, but the
|
|
campaign-progress slot later consumed by the numbered `%s%02d.gmc` save helper `0x00517c70`;
|
|
`[profile+0x7d]` is the same compact option byte mirrored back into the `Setup.win` option
|
|
controls `0x0ce9..0x0ced`; and the campaign-side selector block is no longer only a one-byte
|
|
anchor. Direct `RT3.exe` disassembly of the campaign-side dispatcher at `0x004b89c0` now shows
|
|
the exact mirror shape: when the local campaign-page selector `[window+0x78] <= 4`, the helper
|
|
writes one highlighted progress control `0x0c372 + [profile+0xc4]` and then mirrors the full
|
|
sixteen-byte band `[profile+0xc6..+0xd5]` into controls `0x0c382..0x0c391` through repeated
|
|
`0x540120` calls. The same body also treats `[profile+0xc4]` as an index into the fixed
|
|
sixteen-entry scenario-name table at `0x00621cf0`, whose observed entries include `Go West!`,
|
|
`Germantown`, `Central Pacific`, `Texas Tea`, `War Effort`, `State of Germany`, `Britain`,
|
|
`Crossing the Alps`, `Third Republic`, `Orient Express`, `Argentina Opens Up`,
|
|
`Rhodes Unfinished`, `Japan Trembles`, `Greenland Growing`, `Dutchlantis`, and
|
|
`California Island`. On the launch-side branch the same helper writes startup selector `6`,
|
|
copies the resolved campaign filename into `[profile+0x11]`, forces `[profile+0xc5] = 1`, and
|
|
then issues shell request `0x0cc`. The lower refresh tail at `0x004b8d49..0x004b8d69` also
|
|
shows the observed page-band split over the same progress byte: values `< 5` pair with campaign
|
|
page `1`, values `5..9` with page `2`, values `10..12` with page `3`, and values `>= 13` with
|
|
page `4`. So `[profile+0xc6..+0xd5]` is no longer a generic opaque span at all, but the staged
|
|
sixteen-byte per-scenario campaign selector or unlock band consumed directly by `Campaign.win`.
|
|
The neighboring profile helpers are tighter now too: `0x0047bbf0` is the broad default reset for
|
|
the staged `0x108`-byte runtime-profile record, clearing the whole record and then reseeding the
|
|
visible setup and campaign anchors `[profile+0x77]`, `[profile+0x79]`, `[profile+0x7d]`, the
|
|
random-like dword `[profile+0x83]`, the first setup row-marker byte `[profile+0x87]`, and the
|
|
file-backed launch or rehydrate latch `[profile+0x97]`; `0x00502c00` is now tighter on the same
|
|
slab because its file-backed lane copies the selected row's primary and secondary `0x32`-byte
|
|
string bands into `[profile+0x11]` and `[profile+0x44]` while arming presence byte
|
|
`[profile+0x10]`; and `0x0047bc50` is the compact scan helper over `[profile+0xc6..+0xd5]` that
|
|
returns the first selector byte below `2`, which keeps that band tied to staged campaign progress
|
|
or unlock state rather than to the earlier setup-panel payload fields.
|
|
The message-dispatch side is tighter now too. The local classifier at `0x004b91d8` routes the
|
|
control range `0x0c352..0x0c39b` through five concrete case classes: `0x0c352..0x0c361` enter
|
|
the shared selector or launch branch, `0x0c362..0x0c367` force local page `1`,
|
|
`0x0c368..0x0c392` force local page `2`, `0x0c393..0x0c396` force local page `0`, and
|
|
`0x0c39b` alone forces local page `3`. That matches the constructor and refresh shape: the
|
|
sixteen scenario selector controls live at `0x0c352..0x0c361`, the four page-strip controls
|
|
live at `0x0c368..0x0c36b`, the six-arrow auxiliary strip lives at `0x0c36c..0x0c371`, the
|
|
progress band lives at `0x0c372..0x0c381`, the ribbon or selector band lives at
|
|
`0x0c382..0x0c391`, the string or voice target lane lives at `0x0c392`, the four exit controls
|
|
live at `0x0c397..0x0c39a`, and `0x0c39b` remains the one-off special action control that
|
|
spawns or dismisses the campaign-side companion object. The `Campaign.win` blob now exposes that
|
|
structural split directly too: alongside the art-backed `0x0004c3xx` records it carries
|
|
anonymous zero-name records with the same `0x0bb8 / 0 / 0x0bb9` prelude but selector words in
|
|
the `0x0010c3xx` family. Current local extraction shows exactly
|
|
`0x0010c352..0x0010c361`, `0x0010c362..0x0010c367`, `0x0010c393..0x0010c396`, and one
|
|
`0x0010c39b` record, which is the same non-`.imb` band the message dispatcher treats as the
|
|
structural selector and page-write family. Their second selector word then buckets those records
|
|
under the same page-strip ids as the art-backed records: `0xc368` for
|
|
`0xc352..0xc356`, `0xc362`, `0xc393`, and `0xc39b`; `0xc369` for `0xc357..0xc35b`,
|
|
`0xc363`, and `0xc394`; `0xc36a` for `0xc35c..0xc35e`, `0xc365..0xc366`, and `0xc395`; and
|
|
`0xc36b` for `0xc367`, `0xc35f..0xc361`, and `0xc396`. One final anonymous record at
|
|
`0x0002c392` has no page bucket at all, which fits the already-grounded read of `0xc392` as the
|
|
one-off string or voice target lane rather than a normal page-cell control. The anonymous body
|
|
layout is only partially named, but one file-side distinction is already stable: the ordinary
|
|
structural selector/page records all carry footer words `0xd3000000` and `0xd2000007` at
|
|
relative `+0x98/+0x9c`, while the lone `0xc392` record carries `0x00000000/0x00000000` there.
|
|
So `0xc392` is no longer just “outside the page buckets”; it is also the only current
|
|
anonymous-record outlier in that trailing structural footer pair. The structural selector side is
|
|
tighter now too: `0xc352..0xc361` partition exactly as `5 + 5 + 3 + 3` across page buckets
|
|
`0xc368..0xc36b`, matching the observed campaign page bands for scenario progress values `< 5`,
|
|
`5..9`, `10..12`, and `>= 13`. That makes the anonymous selector records the file-side mirror of
|
|
the same campaign page split, not a separate unrelated control family. The file-order adjacency
|
|
is tighter in the same way: `0xc352..0xc361` each sit immediately after one `RibbonN.imb`
|
|
record and before the next `litCamp` record, which makes them the strongest current file-side fit
|
|
for the structural selector or click-target siblings of the visible campaign ribbon controls.
|
|
The auxiliary anonymous bands line up the same way: `0xc362..0xc367` sit inside the local
|
|
`litArrows.imb` clusters, `0xc393..0xc396` sit inside the `litExits.imb` clusters, and
|
|
`0xc39b` sits once between the first arrow and first exit group. So the current best read is
|
|
that those anonymous records are the structural hitbox or action siblings of the visible arrow,
|
|
exit, and selector art families, not an unrelated hidden control layer. The generic record
|
|
cadence is tighter now too: in the current `Campaign.win` dump the ordinary anonymous structural
|
|
records all span `0x0a7` bytes, while the named art-backed records cluster at `0x0b1`, `0x0b2`,
|
|
and `0x0b3`. The only two visible outliers are the leading `0x0080c351` record at `0x0041`
|
|
with span `0x0a3`, and the trailing `0x0002c392` record at `0x2fb9` with span `0x0b1`. That
|
|
reinforces the current read that `0xc351` and `0xc392` are one-off structural controls flanking
|
|
the main selector or page family rather than ordinary repeated art-backed records.
|
|
The setup-launch corpus now tightens one corrective caveat there too: when the checked
|
|
`Alternate USA`, `Southern Pacific`, and `Spanish Mainline` `.gmp/.gms` files are decoded with
|
|
that same campaign-side interpretation, payload byte `+0x22` is always outside the known
|
|
campaign progress range `0..15` (`0x53`, `0xeb`, `0x5b`, `0xae`, `0x21`, `0x7a`), so the
|
|
ordinary validated setup lane is not simply staging a normal campaign-screen state. The paired
|
|
token block `+0x23..+0x32` is still structurally compatible with the campaign selector band, but
|
|
in the checked files it only populates a small recurring subset of the sixteen scenario lanes,
|
|
chiefly `Go West!`, `Germantown`, `Central Pacific`, `Texas Tea`, and `War Effort`, with
|
|
scenario-family-specific byte values rather than a simple `0/1` unlock bitmap. That makes the
|
|
setup-side staging bridge look more like one shared destination layout being reused for a broader
|
|
launch token family, not a proof that ordinary setup-launched `.gmp/.gms` content is already in
|
|
campaign-screen form.
|
|
Only `0x0e81` also sets `[0x006cec7c+0x82] = 1`, which is currently the strongest sandbox-side
|
|
anchor beneath the later `.gmx` load family.
|
|
That launch band is slightly tighter now too: `0x0dca` is the grayscale-map picker branch above
|
|
the `TGA Files (*.tga)` / `.\Data\GrayscaleMaps` helper at `0x004eb0b0`, not another ordinary
|
|
save-file validator. That launch band is tighter in a second way too: `0x0ddf` is not a lobby
|
|
branch after all, but the separate windowed-mode-gated grayscale-heightmap generation path. It
|
|
reopens the `TGA Files (*.tga)` / `.\Data\GrayscaleMaps` picker through `0x0042a970`, validates
|
|
the chosen image through `0x005411c0`, and only then writes startup selector `2`. The fixed-
|
|
button side is tighter too: submode `15` now aligns with the `Extras` family because it sits
|
|
above the Readme/Weblinks shell-open quartet and the return-to-extras sibling, while submode
|
|
`17` now aligns with the tutorial chooser because it is the only branch that later exposes
|
|
startup selectors `1` and `7`, which RT3 uses for `Tutorial_2.gmp` and `Tutorial_1.gmp`. The
|
|
map-root family is tighter too: submodes `7/8/9` are the only setup branch that flips the file
|
|
root into
|
|
`maps\\*.gm*`, with mode `8` specifically the grayscale-heightmap picker and mode `9` the
|
|
file-backed map-list sibling.
|
|
Submode `13` is slightly tighter now too: current local evidence shows that it stays outside
|
|
both the dedicated file-backed pane and the mode-`3` option-heavy pane, so it is best read for
|
|
now as one top-level non-file-backed setup branch rather than another saved-game list variant.
|
|
The setup-side file roots are tighter now too: the shared file-list builder at `0x4333f0`
|
|
formats either `saved games\\*.smp` or `maps\\*.gm*` from the shell-state fields at
|
|
`[0x006cec74+0x68/+0x6c]`, with the separate `data\\tutorial` root only appearing on the
|
|
tutorial-side `[shell+0x6c] == 2` branch. That means the `Setup.win` submode families are no
|
|
longer one generic file pane: the ordinary setup-backed `.smp` family is broader than the
|
|
narrower file-list pane, because modes `3/4/5/6/10/12/14` stay on the ordinary saved-game side
|
|
while only `4/6/9/10/12/14` re-enter the dedicated file-list panel at `0x5027b0`; the `maps`
|
|
branch is the narrower setup or tutorial launch family above the same shared record builder.
|
|
- Evidence: function-map map/scenario rows, analysis-context exports for `0x00445ac0`, `0x00445de0`,
|
|
`0x00443a50`, `0x00434300`, and `0x00444dd0`, plus objdump string and mode-table evidence for
|
|
`.gmp`, `.gmx`, `.gmc`, `.gms`, `.gmt`, `.smp`, `Quicksave`, the `0x004dd010` mode table at
|
|
`0x005f3d58`, the auxiliary-owner presence check at `0x00434050`, and the `.gmt` handoff through
|
|
`0x00469d30`, together with localized string evidence from ids `3018` and `3898`.
|
|
- Direct shell stubs above that coordinator are tighter now too: `0x004408b0` is the ordinary
|
|
`Save game` wrapper and forwards the pure zero-flag triplet into
|
|
`shell_map_file_world_bundle_coordinator`; `0x004408d0` is the sibling `Quick save` wrapper,
|
|
forwarding flag triplet `(0, 1, 0)`. RT3.lng closes the neighboring `shell_map_file_entry_coordinator`
|
|
pair in the same way: `0x00441ac0` is `Load game` and `0x00441af0` is `Quick load`, with the
|
|
same `(0, 0, 0)` versus `(0, 1, 0)` split above `0x00445ac0`.
|
|
- Current Boundary: bit `0x1` on both broad coordinators now grounds the Quicksave name seed and
|
|
the former third `fileopt.win` flag has been ruled out as a file-flow question because it just
|
|
opens `SettingsWindow.win`. The extension family is now carried conservatively as `.gmp` for the
|
|
editor-map pair, `.gms` for the standalone scenario family, `.gmc` for the campaign-scenario
|
|
family, `.gmx` for the sandbox family, and `.gmt` for the auxiliary preview-surface branch rather
|
|
than another gameplay save family. The higher-value handoff boundary is also closed at the
|
|
current evidence level: after this bring-up, long-lived simulation cadence still rendezvous with
|
|
the same shell-owned frame path rather than surfacing a detached gameplay-only outer loop.
|