Split input/save/load atlas and update references

This commit is contained in:
Jan Petykiewicz 2026-04-12 10:12:10 -07:00
commit 81316e6e49
13 changed files with 5301 additions and 4113 deletions

View file

@ -15,4 +15,12 @@ section files when adding or reviewing grounded narrative content.
- [map-and-scenario-content-load.md](/home/jan/projects/rrt/docs/control-loop-atlas/map-and-scenario-content-load.md)
- [multiplayer-session-and-transport-flow.md](/home/jan/projects/rrt/docs/control-loop-atlas/multiplayer-session-and-transport-flow.md)
- [input-save-load-and-simulation.md](/home/jan/projects/rrt/docs/control-loop-atlas/input-save-load-and-simulation.md)
Input/Save/Load subsections:
- [runtime-roots-camera-and-support-families.md](/home/jan/projects/rrt/docs/control-loop-atlas/runtime-roots-camera-and-support-families.md)
- [post-load-generation-paintterrain-and-save-load-restore.md](/home/jan/projects/rrt/docs/control-loop-atlas/post-load-generation-paintterrain-and-save-load-restore.md)
- [event-editors-companydetail-and-loadscreen.md](/home/jan/projects/rrt/docs/control-loop-atlas/event-editors-companydetail-and-loadscreen.md)
- [editor-breadth.md](/home/jan/projects/rrt/docs/control-loop-atlas/editor-breadth.md)
- [station-detail-overlay.md](/home/jan/projects/rrt/docs/control-loop-atlas/station-detail-overlay.md)
- [next-mapping-passes.md](/home/jan/projects/rrt/docs/control-loop-atlas/next-mapping-passes.md)

View file

@ -0,0 +1,912 @@
# Input, Save/Load, and Simulation: Editor Breadth
### Editor Breadth
The broader map-editor page owner is now bounded through
`map_editor_panel_select_active_section` `0x004ce070` and
`map_editor_panel_dispatch_active_section_message` `0x004cf700`, which switch among the grounded
setup pages, `Cities/Regions`, `Territories`, the `Players` and `Player Pool` setup slices, the
now-grounded `Building Density` page, the locomotives-available and industry-availability pages,
the economic and special-condition pages, the `Port/Warehouse Cargos` page, and the later report
pages. The mid-editor ownership is materially clearer now too: the chairman-slot editor is the
`Players` page, the available-chairman editor is the `Player Pool` page, and the former unnamed
dual tri-state page now lines up with localized page text `997` `Building Density` plus help text
`1017` and the direct field captions `1642` `Starting Building Density Level:` and `1644`
`Building Density Growth:`. Both controls are now bounded as stored ordinal bytes `0/1/2` rather
than loose labels: the first three-choice control is the map-wide starting-density selector, with
its default middle state `1` matching the documented `100%` baseline from `1643`; the second is
the paired overall growth selector whose effects later appear in the city-growth side of the
simulation. `map_editor_city_region_panel_construct` and
`map_editor_city_region_panel_handle_message` own the city-or-region editing lane with rename and
copy-industry-data flows. That copy side is tighter now too: the handler first enters
`0x00420e00`, which rebuilds the selected region's profile collection `[region+0x37f]`, clones
the source region's live label-weight entries when a source region is present, and otherwise
reseeds a fixed default weight set through repeated `0x004206b0` calls. The no-source companion
`0x00420ed0` now makes that split explicit: it rebuilds the same subcollection and then picks one
of two fixed default label-weight sets based on region class dword `[region+0x23e]`, using one
all-`0.2f` family for nonzero-class regions and one class-`0` family that starts with `0.3f`
before continuing with repeated `0.2f` entries. The lower mutator
`0x004206b0` then linearly scans the selected region subcollection by profile label, creates a
new profile only when the copied weight is positive, removes an existing profile when the copied
weight is non-positive, updates `[entry+0x1e]` otherwise, and refreshes the region's derived
availability-summary bytes `[region+0x2f6/+0x2fa/+0x2fe]` through `0x00420410`; `map_editor_territory_panel_construct` and
the adjacent no-source companion `0x00420ed0` is tighter too: it rebuilds the same collection
root `[region+0x37f]` but then seeds one of two fixed default profile-label sets directly through
repeated `0x004206b0` calls, splitting by region class dword `[region+0x23e]`. Nonzero-class
regions take one all-`0.2f` default set, while class-0 regions take a different set that starts
with one `0.3f` weight before continuing with repeated `0.2f` entries. That makes `0x420ed0`
the true class-split default-profile companion to the source-cloning helper at `0x420e00`,
rather than just more of the same editor copy path. Two neighboring collection queries are tight
enough now too. `0x00421d20` counts how many live regions have at least one profile row in
`[region+0x37f]` whose label matches the candidate-name string for one caller-supplied candidate
id; `0x00421e30` resolves the Nth such matching region. Both helpers reuse the same
`0x0041fac0` ordinal label-and-weight copy helper we just grounded, only increment once per
region, and skip nonzero-class regions whose companion count `[region+0x242]` is nonpositive.
Those two queries are what the editor summary side at `0x004cdd56/0x004cdeab` uses before it
formats per-region lists for one selected industry or profile name. The adjacent world-facing
query strip is bounded too: `0x00422010` scans the live region collection for class-0 regions
whose normalized coordinates fall inside one caller-supplied float rectangle, keeps the nearest
region id `[region+0x23a]` by squared XY distance through `0x0051db80`, and returns `0` when no
qualifying region is found; `0x004220b0` is the small wrapper above it that returns the matched
region name `[region+0x356]` or the fallback localized scratch string at `0x0062ba90`.
`map_editor_territory_panel_construct` and
`map_editor_territory_panel_handle_message` own the territory rename and border-remap lane;
`map_editor_locomotive_availability_panel_construct` plus
`map_editor_locomotive_availability_panel_handle_message` now bound the locomotive policy page
over `0x006ada84`; `map_editor_industry_availability_panel_construct` plus
`map_editor_industry_availability_panel_handle_message` do the same for the industry candidate
pool at `0x0062b268`; and `map_editor_port_warehouse_cargo_panel_construct` plus
`map_editor_port_warehouse_cargo_panel_handle_message` now ground the recipe-book page that edits
port or warehouse cargo policies through twelve per-book state blocks at
`[0x006cec78+0x0fe7+index*0x4e1]`. Each book now has a shared maximum annual production float at
`book+0x3ed` and five fixed cargo-line entries starting at `book+0x3f1` with stride `0x30`; each
line is bounded as a mode dword, annual amount, a supplied-cargo token at `+0x08`, and a
demanded-cargo token at `+0x1c`. The constructor and handler now make those fields materially
tighter too: the row pair shown in `Supply Only` and `Production Demand->Supply` is the `+0x08`
supplied-cargo selector, the row pair shown in `Demand Only` and `Production Demand->Supply` is
the `+0x1c` demanded-cargo selector, and the single amount field at `+0x04` is labeled `Annual
Demand:` only in mode `1` but `Annual Supply:` in modes `2/3`. The stronger new runtime-side
result is now a full chain rather than only the importer:
`scenario_state_rebuild_port_warehouse_cargo_recipe_runtime_tables` first imports those same five
lines into one repeated array of identical `0xbc`-byte runtime descriptors with no row-index
special casing, and the candidate-side rebuild pass at
`structure_candidate_collection_rebuild_runtime_records_from_scenario_state` `0x00412d70` then
projects those descriptors into the live structure collection at `0x0062ba8c` before
`structure_candidate_rebuild_cargo_membership_and_scaled_rate_tables` `0x00411ee0` rebuilds the
per-cargo runtime summary tables. The current local file-side result is now tighter too: the
grounded recipe-book root at `0x0fe7` is preserved byte-for-byte across the checked map/save
scenario pairs, so the loader can safely treat the twelve `0x4e1`-byte books as preserved
scenario payload rather than a drifting save-only band. A conservative summary probe now only
reports per-book head signatures, raw cap dwords at `+0x3ed`, and five raw line summaries rooted
at `+0x3f1` so the file-side structure stays aligned with this grounded ownership. The
player-facing line modes remain `Disabled`, `Demand Only`, `Supply Only`, and
`Production Demand->Supply`, and the fourth mode is tighter now too: current wording around
`1674`, `1675`, and `504` plus the downstream scaling path says it is the
production-line mode governed by the shared annual production cap, where the entered annual amount
stays on the supply side while the demanded side becomes the normalized input branch. The
candidate-side accumulator pass reinforces that split by applying the shared production cap only
to the supply-half runtime branch and bypassing that scaling on the normalized demand half. The
lower gameplay side is tighter now too: `structure_candidate_query_cargo_runtime_summary_channels`
`0x00412650` is the first grounded consumer beneath that rebuild chain, because it lazily rebuilds
four per-cargo summary banks and returns one direct-supply channel, one cap-normalized supply
channel, one demand or input channel, and one scaled production-output subrow channel for a
requested cargo id. The internal indexing is tighter now too: the direct-supply lane indexes from
`[desc+0x1c]`, the demand or input lane uses that same resolved cargo id in the no-subrow branch,
and the scaled production-output lane indexes each subordinate row directly from
`[desc+0x44+row*0x1c]`, with no post-resolution failure guard between the importer writes and the
summary-bank updates. So the strongest current read is narrower than a full cargo-id decode: if
the imported low-16 marker rows fail the exact matcher at `0x0041e9f0`, the resulting `0` ids
will still hit the first summary-bank bucket inside `0x00412650`, but the semantic meaning of
cargo id `0` itself remains ungrounded. The sibling helper
`structure_candidate_supports_or_references_cargo_id`
`0x004129d0` then uses those same banks plus the cached cargo-membership arrays to answer whether
a live candidate materially references a cargo at all. One compare step tighter, the raw line
lanes now split cleanly by scenario family while still preserving map->save identity inside each
checked pair. `Alternate USA.gmp` and `Autosave.gms` match at the raw line-content level: books
`0..4` keep mixed line areas, their `line02` slots carry the recurring nonzero mode words
`0x00110000`, `0x000b0000`, `0x000b0000`, `0x00130000`, and `0x00180000`, and the same `line02`
slots also carry one recurring supplied token `0x000040a0`; the neighboring `line00/line01`
slots carry the same recurring demanded token lanes such as `0x00010000`, `0x72470000`,
`0x6f430000`, `0x694c0000`, and `0x694d0000`. `Southern Pacific.gmp` and `p.gms` also match at
the raw line-content level, but the same rooted line slots stay zero in the checked pair.
`Spanish Mainline.gmp` and `g.gms` again match at the raw line-content level yet carry a distinct
nonzero pattern: books `0..4` keep mixed line areas, line-level supplied tokens include
`0x00170000`, `0x00150000`, `0x00004040`, and `0x00004000`, demanded tokens include
`0x00010000`, `0x68430000`, and `0x6c410000`, and the later `line02` mode words stabilize at
`0x00070000` then `0x00010000`. So the loader can now safely treat these raw line lanes as
preserved scenario payload with family-specific signatures, even though the exact cargo-id and
mode-enum semantics still need separate grounding. One inference is tighter now too: when those
demanded-token words are zero in the low 16 bits and printable in the high 16 bits, the byte
order reads as short two-letter stems such as `Gr`, `Co`, `Li`, `Mi`, `Ch`, and `Al`, which fit
the current scenario cargo-name families `Grain`, `Corn`, `Livestock`, `Milk`, `Cheese`, and
`Alcohol` from `RT3.lng`; the runtime probe now exposes those only as probable ASCII stems, not
as fully grounded cargo-id decodes. The supplied-token side is now bounded as a separate layout
family rather than forced into that same stem model: the `Alternate USA` family uses one stable
low-16 marker `0x000040a0` only in `book00..04.line02`, the `Southern Pacific` family leaves the
supplied lanes zero in the checked pair, and the `Spanish Mainline` family splits between two
high-16 numeric tokens `0x00170000` and `0x00150000` in `book00/01.line01` plus the later low-16
markers `0x00004040`, `0x00004000`, and `0x00004040` in `book02..04.line02`. The probe now
exposes those conservatively as token-layout classes `high16-ascii-stem`, `high16-numeric`, and
`low16-marker`, without claiming that the non-stem numeric or marker families are decoded yet.
One more structural layer is stable enough to name conservatively: the checked nonzero recipe
rows repeatedly fall into four line-signature classes. `Alternate USA` books `0..4` all expose
one `demand-numeric-entry` at `line00` (`0x00010000`), one `demand-stem-entry` at `line01`
(`Gr/Co/Li/Mi` stems), and one `supply-marker-entry` at `line02` (nonzero mode plus
`0x000040a0`). `Spanish Mainline` books `2..4` expose that same three-line pattern with
`Ch/Al` stems and the `0x00004040/0x00004000` marker family, while books `0/1` only expose the
earlier `supply-numeric-entry` form at `line01`. So the loader can now distinguish recurring row
roles such as demand-stem versus supply-marker without pretending the marker payloads themselves
are decoded. The importer-side branch map is tighter now too because local `objdump` over
`0x00435630` shows that only nonzero mode dwords materialize into `0xbc` runtime descriptors:
mode `0` lines are skipped entirely, mode `1` enters the demand-only branch, mode `3` enters the
dual demand-plus-supply branch, and every other nonzero mode falls into the supply-side branch.
In the checked corpus that means the recurring `demand-numeric-entry` and `demand-stem-entry`
rows in `Alternate USA` and `Spanish Mainline` are preserved scenario-side line records but do
not become live runtime descriptors, while the later `supply-marker-entry` rows are the ones that
actually reach the runtime import path. The runtime probe now exposes that directly as
`imports_to_runtime_descriptor` plus one conservative `runtime_import_branch_kind`.
The raw token windows beneath those branch labels are tighter now too. The checked mode-zero
demand rows preserve string-bearing windows at `line+0x1c`, and the current probe shows those
conservatively as prefixed ASCII previews such as `..Grain`, `..Corn`, `..Livestock`, and
`..Milk`; local `objdump` over `0x0041e9f0` then shows the importer feeding the corresponding
token buffer into an exact cargo-name matcher built over the live cargo collection at
`0x0062ba8c`. By contrast, the imported `supply-marker-entry` rows feed nonprintable windows such
as `.@...` from `line+0x08` through that same matcher, and the resolver path currently shows no
special-case decoding for those marker forms. So the strongest static read is now: the stem-like
demand rows preserve cargo-name text but are skipped because their mode is zero, while the
nonzero imported marker rows are the live descriptor inputs yet likely fail exact cargo-name
resolution unless another upstream transform exists.
The wrapper layer above that query no longer looks like a hiding place for special treatment
either. Local `objdump` now shows `0x00412960` simply summing the two supply-side floats returned
by `0x00412650`, while `0x004129a0` returns the single scaled production-output lane directly;
neither wrapper checks for cargo id `0` after the query returns. The broader world-side
accumulator at `0x0041e7be` is tighter in the same way: it calls `0x00412650`, requires all four
returned channels to be positive before continuing, and only then scales those four channel
values by one linked-instance count from `0x00413940` into caller-owned accumulators. So the
current strongest read remains structural rather than semantic: unresolved marker rows can still
propagate through the first bank bucket, but the first place that meaning matters is a normal
positivity-gated cargo-channel consumer, not a dedicated null-cargo branch.
The caller side is narrower than before too. The steady-state site bitset owner
`placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` starts its inner cargo
loop at id `1` and only walks upward through the current live cargo count, so it never
intentionally queries cargo id `0`. The broader placed-structure sweep around `0x00452e60`
tightens the same boundary from above: when the requested cargo id is nonzero it resolves the
backing candidate and enters `structure_candidate_supports_or_references_cargo_id`, but when the
requested id is exactly `0` it skips that cargo-reference helper entirely and falls through to a
different linked-site or station-or-transit gate. Current local `objdump` now shows that bypass
first requiring one subtype latch through the placed-structure vtable `+0x70`, then resolving the
linked site id at `[site+0x2a8]` through the placed-structure collection `0x006cec20`, and then
forwarding that linked peer into the narrower predicate at `0x0047fd50`. That narrower helper is
tighter than before too: it resolves the linked peer's backing candidate through the peer site id
at `[peer+0x04]`, reads candidate class byte `[candidate+0x8c]`, and returns true only for the
first three class values `0/1/2` while rejecting `3/4` and anything above `4`. So current local
callers treat cargo id `0` as a nonstandard request bound to one linked-site reachability or
classification side path, not one ordinary cargo lane they routinely probe.
The vtable-`+0x70` latch itself is bounded a bit better now too. It still lacks a direct field
decode, but every local callsite we checked around `0x0040d230`, `0x0040dba0`, `0x0040dbf0`, and
`0x0040f670` uses that slot only as the precondition for touching `[site+0x2a8]` and the
neighboring linked-site helpers `0x0047dda0`, `0x0047fd50`, and `0x004138b0`. That makes the
safest current read a linked-site-bearing or linked-site-capable latch, strongly aligned with the
subtype-`1` construction lane that is the only grounded writer of `[site+0x2a8]`, rather than a
broad cargo or route-style predicate.
The neighboring maintenance pair tightens that linked-site read further. Local `objdump` now
shows `0x0040dba0` and `0x0040dbf0` as complementary tiny helpers that each require the same
vtable-`+0x70` latch, resolve optional linked peer id `[site+0x2a8]` through `0x006cec20`,
forward that linked peer (or null) into `0x0047dda0`, and then mirror opposite values into local
byte `[site+0x42]` (`0` for `0x0040dba0`, `1` for `0x0040dbf0`). The route-entry side beneath
them is tighter too: `0x0047dda0` reads route-entry anchor id `[peer+0x08]`, resolves that anchor
through `0x006cfca8`, and only dispatches one of two route-entry vtable calls when
`0x0048a090(1)` reports that all three anchor-slot dwords `[entry+0x206]`, `[entry+0x20a]`, and
`[entry+0x20e]` are still `-1`. So the strongest current read is no longer just "linked-site
capable" in the abstract: this latch consistently fronts the local linked-peer class gate
`0x0047fd50`, the paired `[site+0x42]` route-entry state toggles, and the later linked-peer
collection sweep `0x004138b0`, which keeps the `cargo id 0` bypass path firmly on the
linked-site route-anchor or classification side rather than on an ordinary cargo lane.
One smaller ownership boundary is tighter too: byte `[site+0x42]` is not private scratch owned
only by that pair. Local `objdump` shows tiny direct setters at `0x0040cbc0` and `0x0040cbd0`
plus a raw getter at `0x0040cbf0`, so the `0x0040dba0/0x0040dbf0` pair is writing one shared
placed-structure state byte rather than inventing a route-entry-only scratch lane. One caution
is tighter now too: there are later mode-gated reads at other addresses that also touch a
`+0x42` byte on their own object layouts, but current local evidence does not yet prove those are
the same placed-structure owner family, so the safest current note keeps only the immediate
`0x0040cbc0/0x0040cbd0/0x0040cbf0/0x0040dba0/0x0040dbf0` cluster grounded together.
The vtable side sharpens that split too. A local `.rdata` scan shows `0x0040dba0` and
`0x0040dbf0` each appearing exactly once, together with `0x0040cbf0`, in one method table rooted
at `0x005c8c50`; the constructor chain is tighter now too, because `0x0040c950` installs that
same table as one concrete placed-structure specialization above the common base table
`0x005cb4c0`, while `0x0040c970` tears the same specialization back down to the base before the
temporary object is freed. By contrast the raw set or get trio
`0x0040cbc0/0x0040cbd0/0x0040cbf0` also appears in several sibling tables such as `0x005c9750`
and `0x005dd1f0`. So the strongest current structural read is that byte `[site+0x42]` belongs
to one broader placed-structure virtual interface, while the linked-peer route-entry toggles are
one specialization-specific override pair inside that family rather than generic setters used by
every sibling.
One negative boundary is tighter now too: the
raw token words in this recipe block do not look like the already grounded shell-side
`AnyCargo/AnyFreight/AnyExpress` selector-table ids from `0x00621e04/0x00621e10`, so the current
best read is that these on-disk line tokens are not just copied UI selector ordinals or the same
small express-side id family in another wrapper. One broader collection pass also now ties
the editor rule side back into runtime filtering:
`structure_candidate_collection_refresh_cargo_economy_filter_flags` `0x0041eac0` rebuilds
per-candidate flag `[candidate+0x56]` across the live structure collection, and current grounded
callers show it rerunning directly off the runtime cargo-economy latch at `[0x006cec74+0x25f]`,
which aligns this lane with the editor's `Disable Cargo Economy` special condition rather than
leaving it as a purely editor-owned recipe page. The first common live gate beneath that filter is
now bounded too: `structure_candidate_is_enabled_for_current_year` `0x0041e220` is the shared
year-and-filter check used by the collection refresh and later candidate-selection branches, while
`structure_candidate_rebuild_local_service_metrics` `0x0041e2b0` is a setup-side local service
scorer that already consumes the same enabled candidate records through world-grid sampling. One
steady-state world-side consumer is now grounded as well:
`placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` walks linked placed
structures, filters live category-`2` candidates through
`structure_candidate_is_enabled_for_current_year`, and compacts the direct and scaled supply-side
channels from `0x00412960` and `0x004129a0` into per-cargo bitsets on the placed-structure record.
The next site-side owner layer is tighter now too:
`placed_structure_refresh_linked_candidate_flag4` `0x0042c8f0` refreshes the sibling state bit at
`[site+0x0e6]`, `placed_structure_refresh_candidate_service_state` `0x0042cdf0` ties that flag
refresh to the cargo-service bitset rebuild,
`placed_structure_rebuild_candidate_local_service_tables` `0x0042ce00` then performs the heavier
per-site candidate score rebuild over the aligned float and word tables at `[site+0x107]`,
`[site+0x02]`, and `[site+0x6c]`, and `placed_structure_refresh_local_service_score_bundle`
`0x0042d580` is now the local wrapper that chains that rebuild into the neighboring post-passes
before the world-grid owner continues. Those post-passes are tighter too:
`placed_structure_apply_route_linked_service_caps` `0x0042cc50` is the first route-backed cap pass
over the rebuilt local tables,
`placed_structure_redistribute_local_service_pressure_from_neighbors` `0x0042c1b0` is the
neighboring-site redistribution pass, and `placed_structure_clamp_candidate_service_age_table`
`0x0042cb30` is the final recent-service clamp over the primary per-candidate word table. Above
that refresh lane, `placed_structure_query_candidate_local_service_metrics` `0x0047e240` is the
first higher-level query, `placed_structure_count_candidates_with_local_service_metrics`
`0x0047e330` counts how many candidates currently produce that query,
`placed_structure_get_nth_candidate_id_with_local_service_metrics` `0x0047e620` is the ordinal
selector over that same visible candidate family,
`placed_structure_query_cached_express_service_class_score` `0x0047e390` caches one parallel class
score for the express family now strongly aligned with `Passengers`, `Mail`, and `Troops`,
`placed_structure_refresh_candidate_local_service_comparison_cache_against_peer_site`
`0x0047eb90` rebuilds one peer-site comparison cache over the same local-service inputs, and
`placed_structure_select_best_candidate_id_by_local_service_score` `0x0047f910` is the best-hit
selector above the direct and directional local-service query pair. Those site-side scores now
have grounded shell read-side consumers too:
`shell_station_detail_format_freight_and_express_summary` `0x00506be0` formats the visible
`Freight: %1` and `Express: %1` lines in `StationDetail.win`, and the same station-detail family
now has a deeper candidate-service lane:
`shell_station_detail_set_active_candidate_service_preview` `0x00504ae0` stores the active
`(station id, candidate id)` pair for the world-side preview scan and now grounds the whole
world-side arming strip through
`world_store_preview_primary_id_0x2179_dispatch_mode3_collection_and_refresh_if_active`
`0x00452f60`,
`world_store_preview_scalar_0x217d_and_refresh_active_mode_if_nonzero` `0x00452d80`,
`world_store_preview_linked_site_id_0x2181_rebind_mode3_and_refresh_if_active`
`0x00452db0`, and
`world_set_aux_preview_mode_0x2171_and_reseed_overlay_companion_grid` `0x00452ca0`,
`shell_station_detail_clear_active_candidate_service_preview` `0x00504a90` tears that pair back
down, `shell_station_detail_update_candidate_service_entry` `0x00504ba0` is the shell-side entry
updater above that preview pair, `shell_station_detail_format_candidate_local_service_summary`
`0x00504bea` uses `placed_structure_query_candidate_local_service_metrics` together with localized
ids `681`, `682`, and `2813` to build the visible candidate service text,
`shell_station_detail_build_to_from_haul_summary_widget` `0x00505150` now grounds the paired `To`
and `From` hauled-traffic strip widgets, `shell_station_detail_present_to_from_haul_stats_popup`
`0x00504770` owns their click-through annual and lifetime `hauled TO/FROM this station` popup,
`shell_station_detail_refresh_nearby_structure_jump_rows` `0x00505470` owns the five-row
nearby-structure jump lane, and `shell_station_detail_refresh_candidate_service_rows` `0x00505760`
is now the larger row-list owner that enumerates active candidate-service entries and wires
`shell_station_detail_update_candidate_service_entry` into the per-row click path. The broader
owner above those lanes is tighter now too: `shell_station_detail_window_refresh_controls`
`0x00506610` is the real `StationDetail.win` refresh pass, validating the current station from the
detail manager, publishing the upper summary lane, splitting the `0xb3b7/0xb3b8` action strip by
scenario latch `[0x006cec74+0x1db]`, routing that scenario branch through
`shell_station_detail_present_scenario_station_connection_triplet_popup` `0x00504590`, routing
class `3/4` sites into the alternate branch
`shell_station_detail_refresh_class_3_or_4_train_service_matrix` `0x00504ec0`, and otherwise rebuilding the nearby-structure lane, the paired `To/From` widgets,
and the candidate-service rows together. The broader message side is bounded now too:
`shell_station_detail_window_handle_message` `0x00505e50` owns the wide `StationDetail.win`
switch over message ids `0`, `0xca`, `0xcb`, and `0x3ea`, routes candidate-service rows
`0xb4dc..0xb5a3` into preview arm or clear or a Ctrl-modified `Overview.win` handoff, routes
nearby-structure rows `0xb40a..0xb413` into the detail transition and optional world-centering
path, refreshes control `0xb3f8` on the `0x3ea` branch, and dispatches the lower
`0xb3b5..0xb3bf` action band through the selected-station ownership and class-gated helper strip.
The compact siblings under that pass are tighter now too:
`shell_station_detail_clear_dynamic_rows_and_haul_widgets_if_dirty` `0x005042c0` is the dirty
clear owner over the dynamic row bands and the paired haul widgets, `shell_station_detail_has_valid_selected_station`
`0x00504370` is the bare selected-station validity probe, `shell_station_detail_selected_station_belongs_to_selected_company`
`0x00504390` is the selected-company ownership gate, and
`shell_station_detail_present_selected_station_not_controlled_notice` `0x005043f0` is the
localized not-controlled popup beneath the same action family,
`shell_station_detail_present_scenario_station_connection_triplet_popup` `0x00504590` is the
scenario-latched station-to-station triplet popup that formats three per-destination scalar lanes
with `%5.2f` or `N/C`, and
`shell_station_detail_refresh_class_3_or_4_train_service_matrix` `0x00504ec0` is the alternate
class-`3/4` branch that rebuilds the `Trains Serviced` / `Trains Maintained` matrix before
reusing the shared haul-popup callback wiring,
`shell_station_detail_refresh_class_gated_action_controls_0xb3bb_to_0xb3bf` `0x005044b0`
refreshes the lower class-gated action strip rather than the older guessed `0xb3f8` lane. The
adjacent lifecycle and navigation side is tighter now too:
`shell_station_detail_window_destruct_release_preview_helpers_and_clear_singleton` `0x00505bf0`
is the real `StationDetail.win` destructor, and
`shell_station_detail_cycle_selected_station_by_direction_preserving_owner_and_station_site_class`
`0x00505cb0` plus wrappers `0x00505e30` and `0x00505e40` now bound the next-or-previous station
stepping path that keeps the selection inside the same owner and station-site class family before
optionally recentering the world view. The broader shell command layer above that station-detail
branch is tighter now too:
`shell_command_step_active_window_subject_forward_or_publish_contextual_notice` `0x00440e00` and
`shell_command_step_active_window_subject_backward_or_publish_contextual_notice` `0x00440f20`
are the paired next-or-previous shell commands that first prefer `StationDetail.win`, then the
live building-detail family, then `CompanyDetail.win`, and finally the sibling singleton at
`0x006d3b20` before falling back to the localized notice pairs `0x017a/0x017b` and
`0x017c/0x017d`. The adjacent direct subject-openers are tighter now too:
`shell_open_or_focus_train_detail_for_current_or_first_owned_train` `0x00441040` reuses current
detail subject `[detail+0x78]` or falls back to the first owned train for the selected chairman
company before re-entering `shell_detail_panel_transition_manager` with mode `2`, while
`shell_open_or_focus_station_detail_for_current_or_first_owned_linked_station` `0x004410d0`
reuses `[detail+0x80]` or falls back to the first owned linked station before the same transition
manager is re-entered with mode `5`. Two later registered command siblings are now bounded only
structurally but still usefully: `0x00441160` requires active scenario plus live world root
`0x0062c120` and dispatches either
`world_enable_preview_mode_0x15_latch_and_enter_if_idle` `0x00453370` or
`world_disable_preview_mode_0x15_latch_and_clear_if_active` `0x00453780` by the query at
`world_query_preview_mode_0x15_latch_active` `0x00450150`,
while `0x004411a0` requires active scenario plus live route-store root `0x006cfca8` and
dispatches either `0x00491880` or `0x004932a0` by the boolean result of `0x004934a0(0)`.
The next registered shell-command strip is bounded the same way now:
`shell_command_toggle_shared_world_preview_global_0x62be84` `0x00441240` flips the shared
preview-oriented global `0x0062be84`,
`shell_command_open_detail_panel_mode_0x19_variant_0_via_game_uppermost_overlay` `0x00441260`
and `...variant_1...` `0x004412a0` both route through
`shell_open_detail_panel_mode_0x19_variant_and_refresh_game_uppermost_overlay` `0x00433da0`,
which restyles `GameUppermost.win` controls `0x7923..0x7925`, mirrors the chosen variant across
detail controls `0x07db..0x0837`, transitions the detail manager into mode `0x19`, and forwards
the selected variant into
`world_view_set_mode_0x19_variant_latch_seed_controller_blend_and_mark_dirty` `0x0043a0a0`, and
`shell_command_enable_shell_state_band_0x1df_and_refresh_derived_year_thresholds` `0x004412e0`
re-enters `scenario_state_rebuild_derived_year_threshold_band` `0x004351c0` and then rewrites the
paired shell-state dwords at `[0x006cec74+0x1df/+0x1e3]` through `0x00482850`. Those three
commands are still structurally named rather than semantically named, but the current static owner
boundaries are now explicit. The same command band is tighter at both edges too: `0x004411e0`
simply flips presenter dword `[0x006d4024+0x114276]` when the main shell presenter is live, and
`0x00441200` is the adjacent active-scenario gate that injects shell message `0xcb` for control
`0x9858` through
`shell_dispatch_synthetic_12_dword_descriptor_from_five_scalars` `0x00538e00`. The later edge
of the same shell strip is bounded too:
`0x00441ac0` and `0x00441af0` are the two small active-scenario plus shell-idle wrappers over
`shell_map_file_entry_coordinator` `0x00445ac0`, forwarding flag triplets `(0,0,0)` and
`(0,1,0)` respectively, while `0x00441b20` is the neighboring live-world clamp that ensures
`[world+0x168d]` never falls below `[world+0x1689]`. The next broader neighbor is now grounded
too: `shell_command_toggle_editor_map_mode_with_one_shot_warning_modals` `0x00441b50` is the
real editor-map-mode toggle owner above `0x00482e50`. It branches on current shell mode
`[0x006cec74+0x68]`, uses one-shot latches `0x0062be88` and `0x0062be8c` to gate localized
warnings `0x017e` and `0x0b24`, and on the non-editor side can instead raise warning `0x0b6e`
when `0x004349a0` reports more than one active profile. After those gates it forwards target mode
`([shell+0x68] == 0)` into
`shell_set_editor_map_mode_and_refresh_detail_panel_world_and_graphics_side_effects` `0x00482e50`.
The adjacent startup-year strip is grounded now too:
`shell_command_raise_startup_selected_year_scalar_by_half_step_and_refresh_calendar` `0x00441cb0`
and `shell_command_lower_startup_selected_year_scalar_by_half_step_and_refresh_calendar`
`0x00441d20` are the paired registered commands beneath localized ids `0x0db5/0x0db6`. Both
require active scenario state plus the same single-profile gate from `0x004349a0`, clear shell
dwords `[0x006cec74+0x233]` and `[+0x124]`, then adjust startup scalar `[0x006cec78+0xbfa]` by
`+0.5` or `-0.5` before re-entering
`world_set_selected_year_and_refresh_calendar_presentation_state` `0x00409e80` with absolute
counter `[0x006cec78+0x15]` and refreshing the live world view through `0x00439a80`. The exact
player-facing command labels are still open, but the static owner boundary is now clear: these
are not generic shell scalars, they are the paired half-step selected-year presentation commands.
The adjacent progress-status side is tighter now too:
`shell_build_percent_status_payload_clamped_0_to_100` `0x00441d90` is the shared save or load
progress payload builder, and
`shell_progress_callback_publish_incremental_percent_status_until_target` `0x00441e20` is the
throttled callback installed at `0x00442960` through global `0x00d93988`. That callback advances
the progress latches `0x0062bec8/0x0062becc/0x0062c118`, rebuilds the percent payload through
`0x00441d90`, republishes it through `0x00538c70`, and services the shell frame through
`0x00482160`. The surrounding `0x00445de0` callers keep that pair on the save or load progress
side of the shell strip rather than as another input-command family. The adjacent companion-image
file seam is bounded now too:
`shell_map_bundle_load_companion_image_file_into_global_staging_buffer_and_sync_tags`
`0x00441f70` and
`shell_map_bundle_write_global_staging_buffer_to_companion_image_file_and_return_path`
`0x004420f0` are the paired `_A.tga` / `_A.jpg` import and export helpers around the same
tagged selector strip at `0x00441ec0`. Both derive an extensionless stem through
`support_copy_string_stem_before_first_dot` `0x0051dde0`, choose the `_A.tga` versus `_A.jpg`
suffix by selector byte `[record+0x09]`, and then shuttle the file bytes through the shared
staging descriptor rooted at `0x0062bed4/0x0062bed8`. That keeps the family grounded on the same
fallback descriptor later reused by
`world_presentation_rebuild_four_overlay_surface_slots_from_source_or_fallback` `0x00535430`,
instead of leaving it as an isolated save-side file copier. The neighboring exporter
`shell_export_live_setup_preview_payload_record_and_normalize_pixel_block_0x100x0x100`
`0x00442ba0` is bounded now too: it copies the live setup payload from `[this+0x66be]`,
patches world dimensions and three shell bytes into offsets `+0x01..+0x0b`, and then
normalizes the embedded `0x100 x 0x100` pixel block at `+0x03c2` through `0x0047a120`
before the save-side callers forward that same record into `0x00441ec0` or the tagged
slot-table serializer at `0x00446312`. The broader sibling
`shell_build_temp_surface_from_payload_preview_pixels_and_query_named_resource_field_0x46`
`0x00442740` is bounded now too: it copies the embedded preview pixels at `[record+0x03c2]`
into a temporary `0x40000`-byte RGBA buffer, constructs one temporary `0xec`-byte surface-like
owner through `0x0053b070 -> 0x00543980( pixels, 0x100, 0x100, 0 )`, forwards the caller path
plus fixed selector `0x46` into `0x00542f50`, stores the returned dword into payload field
`[record+0x18]`, and then releases the temporary owner again through `0x00542c90` and
`0x0053b080`. That keeps the short save-side branch at `0x00445925` grounded as a one-shot
preview-surface query helper rather than leaving another anonymous image-copy leaf between the
tagged export path and the progress notice strip. The broader sibling
`shell_map_bundle_rewrite_companion_payload_file_via_tmp_path_and_progress_callback`
`0x004427c0` is now bounded as the temporary-path owner above that same tag strip: it derives
`%1.tmp` from the source path, installs progress callback `0x00441e20` in `0x00d93988`,
rewrites the middle payload band rooted at `+0x03ce` through `0x00553000`, writes the result
back out through `0x005a276f`, updates payload dword `[record+0x18]`, and only then re-enters
`0x00441ec0`.
The sibling `shell_map_bundle_rewrite_companion_payload_file_from_record_offsets_and_sync_tags`
`0x00442900` is bounded now too: it takes the live payload record in `EAX`, reads the full
companion file named by the caller path, installs the same progress callback, rewrites the
middle payload through `0x00553000` using stored offsets `[record+0x18/+0x1c]`, and then writes
the output back in four spans: the leading `0x03ce` bytes, the transformed middle payload, the
untouched interval `[record+0x18 .. record+0x1c)`, and the remaining tail. It then stores the
caller path back into `[record+0x18]` and re-enters `0x00441ec0`. That closes the offset-driven
save-side sibling reached from `0x004459dd` after `0x00441f70`, so the companion-payload strip
is no longer split between one named temp-path owner and one anonymous offset-band rewrite body.
The underlying temporary-surface seam beneath those save-side helpers is bounded now too.
`surface_owner_allocate_first_free_row_slot_0xa0_and_seed_dimensions_and_type` `0x00541b10`
scans the eight-entry row band `[this+0xa0..+0xbc]`, allocates one `0x32`-byte row, seeds width,
height, and type, and returns the chosen slot index; `0x00541ba0` is the indexed release-side
companion. `surface_owner_open_named_resource_and_dispatch_row_type_import` `0x00542f50` is the
named-resource dispatcher used by `0x00442740`: it opens the caller-seeded resource path,
forwards the result into `0x005428c0`, and then dispatches by imported row type
`[row+0x18] = 2/3/4`. `surface_owner_commit_backing_rgba_buffer_recompute_size_and_republish`
`0x005438d0` is the commit-side publish helper over the active RGBA backing buffer
`[row+0x26]`, while `surface_owner_init_or_ensure_rgba_surface_from_pixels_dims_and_mode`
`0x00543980` is the constructor or ensure owner that allocates one first-use slot through
`0x00541b10(..., width, height, 3)` and then commits the caller pixels through `0x005438d0`.
That keeps the save-side preview seam tied back to the same reusable surface-owner family already
visible in the world-presentation and shell-overlay branches, instead of leaving the temporary
preview query path grounded only at the leaf helper level.
The lower surface-owner base is bounded now too. `surface_owner_base_init_and_register_on_global_list`
`0x00540e30` seeds the fixed owner label, capability bytes, helper-object pair, row-slot bands,
and global intrusive registration under `0x00ccbb2c`; `surface_owner_refresh_cached_byte_totals_and_release_all_row_buffers`
`0x00540fc0` is the shared maintenance owner that recomputes cached byte totals `[this+0xcc/+0xd0]`
across the eight row slots and also owns the full row-buffer release pass; and
`surface_row_repack_rgba_or_rgb32_into_active_16bit_buffer_with_palette_mode_gate` `0x00541210`
is the row-side repack body that converts the active backing pixels into the live 16-bit buffer
`[row+0x2a]`, either through a palette-like accumulated-channel path or a direct nibble-packed
conversion path depending on owner byte `[this+0x96]`. That closes the reusable surface family
one layer deeper instead of stopping at the first slot allocator and commit helpers.
The two remaining compact helpers in that same seam are bounded now too.
`surface_owner_query_dimension_cap_from_mode_and_quality_band` `0x00541160` derives the active
power-of-two size cap `0x100/0x200/0x400/0x800` from owner byte `[this+0x05]`, shell gate
`[0x006d4024+0x11422f]`, and selector dword `[this+0xd8]`, while
`surface_owner_probe_named_file_for_type2_header_signature` `0x005411c0` is the adjacent file
probe that opens one named path, reads `0x12` header bytes, and accepts only the local type-`2`
signature. The broader survivor above them is bounded now too:
`surface_row_encode_active_pixels_and_write_tagged_records_to_open_stream` `0x005428c0`
allocates temporary alpha and RGB planes from the active row, splits the current backing pixels,
seeds the local codec object, and then writes the tagged record family `0xbaba/0xbabb/0xbabe`
into the already-open stream, either directly or through the transformed payload path via
`0x00553000`. That closes the immediate import-export seam under `0x00542f50`; the next open
work in this branch is no longer a still-missing leaf, but the broader type-specific row owners.
Those are bounded now too. `surface_row_import_tagged_baba_babb_babe_payload_to_rgba_buffer`
`0x00541c30` is the type-`4` importer that validates the `0xbabe` lead tag plus the later
`0xbaba/0xbabb` branches, reconstructs one RGBA row from the tagged payload bands, and then
re-enters `0x00541210`. `surface_row_import_headered_rgb_or_paletted_payload_to_rgba_buffer`
`0x00542030` is the type-`3` importer that validates the recovered width, height, and pixel-size
header, allocates a full RGBA destination plus temporary staging, and decodes the supported
`0x18`/`0x20` source families into RGBA rows. `surface_row_import_dds_dxt3_payload_and_optionally_materialize_buffer`
`0x00542d50` is the type-`2` importer: it validates `DDS `, enforces the dimension cap from
`0x00541160`, copies the block-compressed payload from offset `0x80`, stores format tag
`DXT3`, and optionally materializes the live companion buffer through `0x005423d0`.
That closes the current type-dispatch branch under `0x00542f50` without leaving its three row
owners as anonymous stream bodies.
The direct export-side sibling is bounded now too.
`surface_owner_write_first_row_rgba_payload_with_0x12_byte_header_to_named_file` `0x00542b30`
is the paired file-write alternative to `0x00542f50`: it opens one caller path in `wb` mode,
builds the compact `0x12`-byte header with row type `2`, first-row width and height, fixed
pixel-size byte `0x20`, and one optional `0x20` flag bit from the second caller argument, then
optionally forces RGBA materialization through `0x00541970` and writes the first-row RGBA payload
`[row+0x26]` plus that header to the open stream. The paired callers at `0x00520cda`,
`0x00520f61`, and `0x00534dd6` all use it as the direct-file branch immediately before the same
temporary-surface release through `0x00542c90 + 0x0053b080`, so the current export/import seam is
no longer split between one named importer and one anonymous file-write sibling.
The small dispatch sub-strip under that importer is bounded now too.
`surface_owner_dispatch_row_import_by_embedded_type` `0x00542fb0` is the direct selector over
embedded row type `[row+0x18]`, routing type `2/3/4` to `0x00542d50/0x00542030/0x00541c30`.
The wrapper immediately above it,
`surface_owner_allocate_temp_row_slot_dispatch_import_and_release_on_failure` `0x00543000`,
clears selector field `[this+0x07]`, allocates one fresh row slot through `0x00541b10`,
re-enters `0x00542fb0`, drops the slot again through `0x00541ba0` on the `1/2` failure paths,
and then refreshes cached byte totals through `0x00540fc0`. That closes the type-dispatch seam
between the file-open owner and the per-row import bodies instead of leaving one more anonymous
slot wrapper in the middle.
The lower lifecycle in that same surface-owner family is tighter now too.
`surface_owner_query_or_materialize_rgba_buffer_from_active_16bit_row` `0x00541970` is the
shared query-or-materialize helper for non-type-`2` rows: it optionally returns width and height,
returns `[row+0x26]` when RGBA backing pixels already exist, and otherwise expands the live
16-bit source buffer `[row+0x2a]` into nibble-doubled RGBA dwords before storing the new backing
pointer back into `[row+0x26]`. The broader sibling
`surface_owner_capability_gated_postprocess_non_type2_rows_into_live_16bit_buffers` `0x00542550`
is the next owner above that helper: when shell capability byte `[0x006d4024+0x11422d]` is live
and local latch `[this+0x95]` is still clear, it revisits the active row slots, skips type-`2`
and already-processed rows, forces RGBA materialization through `0x00541970`, marks row byte
`[row+0x21]`, seeds row state `[row+0x1c] = 0x3c`, discards the previous 16-bit output buffer,
and rebuilds `[row+0x22/+0x2a]` from a float-heavy neighbor-difference transform over the RGBA
source, halving `[row+0x04]` on the `0x20`-pixel-size branch. The release-side owner is bounded
now too: `surface_owner_release_helpers_unlink_global_entry_and_drop_row_slots` `0x00542c90`
releases optional helper roots `[this+0xdc/+0xe4]`, unlinks the owner from the global intrusive
list rooted at `0x00ccbb2c`, conditionally refreshes the live shell presenter when `[this+0x93]`
is set, and then drops both the selector-side handle and all row slots through
`0x00541780` and `surface_owner_release_all_row_slots_0xa0` `0x00542870`. That closes the
reusable surface-owner seam one level deeper instead of stopping at construction, import, and
commit helpers.
The remaining tiny surface-owner leaves in that strip are bounded now too.
`surface_owner_query_first_row_width_or_one` `0x00541aa0` and
`surface_owner_query_first_row_height_or_one` `0x00541ad0` are the fallback-safe first-row
geometry getters used by later projection and world-presentation math paths, while
`surface_owner_refresh_cached_shell_scalar_0xd4_and_return_bound_handle_0xc0` `0x00541bf0`
simply refreshes cached scalar `[this+0xd4]` from the live shell presenter and returns
`[this+0xc0]`. The last tiny release helper `surface_owner_release_selector_handle_0x07_if_present`
`0x00541c10` does exactly what the current name says: when `[this+0x07]` is live it re-enters
`0x00541780` and clears that handle back to zero.
The later owner `shell_apply_scenario_name_specific_post_load_world_and_object_fixups`
`0x00442c30` is bounded now too: `world_entry_transition_and_runtime_bringup` re-enters it at
`0x00444b50` with the loaded scenario title, and it dispatches on many fixed `.rdata` names
including `Go West!`, `Germany`, `France`, `State of Germany`, `New Beginnings`, `Dutchlantis`,
`Britain`, `New Zealand`, `South East Australia`, `Tex-Mex`, `Germantown`, `The American`,
`Central Pacific`, and `Orient Express`, with several branches further gated by setup payload
byte `[this+0x66de]`. The matched branches then perform targeted live-world edits rather than a
generic title-side publish: they patch object-state dwords and bytes inside collections rooted at
`0x0062be18`, `0x0062bae0`, and `0x006ada80`, adjust selected float and scalar fields, copy
paired ten-dword record blocks when specific name/class pairs match, flip secondary-raster bits
through table `0x005ee508..0x005ee5cc`, retune a later collection at `0x0062b268`, and inject
scenario-specific text lines into the shell-owned band `[this+0x4f30]` through repeated
`0x0051e5d0`. That finally makes the broad post-load scenario-fixup seam explicit instead of
leaving it as an unbounded string-switch body beneath world entry.
One neighboring status helper is bounded now too:
`shell_publish_progress_sample_notice_from_byte_delta_and_elapsed_ticks` `0x00442660` is the
shared byte-delta and elapsed-time notice builder used by both the bundle-service strip and the
save-side progress loop. It measures the current byte counter through `0x00530b70`, formats the
rounded kilobyte delta and elapsed ticks through `%5d` and `% 4d`, packages them through
`0x005193f0 -> 0x00518de0 -> 0x0051d680`, and then updates the running previous-counter latch
`0x0062c11c`.
That setter writes `[shell+0x68]`, then either rebuilds the editor-side shell surface through
`0x004d4500` or refreshes the detail-panel and world side through `0x004d44a0`, `0x004dfda0`,
and `0x0044fb70`, before both branches pulse graphics side effects through `0x00484d70(0x0d, 1)`.
The adjacent display-settings strip is bounded now too:
`shell_command_cycle_display_resolution_forward` `0x00483680` is the registered `+1` command
wrapper into `shell_cycle_display_resolution_and_publish_status` `0x00483780`, while
`0x00483990` and `0x004839a0` are the plain `+1` and `-1` wrappers into that same shared owner.
The owner requires the live shell presenter `0x006d4024`, walks the supported resolution tables
at `0x00620e64/0x00620e7c`, applies the chosen size through `0x005206b0`, publishes the updated
size string through `0x0051b700`, `0x00518de0`, and `0x005386e0`, and then refreshes dependent
presentation state through `0x004625b0`, `0x00484910(1)`, and `0x004821d0`. After that point the
embedded world-view controller strip is tighter now too.
`world_view_sample_local_clearance_ring_clamp_eye_height_and_optionally_republish_triplet`
`0x00439820` samples a five-point local clearance ring around the current eye X/Z pair through
`0x00534490`, keeps the highest sample, expands it through `0x0052d0c0` plus fixed margins, and
republishes the eye triplet through `0x0052d1e0` when the current eye height needs to be lifted.
The embedded controller base beneath that path is now first-class instead of only being referenced
indirectly: `0x0052d140` stores the four blend scalars at `[+0x50..+0x5c]`, `0x0052d180` stores
the focus triplet and raises dirty byte `[+0x64]` when it changes, `0x0052d1e0` stores the eye
triplet and refreshes sampled vertical delta `[+0x66]`, `0x0052d230` extracts focus-to-eye
distance plus heading/pitch-like angles, `0x0052d2b0` serializes the focus, eye, and orientation
lanes into one camera-view snapshot record, `0x0052d400` is the inverse helper that rebuilds the
focus triplet from eye, heading, pitch, and distance, `0x0052d450` rebuilds the eye triplet from
focus, heading, pitch, and distance, `0x0052d640` clamps distance against sampled eye height,
`0x0052d750` is the stream-load companion that rehydrates one stored camera-view snapshot back
into the controller base, and `0x0052d570/0x0052d5a0/0x0052d6f0/0x0052d860` are the
base-reset, default-seed, seed, and reset-plus-seed constructor owners. One level higher,
the compact accessor and dirty-latch strip is bounded now too: `0x0052cd20/0x0052cd60` export the
current eye triplet as packed or split outparams, `0x0052cd40/0x0052cd80` do the same for the
focus triplet, `0x0052cda0/0x0052cdc0` are the matching load-store helpers for auxiliary triplet
`[+0x2c..+0x34]`, `0x0052cde0/0x0052ce20` snapshot the current focus, heading, and distance bands
into the two cached companion strips when their paired dirty latches are cleared, and
`0x0052ce70` refreshes shell presenter scalar `[+0x6a]` while consuming the primary dirty latch
back to zero; the next compact query strip is bounded now too: `0x0052cea0` exports heading and
pitch lanes `[+0x10/+0x14]`, `0x0052cec0` samples owner height at current eye X/Z,
`0x0052cf00` broadens that into a clamped XY-extent peak-height query, `0x0052d0c0` is the
current-eye wrapper into that peak-height query, and `0x0052d0f0` is the normalized scalar-band
containment predicate over `[+0x50..+0x5c]`. One level higher,
`world_view_refresh_dependent_projection_visibility_and_presentation_scalars` `0x0043bde0`
now bounds the larger refresh pass that derives visibility and presentation-side scalars from the
current focus and eye triplets before later motion and input branches resume. The load-side owner
one layer above that strip is bounded now too:
`world_view_load_camera_snapshot_release_pending_helper_and_reseed_blend_scalars` `0x0043ac30`
releases any pending helper handle, clears presenter ownership, resets the local controller strip,
rehydrates one stored camera-view snapshot through `0x0052d750`, conditionally loads one
extra-row band into `[this+0x10e]`, reseeds the four controller blend scalars through
`0x0052d140(0, 0, 1.0, 0.7)`, and then normalizes heading before control returns to the broader
world-view owner family. The adjacent low-side layout-state strip is bounded now too:
`0x00544290/0x00544360` publish or reset the local descriptor blocks rooted at
`[layout+0x352f]` and `[layout+0x34ef]`; the next setter strip `0x00544cb0..0x005450a0`
publishes or clears bound-node property pairs `0x0d/0x0e`, packed property `0x3c`, grouped
property `0x0b`, the broader capability and mode-gated slot strips
`0x1d/0x13/0x14/0x12` and `0x15/0x1a/0x11/0x10`, plus the cached-byte-backed property `0x89`;
and `0x005450c0/0x005450e0/0x00545130` export the cached local block `[layout+0x24f0]` and the
negated local scalar triplet `[layout+0x2517/+0x251b/+0x251f]`, with the middle lane clamped up
to `0.5f`. One level lower, `0x00545180` builds the generated default preset table rooted at
`[layout+0x840]` as `0x90` fixed `0x33`-byte rows from an angular sweep, while
`0x00545400/0x00545470/0x005454a0` are the adjacent indexed row setters and query helpers over
that same table and `0x00545420/0x00545440` are the paired scalar-array siblings for
`[layout+0x25f7/+0x25ff]`; the next local strip `0x005457c0/0x005458a0/0x005458d0` publishes
one property-`0x8b` stack descriptor on the bound node and borrows or releases the current
segment-record window handle `[layout+0x265b]` with global counter `0x00ccd824`; the immediate
sibling wrappers `0x005459f0/0x00545a20/0x00545a40/0x00545a70/0x00545aa0/0x00545ac0/0x00545af0/0x00545b90/0x00545bb0/0x00545be0`
repeat the same borrow-release pattern for the adjacent table handles `[layout+0x2643/+0x2647/+0x264b/+0x264f/+0x2653/+0x263f]`.
The last clean local leaves after that are `0x00545ca0/0x00545d50/0x00545d60/0x00545db0/0x00545e00`,
which cover the first-slot clear plus type-`1` span commit, the accumulated span counter query,
the counter reset and optional bound-node reseed, the bound-node finalize-and-optional-clear
helper, and the small bound-node signature classifier. One level up, the next owner body is
bounded now too: `0x00545e30` queries one external/provider report and builds summary text in
buffer `[layout+0x43c]`, falling back to localized id `0x73` when the provider lookup fails and
otherwise appending the localized fragment strip `0x74..0x7d` plus the fixed format family
`%1(16-bit HW) ` / `%1(8-bit HW) ` / `%1(8-bit) ` / `%1(16-bit) ` from the returned report. The
adjacent reset-and-property strip is also tighter now: `0x005464d0` runs one repeated four-pass
bound-node reset sequence, `0x00546540/0x00546560` force property `0x17` to `7` or `4`,
`0x00546580/0x005465a0` clear or raise property `0xa8`, `0x005467a0/0x005467e0` are the paired
one-bit gate writes for property `0x1c`, and `0x00546810/0x00546850/0x00546890` are the
template-gated and clear-side mode writes for property `0x16` via local mode byte
`[layout+0x254a]`. One level higher again, `0x0054a0c0` is now bounded as the broader setup-side
owner above that strip: it binds one external source onto the bound presentation node, falls
back to the midband release helper when that bind fails, conditionally reapplies the cached
gamma-ramp scalar from `[[layout+0x83c]+0x2f]`, seeds optional handle `[layout+0x33ab]` through
the small `0x00570fbd -> 0x00570f86` refcounted `0x14`-byte object helper pair, which now opens
into a tighter row-container family: `0x0057091d` reserves one `0x40`-byte row block from the
fixed template `0x0056cd2c`, with `0x005708ce/0x005708f2` as the aligned block alloc/free
helpers, `0x00570908/0x005709da` as the destructor and release-side wrappers,
`0x00570fa1` as the direct refcount-drop path, `0x0057098b` answering only `IUnknown` plus one
custom IID, and `0x005709f6` as the first grow-and-duplicate-last-row owner. The next
current-entry strip is also bounded now:
`0x00570aac` seeds the current `0x40`-byte entry to an identity 4x4 matrix, `0x00570b0d`
stores one caller matrix directly into that current slot, and `0x00570b2c/0x00570b76` are the
two immediate left/right composition siblings over the same current matrix through
`0x0056d3cd`. One level wider, the same family now has three helper-generated matrix-pair
variants too: `0x00570bc0/0x00570c2f` build a temporary matrix through `0x0056df7d`,
`0x00570c9e/0x00570d1a` do the same through `0x0056e1a8`, and `0x00570d96/0x00570e12` plus
`0x00570e8e/0x00570f0a` do the same through `0x0056dc9a` and `0x0056dd2a`, with each pair
preserving the same right- and left-side current-matrix composition split. The adjacent helper
region is now bounded as one sibling COM-style object pair too: `0x0057aef3/0x0057aedb/0x00571016`
are the init, refcount-drop, and release-side wrappers for vtable `0x005def30`, with
`0x0057ad5a` as the direct addref helper,
`0x0057ad20` as its destructor and `0x0057ae97` as its `IUnknown` plus custom-IID query gate,
`0x0057ad67` as its resource-field bind plus attached-object and payload-copy owner,
`0x0057add4/0x0057adfb` as the attached-object getter and fixed payload copy-out helpers, and
`0x0057ae0f/0x0057ae1e/0x0057ae2d/0x0057ae53/0x0057ae79/0x0057ae88` as the direct pass-through
wrappers over resource field `[+0x48]` and payload block `[+0x08]`,
while `0x0057af0e/0x00571032` are the destructor and release-side wrapper for sibling vtable
`0x005def5c`, with `0x0057af4e` as the matching addref helper, `0x0057af5b` as the target-attach
plus cached-flag derivation owner, `0x0057afd0` as the target getter, and `0x0057aff6` as the
one-shot target-handle release helper, `0x0057b021` as the paired two-handle clear path,
`0x0057b065` as the matching `IUnknown` plus custom-IID query gate, `0x0057b0a9` as the
refcount-drop helper, `0x0057b0c1` as the first broader target-handle and property-strip
seeding owner, and `0x0057b4fd` as the next target-side transform-block builder over optional
anchor pairs plus caller angle and scale. The resource-field branch under `0x0057ae0f..0x0057ae88`
is now tighter too: `0x00580867` is the small constructor-style init for the `0xb0`-byte
target-service object, clearing the embedded entry-band roots, ready byte, auxiliary handle
fields, and cache link; `0x005808b2` is the matching full destructor, releasing the two
target-bound service handles, both embedded eight-entry bands, attached object, target, the
auxiliary handle family rooted at `[+0x6c/+0x98/+0x9c/+0xa8]`, and then unlinking the object
from the global cache chain rooted at `0x00db89e4`; `0x005809ab` is the release-side wrapper for
that destructor; `0x005809c7` seeds service handles `[+0x64]` and `[+0x68]`, invokes attached
object `[+0x0c]` through slot `+0x10`, republishes those two handles through target slots `+0xdc`
and `+0xd8`, and latches ready byte `[+0x60]`; `0x00580a54` is the paired clear-side sibling
that releases handle `[+0x64]` through target slot `+0xd8`, notifies the attached object through
slot `+0x1c`, and clears `[+0x60]`; `0x00580a84` is the broader release body over those target
handles plus the two embedded eight-entry bands rooted at `[+0x10]` and `[+0x30]`;
`0x00580aff` is the setup-side entry-band owner that chooses one of two fixed parameter triples
from local mode byte `[+0x50]`, seeds scalars `[+0x54/+0x58/+0x5c]` through `0x00570669` and
`0x00570691`, and dispatches live per-entry objects through slot `+0x3c`; `0x00580bb9` is the
small auxiliary-handle release helper over the pointer band rooted at `[+0xa8]`; `0x00580bdc`
is the direct refcount-drop path; `0x00580be8` is the constructor-side owner that stores target
`[+0x04]`, derives mode byte `[+0x50]`, seeds the fixed scalar triple `[+0x54] = 0x15`,
`[+0x58] = 0x40`, `[+0x5c] = 0x10`, builds the entry bands, and binds the auxiliary handle
family rooted at `[+0x6c]`, `[+0x98]`, and `[+0x9c]`; and `0x00580d29` is the primary
payload-dispatch and layout-style service owner below the `0x0057ae2d/0x0057ae53` wrappers,
taking the target-service object, caller payload block, five caller arguments, and fixed
mode-variant flag while using service handle `[+0x6c]` plus external callbacks
`0x005c81e4/0x005c8248/0x005c824c`,
and `0x0058123c` is the cache-or-create factory above that strip, walking the same global cache
root `0x00db89e4` for a matching target, otherwise allocating one `0xb0`-byte object, running
`0x00580867`, and finishing construction through `0x00580be8`. Immediately below that service
factory the local container strip is now bounded too: `0x005812b1/0x005812c1/0x005812cf/
0x0058133d/0x00581371` form the reset, release, push, pop, and status helpers for one growable
dword-pointer vector, while `0x00581379/0x0058138c/0x005813bd/0x00581470/0x005814a4` do the same
for the sibling growable string-pointer vector with accumulated byte count at `[+0x10]`, and
`0x005814ac` is the first owner above that string-vector family, building one newline-joined
text object from the stored strings. The adjacent object strip is now bounded too:
`0x00581673/0x005815cf/0x005815dc/0x00581610` are the init, addref, refcount-drop, and release
wrappers for vtable `0x005e0bd8`, `0x00581594` is the destructor, `0x005815a9` allocates the
owned text buffer, `0x005815fc/0x00581606` are the direct getters for that buffer and its stored
length, and `0x0058162c` is the matching `IUnknown` plus custom-IID query gate. The adjacent
SIMD math strip is now bounded too: `0x00581690` applies the first two basis rows plus
translation row `[+0x30]` to one XY pair and stores the full vec4 result, `0x005816d0` is the
projective sibling that scales by a reciprocal derived from lane 3 and returns projected XY, and
`0x00581730` is the translation-free low-64-bit sibling over just the first two basis rows,
while `0x00581770/0x00581830/0x005818f0` are the corresponding 3D XYZ helpers for basis-only,
basis-plus-translation, and projected basis-plus-translation output, `0x005819f0` is the direct
4D vec4-by-4x4 basis application helper, `0x00581ab0` is the four-row batch sibling over a full
4x4 source block, and `0x00581c00/0x00581cd0` are the shared normalize-or-zero helpers for vec3
and vec4 input. One level wider, `0x00581db0` is now bounded as the shared 4x4 inversion helper
with optional determinant outparam, `0x00582070` is the packed-output batch sibling to the
earlier four-row 4D basis application helper, `0x005821d0` is a standalone 4D cross-product-like
helper over three vec4 inputs, `0x00582280` is the unchecked vec4 normalization sibling, and
`0x00582320/0x005823e0/0x00582470/0x00582520` are the first cubic-basis interpolation helpers
in the same math strip for vec3, vec2, vec4, and the first alternate-basis vec3 case.
The same family now extends cleanly through `0x005825e0` and `0x00582680` as the alternate-basis
vec4 and vec2 siblings, then into `0x00582710/0x00582770/0x005827c0` as the two-scalar affine
blend helpers computing `p0 + s*(p1-p0) + t*(p2-p0)` for vec3, vec4, and vec2 inputs.
The next geometry leaves are bounded too: `0x00582820` is the plane-versus-segment intersection
helper over one plane vec4 and two vec3 endpoints, `0x005828e0` is the standalone 4x4
determinant helper beside the nearby inversion body, and `0x005829b0` builds one plane vec4
from three vec3 points by cross product, normalization, and signed-distance writeout. The next
quaternion strip is now bounded too: `0x00582c30` builds one 4x4 rotation matrix from a
quaternion-like vec4, `0x00582d10` is the quaternion product helper, and `0x00582da0` is the
unchecked quaternion-normalization sibling. The adjacent plane-and-quaternion leaves are tighter
now too: `0x00582aa0` is the shared plane-driven projective 4x4 matrix builder over one plane
vec4 and one second vec4 input, `0x00582e40` is the quaternion inverse helper that conjugates
the spatial XYZ lanes and divides by squared length, `0x00582eb0` rebuilds one quaternion from a
caller 3x3 rotation-matrix block, and `0x00582fd0` builds one quaternion from three caller Euler
angles by halving them, routing the packed tuple through trig helper `0x0058aa70`, and then
combining the resulting sine and cosine lanes. The next packed-row sibling strip is now bounded
too: `0x005830a0` applies one compact 3x3 basis block to one vec3 input, `0x00583160` is the
translation-bearing vec4 sibling, `0x00583220` is the packed projective vec3 sibling that scales
by a reciprocal derived from lane 3, `0x00583320` is the packed 4x4 vec4 application helper,
`0x005833e0` is its four-row batch sibling over a full caller 4x4 source block,
`0x00583530/0x00583600` are the packed vec3 and vec4 normalize-or-zero siblings of
`0x00581c00/0x00581cd0`, `0x005836e0` is the packed 4x4 inversion sibling with optional
determinant outparam, `0x005839a0` is the packed-output batch sibling of `0x005833e0`, and
`0x00583b00` is the packed-row sibling of the earlier 4D cross-product helper. The same packed
analogue strip now extends further: `0x00583cc0` is the packed 4x4 determinant sibling,
`0x00583d90` is the packed three-point plane builder, `0x00583e80` is the packed plane-driven
projective 4x4 matrix builder, `0x00584010` is the packed quaternion-to-matrix sibling,
`0x005840f0` rebuilds one quaternion from a packed 3x3 rotation-matrix block, and
`0x00584210` is the packed Euler-angle-to-quaternion sibling using packed trig helper
`0x0058ad50`. The lower trig seam is bounded now too: `0x00583bb0` and `0x00583c30` are the two
single-angle packed axial rotation-matrix variants above the same trig layer, `0x0058ac60` is
the interleaved packed sine/cosine helper they share, and `0x0058ad50` is the wider packed
sin/cos vector generator used by the packed Euler-angle-to-quaternion helper. The MMX or 3DNow
analogue seam is bounded now too: `0x005842e0` is the quaternion-product sibling,
`0x00584379/0x005843d6` are the vec4 and vec3 normalize-or-zero siblings,
`0x00584489` rebuilds one quaternion from a 3x3 rotation-matrix block,
`0x005848ba` is the MMX or 3DNow Euler-angle-to-quaternion sibling using scalar trig helper
`0x0058b660`, `0x0058497f` is the explicit axis-angle-to-quaternion sibling,
`0x005849eb` is the core quaternion slerp helper, `0x00584b22` and `0x00584baf` are the next
two nested-slerp multi-control helpers, `0x00584c41` is the quaternion inverse sibling,
`0x00584ca5` extracts an axis-angle-style vec4 from one quaternion, and `0x00584d4c` is the
scaled-axis-to-quaternion sibling. The next broader MMX owner is bounded now too: `0x00584df1`
takes four caller key quaternions, aligns neighboring keys onto a common hemisphere, converts the
two relative deltas around each interior key through the already-grounded inverse and
axis-angle-style helpers, averages those tangent-like terms, exponentiates back into quaternions,
and multiplies by the interior keys to write two inner spline-control quaternions. The immediate
plane-and-matrix seam after that is tighter now too: `0x00585b4b` is the row-major MMX
translation-matrix constructor, `0x00585b9b` is the MMX sibling to the shared plane-driven
projective 4x4 matrix builder, `0x00585c86` is the paired plane-reflection matrix helper, and
`0x0058a988` is the shared normalize-by-XYZ-length helper beneath those plane-driven bodies, while
`0x0058a8ca` is the MMX origin-plane-versus-segment intersection sibling and `0x0058a9ec` is the
MMX 4D vec4-by-4x4 basis application sibling. The immediate matrix seam after that is bounded
too: `0x00585d62/0x00585dc5/0x00585e23` are the three single-angle MMX axial 4x4 rotation-matrix
variants, `0x00585e7c` is the MMX diagonal scale-matrix constructor rather than a translation
helper, `0x00585ec3` is the small 4x4 transpose or repack helper, `0x00585f32` is the MMX
identity-matrix constructor, and `0x00585f6b/0x0058603d` are the two MMX quaternion-to-4x4
rotation-matrix variants. The adjacent broader matrix owner beneath that constructor strip is
bounded too: `0x0058584a` is the non-alias-staging MMX 4x4 multiply sibling that repacks one
split-qword matrix to temporary contiguous rows before multiplying it through the second caller
matrix, `0x00585a7c` is the scalar determinant helper for the upper 3x3 basis of the same
split-layout 4x4 matrix family, `0x005860f2` is the broader affine-transform owner that builds
one matrix from optional base translation, base rotation, pivoted post-rotation, and trailing
translation-delta inputs, `0x0058728a` is the adjacent three-angle rotation-matrix builder that
uses half-angle trig rather than the single-angle strip, `0x0058742f` is the uniform-scale
sibling that adds one optional pivoted quaternion rotation and one trailing translation delta,
`0x00587963` is the axis-angle rotation-matrix sibling over a normalized axis vec3 plus one
caller angle, and `0x00587a7c` is the broader shared transform owner that supports one base
translation, up to two optional pivoted quaternion rotations, and one trailing translation delta.
One lower MMX sibling strip is bounded now too: `0x005895fa` is the
3D basis-plus-translation-to-vec4 sibling of `0x00581830`, `0x0058966b` is the basis-only vec3
sibling of `0x00581770`, `0x005896d2` is the vec3 normalize-or-zero sibling of `0x00581c00`, and
`0x00589731` is the two-scalar affine vec3 blend sibling of `0x00582710`. The next MMX
interpolation strip is bounded too: `0x005897a2` is the cubic-basis vec3 sibling of
`0x00582320`, `0x00589876` is the alternate-basis vec3 sibling of `0x00582520`, `0x00589960` is
the projective 3D basis-plus-translation sibling of `0x005818f0`, `0x005899eb` is the four-row
4D basis application sibling of `0x00581ab0`, and `0x0058a1aa` is the cubic-basis vec2 sibling
of `0x005823e0`. The remaining low-dimensional MMX strip is bounded now too: `0x0058a0b8` is the
2D basis-plus-translation-to-vec4 sibling of `0x00581690`, `0x0058a10d` is the basis-only vec2
sibling of `0x00581730`, `0x0058a146` is the projective 2D sibling of `0x005816d0`,
`0x0058a242` is the affine vec2 blend sibling of `0x005827c0`, `0x0058a28b` is the vec2
normalize-or-zero sibling, `0x0058a2ce` is the alternate-basis vec2 sibling of `0x00582680`,
`0x0058a379` is the duplicate-layout 4D vec4-by-4x4 basis application sibling, `0x0058a3fb` is
the four-lane normalize-or-zero sibling, `0x0058a45a` is the MMX 4D cross-product sibling of
`0x005821d0`, `0x0058a58c` is the affine vec4 blend sibling, `0x0058a5fd` and `0x0058a6c5` are
the cubic and alternate-basis vec4 siblings of `0x00582470` and `0x005825e0`, `0x0058a7a3`
builds one plane vec4 from a normal vec3 plus point, and `0x0058a7e6` is the three-point plane
builder sibling of `0x005829b0`. The broader MMX matrix seam just above those leaves is bounded
now too: `0x00588eb2` is the alias-safe packed 4x4 multiply owner over two caller matrices,
`0x00588bd0` and `0x005892aa` are the two broader MMX 4x4 inverse helpers with optional
determinant output, `0x005895de` is the thin FEMMS wrapper over `0x005892aa`, `0x00589bb2` is
the tiny thunk into the projective vec3 apply helper `0x00589960`,
`0x00589bb7` selects identity or the ordered composition of up to three optional 4x4 inputs
through `0x005899eb`, applies the resulting chain through `0x00589960`, and optionally remaps
the normalized result into one caller integer viewport-style range block, `0x00589d3f` is the
inverse-side sibling that composes the same optional chain, inverts it through `0x005892aa`,
optionally maps one caller integer viewport-style coordinate triple back into normalized
projective space, and then applies the inverse chain through `0x00589960`, and `0x00589f67` is
the adjacent inverse-projective sibling that uses alternate inverse helper `0x00588bd0` before
the same viewport-normalize and projective-apply tail. The scalar trig roots beneath the
quaternion side are bounded now too: `0x0058af80` is the shared scalar `atan2`-style angle
worker, `0x0058b080` is the shared scalar arccos-style angle worker, `0x0058b180` is the
adjacent alternate arccos-style branch, `0x0058b280` and `0x0058b380` are the scalar natural-log
and base-10-log helpers, `0x0058b3a0` is the scalar natural-exponential helper, `0x0058b480`,
`0x0058b4a0`, `0x0058b4c0`, and `0x0058b500` are the scalar square-root, absolute-value,
ceil-style, and floor-style helpers, `0x0058b540` and `0x0058b580` are the adjacent
`frexp`-style split and `ldexp`-style scale helpers, `0x0058b5de` and `0x0058b600` are the
compact `modf`-style split and `fmod`-style remainder helpers, `0x0058b660` returns one
cosine/sine-style lane pair from one caller angle,
`0x0058b780` is the paired scalar sine-lane helper used when callers only need that one branch
duplicated, and `0x0058b9e0` is the broader scalar `pow(x, y)` owner that stitches the adjacent
log and exponential strips back together. After that point the strip stops looking like separate
command leaves and turns back into broader owner bodies. The next adjacent command leaves are
bounded the same way:
`shell_command_dispatch_scenario_followon_0x437d70_if_active` `0x00441340` is a guarded hop into
the real cheat-code owner `shell_open_cheat_code_modal_and_dispatch_named_runtime_or_company_cheats`
`0x00437d70`. That owner increments the shared shell counter at `[0x006d401c+0xc60]`, opens the
localized cheat prompt `2922` `Do I detect a cheater in the house?\n\nEnter code (or <ESC> to
cancel):`, and then scans the fixed 26-entry table at `0x005ee2c8`. The active selector strip is
now grounded: winner/loss strings `3618/3619/3620/3622` route through `0x004367c0`, selector `1`
jumps to the out-of-line reset branch at `0x004d676c` that clears the selected-company stat bands
rooted at `[company+0x0cfb]`, `[company+0x0d7f]`, and `[company+0x1c47]`, selectors `2` and `3`
post deltas into the selected company and selected chairman profile through `0x0042a080` and
`0x00476050`, selector `4` resolves one locomotive by primary or alias stem through
`0x00461c00` and applies it to every selected-company train through `0x004aefb0`, selector `5`
forces territory-access byte `1` across the live territory table through `0x00424030`, selector
`7` now reads more tightly as the train-crash branch because `0x004ad7a0(1)` is also the direct
shell-command owner behind the `365` warning `There is no train available to crash!`, and
selectors `6/8/9/10` toggle bytes `[state+0x4c8f/+0x4c8e/+0x4c8d/+0x4c8c]`. The same table also
contains the later cheat labels
`3634` `Orca` and the alias-only tail `Katie..Seymour`, but those rows currently sit above the
visible jump-table bound `0x0a`, so the safest static read is that they are unreached or handled
elsewhere rather than active cases in this owner. By contrast
`shell_command_focus_subject_from_collection_0x62b244_via_selector_0x40b2d0` `0x00441360`
requires the same single-profile gate, resolves one subject through `0x0040b2d0(0, 1)`, and then
forwards that result into `shell_world_focus_selected_subject_kind_and_id` `0x00437a90`.
The neighboring current-train command strip is bounded now too. Shared helper `0x00441790`
resolves either the currently focused world-view train or one fallback train, but only keeps it
when the owner company matches the current scenario-selected company. On top of that resolver,
`0x00441810` is the direct `Current train crashes` command: it opens localized warning `365`
when no owned train survives, otherwise it forwards the train into the crash owner
`0x004ad7a0(1)`. `0x004418a0` is the paired `Current train breaks down` command with the same
gate and warning `366`, but it forwards into the named breakdown owner `0x004ada00(1)`.
`0x00441870` is the simpler `Current train whistles` command, which resolves the same owned train,
finds the train-side visual owner through `0x004a77b0`, and writes request dword `1` into
`[owner+0x33a]`. The immediately adjacent helper strip is bounded now too: `0x004a77d0` is a
tiny two-float query over the same linked route object, defaulting both caller outputs to `10.0f`
when `[train+0x41]` is empty and otherwise tail-calling the lower linked-route metric helper
`0x0041add0`; and `0x004a7810` is the neighboring linked-route row-band refresh that walks
`[route+0x316]` / `[route+0x31a]`, treats literal `steam` emitter definitions specially through
`effect_name_matches_literal_steam` `0x004749a0`, and flips row byte `[row+0x1d8]` accordingly.
The shell command strip on the other side is tighter too: `0x00441900`, `0x00441940`,
`0x00441980`, `0x004419c0`, and `0x00441a00` are the five repeated `Overview.win` page toggles
over detail-manager mode `9`, each closing the current page through
`shell_detail_panel_transition_manager` `0x004ddbd0(-1, 0)` when that exact page is already
active and otherwise requesting mode `9` with page ordinals `0..4`.
`shell_station_list_format_freight_and_express_availability_summary` `0x00506e50` feeds the
station-list summary `%1 has %2 freight loads and %3 express loads available for hauling...`, and
the paired modifier helper `shell_station_list_handle_center_or_rename_action` `0x00506d50` owns
the visible Shift-center and Ctrl-rename row actions. The list owner itself is tighter now too:
`shell_station_list_window_refresh_rows_selection_and_status` `0x00506f30` is the real
`StationList.win` row and status refresh pass, clearing and repopulating controls `0x61a9` and
`0x61aa`, wiring the visible summary and modifier callbacks, mirroring the shared selected-station
latch at `[0x006cec78+0x4cba]` when it still belongs to the current company, and updating the two
status labels `0x61af` and `0x61b0`. The row-side callout lane is tighter too:
`shell_station_list_row_callback_publish_station_callout_card` `0x00506ac0` is the actual
row callback beneath both list controls, resolving the selected station, deriving one category
header through `0x0053de00` and `0x00552560`, and then publishing the station-name plus freight
and express callout card through repeated `shell_publish_text_callout_presentation` calls. The
side-selector branch is tighter too:
`shell_station_list_window_handle_message` no longer just re-enters the raw `StationPick.win`
constructor. It flips the active side bit at `0x006d1710` and then re-enters the modal helper
`shell_station_pick_window_open_modal_and_return_selected_station_id` `0x005078c0`, which
allocates one helper window, runs `shell_station_pick_window_construct` `0x00507620`, brackets the
modal show path, and returns the staged selected station id from `0x00622ae8`. Inside that helper
family, `shell_station_pick_window_rewrite_list_and_scroll_messages_to_primary_select_event`
`0x005075c0` now bounds the small message-normalization strip beneath controls `0x80e8..0x80ea`.
The Shift-center side is tighter now too:
the shared helper `0x00433900` takes one object pointer plus one small mode, derives one
mode-specific `(distance,height)` preset from the target's virtual classification, and then
re-enters `0x0043c9a0` to center the live world view on that object. The report side is clearer
as well:
`0x004d3060` is the dedicated `Stats - Trees` constructor over `map_editor_tree_stats_report`,
`0x004d3080` is the actual `General Validation` constructor over
`map_editor_general_validation_report`, and the same page table also now grounds `Stats - Cargo`,
`Stats - City/Region`, `Stats - City Count`, `Event Variable Values`, and the neighboring
event-validation page. The remaining open editor edge is therefore mostly the deeper gameplay
meaning of those site-side service scores and flag bits, not page ownership.

View file

@ -0,0 +1,423 @@
# Input, Save/Load, and Simulation: Event Editors, CompanyDetail, and LoadScreen
### Event Editors and Scenario Action Windows
The event side is tighter too:
that `0x00433130` pass in turn materializes each live event record through
`scenario_event_refresh_runtime_record_from_packed_state` `0x0042db20`. Current shell-side xrefs
now tighten that event branch too: the first rebuilt linked row family under `0x0042db20` aligns
with the standalone condition list later queried by `EventConditions.win`, while the second
rebuilt family aligns with the four grouped effect lists later deep-copied through
`scenario_event_clone_runtime_record_deep_copy` `0x0042e050` during event duplication and effect
staging. The condition side is tighter now too: the tiny helper cluster
`0x0042df30/0x0042df70/0x0042dfb0/0x0042dff0` is no longer just "some adjacent list scans".
Current evidence bounds it as four predicates over the standalone `0x1e`-row condition list,
testing class bits `0x01`, `0x02`, `0x04`, or any of those bits in the static table
`0x005f3e04 + id*0x81`, with special fallback checks through event fields `[event+0x7f9]`,
`[event+0x7fa]`, and `[event+0x7f0] == 0x63`. The shell side is tighter too: vtable slot
`0x005d0cd8` now binds `shell_event_conditions_window_handle_message` `0x004d59e0`, and vtable
slot `0x005d0cf8` binds `shell_event_effects_window_handle_message` `0x004d7060`. The effects
side is tighter too: the lower helper trio is no longer anonymous. `0x004d5d00` now reads as the
effect-type selector refresh under control family `0x4fb2`, `0x004d5f50` reads as the selected
effect parameter-row repaint, `0x004d6090` is the heavier staged-effect editor refresh over the
`0x4fc7/0x4fce/0x4ff6/0x4ff9/0x4ffc/0x5041/0x5044/0x5046/0x5047` bands, and `0x004d67f0`
commits the current editor state back into the staged effect row at `[this+0x78]`. The verb side
is tighter now too: `shell_open_event_conditions_modal_and_return_result` `0x004d9dc0` and
`shell_open_event_effects_modal_and_return_result` `0x004d9e40` are the shared modal openers
above the two editor windows; `0x004da640`, `0x004da700`, and `0x004d9ed0` now read as the add,
edit, and remove verbs for standalone condition rows; `0x004da7c0`, `0x004da860`, and
`0x004da920` are the matching add, edit, and remove verbs for grouped effect rows; and
`0x004d8120` is now the heavier condition-row list panel refresh those condition-side verbs
re-enter after mutation. The conditions-side refresh split is tighter too: `0x0042d700`
aggregates standalone condition-list class or modifier flags, `0x0042d740` aggregates grouped
effect-row type flags for one selected grouped list, `0x004d9970` owns the condition-class
summary and grouped-row status bands, `0x004d77b0` owns the grouped summary-band affordance gate
for `0x4fed..0x4ff0` when selector `0x5000` lands on `0x5002`, `0x004d9d10` owns the smaller
grouped-effect territory-target affordance on control `0x500b`, `0x004d9f50` owns the selected-event mode
strip and summary text panels, and `0x004d9390` is the mode-dependent detail-row switch beneath
that strip. `0x004da0f0` is tighter too: selector `0x5001` now has the strongest current
RT3.lng fit as the condition-side `Test against...` mode above `0x004d9970`, while selector
`0x5002` has the strongest current fit as the grouped-effect-side `Apply effects...` mode.
That `0x5002` branch now clearly builds control `0x5014` from RT3.lng `1160..1164` as `to the
company/player/player (i.e. chairman)/territory for which the condition is TRUE` before
enabling the adjacent `0x5005`, `0x500a`, and `0x5014..0x501c` family. The strongest current
RT3.lng fit for the remaining visible target-scope strip is now `0x5015 = to the whole game`,
`0x5016..0x5018 = to all/human/AI companies`, `0x5019 + 0x500b = to territories`, and
`0x501a..0x501c = to all/human/AI players`; the grouped effect-row type mask matches that split
directly through bits `0x08`, `0x01`, `0x04`, and `0x02`. The
selected-event strip is tighter now too: `0x004db120` is the broader selected-event repaint and
navigation refresh above those smaller helpers, `0x004db520` and `0x004db5e0` are the previous
and next selected-event stepping verbs, `0x004db8b0` is the add-or-clone event modal helper,
`0x004dba90` is the rename verb, `0x004d9360` is the delete verb, `0x004db6a0` is the live
selected-event id setter behind control `0x4e84`, and `0x004db6f0` is the callback-binding plus
pending-selection bootstrap path that seeds the strip during window bring-up. The larger
dispatcher at `0x004dbb80` now makes the strip explicit: `0x4e85..0x4e8a` are previous, next,
add blank, clone selected, rename, and delete event, while the later grouped band commits current
summary state through `0x004d8d50` before changing grouped selector `[this+0x9c]` via `0x004dbf93`.
The selection bootstrap side is tighter too: `0x004daf40` is now the placeholder reset helper for
the selected-event summary controls `0x4eaf`, `0x4eac`, `0x4ed9`, `0x4edb`, and `0x4fdf..0x4fe2`.
The grouped target-scope side is tighter too: `0x004d8ea0` now reads as the commit helper for current
selected-event text panels before selection or grouped-action changes, `0x004d8d50` now records
the hidden selector family `0x5006..0x500e -> 0..8`, and `0x004dab60` projects that ordinal
one-to-one onto the visible grouped-effect target-scope display strip `0x5014..0x501c`. That
split is firmer now: `0x5006..0x500e` are the canonical hidden selectors that get stored into
`[event + group + 0x7fb]`, while `0x5014..0x501c` are the visible mirror rows republished from
that same ordinal rather than a second independently named selector family. The grouped row and
stored-summary refresh side is tighter too: `0x004d88f0` is now the selected grouped-effect
row-list renderer for `0x4ed5`, formatting the grouped `0x28`-byte rows through RT3.lng
`1154..1159`, and `0x004da9a0` is the current grouped-summary-state republisher that reloads
`0x500a`, `0x500b`, and visible action selection `0x5014..0x501c` from `[event + group + ...]`
before tailing back into `0x004da0f0`,
`0x004dbfca` as the grouped target-scope mode selector that persists the chosen control id into
`0x00622074`, with `0x5001/0x5002` now strongest-fit as `Test against...` and
`Apply effects...`, `0x004dbeeb` as the pending shared summary-text triplet publish helper for
`0x4eac/0x4ed9/0x4edb`,
`0x004d91e0` as the selected-event summary-header and grouped-mode commit helper above
`0x004d8d50`, and `0x004dbe7a` as the narrower `0x4ec6/0x4ec7` choice-event single-player-only
warning modal branch rooted at RT3.lng `3887`. The remaining gaps on
this lane are narrower again because the grouped-band `0x4dc09c` table now closes one earlier
overclaim: controls `0x5001/0x5002` are the only `0x4fed..0x501c` entries that route into
`0x004dbfca` on the `0xcf` side, while visible rows `0x5014..0x501c` only route to the smaller
`0x004d9d10` affordance path and the rest of `0x4ff1..0x5013` are default no-ops. The open
question is therefore no longer whether those visible target-scope rows are direct selector verbs;
current evidence says they are not.
The local slot records are rooted at
`[world+0x69d8]`,
`[slot+0x01]` polarity and the external role gate at `[world+0x0bc3+slot*9]` are now grounded, and
`[slot+0x03]` now looks like the distinguished primary-human-seat marker because current grounded
writes seed it only on slot zero and later logic moves it solely by whole-record compaction. The
open question is no longer whether the seeded trio lands in the visible shell company roster;
current evidence says it does, and ordinary `Start New Company` now looks like a fresh-company
allocator through `start_new_company_dialog_commit_create_company` and
`start_new_company_request_create_company`, not like the path that claims one of the seeded named
railroads. The immediate post-roster station branch is now clearly separate: current grounded
resource names and handlers put mode `8` on `StationDetail.win`, mode `5` on `StationList.win`,
and the subordinate modal selector helper on `StationPick.win` through
`shell_station_pick_window_open_modal_and_return_selected_station_id` above
`shell_station_pick_window_construct`. The company-side ownership question has therefore moved
down a layer rather than staying open. We now have a recovered `CompanyDetail.win`
owner family through `shell_company_detail_window_refresh_controls`,
`shell_company_detail_window_construct`, and `shell_company_detail_window_handle_message`; the
same owner now has one broader bounded read-side lane too, because control `0x9470` uses
`shell_company_detail_render_financial_history_panel` to draw the five-step Revenue or Expenses or
Interest or Profit or Lifetime strip, sibling control `0x9471` reuses
`shell_format_company_financial_summary_card` through
`shell_company_detail_render_company_summary_card`, controls `0x947d` and `0x947e` now ground a
bond maturity and repay panel through `shell_company_detail_render_bond_maturity_and_repay_panel`,
control `0x9488` now grounds the debt or credit or rate summary block through
`shell_company_detail_render_debt_credit_and_rate_summary_panel`, control `0x948a` now grounds the
share-value and dividend-payout block through
`shell_company_detail_render_share_value_and_dividend_summary_panel`, while the broader six-row
per-share stock-data family is now bounded under `shell_format_company_stock_data_panel`, and the
adjacent territory selector lane is bounded through
`shell_company_detail_select_territory_access_row`,
`shell_company_detail_render_territory_access_row`,
`shell_company_detail_sync_selected_territory_from_picker`, and
`shell_company_detail_refresh_selected_territory_access_summary`; the first finance-action layer
beneath it is bounded through the bond, stock-issue, stock-buyback, and dividend-rate helpers; the
territory-access side is bounded too through
`shell_company_detail_refresh_selected_territory_access_summary`,
`shell_company_detail_buy_territory_access_rights_flow`, and the underlying company access-rights
helpers; and the full takeover and merger vote-result lane is now grounded through
`shell_resolve_chairmanship_takeover_vote_and_commit_outcome`,
`shell_present_chairmanship_takeover_vote_outcome_dialog`,
`shell_resolve_merger_vote_and_commit_outcome`, and `shell_present_merger_vote_outcome_dialog`.
The remaining company-side uncertainty is therefore narrower than before: the broader support and
valuation side is now tighter too because
`company_compute_cached_recent_per_share_performance_subscore`,
`company_compute_five_year_weighted_shareholder_return`, and
`company_compute_public_support_adjusted_share_price_scalar` bound the recent per-share
performance and investor-support/share-price blend beneath those vote resolvers; the recent
per-share feeder now has a grounded four-lane tail too, with current partial-year weight
`(5 * [world+0x0f]) - 5`, prior full-year weights `48/36/24/12` on `0x1f/0x1e`, dividend
non-decline pair weights `9/8/7/6` on `0x20`, lane weights `40/10/20/30`, the startup age ramp
`0/0/0/100 -> 25/25/35/100 -> 50/50/65/100 -> 75/75/85/100 -> 100/100/100/100`, a strongest-lane
`*1.25` boost, a weakest-lane `*0.8` reduction, and separate bounded-intermediate versus final
difficulty applications under `0x005f33b8`; the next consumer `0x00424fd0` is also tighter now,
with the young-company interpolation against `[company+0x57]`, caller pressure clamped to
`[-0.2, 0.2]`, one `(shares / 20000)^0.33` share-count growth term, and the later threshold
ladder `0.6 / 0.45 / 0.3 / 1.7 / 2.5 / 4.0 / 6.0` before the issue-`0x37` multiplier,
`scenario_state_compute_issue_opinion_multiplier` now bounds the
next layer of optional company, chairman, and territory-specific opinion overrides on the active
scenario state, and the broader stat-reader family around
`company_read_control_transfer_metric_slot` and
`company_read_year_or_control_transfer_metric_value` is no longer just a merger-premium helper.
Current grounded callers show the same metric family feeding the annual shareholder-revolt and
creditor-liquidation lane surfaced by localized ids `300..304`, while the debt-side shell and
bond lane now separately close `0x38` as `Credit Rating` and `0x39` as `Prime Rate`. That means
the remaining gap is now mostly gone on the UI side too: issue `0x37` is already bounded to the
same investor-confidence family as the equity-support and governance-pressure paths, and current
grounded UI evidence still stops at the investor-attitude sentence family rather than one
standalone caption. The calendar side is tighter now too:
`[world+0x15]` is the absolute counter for the same mixed-radix `12 x 28 x 3 x 60`
year-plus-subfield tuple packed by `0x0051d3c0` and unpacked by `0x0051d460`, not just a vague
“calendar-like” blob. The `TrackLay.win` family now clearly owns `Lay single track.` `Lay double track.`
and `Bulldoze` as its three primary modes, its bridge selector, its wrapped frequency preferences,
and a strongly aligned pair of `Auto-Hide Trees During Track Lay` and `Auto-Show Grade During
Track Lay` toggles; the `StationPlace.win` family now clearly owns its six top-level category
buttons, the station-style scroller, and the station-rotation controls. The older `Building
placement center` string 671 no longer looks like a live StationPlace control label in the current
recovered flow, because the active constructor, preview, refresh, and dispatcher paths all use
neighboring ids such as 669 and 2208 without a direct recovered lookup of 671. On save or load the
broad serialize-versus-restore split is now grounded, the non-Quicksave `.gmp/.gmx/.gmc/.gms`
families are separated, and the auxiliary `.gmt` path is at least bounded to the preview-surface
side owner. The higher-value shell-facing gap has therefore shifted upward to the remaining
semantics of the post-load generation phases, the later recurring structure-population cadence,
the deeper vote-weight formulas inside takeover and merger resolution, and the still-open meaning
of the packed simulation calendar tuple.
### CompanyDetail and Section Ownership
The shell detail family now has an explicit
section-selector lane in addition to the read-side panels already mapped. Controls
`0x9472..0x9475` directly select the four visible CompanyDetail sections through `0x006cfe60`,
`0x9476..0x9479` are the companion visual controls for that same tab strip, and section `0` is now
bounded more tightly as the chairman or governance slice around the portrait-backed chairman band
on `0x9480` plus the dynamic overview widget `0x947f`. That widget is no longer just a vague
status line: the section-0 refresh binds it through a dedicated stack-built dynamic text path,
and the strongest current shared formatter candidate is
`shell_format_company_governance_and_economy_status_panel` at `0x004e5cf0`, which first renders a
five-line company-metric preamble through localized ids `1211..1215`: `Revenues` from slot
`0x2c`, `Profits` from slot `0x2b`, `Load miles hauled` from slot `0x17`, `Revenue per load
mile` from the derived `slot 0x2c / slot 0x17` branch, and `Average speed` from slot `0x26`
rendered through `1216` `%1 m.p.h.`. It then splits the governance summary more concretely: no
linked chairman emits `3045`, wholly owned companies emit `3046` for the scenario-selected
chairman or `3047` for another linked chairman, and investor-owned companies emit the
investor-attitude lines `3048/3049` with one adjective from the table at `0x00622170`. That
branch is no longer using unnamed helpers either: `company_get_linked_chairman_profile_record`
`0x00426ef0` resolves the linked chairman profile and `chairman_profile_owns_all_company_shares`
`0x004768c0` is the full-ownership test behind the `3046/3047` split. The salary side is tighter
too: the formatter computes one signed delta from `[company+0x14f]` and `[company+0x0d59]`, then
chooses `3050..3052` for the scenario-selected chairman or `3053..3055` for another linked
chairman depending on whether that delta is negative, positive, or zero. The bonus line is
narrower still: it only appears when the display year matches `[company+0x34f]`, using amount
`[company+0x353]` with `3056` or `3057`. It then appends the
`1218` `Economy status - %1.` tail caption and stages the adjacent selected-company report or
list help-title pairs `1219/1220` `Income Statement`, `1221/1222` `Balance Sheet`,
`1223/1224` `Haulage Report`, `1225/1226` `Stock Report`, `1227/1228` `Train List`,
`1229/1230` `Station List`, `1231/1232` `Industry List`, and `1233/1234` `Cargo List`.
Current evidence still does not recover separate `CompanyDetail.win` action controls for that
strip under `shell_company_detail_window_handle_message`, so it currently reads as staged
overview text or help content rather than as a closed launcher family. The direct `0x947f`
formatter call is still indirect, but the widget boundary is tighter too: the generic shell
helpers `shell_control_refresh_matching_dynamic_text_payload` `0x00540a47` and
`shell_control_release_dynamic_text_payload` `0x005639d2` now show that type `0x6f` controls
free or swap one heap-backed text payload and then short-circuit as a special dynamic-text case,
which strengthens the reading of `0x947f` as a display-only overview widget rather than a normal
callback control. One adjacent boundary is tighter now too: the broader overview wrapper at
`shell_render_company_overview_panel_header_and_optional_change_affordance` `0x004e5a80` owns
the fallback no-company texts `1210`, `3043`, and `3888`, styles controls `0x3f06` and `0x3f07`,
and on the narrower selected-company branch appends `3044` `Click to change company name and
logo.` plus the neighboring `1941` `Change` affordance before falling through into the shared
`0x004e5cf0` text body. That keeps the name/logo affordance outside the ordinary
`CompanyDetail.win` action dispatcher and makes the `0x947f` alignment cleaner. The message-side
action band is tighter too: `0x94b5` grounds
territory-access purchase, `0x94b6` grounds bankruptcy, `0x94cf..0x94d2` ground bond issue, stock
issue, stock buyback, and dividend-rate changes, `0x9493` routes into the destructive
company-clear helper that deactivates the selected company and clears chairman/share links,
`0x94d6` grounds bankruptcy, `0x94d7..0x94da` ground bond issue, stock issue, stock buyback, and
dividend-rate changes, `0x94db` grounds merger, `0x94dc` grounds resignation, and `0x9538` grounds
chairmanship takeover. The finance-side dialog family is tighter too: the bond-issue lane now has
the dedicated modal renderer `shell_company_detail_render_issue_bond_offer_dialog` `0x004c3560`
for underwriter terms `968..972`, the stock-issue lane has
`shell_company_detail_render_issue_stock_offer_dialog` `0x004c3b50` for the staged offer lines
`975..978`, and the buyback lane has
`shell_company_detail_render_stock_buyback_offer_dialog` `0x004c4300` for broker lines
`981..984`. The compact summary card on sibling control `0x9471` is tighter too:
`shell_format_company_financial_summary_card` at `0x004bfb30` now clearly renders `Cash:`,
`Revenue:`, and `Profits:` from company slots `0x0d`, `0x2c`, and `0x2b`, rather than one looser
unnamed finance block. The dividend lane is now split the same way:
`shell_company_detail_setup_dividend_rate_adjust_controls` `0x004c4c70` binds the paired adjust
controls `0x99e8` and `0xc0f9`,
`shell_company_detail_render_change_dividend_rate_dialog` `0x004c4e30` renders localized ids
`988..990`, and
`shell_company_detail_handle_change_dividend_rate_dialog_message` `0x004c5140` clamps the staged
dividend rate against `company_compute_board_approved_dividend_rate_ceiling` `0x00426260` and
raises localized id `991` when the board refuses a higher dividend, all before the existing
company commit path. All four finance verbs now converge through the shared
callback-driven modal opener `shell_open_custom_modal_dialog_with_callbacks` `0x004c98a0`, which
is also reused by the multiplayer staged text-entry lane. The front controls in section `0` are
tighter too: `0x948b` is a
tutorial-guarded escape or back control that shows localized id `3724` `This option is disabled in
the tutorial.` before falling back to the shell detail-manager escape path, `0x9491` and `0x9492`
only restyle the paired visuals `0x948f` and `0x9490`, and `0x9494` opens localized id `3635`
`Enter the amount that your company's cash should be` and writes the accepted value directly into
the selected company cash pair. The neighboring debt section is tighter now too: controls
`0x947d` and `0x947e` no longer read as one-off bond widgets, but as the owners of two repayable
bond-slot row bands, `0x94e8..0x950f` and `0x9510..0x9537`. Those row controls now clearly
converge on the same repayment path in the message dispatcher: they reject unaffordable repayment
through localized id `2990`, open the early-repayment confirmation rooted at `2991`, and then
either commit through `company_repay_bond_slot_and_compact_debt_table` `0x00423d70` or package
the request through the multiplayer shell transport. The render-side owner is tighter too:
`shell_company_detail_render_bond_maturity_and_repay_panel` formats `Due %1` and `Repay this
bond.` for the selected debt slot while the tiny binder
`shell_company_detail_bind_bond_row_band_for_active_panel` switches between the two row bands.
Current `0xcb` dispatch does not treat `0x948f`, `0x9490`, `0x94d4`, or `0x94d5` as standalone
action cases. The message-side jump table now makes that passive/action split explicit too: in the
dispatch byte map rooted at `0x004c6640`, controls `0x94d6..0x94dc` map to cases `0x06..0x0c`,
control `0x9538` maps to case `0x0d`, and the neighboring companion rows `0x94d4` and `0x94d5`
stay on the default path. The refresh-side ownership is tighter too: the helper now explicitly
loops over `0x94d4..0x9537` as the selected-company-owned band and over `0x9538..0x959b` as the
linked-chairman-owned band, and those two loops do not use the same style polarity.
`0x94d4..0x9537` take style `0x65` when the selected company matches the scenario-selected
company and `0x87` when it differs, while `0x9538..0x959b` take style `0x87` when the selected
company's linked chairman matches the scenario-selected chairman and `0x65` otherwise. The
selected-company action side
is tighter now too: scenario toggle `0x006cec78+0x4a8f` re-enables bankruptcy `0x94d6` together
with passive companion row `0x94d4`, `+0x4a8b` re-enables issue bonds `0x94d7` together with
passive companion row `0x94d5`, `+0x4a87` re-enables stock issue and stock buyback
`0x94d8..0x94d9`, `+0x4a93` re-enables dividend `0x94da` together with the same passive
companion row `0x94d5`, `+0x4adb` re-enables merger `0x94db`, `+0x4acb` re-enables resignation
`0x94dc`, and `+0x4acf` re-enables chairmanship takeover `0x9538`. That makes `0x94d4/0x94d5`
read more like passive companion or heading widgets than hidden verbs. The constructor boundary
is tighter too: current `CompanyDetail.win` setup still only binds explicit callbacks for
`0x9470`, `0x9471`, `0x947d`, `0x947e`, and `0x948c..0x948e`, not for the wider section-0 row
bands. That keeps the remaining `0x94d4..0x959b` content looking more like resource-defined
display rows that are gated and restyled by refresh than like individually code-rendered widgets.
That leaves the main remaining CompanyDetail-specific shell edge at the exact `0x947f` formatter
binding plus the still-unsplit render-side governance rows inside `0x94d4..0x959b`.
### Adjacent LoadScreen.win Report Family
The neighboring shell lane around controls
`0x3ef6..0x4073` is now separated from `CompanyDetail` instead of being treated as one more
extension of the `0x947f` overview path. The real outer owner is
`shell_load_screen_window_construct` `0x004ea620`, which binds `LoadScreen.win`, randomizes the
`LoadScreen%d.imb` background family, stores the singleton at `0x006d10b0`, and seeds the first
visible page-strip controls. Above the older page-specific work, the real message owner is now
`shell_load_screen_window_handle_message` `0x004e3a80`: it owns page id `[this+0x78]`,
page-local substate `[this+0x7c]`, page-kind `[this+0x80]`, current company `[this+0x88]`,
current chairman profile `[this+0x8c]`, display year `[this+0x9c]`, and the page-local report
row latch `[this+0x118]`, then fans back into the shared selector
`shell_load_screen_select_page_subject_and_refresh` `0x004e2c10`, the company-step helper
`0x004e3a00`, and narrower page branches such as `0x004e45d0`. The matching render-side owner is
now bounded too: `shell_load_screen_render_active_page_panel` at `0x004ea060` formats the common
heading and panel frame, then switches on page id `[this+0x78]` and hands control down into the
active page body. That older branch is now demoted to what it actually is:
`shell_load_screen_profile_stock_holdings_page_handle_message`, the page-specific handler beneath
the stock-holdings slice. Inside that same family,
`shell_load_screen_render_profile_stock_holdings_summary_panel` at `0x004e5300` grounds the
selected-profile holdings page: it resolves the current chairman profile from `[this+0x8c]`,
renders the top summary rows `1204` `Stock Value:`, `1205` `Total Assets:`, and
`1206` `Stock Holdings:`, then walks the active company roster and formats one row per positive
holding through `1201` `Click to view details on %1.`, `1207` `%1 Shares`, and `1208` `%1 Value`,
falling back to `1209` `None` when no positive holdings survive. It also appends `3029`
`Click to change player name and portrait.` plus the adjacent `1941` `Change` affordance only
when the rendered profile matches the scenario-selected chairman. The earlier pages are tighter
now too: `0x004e68e0` is the selected-company financial ranking page using the active company
roster plus `1235..1245` for revenue, profit, cash, track mileage, and report affordances; and
`0x004e6ef0` is the active-chairman wealth ranking page using the chairman profile collection
plus `1237`, `1241`, `1246..1250` for cash, stock, total, and purchasing-power style comparisons.
The later sibling renderers are broader than that one holdings page now too: `0x004e7670` is the
selected-company train list page using `1235..1267`, `0x004e8270` is the selected-company
building list page using `1268..1278`, `0x004e8bb0` is the selected-company station list page
using `1279..1288`, and `0x004e9460` is the map-wide cargo list page using `1289..1298` over the
live candidate collection rather than one company roster. The last broad early-page owner is
tighter now too: `0x004e9b20` is the shared multi-year company report-table renderer for page
`4` `Income Statement`, page `5` `Balance Sheet`, and page `6` `Haulage Report`, all driven from
`0x004ea060` with one caller-supplied mode byte and yearly company rows built through
`company_read_year_or_control_transfer_metric_value`. The row families are bounded too:
income-statement rows `1301..1315`, balance-sheet rows `2816` and `1317..1322`, and
haulage-report rows `1323..1335`. The only special rows inside that family are now tighter too:
`0x00425880` and `0x004258c0` provide the negative-cash and positive-cash interest-rate inserts
for the `%1/%2` placeholders in strings `2815` and `2816`, so they are no longer anonymous
private math blobs. The adjacent early siblings are tighter now too: `0x004e5130` is the
selected-company `Stock Data` page wrapper that falls back through `1299` and otherwise reuses
`0x004c0160` to render the `Largest Shareholders`, `Shares`, and `Per Share Data` family;
`0x004e6ef0` is the `Player List` page; `0x004e5300` is the `Player Detail` holdings page; and
`0x004e51ea` is the `Game Status` briefing panel that pulls current scenario briefing text from
the live scenario text store and appends the `1772/1773` `Briefing` affordance. The active-page
renderer at `0x004ea060` is now tighter too because its 13-byte page descriptor table at
`0x006220a0` has been decoded directly as `{ page kind, title string id, `0x3ef8` backlink
page, selected-company-header flag }`. The currently grounded rendered title order is:
`XXX`, `COMPANY OVERVIEW`, `COMPANY LIST`, `INCOME STATEMENT`, `BALANCE SHEET`,
`HAULAGE REPORT`, `STOCK DATA`, `PLAYER LIST`, `PLAYER DETAIL`, `GAME STATUS`,
`TRAIN LIST`, `TRAIN DETAIL`, `STATION LIST`, `STATION DETAIL`, `CARGO LIST`,
and `INDUSTRY LIST`. Its live body bindings are now bounded too: page `0` falls back to
`1203` `Unable to display page`, page `1` is the company overview wrapper, page `2` is the
company list page, pages `3..5` are income statement, balance sheet, and haulage report, page
`6` is stock data, page `7` is player list, page `8` is player detail, page `9` is game status,
page `0x0a` is train list, page `0x0b` currently falls back to `1203`, page `0x0c` is station
list, page `0x0d` currently falls back to `1203`, page `0x0e` is cargo list, and page `0x0f`
is industry list. The row-click path is tighter now too: player-list rows re-enter page `8`
directly, but train, station, and industry rows leave `LoadScreen.win` through the shell
detail-panel manager at `0x004ddbd0` instead of switching to title-table pages `0x0b` or
`0x0d`. Page `0` is tighter now too: its descriptor is kind `0`, title `1200` `XXX`, backlink
`0`, and header flag `0`, and no current post-constructor selector path has been recovered for
it. The descriptor side now also bounds the only known reverse route for the dormant detail
titles: `0x3ef8` is the table-driven backlink affordance, so if page `0x0b` or `0x0d` were ever
selected, the known reverse path would return to train-list page `0x0a` or station-list page
`0x0c` respectively rather than through a separate detail-only owner.
The launcher side is tighter too: current grounded `shell_open_or_focus_load_screen_page`
callers cover pages `1`, `2`, `3`, `4`, `5`, `6`, `7`, `9`, `0x0a`, `0x0c`, `0x0e`, and `0x0f`,
and no current recovered opener or row-click route selects `0x0b` or `0x0d`. So the
`LoadScreen.win` family now has a much cleaner shape: one outer message owner
`0x004e3a80`, one active-page render owner `0x004ea060`, and then the narrower page-specific
handlers and renderers beneath them. The launcher side is tighter now too: `0x004e4ee0` is the
shared open-or-focus ledger-page owner above this family. Outside sandbox it either re-enters
`shell_load_screen_select_page_subject_and_refresh` on the live runtime at `0x006d10a8` or
allocates that transient runtime, seeds it through `0x004e4b10`, and enters the visible modal
loop; inside sandbox it raises localized id `3899` `The ledger is not available in sandbox mode.`
instead.
The direct shell-command strip above that opener is now explicit too: `0x00440700..0x0044086e`
are just tiny `scenario-present -> open page` wrappers for pages `1`, `3`, `4`, `5`, `6`,
`0x0a`, `0x0c`, `0x0f`, `0x0e`, `2`, `7`, and `9` respectively. So the recovered launcher range
is no longer only “callers of `0x004e4ee0`” in the abstract; each of those small shell-command
stubs now just forwards one fixed page id into the shared opener.
instead. That narrows the remaining `LoadScreen.win` gap again: `TRAIN DETAIL` and
`STATION DETAIL` now read as dormant title-table entries unless some still-unrecovered nonstandard
selector reaches them. The live auto-load boundary is tighter now too: hook-driven
`shell_transition_mode(4, 0)` now completes old-mode teardown, reconstructs and republishes
`LoadScreen.win`, and returns cleanly, but the later post-transition service ticks still keep
`[0x006cec78] = 0`, `[shell_state+0x0c]` on the same `LoadScreen.win` singleton, and
`[LoadScreen.win+0x78] = 0` through at least counts `2..8`. So the next runtime edge is no
longer the old mode-`4` teardown or publish band; it is the `LoadScreen.win` message owner
`0x004e3a80` itself, because later service alone is not promoting the plain load screen into the
separate startup-runtime object path. One later runtime probe did not actually reach that edge:
the `0x004e3a80` hook installed, but the run never produced any ready-count, staging,
transition, post-transition, or load-screen-message lines, only ordinary shell node-vcall
traffic. So that result is now treated as a gate-or-cadence miss rather than as evidence against
the `LoadScreen.win` message path itself. The newer shell-state service trace tightens it again:
on a successful staged run the later service ticks do execute in `mode_id = 4`, but the
`0x004e3a80` message hook still stays silent while the state remains frozen in the plain
`LoadScreen.win` shape. So the next runtime boundary is now the shell-runtime prime call
`0x00538b60` beneath `shell_state_service_active_mode_frame` `0x00482160`, not the message owner
alone. The first direct `0x00538b60` probe run is not trustworthy yet, though: it stopped
immediately after the first shell-state service-entry line, before any ready-count or
runtime-prime entry logs. So that result is currently treated as probe validation work, not as a
real boundary move inside RT3. The static service branch is conditional too: `0x00482160` only
enters `0x00538b60` when `[shell_state+0xa0] == 0`, so silence from the runtime-prime hook does
not yet prove the shell stops before that call unless the service-entry logs also show the `+0xa0`
gate open. The newer run now closes that condition: `[shell_state+0xa0]` is `0`, and the
`0x00538b60` runtime-prime hook enters and returns cleanly. The newer run closes the next owner
too: `0x00520620` `shell_service_frame_cycle` also enters and returns cleanly on the same frozen
mode-`4` path, and the logged fields match its generic branch rather than a startup-promotion
lane (`[+0x1c] = 0`, `[+0x28] = 0`, `flag_56 = 0`, `[+0x58]` pulsed then cleared, and
`0x006cec78` stayed `0`). The static body under the same owner is tighter now too: `0x00538b60`
first re-enters `0x0054f6a0`, refreshes the primary timed-text lane from `[owner+0x1c]` through
`0x005386e0` when that deadline has expired, walks the registered shell-window list from tail
`[owner+0x04]` backward through `+0x54` while servicing each node through `0x0053fda0` and
`0x0051f1d0`, and only then conditionally presents the secondary and primary text lanes through
`0x005519f0`. So the next runtime boundary under the same shell-state service pass is now one
level deeper: the per-object service walker `0x0053fda0` beneath `0x00538b60`. The newer run
closes that owner too: it enters and returns cleanly while servicing the `LoadScreen.win` object
itself, with `field_1d = 1`, `field_5c = 1`, and a stable child list under `[obj+0x70/+0x74]`,
and its first child-service vcall target at slot `+0x18` stays `0x005595d0`. Since `0x006cec78`
still stays `0` through those clean object-service passes, the next runtime boundary is now the
child-service target `0x005595d0`, not the higher object walker. The newer child-service run
narrows that again: the first sixteen `0x005595d0` calls are stable child lanes under the same
`LoadScreen.win` parent, with `[child+0x86]` pointing back to the load-screen object,
`field_b0 = 0`, and a split where earlier children carry `flag_68 = 0x03` and return `4` while
later siblings carry `flag_68 = 0x00` and return `0`. The static body matches that read too:
`0x005595d0` is gated by `0x00558670` and then spends most of its work in draw or overlay
helpers `0x54f710`, `0x54f9f0`, `0x54fdd0`, `0x53de00`, and `0x552560`, so it now reads as
another presentation-side service lane rather than the missing startup-runtime promotion. The
widened allocator-window trace then reconciled the runtime with
the static mode-`4` branch one step further: the first transition-window allocation is `0x7c`,
which matches the static pre-construct `0x48302a -> 0x53b070` alloc exactly, and the later
`0x111/0x84/0x3a/0x25...` allocations all occur before `LoadScreen.win` construct returns, so
they now read as constructor-side child or control setup. That means the allocator probe did not
disprove the still-silent startup-runtime slice; it simply exhausted its log budget inside the
constructor before the post-construct block. The later reset-at-return run is now the decisive
one: after `LoadScreen.win` construct returns there are still no further allocator hits before
publish and transition return, which matches the corrected jump-table decode because mode `4`
does not own the `0x46c40 -> 0x4336d0 -> 0x438890` startup-runtime path.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,652 @@
# Input, Save/Load, and Simulation: Post-load Generation, PaintTerrain, and Save/Load Restore
### Post-load Generation, PaintTerrain, and Save/Load Restore
The same brush strip is tighter now too:
`0x004bc210` stores the selected ordinal and refreshes one scalar caption
from table `0x00621e24`, `0x004bc260` exposes the cached world coordinate pair plus the
currently selected scalar, and `0x004bc290` restyles the ordinal strip `0x0fa1..0x0fa7` plus
the mapped mode strip `0x0faa..0x0faf` against the current mode dword `[0x006d0818+0x8c]`. The
next unresolved layer is narrower and more semantic: the setup side now has one grounded
owner, `world_run_post_load_generation_pipeline`, and its building-side branch is no longer just
one opaque block. We now have a region family, a region-border overlay rebuild, a region-owned
structure-demand and placement dispatcher, and a deeper per-region worker that computes category
demand, subtracts existing coverage, and tries candidate placements. The category map is tighter
too: category `0` falls back to `House`, category `2` is the year-gated weighted region-profile
family that also feeds the localized `Industry Weightings` stats panel, and category `3` now
reaches a separate pool-driven picker whose fallback label is `Commercial` but whose aligned
player-facing stats bucket is `City Support`. The normalized region band is tighter too:
`world_region_normalize_cached_structure_balance_scalars` `0x00422320` no longer just writes an
anonymous cached preview band at `[region+0x2e2/+0x2e6/+0x2ea/+0x2ee]`. Current growth-report
evidence now grounds `[region+0x2e2]` as the weighted-profit-margin scalar and `[region+0x2ee]`
as the annual-density-adjust scalar later formatted as a percent in `Stats - City/Region`, with
`[region+0x2e6/+0x2ea]` left as the intermediate normalized-delta and clamped companion slots
beneath that final adjust term. The per-region prepass feeding that normalization is tighter too:
`0x00420d40` clears `[region+0x306/+0x30a/+0x30e]`, walks the linked placed-structure chain from
`[region+0x383]`, accumulates two local placed-structure metrics through `0x0040ca70` and
`0x0040ca80`, and only for class-0 candidates also folds source field `[source+0x141]` through
`0x0040cec0` into the third accumulator before tailing into the later scalar refresh. That tail
helper `0x00420560` is tighter now too: on class-0 regions it revisits the same linked chain and
folds a class-mix contribution into `[region+0x312]`, with one source-derived term for candidate
class `0`, a separate branch keyed by `[candidate+0x78c]` and `[site+0x246]` for class `2`, one
fixed increment for class `3`, and no current contribution from class `1`. One neighboring
collection-side dispatcher is tighter now too: `0x00433b80` only runs when global mutation depth
`0x0062be40` is back at zero and then conditionally fans into the optional refresh hooks
`0x00481430`, `0x00413860`, `0x004b2a90`, and `0x004931e0`. The periodic boundary
side is narrower now too. `0x00422100`, reached only from
`simulation_service_periodic_boundary_work` `0x0040a590`, first requires several live world
state gates to stay clear, derives one year-sensitive random threshold from selected-year fields
plus world width, then scans the region collection for eligible class-0 regions whose transient
dwords `[region+0x276]` and `[region+0x302]` are both clear and which fail the city-connection
peer probe `0x00420030(1,1,0,0)`. When the gate passes it picks one random eligible region,
derives one small severity bucket from `[region+0x25e]`, stores the scaled amount back into
`[region+0x276]`, and appends one queued `0x20`-byte record through `0x004337c0` with literal
kind `7`, the chosen region id, that amount, the fixed payload `0x005c87a8`, and sentinel dwords
`-1/-1`. That append helper is now grounded directly too: `0x004337c0` allocates one zeroed
linked `0x20`-byte node, copies one string or payload seed into `[node+0x04..]`, stores the six
trailing caller dwords at `[node+0x08..+0x1c]`, and appends the finished node to the singly
linked list rooted at `[state+0x66a6]`. The gameplay label for that queued-record family is still
open, but the structural link from periodic region selection into the scenario-state queue is now
direct instead of speculative. One neighboring narrow counter is bounded too: `0x00422850`
counts class-0 regions that pass a second `0x00420030` peer-probe variant with fixed flags
`(1,1,1)` plus one caller-supplied trailing dword, and current callers are the query/script
dispatch at `0x0042f856` and the later region-stats formatter at
`0x004d2088`. The
remaining setup-side uncertainty has therefore narrowed
again: the region seed and border-overlay pair clearly complete before the `Setting up Players and
Companies...` banner is posted; `[0x006cec74+0x174]` now looks like the direct building-population
gate; `[0x006cec74+0x178]` now looks like the direct seeding-burst gate and selected-year-adjust
policy; and `[0x006cec74+0x68]` now aligns with editor-map mode because the same flag forces the
`.gmp` family in the shell file coordinators while suppressing the later building and seeding
branches and diverting the deeper region worker into alternate logic. One write side for that
`[shell+0x178]` policy is now grounded too: inside `shell_dispatch_ui_command` `0x00464410`,
command ids `0x9d26..0x9d28` store `command_id - 0x9d26` directly into `[0x006cec74+0x178]`,
yielding live values `0`, `1`, and `2`. That means the later restore branch is no longer gated
by an abstract hidden shell latch; at least one of its adjustment inputs is an explicit UI
launch policy and current evidence still does not show that value being recovered from saved
state. The `319` lane itself is no longer the
open structural gap; it now clearly owns chairman-profile slot seeding, profile-record
materialization, a shell editor surface over the same local record family, and a separate
live-company presentation path through the company-list window. The later interior order of that
same `319` lane is tighter now too: after the route-entry collection refresh on `0x006cfca8` it
refreshes the auxiliary route-entry tracker collection `0x006cfcb4`, then runs
`placed_structure_collection_refresh_local_runtime_records_and_position_scalars` `0x004133b0`,
then a flagged world-grid cleanup sweep through the compact grid-flag query
`0x00448af0` plus the neighboring local chunk-cell write helper `0x00533fe0`, and only after
that the later route-entry post-pass at `0x00491c20`. The same `319` lane is tighter internally
now too:
before that later world and shell reactivation tail, `world_entry_transition_and_runtime_bringup`
runs one distinct post-bundle status and runtime refresh phase that posts progress ids `0x196`
and `0x197` through `0x005193f0/0x00540120` with paired `0x004834e0` follow-ons, refreshes the
live event collection at `0x0062be18` through
`scenario_event_collection_refresh_runtime_records_from_packed_state` `0x00433130`, rebuilds the
scenario-side port-or-warehouse cargo recipe runtime tables through `0x00435630`, and then runs
the named-candidate availability preseed through `0x00437743`. One later subphase is tighter now
too: before the broad world-reactivation sweep it posts progress ids `0x32dc/0x3714/0x3715`,
reloads one `0x108`-byte packed profile block through `0x00531150`, conditionally copies staged
runtime-profile bytes back into `0x006cec7c` while latch `[profile+0x97]` is set, mirrors the
grounded campaign-scenario bit `[profile+0xc5]` and sandbox bit `[profile+0x82]` into world
bytes `[world+0x66de]` and `[world+0x66f2]`, and restores the selected year/profile lane through
a tighter two-stage calendar path than before. Current local disassembly now shows the raw saved
lane at `[profile+0x77]` first feeding helper `0x0051d3f0` with constant components
`(month=1, day=1, subphase=0, tick=0)`, which writes the resulting Jan-1-style tuple dwords
into `[world+0x05/+0x09]`. Only after that seed does the same lane enter one mode-sensitive
adjustment branch: non-editor startup mode can decrement the lane by `1` or `3` depending on
shell-state editor gate `[0x006cec74+0x68]`, shell-side selected-year-adjust policy
`[0x006cec74+0x178]`, and the saved special-condition slot `[0x006cec78+0x4af7]`, and only that
adjusted lane then feeds
helper `0x0051d390` before `world_set_selected_year_and_refresh_calendar_presentation_state`
`0x00409e80` stores the final absolute counter into `[world+0x15]` and refreshes
`[world+0x0d/+0x11]`. That means the restore no longer reads as a direct
`[profile+0x77] -> [world+0x15]` copy; the raw lane seeds the tuple immediately, but the final
absolute-counter restore still depends on live shell/startup context. That dependency is tighter
now too: current local evidence shows `[shell+0x178] == 1` decrementing the restored lane by
`1`, `[shell+0x178] == 2` subtracting `3`, and otherwise a nonzero
`[0x006cec78+0x4af7]` supplying the fallback `-1` branch. That field is no longer unresolved:
current local disassembly now shows `0x00436d10` bulk-zeroing the dword table rooted at
`[startup+0x4a7f]` through `rep stos`, which includes `+0x4af7`, while the editor-side special
conditions owner at `0x004cb2b0/0x004cb8e0` counts and commits that same 49-entry table from the
static rule descriptors at `0x005f3ab0`. The `.smp` save or restore family now grounds that live
band directly too: `world_runtime_serialize_smp_bundle` `0x00446240` writes `49` dwords from
`[world+0x4a7f..+0x4b3f]` plus one trailing scalar at `[world+0x4b43]`, and
`world_load_saved_runtime_state_bundle` `0x00446d40` restores the same fixed `0xc8`-byte band
symmetrically. Slot `30` in that table is localized pair `3722/3723`
`Disable Cargo Economy`, so `+0x4af7` now reads as the live copy of that saved scenario rule,
not a startup-runtime-only mystery latch. The neighboring fixed reads line up with the same rule
cluster too: `+0x4aef` is slot `28` `Completely Disable Money-Related Things`, `+0x4af3` is slot
`29` `Use Bio-Accelerator Cars`, `+0x4afb` is slot `31` `Use Wartime Cargos`, `+0x4aff` is slot
`32` `Disable Train Crashes`, `+0x4b03` is slot `33` `Disable Train Crashes AND Breakdowns`, and
`+0x4b07` is slot `34` `AI Ignore Territories At Startup`. So the remaining loader gap is
narrower than before: the restore still depends on live shell policy `[shell+0x178]`, but the
`+0x4af7` input itself is save-derived scenario rule data rather than something that requires
runtime tracing to discover. Its read-side family is no longer isolated to the selected-year
restore either: it also shapes the chunk size in
`simulation_run_chunked_fast_forward_burst` `0x00437b20` and appears in candidate/local-service
selection and station-detail-side scoring branches around `0x0047f910`, `0x00410d87`, and
`0x005069c6`, which now makes this whole slot cluster look like broader runtime consumers of
scenario special conditions rather than one startup-only mode enum. One file-side anchor is now
tighter too: the checked classic and 1.05 `gmp/gms/gmx` corpus does expose the same aligned
`0x0d64..0x0e2c` `50`-dword band as the grounded `.smp` runtime save or restore copy into
`[world+0x4a7f..+0x4b43]`, but most checked file families only populate a sparse subset of that
band. The first `36` dwords still behave like the older inferred fixed rule matrix with hidden
slot `35` fixed to sentinel value `1`, while the trailing `13` unlabeled rule lanes plus one
scalar vary much more selectively by file family. Current local corpus scans make that split
concrete: the grounded 1.05 scenario-save family (`p.gms`, `q.gms`) stably lights lanes
`35, 37, 39, 44, 45, 46, 47, 48`; the base 1.05 save family (`Autosave.gms`, `nom.gms`) only
shares lane `35` stably and otherwise varies sparsely through `42`, `45`, and `47`; the checked
grounded 1.05 maps, the lone 1.05 alt save, and the visible sandbox-family `.gmx` files keep
only the sentinel lane `35` nonzero. So the current loader boundary is narrower than before: the
`.smp` path still gives a grounded direct runtime-band restore, and checked `gmp/gms/gmx` files
now show a partially populated projection of that same aligned band rather than a wholly separate
fixed record family. The overlap against the later scalar window is now explicit too: trailing
band indices `36..49` are byte-identical with post-window offsets `0x00..0x34`, so every nonzero
lane in that prefix of the post-sentinel scalar window is also a nonzero lane in the aligned
runtime-rule band. That means the real “other fields” boundary inside the post-sentinel window
starts only at `0x0e2c`: `0x0df4..0x0e2c` is the aligned-band overlap prefix, while
`0x0e2c..0x0f30` is the later tail that still looks like save-side scalar state. Local corpus
scans now make that tail split more specific. The base 1.05 save family
(`Autosave.gms`, `nom.gms`) shares a stable tail subset at relative offsets
`0xb4`, `0xc0`, `0xe0`, `0xfc`, and `0x100`, with additional per-file lanes around them. The
1.05 scenario-save family (`p.gms`, `q.gms`) has a much denser stable tail covering
`0x08`, `0x0c`, `0x10`, `0x14`, `0x20`, `0x24`, `0x28`, `0x30`, `0x34`, `0x3c`, `0x5c`,
`0x6c`, `0xa0`, `0xa8`, `0xbc`, `0xc0`, `0xc4`, `0xc8`, `0xcc`, `0xdc`, `0xe0`, `0xe4`,
`0xe8`, `0xf4`, `0xf8`, and `0xfc`; those values still differ per save, but the occupancy is
stable. The lone 1.05 alt save (`g.gms`) only lights `0x20`, `0x34`, `0xf0`, and `0xf4`.
Grounded map families and classic saves keep the tail zeroed, while the only current map-side
outlier remains `Tutorial_2.gmp` under the broad unknown map-family bucket. The immediately
following fixed file window at `0x0df4..0x0f30` is now bounded separately as well: checked maps
and classic saves leave that whole post-sentinel band zeroed,
while checked 1.05 saves carry sparse nonzero dwords there, many of which decode cleanly as
normal little-endian `f32` values. That makes the adjacent band look like a 1.05 save-only
runtime band rather than scenario-static payload, even though its semantics are still open.
One numeric alignment inside that band is now exact too: the tail start `0x0e2c` is the same
relative distance from the aligned runtime-rule base `0x0d64` as live object offset `+0x4b47`
is from grounded world-rule base `[world+0x4a7f]`, so the bounded tail window
`0x0e2c..0x0f30` is offset-aligned with live bytes `[world+0x4b47..+0x4c4b]`. The first
grounded live field at that boundary is no longer anonymous. `0x004367c0` sets one outcome mode
in `[world+0x4a73]`, zeros `[world+0x4d]`, snapshots the selected-year lane to `[world+0x4c88]`,
and then copies localized id `2923` `You lose.` or `2924` `You win, cheater...` into
`[world+0x4b47]`; `0x00472dd0` formats localized id `3918` `%1 has won the game!` with one live
profile name and writes that string into the same destination; and one compact runtime-effect
branch inside `world_apply_compact_runtime_effect_record_to_resolved_targets` `0x00431b20` resets
the same destination to the fixed placeholder token at `0x005c87a8`. That gives a grounded live
interpretation for the start of the tail: `[world+0x4b47]` is the start of a victory or outcome
status-text buffer, not a float lane. The same evidence also gives a useful caution: those live
helpers copy up to `0x12c` bytes into `[world+0x4b47..+0x4c73]`, so the current bounded file-tail
window `0x0e2c..0x0f30` cuts through the first `0x104` bytes of a grounded text field rather
than ending on a clean live-field boundary. One small continuation probe now tightens that edge:
the remaining file window `0x0f30..0x0f58` is exactly the last `0x28` bytes needed to reach the
clean live-field boundary at `[world+0x4c73]`, and checked 1.05 saves still carry sparse nonzero
bytes in that continuation window rather than a trailing text-looking suffix. Checked 1.05 save
bytes in the aligned region therefore still do not resemble preserved text; they stay mostly zero
at the beginning and many nonzero lanes decode as ordinary `f32` values. So the safest current
note is: the tail is offset-aligned with the live object beyond `+0x4b43`, but it is not yet a
validated byte-for-byte mirror of the live `[world+0x4b47]` status-text buffer, and the current
nonzero save-side content continues right up to the first clean field edge at `0x0f58`. The next
exact grounded fields after that edge are byte lanes, not restored dwords: `0x0f59` maps to
`[world+0x4c74]` `Auto-Show Grade During Track Lay`, `0x0f5d` maps to `[world+0x4c78]`
`Starting Building Density Level`, `0x0f61` maps to `[world+0x4c7c]` `Building Density Growth`,
`0x0f65` maps to grounded dword `[world+0x4c80]` `leftover simulation time accumulator`, and
`0x0f6d` maps to byte `[world+0x4c88]` `selected-year lane snapshot`. The first later grounded
dword after that is `[world+0x4c8c]` at `0x0f71`. That means the simple 4-byte file-lane model
stops matching grounded live field boundaries immediately after the text-buffer edge: the post-
`0x0f58` file bytes are still offset-correlated to live state, but they are no longer naturally
dword-aligned with the next grounded object fields. The new byte-neighborhood probe makes the
mismatch more concrete. In checked 1.05 scenario saves, the exact grounded byte offsets
themselves do not look like clean selector values: `p.gms` carries `0x33` at `0x0f5d` and `0x8c`
at `0x0f6d`, while `q.gms` carries `0xcc` and `0xba` at those same offsets. The only clean
float-looking starts in that neighborhood instead appear one byte earlier, at `0x0f5c` and
`0x0f6c`: `p.gms` decodes those as roughly `7.6` and `6.0172`, while `q.gms` decodes them as
roughly `23.6` and `44.6824`. That tightens the current read further: the checked save bytes
remain offset-correlated to the live `[world+0x4c74..+0x4c8c]` neighborhood, but they are still
not a validated byte-for-byte mirror of the exact live field layout. Local
A second byte-oriented neighborhood immediately after that now has the same kind of split rather
than a clean restored-field mirror. The earlier grounded anchors in that band all stay zero in
the checked 1.05 saves: exact file offset `0x0f87` maps to selected-year bucket companion scalar
`[world+0x4ca2]`, while `0x0f93` and `0x0f97` map to the two startup-dispatch reset-owned bands
`[world+0x4cae]` and `[world+0x4cb2]`, and the local corpus leaves all three exact dword starts
zeroed. The same is true for the later exact byte-owned policy lanes: file offsets `0x0f78`,
`0x0f7c`, `0x0f7d`, and `0x0f7e` map cleanly to grounded byte fields `[world+0x4c93]` and
`[world+0x4c97..+0x4c99]`: the linked-site removal follow-on gate plus the three editor
locomotives-page policy bytes `All Steam Locos Avail.`, `All Diesel Locos Avail.`, and `All
Electric Locos Avail.`. In the checked 1.05 save corpus those four exact byte lanes all stay
`0`, which is at least structurally clean. The later grounded dword fields in the same
neighborhood are less direct again. Exact file offset `0x0f9f` maps to `[world+0x4cba]` (the
station-list selected-station mirror) and exact offset `0x0fa3` maps to cached
available-locomotive rating `[world+0x4cbe]`, but the checked save bytes at those exact dword
starts do not look like clean preserved ids or floats. The only stable float-looking starts sit
three bytes earlier, at `0x0f9c` and `0x0fa0`: `p.gms` yields roughly `96.8754` and `186.4795`,
`q.gms` yields `329.9467` and the same `0x0fa0`-side candidate shape, `g.gms` yields `7.0` and
`95.8507`, and `Autosave.gms` only shows the later `0x0fa0` candidate at about `68.2629`. So
this later band now has the same conservative read as the post-text one: the save bytes are
still offset-correlated to grounded live fields, but the exact live byte or dword layout is not
yet validated as a direct on-disk mirror.
One more structural cut is now grounded beyond that neighborhood. The aligned scalar plateau
`0x0fa7..0x0fe7` ends exactly at the later recipe-book root `[world+0x0fe7]` already grounded in
the port-or-warehouse cargo editor and runtime rebuild path. We still do not have live semantic
names for the plateau itself, but its aligned dword run now splits cleanly by save family. The
base 1.05 saves (`Autosave.gms`, `nom.gms`) carry one stable signature with
`0x0faf = 0x8000003f`, `0x0fb3 = 0x75c28f3f`, repeated `0x75c28f3c` lanes through `0x0fbf`, a
sign-flipped lane `0x0fc3 = 0xa3d70a3c`, one tiny marker at `0x0fc7 = 0x0000003b`, and
`0x0fcb = 0x00300000`. The scenario-save family (`p.gms`, `q.gms`) carries a different stable
plateau over the same offsets, beginning `0x0faf = 0x4000003f`, `0x0fb3 = 0xe560423f`, then
`0x03126f3b`, `0x1374bc3c`, and paired `0x23d70a3c` lanes at `0x0fbf/0x0fc3`, with
`0x0fc7 = 0x0000003c`. The alt-save family (`g.gms`) follows the base signature through
`0x0fc7`, then diverges sharply into the same `0xcdcdcd..` fill pattern already seen in its
earlier header lanes. So the current best fit for `0x0fa7..0x0fe7` is a family-shaped aligned
scalar plateau that belongs to save-side runtime state and terminates immediately before the
grounded recipe-book block, not one more directly named live-field mirror. One conservative
loader-side summary probe now starts exactly at that recipe root instead of extending the plateau
model further. The fixed recipe-book block spans twelve books from `0x0fe7` with stride `0x4e1`,
and the checked map/save pairs `Alternate USA.gmp -> Autosave.gms`, `Southern Pacific.gmp ->
p.gms`, and `Spanish Mainline.gmp -> g.gms` preserve that rooted block byte-for-byte in the
sampled local corpus. The current probe therefore treats it as preserved scenario payload rather
than save-only runtime drift and only reports per-book signatures: a coarse head kind over the
pre-line region, the raw `book+0x3ed` annual-production dword, and one raw summary for each of
the five fixed `0x30`-byte cargo lines beginning at `book+0x3f1`: coarse line kind, raw mode
dword, raw annual-amount dword, and the raw supplied/demanded cargo-token dwords at `+0x08` and
`+0x1c`. That is enough to separate zero, `0xcd`-filled, and mixed books or lines without
overstating line semantics beyond the grounded editor/runtime ownership already documented below.
Local
corpus clustering now makes the remaining split more specific. The base 1.05 save family
(`Autosave.gms`, `nom.gms`) shares a narrow tail-heavy subset with stable relative offsets
`0xec`, `0xf8`, `0x118`, `0x134`, and `0x138`, while still varying in value across files. The
1.05 scenario-save family (`p.gms`, `q.gms`) shares a much broader stable set spanning almost the
whole window from `0x04` through `0x134`, again with per-file scalar differences but consistent
occupancy. Pairwise compare runs tighten that read further: `Autosave.gms` vs `nom.gms` does not
preserve one common numeric tail signature even at the shared base-save offsets, and `p.gms` vs
`q.gms` keeps the broad scenario-save occupancy pattern but still changes every shared value, with
`q.gms` additionally lighting two extra lanes at `0x78` and `0x84`. So the current best fit is
“family-shaped live scalar state” rather than family-default constants. The lone 1.05 alt-save
sample (`g.gms`) only lights up four lanes at `0x58`, `0x6c`,
`0x128`, and `0x12c`. The checked 1.05 maps and classic saves stay zero in that same bounded
window, which strengthens the current read that this is runtime-save scalar state rather than
generic map payload. One older unknown map-family outlier in the local corpus does still carry a
populated window: `Tutorial_2.gmp` under the classic install tree. So the safest current note is
“zero for grounded map families and classic save families, nonzero for observed 1.05 save
families, with one older unknown-map exception.” Static consumer grounding is still sparse for
that tail: direct object-offset hits currently only name the trailing scalar `[world+0x4b43]`
through the editor panel and `.smp` save or restore family, while local opcode searches do not
yet surface equally direct reads for the intervening `+0x4b0b..+0x4b3f` tail lanes. So the
save-file family clustering is now strong, but those later tail scalars remain structurally
bounded rather than semantically named. The
same branch is no longer world-entry-only either: current local
disassembly now shows the identical lane-adjust and
`0x51d3f0 -> 0x51d390 -> 0x409e80` sequence in the post-fast-forward selected-year tail at
`0x004370e0`, which lines up with the existing post-fast-forward callers already mapped under
`0x00433bd0`, `0x00435603`, `0x0041e970`, and `0x00436af0`. That restore now
also has some neighboring slot semantics bounded well enough to carry in the loader notes. Slot
`31` `[0x006cec78+0x4afb]` is no longer best read as an unnamed runtime cargo-economy latch:
local disassembly now ties it directly to the saved special-condition table entry `Use Wartime
Cargos`, and the strongest current runtime owner is
`structure_candidate_collection_refresh_cargo_economy_filter_flags` `0x0041eac0`. Inside that
candidate-collection sweep the branch at `0x0041ed37` only activates when slot `31` is set and
then treats the string family `Clothing`, `Cheese`, `Meat`, `Ammunition`, `Weapons`, and
`Diesel` as one special cargo set before writing the live candidate filter byte `[entry+0x56]`.
That makes the old read-side note around `0x00412560` tighter too: the neighboring descriptor
gate is now best understood as using the live copy of the `Use Wartime Cargos` scenario rule,
not an anonymous cargo-economy mode byte. Slot `34` `[0x006cec78+0x4b07]` is similarly bounded
on the runtime side: the wrapper at `0x004013f0`, which sits immediately above the broader
company-start or city-connection chooser `0x00404ce0`, snapshots region dword `[entry+0x2d]`
across all `0x18` live region records in `0x006cfc9c`, zeros that field while the chooser runs,
and then restores the original values on exit. That is a strong current fit for the editor rule
`AI Ignore Territories At Startup`, even though the exact meaning of region field `+0x2d`
remains open. Slot `29` `[0x006cec78+0x4af3]` is less semantically tidy but still worth carrying
as a bounded consumer family: the branch at `0x0041d286` activates one later placed-structure or
building-side scoring path only when that slot is nonzero and the linked candidate or era record
at `[entry+0x41]` equals `5`, while two already-grounded world helpers
`world_scan_secondary_grid_marked_cell_bounds` `0x0044ce60` and
`world_service_secondary_grid_marked_cell_overlay_cache` `0x0044c670` also gate on the same
slot. So the identity of slot `29` as saved rule data is grounded, but the downstream runtime
semantics are still mixed enough that the loader should preserve the raw value without trying to
rename its whole consumer family yet. The neighboring train-safety slots are now bounded enough
to keep as a cautious runtime split too. Slot `33` `[0x006cec78+0x4b03]`
`Disable Train Crashes AND Breakdowns` is the coarse gate in the currently recovered train-side
deterioration family around `0x004af8a0`: the very first branch at `0x004af8ab` jumps straight
to the function tail when the slot is set, bypassing the year-scaled threshold build, the later
random or threshold comparison, and the two follow-on state transitions at `0x004ad7a0` and
`0x004ada00`. Slot `32` `[0x006cec78+0x4aff]` `Disable Train Crashes` is narrower in the same
family: after the threshold path has already run, the branch at `0x004af9c1` uses slot `32` to
suppress only the lower failure-transition path and force the milder follow-on at `0x004ada00`.
That same slot-`33` read also appears in the smaller train-side scalar query at `0x004ac460`,
where setting it returns one fixed float immediately before the ordinary route-object-dependent
calculation runs. So the current best loader-facing read is: slot `33` is the broad train
deterioration bypass, slot `32` is the narrower crash-only branch inside that same family, but
the exact player-facing names of the two unnamed train helpers still need one more naming pass.
That restore now
also has one concrete file-side correlation in the classic `.gms` family: local save inspection
now consistently finds `0x32dc` at `0x76e8`, `0x3714` at `0x76ec`, and `0x3715` at `0x77f8` in
`Autosave.gms`, `kk.gms`, and `hh.gms`, leaving one exact `0x108`-byte span from `0x76f0` to
`0x77f8` between `0x3714` and `0x3715`. That span already carries staged-profile-looking payload
text such as `British Isles.gmp`, so the current static-file evidence now supports the atlas-side
`0x108` packed-profile note for the classic save family even though the exact field layout inside
that block is still unresolved. The same classic corpus is tighter now too: inside that
`0x108` span the map-path C string begins at relative offset `0x13`, the display-name C string
begins at `0x46`, the block is otherwise almost entirely zeroed, and the three local samples are
byte-identical except for the leading dword at `+0x00` (`3` in `Autosave.gms` and `hh.gms`,
`5` in `kk.gms`). The currently atlas-tracked bytes `[profile+0x77]`, `[profile+0x82]`,
`[profile+0x97]`, and `[profile+0xc5]` are all `0` in that classic sample set, so the current
file-side evidence grounds the block boundaries and the embedded strings but does not yet show
live examples of those branch-driving latches being set. One 1.05-era file-side analogue is now
visible too, but only as an inference from repeated save structure rather than a disassembly-side
field map: local `.gms` files in `rt3_105/Saved Games` carry one compact string-bearing block at
`0x73c0` with the same broad shape as the classic profile slab, including a leading dword at
`+0x00`, one map-path string at `+0x10`, one display-name string at `+0x43`, and a small
nonzero tail around `+0x76..+0x88`. In that 1.05 corpus the analogue bytes at relative `+0x77`
and `+0x82` are now nonzero in every checked sample (`Autosave.gms`/`nom.gms` show `0x07` and
`0x4d`; `p.gms`/`q.gms` show `0x07` and `0x90`; `g.gms` shows `0x07` and `0xa3`), while
relative `+0x97` and `+0xc5` remain `0`. The compared 1.05 save set is tighter now too:
`Autosave.gms` and `nom.gms` cluster together on `Alternate USA.gmp` with `+0x82 = 0x4d`,
`g.gms` carries `Spanish Mainline.gmp` with `+0x82 = 0xa3`, and `p.gms`/`q.gms` cluster on
`Southern Pacific.gmp` with `+0x82 = 0x90`; across all five files the same inferred analogue
lane at `+0x77` stays fixed at `0x07`, while the same map- or scenario-sensitive tail word at
`+0x80` tracks those `0x4d/0xa3/0x90` byte lanes (`0x364d0000`, `0x29a30000`, `0x1b900000`).
The leading dword at `+0x00` also splits the same corpus, with `Autosave.gms` alone at `3` and
the other four checked 1.05 saves at `5`. That is enough to say the wider save corpus does
contain nonzero candidates for two of the atlas-tracked profile lanes, and that one of them
varies coherently with the loaded scenario family, but not yet enough to claim that the 1.05
block reuses the exact same semantic field assignments as the classic one. The loader-side
family split is tighter now too: `p.gms` and `q.gms` no longer live under a generic fallback;
their save headers now classify as one explicit `rt3-105-scenario-save` branch with preamble
words `0x00040001/0x00018000/0x00000746` and the early secondary window
`0x00130000/0x86a00100/0x21000001/0xa0000100`, while `g.gms` now classifies as a second
explicit `rt3-105-alt-save` branch with the different preamble lane
`0x0001c001/.../0x00000754` and early window
`0x00010000/0x49f00100/0x00000002/0xa0000000`. That branch now carries the same bootstrap,
anchor-cycle, named 1.05 trailer, and narrow profile-block extraction path as the other 1.05
saves. The bridge just below that trailer is now explicit too: the common 1.05 save branch
carries selector/descriptor `0x7110 -> 0x7801` in `Autosave.gms` and `0x7110 -> 0x7401` in
`nom.gms`, and both still reach the same first later candidate at
`span_target + 0x189c`, well before the packed profile at `span_target + 0x3d48`; the
`rt3-105-alt-save` branch instead carries `0x54cd -> 0x5901` and its first later candidate
lands at `packed_profile + 0x104`, essentially on the profile tail; the scenario-save branch
still diverges locally with `0x0001 -> 0x0186` and never enters that later `0x32c8`-spanned
bridge at all. The common-branch bridge payload is narrower now too: both checked base saves
expose the same 0x20-byte primary block at `0x4f14` followed by the same denser secondary block
at `0x671c`, `0x1808` bytes later, and that secondary block now appears to run intact up to the
packed-profile start at `0x73c0` for a total observed span of `0xca4` bytes. The trailing slice
of that secondary block is now typed one level further: a small header at `secondary+0x354`
carries the observed stride `0x22`, capacity `0x44`, and count `0x43`, followed by a fixed-width
67-entry name table starting at `secondary+0x3b5` and running through names like
`AluminumMill`, `AutoPlant`, `Bakery`, `Port00..11`, and `Warehouse00..11`, with a short footer
(`dc3200001437000000`) after the last entry. The trailing per-entry word is now surfaced too:
most entries carry `0x00000001`, while the currently observed zero-trailer subset is
`Nuclear Power Plant`, `Recycling Plant`, and `Uranium Mine`. That footer is tighter now too:
it parses directly as `0x32dc`, `0x3714`, and one trailing zero byte, so the shared
map/save catalog currently ends on the same two grounded late-rehydrate progress ids that the
classic staged-profile band already exposed. The strongest structural read is therefore that the
entire `0x6a70..0x73c0` catalog region is shared verbatim between `Alternate USA.gmp` and the
derived `Autosave.gms`, not rebuilt independently during save. Combined with the earlier
grounded record-layout work under `0x00437743`, `0x00434ea0`, and `0x00434f20`, the current
safest semantic read is that this shared catalog is the bundled source form of the scenario-side
named candidate-availability table later mirrored into `[state+0x66b2]`, with each entry's
trailing dword now reading as the same availability override bit later copied into
`[candidate+0x7ac]`. The loader-side coverage is tighter now too: the same table parser now
attaches both to the common-save bridge payload and directly to the fixed source range in
`.gmp` files and the non-common `rt3-105-scenario-save` / `rt3-105-alt-save` branches. That
makes the scenario variation explicit instead of anecdotal. `Alternate USA` keeps only three
zero-availability names in this table (`Nuclear Power Plant`, `Recycling Plant`, `Uranium
Mine`), `Southern Pacific` widens the zero set to twelve (`AutoPlant`, `Chemical Plant`,
`Electric Plant`, `Farm Rubber`, `FarmRice`, `FarmSugar`, `Nuclear Power Plant`, `Plastics
Factory`, `Recycling Plant`, `Tire Factory`, `Toy Factory`, `Uranium Mine`), and `Spanish
Mainline` widens it again to forty-two, including `Bauxite Mine`, `Logging Camp`, `Oil Well`,
`Port00`, and the `Warehouse00..11` run while also flipping `Recycling Plant` back to
available. The header lanes just ahead of the table vary coherently with those scenario
branches too: `Alternate USA` carries `header_word_0 = 0x10000000`, `Southern Pacific`
carries `0x00000000`, and `Spanish Mainline` carries `0xcdcdcdcd`, while the structural
fields from `header_word_2` onward remain stable (`0x332e`, `0x1`, `0x22`, `0x44`, `0x43`)
and the 9-byte footer still decodes as `0x32dc`, `0x3714`, `0x00` in all three checked maps.
A wider corpus scan over the visible `.gmp`/`.gms` files makes those two anonymous header
lanes less mysterious too: the parser currently sees only three stable
`(header_word_0, header_word_1)` pairs across 79 files with this table shape, namely
`(0x00000000, 0x00000000)`, `(0x10000000, 0x00009000)`, and
`(0xcdcdcdcd, 0xcdcdcdcd)`. The zero-availability count varies widely underneath the first and
third pairs (`0..56` under the zero pair, `14..67` under the `0xcdcdcdcd` pair), so those two
lanes no longer look like counts or direct availability payload; the safest current read is
that they are coarse scenario-family or source-template markers above the stable
`0x332e/0x22/0x44/0x43` table header, with `0xcdcdcdcd` still plausibly acting as one reused
filler or sentinel lane rather than a meaningful numeric threshold. Current exported
disassembly notes still do not ground one direct loader-side or editor-side consumer of
`header_word_0` or `header_word_1` themselves, so that family-marker read remains an
inference from corpus structure rather than a named field assignment.
The new loader-side compare command makes the save-copy claim sharper too: for the checked
pairs `Alternate USA.gmp -> Autosave.gms`, `Southern Pacific.gmp -> p.gms`, and
`Spanish Mainline.gmp -> g.gms`, the parsed candidate-availability table contents now match
exactly entry-for-entry, with the only reported differences being the outer container family
(`map` vs `save`) and source-kind path (`map-fixed-catalog-range` vs the save-side branch).
has the explicit companion `world_refresh_selected_year_bucket_scalar_band` `0x00433bd0`, which
rebuilds the dependent selected-year bucket floats after the packed year changes; and then
rehydrates the named locomotive availability collection at `[world+0x66b6]` through
`locomotive_collection_refresh_runtime_availability_overrides_and_usage_state` `0x00461e00`.
That locomotive-side restore is tighter now too: its tail explicitly re-enters
`scenario_state_refresh_cached_available_locomotive_rating` `0x00436af0`, which rebuilds one
cached available-locomotive rating at `[state+0x4cbe]` from the current year plus the strongest
surviving available locomotive-side rating scalar `[loco+0x20]`, and the tiny query sibling
`0x00434080` is now bounded as the shell-side clamped read helper over that same cached field,
with the grounded shell-side reader later bucketing that value against `40/50/70/85/100`. The
same rehydrate band also refreshes the live structure-candidate filter and year-visible counts
through `structure_candidate_collection_refresh_filter_and_year_visible_counts` `0x0041e970`,
rebuilding the paired per-slot bands at `[candidates+0x246]` and `[candidates+0x16e]` and the
aggregate counts at `[candidates+0x31a]` and `[candidates+0x242]`; the same late checkpoint also
re-enters `placed_structure_collection_seed_candidate_subtype2_runtime_latch` `0x00434d40`,
which seeds runtime dword `[candidate+0x7b0]` across subtype-`2` candidate records before the
later world-wide reactivation sweep. That checkpoint also now has an explicit shell-facing scalar
publisher: `world_publish_shell_controller_progress_scalar_from_year_thresholds_or_selector_overrides`
`0x004354a0` writes one clamped `0..255` value into the current shell presentation object,
sourcing it either from the shell selector override pairs or from the scenario-side year-threshold
band rooted at `[state+0x3a/+0x51/+0x55/+0x59/+0x5d/+0x61]`; and just ahead of the later
scenario-side recipe rebuild, the same band also re-enters
`scenario_state_ensure_derived_year_threshold_band` `0x00435603`, which only falls into its
heavier rebuild body while `[state+0x3a] < 2` and otherwise leaves the derived year-threshold
companion slots `[state+0x51/+0x55/+0x59/+0x5d/+0x61]` unchanged. The neighboring late status
checkpoints around progress ids `0x196` and `0x197` also share one explicit stage gate now:
`world_query_global_stage_counter_reached_late_reactivation_threshold` `0x00444dc5` compares the
global counter `0x00620e94` against threshold `0x9901`, and the two current callers use a
negative result to clear `[world+0x39]` before the broader world and shell reactivation sweep.
The later reactivation tail is tighter now too: it includes the region-center world-grid flag
reseed pass
`0x0044c4b0`, which clears bit `0x10` across the live grid and then marks one representative
center cell for each class-`0` region through `0x00455f60`; its immediate sibling `0x0044c450`
then reruns `placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` across every
live grid cell. The small secondary-raster premark helper `0x0044c570` is bounded now too: it
only admits cells whose current raster byte has no bits in mask `0x3e` and whose parallel class
query `0x00534e10` is false, then rewrites that masked class field to `0x02` and widens the same
cached bounds-and-count band `[world+0x21c6..+0x21d6]`. The next helper `0x0044ce60` scans the secondary raster at `[world+0x2135]`
for cells with any bits in mask `0x3e`, caching min/max bounds plus a marked-cell count in
`[world+0x21c6..+0x21d6]`; the larger sibling `0x0044c670` then consumes those cached bounds to
normalize the same raster and rebuild one dependent overlay/cache surface before the later
route-style rebuild, shell-window, and briefing branches. That overlay side is tighter now too:
after `0x0044c670` resolves scaled surface dimensions through `0x00534c50`, it walks one local
`3 x 32` sample lattice through the static offset tables at `0x00624b28/0x00624b48`, keeps only
secondary-raster classes `4..0x0d`, folds several interpolated `0x0051db80` samples into one
strongest local score, writes packed overlay pixels into the staged surface buffer, and only then
publishes that staged overlay through `0x00534af0`. The lower helper layer under that overlay
pass is tighter now too: `0x00534e10` is the reusable secondary-raster class-set
predicate for classes `1/3/4/5`, `0x00534e50` is the smaller neighboring class-subset predicate
for `1/4`, `0x00534ec0` covers `2/4/5`, `0x00534f00` covers `3/5`, `0x00534e90` is the
marked-bit query over the same 3-byte cell family, and the nearby local counter `0x0044bdb0`
is now bounded as the 8-neighbor count companion for that same `2/4/5` subset, walking the
shared `0x00624b28/0x00624b48` offset tables and re-entering `0x00534ec0` on each bounded
neighbor cell. The first caller cluster around `0x0044bf9d..0x0044c37b` therefore reads as a
secondary-raster neighborhood service band rather than a generic map scan.
`0x00533e70` and `0x00534160` are the coarser siblings over the overlay table at `[world+0x1685]`:
the first clears coarse chunk objects across one clamped rectangle, while the second ensures one
chunk object and seeds local marks through its deeper stamp helper. One level up, the neighboring
rect owner `0x005374d0` now reads as the shared secondary-overlay refresh pass: it reruns the
local sample and unsigned-word reducers `0x00536230/0x00536420`, rebuilds the signed vector byte
planes through `0x00536710`, and then rebuilds the multiscale support surfaces through
`0x00533890`, whose inner reducers now explicitly target the packed sample-triplet buffer plus
the float and unsigned-word support planes rooted at the five-entry per-scale families
`[world+0x15f1..+0x1601]`, `[world+0x1605..+0x1615]`, and `[world+0x1619..+0x1629]`. The setup
side of that same family is tighter now too:
`0x005375c0` is the shared ensure-and-seed owner that allocates the sample, sidecar, mask,
raster, vector, and coarse-cell tables together; crucially, it seeds `[world+0x1655]` with byte
`0x02` and `[world+0x1659]` with byte `0x01`, which closes the default-fill split. The local
component-walk owner under the same neighborhood band is tighter now too: `0x0044c200`
allocates a temporary `width*height` visit bitmap at `0x0062c128`, seeds one class-`2/4/5`
starting cell, derives an initial direction index through the remap table `0x005ee5d4`, and then
fans into the deeper recursive walker `0x0044be20`. That deeper walker widens dirty bounds
`[world+0x21ad..+0x21b9]`, stamps one companion-word orientation lane through `0x005ee5cc`,
reuses `0x00534ec0` plus `0x0044bdb0` to filter admissible neighbors, tracks temporary
visitation in `0x0062c128`, and then applies the local byte-1 edge-bit `0x04/0x08` updates
before returning. So the `0x0044bf9d..0x0044c422` cluster now reads as a real connected-component
walk plus edge-flag refresh layer over the secondary raster rather than only a loose group of
local neighbor counters. The adjacent mutation strip is tighter now too: `0x0044dcf0` refreshes
companion-word bit `0x200` in one local rectangle by checking whether any neighbor belongs to
class set `2/4/5`, while `0x0044df10` clears three local sidecar byte planes, demotes class `4`
to `1` and class `5` to `3`, and then reruns that marked-bit refresh over the surrounding
`+/-1` window. One level up, `0x0044e500` is the rect-wide owner that recomputes byte-1 edge
bits `0x04/0x08` for class-`2/4/5` cells, dispatches `0x0044df10` on incompatible local
patterns, and finally consumes the pending global seed pair at `[0x006d1304+0x78/+0x7c]`
through `0x0044c200`. The shell-side owner of that pending pair is tighter now too:
`[0x006d1304]` is the live `PaintTerrain.win` shell singleton while the callback-heavy side also
keeps a second rooted pointer at `0x006d1334`; the tool constructor snapshots the broader
terrain-paint state into both families while the world-side raster owner still only consumes
`[0x006d1304+0x78/+0x7c]` as one pending component-seed pair. Its radial sibling `0x0044e7d0`
is narrower:
after validating world-space
coordinates through `0x00414bd0`, it stamps class-`2` marks into the secondary raster by walking
one clamped bounding box and admitting cells only when the radial falloff helper `0x0051db80`
stays positive before re-entering `0x0044c570`. The two small support predicates under that same
strip are now explicit too: `0x00414bd0` is the float grid-bounds gate, and `0x00449df0` is the
integer rectangle clamp-and-validity helper shared by the local mutation owners. One level up,
the broader rect-scoped owner is tighter now too:
`world_rebuild_secondary_raster_derived_surface_and_companion_planes_in_rect` `0x0044e940`
first reclamps the caller rectangle through `0x00449df0`, reruns the local edge-refresh owner
`0x0044e500`, lazily ensures one presentation target through
`0x0051f090/0x00534910/0x00534920/0x00534930`: the first helper resolves the shared
world-presentation owner, `0x00534910/0x00534920` expose the current staging flag and buffer
root, and `0x00534930` captures one normalized-bounds rect into that staging buffer before the
later publish step `0x00534af0`. The same family then resolves scaled target dimensions through
`0x00534c50` before allocating one temporary `width*height` mask. Its main scan then
walks the live secondary raster `[world+0x165d]` through the same class predicates
`0x00534e10/0x00534e50/0x00534f00/0x00534ec0`: class-`1/3/4/5` cells force `0xff` into the four
sidecar byte planes `[world+0x1631..+0x163d]`, while the broader per-cell pass writes packed
values into the ensured target through `0x00534730` and also updates nibble lanes at byte offsets
`+0x2` and `+0x5` inside the same three-byte secondary-raster cell family. After the publish it
notifies the shell owner at `0x0062be68`, re-enters `0x00449f80` and `0x004881b0`, frees the
temporary mask, expands the caller rectangle by dirty bounds `[world+0x21ad..+0x21b9]` through
`0x00536710`, and finally seeds companion byte `[world+0x162d]` with `0xc4` on cells selected
from mask plane `[world+0x1655]`. So the `0x0044e500 -> 0x0044e940` band is now a real
derived-surface and companion-plane rebuild family rather than only a loose collection of local
raster mutations. The local
evidence now also supports a stronger negative conclusion: unlike `[world+0x1655]`, that second
mask plane is not part of the actively rebuilt runtime overlay path, and in the grounded local
corpus it behaves only as a separately seeded, cleared, and persisted sibling plane. One level
lower, the
base-plane allocator `0x00532c80` now reads more cleanly too: it is the narrower owner that
clears `[world+0x15e1]`, optionally applies the current grid dimensions, allocates the base
float-summary plane `[world+0x1605]`, the four sidecar byte planes `[world+0x1631..+0x163d]`,
both one-byte mask planes `[world+0x1655/+0x1659]`, and the packed secondary raster
`[world+0x165d]`, then seeds those planes with the same `0x02/0x01/0x00` default split. The
load-side owner for those same planes is tighter now too: the constructor thunk `0x0044e910`
immediately feeds the heavier payload body `0x0044cfb0`, which reads the rooted chunk families
`0x2ee2/0x2ee3/0x2ef4/0x2ef5/0x2ef6/0x2ee4/0x2ee5/0x2f43/0x2f44`, allocates the core world-grid
and secondary-raster arrays `[world+0x2129..+0x2141]` plus the route-entry collection
`0x006cfca8`, initializes every grid-cell record through `0x0042ae50`, and only then hands off
into `world_compute_transport_and_pricing_grid` `0x0044fb70`, the neighboring presentation
refresh `0x00449f20`, and the shell-mode pulse `0x00484d70`. So the `0x0044e910 -> 0x0044cfb0`
load side is now bounded as the heavy world-grid and secondary-raster bundle-load body rather
than just another anonymous constructor tail. One
level higher again, the broader world-presentation reinitializer `0x00537e60` now sits above
that base allocator and the larger support-family ensure path `0x005375c0`: it stores the live
grid dimensions, hard-resets the whole overlay runtime family through `0x00532590`,
and that reset strip is no longer opaque either: the immediately preceding local helpers
`0x00532310..0x00532550` now bound one compact overlay-local state family under the same owner.
`0x00532310/0x00532360/0x00532370/0x00532380` own the seven-dword companion block
`[world+0x15b5..+0x15cd]` together with live flag byte `[world+0x15b4]`; `0x005323f0`,
`0x00532460`, and `0x00532490` are the ensure, publish, and query strip for cached surface root
`[world+0x478]` using saved dimensions `[world+0x159c/+0x15a0]`; `0x005324e0/0x00532500` are the
live-flag setters for `[world+0x159b]`; `0x00532510` is the direct setter for mode byte
`[world+0x159a]`; and `0x00532520/0x00532550` own the four-dword saved dimension quad
`[world+0x15a4..+0x15b0]`. So the broader `0x00532590` reset really does sit at the base of a
concrete local cached-surface and companion-block owner family, not just a pile of unrelated
presentation fields. The reinitializer then
reinitializes the secondary-overlay family for those dimensions, and then republishes the
neighboring overlay constants and support owners used by both the world-side reattach branch and
the `.smp` restore-side presentation rebuild path, including several owners that all funnel
through the shared static-template slot allocator `0x00532ad0` over the local `0x100` pointer
band at `[world+0x08]`. Those neighboring owners are tighter now too: `0x00535070` is the small
primary overlay-surface-or-template setup owner; `0x00535100` is the heavier requested-dimension
apply and four-slot overlay-surface rebuild owner used by the setup-side regenerate branch and
the load-side bundle path; while `0x005356e0` and `0x00535890` seed two
larger static-template slot bands rooted at `[world+0x1568/+0x156c/+0x1574/+0x1578]` and
`[world+0x1560/+0x1564]` respectively; the remaining heavier sibling `0x00535430` now reads as a
shared four-slot overlay-surface rebuild owner that resamples one source or fallback descriptor
into a short local slot strip above `[world+0x155c]`. The immediate helper strip under that same
family is tighter now too: `0x00534f60` is the small presentation-owner base init above
`0x00532590`; `0x00534f80` releases one transient surface handle at `[world+0x478]` and clears
byte `[world+0x159b]`; `0x00532760` releases the current overlay slot chosen by selector
`[world+0x1558]`; `0x005327a0` clamps two requested surface dimensions down to supported
power-of-two sizes while also enforcing shell display caps from `[0x006d4024+0x114243/+0x114247]`;
`0x00532860` is the local twelve-slot stitching pass over the parallel bands rooted at
`[world+0x08/+0x0c/+0x18]`, copying terminal rows and edge dwords between those sibling slot
surfaces before finalizing the primary band through `0x00541c10`;
`0x00532960` is the adjacent paired projection helper that maps two caller counters through the
current `16x16` and `4x4` rounded grid quanta and writes the resulting coarse offsets back to two
out-pointers;
`0x005329e0` maps one `(x,y)` pair into a `1`-based coarse `4x4` overlay region id using the
current rounded grid dimensions; `0x00532a30` is the direct getter for local dword `[world+0x1554]`,
which still reads only as the live count or tag for this overlay slot band;
`0x00532a40` and `0x00532aa0` are the time-selected query helpers over the first and second
template-seeded slot bands rooted at `[world+0x1568/+0x156c]` and `[world+0x1560/+0x1564]`; and
`0x00532a90` is the direct getter for trailing fallback slot `[world+0x1578]`. The next adjacent
owner is tighter now too: `0x00532b30` is the shared release/reset path for the local overlay
slot band at `[world+0x08]`, with a split release policy keyed by shell flag
`[0x006d4024+0x11422e]` and a special forced-direct range for slot ids `1..0x10`, after which it
clears band fields `[world+0x1554/+0x1568/+0x1570/+0x155c/+0x1560/+0x1564]`. The tail of that
same reinitializer is tighter one level up too: `0x00527ce0` is the broader ensure owner that
watches current grid extents plus world tag `[world+0x2121]`, re-enters `0x00532860` when those
cached values change, rebuilds or releases local helper `[this+0x65]`, and then clears the two
large global scratch planes rooted at `0x008f2520` and `0x00b33530`. The tail of that same
reinitializer is
tighter now too: after the larger support-family setup it seeds one seven-entry default overlay
companion set through `0x005373b0`, whose inner allocator `0x00535950` populates the local
`0x1b`-entry slot table from the static template rows `0x005dd300..0x005dd378`. The lifecycle
side is tighter in the same way now: `0x00536044` is the shared teardown owner that frees those same
three five-entry support families together with both mask planes, the packed secondary raster,
the vector-byte planes, the local staging buffer, and the neighboring sidecar or coarse-cell
tables. The remaining base-float lane is tighter too: the larger rebuild owner
`0x00538360` now clearly writes one base float-summary field into `[world+0x1605]`, clears both
one-byte mask planes, and then only repopulates the primary mask plane `[world+0x1655]` for the
qualifying class-`1` interior cells before re-entering `0x00532d90` to normalize that base
float-summary plane globally and `0x00532f60` to expand positive cells through one caller radius.
That asymmetry is now enough to close the local semantic edge: `[world+0x1655]` is the actively
rebuilt primary overlay mask, while `[world+0x1659]` is only the separately seeded and persisted
secondary mask sibling with no comparably grounded distinct read-side consumer. The only grounded
getter call to its root accessor `0x00533b60` is the shell staging branch at `0x00525bad`, and
that branch immediately discards the returned pointer. The bundle side is now explicit too:
`.smp` save-load treats the two mask planes as separate payloads with chunk ids `0x2cee` for
`[world+0x1655]` and `0x2d51` for `[world+0x1659]`, while the neighboring `0x2d49/0x2d50`
branches are the separate packed secondary-raster import lanes rather than alternate consumers
of the second mask plane. So, in the mapped local code, `0x1659` is best treated as a persisted
compatibility or seed-state sibling, not as a second actively consumed runtime overlay mask. The
transport/pricing preview side is tighter now too: `0x00538060` sits directly beneath
`0x0044faf0`, first seeds one preview handle through `0x00535430` using the short `C_`
descriptor, temporarily overrides shell globals
`[0x006d4024+0x11423b/+0x11423f/+0x114254/+0x114255]`, and then loads `%1.tga` through
`0x0053c1c0 -> 0x00541970`. It clamps that sampled image into the `0x401 x 0x401` range,
rewrites `[world+0x1605]` plus the mask/raster family `[world+0x1655/+0x1659/+0x165d]` from the
sampled pixels, optionally re-enters `0x00532d90/0x00532f60`, republishes the seeded preview
handle through `0x0053c000`, and then re-enters `0x005375c0(1, 0, 0)`. The small shell-global
owner it also touches is tighter now too: `0x006d401c` is constructed by `0x00538640`,
`0x005386e0` publishes the primary timed text lane, `0x005387a0` publishes the secondary fixed
`10000` ms lane, `0x00538810` finds the first registered shell window containing one child
control id by walking each window through `0x0053f830`, and `0x00538840/0x00538880/0x00538890`
manage the owner's local `1000`-slot active-token table keyed by child control id. The adjacent
list strip is tighter too: `0x00538990` is the registered-window virtual-slot-`0` gate that
stops on the first zero return, `0x005389c0` is the shared unlink helper for the same doubly
linked list rooted at `[owner+0x00/+0x04]`, `0x00538a60` is the zero-counter gate over
`[owner+0xc60]`, `0x00538a70` is the matching full reset-and-release body used during bootstrap
teardown, and `0x00538a10/0x00538a20/0x00538a30/0x00538a40` are the direct getter, setter,
increment, and clamped decrement helpers for the owner's scalar lanes `[+0xc5c]` and `[+0xc60]`.
The next shell-runtime strip is tighter now too: `0x005388d0` is the shared `12`-dword
descriptor dispatcher with the optional override validator at `[owner+0xc75]` and the recursive
`kind 6 -> 0xb7` rewrite; `0x00538c70` is the prioritized cached-text owner over
`[owner+0xbd8/+0xbdc/+0xbe0/+0xbe4]` that emits descriptor kind `0xae` through `0x005388d0`;
`shell_dispatch_synthetic_12_dword_descriptor_from_five_scalars` `0x00538e00` is the five-scalar
descriptor-synthesis wrapper above that same dispatcher;
`0x00538e50` is the sorted registered-window insert owner over node key `[node+0x21]`;
`0x00538ec0` is the refresh sweep over the indexed helper collection rooted at `[owner+0xc69]`;
and `0x00538f10` is the broader optional-window publish plus blocking descriptor loop used by
modal launchers and some shell transition paths.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,148 @@
# Input, Save/Load, and Simulation: Station-detail Overlay
### Station-detail overlay
The shell-side candidate preview pair now has a grounded world consumer
too. `world_render_station_candidate_service_map_overlay` at `0x0043f640` reads the active
`(station id, candidate id)` pair from
`world_store_station_detail_candidate_service_preview_pair_globals` `0x0043f620` and
`world_clear_station_detail_candidate_service_preview_pair_globals` `0x0043f610`, scans the
placed-structure collection, and then splits the legend by candidate mode. When the active candidate carries a
nonzero route-style byte at `[candidate+0x46]`, the overlay uses the heavier helper
`placed_structure_query_candidate_directional_route_overlay_summary` at `0x0047e690` in both
directions between the preview station and each scanned site and formats the resulting directional
rows as `3874` `Coming To %1` and `3875` `Going From %1`. When that byte is zero, the same overlay
falls back to the direct local-service path through
`placed_structure_query_candidate_local_service_metrics` and formats the two legend rows instead
as `3876` `Current Supply @ < %1` and `3877` `Current Demand @ > %1`. Empty directional lanes
collapse to `3878` `--None--`, and one title lane falls back to literal `All`. Current disassembly
no longer supports treating `3872` `Already Connected by Another Company` or `3873` `Not
Connected` as direct overlay-body emits.
#### Corrected boundary
The neighboring connection-state note pair now appears
to live in a city connection-bonus label formatter, not in `0x0043f640`. That formatter is now
bounded as `city_site_format_connection_bonus_status_label` at `0x004207d0`: it directly chooses
localized ids `3868` through `3873` after consulting the reusable city-peer scan
`city_connection_bonus_exists_matching_peer_site` at `0x00420030`. Separately, `3879` `Out of
Sync` is grounded under the multiplayer preview dataset path instead:
`multiplayer_preview_dataset_service_launch_state_and_warn_out_of_sync` at `0x0046b780` checks
global `0x006cd91c`, raises the `Out of Sync` shell status through `0x5386e0`, and then continues
through the wider multiplayer preview launch-state service. So the station-detail overlay
currently owns only the `Coming To`, `Going From`, `Current Supply`, `Current Demand`, `--None--`,
and `All` legend lanes.
#### Ownership side
One reusable site helper is grounded now too.
`placed_structure_query_linked_company_id` at `0x0047efe0` resolves the current placed structure's
linked instance through `0x0062b26c` and returns its company id from `[instance+0x276]`; the
adjacent city bonus formatter at `0x004207d0` compares that id against the active company selector
before choosing whether a scanned site should carry `3871` `Connected By Another Company` or
`3872` `Already Connected by Another Company`. The larger caller boundary is no longer open
either: the first bounded announcement owner above this formatter family is now
`company_evaluate_and_publish_city_connection_bonus_news` at `0x00406050`, which re-enters the
peer-route candidate builder at `0x004046a0` and later publishes one of the localized
city-connection bonus news strings `2888`, `2890`, or `2921` through the shell news path.
#### Peer-selector side
The city bonus formatter no longer depends only on
boolean peer existence. The companion helper
`city_connection_bonus_select_first_matching_peer_site` at `0x00420280` is now grounded as the
first-match selector paired with `city_connection_bonus_exists_matching_peer_site`: it walks the
same city-peer candidate set, applies the same site-class table plus the narrower
station-or-transit and linked-instance class-byte flags, and returns one representative matching
peer site id instead of a boolean. `city_site_format_connection_bonus_status_label` reuses that
selector after the note checks so it can recover one linked company context from the selected
peer. The remaining open edge here is therefore above this formatter family, not inside the
peer-scan pair itself.
#### Caller side
The reusable bridge between the status formatter and the
company news lane is now bounded too. `city_connection_bonus_build_peer_route_candidate` at
`0x004046a0` reuses `city_connection_bonus_select_first_matching_peer_site` with both selector
flags forced on, samples the selected peer's derived coordinates through `0x0047df30` and
`0x0047df50`, and then either tries the shared heavy builder
`city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0` or falls
back to the smaller wrapper `city_connection_bonus_try_compact_route_builder_from_region_entry`
`0x00404640` before handing the result back to the company-side announcement sweep at
`0x00406050`. The score side of that announcement lane is tighter now as well:
`city_compute_connection_bonus_candidate_weight` at `0x004010f0` provides the per-city opportunity
weight, `company_query_min_linked_site_distance_to_xy` at `0x00405920` provides the nearest
linked-site distance term, `company_count_linked_transit_sites` at `0x00426590` provides one of
the company-side caps, `company_compute_connection_bonus_value_ladder` at `0x00425320` supplies
the bounded company-side value scalar, and
`company_compute_prime_rate_from_issue39_scenario_baseline` at `0x00424580` now bounds the
shared prime-rate-side helper that this lane reuses beside the raw issue-`0x39` total,
`scenario_state_sum_issue_opinion_terms_raw` at `0x00436710` now bounds the raw additive
issue-total helper beneath that term, and `company_connection_bonus_lane_is_unlocked` at
`0x00427590` is the small boolean gate above the ladder. Wider governance and CompanyDetail xrefs
now tighten slot `0x2b` into the rolling net-profits lane reused by annual finance checks and a
per-share/history formatter, while the report-history descriptor table now aligns raw slot `0x09`
with the Income Statement fuel-cost lane surfaced by tooltip `1309`. The wider result now reads
more like recent net profits minus recent fuel burden than a governance-pressure term. That now
also sharpens the annual finance lane at `0x00401c50`: the first bankruptcy branch reads as
sustained cash-and-debt stress over recent profits and fuel burden, the later fallback branch as
a deeper `-300000` cash / three bad years cleanup trigger, and the later stock-issue branch reads
as a price-to-book-versus-coupon approval ladder rather than a generic support vote. The tail is
cleaner now too: it compares total retired versus newly issued principal to choose the `2882..2886`
debt headline family, then publishes `2887` separately from the accumulated repurchased-share
count. The sibling news owner above the same
city-pair route family is bounded now too:
`simulation_try_select_and_publish_company_start_or_city_connection_news` `0x00404ce0`
filters and scores candidate city entries, re-enters the same shared heavy builder through
`city_connection_try_build_route_between_region_entry_pair` `0x00404c60` for the dense pair
sweep and the final retry, and then publishes `2889` `%1 has started a new company - the %2`
or `2890` `%1 has connected %2 to %3.` through the shell news path. The remaining open edge on
this branch is therefore narrower now: it is mostly whether `0x39` should be read as the
narrower city-connection public-opinion lane or as part of a broader management-attitude family,
not the ownership of the connection-bonus formatter, peer-route candidate path, or company news
gate.
#### Route-list side
The neighboring helper
`placed_structure_append_unique_route_entry` at `0x0047f010` is now grounded as the
append-if-missing builder for the six-byte route-entry list rooted at `[site+0x462]` and
`[site+0x466]`. That matters here because the directional overlay query at `0x0047e690` consumes
the same list, so the remaining uncertainty is no longer list ownership. It is down to the exact
semantics of each entry's `u32` payload.
#### Route-entry and Cache Side
The adjacent helper strip is tighter now too.
`placed_structure_service_candidate_local_service_comparison_cache_decay_and_row_propagation`
`0x0047df70` is the recurring age-and-propagation service pass over the paired comparison-cache
float tables `[site+0x3e]` and `[site+0x112]` with age stamps at `[site+0x1e6]`; it zeroes stale
entries older than `0x1d8800`, decays younger ones by the fixed `0x005ce900/0x005ce8f8` scales,
and then propagates stronger marked row values back through the three five-float row bands rooted
at `[site+0x24/+0x28/+0x2c]`. The wrapper
`placed_structure_query_candidate_route_or_local_service_comparison_score` `0x0047e9a0` is now
bounded too: it delegates to `placed_structure_query_candidate_directional_route_overlay_summary`
`0x0047e690` when the requested candidate carries a grouped routing class, otherwise it uses the
simpler local `[cell+0x103]` lane and the current sample list at `[site+0x34/+0x38]` before
writing back into the same comparison-cache bands. The route-entry strip beneath the linked-peer
family is no longer open either: `placed_structure_resolve_route_entry_anchor_record`
`0x0047f310` is the direct resolver over `[site+0x08]`, and
`placed_structure_route_anchor_matches_or_reaches_route_entry_id` `0x0047f250` is the boolean
gate above it, first checking a direct match against `[site+0x08]` and then re-entering
`0x0048e050(mode 2, fallback -1)` on the resolved route-entry record. The route-link companion
`route_link_route_entry_reaches_peer_site_route_group` `0x0047f2d0` is tighter now too: it reads
the peer site's route-entry anchor from `[peer+0x08]`, resolves the current link's own anchor,
and re-enters `0x0048e3c0` to test whether the two anchors belong to the same reachable
route-side family. One smaller linked-peer-side setter is grounded as well:
`placed_structure_set_overlay_mark_byte_and_refresh_linked_peer_overlay_if_changed` `0x0047f290`
updates byte `[site+0x5bc]` and then re-enters
`placed_structure_refresh_linked_peer_overlay_when_linked_peer_flagged` `0x0040d2d0` when the
byte changes.
#### Terrain-class Side
The nearby linked-instance raster wrappers are no
longer anonymous. `world_resolve_secondary_raster_class_record_at_float_xy` `0x0044e270` is the
world-side float-XY lookup over `[world+0x2131]` plus class table `0x006cfc9c`;
`placed_structure_query_linked_instance_secondary_raster_class_id` `0x0047f170` is the raw
linked-instance wrapper that returns the shifted class id directly; and the paired
record-returning wrappers `placed_structure_resolve_linked_instance_secondary_raster_class_record`
`0x0047f0e0` and
`placed_structure_resolve_linked_instance_secondary_raster_class_record_via_world_query`
`0x0047f1f0` now bound the two record-returning lanes used by the later world-side and
linked-peer filters. That means the remaining uncertainty in this neighborhood is no longer the
route-entry or terrain-class helper ownership; it is the broader user-facing meaning of the later
callers that consume those gates.