diff --git a/artifacts/exports/rt3-1.06/function-map.csv b/artifacts/exports/rt3-1.06/function-map.csv index a21d187..caafa37 100644 --- a/artifacts/exports/rt3-1.06/function-map.csv +++ b/artifacts/exports/rt3-1.06/function-map.csv @@ -1,6 +1,27 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,confidence,notes,verified_against -0x0040a590,892,simulation_service_periodic_boundary_work,simulation,cdecl,inferred,objdump + analysis-context,3,Periodic simulation-maintenance dispatcher inside the world-step family. It switches on the local calendar or phase byte at [this+0x0f] routes one heavy mode through the larger recurring service branch at 0x0040a160 falls back to the simpler one-step advance at 0x00409e80 for other modes and runs several global manager sweeps across 0x0062be10 0x006ceb9c 0x006cfcbc 0x006cec20 and 0x0062bae0 before handing control back to the enclosing stepper. One conditional branch also re-enters shell_map_file_world_bundle_coordinator at 0x00445de0 which keeps the save-or-package family connected to the live simulation cadence.,objdump + analysis-context + caller xrefs +0x004010f0,521,city_compute_connection_bonus_candidate_weight,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Computes one city-side weight for the connection-bonus news and placement lanes. The helper rejects early when the city subtype field `[this+0x23e]` is nonzero, then builds a base float from the city-side scalar fields `[this+0x306]`, `[this+0x30a]`, and `[this+0x30e]`. When the optional stack company id is nonzero it also resolves the city's derived coordinates through `0x00455800` and `0x00455810`, probes the live world root at `0x0062c120` through `0x0044e270`, and rejects the city unless the selected company passes the follow-on world-side ownership or access check through `0x00424010`. The helper then scans the live placed-structure collection at `0x006cec20`, filters peers through `0x0041f6e0` plus the linked-instance class test `0x0047de00 -> 0x0040c990 == 1`, counts qualifying linked sites in the city, and detects whether one rival company already has an eligible linked site there. The final weight is scaled down by the inverse of `(qualifying_site_count + 1)` and then further damped when rival ownership is present, so the current grounded meaning is a city connection-bonus opportunity weight rather than a simple population or size score. Current grounded callers are the company-side news sweep at `0x00406050` and one neighboring setup-side branch at `0x00404d90`.","objdump + caller xrefs + callsite inspection + city-bonus correlation" +0x00402c90,19,placed_structure_resolve_linked_candidate_record,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,2,"Tiny placed-structure-to-candidate resolver over the global candidate collection at `0x0062b268`. The helper reads one candidate id from `[this+0x173]`, re-enters the shared indexed-collection record resolver at `0x00518140`, and returns the resulting candidate record pointer. Current grounded caller is the BuildingDetail-side branch at `0x00506441`, where it is used immediately after resolving one placed-structure record from `0x0062b2fc`. This now looks like the direct placed-structure linked-candidate accessor rather than another anonymous local helper.","objdump + caller xrefs + callsite inspection + collection-resolver correlation" +0x00402cb0,3457,city_connection_try_build_route_with_optional_direct_site_placement,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Shared heavy route-builder and optional direct-placement helper beneath the city-connection route and news family. The function starts at a clean prologue at `0x00402cb0`, seeds one builder-state latch band at `[this+0xf5]`, `[this+0xf6]`, `[this+0xf8]`, `[this+0xfa]`, `[this+0xfc]`, and `[this+0x10a]`, and then splits into three grounded internal lanes. The first is an early explicit route-store attempt through `0x004a01a0` over the global route-entry store `0x006cfca8`, which can update the builder slot table without placing a new site. The second is a single-endpoint direct-placement lane around `0x00403d92..0x00403ef3`: it scans the live placed-structure collection `0x0062b2fc` for `Maintenance` and `ServiceTower` stems, projects one candidate placement through `0x00417840`, validates it through `0x004197e0`, and then commits through the first direct placement branch `0x00403ed5 -> placed_structure_collection_allocate_and_construct_entry` `0x004134d0` -> `placed_structure_finalize_creation_or_rebuild_local_runtime_state` `0x0040ef10`. The third is a later paired-endpoint fallback lane around `0x00403f41..0x00404489`: it seeds two endpoint candidates from the same `Maintenance` and `ServiceTower` stem scan, builds one temporary route-entry candidate list, iterates that list against span and year-scaled step terms, projects trial placements through `0x00417840`, and on success commits through the second direct placement branch `0x0040446b -> 0x004134d0 -> 0x0040ef10` before clearing a small exclusion window in the temporary list. Outside those lanes it also re-enters geometry, region, and route-store helpers around `0x004423a0`, `0x00482e00`, `0x004931e0`, `0x00494310`, and the global route-entry stores `0x006cfcb4` / `0x006cfca8`, and it can still unwind through route-state cleanup without committing new placed structures. Current grounded callers are the compact region-entry wrapper `city_connection_bonus_try_compact_route_builder_from_region_entry` `0x00404640`, the peer-route candidate builder `city_connection_bonus_build_peer_route_candidate` `0x004046a0`, the direct region-entry pair wrapper `city_connection_try_build_route_between_region_entry_pair` `0x00404c60`, and the direct retry paths inside `simulation_try_select_and_publish_company_start_or_city_connection_news` `0x00404ce0`. This now bounds the old unresolved `0x00403xxx..0x00404631` placement chooser as one shared city-connection route or placement helper with a cleaner internal policy split, even though some lower helper semantics remain open.","objdump + caller xrefs + callsite inspection + placement-correlation + route-builder correlation + Maintenance/ServiceTower scan correlation" +0x004046a0,1388,city_connection_bonus_build_peer_route_candidate,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Reusable candidate builder beneath the city-connection bonus news and status family. The helper starts from one region or city entry in the collection at `0x0062bae0`, samples that entry's two derived coordinate terms through `0x00455800` and `0x00455810`, then re-enters `city_connection_bonus_select_first_matching_peer_site` at `0x00420280` with both selector flags forced on so it can recover one representative connected peer site. When a peer is found it samples the peer's derived coordinates through `0x0047df30` and `0x0047df50`; when an explicit caller-owned route anchor is present it first tries the heavier route builder at `0x00402cb0`, otherwise it falls back to the smaller helper at `0x00404640`. If neither early path succeeds the function collects one local candidate band from the two global route-entry stores at `0x006cfcb4` and `0x006cfca8`, filters those entries against the current city id and several route-state predicates, computes one compact bounding window around each surviving candidate, and then chooses the best remaining candidate by smallest span before retrying `0x00402cb0`. Current grounded callers are the wider company-side city-connection bonus sweep at `0x00406050` and one neighboring branch at `0x00406b73`, which together make this look like the shared peer-route candidate builder above the city bonus peer-selector family rather than a direct UI formatter.","objdump + caller xrefs + callsite inspection + peer-selector correlation + route-builder correlation" +0x00404640,82,city_connection_bonus_try_compact_route_builder_from_region_entry,map,thiscall,inferred,objdump + caller inspection + route-builder correlation,3,"Small route-builder helper beneath `city_connection_bonus_build_peer_route_candidate` `0x004046a0`. The helper resolves one caller-supplied region or city entry id through collection `0x0062bae0`, derives that entry's compact coordinate pair through `0x00401000`, reads one explicit route-anchor or peer-site id from `[this+0x00]`, and then re-enters the heavier route builder at `0x00402cb0` with that resolved coordinate pair plus default wildcard arguments `-1/0/-1` in the remaining route slots. Current grounded caller is the city-connection bonus candidate builder at `0x004047bf`, where this helper is used as the smaller fallback path when the earlier explicit-anchor route attempt does not apply. This now looks like the compact region-entry wrapper around the shared route builder rather than a generic coordinate helper.","objdump + caller inspection + route-builder correlation + city-bonus fallback correlation" +0x00404c60,124,city_connection_try_build_route_between_region_entry_pair,map,fastcall,inferred,objdump + caller inspection + route-builder correlation,3,"Compact fastcall route-builder above the shared route store at `0x006cfca8`. The helper resolves the two caller-supplied region or city entry ids through collection `0x0062bae0`, derives both endpoint coordinate pairs through `0x00401000`, and then re-enters the heavier route builder at `0x00402cb0` with those two endpoints plus the caller's remaining stack-side policy tuple. Current grounded callers are the pair-selection sweeps inside `simulation_try_select_and_publish_company_start_or_city_connection_news` `0x00404ce0`, where it is used both for the early dense score matrix and the later selected-pair retry. This now looks like the direct region-entry pair wrapper around the shared route builder rather than another anonymous internal callsite.","objdump + caller inspection + route-builder correlation + pair-selection correlation" +0x00404ce0,3124,simulation_try_select_and_publish_company_start_or_city_connection_news,simulation,fastcall,inferred,objdump + caller inspection + RT3.lng strings,3,"Broad fastcall city-pair chooser and news publisher above `city_connection_try_build_route_between_region_entry_pair` `0x00404c60`. When the stack company-id argument is zero the helper sweeps up to `0xa0` region-or-city entries from `0x0062bae0`; when it is nonzero it first validates that company through collection `0x0062be10`, stat family `0x2329` mode `0x0d` via `0x0042a5d0`, and the territory-access gate `0x00424010`. Eligible city entries are filtered through `city_connection_bonus_exists_matching_peer_site` `0x00420030`, weighted through `city_compute_connection_bonus_candidate_weight` `0x004010f0`, damped by map-size terms, territory access, and current region flags, and stored into temporary score bands. The helper then builds one dense pair matrix, repeatedly re-enters `0x00404c60` to validate candidate city pairs, can update one company-side selected endpoint pair through `0x00426f20`, and finally publishes shell news through `0x004554e0`. Current grounded publication ids are `2889` `%1 has started a new company - the %2` and `2890` `%1 has connected %2 to %3.`. Current grounded callers are `0x00401455`, which temporarily clears region-state dwords `[0x006cfc9c+0x2d]` before a global pass, and `0x00401b36`, which re-enters the same chooser with the active company and linked chairman after the smaller company-side city-connection bonus lane falls through. This now looks like the broader company-start-or-city-connection headline chooser above the smaller city-connection bonus sweep at `0x00406050` rather than another anonymous route-builder.","objdump + caller inspection + RT3.lng strings + route-builder correlation + pair-selection correlation + publication-path correlation" +0x00405920,189,company_query_min_linked_site_distance_to_xy,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Queries the minimum distance from one company to an input X or Y point pair. The helper walks the live placed-structure collection at `0x006cec20`, keeps only sites whose linked company id from `placed_structure_query_linked_company_id` at `0x0047efe0` matches `[this+0x00]`, samples each surviving site's derived coordinates through `0x0047ded0` and `0x0047df00`, and then computes one scalar distance against the caller-supplied coordinate pair through `0x0051dbe0`. It returns the minimum observed distance across all linked sites, clamped to a floor of `1.0` when a closer or degenerate result would go lower. The current grounded caller is `company_evaluate_and_publish_city_connection_bonus_news` at `0x00406050`, where this helper provides the distance term later blended into each city candidate score.","objdump + caller xrefs + callsite inspection + distance-term correlation" +0x00406050,2966,company_evaluate_and_publish_city_connection_bonus_news,simulation,thiscall,inferred,objdump + caller inspection + RT3.lng strings,4,"Broader company-side city-connection bonus sweep above `city_connection_bonus_build_peer_route_candidate` at `0x004046a0`. The function starts by building one announcement-value floor from several company-side support or governance helpers: the generic metric readers at `0x0042a5d0` and `0x00426ef0`, the linked transit-site counter `company_count_linked_transit_sites` at `0x00426590`, the small bonus-lane gate at `0x00427590`, and the longer company value ladder at `0x00425320`. Once that floor is high enough it walks the region-or-city collection at `0x0062bae0` and computes one per-city opportunity score from three terms: the city-side opportunity weight from `city_compute_connection_bonus_candidate_weight` at `0x004010f0`, the minimum linked-site distance from `company_query_min_linked_site_distance_to_xy` at `0x00405920`, and one city-side coordinate or spacing term around `0x00455800` and `0x00455810`. Those city scores are then adjusted by rival-company presence, chairman-profile scaling, the map-editor building-density setting at `0x006cec78+0x4c78`, and a linked-transit-site-count cap before the function keeps up to ten city ids in the persistent band at `[this+0x0d42]`. It repeatedly re-enters `city_connection_bonus_build_peer_route_candidate` to validate the best remaining entry, and when one validated winner survives it formats company and city names into the localized news strings `2888` `%1 has connected to %2.`, `2890` `%1 has connected %2 to %3.`, or `2921` `%1 has put a station in %2, but to win the %3 connection bonus, this station must be connected to ANOTHER city.` before publishing the result through the shell news helper at `0x004554e0`. When no winner survives it sets the byte latch at `[this+0x0d18]` instead. This is now the first grounded announcement owner above the city-connection bonus status formatter and peer-selector pair rather than just an anonymous caller around `0x004064c0`.","objdump + caller inspection + RT3.lng strings + peer-route candidate correlation + publication-path correlation + score-component correlation" +0x00426590,135,company_count_linked_transit_sites,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Counts the live linked placed structures for this company that also pass the station-or-transit gate. The helper walks the placed-structure collection at `0x006cec20`, keeps only peers whose linked company id from `placed_structure_query_linked_company_id` at `0x0047efe0` matches `[this+0x00]`, requires the linked-instance class byte through `0x0047de00 -> 0x0040c990 == 1`, and optionally enforces the narrower station-or-transit predicate through `0x0047fd50` when the caller passes a nonzero stack flag. The current grounded caller is `company_evaluate_and_publish_city_connection_bonus_news` at `0x00406050`, where the helper contributes the current linked transit-site count used in the bonus-value ladder and later building-density caps.","objdump + caller xrefs + callsite inspection + connection-bonus count correlation" +0x00427590,47,company_connection_bonus_lane_is_unlocked,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Small boolean gate above `company_compute_connection_bonus_value_ladder` at `0x00425320`. The helper rejects immediately when the scenario-state flag at `0x006cec78+0x4a8b` is set or when the company age-like counter at `[this+0x5b]` has reached `0x14`; otherwise it computes the zero-argument connection-bonus value ladder through `0x00425320` and returns true only when the resulting integer value is at least `5`. Current grounded callers are `company_evaluate_and_publish_city_connection_bonus_news` at `0x00406050` and the later mid-function gate around `0x004064a9`, so current best meaning is one unlock or eligibility gate for the stronger city-connection bonus lane rather than a generic support predicate.","objdump + caller xrefs + callsite inspection + connection-bonus correlation" +0x0040a590,892,simulation_service_periodic_boundary_work,simulation,cdecl,inferred,objdump + analysis-context,3,"Periodic simulation-maintenance dispatcher inside the world-step family. It switches on the local calendar or phase byte at [this+0x0f] routes one heavy mode through the larger recurring service branch at 0x0040a160 falls back to the simpler one-step advance at 0x00409e80 for other modes and runs several global manager sweeps across 0x0062be10 0x006ceb9c 0x006cfcbc 0x006cec20 and 0x0062bae0 before handing control back to the enclosing stepper. The route-style lane is tighter here now too: one recurring branch at `0x0040a91f` re-enters `placed_structure_collection_refresh_quarter_subset_route_style_state` `0x00413580`, which refreshes every fourth live placed structure for route-style candidate scoring and peer-link emission. One conditional branch also re-enters shell_map_file_world_bundle_coordinator at 0x00445de0 which keeps the save-or-package family connected to the live simulation cadence.",objdump + analysis-context + caller xrefs 0x0040ab50,339,simulation_advance_to_target_calendar_point,simulation,cdecl,inferred,objdump + analysis-context,3,Advances the active world state toward one caller-selected packed calendar target while guarded by the recursion counter at 0x0062b240. The helper compares the current local tuple fields [this+0x0d] [this+0x0f] [this+0x11] and [this+0x14] against a target resolved through 0x0051d550 and 0x0051d5f0 then either recurses in larger 0x168-sized chunks or advances through the smaller periodic step family rooted at 0x00409e80 and 0x0040a9c0. Each successful step notifies the live world root at 0x0062c120 through 0x00450030. Grounded callers include the frame-time accumulator at 0x00439140 the larger fast-forward helper at 0x00437b20 and one shell UI command path.,objdump + analysis-context + caller xrefs +0x0040ef10,1984,placed_structure_finalize_creation_or_rebuild_local_runtime_state,map,thiscall,inferred,objdump + caller inspection + placement and mutation correlation,3,"Broad placed-structure post-create or post-edit rebuild above the narrower route-style lane. The helper validates several linked-site and world-state preconditions before keeping the current site live, increments the global live-site count at `0x0062be40`, seeds runtime mode and year fields at `[this+0x390]`, `[this+0x3d4]`, and `[this+0x3d5]`, refreshes the adjacent site-status or overlay family through `0x0040d2d0`, and rebuilds one larger local owner or service bundle through `0x00418be0`, `0x0040eba0`, and the scalar-staging family `0x00475ed0` / `0x00474fe0` / `0x00475010` / `0x00475030` into fields such as `[this+0x24e]`, `[this+0x252]`, `[this+0x25a]`, and `[this+0x25e]`. Later in the same body it re-enters `0x0040db30`, and when the local latch at `[this+0x29e]` is still zero it also re-enters `placed_structure_rebuild_route_style_candidate_scores_and_peer_links` `0x004101e0` with stack flag `1`. Current grounded callers include the placement-side builders at `0x00403ef3` and `0x00404489`, later site-mutation paths at `0x0046f073` and `0x004707ff`, and one train-side site operation at `0x005098eb`, so this now looks like the broad post-create or post-edit runtime rebuild above route-style scoring and peer-link emission rather than a route-style-only helper.","objdump + caller inspection + placement and mutation correlation + route-style rebuild correlation" +0x0040f6d0,891,placed_structure_construct_entry_from_candidate_and_world_args,map,thiscall,inferred,objdump + constructor inspection + caller correlation,3,"Lower constructor beneath the shared placed-structure allocator at `0x004134d0`. The helper writes the new placed-structure id into `[this+0x2a4]`, clears a large band of local runtime fields, copies the candidate stem or label payload from the caller-supplied construction scratch record, initializes local world geometry through `0x0040cd70`, `0x0045b9b0`, `0x00455750`, and `0x00455720`, quantizes the input coordinates into the cached grid terms at `[this+0x388]` and `[this+0x38c]`, seeds the current scenario year into `[this+0x3d5]`, and initializes the class-weight lanes near `[this+0x28a]` from the linked candidate vtable owner. It then zeroes the local route-style and service-score bands, conditionally builds the first local owner or service record through `0x00418be0` and `0x0040eba0`, resolves the initial linked site id at `[this+0x2a8]` through `0x00481390` when the backing candidate subtype byte `[candidate+0x32]` is `1`, seeds region linkage through `0x0044a800` and `0x0041f7e0`, optionally re-enters `0x0040db30` for subtype `4`, and finally seeds the trailing random-like dwords at `[this+0x3d9]` and `[this+0x3dd]` from `0x518d70`. Current grounded caller is `placed_structure_collection_allocate_and_construct_entry` `0x004134d0`, so this is now the concrete placed-structure constructor rather than an anonymous lower helper beneath the placement-side builders.","objdump + constructor inspection + caller correlation + placed-structure runtime-state correlation" +0x0040fbe0,224,placed_structure_endpoint_pair_has_shared_route_entry_key,map,thiscall,inferred,objdump + caller inspection + world-grid chain comparison,3,"Boolean peer-test between one placed structure and one caller-supplied peer site id. The helper converts the current site and the peer site into their derived world-grid owner records through `0x00455800`, `0x00455810`, the world-grid tables rooted at `[0x0062c120+0x2129]`, and the placed-structure resolver `0x0040fa50`. It then compares the two route-entry chains rooted at `[cell+0x0ef]`, using the chain lengths at `[cell+0x0eb]`, and returns `1` on the first shared leading `u16` route-entry key; otherwise it returns `0`. Current grounded callers are the route-link emitter at `0x0040fef0`, where it blocks duplicate endpoint pairing before `placed_structure_route_link_allocate_site_pair_for_candidate_class` `0x00467f50`, and the neighboring cleanup sweep at `0x0040d2aa`, where it decides whether an existing site-owned route-link should be erased. This now looks like the shared duplicate-or-overlap test for the route-link family rather than a generic proximity check.","objdump + caller inspection + world-grid chain comparison + route-link duplicate-check correlation" +0x0040fef0,752,placed_structure_try_emit_best_route_style_peer_link_for_candidate_class,map,thiscall,inferred,objdump + caller inspection + placed-structure sweep inspection,3,"Scans the live placed-structure collection for one best peer site and emits a missing route-link for one caller-selected candidate class when a qualifying endpoint pair survives. The helper first derives one distance cap from the current placed-structure population size at `0x0062b26c`, scales that cap by the caller-supplied float, and then walks the live placed-structure ids in a wrapped pseudo-random order. Candidate peers must have a positive class-specific weight in the placed-structure lane `[peer+class*4+0x27e]`, differ from the source site, pass the linked-instance class gate `0x0040c990 == 1`, and lie inside the chosen distance window after the coordinate and span checks built from `0x00455800`, `0x00455810`, `0x00455f60`, and nearby math helpers. The strongest surviving peer is kept through a weighted comparison, and if one remains the helper re-enters `placed_structure_endpoint_pair_has_shared_route_entry_key` `0x0040fbe0`; only when that duplicate check fails does it call `placed_structure_route_link_allocate_site_pair_for_candidate_class` `0x00467f50` with the source site id from `[this+0x2a4]`, the chosen peer id, and the same candidate-class argument. Current grounded callers are the larger per-site world pass around `0x00410665` and the route-style grid contribution branch at `0x0042cafe`, so this now looks like the current peer-selection emitter for site-owned route-style links rather than a low-level allocator wrapper.","objdump + caller inspection + placed-structure sweep inspection + route-link emission correlation" +0x004101e0,6843,placed_structure_rebuild_route_style_candidate_scores_and_peer_links,map,thiscall,inferred,objdump + caller inspection + route-style emission correlation,3,"Large per-site rebuild pass above the route-style link emitter. The helper first requires the current placed structure to pass the linked-instance class gate `0x0040c990 == 1` and several scenario-state gates rooted at `0x006cec78` and `0x006cec7c`, then derives one set of per-class route-style score scalars from the current site's local state, scenario opinion multipliers through `0x00436590`, year-dependent dampers, and the placed-structure class-weight lanes near `[this+0x28a]`. For the first three route-style classes it conditionally re-enters `placed_structure_try_emit_best_route_style_peer_link_for_candidate_class` `0x0040fef0` with the caller-supplied mode flag and one computed float score. The function then continues into a larger descriptor-driven scoring phase over the current candidate's runtime descriptor array at `[candidate+0x37]`, building temporary score bands and normalizing them against the same local totals before later write-back. Current grounded callers are the local per-site branch at `0x0040f640`, which reaches it with stack flag `1`, and the broader placed-structure sweep at `0x004135e3`, which reaches it with stack flag `0`; this is therefore the strongest current owner for route-style candidate scoring and peer-link emission on one live placed structure rather than a narrow one-off helper.","objdump + caller inspection + route-style emission correlation + descriptor-loop inspection" +0x004134d0,112,placed_structure_collection_allocate_and_construct_entry,map,thiscall,inferred,objdump + caller xrefs + constructor inspection,3,"Shared direct placement helper above the broader placed-structure runtime rebuild. The helper first obtains one temporary `0x3e1`-sized construction scratch object through `0x53b070` and `0x0040c950`, then allocates one live placed-structure entry from the current collection through `0x518900`, resolves the new record through `0x518140`, and finally re-enters the lower constructor at `0x0040f6d0` with the new entry id plus the caller-supplied coordinate and candidate payload tuple. Current grounded callers include the candidate-placement branches at `0x00403ed5`, `0x0040446b`, and `world_region_try_place_candidate_structure` `0x00422ee0`, plus later mutation or editor-side branches at `0x0046efbf`, `0x0047074b`, `0x00472bef`, `0x00472d03`, and `0x00508fd1`. This now looks like the shared placed-structure allocator and constructor entrypoint beneath the placement-side builders rather than a route-style-specific helper.","objdump + caller xrefs + constructor inspection + placement correlation" +0x00417790,160,map_angle_rotate_grid_offset_pair_into_world_offset_pair,map,cdecl,inferred,objdump + callsite inspection + math-table correlation,2,"Small angle-table rotation helper beneath the placement projection family. The helper normalizes the caller-supplied heading float into the engine's cyclic angle domain, indexes one sine or cosine-like basis table under `0x006d4024`, and then applies that basis pair to the caller-supplied X or Y grid offsets before writing the rotated world-space offset pair through the two out-pointers. Current grounded caller is `placed_structure_project_candidate_grid_extent_offset_by_rotation` `0x00417840`, so this now looks like the low-level offset-rotation helper rather than a generic trig wrapper.","objdump + callsite inspection + math-table correlation" +0x00417840,205,placed_structure_project_candidate_grid_extent_offset_by_rotation,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Projects one candidate-sized local grid extent into rotated world-space X or Y offsets for placement and mutation previews. The helper resolves the caller-supplied placed-structure id through the current collection, pulls one local grid basis pair through `0x00413d80`, reads the linked candidate footprint bytes `[candidate+0xb8]` and `[candidate+0xb9]`, converts those grid extents into local offset terms, and then re-enters `map_angle_rotate_grid_offset_pair_into_world_offset_pair` `0x00417790` with the caller-supplied heading float to produce the rotated output pair. Current grounded callers include the city-connection placement chooser `0x00402cb0`, the placed-structure local rebuild lane at `0x0040de78`, subtype-`1` placement validation inside `0x004197e0`, and later world-side update branches at `0x00417b6f`, `0x00417e27`, `0x0041a250`, `0x0041a615`, `0x004802c6`, `0x00480875`, and `0x00480d50`. This now looks like the shared projected-footprint offset helper beneath placement validation rather than an unnamed geometry routine.","objdump + caller xrefs + callsite inspection + placement-correlation" +0x004197e0,5232,placed_structure_validate_projected_candidate_placement,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Heavy placement validator beneath the city-connection chooser and several direct mutation paths. The helper resolves one anchor placed-structure id from the current collection at `0x0062b2fc`, optionally validates the caller-supplied company through `0x0062be10`, scenario-state and shell-mode gates around `0x004338c0` and `[0x006cec7c+0x82]`, the current world tile through `0x00414bd0` and `0x00534e10`, and territory access through `0x00424010`, and then walks a large footprint-validation pass over the linked candidate record from `0x0062b268`. That deeper pass uses the candidate footprint bytes `[candidate+0xb8]` and `[candidate+0xb9]`, multiple temporary occupancy banks on the stack, route or road-side probes through `0x00448af0`, `0x004499c0`, and `0x00413df0`, and subtype-specific follow-on branches keyed by `[candidate+0x32]` plus optional route-entry and company-side arguments. The helper returns a placement-success boolean, can optionally write failure text through the caller-supplied output buffer using localized ids `0x0b55..0x0b58` or fallback strings `0x00be/0x00bf`, and is currently grounded as the shared go-or-no-go gate immediately before direct placement commits. Current grounded callers include both direct-placement lanes inside `city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0`, the placed-structure local rebuild branch at `0x0040dedb`, later mutation or editor-side branches at `0x00422afa`, `0x0046ef6b`, `0x0047070f`, `0x00472bcc`, `0x00472cd4`, and two shell-side callers at `0x00507f57` and `0x005083cc`.","objdump + caller xrefs + callsite inspection + company-access correlation + footprint-validation correlation" +0x00413580,160,placed_structure_collection_refresh_quarter_subset_route_style_state,map,thiscall,inferred,objdump + caller inspection + collection-iteration inspection,3,"Collection-wide placed-structure sweep that refreshes one quartered subset of the route-style lane on each call. The helper computes a start index from the scenario time byte at `0x006cec78+0x11` modulo `4`, then walks every fourth live placed-structure record in the collection, requiring each record to pass the linked-instance class gate `0x0040c990 == 1` before re-entering `placed_structure_rebuild_route_style_candidate_scores_and_peer_links` `0x004101e0` with stack flag `0`. After each qualifying per-site rebuild it seeds the two trailing dword fields at `[site+0x3d9]` and `[site+0x3dd]` from `0x518d70`. Current grounded caller is the recurring simulation-maintenance branch at `0x0040a91f`, which makes this the strongest current owner for the periodic quarter-subset refresh of route-style peer-link state rather than a one-shot world-build pass.","objdump + caller inspection + collection-iteration inspection + periodic-cadence correlation" 0x00411ee0,451,structure_candidate_rebuild_cargo_membership_and_scaled_rate_tables,map,thiscall,inferred,objdump + callsite inspection,3,"Rebuilds the per-candidate cargo summary tables after one runtime descriptor array has been materialized. The helper clears the two cargo-id pointer tables at `[this+0x79c]` and `[this+0x7a0]`, their counts at `[this+0x7a4]` and `[this+0x7a8]`, and one float-like per-cargo accumulator band rooted at `[this+0x0a1]`, then walks every live `0xbc` descriptor in `[this+0x37]` against the current scenario year at `[0x006cec78+0x0d]`. For each active subordinate cargo row in the descriptor-owned `0x1c`-byte entry band it resolves one cargo id through the global cargo collection at `0x0062ba8c`, updates the per-cargo accumulator, and tracks one or two levels of cargo membership before compacting those marks into the two emitted cargo-id tables. The stronger production-mode result is now bounded here rather than only in the editor importer: when the descriptor-side mode flag at `[desc+0x00]` is zero the subordinate row amount is multiplied by the shared recipe-book production cap at `[this+0x2a]` and divided by the descriptor amount at `[desc+0x04]`; when that mode flag is nonzero the helper bypasses that scaling path. That matches the editor-side split where production mode keeps the entered annual amount on the supply half while the demand half is normalized to `1.0`, so the demand-side production branch now looks like a normalized input selector or gate while the supply side is the branch that receives cap-scaled runtime rates. Current grounded callers are the collection-wide rebuild sweeps at `0x00412bd0` and `0x00412d70`.","objdump + callsite inspection + scenario-state correlation + cargo-collection correlation" 0x00412560,144,structure_candidate_runtime_descriptor_is_active_for_current_year_and_mode,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Descriptor-level activity gate beneath the port or warehouse cargo runtime family. The helper first special-cases descriptor mode `0` by resolving the primary cargo id at `[desc+0x1c]` through the global cargo collection at `0x0062ba8c`; it then requires the current scenario year at `[0x006cec78+0x0d]` to lie inside the descriptor year window `[desc+0x20]..[desc+0x22]`, and finally checks one caller-selected mode byte at `[desc+0x24]` or `[desc+0x25]` for the active mode bank. When the runtime cargo-economy latch at `[0x006cec78+0x4afb]` is clear and the descriptor owns subordinate cargo rows, it also requires every subordinate cargo id in the `0x1c`-byte row band at `[desc+0x44]` to resolve through the same cargo collection. Current grounded callers are `structure_candidate_count_active_scaled_supply_descriptors` at `0x004125f0`, `structure_candidate_query_cargo_runtime_summary_channels` at `0x00412650`, and neighboring world-side query branches around `0x0040fb8d`, `0x00410721`, and `0x00410b71`.","objdump + caller xrefs + callsite inspection + cargo-collection correlation" 0x004125f0,87,structure_candidate_count_active_scaled_supply_descriptors,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Counts active runtime descriptors that participate in the scaled supply-side production lane for one caller-selected mode bank. The helper walks the current descriptor array at `[this+0x37]`, selects only descriptors whose mode dword at `[desc+0x00]` is zero and whose subordinate row count at `[desc+0x2c]` is positive, and then reuses `structure_candidate_runtime_descriptor_is_active_for_current_year_and_mode` at `0x00412560` before incrementing the returned count. Current grounded caller is `structure_candidate_query_cargo_runtime_summary_channels` at `0x00412650`, where the resulting count is used to divide the shared production-cap float across the active scaled-supply descriptors.","objdump + caller xrefs + callsite inspection" @@ -10,6 +31,19 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00412ca0,192,world_region_pick_commercial_profile_label_by_region_rank,map,thiscall,inferred,objdump + strings + callsite inspection,4,"Selects one category-3 candidate label from the global structure pool `0x0062b268` for the current region bucket. The helper converts the caller-supplied region rank through the region-count manager at `0x0062bae0`, uses that derived bucket to read per-candidate weights from `[candidate+region_index*4+0x8d]`, repeatedly subtracts those weights across up to five passes while only considering pool entries whose category byte at `[candidate+0x32]` is `3`, and copies the chosen candidate name into the caller buffer. When no weighted category-3 candidate survives the sweep it falls back to the static token `Commercial` at `0x005c92e8`. A later region-stats panel lines the same third slot up with localized id `1040` `City Support`, so current evidence treats this as the low-level label picker for a broader city-support family whose fallback token happens to be `Commercial`. The current grounded caller is `world_region_balance_structure_demand_and_place_candidates` at `0x004235c0`.","objdump + rdata strings + callsite inspection + region stats disassembly + RT3.lng strings" 0x0041ea50,179,world_setup_building_collection_phase,map,cdecl,inferred,objdump + strings + callsite inspection,3,"Post-load world-generation subphase inside world_run_post_load_generation_pipeline. The helper iterates the building-related collection at `0x0062ba8c`, chooses either the full pass or one modulo-selected bucket from the current world byte at `[0x006cec78+0x0f]`, resolves each entry through `0x00518380` and `0x00518140`, and then dispatches the selected record into the lower setup worker at `0x0041e2b0`. Current grounded callsite is the early collection sweep inside world_run_post_load_generation_pipeline immediately before the localized progress update `Setting up Players and Companies...`, so this looks like the collection-owned building-setup staging phase rather than one of the later player-speed or shell-frame loops.",objdump + caller context + RT3.lng strings 0x0041e220,52,structure_candidate_is_enabled_for_current_year,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Common live-availability gate for one structure-candidate record. The helper first requires the cargo-economy or editor filter flag at `[this+0x56]` to be nonzero, then compares the current scenario year against the candidate threshold at `[this+0x21]`, using either `[0x006cec78+0x05]` or `[+0x0d]` depending on the runtime branch latched at `[0x006cec78+0x46c38]`. Current grounded callers include the collection counter refresh at `0x0041e970`, the placed-structure cargo-bitset sweep at `0x0042c690`, and several later shell or world-side candidate-selection branches, so this now looks like the shared year-and-filter gate beneath the editor's cargo-economy path rather than a setup-only helper.","objdump + caller xrefs + callsite inspection + cargo-economy filter correlation" +0x0041e650,142,structure_candidate_query_route_style_or_local_availability_metric,map,thiscall,inferred,objdump + caller xrefs + callsite inspection + collection-correlation,3,"Returns one candidate-side float metric whose meaning splits on the route-style byte at `[this+0x46]`. When that byte is zero the helper simply returns the cached local float at `[this+0x5a]`. When it is nonzero it resolves one grouped routing-class value from candidate field `[this+0x3e]` through the structure-candidate collection side table at `0x0062ba8c+0x9a`, then walks collection `0x006ada90` through `indexed_collection_slot_count` `0x00517cf0`, `indexed_collection_get_nth_live_entry_id` `0x00518380`, and `indexed_collection_resolve_live_entry_by_id` `0x00518140` to count entries whose class byte at `[entry+0x10]` matches, whose state byte at `[entry+0x12]` carries bit `0x2`, and whose word at `[entry+0x08]` is zero. It returns that matched count divided by the fixed float constant at `0x005c8554`. Current grounded callers include two sortable-value branches inside `shell_load_screen_render_map_cargo_list_panel` at `0x004e9460` and one neighboring shell renderer around `0x004f46d0`, so this now looks like the shared route-style-versus-local availability metric beneath candidate cargo summaries rather than a generic price reader.","objdump + caller xrefs + callsite inspection + collection-correlation + route-style-byte correlation" +0x00467eb0,104,placed_structure_route_link_attach_site_owner,map,thiscall,inferred,objdump + caller xrefs + chain-layout inspection,3,"Attaches one `0x006ada90` route-link record onto the owner chain of one placed structure. The helper first detaches the current record through `0x00467df0`, stages the caller-supplied placed-structure id into route-link field `+0x0a`, links the record into the placed-structure-owned chain at `[site+0x272]` through route-link field `+0x04`, and then re-enters `0x00467c30` to recompute the route-link flag byte at `+0x12` against neighboring site pairs. When that flag byte keeps bit `0x2` set, the helper also projects one class-indexed signed contribution through `0x0040fa50` and accumulates it into the placed structure through `0x0042b310`. Current grounded caller is the route-link allocator path at `0x00468067`, which makes this the clearest current owner bridge from one freshly allocated `0x006ada90` record into the site-linked chain later scanned by `placed_structure_query_candidate_directional_route_overlay_summary` at `0x0047e690` and `structure_candidate_query_route_style_or_local_availability_metric` at `0x0041e650`.","objdump + caller xrefs + chain-layout inspection + route-link-correlation" +0x00467df0,183,placed_structure_route_link_detach_current_owner_chain,map,thiscall,inferred,objdump + caller xrefs + chain-layout inspection,3,"Detaches one `0x006ada90` route-link record from whichever owner chain currently anchors it. The helper first checks route-link field `+0x08`; when nonzero it treats that field as one route-node-like owner id in collection `0x006cfcbc` and unlinks the record through owner field `+0x04` plus route-node link slot `+0x29`. Otherwise it falls back to the placed-structure owner path, using route-link field `+0x0a` as one site id in collection `0x0062b26c`, optionally applying the same class-indexed signed contribution rollback through `0x0040fa50` and `0x0042b310` when flag byte `+0x12` keeps bit `0x2` set, and then unlinking through `[site+0x272]`. Current grounded callers are the site-owner attach path at `0x00467eb0`, the route-node attach path at `0x00467f20`, and the route-link destructor path at `0x004680b0`, so this now looks like the shared detach helper beneath all owner-chain rewrites for the route-link family.","objdump + caller xrefs + chain-layout inspection + owner-slot correlation" +0x00467c30,443,placed_structure_route_link_recompute_endpoint_pair_state,map,thiscall,inferred,objdump + caller xrefs + endpoint-pair inspection,3,"Recomputes the route-link state byte at `+0x12` from the active site-endpoint pair and updates the linked site contribution when that state flips. The helper only runs on the site-owned branch where route-link field `+0x08` is zero; it resolves the two endpoint site ids from fields `+0x0a` and `+0x0e` through collection `0x0062b26c`, clears the prior bit-`0x2` state, then compares the two endpoint-side route-entry chains through `0x00455f60`, `0x0047de00`, `0x0040c990`, and `0x0047f2d0` until it finds a compatible shared peer. On the first match it restores bit `0x2` in the state byte. If the boolean substate derived from bit `0x1` changes across the recomputation, the helper applies one signed class-indexed contribution through candidate class byte `+0x10`, the class-weight table at `0x0062ba8c+0x8e`, and `0x0042b310` against the first endpoint owner. Current grounded callers are the site-owner attach path `0x00467eb0`, the route-link rebuild sweep around `0x004682e6`, and the route-link allocator path at `0x0046809b`, so this now looks like the endpoint-pair state reconciler beneath the route-link family rather than a generic chain walk.","objdump + caller xrefs + endpoint-pair inspection + shared-peer correlation" +0x00467f20,45,placed_structure_route_link_attach_route_node_owner,map,thiscall,inferred,objdump + caller xrefs + chain-layout inspection,3,"Attaches one `0x006ada90` route-link record onto the owner chain of one route-node-like record in collection `0x006cfcbc`. The helper first detaches the current record through `0x00467df0`, then stages the caller-supplied route-node id into route-link field `+0x08` and links the route-link through owner field `+0x04` plus route-node link slot `+0x29`. Current grounded caller is the route-node-side rewrite path at `0x004680e0`, which keeps this as the route-node owner companion to `placed_structure_route_link_attach_site_owner` rather than another site-chain helper.","objdump + caller xrefs + chain-layout inspection + route-node-owner correlation" +0x00467f50,352,placed_structure_route_link_allocate_site_pair_for_candidate_class,map,cdecl,inferred,objdump + caller xrefs + stack-layout inspection + class-counter correlation,3,"Allocates and seeds one new `0x006ada90` route-link record for a caller-supplied placed-structure pair and candidate class. The helper builds one `0x19`-byte local template whose current grounded creation-side writes seed route-link fields `+0x0c` and `+0x0e` from the two input site ids, class byte `+0x10` from the supplied candidate-class argument, and one masked initial state template from the class side table at `0x005f2adc[class]`. It then allocates the live record from the route-link collection, attaches it to the first site through `placed_structure_route_link_attach_site_owner` `0x00467eb0`, increments the grouped class counters at `[class_record+0x5a]` and `[class_record+0x5e]` through the candidate-class table at `0x0062ba8c+0x8e`, and finally re-enters `placed_structure_route_link_recompute_endpoint_pair_state` `0x00467c30`. Current direct creation-side caller is `placed_structure_try_emit_best_route_style_peer_link_for_candidate_class` `0x0040fef0`, while grounded internal calls land at `0x00468067` and `0x0046809b`; this is therefore the strongest current owner for creation-side site-pair seeding in the route-link family.","objdump + caller xrefs + stack-layout inspection + class-counter correlation + route-link-collection correlation" +0x004680b0,96,placed_structure_route_link_release_and_detach,map,thiscall,inferred,objdump + caller xrefs + class-counter correlation,3,"Releases one live `0x006ada90` route-link record's class-side counters and then detaches it from its current owner chain. The helper resolves the candidate-class record from route-link byte `+0x10` through `0x0062ba8c+0x8e`, subtracts the fixed creation-side increment from `[class_record+0x5a]`, then chooses one of the two trailing accumulator slots `[class_record+0x62]` or `[class_record+0x66]` by testing state byte `+0x12 & 0x1`. After that class-side rollback it tails into `placed_structure_route_link_detach_current_owner_chain` `0x00467df0`. Current grounded caller is the route-link collection sweep around `0x004681ae`, which keeps this as the clearest release-side companion to `placed_structure_route_link_allocate_site_pair_for_candidate_class` rather than another attach helper.","objdump + caller xrefs + class-counter correlation + detach-tail correlation" +0x00468110,39,placed_structure_route_link_collection_construct,map,thiscall,inferred,objdump + world-bringup correlation + collection-layout inspection,3,"Constructs the world-side route-link collection later published at `0x006ada90`. The helper seeds the collection vtable at `0x005ce130`, then initializes one indexed collection through `0x00518570` with grounded parameters `(record_size=0x19, initial_slots=0x64, growth=0x64, id_base=1)`. Current grounded caller is the world bring-up path at `0x004488a3`, where the resulting manager is stored into `0x006ada90` beside the placed-structure and candidate collections. This is the strongest current owner name for the record family later scanned by the route-style overlay and availability helpers.","objdump + world-bringup correlation + collection-layout inspection + manager-publication correlation" +0x00468140,18,placed_structure_route_link_collection_destroy,map,thiscall,inferred,objdump + world-shutdown correlation + collection-layout inspection,3,"Destroys the world-side route-link collection rooted at `0x006ada90`. The helper restores the same collection vtable at `0x005ce130`, releases the indexed-collection payload through `0x00518600`, and then tails into the common collection teardown at `0x00518bd0`. Current grounded callers are the global world-shutdown path at `0x0044931d` and the route-link collection sweep at `0x004681ae`, which keep this as the clear destructor companion to `placed_structure_route_link_collection_construct`.","objdump + world-shutdown correlation + collection-layout inspection + manager-publication correlation" +0x004681f0,100,placed_structure_route_link_collection_remove_links_touching_site_id,map,thiscall,inferred,objdump + caller xrefs + field-match inspection,3,"Collection-wide cleanup sweep over `0x006ada90` that removes every route-link record whose grounded site-reference triple matches one caller-supplied placed-structure id. The helper walks the live route-link collection and deletes any record whose `u16` fields at `+0x0a`, `+0x0c`, or `+0x0e` equal the requested id, reusing the collection erase vfunc for each match. Current grounded callers include the placed-structure teardown path at `0x0040e23b`, where the supplied id comes from `[site+0x2a4]`, so this now looks like the site-side cleanup companion for the route-link family rather than a generic collection filter.","objdump + caller xrefs + field-match inspection + site-cleanup correlation" +0x00468260,84,placed_structure_route_link_collection_remove_links_by_route_node_id,map,thiscall,inferred,objdump + caller xrefs + field-match inspection,3,"Collection-wide cleanup sweep over `0x006ada90` that removes every route-link record whose route-node owner field at `+0x08` matches one caller-supplied id. The helper walks the live route-link collection, compares each record's `u16` field `+0x08` against the requested route-node id, and erases matching records through the same collection vfunc used by the broader cleanup paths. Current grounded caller is the neighboring runtime teardown at `0x004acf03`, which keeps this as the route-node-side cleanup companion to `placed_structure_route_link_collection_remove_links_touching_site_id` rather than another site sweep.","objdump + caller xrefs + field-match inspection + route-node-cleanup correlation" +0x004682c0,58,placed_structure_route_link_collection_recompute_all_endpoint_pair_state,map,thiscall,inferred,objdump + caller inspection + collection-iteration inspection,3,"Collection-wide recompute sweep over the live `0x006ada90` route-link family. The helper iterates every live route-link id through `indexed_collection_slot_count` `0x00517cf0`, `indexed_collection_get_nth_live_entry_id` `0x00518380`, and `indexed_collection_resolve_live_entry_by_id` `0x00518140`, then re-enters `placed_structure_route_link_recompute_endpoint_pair_state` `0x00467c30` on each resolved record. This is the clean whole-collection state refresh companion to the per-record recompute helper rather than another allocator or cleanup path.","objdump + caller inspection + collection-iteration inspection + recompute-helper correlation" +0x00468300,235,placed_structure_route_link_rebuild_route_style_grid_counters_and_endpoint_state,map,thiscall,inferred,objdump + caller inspection + world-grid correlation + collection-iteration inspection,3,"Higher-level rebuild pass above the route-link family that resets the route-style world-grid counters and then recomputes live endpoint state across `0x006ada90`. The helper first reads three candidate-class ids from the structure-candidate side table at `0x0062ba8c+0x88/+0x8a/+0x8c`, walks the active world-grid tables rooted at `[0x0062c120+0x2129]`, and clears the aligned per-cell dword lanes at offset `+0x103` for those three classes. It then iterates every live route-link record in `0x006ada90`, clears state bit `0x2` in each record's flag byte at `+0x12`, and re-enters `placed_structure_route_link_recompute_endpoint_pair_state` `0x00467c30`. Current grounded callers include the recurring simulation-maintenance branch at `0x0040a575`, the world bring-up side near `0x00444b2f`, and one later world-side update path at `0x00481157`, which makes this the clearest current owner of the full-family route-style counter-and-state rebuild rather than just another collection walk.","objdump + caller inspection + world-grid correlation + collection-iteration inspection + route-style-class correlation" 0x0041e2b0,589,structure_candidate_rebuild_local_service_metrics,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Setup-side local-metrics rebuild for one live structure candidate after it has passed `structure_candidate_is_enabled_for_current_year` at `0x0041e220`. The helper clears the metric bands at `[this+0x6a]`, `[+0x6e]`, `[+0x72]`, `[+0x76]`, and `[+0x7a]`, then samples repeated world-grid slices off the active world root at `0x0062c120` through `0x0042c960` and the per-cell tables rooted at `[world+0x2129]`. It accumulates one broad local magnitude at `[this+0x6a]`, folds two optional positive channels into `[this+0x6e]` and `[this+0x72]`, and finally normalizes and scales the trailing summary pair `[this+0x76]` and `[this+0x7a]` with fixed constants. Current grounded caller is `world_setup_building_collection_phase` at `0x0041ea50`, so this still looks like a setup-time local service or demand scorer rather than the recurring owner of the whole cargo-economy lane, but it is now one clear downstream consumer of the same `[candidate+0x56]` live-availability gate.","objdump + caller xrefs + callsite inspection + world-grid correlation" 0x0042c1b0,886,placed_structure_redistribute_local_service_pressure_from_neighbors,map,thiscall,inferred,objdump + caller xrefs + neighborhood sweep inspection,3,"Neighbor-aware local-service post-pass for one placed-structure or site record. The helper first builds a bounded set of nearby site references by scanning offset patterns from `0x00624b28` and `0x00624b48` against the world-grid tables rooted at `[0x0062c120+0x2129]`, keeping only neighbors whose state byte at `+0x0e6` is compatible with the current site and recording per-neighbor weights derived from the local word tables near `[site+0x00]` and `[site+0x0f3]`. It then walks the live candidate collection and, for each live non-remapped candidate, chooses the strongest positive neighbor deficit after scaling through the candidate-side weight at `[candidate+0x52]`; when a positive deficit remains it commits the redistribution through `0x0042bf80`. Current grounded caller is the composite local refresh `0x0042d580`, so this looks like the neighboring-site redistribution pass beneath the local service-score bundle rather than an independent outer loop.","objdump + caller xrefs + neighborhood sweep inspection + candidate-weight correlation" 0x0041eac0,794,structure_candidate_collection_refresh_cargo_economy_filter_flags,map,thiscall,inferred,objdump + caller xrefs + callsite inspection + rdata strings,3,"Collection-wide refresh of one cargo-economy-sensitive candidate flag in the live structure collection at `0x0062ba8c`. The helper first walks the global candidate pool at `0x0062b268`, filters category-`2` entries through the paired availability bytes `[candidate+0xba]` and `[candidate+0xbb]` plus the recipe-runtime latch `[candidate+0x7ac]`, and builds one temporary per-cargo mask keyed by cargo names such as `Clothing`, `Cheese`, `Meat`, `Ammunition`, `Weapons`, `Diesel`, `Troops`, and `Passengers`; one special-case branch also uses structure labels such as `Barracks` and `Recycling Plant` while consulting the region collection at `0x0062bae0`. It then iterates the live structure collection itself, combines that temporary cargo mask with the candidate-local bytes `[entry+0x47]`, `[entry+0x48]`, and `[entry+0x49]`, the runtime cargo-economy latch at `[0x006cec74+0x25f]`, and one neighboring mode gate at `[0x006cec78+0x4afb]`, and writes the resulting enabled-or-filtered state into `[entry+0x56]` before re-entering `0x0041e970` to rebuild the derived visible counts. Current grounded callers are the collection-side setup path around `0x0041f4cb` and the runtime toggle branch at `0x0046577c`, where the same `0x006cec74+0x25f` bit is flipped directly; that makes this the strongest current bridge from the editor's `Disable Cargo Economy` rule into live structure-candidate filtering rather than a purely editor-side helper.","objdump + caller xrefs + callsite inspection + rdata strings + special-condition correlation" @@ -30,12 +64,16 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004248d0,759,company_compute_cached_recent_performance_support_score,simulation,thiscall,inferred,objdump + caller inspection,3,"Builds one cached company-side support score from recent yearly metric history and current scenario difficulty. When the company is inactive via `[this+0x3f]` it returns the fixed negative fallback at `0x005c8598`; otherwise it reuses the cache in `[this+0x0cfb]` and `[this+0x0cff]` when the current year at `[0x006cec78+0x15]` matches. On a cold pass it walks the recent year window above the founding year at `[this+0x157]`, queries multiple yearly stat ids through `0x0042a5d0` including `0x1f`, `0x1e`, `0x20`, and `0x1d`, blends those results with recency weights and one difficulty table under `0x005f33b8`, clamps intermediate ratios, stores one bounded subscore into `[this+0x0d19]`, and finally caches the resulting float in `[this+0x0cff]` with the current year in `[this+0x0cfb]`. Current grounded callers are the public-support blend helper at `0x00424fd0` and nearby company telemetry or policy branches.","objdump + caller inspection + cache-field correlation" 0x00425a90,194,company_declare_bankruptcy_and_halve_bond_debt,simulation,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the grounded company bankruptcy commit path. The helper walks the live bond table rooted at `[this+0x5f]`, halves each outstanding principal, recomputes finance metrics through `0x0042a040` and `0x00424fd0`, reduces the company value field at `[this+0x47]`, and stamps the current year into `[this+0x163]` as the localized bankruptcy-cooldown anchor. Current grounded shell caller is `shell_company_detail_bankruptcy_flow` on the `CompanyDetail.win` path.","objdump + RT3.lng strings + caller inspection + finance-field correlation" 0x004261b0,74,company_count_unassigned_shares_after_active_chairman_holdings,simulation,thiscall,inferred,objdump + caller inspection,4,"Returns the current company share pool at `[this+0x47]` minus the positive holdings found in each active chairman profile record under `0x006ceb9c`. The helper uses the company collection index from `[this+0x00]` to read per-profile holdings from `[profile + company_index*4 + 0x15d]`, sums only positive entries, and subtracts that total from the company share count. Current grounded callers are the takeover and merger vote resolvers, which stage the result into `0x006d1a04` and `0x006d1104` before the lower public-vote support formulas run.","objdump + caller inspection + takeover and merger vote correlation" +0x00426260,607,company_compute_board_approved_dividend_rate_ceiling,simulation,thiscall,inferred,objdump + caller inspection,4,"Computes one nonnegative per-share dividend ceiling for the selected company. The helper starts from the current support or governance lane `0x2329/0x0d`, normalizes that value by the current outstanding-share band at `[this+0x47]`, then scans a bounded recent-year window relative to the founding year `[this+0x157]` and current scenario year `[0x006cec78+0x0d]`, taking minima from the shareholder-facing slots `0x2b` and `0x2c`. In the early-company path it also folds in `[this+0x57]` and the previous-year slot `0x1c`, applies several scale constants, and clamps the result at zero before returning the final per-share ceiling. Current grounded shell caller is `shell_company_detail_handle_change_dividend_rate_dialog_message` at `0x004c5140`, where this is the direct board-approval limit behind localized id `991` when the player tries to raise the dividend too far.","objdump + caller inspection + dividend-ceiling correlation" 0x00426890,68,company_find_collection_index_by_company_id,simulation,thiscall,inferred,objdump + caller inspection,4,"Finds one live company collection index by comparing the requested company id against the first dword of each entry in the company manager at `0x0062be10`. The helper returns the zero-based index on a match or `-1` when no live company record matches. Current grounded callers are the takeover and merger vote resolvers, which use that index before reading profile-side per-company holdings from `0x006ceb9c`.","objdump + caller inspection + company collection correlation" 0x00426be0,53,company_can_purchase_territory_access_rights,simulation,thiscall,inferred,objdump + caller inspection + RT3.lng strings,4,"Returns whether the current company may purchase territory-access rights for one requested territory id. The helper first rejects territories where the company already has access through the byte table at `[this + territory*0x38d + 0x1d9f]`, then resolves the territory through `0x006cfc9c` and only returns `1` when the territory-side mode byte at `[territory+0x2d]` equals `1`. Current grounded callers are the `CompanyDetail.win` territory-access summary helper at `0x004c1b60` and the buy-rights flow at `0x004c5fc9`, where this is the direct gate between localized ids `947` and `948` plus the actionable `961` purchase prompt.","objdump + caller inspection + RT3.lng strings + territory-flag correlation" -0x0042a2e0,645,company_read_control_transfer_metric_slot,simulation,thiscall,inferred,objdump + caller inspection,3,"Reads one derived company metric from the bounded slot family `0x13..0x2a` used by control-transfer, public-support, and annual governance logic. The dispatcher mixes direct company fields such as `[this+0x4b]`, `[this+0x53]`, `[this+0x323]`, `[this+0x327]`, `[this+0x333]`, `[this+0x33f]`, and the later counters near `[this+0x34b]` and `[this+0x14f]` with a few computed ratios and helper-backed terms. The first grounded slot `0x13` already resolves through `company_compute_public_support_vote_scalar` at `0x00424fd0`, while nearby governance callers also use slots such as `0x1f`, `0x29`, `0x2b`, and `0x2c` in the annual shareholder-revolt and creditor-warning lane surfaced by localized ids `300..304`. This now looks like a generic company support-and-governance metric dispatcher rather than a merger-only issue reader.","objdump + caller inspection + metric-slot correlation + governance-string correlation" +0x00426d60,393,company_deactivate_and_clear_chairman_share_links,simulation,thiscall,inferred,objdump + caller inspection + collection-state correlation,4,"Runs the destructive selected-company clear path currently reached from `CompanyDetail.win`. The helper first rejects inactive companies through `[this+0x3f]`, then zeroes all active-chairman share holdings for this company across `0x006ceb9c`, clears the linked chairman backpointer `[company+0x3b]` and the profile-side owning-company field `[profile+0x1dd]`, clears the selected-company latch when the scenario currently points at this company, marks the company inactive by zeroing `[company+0x3f]`, and walks two live collections to drop or invalidate remaining references that still point back to this company. The tail then rebuilds one local name block from `[company+0x4]` and publishes the change through the scenario-state helper at `0x004360d0`. Current grounded shell caller is the `0x9493` section-0 control under `shell_company_detail_window_handle_message`, so current best meaning is a company deactivation or liquidation-style clear path rather than an ordinary governance vote helper.","objdump + caller inspection + collection-state correlation + CompanyDetail control correlation" +0x00426ef0,43,company_get_linked_chairman_profile_record,simulation,thiscall,inferred,objdump + caller inspection,4,"Resolves the linked chairman profile record for one company. The helper reads the linked chairman id from `[this+0x3b]`, validates it against the live profile collection at `0x006ceb9c`, and returns the resolved profile record through `0x00518140`; zero or invalid ids return null. Current grounded callers include the CompanyDetail section-0 overview formatter at `0x004e5cf0`, where this is the direct bridge from a selected company to the chairman profile used for ownership and governance text.","objdump + caller inspection + chairman-link correlation" +0x0042a2e0,645,company_read_control_transfer_metric_slot,simulation,thiscall,inferred,objdump + caller inspection,3,"Reads one derived company metric from the bounded slot family `0x13..0x2f` used by control-transfer, public-support, and annual governance logic. The dispatcher mixes direct company fields such as `[this+0x4b]`, `[this+0x53]`, `[this+0x323]`, `[this+0x327]`, `[this+0x333]`, `[this+0x33f]`, and the later counters near `[this+0x34b]` and `[this+0x14f]` with a few computed ratios and helper-backed terms. The first grounded slot `0x13` already resolves through `company_compute_public_support_vote_scalar` at `0x00424fd0`, while nearby governance callers also use slots such as `0x1f`, `0x29`, `0x2b`, and `0x2c` in the annual shareholder-revolt and creditor-warning lane surfaced by localized ids `300..304`. Wider shell-side xrefs now tighten `0x2b` and neighboring slots `0x2c`, `0x2e`, and `0x2f` into the same shareholder-facing per-share or history family reused by a CompanyDetail formatter beside localized text including `925` `Profits:`, `928` `Largest Shareholders`, `929` `Shares`, and `930` `Per Share Data`. This now looks like a generic company support-and-governance metric dispatcher rather than a merger-only issue reader.","objdump + caller inspection + metric-slot correlation + governance-string correlation + company-detail correlation" 0x0042a5d0,131,company_read_year_or_control_transfer_metric_value,simulation,thiscall,inferred,objdump + caller inspection + RT3.lng strings,3,"Reads one company-side float from either a year-relative stat series or the local support-and-governance metric slot family. When the family argument is `0x2329` or one of the neighboring current-year offsets, the helper resolves one year-relative table entry from the series rooted at `[this+0x0d7f]`; when the request falls back to the bounded slot family it delegates to `company_read_control_transfer_metric_slot` at `0x0042a2e0`. The `0x2329` token is no longer treated as an issue id here: it is the stat-family selector paired with the localized company-stat label id `2329`, and current grounded callers use this wrapper beneath merger, takeover, bankruptcy, annual shareholder-revolt, creditor-liquidation, and other company-policy dialogs to fetch yearly or current support-side values. This makes the helper a generic company stat reader rather than an issue-specific vote formula.","objdump + caller inspection + RT3.lng strings + stat-family correlation + governance-string correlation" 0x0042c690,311,placed_structure_rebuild_candidate_cargo_service_bitsets,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Rebuilds two per-cargo bitsets on one placed-structure or site record using the live structure-candidate collection at `0x0062ba8c`. The helper clears the bitsets rooted at `[this+0x0d8]` and `[this+0x0df]`, walks the linked placed-structure chain starting at `[this+0x0d6]` through `0x0062b26c`, selects only linked instances whose backing candidate resolves through vtable `+0x80` with category byte `2`, and then scans the live candidate collection for entries that pass `structure_candidate_is_enabled_for_current_year` at `0x0041e220`. For each passing candidate it queries the direct and scaled supply-side cargo channels through the wrappers at `0x00412960` and `0x004129a0`; positive direct supply sets bits in `[this+0x0df]`, while positive scaled supply on candidates with runtime cargo state at `[candidate+0x78c]` sets bits in `[this+0x0d8]`. Current grounded callers sit immediately above the sibling helper at `0x0042cdf0`, which makes this the strongest current steady-state consumer of the rebuilt editor cargo runtime tables rather than a pure setup path.","objdump + caller xrefs + callsite inspection + cargo-summary correlation" 0x0042c8f0,112,placed_structure_refresh_linked_candidate_flag4,map,thiscall,inferred,objdump + caller xrefs + linked-instance inspection,3,"Refreshes bit `0x4` in the placed-structure state byte at `[this+0x0e6]` from the currently linked placed-instance chain rooted at `[this+0x0d6]`. The helper walks linked instances through `0x0062b26c`, keeps only entries whose backing instance passes `0x0040c990 == 1`, resolves each surviving instance through vtable slot `+0x80`, and sets the local flag when any resolved candidate record has nonzero byte `[candidate+0xba]`; otherwise it clears that bit. Current grounded callers are the immediate wrapper `0x0042cdf0` plus the relink helpers at `0x0042c9a0` and `0x0042c9f0`, so this looks like the sibling state refresh that runs beside the cargo-service bitset rebuild even though the exact player-facing meaning of `[candidate+0xba]` is still open.","objdump + caller xrefs + linked-instance inspection + candidate-flag correlation" +0x0042cab0,117,placed_structure_accumulate_candidate_metric_or_emit_route_style_peer_link,map,thiscall,inferred,objdump + caller inspection + route-style remap inspection,3,"Small candidate-side projection helper used by the broader route-style rebuild lane. The helper starts by querying one integer local metric through `0x0042c960` for the caller-supplied candidate index, then resolves the matching structure-candidate record through `0x0062ba8c` and re-enters `0x0041e1f0` to stage one floating contribution. It next reads the candidate's route-style remap slot at `0x0062ba8c+0x9a`: when that slot is negative it adds the contribution directly into the local route-style grid lane at `[this+candidate*4+0x103]`; when the slot is nonnegative it instead re-enters `placed_structure_try_emit_best_route_style_peer_link_for_candidate_class` `0x0040fef0` with the remapped class id and the same floating contribution. Current grounded caller is the larger per-site route-style rebuild pass at `0x004101e0`, which makes this the clearest current branch where ordinary candidate metrics stay local but remapped route-style candidates become peer-link emission requests.","objdump + caller inspection + route-style remap inspection + peer-link emission correlation" 0x0042cb30,124,placed_structure_clamp_candidate_service_age_table,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Late clamp pass over the primary per-candidate word table rooted at `[this+0x00]`. When the site owns a nonzero route latch at `[this+0x0d4]` and `0x0042c880` signals the pass should run, the helper walks every live non-remapped candidate, queries one route-linked age or freshness value through `0x0042c110`, shifts that result into the local word-table scale, and replaces `[this+candidate*2]` with the smaller of the current value and the new clamp. Current grounded callers are the local bundle wrapper `0x0042d580` and the later world-grid sweep at `0x00450133`, so this now looks like the final recent-service clamp on the local candidate age table rather than another raw scoring helper.","objdump + caller xrefs + callsite inspection + route-age correlation" 0x0042cbb0,145,placed_structure_route_supports_candidate_local_service_mode,map,thiscall,inferred,objdump + caller xrefs + route-record inspection,3,"Boolean route-linked predicate for one candidate-local service branch. The helper walks the route or service record chain owned by the current site through `[this+0x0d4]` and collection `0x006cec20`, reads one candidate-indexed float lane at `[route+0x3e]`, and compares the route-side threshold at `[route+0x112]` against the current local word-table value for that candidate after scaling through `0x00437d20`. It returns `1` on the first matching route record and `0` otherwise. Current grounded caller is `placed_structure_rebuild_candidate_local_service_tables` at `0x0042ce00`, where this predicate selects one of the route-backed scoring transforms.","objdump + caller xrefs + route-record inspection + candidate-table correlation" 0x0042cc50,402,placed_structure_apply_route_linked_service_caps,map,thiscall,inferred,objdump + caller xrefs + route-record inspection,3,"Route-linked cap pass over the aligned local service tables. The helper walks the route or service record chain rooted at `[this+0x0d4]` through `0x006cec20`, then for each live non-remapped candidate that passes `structure_candidate_is_enabled_for_current_year` it compares the route-side candidate float at `[route+0x42]` against the current site float table at `[this+0x107]` and the current primary word-table value at `[this+0x00]`. When the route-linked ratio stays inside the live clamp window it writes a lower capped value back into the primary word table. Current grounded caller is the composite local refresh `0x0042d580`, so this now looks like the first route-backed cap pass that shapes the rebuilt local service tables before the later neighborhood redistribution and recent-service clamp run.","objdump + caller xrefs + route-record inspection + local-table correlation" @@ -44,9 +82,14 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0042d580,26,placed_structure_refresh_local_service_score_bundle,map,thiscall,inferred,objdump + caller xrefs + wrapper inspection,4,"Composite local-service refresh for one placed-structure or site record. The helper first runs `placed_structure_rebuild_candidate_local_service_tables` at `0x0042ce00`, then immediately chains into the neighboring local post-passes at `0x0042cc50`, `0x0042c1b0`, and `0x0042cb30` before returning. Current grounded caller is the world-grid sweep at `0x00450110`, which uses this as the stronger per-site local-service refresh after the lighter cargo-service-state pass at `0x00450003`.","objdump + caller xrefs + wrapper inspection" 0x00428a10,22,company_clear_selected_chairman_if_current_profile,simulation,thiscall,inferred,objdump + caller inspection,4,"Clears the linked chairman for the current company when the supplied profile id matches `[this+0x3b]`. On a match the helper zeroes the incoming profile id and tail-calls `0x00427c70`; otherwise it returns without changing company state. Current grounded shell caller is `shell_company_detail_resign_chairmanship_flow`, which uses this as the commit step behind the localized resignation confirmation.","objdump + caller inspection + chairman-link correlation" 0x00424fd0,751,company_compute_public_support_vote_scalar,simulation,thiscall,inferred,objdump + caller inspection,3,"Computes one bounded public-support scalar used by company policy, takeover or merger voting, and the adjacent annual governance lane. The helper starts from `company_compute_cached_recent_performance_support_score` at `0x004248d0`, blends that score with the company-side field `[this+0x57]`, applies extra startup or age smoothing when the current year is still within five years of `[this+0x157]`, and optionally updates the mutable support field `[this+0x4f]` when the caller supplies nonzero control arguments. It then folds in company value `[this+0x47]`, one profile or company affinity term from `0x00436590`, the current linked chairman id `[this+0x3b]`, and one difficulty table under `0x005f33b8`, clamps the result into a bounded 0-to-positive range, and returns the final float. Current grounded callers include the merger vote resolver at `0x004ebd10`, the company-side takeover and policy family, and the annual shareholder-revolt or creditor-pressure path that surfaces localized ids `300..304`. The direct scenario-state issue lane here uses issue id `0x37`, which now looks like the broader company-management or public-sentiment slot rather than the narrower merger-only management-attitude slot.","objdump + caller inspection + support-field correlation + issue-id correlation + governance-string correlation" +0x00424580,82,company_compute_issue39_opinion_bias_scalar,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Small company-side float helper beneath the city-connection bonus lane. It first reads one normalized scenario baseline from `0x00433740` on active scenario state `0x006cec78`, then adds the scaled raw issue-39 opinion total from `scenario_state_sum_issue_opinion_terms_raw` at `0x00436710` using the current company id `[this+0x00]`, linked chairman id `[this+0x3b]`, and no territory argument. Current grounded callers are the wrapper at `0x00427540` and the mid-ladder branch inside `company_compute_connection_bonus_value_ladder` at `0x00425425`, so current best meaning is the issue-39 opinion bias scalar beneath city-connection bonus and announcement scoring rather than a generic company-support helper.","objdump + caller xrefs + callsite inspection + issue-39 correlation + connection-bonus correlation" +0x00425880,64,company_compute_negative_cash_balance_interest_rate,shell,thiscall,inferred,objdump + LoadScreen report correlation + localized string correlation,4,"Small company-side rate helper used only by the shared `LoadScreen.win` report-history renderer at `0x004e9b20`. The helper reads one control-transfer or yearly metric through `company_read_year_or_control_transfer_metric_value` at `0x0042a5d0` using family `0x2329` and slot `0x22`, combines that with the issue-39 opinion bias scalar from `company_compute_issue39_opinion_bias_scalar` at `0x00424580`, normalizes the result through two fixed constants, and returns one bounded float formatted as the first `%1` insert in localized strings `2815` and `2816`. Current grounded meaning is the company's negative-cash borrowing interest rate, i.e. the rate the company currently pays on negative cash balances in the Income Statement and Balance Sheet help rows.","objdump + LoadScreen report correlation + localized string correlation + helper call inspection" +0x004258c0,396,company_compute_positive_cash_balance_interest_rate,shell,thiscall,inferred,objdump + LoadScreen report correlation + localized string correlation,4,"Company-side rate helper paired with `company_compute_negative_cash_balance_interest_rate` beneath the shared `LoadScreen.win` report-history renderer at `0x004e9b20`. The helper starts from the same issue-39 opinion bias scalar at `0x00424580`, subtracts one baseline constant, then reads the company cash metric through `company_read_year_or_control_transfer_metric_value` at `0x0042a5d0` using family `0x2329` and slot `0x0d`. It applies a piecewise threshold ladder over that cash or liquidity lane, clamps the result into several fixed bands, and returns the second `%2` insert for localized strings `2815` and `2816`. Current grounded meaning is the company's positive-cash deposit interest rate, i.e. the rate the company currently earns on positive cash balances in the Income Statement and Balance Sheet help rows.","objdump + LoadScreen report correlation + localized string correlation + helper call inspection + piecewise-threshold correlation" +0x00425320,607,company_compute_connection_bonus_value_ladder,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Builds one bounded company-side value scalar beneath the city-connection bonus lane. The helper returns `0` when the company-active flag at `[this+0x3f]` is clear; otherwise it walks a four-step recent-year window relative to the current scenario year at `0x006cec78+0x0d` and the company founding year at `[this+0x157]`, reads one pair of support-or-governance slots through `company_read_year_or_control_transfer_metric_value` at `0x0042a5d0` with ids `0x2b` and `0x09`, accumulates their weighted differences with descending weights `4..1`, averages that ladder, blends in the current stat-family `0x2329` mode `0x12` term, and multiplies the result through the neighboring company-side multiplier at `0x00423e40`. When the current support lane `0x2329` mode `0x0d` is high enough, it also folds in the active scenario issue-opinion multiplier at `0x00436710` for issue id `0x39` using the current company and linked chairman ids. Wider xrefs now tighten `0x2b` into the same rolling shareholder-facing performance lane reused by the annual shareholder-revolt or creditor-pressure checks and a CompanyDetail per-share/history formatter; `0x09` remains narrower and currently looks like a current governance-pressure term that is only read after those broader yearly trend and public-support gates succeed. The tail then clamps the result through a bounded piecewise ladder with extra startup smoothing across roughly the first five years after founding. Current grounded callers are `company_evaluate_and_publish_city_connection_bonus_news` at `0x00406050`, the smaller wrapper at `0x00427540`, and the boolean unlock gate at `0x00427590`, so current best meaning is the company-side connection-bonus value ladder rather than a generic public-support scalar.","objdump + caller xrefs + callsite inspection + issue-slot correlation + connection-bonus correlation + governance-lane correlation" 0x00429990,86,company_collection_get_nth_active_company_id,simulation,thiscall,inferred,objdump + caller inspection,4,"Returns the company id of one requested active-company ordinal within the live company collection rooted at `0x0062be10`. The helper linearly walks collection slots through `0x00518380`, tests the active company-state flag at `[entry+0x3f]`, decrements the caller-supplied ordinal only for active entries, and returns the first company id whose active ordinal matches zero. Current grounded callers use it as the forward mapping between active-company page indices and concrete company ids in shell-side roster, detail, and picker flows.","objdump + caller inspection + active-company roster correlation" 0x004299f0,84,company_collection_count_active_companies_before_company_id,simulation,thiscall,inferred,objdump + caller inspection,4,"Counts how many active companies precede one requested company id in the live company collection at `0x0062be10`. The helper linearly walks collection slots through `0x00518380`, stops when the entry id matches the requested company id, and increments the return counter only for active entries whose state flag at `[entry+0x3f]` is nonzero. Current grounded callers use this as the inverse mapping for shell-side company paging and company-relative selector paths before converting back through `company_collection_get_nth_active_company_id` at `0x00429990`.","objdump + caller inspection + active-company roster correlation" 0x00429a50,62,company_collection_count_active_companies,simulation,thiscall,inferred,objdump + caller inspection,4,"Counts active companies in the live company collection rooted at `0x0062be10`. The helper walks collection slots through `0x00518380`, resolves each record through `0x00518140`, and increments the total only when the active-state flag at `[entry+0x3f]` is nonzero. Current grounded callers use this as the active-company roster size for shell-side company browsing and neighboring selector math.","objdump + caller inspection + active-company roster correlation" +0x00434050,11,shell_has_auxiliary_preview_owner,shell,cdecl,inferred,objdump + caller inspection + side-owner correlation,4,"Tiny presence probe over the auxiliary preview or side owner rooted at `0x006cd8d8`. The helper returns `1` when that owner pointer is nonnull and `0` otherwise. Current grounded callers include the `.gmt` save-side branch in `shell_map_file_world_bundle_coordinator` `0x00445de0`, the shell-state frame service pass `0x00482160`, the `BuildingDetail.win` subject-sync and tutorial gate lane around `0x004b9e10` and `0x004bb9e0`, and adjacent train-side branches that round route scalars or finalize auxiliary route buffers only when this side owner is live.","objdump + caller inspection + side-owner correlation + caller xrefs" 0x00434300,881,world_runtime_release_global_services,map,cdecl,inferred,objdump + analysis-context,3,Releases or clears a broad set of world-runtime global services owned by the current map object before a new world entry or sibling save branch continues. The helper walks the owner collection at [this+0x66b2] and then touches many global manager slots including 0x0062b244 0x0062cfcbc 0x0062be10 0x0062c120 0x0062ba8c 0x0062ba88 0x0062b2fc 0x0062b268 0x006cea4c and 0x006acd34 through repeated release-style calls and nulling writes. Current grounded callers are the heavier world-entry branch at 0x00443a50 the sibling .smp world-state branch at 0x00446d40 and shell_transition_mode at 0x00482ec0.,objdump + analysis-context + caller xrefs 0x0043cb00,295,world_view_step_heading_quadrant,shell,thiscall,inferred,objdump + caller xrefs,3,Applies one discrete heading-step command to the live world-view owner at 0x0062be68. The helper quantizes the current heading-like field [this+0x10] into one of four wrapped sectors derives the neighboring sector selected by the signed caller step and writes the resulting snapped heading back before rebuilding the dependent view state through 0x0043a750 0x0052d640 and 0x0043bde0. Current grounded callers are the paired shell UI command branches at 0x004de83d and 0x004de857 so this looks like the discrete rotate-view command family rather than free camera drag.,objdump + caller xrefs + callsite inspection 0x0043cc30,437,world_view_step_zoom_bucket,shell,thiscall,inferred,objdump + caller xrefs,3,Applies one discrete zoom or view-height bucket step to the live world-view owner at 0x0062be68. It derives a seven-entry threshold table under 0x005ee4dc and 0x0062be4c compares the current view-height field [this+0x18] against those thresholds chooses the neighboring bucket selected by the signed caller step clamps the result into the supported range and then rebuilds the dependent view state through 0x0043c610 0x00439820 and 0x0043bde0. Current grounded callers are the signed shell UI command pair at 0x004de871 and 0x004de88b and the keyboard-owned smoothing branch inside world_view_service_shell_input_pan_and_hover at 0x0043dca4.,objdump + caller xrefs + callsite inspection @@ -58,8 +101,67 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0043d740,937,world_view_service_keyboard_turn_pan_and_zoom_bindings,shell,thiscall,inferred,objdump + callsite inspection,4,"Keyboard-driven world-view interaction helper beneath world_view_service_shell_input_pan_and_hover. It samples elapsed wall-clock time through 0x0051d890 against the previous timestamp at 0x0062be74 clamps the per-pass delta into the 0x08 through 0xc8 range and polls four configurable binding-pair families through the shell input table at 0x006d4018 via 0x0054e7d0. The first two pair families at [this+0x0a6] through [this+0x0b2] and [this+0x0b6] through [this+0x0c2] now ground as the default `Camera Forward` or `Camera Backward` pair and `Camera Left` or `Camera Right` pair. The third family at [this+0x0c6] through [this+0x0d2] produces a signed zoom-step or view-height delta that is returned through the caller-owned out-parameter for later smoothing and grounds as the default `Camera Zoom In` or `Camera Zoom Out` pair, while the fourth family at [this+0x0d6] through [this+0x0e2] applies continuous heading turns through 0x0043c810 and grounds as the default `Camera Rotate Left` or `Camera Rotate Right` pair. When the pan families are active the helper reaches world_view_pan_relative_offset_in_camera_plane at 0x0043d130 after checking the active world-view state. Current grounded caller is world_view_service_shell_input_pan_and_hover at 0x0043db00.",objdump + callsite inspection + caller xrefs + registration xrefs + RT3.lng 0x00439e40,557,world_view_seed_keyboard_binding_slot_pairs,shell,thiscall,inferred,objdump + callsite inspection,4,"Initializes the eight world-view keyboard binding slot pairs rooted at [this+0x0a6] through [this+0x0e2]. The helper zeroes the paired 4-byte fields then queries the global action-binding registry through 0x0045f370 using eight distinct stub roots at 0x0043d2a0 through 0x0043d310. The registration block at 0x00460769 through 0x004608e7 plus `Data/Language/RT3.lng` show those eight roots are seeded as four labeled directional pairs: `Camera Forward` id 0x0d8a on Up, `Camera Backward` id 0x0d8b on Down, `Camera Left` id 0x0d8c on Left, `Camera Right` id 0x0d8d on Right, `Camera Zoom In` id 0x0d8e on Up, `Camera Zoom Out` id 0x0d8f on Down, `Camera Rotate Left` id 0x0d90 on Left, and `Camera Rotate Right` id 0x0d91 on Right. The first bank feeds the pan pairs later consumed at [this+0x0a6] through [this+0x0c2], while the second bank feeds the zoom-step and heading-turn pairs later consumed at [this+0x0c6] through [this+0x0e2]. After the registry lookups the helper normalizes several legacy companion values across all eight pairs by remapping 0x2 to 0x10 0x20 to 0x12 and 0x4 to 0x11 before storing the results back. This now looks like the live world-view setup path above world_view_service_keyboard_turn_pan_and_zoom_bindings at 0x0043d740 rather than a separate config-side binding store.",objdump + callsite inspection + callee inspection + registration xrefs + RT3.lng 0x0043db00,1968,world_view_service_shell_input_pan_and_hover,shell,thiscall,inferred,objdump + callsite inspection,4,Recurring world-view service that fuses shell input state into the live world-view owner at 0x0062be68. It begins by delegating keyboard-bound turn pan and zoom work to world_view_service_keyboard_turn_pan_and_zoom_bindings at 0x0043d740 then samples controller and view state through 0x00543c50 and 0x00543ba0 caches successive shell input coordinates from 0x006d4018 offsets 0xa94 and 0xa98 derives smoothed cursor or hover deltas against [this+0x2f6] [this+0x2fa] and [this+0x2fe] updates one world-under-cursor cache through 0x00448ac0 and 0x00448bd0 and refreshes the GameUppermost overlay through 0x004e0730 when the pan state changes. The helper repeatedly consults world_view_should_drive_primary_pan_channel at 0x0043af60 and world_view_should_drive_secondary_pan_channel at 0x0043b030 drives one of the lower motion branches at 0x0043e610 0x0043f4f0 or 0x0043e2c0 and smooths the keyboard zoom-step channel through the shared accumulator at 0x0062be78 before issuing discrete view-height bucket steps through world_view_step_zoom_bucket at 0x0043cc30. Current grounded callers include the recurring world-frame path at 0x00439730 and two setup or transition loops at 0x00516859 and 0x00516921. This now looks like the shared shell-input coordinator above keyboard turn pan zoom cursor drag and hotspot world-view motion rather than a mouse-only helper.,objdump + callsite inspection + caller xrefs -0x0043f640,3797,world_render_station_candidate_service_map_overlay,render,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Renders the world-side map overlay behind the active `StationDetail.win` candidate-service preview. The helper reads the currently previewed `(station id, candidate id)` pair from `0x005ee4fc` and `0x005ee500`, rejects early when shell preview mode or cargo-economy gates are inactive, re-enters `placed_structure_query_candidate_local_service_metrics` at `0x0047e240`, and then scans the placed-structure collection at `0x006cec20` through either the direct local-service path or the heavier route-side helper at `0x0047e690`. The candidate byte at `[candidate+0x46]` now looks like the key legend split: when it is nonzero the overlay formats the directional route rows `3874` `Coming To %1` and `3875` `Going From %1`; when it is zero the same two legend lanes instead format `3876` `Current Supply @ < %1` and `3877` `Current Demand @ > %1`. Empty directional lanes collapse to `3878` `--None--`, and the title lane falls back to literal `All` when no specific candidate label is active. The exact emitters for the connection-state notes `3872` `(Already Connected by Another Company)` and `3873` `(Not Connected)` are now bounded by adjacent overlay-side ownership checks, but `3879` `Out of Sync` does not appear inside this function body and should currently be treated as a nearby but unresolved sibling owner. This now looks like the first grounded world-side owner above the shell preview pair armed by `shell_station_detail_set_active_candidate_service_preview` at `0x00504ae0` rather than a generic hidden scanner.","objdump + RT3.lng strings + caller inspection + preview-overlay correlation + legend-branch correlation" -0x00439140,1086,simulation_frame_accumulate_and_step_world,simulation,cdecl,inferred,objdump + analysis-context,4,"Frame-owned simulation cadence after world bring-up and still directly called from shell_service_pump_iteration at 0x00483f70 rather than a separately grounded outer gameplay loop. The routine samples elapsed time through 0x0051d890 mixes shell and mode scalars into a simulation quantum keeps leftover fractional time in [this+0x4c80] and when enough time has accumulated repeatedly calls simulation_advance_to_target_calendar_point at 0x0040ab50 using the current step quantum from 0x005f2b38. Around those simulation steps it refreshes shell-facing presentation helpers under 0x006d4024 and 0x006d0818 updates multiple world collections and transport or scenario side structures and services the recurring GameMessage.win branch through 0x004e0720 before later follow-up work. One deeper world-mode sidecar inside the same frame path now looks grounded too: after delegating to world_view_service_shell_input_pan_and_hover at 0x0043db00 the frame compares the active controller-view pointer at [0x006d4024+0x18]+0x366e against the latched world object at [this+0x66a2], releases the previous object through vtable slot +0x64, and when the new object passes its own availability test at slot +0x1c plus shell-detail control gate 0x07d6 on 0x006d0818 it latches the new object and calls slot +0x60. That makes the frame owner the first grounded non-camera world-input coordinator for hover or focus-target transitions beneath the shell-fed camera stack, even though click or command semantics are still unresolved. This is the strongest grounded owner so far for the recurring gameplay simulation cadence that follows world_entry_transition_and_runtime_bringup.",objdump + analysis-context + caller xrefs + callsite inspection +0x00420030,578,city_connection_bonus_exists_matching_peer_site,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Reusable placed-structure scan beneath the city-connection bonus note family. The helper walks the live placed-structure collection at `0x006cec20`, first requiring each candidate peer to match one site-class token from the caller's local six-byte class table through `0x0042b2d0`, then applying four bounded caller-controlled filters before returning success on the first matching peer. Current filter roles are tighter now: the first stack flag enables the station-or-transit site-type gate through `0x0047fd50`; the second stack flag enables the linked-instance class-byte test through `0x0047de00 -> 0x0040c990 == 1`; the third stack flag enables the deeper route or peer-reachability sweep through `0x0047f310` and `0x0048e3c0`; and the fourth stack dword is an optional owning-company id that is matched through `placed_structure_query_linked_company_id` at `0x0047efe0`. Current grounded callers include the adjacent city bonus or status formatter around `0x004207d0`, where the helper's boolean combinations choose localized ids `3868` through `3873`, plus wider world-side sweeps at `0x00404d66`, `0x004221ea`, `0x00422264`, `0x00435930`, and `0x00435944`. This now looks like the common city-connection peer probe rather than a generic anonymous scan.","objdump + caller xrefs + callsite inspection + city-bonus note correlation + filter-role decoding" +0x00420280,204,city_connection_bonus_select_first_matching_peer_site,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Companion selector beside `city_connection_bonus_exists_matching_peer_site`. The helper walks the live placed-structure collection at `0x006cec20`, requires each candidate peer to match one site-class token from the caller's six-byte class table through `0x0042b2d0`, and then applies two caller-controlled filters before returning the first matching placed-structure id from the collection instead of a boolean. The first stack flag enables the same station-or-transit site-type gate through `0x0047fd50`; the second stack flag enables the stricter linked-instance class-byte requirement through `0x0047de00 -> 0x0040c990 == 1`; when either flag is zero the corresponding predicate becomes permissive. Current grounded callers are the city bonus or status formatter at `0x004207d0`, which uses the selected peer to recover linked-company context after the boolean note checks, and the earlier world-side branch at `0x004046f5`, which passes both flags as `1` before sampling the selected peer's derived coordinates through `0x0047df30` and `0x0047df50`. This now reads as the first-match peer selector paired with the broader existence probe rather than as a second generic scan.","objdump + caller xrefs + callsite inspection + filter-role decoding + peer-selector correlation" +0x004207d0,1053,city_site_format_connection_bonus_status_label,map,thiscall,inferred,objdump + caller inspection + RT3.lng strings,4,"Adjacent city-site label formatter above the city-connection peer helpers at `0x00420030` and `0x00420280`. When the preview-global `0x0062be84` is armed or the city-side subtype field `[this+0x23e]` is nonzero the function falls back into the neighboring virtual-style formatter at `0x00455860`; otherwise it builds one visible text block from the base city label at `[this+0x356]`, optionally appends the numeric value in `[this+0x276]`, and can append localized id `207` `(Connected)` when the active linked world object and city class checks succeed. If `[this+0x276]` is nonzero it then chooses one of the city-connection bonus note strings `3868` through `3873` by calling `city_connection_bonus_exists_matching_peer_site` at `0x00420030` with three meaningful filter combinations: a deeper peer-reachability pass, an active-company-only pass using `scenario_state_get_selected_chairman_company_record` at `0x004337a0`, and a broader any-company pass. After those boolean note checks it also re-enters `city_connection_bonus_select_first_matching_peer_site` at `0x00420280` to recover one representative matching peer site, resolves that peer's linked company through `placed_structure_query_linked_company_id` at `0x0047efe0`, and uses the selected company record when formatting the follow-on company-oriented text lane. That current grounded split is enough to tie `3869` `Connected By Another Station`, `3870` `Already Connected`, `3871` `Connected By Another Company`, `3872` `Already Connected by Another Company`, and `3873` `Not Connected` to this formatter boundary rather than to the station-detail overlay body. The helper also writes one caller-owned color field and label-priority scalar before returning style code `3`, so it currently reads as a world-label or hover-summary formatter for city connection-bonus state rather than a generic text helper.","objdump + caller inspection + RT3.lng strings + city-bonus note correlation + filter-combination decoding + peer-selector correlation" +0x0043f640,3797,world_render_station_candidate_service_map_overlay,render,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Renders the world-side map overlay behind the active `StationDetail.win` candidate-service preview. The helper reads the currently previewed `(station id, candidate id)` pair from `0x005ee4fc` and `0x005ee500`, rejects early when shell preview mode or cargo-economy gates are inactive, re-enters `placed_structure_query_candidate_local_service_metrics` at `0x0047e240`, and then scans the placed-structure collection at `0x006cec20` through either the direct local-service path or the heavier route-side helper at `0x0047e690`. The candidate byte at `[candidate+0x46]` now looks like the key legend split: when it is nonzero the overlay formats the directional route rows `3874` `Coming To %1` and `3875` `Going From %1`; when it is zero the same two legend lanes instead format `3876` `Current Supply @ < %1` and `3877` `Current Demand @ > %1`. Empty directional lanes collapse to `3878` `--None--`, and the title lane falls back to literal `All` when no specific candidate label is active. The neighboring connection-state notes `3872` `Already Connected by Another Company` and `3873` `Not Connected` no longer look like direct overlay-body emits; current grounded disassembly keeps them in the adjacent city bonus or status formatter `city_site_format_connection_bonus_status_label` at `0x004207d0`, which reuses `city_connection_bonus_exists_matching_peer_site` at `0x00420030` plus `placed_structure_query_linked_company_id` at `0x0047efe0` before choosing those strings. `3879` `Out of Sync` is also outside this function body and belongs to the multiplayer preview dataset path at `0x0046b780`. This now looks like the first grounded world-side owner above the shell preview pair armed by `shell_station_detail_set_active_candidate_service_preview` at `0x00504ae0` rather than a generic hidden scanner.","objdump + RT3.lng strings + caller inspection + preview-overlay correlation + legend-branch correlation + adjacent-formatter boundary check" +0x00439140,1086,simulation_frame_accumulate_and_step_world,simulation,cdecl,inferred,objdump + analysis-context,4,"Frame-owned simulation cadence after world bring-up and still directly called from shell_service_pump_iteration at 0x00483f70 rather than a separately grounded outer gameplay loop. The routine samples elapsed time through 0x0051d890 mixes shell and mode scalars into a simulation quantum keeps leftover fractional time in [this+0x4c80] and when enough time has accumulated repeatedly calls simulation_advance_to_target_calendar_point at 0x0040ab50 using the current step quantum from 0x005f2b38. Around those simulation steps it refreshes shell-facing presentation helpers under 0x006d4024 and 0x006d0818 updates multiple world collections and transport or scenario side structures and services the recurring GameMessage.win branch through `game_message_window_service_if_present` `0x004e0720` before later follow-up work. The shell-owned cadence evidence is tighter here now too: one direct frame-side branch at `0x0043970f` opens or focuses `LoadScreen.win` through `shell_open_or_focus_load_screen_page` `0x004e4ee0`, and the post-step shell-window ladder then services several sibling shell windows by presence-probe plus dirty-latch pairs instead of any detached gameplay-only owner. Current grounded members of that ladder now include the shared custom modal through `shell_has_live_custom_modal_dialog` `0x004c8680` plus `shell_mark_custom_modal_dialog_dirty` `0x004c8670`, the file-options dialog through `shell_has_file_options_dialog` `0x004dc7d0` plus `shell_mark_file_options_dialog_dirty` `0x004dc7e0`, `LoadScreen.win` through `shell_has_live_load_screen_window` `0x004e1f50` plus `shell_mark_load_screen_window_dirty` `0x004e1f60`, `SettingsWindow.win` through `shell_has_settings_window` `0x004fe120` plus `shell_mark_settings_window_dirty` `0x004fe130`, `Overview.win` through `shell_has_live_overview_window` `0x004f2e80` plus `shell_mark_overview_window_dirty` `0x004f2e90`, `BuildingDetail.win` through `shell_has_live_building_detail_window` `0x004b9d70` plus `shell_mark_building_detail_window_dirty` `0x004b9d80`, and now `Trainbuy.win` through `shell_has_live_trainbuy_window` `0x0050f740` plus `shell_mark_trainbuy_window_dirty` `0x0050f750`. One deeper world-mode sidecar inside the same frame path now looks grounded too: after delegating to world_view_service_shell_input_pan_and_hover at 0x0043db00 the frame compares the active controller-view pointer at [0x006d4024+0x18]+0x366e against the latched world object at [this+0x66a2], releases the previous object through vtable slot +0x64, and when the new object passes its own availability test at slot +0x1c plus shell-detail control gate 0x07d6 on 0x006d0818 it latches the new object and calls slot +0x60. That makes the frame owner the first grounded non-camera world-input coordinator for hover or focus-target transitions beneath the shell-fed camera stack, even though click or command semantics are still unresolved. This is the strongest grounded owner so far for the recurring gameplay simulation cadence that follows world_entry_transition_and_runtime_bringup.","objdump + analysis-context + caller xrefs + callsite inspection + frame-disassembly correlation" +0x00433b00,117,shell_can_open_trainbuy_window_or_warn,shell,thiscall,inferred,objdump + caller inspection + RT3.lng strings,4,"Shared availability gate above the shell-side `Trainbuy.win` family. The helper first rejects scenario states where the train-buy action is globally disabled through `[0x006cec78+0x4aa3]`, surfacing localized id `334` `That action is not allowed in this scenario.` through the shared shell modal path when blocked. It then checks whether the active company or world object state supplied by the caller allows train purchase; if no company is active it raises id `337` `You can't buy a train without starting a company first!`, and if no track has been placed it raises id `338` `You can't buy a locomotive until some track has been placed!`. Only the success path returns nonzero to the callers at `0x004406d3` and `0x004de7d9`, both of which immediately enter `shell_open_or_focus_trainbuy_window` at `0x00512c50`.","objdump + caller inspection + RT3.lng strings + train-buy gate correlation" +0x0050f740,6,shell_has_live_trainbuy_window,shell,cdecl,inferred,objdump + caller inspection + strings correlation,4,"Tiny presence probe for the shell-side `Trainbuy.win` singleton rooted at `0x006d3ac8`. The helper returns the live-flag dword at `0x006d3ae4`, which is set during `shell_open_or_focus_trainbuy_window` at `0x00512c50` and cleared after that family tears the singleton down. Current grounded callers include the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, where it sits beside the sibling overview, building-detail, load-screen, settings, custom-modal, and file-options probes.","objdump + caller inspection + strings correlation + singleton correlation" +0x0050f750,11,shell_mark_trainbuy_window_dirty,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Tiny dirty-latch setter paired with `shell_has_live_trainbuy_window`. The helper stores `1` into `0x006d3adc`, which current nearby call patterns treat as the `Trainbuy.win` refresh or service request latch once the live singleton family rooted at `0x006d3ac8` exists. Current grounded callers include the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, and the same latch is consumed on the message-`0` service path inside the family handler at `0x00512202` through the `0x00512c09` branch.","objdump + caller inspection + nearby-family correlation + singleton correlation + service-path inspection" +0x0050f760,45,shell_trainbuy_window_query_selected_locomotive_id,shell,cdecl,inferred,objdump + caller inspection + strings correlation,4,"Returns the currently selected locomotive id or `0` when the shell-side `Trainbuy.win` family has no valid active selection. The helper first checks whether the live singleton at `0x006d3ac8` exists and whether control resource `0x2afe` exposes one nonnegative selected row through `0x0055fba0`; on success it returns that selected locomotive id. Current grounded callers include the route, upgrade-cost, and purchase-confirmation branches inside `shell_trainbuy_window_handle_message`, where this value is then resolved through the locomotive collection at `0x006ada84`.","objdump + caller inspection + strings correlation + selected-row correlation" +0x0050f790,241,shell_trainbuy_window_compute_selected_upgrade_total_and_count,shell,thiscall,inferred,objdump + caller inspection + RT3.lng strings,4,"Computes the current selected-train upgrade summary beneath the shell-side `Trainbuy.win` family. The helper counts all flagged train entries in the `0x2000`-byte selection array rooted at `0x006d1aa8`, resolves the currently selected locomotive choice through `shell_trainbuy_window_query_selected_locomotive_id` at `0x0050f760`, and then multiplies the resulting selected-train count by the per-train upgrade cost from `0x004619c0` after converting the current and target locomotive ids through `0x004337b0` and `0x004337a0`. It writes the total upgrade cost through the first out-parameter and the number of selected trains through the second. Current grounded callers are the summary formatter at `0x0050f890` and the purchase-or-upgrade confirmation path inside `shell_trainbuy_window_handle_message`.","objdump + caller inspection + RT3.lng strings + selection-array correlation + upgrade-cost correlation" +0x0050f890,368,shell_trainbuy_window_render_selected_train_upgrade_summary,shell,cdecl,inferred,objdump + caller inspection + RT3.lng strings,4,"Formats the selected-train upgrade summary text in the shell-side `Trainbuy.win` family. After resolving the currently selected locomotive id through `shell_trainbuy_window_query_selected_locomotive_id` at `0x0050f760`, the helper calls `shell_trainbuy_window_compute_selected_upgrade_total_and_count` at `0x0050f790` and then builds the player-facing status string from localized ids `1338` `No trains currently selected to upgrade.`, `1339` `Total Cost to Upgrade the %1 Selected Trains to %2 is %3.`, and `1340` `Total Cost to Upgrade the 1 Selected Train to %1 is %2.`. It publishes the resulting heap-backed text through the callback-driven shell control path rooted at control resource `0x275c`. Current grounded callers are the family refresh path at `0x00511500` and the row-selection branch at `0x00512ac7`.","objdump + caller inspection + RT3.lng strings + upgrade-summary correlation" +0x0050fc00,1003,shell_trainbuy_window_render_selected_train_route_and_state_panel,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Renders the richer selected-train detail panel beneath the shell-side `Trainbuy.win` family. The helper resolves the currently selected train and its linked locomotive definition, formats one header block through the shared shell text path at `0x005519f0`, and then builds the lower route or cargo state block through `0x0053de00`, `0x0041d540`, and `0x00552560`. When the runtime latch at `[0x006cec74+0x180]` is set it also appends up to three localized fragments through ids `1341..1343`, gated by bytes `[train+0x30..0x32]`, before laying the final text out. Current grounded callers are the per-row hover or selection refresh paths beneath `Trainbuy.win`; the evidence is strong enough to treat it as the selected-train route-and-state renderer even though the exact player-facing captions for the three optional fragments are still unrecovered.","objdump + caller inspection + nearby-family correlation + selected-train correlation" +0x00511500,2941,shell_trainbuy_window_construct,shell,thiscall,inferred,objdump + caller inspection + strings correlation,4,"Constructs the shell-side `Trainbuy.win` singleton later published at `0x006d3ac8`. The constructor binds the window resource through `0x0053fa50`, caches three shell runtime handles in `0x006d3abc..0x006d3ac4`, seeds the live singleton pointer at `0x006d3ac8`, builds one filtered locomotive-choice list under `0x006d3ae8`, and then wires the family controls and callbacks through `0x00540120`. Current grounded control ownership is broad enough to treat this as the full `Trainbuy.win` family rather than a small helper: it binds the main action and selection controls under resources `0x2afa..0x2aff`, the selected-train summary path through `shell_trainbuy_window_render_selected_train_upgrade_summary` at `0x0050f890`, the per-row hover helpers at `0x0050fa00` and `0x0050fc00`, the selected-row refresh helper at `0x00511170`, and the selection-paging helper at `0x00512080`. Current grounded caller is `shell_open_or_focus_trainbuy_window` at `0x00512c50`.","objdump + caller inspection + strings correlation + control-wiring inspection + singleton correlation" +0x00512080,372,shell_trainbuy_window_refresh_controls,shell,thiscall,inferred,objdump + caller inspection + strings correlation,4,"Refreshes the visible control state for the shell-side `Trainbuy.win` family. The helper consumes and clears the temporary refresh gate at `0x006d3ae1`, clamps the current selected locomotive-row index from control resource `0x2aff` against the live filtered choice list length at `0x006d3aec`, rewrites the list-selection state across control `0x88`, updates the current mode-strip and list-state controls rooted at `0x00622b28`, and then tail-calls the selected-row detail refresher at `0x00511170`. Current grounded callers are the family constructor at `0x00511500`, the action path after row or mode changes inside `shell_trainbuy_window_handle_message`, and the initial open path in `shell_open_or_focus_trainbuy_window` at `0x00512dd5`.","objdump + caller inspection + strings correlation + list-state correlation" +0x00512c50,615,shell_open_or_focus_trainbuy_window,shell,cdecl,inferred,objdump + caller inspection + strings correlation + RT3.lng strings,4,"Shared opener for the shell-side `Trainbuy.win` singleton rooted at `0x006d3ac8`. The helper first rejects duplicate opens through the live flag at `0x006d3ae4`, seeds the family globals `0x006d3ad0..0x006d3ad8`, `0x006d3acc`, `0x006d3aa8`, `0x006d1aa0`, `0x006d1aa4`, `0x006d3af0`, `0x006d3af4`, `0x00622b24`, and the filtered locomotive-choice list at `0x006d3ae8`, allocates an `0x80`-byte shell window object, constructs it through `shell_trainbuy_window_construct` at `0x00511500`, refreshes it through `shell_trainbuy_window_refresh_controls` at `0x00512080`, and publishes it to the shell runtime at `0x006d401c`. Current grounded callers are the direct train-buy shell command branches at `0x004406ee` and `0x004de7f4` after `shell_can_open_trainbuy_window_or_warn` at `0x00433b00`, plus the sibling train-side action family around `0x00514c97` and `0x00514d7e`. The current family semantics are broader than a bare locomotive picker: nearby message and summary paths show that the same window also stages selected-train upgrade state and train-route editing affordances, but the strongest resource-name anchor remains `Trainbuy.win`.","objdump + caller inspection + strings correlation + RT3.lng strings + singleton correlation + control-family correlation" +0x00512f80,193,shell_trainbuy_window_refresh_selection_side_toggle,shell,thiscall,inferred,objdump + caller inspection + control-flow inspection,4,"Refreshes the small side-toggle strip beneath `Trainbuy.win` and stores the chosen side in `0x006d3b28`. The helper converts the caller-supplied boolean into two opposing style states on controls `0x6593` and `0x6594`, rewrites one small layout block through `0x0053fe90`, and keeps the current side latched for the surrounding message paths that call it with `0` and `1` at `0x00514fed` and `0x00514fd8`. Current grounded caller is the neighboring train-side window family rooted at `0x006d3b20`, which reuses the same selected-train context but is not yet safely named.","objdump + caller inspection + control-flow inspection + side-toggle correlation" +0x005130f0,62,shell_trainbuy_window_query_selected_train_record,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Returns the currently selected train record or `0` when the active shell detail controller at `0x006d0818` does not hold one valid train id in `[this+0x90]`. The helper validates that selected id against the train collection at `0x006cfcbc` and then resolves the live record through `0x00518140`. Current grounded callers include the neighboring train-side shell window family around `0x005146d6`, `0x00514ce2`, and `0x00515176`, which repeatedly reuse the same selected-train pointer for route, upgrade, and warning flows.","objdump + caller inspection + nearby-family correlation + selected-train correlation" +0x00513130,51,shell_trainbuy_window_query_selected_train_id,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Returns the currently selected train id from the active shell detail controller at `0x006d0818` when that id is positive and still present in the train collection at `0x006cfcbc`; otherwise returns `-1`. Current grounded callers are the same neighboring train-side shell families that package selected-train requests for local and multiplayer follow-on work.","objdump + caller inspection + nearby-family correlation + selected-train-id correlation" +0x00513170,44,shell_trainbuy_window_has_valid_selected_train,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Boolean validity probe above `shell_trainbuy_window_query_selected_train_id`. The helper returns `1` only when the active shell detail controller at `0x006d0818` currently holds one positive train id in `[this+0x90]` and that id is still live in the train collection at `0x006cfcbc`. Current grounded callers include the train-side command family around `0x00514c66`, `0x00514cb5`, `0x00514d9c`, and `0x0051515c`, where it gates nearly every selected-train verb before deeper ownership or route checks run.","objdump + caller inspection + nearby-family correlation + selected-train-id correlation" +0x005131a0,125,shell_trainbuy_window_selected_train_belongs_to_selected_company,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Boolean ownership probe for the currently selected train. After resolving the selected train record through the same `0x006d0818` plus `0x006cfcbc` path as `shell_trainbuy_window_query_selected_train_record`, the helper compares that record's linked company id at `[train+0x51]` against the current scenario-selected company from `0x004337a0`. It returns `1` only when they match. Current grounded callers include the neighboring train-side command family, where failure falls into the explicit warning path at `0x00513220`.","objdump + caller inspection + nearby-family correlation + company-match correlation" +0x00513220,351,shell_trainbuy_window_warn_selected_train_not_owned_by_current_company,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Shared warning modal raised when a selected train does not belong to the current scenario-selected company. The helper resolves one player-facing label through `0x004a8bd0` when a live selected train exists, falls back to the static string block at `0x005c87a8` otherwise, formats localized id `0x250`, and then opens the standard callback-driven shell modal through `shell_open_custom_modal_dialog_with_callbacks` at `0x004c98a0`. Current grounded caller is the ownership-failure branch immediately after `shell_trainbuy_window_selected_train_belongs_to_selected_company` at `0x00514a35`.","objdump + caller inspection + nearby-family correlation + modal correlation" +0x00513720,168,shell_trainbuy_window_refresh_selection_column_empty_state_labels,shell,thiscall,inferred,objdump + caller inspection + control-flow inspection,4,"Refreshes the paired empty-state labels and styles on controls `0x65a1` and `0x65a2`. The helper inspects the currently active side resource `0x65a3/0x65a4`, checks whether its list selection at `[resource+0x1d6]` is negative, and then switches the two visible placeholder strings between localized ids `0x25b..0x25e` while also rewriting both controls' styles through `0x00540120`. Current grounded callers are the neighboring train-side shell window family constructor at `0x005145f3` and the row-selection action lane at `0x005148f3`.","objdump + caller inspection + control-flow inspection + placeholder-label correlation" +0x00514110,67,shell_train_detail_window_refresh_selected_train_name_label,shell,cdecl,inferred,objdump + caller inspection + strings correlation,4,"Small dynamic-label refresher beneath the shell-side `TrainDetail.win` family rooted at `0x006d3b20`. After validating the currently selected train id from the shell detail controller at `0x006d0818`, the helper resolves control `0x659d` inside the live `TrainDetail.win` singleton and forwards the caller-supplied subject string through `0x004bffc0`. Current grounded caller is the family constructor at `0x00514420`, which binds this helper as the dynamic-text callback for control `0x659d`.","objdump + caller inspection + strings correlation + callback binding" +0x00514160,704,shell_train_detail_window_refresh_controls,shell,thiscall,inferred,objdump + caller inspection + strings correlation,4,"Refreshes the visible control state for the shell-side `TrainDetail.win` family rooted at `0x006d3b20`. The helper rewrites the two top selection bands `0x65a3` and `0x65a4` from the current side latch at `0x006d3b24`, rebuilds the selected train's nested row state from the current train record resolved through the shell detail controller at `0x006d0818`, installs the per-row callbacks and renderers for the metric rows `0x65b6`, `0x65b9`, `0x65bc`, and `0x65bf`, updates the placeholder and summary text controls `0x659a`, `0x659b`, and `0x659d`, and then refreshes the current row selection plus the paired empty-state labels through `0x004bf320` and `shell_trainbuy_window_refresh_selection_column_empty_state_labels` at `0x00513720`. Current grounded callers are the family constructor at `0x00514420`, the opener at `0x00514620`, and several action paths inside the family message dispatcher at `0x00514690`.","objdump + caller inspection + strings correlation + callback binding + row-state correlation" +0x00514420,512,shell_train_detail_window_construct,shell,thiscall,inferred,objdump + caller inspection + strings correlation,4,"Constructs the shell-side `TrainDetail.win` singleton later published at `0x006d3b20`. The constructor seeds the local vtable at `0x005d1990`, caches three shell runtime handles in `0x006d3b14..0x006d3b1c`, binds the `TrainDetail.win` resource directly through `0x0053fa50` using the embedded string at `0x005d19c0`, and then wires the family controls and callbacks through `0x00540120`. Current grounded bindings are broad enough to treat this as the full `TrainDetail.win` family: it installs row-click callbacks on `0x65a3` and `0x65a4`, metric renderers on `0x65ab` and `0x65ac`, the selected-train callback on `0x659c`, the dynamic-name label callback on `0x659d`, seeds the side-toggle state through `shell_trainbuy_window_refresh_selection_side_toggle` at `0x00512f80`, and then refreshes the full window through `shell_train_detail_window_refresh_controls` at `0x00514160`. Current grounded callers are the shell detail-panel transition manager at `0x004ddda1` and the direct opener at `0x00514620`.","objdump + caller inspection + strings correlation + callback binding + singleton correlation" +0x00514620,110,shell_open_or_focus_train_detail_window,shell,thiscall,inferred,objdump + caller inspection + strings correlation,4,"Shared opener or focus path for the shell-side `TrainDetail.win` singleton. When the caller supplies one valid train id present in the train collection at `0x006cfcbc`, the helper can seed the selected train subject through `0x004a7390`; when a live `TrainDetail.win` singleton already exists at `0x006d3b20` and the current shell runtime subject matches the incoming one, it simply refreshes that window and pings the shell runtime. Current grounded direct caller is the surrounding shell command path at `0x0046cbda`, and the existing constructor edge at `0x004ddda1` confirms that this opener sits above the same `TrainDetail.win` family rather than the neighboring `Trainbuy.win` singleton.","objdump + caller inspection + strings correlation + singleton correlation" +0x00514690,1920,shell_train_detail_window_handle_message,shell,thiscall,inferred,objdump + caller inspection + control-flow inspection + RT3.lng strings,4,"Primary message dispatcher for the shell-side `TrainDetail.win` family rooted at `0x006d3b20`. The handler processes shell messages `0`, `0xca`, `0xcb`, and the recurring service message `0x3e9`; routes the top-level side-toggle, list-selection, and metric-row controls through a dispatch table over resources `0x659c..0x6947`; repeatedly reuses the currently selected train via the helper family at `0x005130f0..0x00513220`; and fans out into several now-bounded train verbs. Current explicit branches include one selected-train engine-replacement or trainbuy handoff lane that checks scenario gate `[0x006cec78+0x4a97]`, raises localized ids `593` `That action is not allowed in this scenario.` and `594` `You can not replace the engine while the train is broken-down.` on failure, and otherwise re-enters `shell_open_or_focus_trainbuy_window` at `0x00512c50` or the neighboring local follow-on path at `0x00436820`; one selected-train retirement lane that checks `[0x006cec78+0x4a9b]`, rejects blocked states through ids `595` and `597`, confirms through id `596`, and then either tears the train down locally through the train collection plus `shell_detail_panel_transition_manager` mode `2` or packages multiplayer opcode `0x37`; plus one tighter route-edit lane over the shared `0x33`-stride route-entry family, where removal re-enters `train_route_list_remove_entry_and_compact` at `0x004b3000` and staged insertion re-enters `train_route_list_insert_staged_entry_at_index` at `0x004b3160`, then validates the resulting route through `train_route_list_validate_reachability_and_station_pair` at `0x004b2c10` and commits the follow-on train state through `train_set_route_operating_mode_and_scalar` at `0x004ab980`, with multiplayer opcode mirrors `0x3d`, `0x3f`, and `0x41`. It also consumes the family refresh path through `shell_train_detail_window_refresh_controls` at `0x00514160`. Current evidence is broad enough to treat this as the full `TrainDetail.win` message owner even though several deeper per-action verbs remain semantically open.","objdump + caller inspection + control-flow inspection + dispatch-table inspection + selected-train helper correlation + RT3.lng strings" +0x004a9460,65,train_current_route_context_uses_strict_reachability_mode,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Small boolean gate keyed off the train's current linked route object at `[this+0x41]`. The helper resolves that route object through `0x0062ba84`, follows its class or profile reference through `0x0041adb0`, uses the resulting id at `[profile+0x126]` to query the small class table rooted at `0x006ada84`, and returns `1` only when the final type field at `[entry+0x10]` equals `2`. Current grounded callers include the local and multiplayer route-entry insertion success paths at `0x00515430` and `0x004718fe`, where a true result triggers the stricter second `train_route_list_validate_reachability_and_station_pair` pass before mode `0x13` is selected, and several neighboring simulation branches such as `0x004ad5e2` and `0x004b1ec5` that use the same gate before re-entering the stronger route-state path. Current evidence is therefore tight enough to treat this as a shared current-route-context gate for the stricter reachability or operating-mode family even though the player-facing meaning of class type `2` remains open.","objdump + caller xrefs + callsite inspection + route-context correlation" +0x004a94b0,381,train_finalize_aux_route_entry_buffer_preserving_subflags,simulation,thiscall,inferred,objdump + caller xrefs + route-entry inspection,3,"One train-side cleanup or finalize helper over the auxiliary route-entry wrapper at `[this+0x1c6]`. When that wrapper is present, the helper walks the embedded `0x33`-stride route-entry list rooted at `[aux+0x0c]`, rewrites one bounded payload band back into the selected entries, and explicitly preserves route-entry flag bits `0x40`, `0x20`, and `0x10` in byte `+0x28` across the rewrite. It then frees the auxiliary wrapper through `0x005a1145` and clears `[this+0x1c6]`. Current grounded caller is the larger train-side route-state branch at `0x004b0cf0`, where this helper sits behind the scenario-state gate at `0x00434050` and ahead of the later current-route-entry resolution path. Current evidence is therefore strong enough to treat this as an auxiliary route-entry buffer finalize step that preserves the lower route-entry subflags even though the exact player-facing meaning of those bits remains open.","objdump + caller xrefs + route-entry inspection + auxiliary-buffer correlation" +0x004ab980,760,train_set_route_operating_mode_and_scalar,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Shared train-side mode setter beneath route editing and adjacent operating-state transitions. The helper clears several transient route-state fields at `[this+0x55]`, `[this+0x59]`, `[this+0x5d]`, and `[this+0x1a7]`, optionally rounds the caller-supplied scalar argument to an integer when the scenario-state gate at `0x00434050` is active, dispatches over mode ids `0..0x13`, and in several branches toggles the train byte at `[this+0xf4]` across the linked route-object chain rooted at `[this+0x41]` before notifying follow-on state refresh helpers `0x004a8100` or `0x004a81b0`. Every successful path writes the chosen mode id to `[this+0xe8]` and the final scalar to `[this+0xec]`. Current grounded callers include the local and multiplayer route-entry insertion success path at `0x004718a0` and `0x00515450`, which select mode `0x13` after the stricter post-insertion validation succeeds and mode `0x0a` after the looser fallback path. Current evidence is therefore tight enough to treat this as the shared train route operating-mode and scalar setter even though the player-facing names of the individual mode ids remain open.","objdump + caller xrefs + callsite inspection + mode-write correlation + route-edit correlation" +0x004b2b80,29,train_route_list_count_live_site_reference_entries,simulation,thiscall,inferred,objdump + caller xrefs + route-entry inspection,4,"Counts the subset of entries in the same train-owned `0x33`-stride route-entry list whose flag byte at `+0x28` is nonnegative. Current grounded callsites make that sign-bit split meaningful: sign bit clear entries are the live placed-structure-backed family, while sign bit set entries use the direct route-node payload side instead. Current callers include the shell-side formatter branches at `0x004be50c` and `0x004be53c`, plus the train purchase or readiness path at `0x005126c2`, where the count must reach at least `2` before the deeper route validation lane is allowed to continue. Current evidence is therefore tight enough to treat this as the shared count of live site-reference route entries rather than a generic row counter.","objdump + caller xrefs + route-entry inspection + callsite inspection" +0x004b2c10,656,train_route_list_validate_reachability_and_station_pair,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection + RT3.lng strings,4,"Shared route validator above the train route-entry insertion and edit family. The helper walks the same train-owned `0x33`-stride route-entry list and splits on route-entry flag byte `+0x28`: sign bit clear entries resolve live placed-structure ids from field `+0x29` through the placed-structure collection at `0x006cec20` before mapping those structures into the route-node collection at `0x006cfca8`, while sign bit set entries take one direct route-node payload from field `+0x2b`. It then re-enters `0x004a6630` for each successive route step and one optional caller-supplied external target. While scanning, it also tracks up to two distinct station-like placed-structure ids through `0x0047fd50`; the final result fails when any placed structure or route node cannot be resolved, when any `0x004a6630` sweep leaves the output marker at `-1`, or when the scan never accumulates both ends of that station pair. Current grounded callers include the local and multiplayer insertion paths at `0x004718a0` and `0x00515450`, where failure leads to localized route warnings `3089` `At least one station on the route is not connected to the others.`, `3090` `This train cannot reach the station you've selected.`, and `3091` `This train cannot reach the track waypoint you've selected.`. Current evidence is therefore tight enough to treat this as the shared route reachability and terminal-station-pair validator rather than a generic list scan.","objdump + caller xrefs + callsite inspection + RT3.lng strings + placed-structure correlation + route-warning correlation + route-entry flag split" +0x004b2f00,250,train_route_list_select_entry_and_refresh_linked_site_state,simulation,thiscall,inferred,objdump + caller xrefs + state-layout inspection,4,"Shared selector helper for one train-owned route-entry list whose records are `0x33` bytes wide. The helper clamps the requested selected index against the current count at `[this+0x4]`, stores the new selection in `[this+0x8]`, and only when route-entry flag byte `+0x28` has its sign bit clear does it extract the previous and new placed-structure ids from field `+0x29` and forward that old/new site pair into `0x004819b0`; sign bit set entries skip that placed-structure extraction path. It then refreshes the linked train-side state through `0x004abca0`, `0x004ad260`, and `0x004b2ea0`. When the caller requests it, it also marks the owning train record's byte `[train+0x1b9]`. Current grounded callers include the local `TrainDetail.win` route-entry branch at `0x00514a96`, the multiplayer-side route-entry handlers at `0x00471730` and `0x004097f9`, and the removal helper `train_route_list_remove_entry_and_compact` at `0x004b3000`. The same route family is now also tied to localized reachability warnings `3089..3091`, so this reads as a train route-stop or waypoint selection helper rather than a generic row selector.","objdump + caller xrefs + state-layout inspection + placed-structure-id correlation + route-warning correlation + route-entry flag split" +0x004b3000,341,train_route_list_remove_entry_and_compact,simulation,thiscall,inferred,objdump + caller xrefs + state-layout inspection,4,"Removes one entry from the same `0x33`-stride train-owned route list and compacts the remaining records. The helper validates the caller-supplied index against current count `[this+0x4]`, repairs the selected index `[this+0x8]`, re-enters `train_route_list_select_entry_and_refresh_linked_site_state` at `0x004b2f00` when the removed row was the selected one, allocates a shorter replacement buffer, copies the prefix and suffix segments around the removed row, decrements the list count, frees the old buffer, and then refreshes the linked train-side state through `0x004abca0`, `0x004ad260`, and `0x004b2ea0`. Current grounded callers include the local `TrainDetail.win` route-entry removal branch at `0x00515211` and the multiplayer-side handler at `0x00471823`.","objdump + caller xrefs + state-layout inspection + compacting-buffer correlation + route-list correlation" +0x004b3160,530,train_route_list_insert_staged_entry_at_index,simulation,thiscall,inferred,objdump + caller xrefs + state-layout inspection + RT3.lng strings,4,"Inserts one staged `0x33`-byte route-entry record into the same train-owned route list at one caller-selected index. Before insertion the helper seeds parts of the staged record from the prior terminal route entry and preserves the currently grounded lower route-entry subflags `0x40`, `0x20`, and `0x10` in field `+0x28`. That same flag byte also carries the top-level entry split: sign bit clear entries use one live placed-structure id in field `+0x29`, while sign bit set entries use one direct route-node payload in field `+0x2b`. Only the live site-reference branch can re-enter the narrower tutorial gate `tutorial_validate_train_route_station_indicator_step` at `0x00516d00`, and only when the staged placed-structure id is station-or-transit-like and the shell tutorial family rooted at `0x006d3b4c` is active. The helper then allocates a `(count+1)` replacement buffer, copies the prefix rows, writes the staged record at the requested insertion index, copies the suffix rows, frees the old buffer, bumps the count, repairs the selected index, and refreshes the linked train-side state. Current grounded callers include the local `TrainDetail.win` insertion or staging branch at `0x00515417`, the multiplayer-side handlers at `0x004718e5` and `0x004097eb`, and the nearby validation path that surfaces localized reachability warnings `3090` `This train cannot reach the station you've selected.` and `3091` `This train cannot reach the track waypoint you've selected.`. Current evidence is therefore tight enough to treat this as the route-stop or waypoint insertion helper above that validation family rather than as a generic record copier.","objdump + caller xrefs + state-layout inspection + RT3.lng strings + insertion-buffer correlation + route-warning correlation + route-entry flag split + subflag preservation" +0x00516be0,284,tutorial_advance_step_and_refresh_expected_control_ids,shell,cdecl,inferred,objdump + caller xrefs + local disassembly + tutorial-table inspection,4,"Advances one active shell tutorial step and refreshes the small expected-control cache under `0x00622b34..0x00622b3c`. The helper first returns immediately when the tutorial-active flag at `0x006d3b4c` is zero; otherwise it increments the current tutorial step index at `0x006d3b50`, consults the `0x40`-byte descriptor table rooted at `0x00622b48`, and skips several currently grounded step codes when their extra world or shell-state predicates fail. After choosing the next live step it copies the previous expected control id from `0x00622b34` into `0x00622b38`, then loads the new expected control id and one current alternate-accepted control id from descriptor offsets `+0x34` and `+0x38` into `0x00622b34` and `0x00622b3c`. Current shell-command correlation is now tight enough to support that narrower reading: the generic shell control path around `0x004de199` and `0x004de724` compares incoming control ids directly against `0x00622b3c` and suppresses the tutorial-only `3587` rejection when they match, which makes `0x00622b3c` look like a current companion control id rather than a page or mode selector. The helper also rate-limits one small shell-side nudge through `0x0045ea20` while the tutorial runs. Current grounded callers are the generic shell control path at `0x00540cca` and the train-route tutorial validator at `0x00516d93`, which makes this the current best owner for the tutorial step-advance and expected-control cache instead of leaving `0x00622b34/38/3c` as anonymous globals.","objdump + caller xrefs + local disassembly + tutorial-table inspection + control-cache correlation + shell-command correlation" +0x00516d00,143,tutorial_validate_train_route_station_indicator_step,shell,thiscall,inferred,objdump + caller xrefs + callsite inspection + nearby-state inspection + RT3.lng strings,4,"Small shell-side tutorial gate used before one live station-or-transit site id is committed into the train route-entry list. The helper only matters while the tutorial state family rooted at `0x006d3b4c` is active: it consults the current tutorial step index at `0x006d3b50`, reads that step's code from the `0x40`-byte tutorial descriptor table rooted at `0x00622b48`, and accepts only the currently grounded step codes `0x172` and `0x17c`, which align with localized tutorial prompts `3777` `Click on the yellow station indicator for Milan.` and `3778` `Now click on the station indicator for Turin`. For accepted steps it stages the caller-supplied site id into `0x006d3b5c` and, in the second step, advances the surrounding tutorial state through `0x00516be0` only when the incoming site differs from the currently staged one. For incompatible tutorial steps it opens one callback-driven shell modal through `0x004c98a0` and returns `0`, which causes `train_route_list_insert_staged_entry_at_index` at `0x004b3160` to abort before the record is inserted. Current evidence is therefore tight enough to treat this as the tutorial-side train-route station-indicator validator rather than a general `TrainDetail.win` row-kind gate.","objdump + caller xrefs + callsite inspection + nearby-state inspection + RT3.lng strings + modal correlation" +0x00517d40,66,indexed_collection_entry_id_is_live,simulation,thiscall,inferred,objdump + caller inspection + collection-bitset inspection,4,"Shared indexed-collection presence test over the common collection layout that uses `[this+0x14]` as the upper id bound and `[this+0x34]` as the tombstone or disabled-bitset. The helper rejects nonpositive or out-of-range ids and otherwise returns `1` only when the bit for the requested id is clear, i.e. when the entry is currently live. Current grounded callers include `shell_building_detail_refresh_subject_cargo_and_service_rows` `0x004ba3d0`, where it guards ordinary candidate ids before `indexed_collection_resolve_live_entry_by_id` `0x00518140`, and neighboring collection walkers that treat the same ids as positive live-record selectors rather than zero-based dense ordinals.","objdump + caller inspection + collection-bitset inspection + callsite correlation" +0x00517cf0,3,indexed_collection_slot_count,simulation,thiscall,inferred,objdump + caller inspection + collection-layout inspection,4,"Tiny shared accessor that returns the current slot-count field `[this+0x18]` from the common indexed-collection layout. Current grounded callers use it as the upper bound for zero-based slot walks before resolving one nth live entry id through `indexed_collection_get_nth_live_entry_id` `0x00518380`.","objdump + caller inspection + collection-layout inspection + slot-walk correlation" +0x00518140,89,indexed_collection_resolve_live_entry_by_id,simulation,thiscall,inferred,objdump + caller inspection + collection-layout inspection,4,"Shared indexed-collection record resolver over the same common collection layout. The helper rejects nonpositive, out-of-range, or tombstoned ids through the `[this+0x14]` bound and `[this+0x34]` bitset, then returns one live record pointer from the payload rooted at `[this+0x30]`. When collection flag dword `[this+0x04]` is nonzero it treats that payload as a flat `stride=[this+0x08]` record array and returns `base + stride*id`; otherwise it treats the payload as an array of record pointers stored in `stride=[this+0x08]` slots and returns the pointer loaded from `base + stride*id`. Current grounded callers include the company, profile, train, and structure-candidate families, where it is the common bridge from one positive collection id to one concrete live record pointer.","objdump + caller inspection + collection-layout inspection + direct-vs-indirect payload correlation" +0x00518380,364,indexed_collection_get_nth_live_entry_id,simulation,thiscall,inferred,objdump + caller inspection + collection-layout inspection,4,"Shared nth-live-entry selector over the same indexed-collection layout. With traversal mode `0` it walks slot ids in forward order, skipping tombstoned ids through the bitset at `[this+0x34]`, and returns the positive entry id whose zero-based live ordinal matches the caller-supplied index; recent results are memoized in the small cache bands rooted at `[this+0x68]` and `[this+0x78]`. With nonzero traversal mode it reuses the auxiliary link banks rooted at `[this+0x38]`, `[this+0x48]`, and `[this+0x58]` to step through one alternate live-order chain before returning the resulting id. Current grounded callers across company, profile, structure-candidate, and placed-structure families mostly use traversal mode `0`, where this is the shared bridge from one zero-based live ordinal to one positive collection entry id.","objdump + caller inspection + collection-layout inspection + cache-band inspection + alternate-chain correlation" +0x0051c920,223,localization_lookup_display_label_by_stem_or_fallback,shell,thiscall,inferred,objdump + caller inspection + language-table correlation + static-table inspection,4,"Shared shell-side label helper that turns one ASCII stem string into one player-facing display label. The helper case-folds the first letter, scans the static `(stem, string-id)` table rooted at `0x006243c8`, compares candidate stems case-insensitively, and returns the localized text for the first matching string id through `0x005193f0` when that localized entry is nonempty. The current table correlation already grounds entries such as `Alcohol`, `Aluminum Mill`, `Automobiles`, `Bauxite`, and `Big Boy` against RT3.lng ids `3202..3220`. When no table entry matches, the helper falls back to localized id `3866` `Could not find a translation table entry for '%1'`. Current grounded callers include `shell_building_detail_refresh_subject_cargo_and_service_rows` `0x004ba3d0`, where it sits directly above candidate field `[record+0x04]`, and several neighboring list and detail renderers that need one display label from the same stem family.","objdump + caller inspection + language-table correlation + static-table inspection + RT3.lng correlation" +0x004f2e80,14,shell_has_live_overview_window,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Tiny presence probe for the shell-side `Overview.win` singleton rooted at `0x006d12bc`. The helper returns `1` when that live overview object pointer is nonnull and `0` otherwise. Current grounded callers include the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, where it sits beside other shell-window probes, and the overview family itself around `0x004f3a10`, which uses the same singleton to suppress duplicate opens.","objdump + caller inspection + nearby-family correlation + singleton correlation" +0x004f2e90,11,shell_mark_overview_window_dirty,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Tiny dirty-latch setter paired with `shell_has_live_overview_window`. The helper stores `1` into `0x006d12cc`, which current nearby call patterns treat as the `Overview.win` refresh or service request latch once the live overview singleton at `0x006d12bc` exists. Current grounded caller is the same post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`.","objdump + caller inspection + nearby-family correlation + singleton correlation" +0x004f38a0,67,shell_overview_window_construct,shell,thiscall,inferred,objdump + caller inspection + strings correlation,4,"Constructs the shell-side `Overview.win` object later published at `0x006d12bc`. The constructor seeds the local vtable at `0x005d1368`, binds the shell window resource through `0x0053fa50`, clears the selected subject field at `[this+0x7c]`, and installs the shared control callback `0x004f3880` on control `0x88bf`. Current grounded caller is `shell_open_or_focus_overview_window` at `0x004f3a10`, and current string-table correlation leaves `Overview.win` as the strongest owner name for this singleton family.","objdump + caller inspection + strings correlation + singleton correlation" +0x004f38f0,562,shell_overview_window_handle_message,shell,thiscall,inferred,objdump + caller inspection + control-flow inspection,4,"Primary message dispatcher for the shell-side `Overview.win` family rooted at `0x006d12bc`. The handler processes the usual shell message ids `0`, `0xca`, and `0xcb`; uses the current subject object at `[this+0x78]`; opens follow-on detail lanes through `0x004f2ea0`; and raises simple shell modals through `shell_open_custom_modal_dialog_with_callbacks` `0x004c98a0` when the requested drill-down path is currently invalid. It also consumes the family dirty latch at `0x006d12cc` on the recurring service path. Current grounded caller is the shell runtime after construction through `shell_open_or_focus_overview_window`.","objdump + caller inspection + control-flow inspection + dirty-latch correlation" +0x004f3a10,272,shell_open_or_focus_overview_window,shell,cdecl,inferred,objdump + caller inspection + strings correlation,4,"Shared opener for the shell-side `Overview.win` singleton. When a valid overview subject exists under the live world-side owner at `0x006cea4c` and no current overview window is open, the helper allocates an `0x80`-byte shell object, constructs it through `shell_overview_window_construct` at `0x004f38a0`, publishes it through the shell runtime at `0x006d401c`, and stages the selected subject pointer into the live singleton at `0x006d12bc` before routing it into the family message path at `0x004f2ea0`. When an overview window already exists it leaves the current singleton in place. Current grounded callers include the world-side action branches at `0x004396ae` and `0x004414c6`, both of which pass one subject object resolved from `0x006cea4c` before opening the overview path.","objdump + caller inspection + strings correlation + singleton correlation + publish-path inspection" +0x004b99c0,88,structure_candidate_collection_get_nth_active_candidate_id,map,cdecl,inferred,objdump + caller inspection + collection iteration,4,"Returns the zero-based nth active candidate id from the structure-candidate collection at `0x0062ba8c`. The helper iterates the collection through `0x517cf0` and `0x518380`, skips candidates whose active byte in the returned record is clear, decrements the caller-supplied ordinal only across the surviving entries, and finally returns the matching candidate id or `0` when the requested active slot does not exist. Current grounded callers are the shell-side building-detail branches at `0x004ba01f`, `0x004bbcfd`, and `0x004bbd56`, where ordinals `page-3` are translated back into live candidate ids before the selected-building service and capability rows are refreshed.","objdump + caller inspection + collection iteration + active-candidate correlation" +0x004b9a20,833,shell_building_detail_refresh_flagged_service_capability_rows,shell,thiscall,inferred,objdump + caller inspection + control-range inspection,3,"Shared `BuildingDetail.win` refresh helper for the flagged service or capability row bands driven from the currently selected building subject at `0x006cfe04`. The helper repeatedly restyles controls in the `0x7d07..0x7d1c` range through `0x540120`, using route-entry flag byte `+0x28` from the selected building subject as the decision source. Current local control correlation now bounds that mask family more tightly than a generic bit consumer: `0x7d07/0x7d08` split the zero-versus-nonzero `0x30` mask, `0x7d11/0x7d12` split the bit-`0x20`-only case, `0x7d13/0x7d14` split the exclusive-or `0x20^0x10` case, `0x7d17/0x7d1a` track bit `0x20`, `0x7d18/0x7d1b` track bit-`0x10`-only, and `0x7d19/0x7d1c` track the combined `0x30` case. The later repeated row family rooted at `0x7f58..0x801f` also consults bit `0x40` together with the currently selected candidate or service id in subject field `+0x24`, but current evidence now narrows that lane too: it is a selected-ordinal highlight band rather than a generic restyle loop. The special express-side triplet at `0x7f58..0x7f5a` is the fixed table-driven branch; after that the helper falls through into the ordinary active-candidate/service rows. When the selected id is below `0x384`, the helper translates it through `structure_candidate_collection_get_nth_active_candidate_id` at `0x004b99c0` and highlights ordinal `3 + active-candidate-rank` for the current subject id; otherwise it treats `0x384..` as the parallel express-side family directly. Current grounded callers include the broader building-detail refresh path at `0x004bae97`, the constructor-adjacent refreshes at `0x004bbcf3` and `0x004bbd0d`, and neighboring handler branches at `0x004bb8e3`, `0x004bbe5c`, and `0x004bc039`. Current evidence is therefore strong enough to treat this as the shared shell-side consumer of route-entry subflags `0x10`, `0x20`, and `0x40` even though the ordinary candidate-row captions still remain open.","objdump + caller inspection + control-range inspection + route-entry flag correlation + active-candidate correlation + control-family triplet correlation + row-mask partition correlation + selected-ordinal highlight correlation" +0x004ba3d0,2380,shell_building_detail_refresh_subject_cargo_and_service_rows,shell,thiscall,inferred,objdump + caller inspection + strings correlation,3,"Large `BuildingDetail.win` refresh helper for the selected subject row families centered on controls `0x7d06`, `0x7d96..`, `0x7d0e`, and the adjacent `0x7d6a/0x7d6b` and `0x7d9d` visual lanes. The helper walks the selected building subject at `0x006cfe04`, iterates the per-subject id list rooted at `[subject+0x01]`, validates ordinary ids through the structure-candidate collection at `0x0062ba8c` with `indexed_collection_entry_id_is_live` `0x00517d40`, resolves them into concrete live candidate records through `indexed_collection_resolve_live_entry_by_id` `0x00518140`, and then uses candidate field `[record+0x04]` as the shared stem for both the ordinary row asset path `%s.imb` and the neighboring display-label lookup through `localization_lookup_display_label_by_stem_or_fallback` `0x0051c920`. Only when that ordinary candidate branch fails does it fall back to the fixed express-side special ids `0x384..0x386`. Current table correlation now bounds that fixed branch more sharply: `0x00621df8` seeds the short-label controls `0x7dc8..0x7dca` with localized ids `494..496` `Any Cargo`, `Any Freight`, and `Any Express`, while `0x00621e10` seeds the adjacent asset-name controls `0x7e90..0x7e92` with `AnyCargo`, `AnyFreight`, and `PassMail` before `%1.imb` formatting. The helper also uses `Cargo.imb`, `Caboose.imb`, and the adjacent asset string `Dining.imb` while rebuilding the visible row payloads; current RT3.lng alignment now ties the longer descriptive popup/help side to `497/498` for freight/express and the two special service rows to localized labels `911` `Dining Car` and `912` `Caboose`. One resource-side boundary is tighter now too: the extracted `BuildingDetail.win` blob currently exposes only a sparse embedded text table with the help line `0xbb8`, the asset-name string `0xbb9`, and one standalone caption entry `0xbba` `Cargo`, which is the strongest current resource-side anchor for the row header around `0x7d06` and simultaneously reinforces that the deeper ordinary rows are being labeled from live candidate-record stems rather than from a larger hidden caption table. Current subflag correlation is tighter too: the extra visual lanes `0x7d6a`, `0x7d6b`, and `0x7d9d` are driven from the same selected-subject flag byte at `+0x28`, with `0x7d9d` on the bit-`0x20` branch using `Caboose.imb` and the sibling bit-`0x10` special lane using `Dining.imb`. The helper then re-enters both `shell_building_detail_refresh_subject_pair_value_rows` at `0x004bad20` and the flagged-row helper `shell_building_detail_refresh_flagged_service_capability_rows` at `0x004b9a20`. Current grounded callers include the main building-detail refresh at `0x004baedd`, constructor-adjacent and handler-side refreshes at `0x004bb8dc`, `0x004bbc89`, `0x004bbd6a`, and `0x004bc02b`. Current evidence is therefore strong enough to treat this as the selected-building cargo or service row owner even though several ordinary candidate-row captions remain unrecovered.","objdump + caller inspection + strings correlation + control-range inspection + candidate-id correlation + collection-helper correlation + stem-label correlation + subflag-row correlation + asset-string block correlation + RT3.lng correlation + table-entry correlation + win-resource extraction" +0x004ba270,311,shell_building_detail_handle_subject_value_row_band_action,shell,cdecl,inferred,objdump + callsite inspection + local disassembly,3,"Small `BuildingDetail.win` row-band action callback over the control-id family `0x7d07..0x7d14`. The helper switches on the clicked control id minus `0x7d07`, updates the selected building subject rooted at `0x006cfe04`, and treats subject bytes `+0x21`, `+0x22`, and `+0x23` as one current selection plus one bounded low/high pair. On change it increments the family dirty latch at `0x006cfe0c`, writes the refreshed current or bound value back through the shared shell control helper on code `0x66`, and when the side list helper at `0x006cfe08` is active it re-enters the neighboring follow-up refresh path at `0x004b9ec0`. Current direct installation site is the `0x7d0e` widget branch inside `shell_building_detail_refresh_subject_cargo_and_service_rows` at `0x004bacc9`, which keeps this bounded as the live action owner for the paired value rows rather than another passive formatter.","objdump + callsite inspection + local disassembly + selected-subject field correlation" +0x004bad20,461,shell_building_detail_refresh_subject_pair_value_rows,shell,thiscall,inferred,objdump + caller inspection + control-range inspection,3,"Shared `BuildingDetail.win` helper for the mutually exclusive subject-value row pairs around controls `0x7d05..0x7d14`. The helper first styles the leading pair `0x7d05/0x7d06`, then chooses between the value-row pairs `0x7d07/0x7d08`, `0x7d11/0x7d12`, and `0x7d13/0x7d14` from the selected building subject at `0x006cfe04`, using the same flag byte at `+0x28` that drives the neighboring cargo or service rows. On the nonzero selector branch it instead refreshes the current-selection status around `0x7d0d/0x7d0e` from the subject count byte and the subject field at `+0x21`, then tails back into `shell_building_detail_refresh_subject_cargo_and_service_rows` at `0x004ba3d0`. Current payload values for the mutually exclusive pairs come from subject fields `+0x22` and `+0x23`, and current grounded caller correlation keeps this bounded as one shared pair-value row owner rather than a separate top-level widget family.","objdump + caller inspection + control-range inspection + subject-field correlation + flag-branch correlation" +0x004b9d70,14,shell_has_live_building_detail_window,shell,cdecl,inferred,objdump + caller inspection + strings correlation,4,"Tiny presence probe for the shell-side `BuildingDetail.win` singleton rooted at `0x006cfe00`. The helper returns `1` when that live detail object pointer is nonnull and `0` otherwise. Current grounded callers include the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, where it sits beside the sibling overview, load-screen, settings, custom-modal, and file-options probes.","objdump + caller inspection + strings correlation + singleton correlation" +0x004b9d80,11,shell_mark_building_detail_window_dirty,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Tiny dirty-latch setter paired with `shell_has_live_building_detail_window`. The helper stores `1` into `0x006cfe10`, which current nearby call patterns treat as the `BuildingDetail.win` refresh or service request latch once the live singleton at `0x006cfe00` exists. Current grounded caller is the same post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`.","objdump + caller inspection + nearby-family correlation + singleton correlation" +0x004b9e10,166,shell_building_detail_submit_aux_owner_subject_sync_request,shell,cdecl,inferred,objdump + caller inspection + state-block inspection,3,"Small side-owner sync helper for `BuildingDetail.win`. When the auxiliary owner at `0x006cd8d8` is present and the local dirty counter `0x006cfe0c` is nonzero, the helper allocates a `0x3f`-byte request block, stamps a small header through `0x005216c0` and `0x00513130`, stores one mirrored-subject mode bit in request word `+0x08`, stores the current building-detail ordinal from `0x00621df4`, then copies the full staged building subject record from `0x006cfe04` into the request body before queueing it through `0x00469d30` on the owner-local request list at `[0x006cd8d8+0x8f48]`. Current direct callers are the `0x7d01` and `0x7d09/0x7d0a` branches inside `shell_building_detail_window_handle_message` `0x004bb9e0`, and both now clearly source that mode bit from the side-list mirror latch at `[0x006cfe08+0x0c]`, which keeps this bounded as an auxiliary-owner subject-sync path that preserves local mirror-state rather than a generic widget refresh. The helper also currently suppresses submission when the neighboring live-flag dword at `0x006d3ae4` is nonzero.","objdump + caller inspection + state-block inspection + side-owner queue correlation + mirror-latch correlation" +0x004b9ec0,272,shell_building_detail_propagate_selected_subject_state_into_side_list,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Shared follow-up helper for `BuildingDetail.win` when the sibling side-list owner at `0x006cfe08` is active and its mirror latch at `+0x0c` is nonzero. The helper walks every indexed side-list subject through `0x004b2b60`, copies the currently selected subject state from `0x006cfe04` into each sibling record, mirrors the current service or capability id at `[subject+0x24]`, and propagates the mutable subflag family in byte `+0x28` with bits `0x40`, `0x20`, and `0x10` preserved from the active subject. It also copies the current-selection fields `+0x21/+0x22/+0x23` and the live id list rooted at `+0x01`, which is why the paired value-row action helper at `0x004ba270` and several handler-side selector branches re-enter this path after mutating the active subject. Current grounded callers are `shell_building_detail_handle_subject_value_row_band_action` at `0x004ba270` and the handler-side refresh branches at `0x004bbc9d`, `0x004bbd81`, and `0x004bbe55`.","objdump + caller inspection + local disassembly + selected-subject field correlation + side-list iteration correlation + mirror-latch correlation" +0x004b9fd0,672,shell_building_detail_present_flagged_service_capability_popup,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Popup callback installed on the larger `BuildingDetail.win` flagged-row band. The helper takes one clicked control id in the `0x7f58..0x801f` family, resolves either one fixed express-side descriptor from table `0x00621e04` for the first three rows or one active candidate/service id from the selected subject at `0x006cfe04+0x24`, and then formats an explanatory shell popup before returning through `0x538c70`. Current table correlation now closes that first triplet more cleanly: `0x00621e04` supplies localized ids `494`, `497`, and `498`, so the fixed popup/help branch is specifically `Any Cargo`, `Any Freight\\n(Freight is everything but Passengers, Mail, and Troops)`, and `Any Express\\n(Express is Passengers, Mail, and Troops)` for controls `0x7f58..0x7f5a`. Current language-table correlation also tightens the ordinary popup split: one single-line availability popup uses localized id `3922` `%1\\nLoads available at %2: %3`, while the ordinary candidate branch uses localized id `2981` `%1\\nLoads available at %2: %3 Current Price: %4` and can append localized id `2982` `Price at next station, %1: %2 (%3%4)`. On that ordinary branch it resolves the current candidate through `structure_candidate_collection_get_nth_active_candidate_id` at `0x004b99c0`, compares the selected site against the current subject site at `+0x29`, queries local service metrics through `placed_structure_query_candidate_local_service_metrics` at `0x0047e240`, and conditionally computes the nearby-site delta line before presenting the final text. Current direct installation sites are the callback-registration branches at `0x004bb43f` and `0x004bb8a6`, which keeps this bounded as the live explanatory popup owner for the `0x7f58..0x801f` selector rows rather than another passive formatter.","objdump + caller inspection + local disassembly + callback-registration correlation + popup-path correlation + candidate-metric correlation + RT3.lng correlation + table-entry correlation" +0x004bb9e0,2183,shell_building_detail_window_handle_message,shell,thiscall,inferred,objdump + caller inspection + strings correlation,4,"Primary message dispatcher for the shell-side `BuildingDetail.win` family rooted at `0x006cfe00`. The handler switches over shell messages `0`, `0xca`, and `0xcb`; updates the staged building subject in `0x006cfe04` and its list helper at `0x006cfe08`; refreshes the visible control ranges `0x7d..0x8051`; and consumes the dirty latch at `0x006cfe10` on the recurring service path. Its action cases are now tighter than a generic navigation bucket. The `0x7d01` branch is no longer just an isolated oddball either: extracted `BuildingDetail.win` text now makes `Set the initial cargo amount for 'Disable Cargo Economy' scenarios.` the strongest current caption candidate for that control, the message path can mirror that action through `shell_building_detail_submit_aux_owner_subject_sync_request` `0x004b9e10` when `shell_has_auxiliary_preview_owner` `0x00434050` reports the side owner live, and one later rejection path now clearly raises localized id `3587` `This option is only available by following the tutorial.` behind the active tutorial flag at `0x006d3b4c` plus the cached previous expected-control id at `0x00622b38`. The `0x7d02/0x7d03` pair flips selected-subject bit `0x40` and re-enters `shell_building_detail_refresh_subject_pair_value_rows` `0x004bad20`, which makes that pair the real top-level mode switch between the bounded pair-value branch and the current-selection/status branch around `0x7d0d/0x7d0e`. The `0x7d09/0x7d0a` pair steps neighboring building subjects through `0x004b2b60`, skipping disallowed subjects on the local iteration path, and the same branch can also mirror the new selected subject through `0x004b9e10` when that auxiliary owner is present. The `0x7d0f/0x7d10` pair flips selected-subject bits `0x20` and `0x10`, i.e. the same special-service subflags later rendered as `Caboose` and `Dining Car`, and then re-clamps the paired value widgets through the same shared refresh path. The `0x7f58..0x801f` selector band changes the current service or capability id at `[subject+0x24]` before re-entering `shell_building_detail_refresh_flagged_service_capability_rows` `0x004b9a20`; current refresh-side correlation now shows that band as one selected-ordinal picker over three fixed express rows plus the ordinary active-candidate rows rather than an undifferentiated list. The `0x8020..0x8051` action band is now tighter too: it is primarily a per-row removal family over the selected subject's live id list rooted at `+0x01`, zeroing one indexed entry, compacting the remaining dword ids, decrementing count byte `+0x00`, clamping the current-selection byte `+0x21`, and then refreshing the visible row bands. Two special row indices inside that same band re-route into the adjacent `0x7d0f/0x7d10` subflag-clearing path instead of ordinary list compaction when the current `0x20/0x10` service-bit state requires it. The handler can also open simple shell modals through `shell_open_custom_modal_dialog_with_callbacks` `0x004c98a0` when one building-side action is disallowed. Current grounded callers are the shell runtime after construction and the explicit dirty-latch service path.","objdump + caller inspection + strings correlation + control-range inspection + dirty-latch correlation + selected-subject mutation correlation + RT3.lng correlation + selected-ordinal correlation + remove-entry compaction correlation + auxiliary-owner sync correlation + tutorial-rejection correlation + expected-control-cache correlation" +0x004baef0,2793,shell_building_detail_window_refresh_controls,shell,thiscall,inferred,objdump + caller inspection + control-range inspection,4,"Primary refresh path for the shell-side `BuildingDetail.win` family. The helper rebuilds the top-level control bands under `0x7d02..0x8051`, including the paired mode switch `0x7d02/0x7d03` from subject flag `0x40`, the smaller special-service toggles `0x7d0f/0x7d10` from subject bits `0x20` and `0x10`, the current-selection status widget around `0x7d0d/0x7d0e`, the selected-building cargo or service rows through `shell_building_detail_refresh_subject_cargo_and_service_rows` at `0x004ba3d0`, the paired subject-value rows through `shell_building_detail_refresh_subject_pair_value_rows` at `0x004bad20`, and the flagged service or capability rows through `shell_building_detail_refresh_flagged_service_capability_rows` at `0x004b9a20`. Current control-building correlation now makes the leading special-row bands explicit too: the short-label triplet `0x7dc8..0x7dca`, its adjacent asset/icon triplet `0x7e90..0x7e92`, and the popup/selectable triplet `0x7f58..0x7f5a` are the fixed express-side branch before the broader ordinary candidate rows. Current branch structure is tighter too: when subject bit `0x40` is set the refresh ends on the selected-subject cargo/service family rooted at `0x004ba3d0`, while the clear branch instead ends on the flagged capability-selector family rooted at `0x004b9a20`. It also hides or shows the larger control ranges `0x7dc8..0x7f57`, `0x7f58..0x801f`, and `0x8020..0x8051` through the shared shell control toggles at `0x53fe00`. Current grounded callers are the main constructor-side and focus refreshes at `0x004bbace`, `0x004bc0cc`, and `0x004bc0de`, and the message dispatcher at `0x004bb9e0`.","objdump + caller inspection + control-range inspection + subject-flag correlation + helper-family correlation + branch-end correlation + control-family triplet correlation" +0x004bc0a0,71,shell_building_detail_window_construct,shell,thiscall,inferred,objdump + caller inspection + strings correlation,4,"Constructs the shell-side `BuildingDetail.win` object later published at `0x006cfe00`. The constructor seeds the local vtable at `0x005d05e0`, binds the window resource through `0x0053fa50`, and immediately refreshes the visible subject and control bands through `0x004baef0`. Current grounded caller is `shell_open_or_focus_building_detail_window` at `0x004bc100`, and current string-table correlation leaves `BuildingDetail.win` as the strongest owner name for this singleton family.","objdump + caller inspection + strings correlation + singleton correlation" +0x004bc100,203,shell_open_or_focus_building_detail_window,shell,cdecl,inferred,objdump + caller inspection + strings correlation,4,"Shared opener for the shell-side `BuildingDetail.win` singleton. The caller supplies the building-detail list helper in `ECX`, one current building subject in `EDX`, and one selected ordinal on the stack. The helper seeds the shared family globals at `0x006cfe04`, `0x006cfe08`, and `0x00621df4`, validates that the supplied building subject resolves to one live world object through the placed-structure collection at `0x006cec20`, allocates a `0x78`-byte shell object when no detail window is live, constructs it through `shell_building_detail_window_construct` at `0x004bc0a0`, publishes it through the shell runtime at `0x006d401c`, and tears it back down on return while clearing `0x006cfe00`. Current grounded callers include the world-side branch around `0x004bbace`, which updates the current building subject before opening this detail family. Current string-table correlation leaves `BuildingDetail.win` as the strongest owner name for this singleton family.","objdump + caller inspection + strings correlation + publish-path inspection + singleton correlation" 0x004384d0,570,world_run_post_load_generation_pipeline,map,cdecl,inferred,objdump + strings + caller xrefs,4,"Large post-load world-generation pipeline reached after world entry and shell-side file-load success paths. It increments the world-root generation counter at `[0x0062c120+0x2205]`, can run one preliminary branch through `0x00437743`, and then advances through a more bounded staged setup sequence with shell progress updates through `0x004834e0`. The visible banner order is now grounded from the direct string ids in the function body: id `318` `Computing Transportation and Pricing...` is posted first and remains active while the pipeline runs world_compute_transport_and_pricing_grid at `0x0044fb70`, the early collection pass world_setup_building_collection_phase at `0x0041ea50`, and the conditional region pair world_region_collection_seed_default_regions at `0x00421b60` plus world_region_border_overlay_rebuild at `0x004882e0`; only after those complete does the pipeline post id `319` `Setting up Players and Companies...`. That `319` lane is no longer just gate plumbing: the primary grounded work there is still the chairman-profile pair world_seed_default_chairman_profile_slots at `0x004377a0` plus world_build_chairman_profile_slot_records at `0x00437220`, but current neighboring setup flow also exposes one conditional company-side helper at `0x0047d440` under sandbox or non-editor shell-state conditions. Current evidence is tighter on the remaining gates too: `[0x006cec74+0x68]` now aligns with the editor-map `.gmp` mode in the shell file coordinators and acts as the broader master editor-mode flag that suppresses both later world-generation branches and diverts region-side calculations into alternate paths; `[0x006cec74+0x174]` is the direct building-population gate above id `320` `Setting Up Buildings...` and world_region_collection_run_building_population_pass at `0x00421c20`; `[0x006cec74+0x178]` is the direct seeding-burst gate above id `321` `Seeding Economy...` and simulation_run_chunked_fast_forward_burst at `0x00437b20`; and id `322` `Calculating Heights...` finishes through `0x0044d410`. The body fans into the live world root at `0x0062c120`, manager collections `0x0062ba8c`, `0x0062bae0`, and `0x006cfc9c`. Current grounded callers are the world-entry side around `0x004390ea` and the shell file-load side around `0x004dccfc`.","objdump + RT3.lng strings + caller xrefs + callsite inspection + file-flow correlation" 0x00435630,648,scenario_state_rebuild_port_warehouse_cargo_recipe_runtime_tables,map,thiscall,inferred,objdump + caller xrefs + state-layout inspection,4,"Rebuilds the runtime port-or-warehouse cargo-line tables from the scenario-side recipe-book state rooted at `[this+0x0fe7]`. The helper first biases into the recipe-book payload at `[this+0x13d4]`, then iterates all `12` recipe-book blocks in `0x4e1`-byte steps. For each book it clamps the shared maximum annual production float that precedes the first line, counts active lines across five repeated `0x30`-byte line records, and then imports those five lines into one parallel runtime array of `0xbc`-byte descriptors. The importer treats every line slot symmetrically rather than special-casing any row index: each slot reads one mode dword, one annual amount, and two cargo-token strings, resolves nonempty cargo strings through the global cargo collection at `0x0062ba8c`, and builds paired runtime halves for the mode families `2/3` and `1/3`. Current mode gating is now tight enough to treat the polarity as grounded rather than provisional: the source token at `line+0x08` is the supplied-cargo field because it is the branch activated for `Supply Only` and `Production Demand->Supply`, while the source token at `line+0x1c` is the demanded-cargo field because it is the branch activated for `Demand Only` and `Production Demand->Supply`. The constructor and handler now tighten the amount semantics too: `line+0x04` is the per-line annual-demand field only in mode `1`, but it becomes the annual-supply field in modes `2/3`. The importer matches that split by copying `line+0x04` directly into the supply-side runtime half for modes `2/3`, while the production-mode demand half is normalized to `1.0` rather than reusing the entered amount. That makes the five editor-side row entries look like generic cargo-line slots rather than five fixed named production roles. Current grounded callers include the scenario-state initializer at `0x00436ee0`, world-load or map-entry side branches at `0x00443ebc`, `0x00444ac1`, and `0x00448126`, plus the live editor page constructor at `0x004cf935`.","objdump + caller xrefs + state-layout inspection + cargo-collection correlation + mode-table correlation + constructor correlation" 0x00437b20,218,simulation_run_chunked_fast_forward_burst,simulation,thiscall,inferred,objdump,3,"Shell-mediated burst advance helper above simulation_advance_to_target_calendar_point. It marks a local fast-forward latch at `[this+0x46c38]`, derives one loop count from shell-state `0x006cec74+0x178` and active-mode flag `[0x006cec78+0x4af7]`, then repeatedly advances the world toward fixed target `0x05a0` through simulation_advance_to_target_calendar_point while pumping the shell-side service helper at `0x004834e0` between chunks. After the burst it clears the latch, sweeps the world collection at `0x0062bae0`, and tails into the neighboring cleanup path at `0x00434d40`. The current grounded owner is world_run_post_load_generation_pipeline at `0x004384d0`, where the helper sits behind shell-state gate `[0x006cec74+0x178]` under the localized `Seeding Economy...` phase after the earlier transportation-pricing and building-setup work has already run. This keeps the helper on the map or scenario setup side rather than the ordinary player-facing speed-control path.","objdump + caller context + RT3.lng strings + phase ordering" @@ -71,6 +173,8 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00434890,35,scenario_state_set_selected_chairman_profile,map,thiscall,inferred,objdump + global-state inspection,4,"Sets the currently selected chairman profile on the shell-side scenario state object at `0x006cec78`. The helper stores the incoming persona id into `[this+0x25]`, resolves that persona through the global profile collection at `0x006ceb9c`, and then copies the linked owner-company id from `[profile+0x1dd]` into `[this+0x21]`. This grounds the summary pair used by the post-load chairman-profile setup lane: `[state+0x25]` is the selected chairman profile id and `[state+0x21]` is the corresponding owning company id.","objdump + global-state inspection + caller correlation" 0x004348c0,23,scenario_state_get_selected_chairman_profile_record,map,thiscall,inferred,objdump + global-state inspection,4,"Returns the currently selected chairman profile record for the shell-side scenario state object at `0x006cec78`. The helper reads `[this+0x25]` as a profile id and resolves it through the global persona collection at `0x006ceb9c`; zero or negative ids return null. This pairs directly with scenario_state_set_selected_chairman_profile at `0x00434890`.","objdump + global-state inspection + caller correlation" 0x00436590,372,scenario_state_compute_issue_opinion_multiplier,simulation,thiscall,inferred,objdump + caller inspection,4,"Computes one bounded opinion multiplier for a caller-selected issue slot on the active scenario or shell state rooted at `0x006cec78`. The helper starts from the base issue term at `[this + issue*4 + 0x8a]`, clamps that raw value to a floor of `-99`, normalizes it into a multiplier around `1.0`, and then optionally folds in up to three issue-specific override tables: a company-side term from `[company + issue*4 + 0x35b]`, a chairman-profile term from `[profile + issue*4 + 0x2ab]`, and a territory-side term from `[territory + issue*4 + 0x3b5]`. When the profile argument is omitted but a valid company is supplied, it implicitly reuses that company's linked chairman id from `[company+0x3b]`. The final multiplier is clamped to a small positive floor near `0.01` before return. Current grounded callers include the public-support blend helper at `0x00424fd0`, the merger vote resolver at `0x004ebd10` with issue id `0x3a`, and several other company-policy and shell-side opinion branches. The merger-side `0x3a` use now lines up directly with `RT3.lng` id `726`, which says public merger votes depend on their attitude toward the management of the two companies, so this issue slot is now best read as the merger-management-attitude multiplier.","objdump + caller inspection + issue-table correlation + merger-text correlation" +0x004768c0,53,chairman_profile_owns_all_company_shares,simulation,thiscall,inferred,objdump + caller inspection,4,"Boolean ownership predicate over one chairman profile and company id. The helper resolves the requested company through the live company collection at `0x0062be10`, reads the company's full outstanding-share count from `[company+0x47]`, and compares it against the current profile's holding slot for that same company at `[profile + company_id*4 + 0x15d]`. It returns `1` only when the profile holds the full outstanding-share band and `0` otherwise. Current grounded caller is the CompanyDetail section-0 overview formatter at `0x004e5cf0`, where this is the decision point between the wholly-owned text family `3046/3047` and the investor-attitude text family `3048/3049`.","objdump + caller inspection + ownership-predicate correlation" +0x00436710,163,scenario_state_sum_issue_opinion_terms_raw,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Raw additive companion to `scenario_state_compute_issue_opinion_multiplier` on the active scenario or shell state rooted at `0x006cec78`. The helper starts from the base issue term at `[this + issue*4 + 0x8a]`, then optionally adds the company override term at `[company + issue*4 + 0x35b]`, the chairman-profile override term at `[profile + issue*4 + 0x2ab]`, and the territory override term at `[territory + issue*4 + 0x3b5]` without normalizing or clamping the result into a multiplier. When the profile argument is omitted but a valid company is supplied, it implicitly reuses that company's linked chairman id from `[company+0x3b]`. Current grounded callers include the city-connection bonus lane through `company_compute_issue39_opinion_bias_scalar` at `0x00424580` and several neighboring policy or setup branches that treat the returned integer as one raw issue-opinion total rather than a finished probability or vote scalar.","objdump + caller xrefs + callsite inspection + issue-table correlation + raw-sum correlation" 0x00437a60,41,world_toggle_pause_or_restore_game_speed,simulation,thiscall,inferred,objdump + strings,3,"Pause or resume toggle over the world game-speed fields. When the current mode at `[this+0x19]` is above zero it re-enters world_set_game_speed_mode with target `0` to pause; otherwise it restores the saved nonzero resume mode from `[this+0x1d]`. This matches the player-facing speed-control family rooted in `Paused` through `Very Fast` and their tooltips in `RT3.lng` ids `1795..1800`.","objdump + RT3.lng strings" 0x00443a50,1073,world_entry_transition_and_runtime_bringup,map,cdecl,inferred,objdump + analysis-context,4,First grounded gameplay-world entry coordinator reached from shell_map_file_entry_coordinator. It stages the selected file path into 0x0062bee0 dismisses the shell detail-panel controller at 0x006d0818 drives shell_transition_mode through 0x00482ec0 and shell_state_service_active_mode_frame then marks shell state for the transition and resets the previous world bundle through world_runtime_release_global_services and the neighboring allocator branch at 0x00438890. After the transition wait it builds temporary bundle payloads from %1\\%2 and %1.tmp allocates or serializes several world-entry records through 0x00530c80 0x00531150 and 0x00531360 allocates the new world root at 0x0062c120 from the staged filename through 0x0044e910 notifies the shell owner at 0x0062be68 and then initializes multiple world-facing global managers including 0x0062ba8c 0x0062b2fc 0x0062b26c and 0x006ada90. This now looks like the first real shell-to-gameplay world-entry bring-up path rather than shell-only staging.,objdump + analysis-context + caller xrefs + strings 0x00444dd0,3301,map_bundle_open_reference_databases,map,cdecl,inferred,ghidra-headless,3,Opens and registers a broad reference-database bundle for the active map path. The routine formats %1\\%2 paths allocates bundle state through 0x00530c80 and wires many global datasets including gpdLabelDB gpdCityDB and related city geographic and map reference tables before later shell and map loaders continue.,ghidra + rizin + llvm-objdump + strings @@ -134,13 +238,13 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00477860,90,profile_collection_get_nth_active_chairman_record,map,thiscall,inferred,objdump + callsite inspection,4,"Returns one zero-based active chairman-profile record from the global persona collection at `0x006ceb9c`. The helper skips any entry whose live flag `[profile+0x4]` is zero and decrements the requested ordinal across the remaining active entries until it resolves one record or returns null. Current grounded caller is `world_conditionally_seed_named_starting_railroad_companies` at `0x0047d440`, which requests ordinal `1` to bind the second seeded railroad to the second active chairman profile when present.","objdump + callsite inspection + caller correlation" 0x00478200,291,shell_queue_single_world_anchor_overlay,shell,cdecl,inferred,ghidra-headless,3,Builds one world-anchor overlay packet for the current owner object. It samples the owner transform through 0x00455800 and 0x00455810 derives projected half-height and half-width through 0x00477a10 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and then enqueues the finished marker through shell_queue_world_anchor_marker.,ghidra + rizin + llvm-objdump 0x00478330,2432,shell_queue_world_anchor_overlay_list,shell,cdecl,inferred,ghidra-headless,3,Builds and queues a repeated world-anchor overlay list for one owner-managed collection. The routine iterates several owner sublists and state branches repeatedly derives projected extents through 0x00477a10 0x004779c0 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and emits one shell_queue_world_anchor_marker packet per accepted overlay entry.,ghidra + rizin + llvm-objdump -0x0047d080,186,start_new_company_dialog_open,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Opens the shell-side `Start New Company...` dialog rooted at localized id `574`. The helper rolls one persona-dependent shell color or portrait token through a small static table, allocates the modal shell window through the constructor/callback pair `0x0047c590` and `0x0047c3a0`, increments the scenario-side start-company generation counter at `[0x006cec78+0x41]`, and stores the live dialog owner at `0x006d3b4c`. Current grounded caller is the company-list window handler at `0x004c6f30`, which reaches this helper from the synthetic company-row id `0x7fff` after optional resignation confirmation through localized string `272` `You're currently chairman of the %1... Proceed?`.","objdump + RT3.lng strings + caller inspection" +0x0047d080,186,start_new_company_dialog_open,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Opens the shell-side `Start New Company...` dialog rooted at localized id `574`. The helper rolls one persona-dependent shell color or portrait token through a small static table, allocates the modal shell window through the constructor/callback pair `0x0047c590` and `0x0047c3a0`, increments the scenario-side start-company generation counter at `[0x006cec78+0x41]`, and enters the shared callback-driven modal path through `shell_open_custom_modal_dialog_with_callbacks` at `0x004c98a0`. Current grounded caller is the company-list window handler at `0x004c6f30`, which reaches this helper from the synthetic company-row id `0x7fff` after optional resignation confirmation through localized string `272` `You're currently chairman of the %1... Proceed?`. The older claim that this helper stored one live dialog owner at `0x006d3b4c` is no longer supported by direct disassembly; current stronger evidence treats `0x006d3b4c` as part of the broader shell tutorial state family instead.","objdump + RT3.lng strings + caller inspection + modal-path inspection + tutorial-state correction" 0x0047d120,509,start_new_company_dialog_commit_create_company,shell,cdecl,inferred,objdump + caller inspection + company-constructor inspection,4,"Commits the shell-side `Start New Company...` dialog and creates one fresh live company record rather than claiming one of the pre-seeded named railroads. After validating the dialog state it resolves the selected chairman-profile summary from `0x006cec78`, unlinks any existing company from that chairman through `0x00427c70`, allocates a new company id from the live company collection at `0x0062be10`, formats the dialog-owned company-name buffer at `0x006cebd8`, and initializes the new company through `0x00428420`. It then clamps one startup-funding lane against the new company's local limit fields, writes the chosen funding back to `0x006cec14`, updates one per-profile financing slot at `[profile+company_id*4+0x15d]`, applies the resulting debt through `0x00476050`, publishes the new selected company id through `0x00433790`, and triggers one shell refresh through `0x00432f40`. When the dialog instead diverts into the `0x3f2` side path, it packages the same staged company payload into the Multiplayer preview request owner at `0x006cd8d8` through `0x00469d30`.","objdump + caller inspection + company-constructor inspection + global-state correlation" 0x0047d320,280,start_new_company_request_create_company,map,thiscall,inferred,objdump + caller inspection + company-constructor inspection,4,"Creates one fresh company record from a compact startup-company request block. The request layout is now partly grounded: `[this+0x0]` is the chairman profile id in `0x006ceb9c`, `[this+0x4]` is the localized railroad-name id or equivalent name token, `[this+0x8]` plus `[this+0xc]` form the startup-funding total later divided by the new company rate lane, and `[this+0x10]` is the staged company-name buffer. The helper unlinks any existing company from the referenced chairman through `0x00427c70`, allocates a fresh company id from the live company collection at `0x0062be10`, initializes that company through `0x00428420`, and updates one per-profile financing slot at `[profile+company_id*4+0x15d]`. If the request chairman matches the current selected chairman summary from `0x006cec78`, it also publishes the new selected company id through `0x00433790`. Current grounded caller is the neighboring startup-company branch at `0x00470e48`, which reaches this helper when the request cannot be resolved to an existing company record.","objdump + caller inspection + company-constructor inspection + global-state correlation" 0x0047e240,240,placed_structure_query_candidate_local_service_metrics,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Queries one candidate-specific local service metric pair for the current placed-structure or site context. The helper first resolves the requested candidate index through the live structure collection at `0x0062ba8c` and rejects entries that fail `structure_candidate_is_enabled_for_current_year` at `0x0041e220`; on rejection it returns `0`, writes count `0` to the optional first out-pointer, and writes fallback float `1.0` to the optional second out-pointer. For live candidates it resolves the optional linked placed instance at `[this+0x04]`, passes that context through `0x00455f60`, and queries the base integer metric through `0x0042c960`; when the caller has a nonzero local sample list at `[this+0x38]` and `[this+0x34]`, it then accumulates matching per-cell float contributions from the world-grid table rooted at `[0x0062c120+0x2129]` into the second out-value. Current grounded callers include the shell or world-side branches at `0x0043f72e`, `0x0043f936`, `0x0047e365`, `0x0047ecd3`, `0x0047faff`, `0x004ba072`, `0x004bb51c`, and `0x00504d0f`, so this now looks like the first higher-level site query above the cargo-service bitset lane rather than another raw editor-runtime helper.","objdump + caller xrefs + callsite inspection + world-grid correlation" 0x0047e330,96,placed_structure_count_candidates_with_local_service_metrics,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Counts how many live structure candidates currently produce a valid local service-metric result for the current placed-structure or site context. The helper walks the full candidate collection at `0x0062ba8c`, resolves each entry id through `0x00518380`, and reuses `placed_structure_query_candidate_local_service_metrics` at `0x0047e240` with null out-pointers; it increments the return value only when that lower query succeeds. Current grounded callers keep this in the same site-query family as `0x0047e240`, so it now looks like the bounded count wrapper above the candidate-local service-metric lane.","objdump + caller xrefs + callsite inspection" 0x0047e390,656,placed_structure_query_cached_express_service_class_score,map,thiscall,inferred,objdump + caller xrefs + string correlation + callsite inspection,3,"Cached site-side query for one express-service class score. The helper special-cases request ids `0x384`, `0x385`, and `0x386` through three cached float-plus-timestamp pairs at `[this+0x14]/[+0x20]`, `[this+0x10]/[+0x1c]`, and `[this+0x0c]/[+0x18]`; when a cached value is younger than `0x0b40` ticks it returns immediately. On a cold path it scans all `0x35` live structure candidates, uses `0x0041e260` to keep only candidates that match the requested class, and then accumulates local per-cell contributions from the repeated sample list at `[this+0x34]` and the same world-grid tables under `[0x0062c120+0x2129]`. Nearby strings now strongly align the three class ids with the express cargo family `Passengers`, `Mail`, and `Troops`, but current grounded callers still treat this as a generic class-score query rather than a fully named UI lane. Current grounded callers include the shell or world-side branches at `0x00506c2d`, `0x00506c3d`, `0x00506e97`, and `0x00506ebf`.","objdump + caller xrefs + string correlation + callsite inspection + express-family correlation" -0x0047e690,784,placed_structure_query_candidate_directional_route_overlay_summary,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Builds the heavier directional route-summary channel used by the station-detail candidate-service overlay when the active candidate carries a nonzero route-style byte at `[candidate+0x46]`. The helper converts one caller-supplied distance or bucket limit into a capped step count up to `0x28`, resolves the requested candidate's grouped routing class from `0x0062ba8c+0x9a`, then walks the current placed structure's linked route list at `[this+0x466]` and follows each route-linked placed structure through the live instance collections at `0x0062b26c` and `0x006ada90`. For matching class entries it re-enters `0x004676a0` to measure one directional route value against the peer placed-structure argument, keeps the strongest bounded values in a sorted local lane, and finally accumulates those kept route values into the caller-owned out-pointers. Current grounded overlay callers at `0x0043f89a` and `0x0043f8ee` invoke it in both directions between the preview station and each scanned placed structure before `world_render_station_candidate_service_map_overlay` turns those two returned channels into the `Coming To` and `Going From` legend rows.","objdump + caller xrefs + callsite inspection + overlay-caller correlation + legend-correlation" +0x0047e690,784,placed_structure_query_candidate_directional_route_overlay_summary,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Builds the heavier directional route-summary channel used by the station-detail candidate-service overlay when the active candidate carries a nonzero route-style byte at `[candidate+0x46]`. The helper converts one caller-supplied distance or bucket limit into a capped step count up to `0x28`, resolves the requested candidate's grouped routing class from `0x0062ba8c+0x9a`, then walks the current placed structure's linked route list at `[this+0x466]` and follows each route-linked placed structure through the live instance collections at `0x0062b26c` and the route-link collection `0x006ada90`. For matching class entries it re-enters `0x004676a0` to measure one directional route value against the peer placed-structure argument, keeps the strongest bounded values in a sorted local lane, and finally accumulates those kept route values into the caller-owned out-pointers. Current grounded overlay callers at `0x0043f89a` and `0x0043f8ee` invoke it in both directions between the preview station and each scanned placed structure before `world_render_station_candidate_service_map_overlay` turns those two returned channels into the `Coming To` and `Going From` legend rows.","objdump + caller xrefs + callsite inspection + overlay-caller correlation + legend-correlation + route-link-collection correlation" 0x0047d440,845,world_conditionally_seed_named_starting_railroad_companies,map,cdecl,inferred,objdump + caller xrefs + global-state inspection,4,"Conditional company-side setup helper adjacent to the `Setting up Players and Companies...` lane. Current grounded callers are the neighboring bring-up flow after world_seed_default_chairman_profile_slots at `0x004377a0` and a second setup-side branch around `0x00438300`, both under the same sandbox or non-editor shell-state conditions: it runs only when the Multiplayer preview dataset owner at `0x006cd8d8` is absent and either sandbox flag `[0x006cec7c+0x82]` is set or shell-state flag `[0x006cec74+0x14c]` is set while editor-map mode `[0x006cec74+0x68]` is clear. The helper first realigns the selected company from the chosen chairman profile when the current summary pair points at a missing company, then iterates exactly three fixed localized railroad-name ids through `0x00428420`: `0x23f` `Missouri Pacific`, `0x240` `New York Central`, and `0x241` `Grand Trunk Railroad` from `RT3.lng` ids `575..577`. That makes the branch look like a seeded trio of named starting railroad companies rather than a generic company refresh. The first seeded company is tied to the selected chairman-profile summary from `0x006cec78`, tuned from that selected chairman's per-profile fields `[profile+0x154]` and `[profile+0x158]`, and then written back as the selected company id through `0x00433790`. The second company is narrower now too: it only binds when `profile_collection_count_active_chairman_records` at `0x00477820` reports at least two live chairman records, and it then links through `profile_collection_get_nth_active_chairman_record` at `0x00477860` with ordinal `1`, so the second railroad is specifically the second active chairman-owned company rather than an arbitrary extra bind. The third railroad currently gets no matching chairman-link branch in the grounded code and therefore remains an unchaired named company in the live roster. All three records are constructed or refreshed from the live company collection at `0x0062be10` through `0x00428420`, while chairman-to-company ownership links are applied through `0x00427c70` and neighboring writes to `[profile+0x1dd]`.","objdump + caller xrefs + global-state inspection + state-accessor correlation + RT3.lng strings + company-constructor inspection + profile-helper inspection" 0x0047efe0,28,placed_structure_query_linked_company_id,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Returns the owning company id for one placed structure when a linked placed-instance record is present. The helper resolves `[this+0x04]` through the live placed-instance collection at `0x0062b26c` and then returns the company-like field at `[instance+0x276]`; when no linked instance is present it falls back to `0`. Current grounded callers include the station candidate-service overlay at `0x0043fff7`, where the returned company id is compared against the active company selector before the overlay chooses whether a scanned site should carry the `Already Connected by Another Company` note.","objdump + caller xrefs + callsite inspection + overlay-owner correlation" 0x0047f010,195,placed_structure_append_unique_route_entry,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Appends one unique six-byte route-entry record onto the placed-structure route list rooted at `[this+0x462]` and `[this+0x466]`. The helper first scans the existing list for the incoming leading `u16` key and returns early on duplicates; otherwise it allocates a new `(count*6)+6` byte buffer, copies the existing records, writes the new `u16` key at offset `+0x0` and the caller-supplied `u32` payload at `+0x2`, frees the previous buffer, and increments the route-entry count. Current grounded callers include the placed-structure side at `0x0042c554`, which walks the linked instance chain through `[site+0x0d6]` and `[instance+0x2a2]` while appending entries, and the world-side branch at `0x0040db7d`, which appends one selected placed-structure id plus a companion payload from a route-like table. This is therefore the current reusable append-if-missing helper above the route-entry list later consumed by `placed_structure_query_candidate_directional_route_overlay_summary` at `0x0047e690`.","objdump + caller xrefs + callsite inspection + buffer-layout correlation" @@ -163,17 +267,65 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004874f0,70,shell_close_tiger_tank_viewer,shell,cdecl,inferred,ghidra-headless,4,Closes and frees the dedicated TigerTank shell viewer rooted at 0x006cfc8c. It detaches the viewer if currently selected in the shell owner at 0x0062be68 destroys its internal resources through 0x00530680 frees the object and clears the global viewer slot.,ghidra + rizin + llvm-objdump + strings 0x00489830,496,scenario_text_export_report_language_file,scenario,cdecl,inferred,ghidra-headless,3,Opens one existing MAPS\\%s.lng file for the selected map and reports on its parsed contents without rebuilding it. The routine loads the file into memory iterates numbered entries through 0x00488540 formats summary strings through 0x004895c0 and presents success or failure dialogs when interactive mode is enabled.,ghidra + rizin + llvm-objdump + strings 0x00489a20,1085,scenario_text_export_batch_process_maps,scenario,cdecl,inferred,ghidra-headless,4,Enumerates maps\\*.gmp and batch-processes every scenario through the scenario-text export branch. Command 0x7542 runs the build path through 0x004886e0 while command 0x7543 runs the report path through 0x00489830; the wrapper tracks progress formats per-map status strings and emits a final summary dialog.,ghidra + rizin + llvm-objdump + strings +0x004bfb30,956,shell_format_company_financial_summary_card,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Reusable shell company financial-summary formatter shared by `CompanyDetail.win` and the company-list row lane. The helper resolves the linked chairman and current selected profile through `0x006cec78` and `0x006ceb9c`, highlights the card when the company belongs to the selected chairman, formats the visible company header text, and then renders a compact three-row finance block under localized ids `633` `Cash:`, `607` `Revenue:`, and `925` `Profits:`. The grounded metric mapping is now tighter too: `Cash:` comes from `company_read_year_or_control_transfer_metric_value` at `0x0042a5d0` with slot `0x0d` and stat-family selector `0x2329`, `Revenue:` comes from the same reader with slot `0x2c`, and `Profits:` comes from slot `0x2b`; the revenue and profit rows also switch color when the readback is negative. Grounded callers are `shell_company_detail_render_company_summary_card` at `0x004c1ab0` and `shell_company_list_format_company_or_start_row` at `0x004c6b40`.","objdump + RT3.lng strings + caller inspection + shared shell formatter correlation + compact-metric-row correlation" +0x004c1610,48,shell_company_detail_bind_bond_row_band_for_active_panel,shell,cdecl,inferred,objdump + caller inspection,4,"Tiny CompanyDetail helper that binds one contiguous debt-row control band to whichever bond panel is active. When the source control id is `0x947e` it enables the upper row band `0x94e8..0x950f`; otherwise it enables the sibling row band `0x9510..0x9537`. Current grounded owner is the CompanyDetail refresh path at `0x004c2ca0`, where this helper sits beside the shared bond readout callback for controls `0x947d` and `0x947e` and makes those two controls read as twin bond-slot list owners rather than as one-off buttons.","objdump + caller inspection + bond-row-band correlation" +0x004c16b0,35,shell_company_detail_copy_selected_company_debt_slot_triplet,shell,cdecl,inferred,objdump + caller inspection,3,"Small CompanyDetail helper that copies one 12-byte triplet from the currently selected company's debt-record band near `[company+0x5f + slot*0xc]` into a caller-supplied output buffer. Current grounded callers use it while building the bond maturity and repay readout lane and the adjacent action-message debt checks.","objdump + caller inspection + debt-slot correlation" +0x004c16f0,59,shell_company_detail_resolve_selected_company,shell,cdecl,inferred,objdump + caller inspection,4,"Resolves the current `CompanyDetail.win` company into the live company collection and returns the validated company record pointer or null. The helper reads the selected company id from shell detail owner `0x006d0818+0x90`, rejects nonpositive ids, verifies existence through company collection `0x0062be10`, and then returns the concrete record through `0x00518140`. It is the common shared accessor beneath the CompanyDetail read-side panels, finance actions, territory-access lane, and company-governance flows.","objdump + caller inspection + shared CompanyDetail accessor correlation" +0x004c1730,546,shell_company_detail_render_financial_history_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"CompanyDetail-specific widget callback for control `0x9470`. The helper resolves the currently selected company through the shell detail owner at `0x006d0818`, lays out a five-step history strip, and renders localized labels `607` `Revenue:`, `944` `Expenses:`, `945` `Interest:`, `610` `Profit:`, and `611` `Lifetime`. Current grounded metric reads come from the same wider company history family through `company_read_year_or_control_transfer_metric_value` at `0x0042a5d0`, notably slots `0x2c`, `0x2e`, `0x2f`, and `0x2b`. Current grounded owner is the CompanyDetail constructor `0x004c5540`, which binds this callback onto the finance-history panel rather than onto a generic company-list row.","objdump + RT3.lng strings + caller inspection + CompanyDetail panel correlation" +0x004c1ab0,169,shell_company_detail_render_company_summary_card,shell,cdecl,inferred,objdump + caller inspection + shared formatter correlation,4,"Thin `CompanyDetail.win` widget callback for control `0x9471`. The helper resolves the current selected company through the shell detail owner at `0x006d0818` and forwards the draw to `shell_format_company_financial_summary_card` at `0x004bfb30` using the widget rectangle supplied by the current control tree. Current grounded owner is the CompanyDetail constructor `0x004c5540`, which binds this callback beside the separate financial-history panel callback at `0x004c1730`.","objdump + caller inspection + shared formatter correlation" +0x004c1d30,48,shell_company_detail_select_territory_access_row,shell,cdecl,inferred,objdump + caller inspection,4,"Small `CompanyDetail.win` territory-picker selection callback bound to the adjacent control pair `0x948d` and `0x948e`. When the incoming row ordinal is nonnegative, the helper resolves the current picker widget under `0x948c`, reads the chosen territory id from the row field at `[widget+0x117]`, and then forwards that territory id into `shell_company_detail_refresh_selected_territory_access_summary` at `0x004c1b60`. A negative row ordinal falls back to territory id zero before the same summary refresh.","objdump + caller inspection + picker-field correlation" +0x004c1d70,323,shell_company_detail_render_territory_access_row,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Territory-row renderer for the `CompanyDetail.win` access-rights lane. The callback resolves the currently selected company through `0x006d0818`, resolves the supplied territory id through the territory collection at `0x006cfc9c`, and then renders the territory row through the shell text widgets rooted at `0x006cfe50` and `0x006cfe58`. Current grounded logic also checks access rights through `company_has_territory_access_rights` at `0x00424010`, varies the row styling accordingly, and triggers the focused-row highlight path through `0x0054f710` when the rendered territory matches the globally selected territory id at `0x006cfe5c`. The CompanyDetail constructor binds this callback onto the paired territory-row controls `0x948d` and `0x948e`.","objdump + RT3.lng strings + caller inspection + territory-row correlation" 0x004c1b60,462,shell_company_detail_refresh_selected_territory_access_summary,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Refreshes the selected-territory status summary in `CompanyDetail.win`. The helper caches the active territory id in `0x006cfe5c`, resolves the territory through `0x006cfc9c`, and formats one of three localized status texts for the current selected company: id `946` when the company already has access rights, id `947` when rights are unavailable but purchasable, or id `948` when the company cannot purchase rights at all. It also republishes the selected-territory control rooted at `0x948c`. Current grounded callers are the territory-summary callbacks at `0x004c1d30`, `0x004c1d70`, and `0x004c22e0`.","objdump + RT3.lng strings + caller inspection + territory-status correlation" -0x004c3890,693,shell_company_detail_issue_bond_offer_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` bond-issue action flow. The helper resolves the currently selected company through the shell detail owner at `0x006d0818`, rejects requests when the company already has too many outstanding bonds through localized id `973`, rejects weak credit through localized id `974` plus the credit-rating tables at `0x00620d00..0x00620d14`, and otherwise opens the underwriter offer dialog for localized ids `968` through `972`. On acceptance it issues the bond through the selected-company method at `0x004275c0`; when the multiplayer-side shell owner is active it instead packages the same request through the asynchronous shell transport path rooted at `0x006cd8d8`. Current grounded caller is `shell_company_detail_window_handle_message` at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + bond-dialog correlation" +0x004c1ec0,587,shell_company_detail_render_bond_maturity_and_repay_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"CompanyDetail-specific bond readout callback bound to controls `0x947d` and `0x947e`. The helper resolves the currently selected company through `0x006d0818`, indexes one 12-byte debt-record slot from the selected company near `[company+0x5f + slot*0xc]`, formats the maturity caption through localized id `949` `Due %1`, formats the current bond amount or value through the shared numeric formatter family at `0x0051c000`, and then renders the repay affordance through localized id `950` `Repay this bond.`. In the surrounding refresh path this panel is paired with `shell_company_detail_bind_bond_row_band_for_active_panel` at `0x004c1610`, so the two controls now read as the owners of twin repayable bond-slot row bands `0x94e8..0x950f` and `0x9510..0x9537` rather than as isolated text widgets. Current grounded owner is the CompanyDetail constructor `0x004c5540`, which binds this callback onto the adjacent debt-panel controls rather than onto the territory or finance-history lanes.","objdump + RT3.lng strings + caller inspection + debt-panel correlation + bond-row-band correlation" +0x004c22e0,56,shell_company_detail_sync_selected_territory_from_picker,shell,cdecl,inferred,objdump + caller inspection,4,"Small `CompanyDetail.win` territory-sync callback for control `0x948c`. The helper resolves the current territory-picker widget through the live CompanyDetail window at `0x006cfe4c`, reads the currently focused territory id from `[widget+0x117]` when a picker row is present, and then forwards that territory id into `shell_company_detail_refresh_selected_territory_access_summary` at `0x004c1b60`. When no picker row is active it falls back to territory id zero before refreshing the same summary.","objdump + caller inspection + picker-sync correlation" +0x004c23a0,1259,shell_company_detail_render_capital_and_dividend_summary_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"CompanyDetail-specific summary callback bound to control `0x9488`. The helper resolves the currently selected company through `0x006d0818` and renders the player-facing finance-summary block under localized ids `951` `Total Debt:`, `952` `Credit Rating:`, `953` `Average Interest Rate:`, `954` `Prime Rate:`, `955` `Market Cap:`, `956` `Annual Dividend:`, and `957` `Annual Dividend Payments:`. Current grounded logic uses the company metric readers at `0x0042a5d0`, `0x00423e40`, and `0x00423eb0`, the credit-rating text table at `0x00620d00..0x00620d14`, and the outstanding-share count at `[company+0x47]` when deriving the rendered values. The CompanyDetail refresh path wires this callback onto the same read-side tab family as the bond and per-share panels.","objdump + RT3.lng strings + caller inspection + finance-summary correlation" +0x004c2720,1394,shell_company_detail_render_per_share_metrics_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"CompanyDetail-specific per-share metrics callback bound to control `0x948a`. The helper resolves the currently selected company through `0x006d0818` and renders the player-facing per-share block under localized ids `937` `Share Price:`, `938` `Book Value Per Share:`, `939` `Revenue Per Share:`, `940` `Earnings Per Share:`, `941` `Dividend Per Share:`, and `942` `5 Year Weighted Return:`. It also formats the dated caption lane through localized id `943` `Dec-%1` and uses the same current-company metric helpers as the surrounding CompanyDetail summary family. Current grounded owner is the CompanyDetail refresh path, which binds this panel beside the debt/capital summary block rather than inside the action-message dispatcher.","objdump + RT3.lng strings + caller inspection + per-share panel correlation" +0x004c3470,621,shell_company_detail_step_selected_active_company_delta,shell,cdecl,inferred,objdump + caller inspection,4,"CompanyDetail-specific company-navigation helper. The routine resolves the currently selected company id through the detail owner at `0x006d0818`, converts it to an active-company ordinal through `company_collection_count_active_companies_before_company_id` `0x004299f0`, wraps `ordinal + delta` modulo the active-company count from `company_collection_count_active_companies` `0x00429a50`, resolves the replacement company id through `company_collection_get_nth_active_company_id` `0x00429990`, writes it back through detail-manager setter `0x004dd8a0`, refreshes the visible panel through `shell_company_detail_window_refresh_controls` `0x004c2ca0`, notifies the detail manager through `0x004dd410`, and resets territory picker control `0x948c` through `0x00538e00`. Current grounded wrappers are the next and previous company selectors at `0x004c3540` and `0x004c3550`.","objdump + caller inspection + CompanyDetail navigation correlation" +0x004c3540,5,shell_company_detail_select_next_active_company,shell,cdecl,inferred,objdump + caller inspection,4,"Trivial CompanyDetail wrapper that seeds delta `+1` in `ecx` and tail-calls `shell_company_detail_step_selected_active_company_delta` `0x004c3470`. Current grounded callers include shell-side world and company-detail navigation paths.","objdump + caller inspection + wrapper correlation" +0x004c3550,5,shell_company_detail_select_previous_active_company,shell,cdecl,inferred,objdump + caller inspection,4,"Trivial CompanyDetail wrapper that seeds delta `-1` in `ecx` and tail-calls `shell_company_detail_step_selected_active_company_delta` `0x004c3470`. Current grounded callers include shell-side world and company-detail navigation paths.","objdump + caller inspection + wrapper correlation" +0x004c3560,816,shell_company_detail_render_issue_bond_offer_dialog,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Dedicated shell renderer for the `CompanyDetail.win` bond-offer dialog. The helper resolves the currently selected company from the live collection at `0x0062be10`, derives the staged offer terms from the same local bond-offer state later committed by `shell_company_detail_issue_bond_offer_flow`, and then lays out the localized underwriter lines `968..972`: `Underwriters offer to issue bonds as follows:`, `Amount:`, `Interest Rate:`, `Underwriting Fees:`, and `Go ahead and issue the bond?`. Current grounded caller is the issue-bond flow at `0x004c3890`, which passes this helper as the custom dialog renderer into the shared shell finance modal path at `0x004c98a0`.","objdump + RT3.lng strings + caller inspection + finance-dialog correlation" +0x004c3890,693,shell_company_detail_issue_bond_offer_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` bond-issue action flow. The helper resolves the currently selected company through the shell detail owner at `0x006d0818`, rejects requests when the company already has too many outstanding bonds through localized id `973`, rejects weak credit through localized id `974` plus the credit-rating tables at `0x00620d00..0x00620d14`, and otherwise opens the underwriter offer dialog for localized ids `968` through `972` using the dedicated renderer `shell_company_detail_render_issue_bond_offer_dialog` at `0x004c3560`. On acceptance it issues the bond through the selected-company method at `0x004275c0`; when the multiplayer-side shell owner is active it instead packages the same request through the asynchronous shell transport path rooted at `0x006cd8d8`. Current grounded caller is `shell_company_detail_window_handle_message` at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + bond-dialog correlation" +0x004c3b50,992,shell_company_detail_render_issue_stock_offer_dialog,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Dedicated shell renderer for the `CompanyDetail.win` stock-issue offer dialog. The helper resolves the currently selected company from the live collection at `0x0062be10`, reads the staged offer state from `0x006cfe64` and `0x006cfe68`, and lays out the localized stock-offer lines `975..978`: `Underwriters offer to issue stock as follows:`, `Shares:`, `Total Proceeds:`, and `Go ahead and issue the stock?`. Current grounded caller is `shell_company_detail_issue_stock_offer_flow` at `0x004c3f30`, which passes this helper as the custom dialog renderer into the shared shell finance modal path at `0x004c98a0`.","objdump + RT3.lng strings + caller inspection + finance-dialog correlation" 0x004c3f30,968,shell_company_detail_issue_stock_offer_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` stock-issue action flow. The helper derives a proposed share count and proceeds from the selected company into the local globals `0x006cfe64` and `0x006cfe68`, rejects weak offerings through localized id `979`, rejects oversaturated issuance through localized id `980`, and otherwise opens the underwriter offer dialog for localized ids `975` through `978`. On acceptance it issues the stock through the selected-company method at `0x00427450`; when the multiplayer-side shell owner is active it routes the same request through the asynchronous shell transport path rooted at `0x006cd8d8`. Current grounded caller is `shell_company_detail_window_handle_message` at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + stock-issue correlation" -0x004c46d0,1420,shell_company_detail_buyback_stock_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` stock-buyback action flow. The helper computes a proposed repurchase quantity and total cash cost into `0x006cfe64` and `0x006cfe68`, rejects cases with no public float through localized id `985`, rejects requests that would retire the final protected share band through id `986`, rejects insufficient company cash through id `987`, and otherwise opens the broker buyback dialog for localized ids `981` through `984`. On acceptance it repurchases the shares through the selected-company method at `0x004273c0`; when the multiplayer-side shell owner is active it routes the same request through the asynchronous shell transport path rooted at `0x006cd8d8`. Current grounded caller is `shell_company_detail_window_handle_message` at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + stock-buyback correlation" +0x004c4300,976,shell_company_detail_render_stock_buyback_offer_dialog,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Dedicated shell renderer for the `CompanyDetail.win` stock-buyback offer dialog. The helper resolves the currently selected company from the live collection at `0x0062be10`, reads the staged buyback state from `0x006cfe64` and `0x006cfe68`, and lays out the localized broker-offer lines `981..984`: `Brokers are able to locate the following shares on the market:`, `Brokerage Fees:`, `Total Cost:`, and `Go ahead and buy back the stock?`. Current grounded caller is `shell_company_detail_buyback_stock_flow` at `0x004c46d0`, which passes this helper as the custom dialog renderer into the shared shell finance modal path at `0x004c98a0`.","objdump + RT3.lng strings + caller inspection + finance-dialog correlation" +0x004c46d0,1420,shell_company_detail_buyback_stock_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` stock-buyback action flow. The helper computes a proposed repurchase quantity and total cash cost into `0x006cfe64` and `0x006cfe68`, rejects cases with no public float through localized id `985`, rejects requests that would retire the final protected share band through id `986`, rejects insufficient company cash through id `987`, and otherwise opens the broker buyback dialog for localized ids `981` through `984` using the dedicated renderer `shell_company_detail_render_stock_buyback_offer_dialog` at `0x004c4300`. On acceptance it repurchases the shares through the selected-company method at `0x004273c0`; when the multiplayer-side shell owner is active it routes the same request through the asynchronous shell transport path rooted at `0x006cd8d8`. Current grounded caller is `shell_company_detail_window_handle_message` at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + stock-buyback correlation" +0x004c4c70,448,shell_company_detail_setup_dividend_rate_adjust_controls,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Custom setup callback for the `CompanyDetail.win` dividend-rate dialog opened by `shell_company_detail_change_dividend_rate_flow` at `0x004c5360`. The helper resolves the currently selected company, stages two small shell control descriptors, and binds the paired dividend-adjust controls with ids `0x99e8` and `0xc0f9` back into the shared finance modal through the shell control-registration path rooted at `0x0053f9c0`. Current grounded behavior makes this the control-setup half of the dividend modal beside the text renderer at `0x004c4e30` and the message handler at `0x004c5140`.","objdump + RT3.lng strings + caller inspection + dividend-dialog control-setup correlation" +0x004c4e30,784,shell_company_detail_render_change_dividend_rate_dialog,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Dedicated shell renderer for the `CompanyDetail.win` change-dividend dialog. The helper resolves the currently selected company from the live collection at `0x0062be10`, renders the localized prompt and value lines `988..990`: `Change Dividend Rate`, `Dividend Rate:`, and `Total Annual Dividends:`, formats the staged per-share dividend from `0x006cfe48`, and derives the annual total from that same staged rate times the current outstanding-share count at `[company+0x47]`. Current grounded caller is `shell_company_detail_change_dividend_rate_flow` at `0x004c5360`, which passes this helper into the shared shell finance modal path at `0x004c98a0`.","objdump + RT3.lng strings + caller inspection + dividend-dialog renderer correlation" +0x004c5140,544,shell_company_detail_handle_change_dividend_rate_dialog_message,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Custom message callback for the `CompanyDetail.win` change-dividend dialog. The helper handles shell message `0xcb` from the paired adjust controls `0x99e8` and `0xc0f9`, raises or lowers the staged dividend-per-share value in `0x006cfe48`, clamps decrements at zero, and clamps increments against the board-approved per-share ceiling from `company_compute_board_approved_dividend_rate_ceiling` at `0x00426260`. When the player tries to raise the dividend beyond that ceiling it opens localized id `991` `Your board of directors feels that the company is not financially strong enough for a higher dividend...` through the shared modal path instead of accepting the increase. Current grounded caller is `shell_company_detail_change_dividend_rate_flow` at `0x004c5360`, which passes this helper as the dialog message owner into `0x004c98a0`.","objdump + RT3.lng strings + caller inspection + dividend-dialog message correlation + dividend-ceiling correlation" 0x004c5360,472,shell_company_detail_change_dividend_rate_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` dividend-rate action flow. The helper seeds the current dividend-per-share value from `[company+0x4b]` into `0x006cfe48`, opens the shared finance dialog rooted at callbacks `0x004c4c70`, `0x004c4e30`, and `0x004c5140` under localized ids `988` through `990`, and then commits the accepted new dividend rate through the selected-company method at `0x00423fb0`. When the multiplayer-side shell owner is active the same request is packaged through the asynchronous shell transport path rooted at `0x006cd8d8`. Current grounded caller is `shell_company_detail_window_handle_message` at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + dividend-dialog correlation" -0x004c2ca0,1964,shell_company_detail_window_refresh_controls,shell,thiscall,inferred,objdump + strings + caller inspection,4,"Shared refresh pass for the shell-side `CompanyDetail.win` family rooted at `0x006cfe4c`. The helper first requires a live shell detail-panel owner at `0x006d0818` with a selected company id in `[detail+0x90]`, resolves that company through the live collection at `0x0062be10`, and then repopulates the control bands rooted at `0x9476`, `0x947b`, `0x9480`, `0x948f`, and `0x9490`. Current grounded cases include a four-tab selector strip keyed by `0x006cfe60`, per-company chairman text or vacancy text through localized ids `0x3be` and `0x3bf`, and repeated control-tree updates through `0x00540120` and `0x0053f830`. The constructor at `0x004c5540` and many message-side branches at `0x004c56a0` converge back into this helper, which makes it the current owner-side refresh pass for the CompanyDetail window rather than a generic company-list helper.","objdump + strings + caller inspection + control-band correlation" -0x004c5540,347,shell_company_detail_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `CompanyDetail.win` panel later published at `0x006cfe4c`. The constructor installs vtable `0x005d0858`, binds `CompanyDetail.imb` and `CompanyDetail.win` through `0x0053d110` and `0x0053fa50`, seeds the primary action controls `0x9470`, `0x9471`, `0x947d`, `0x947e`, `0x948c`, `0x948d`, and `0x948e` through callbacks `0x004c1730`, `0x004c1ab0`, `0x004c1ec0`, `0x004c22e0`, `0x004c1d70`, and `0x004c1d30`, stores the singleton resources at `0x006cfe50..0x006cfe58`, and then immediately repopulates the visible state through `shell_company_detail_window_refresh_controls` at `0x004c2ca0`. A grounded shell detail-manager caller reaches this constructor at `0x004dde24`, which corrects the earlier assumption that the post-roster company branch still had no recovered detail-window owner.","objdump + strings + detail-manager correlation + caller inspection" -0x004c56a0,4228,shell_company_detail_window_handle_message,shell,thiscall,inferred,objdump + strings + caller inspection,4,"Primary message dispatcher for the shell-side `CompanyDetail.win` family rooted at vtable `0x005d0858`. The helper switches on the incoming shell message id and then on wide control bands beginning at `0x94e8` and `0x9510`, routes the grounded finance actions into `shell_company_detail_issue_bond_offer_flow` `0x004c3890`, `shell_company_detail_issue_stock_offer_flow` `0x004c3f30`, `shell_company_detail_buyback_stock_flow` `0x004c46d0`, and `shell_company_detail_change_dividend_rate_flow` `0x004c5360`, and also grounds the non-finance action lanes through `shell_company_detail_resign_chairmanship_flow` `0x004c5a0e`, `shell_company_detail_bankruptcy_flow` `0x004c5b99`, `shell_company_detail_buy_territory_access_rights_flow` `0x004c5fc9`, `shell_company_detail_attempt_merger_flow` `0x004ec640`, and `shell_company_detail_attempt_chairmanship_takeover_flow` `0x0050ccc0`. It repeatedly converges back into `shell_company_detail_window_refresh_controls` at `0x004c2ca0` after state changes. Current grounded evidence is enough to treat this as the real company-detail owner path, while the remaining uncertainty has narrowed to deeper election or merger result-resolution helpers rather than the ownership of the action lanes themselves.","objdump + strings + caller inspection + control-band correlation" +0x004c2ca0,1964,shell_company_detail_window_refresh_controls,shell,thiscall,inferred,objdump + strings + caller inspection,4,"Shared refresh pass for the shell-side `CompanyDetail.win` family rooted at `0x006cfe4c`. The helper first requires a live shell detail-panel owner at `0x006d0818` with a selected company id in `[detail+0x90]`, resolves that company through the live collection at `0x0062be10`, and then repopulates the section strip and section-specific control bands rooted at `0x9472..0x9490`. Current grounded state is keyed by section index `0x006cfe60`: section `0` is the chairman/governance slice around `0x9480` and the dynamic multi-line overview widget `0x947f`, section `1` is the debt-and-capital slice around `0x947d`, `0x947e`, and `0x9488`, section `2` is the per-share slice around `0x948a`, and section `3` is the territory-access slice around `0x948c`, `0x948d`, and `0x948e`. The same refresh now cleanly splits the four visible section selectors `0x9472..0x9475` from their companion visual controls `0x9476..0x9479`, keeps the adjacent section-navigation or decoration bands around `0x947b..0x947c` and `0x948f..0x9490` synchronized with the current section, and formats the current chairman summary through localized ids `958` `Chairman: %1` and `959` `Chairman: None` together with the portrait-backed chairman band on `0x9480`. The section-0-only bind for `0x947f` is tighter now too: the refresh passes a dedicated stack-built dynamic-text payload through the special `0x6f` control path instead of using the normal callback-widget lane, and the shared helpers `shell_control_refresh_matching_dynamic_text_payload` at `0x00540a47` plus `shell_control_release_dynamic_text_payload` at `0x005639d2` now show that type `0x6f` frees or swaps one heap-backed text payload and then short-circuits as a special case. That keeps `shell_format_company_governance_and_economy_status_panel` at `0x004e5cf0` as the strongest current semantic match for `0x947f` while making the widget itself look more clearly like a display-only dynamic-text control rather than a normal callback widget. One wider action-row split is tighter now that the range loops are explicit: the helper walks `0x94d4..0x9537` as the selected-company-owned governance/action band and applies style `0x65` when the selected company matches the scenario-selected company at `0x00434870`, otherwise `0x87`; it then walks `0x9538..0x959b` as the linked-chairman-owned band and applies style `0x87` when the selected company's linked chairman id `[company+0x3b]` matches the scenario-selected chairman at `0x004337b0`, otherwise `0x65`. The selected-company side is no longer one vague gated block either: scenario-state toggle `[0x006cec78+0x4a8f]` re-enables bankruptcy row `0x94d6` together with passive companion row `0x94d4`, `[0x006cec78+0x4a8b]` re-enables issue-bond row `0x94d7` together with passive companion row `0x94d5`, `[0x006cec78+0x4a87]` re-enables stock issue and stock buyback rows `0x94d8..0x94d9`, `[0x006cec78+0x4a93]` re-enables dividend row `0x94da` together with the same passive companion row `0x94d5`, `[0x006cec78+0x4adb]` re-enables merger row `0x94db`, `[0x006cec78+0x4acb]` re-enables resign row `0x94dc`, and `[0x006cec78+0x4acf]` re-enables takeover row `0x9538`; `0x9493` only re-enables when editor-map mode `[0x006cec74+0x68]` is clear. That makes `0x94d4/0x94d5` read more like passive companion or heading widgets than hidden verbs. The constructor at `0x004c5540` and many message-side branches at `0x004c56a0` converge back into this helper, which makes it the current owner-side refresh pass for the CompanyDetail window rather than a generic company-list helper.","objdump + strings + caller inspection + section-switch correlation + chairman-band correlation + governance-band gating correlation + selected-company styling correlation + dynamic-overview-widget correlation + passive-companion-row gating correlation + scenario-toggle correlation + explicit-row-loop correlation + type-0x6f control correlation" +0x004c5540,347,shell_company_detail_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `CompanyDetail.win` panel later published at `0x006cfe4c`. The constructor installs vtable `0x005d0858`, binds `CompanyDetail.imb` and `CompanyDetail.win` through `0x0053d110` and `0x0053fa50`, seeds the primary action controls `0x9470`, `0x9471`, `0x947d`, `0x947e`, `0x948c`, `0x948d`, and `0x948e` through callbacks `0x004c1730`, `0x004c1ab0`, `0x004c1ec0`, `0x004c22e0`, `0x004c1d70`, and `0x004c1d30`, stores the singleton resources at `0x006cfe50..0x006cfe58`, and then immediately repopulates the visible state through `shell_company_detail_window_refresh_controls` at `0x004c2ca0`. One negative boundary is useful too: current constructor-time binding still does not install dedicated per-row callbacks for the broader section-0 governance bands `0x94d4..0x9537` and `0x9538..0x959b`, which keeps those rows looking more like resource-defined display bands gated and restyled by the refresh pass than like individually code-rendered widgets. A grounded shell detail-manager caller reaches this constructor at `0x004dde24`, which corrects the earlier assumption that the post-roster company branch still had no recovered detail-window owner.","objdump + strings + detail-manager correlation + caller inspection + constructor-binding absence correlation" +0x004c56a0,4228,shell_company_detail_window_handle_message,shell,thiscall,inferred,objdump + strings + caller inspection,4,"Primary message dispatcher for the shell-side `CompanyDetail.win` family rooted at vtable `0x005d0858`. The helper switches on the incoming shell message id and now has a grounded section-selector lane too: message `0xca` on controls `0x9472..0x9475` writes `control-0x9472` into section index `0x006cfe60` before re-entering `shell_company_detail_window_refresh_controls` `0x004c2ca0`. Its broader action band is now tighter as well. Under message `0xcb`, control `0x94b5` routes into `shell_company_detail_buy_territory_access_rights_flow` `0x004c5fc9`, `0x94b6` routes into `shell_company_detail_bankruptcy_flow` `0x004c5b99`, `0x94cf` routes into `shell_company_detail_issue_bond_offer_flow` `0x004c3890`, `0x94d0` routes into `shell_company_detail_issue_stock_offer_flow` `0x004c3f30`, `0x94d1` routes into `shell_company_detail_buyback_stock_flow` `0x004c46d0`, `0x94d2` routes into `shell_company_detail_change_dividend_rate_flow` `0x004c5360`, `0x9493` routes into the destructive company-clear helper `company_deactivate_and_clear_chairman_share_links` `0x00426d60`, `0x94d6` routes into `shell_company_detail_bankruptcy_flow` `0x004c5b99`, `0x94d7` routes into `shell_company_detail_issue_bond_offer_flow` `0x004c3890`, `0x94d8` routes into `shell_company_detail_issue_stock_offer_flow` `0x004c3f30`, `0x94d9` routes into `shell_company_detail_buyback_stock_flow` `0x004c46d0`, `0x94da` routes into `shell_company_detail_change_dividend_rate_flow` `0x004c5360`, `0x94db` routes into `shell_company_detail_attempt_merger_flow` `0x004ec640`, `0x94dc` routes into `shell_company_detail_resign_chairmanship_flow` `0x004c5a0e`, and `0x9538` routes into `shell_company_detail_attempt_chairmanship_takeover_flow` `0x0050ccc0`. The same `0xcb` jump table now makes the passive/action split explicit rather than inferred: in the dispatch byte map rooted at `0x004c6640`, offsets `0x4b..0x51` for controls `0x94d6..0x94dc` map to cases `0x06..0x0c`, offset `0xad` for control `0x9538` maps to case `0x0d`, and the neighboring companion rows `0x94d4` and `0x94d5` stay on the default `0x0e` path. The debt-side row bands are narrower now too: under the same `0xcb` path, controls `0x94e8..0x950f` and `0x9510..0x9537` resolve a selected debt-slot index beneath the two bond panels `0x947d` and `0x947e`, reject repayment when the selected slot's principal exceeds the current cash-side metric through localized id `2990`, otherwise open the localized early-repayment confirmation rooted at id `2991`, and on acceptance either commit through `company_repay_bond_slot_and_compact_debt_table` `0x00423d70` or package the same request through the multiplayer shell transport. The same dispatcher also now bounds most of the section-0 control cluster: control `0x948b` is a tutorial-guarded escape or back control that either shows localized id `3724` `This option is disabled in the tutorial.` or falls back to `0x004ddbd0`, controls `0x9491` and `0x9492` only restyle the paired visual controls `0x948f` and `0x9490`, and control `0x9494` opens localized id `3635` `Enter the amount that your company's cash should be` through the shell numeric-entry dialog family and then writes the accepted value into the selected company cash pair at `[company+0x11f7]` and `[company+0x11fb]`. Current `0xcb` dispatch does not treat `0x948f`, `0x9490`, `0x94d4`, or `0x94d5` as standalone action cases, and the refresh-side gates now sharpen that split further: `0x94d4` is the passive companion row that comes back beside bankruptcy `0x94d6`, while `0x94d5` is the passive companion row that comes back with the issue-bond/dividend side of the finance cluster `0x94d7` and `0x94da`. The remaining open section-0 control is therefore mainly `0x947f`, plus the still-unsplit render-side text rows inside the broader governance bands `0x94d4..0x9537` and `0x9538..0x959b`. It repeatedly converges back into `shell_company_detail_window_refresh_controls` after state changes. Current grounded evidence is enough to treat this as the real company-detail owner path, while the remaining uncertainty has narrowed to the last section-0 summary binding and deeper governance-row semantics rather than the ownership of the action lanes themselves.","objdump + strings + caller inspection + jump-table correlation + section-selector correlation + debt-row-band correlation + cash-edit dialog correlation + tutorial-guard correlation + governance-band companion-row correlation + passive-companion-row gating correlation + control-jump-table byte-map correlation" 0x004c5a0e,268,shell_company_detail_resign_chairmanship_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` resignation confirmation flow. The branch opens localized confirmation id `964` `Are you sure you want to resign the chairman's position?` and on acceptance commits the change through `company_clear_selected_chairman_if_current_profile` at `0x00428a10`. When the multiplayer-side shell owner is active it packages the same request through the asynchronous shell transport path rooted at `0x006cd8d8` instead of mutating the company immediately. Current grounded owner is the wider company-detail message dispatcher at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + dialog correlation" 0x004c5b99,428,shell_company_detail_bankruptcy_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` bankruptcy action flow. The branch checks the localized cooldown and eligibility strings `965` through `967`, rejects requests when the selected company is not yet bankruptable, and on acceptance commits the change through `company_declare_bankruptcy_and_halve_bond_debt` at `0x00425a90`. When the multiplayer-side shell owner is active it packages the same request through the asynchronous shell transport path rooted at `0x006cd8d8` instead of mutating the company immediately. Current grounded owner is the wider company-detail message dispatcher at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + bankruptcy-dialog correlation" 0x004c5fc9,659,shell_company_detail_buy_territory_access_rights_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` territory-access purchase flow for the currently selected territory. The branch first resolves the selected territory from the territory-summary controls rooted at `0x948c..0x948e`, requires that the detail panel is still showing the current chairman-owned company, then splits cleanly by access state. When the company lacks rights but the territory is purchasable, it computes the access-rights price through `0x004879f0`, shows localized id `961` when purchase is possible, id `962` when cash is insufficient, and id `963` when rights cannot be purchased at all. Accepting id `961` commits the change through `company_set_territory_access_rights_byte` at `0x00424030` and the cash-side mutation at `0x0042a040`; when the multiplayer-side shell owner is active it instead packages the same request through the asynchronous shell transport path rooted at `0x006cd8d8`. Current grounded owner is the wider company-detail message dispatcher at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + territory-access branch correlation" +0x004c98a0,880,shell_open_custom_modal_dialog_with_callbacks,shell,cdecl,inferred,objdump + caller inspection,4,"Generic shell modal opener for callback-driven custom dialogs. The helper snapshots the current detail-owner context, stores one caller-supplied mode or prompt token at `0x00621f40`, stores one optional custom control callback or row-owner token at `0x006cfeb0`, allocates a shared `0xa0`-byte modal object with vtable `0x005d0a04`, and seeds it through the lower constructor at `0x004c86c0` using the caller's custom message, setup, and render callbacks plus the surrounding button or style parameters. When the optional callback slot is present it also binds that callback onto control `0x03ed`. The same helper temporarily pushes shell modal state through `0x0053f000`, enters the visible modal loop through `0x00538f10`, and then tears the object back down while restoring the surrounding shell or world presentation state. Current grounded callers include the CompanyDetail finance dialogs for bond issue, stock issue, stock buyback, and dividend changes, plus `multiplayer_open_staged_text_entry_dialog` at `0x004ee0e0`.","objdump + caller inspection + modal-lifecycle correlation" +0x004c8670,11,shell_mark_custom_modal_dialog_dirty,shell,cdecl,inferred,objdump + nearby-constructor correlation + frame-caller inspection,4,"Tiny dirty-latch setter paired with the shared callback-driven custom modal family rooted at `0x006cfeb4`. The helper stores `1` into `0x006cfeac`, which current nearby call patterns treat as the custom-modal refresh or service request latch after the lower constructor at `0x004c86c0` and opener `shell_open_custom_modal_dialog_with_callbacks` have published a live modal object. Current grounded caller is the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`.","objdump + nearby-constructor correlation + frame-caller inspection + custom-modal correlation" +0x004c8680,14,shell_has_live_custom_modal_dialog,shell,cdecl,inferred,objdump + nearby-constructor correlation + frame-caller inspection,4,"Tiny presence probe for the shared callback-driven custom modal family. The helper reads the live modal singleton at `0x006cfeb4`, returns `1` when that pointer is positive or nonnull, and returns `0` otherwise. Current grounded caller is the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, where this branch now sits beside the `LoadScreen`, file-options, and other shell-window probes rather than any detached gameplay-only UI owner.","objdump + nearby-constructor correlation + frame-caller inspection + custom-modal correlation" +0x004e1d60,1169,shell_load_screen_refresh_page_strip_and_page_kind_controls,shell,thiscall,inferred,objdump + descriptor-table decode + caller inspection,4,"Shared refresh helper beneath the shell-side `LoadScreen.win` family. The helper reads the active 13-byte page descriptor record at `0x006220a0 + page*0x0d` using current page id `[this+0x78]`, where the record now grounds as `{ page_kind_dword, title_string_id, back_link_page_dword, selected_company_header_flag_byte }`. It copies the descriptor kind into `[this+0x80]`, refreshes the page-strip and companion controls `0x3e80`, `0x3e81`, `0x3eee..0x3ef7`, `0x3ef8`, `0x3efb`, `0x3efc`, `0x3f0a`, `0x3f0b`, and `0x3f0e` through the generic shell control path at `0x00540120`, and applies page-specific row-band styling from current page-local row state `[this+0x7c]`, row count `[this+0x84]`, and stacked selection history `[this+0x0a0..0x118]`. The descriptor decode now also bounds control `0x3ef8` as the table-driven backlink affordance: page `0` keeps backlink `0`, page `1` backlinks to page `2`, page `8` backlinks to page `7`, page `0x0b` backlinks to page `0x0a`, and page `0x0d` backlinks to page `0x0c`. Current descriptor decode therefore keeps page `0` as kind `0`, title id `1200` `XXX`, backlink `0`, and header flag `0`; page `1` as company-overview kind `1` with backlink page `2`; page `8` as player-detail kind `3` with backlink page `7`; page `0x0b` as dormant train-detail title with backlink page `0x0a`; and page `0x0d` as dormant station-detail title with backlink page `0x0c`. Current grounded caller is `shell_load_screen_select_page_subject_and_refresh` at `0x004e2c10`, which uses this helper after storing a new page or subject selection.","objdump + descriptor-table decode + caller inspection + control-style correlation + backlink-control correlation" +0x004e2c10,3472,shell_load_screen_select_page_subject_and_refresh,shell,thiscall,inferred,objdump + caller inspection + state-flow correlation,4,"Shared page or subject selector beneath the shell-side `LoadScreen.win` family rooted at `0x006d10b0`. The helper accepts a page id, a page-local subselector, and an optional subject id; defaults of `-1` reuse the current fields at `[this+0x78]`, `[this+0x7c]`, and caller-selected company or profile state. It stores the chosen page in `[this+0x78]`, the subselector in `[this+0x7c]`, resets several page-local fields including `[this+0x84]` and the report-row latch at `[this+0x75c]`, updates the current company id `[this+0x88]` or profile id `[this+0x8c]` depending on page ownership, and then repaints the active page controls through `0x00563250` and `0x0053fe00`. Several page-specific branches also recompute bounded row-count state for the report lists on pages `0x0a`, `0x0c`, `0x0f`, and `0x0e`, including row styling over control band `0x3f48..`. The surrounding descriptor table now makes one narrower part of this family explicit too: when control `0x3ef8` is used as a backlink affordance, the selected page target comes from the current descriptor backlink dword rather than from a separate hardcoded detail-page branch. Current grounded callers include the broad `LoadScreen.win` dispatcher at `0x004e3a80`, the page-specific stock-holdings branch at `0x004e45d0`, and the selected-company or selected-profile step helpers at `0x004e3a00` plus `0x004e45d0`, so this now reads as the family-wide page or subject refresh owner rather than a CompanyDetail helper.","objdump + caller inspection + state-flow correlation + page-refresh correlation + backlink-target correlation" +0x004e3a00,112,shell_load_screen_step_selected_company_delta,shell,thiscall,inferred,objdump + caller inspection + company-collection correlation,4,"Steps the current `LoadScreen.win` selected company forward or backward across the active company roster. The helper wraps `selected_company + delta` through `company_collection_count_active_companies` at `0x00429a50`, resolves the replacement id through `company_collection_get_nth_active_company_id` at `0x00429990`, stores it into `[this+0x88]`, and then re-enters `shell_load_screen_select_page_subject_and_refresh` at `0x004e2c10` with the current page id in `[this+0x78]`. Current grounded callers are the `0x3efd/0x3efe` year or company navigation lane inside `LoadScreen.win`.","objdump + caller inspection + company-collection correlation + page-refresh correlation" +0x004e3a80,2900,shell_load_screen_window_handle_message,shell,thiscall,inferred,objdump + caller inspection + resource correlation,4,"Primary message dispatcher for the shell-side `LoadScreen.win` family rooted at singleton `0x006d10b0`. The handler switches on the incoming shell message id and owns page state `[this+0x78]`, page-local substate `[this+0x7c]`, page-kind byte `[this+0x80]`, current company `[this+0x88]`, current chairman profile `[this+0x8c]`, display year `[this+0x9c]`, and the page-local report-row latch `[this+0x118]`. Message `0xcb` on the page-strip controls routes through the page-kind dispatch rooted at `[this+0x80]`, where several cases re-enter `shell_load_screen_select_page_subject_and_refresh` at `0x004e2c10`, the company-step helper at `0x004e3a00`, or narrower page handlers such as `0x004e45d0`. One separate control band `0x3fd4..0x4073` selects report or list pages by updating `[this+0x75c]` and a boolean accent latch `[this+0x760]` before refreshing control `0x3fac`. The row band `0x3f48..0x3f51` is tighter now too: on page `7` it promotes one selected player row into page `8` through `shell_load_screen_select_page_subject_and_refresh`; on page `0x0a` it routes the chosen train through the shell detail-panel manager `0x004ddbd0` in mode `2` and then centers via `0x00437a90`; on page `0x0c` it routes the chosen station through the same manager in mode `5` and then centers via `0x00437a90`; and on page `0x0f` it routes the chosen industry or building through the same manager in mode `0x0a` before the same centering path. Current grounded ownership therefore includes the company or profile page routes for ids `0`, `2`, `7`, `8`, `9`, `0x0a`, `0x0c`, `0x0e`, and `0x0f`, while the title-table detail ids `0x0b` and `0x0d` still do not appear on the live row-click path or any recovered page-strip action lane. This makes `0x004e3a80` the real outer `LoadScreen.win` message owner above the sibling renderers at `0x004e5300`, `0x004e5a80`, and `0x004e5cf0` rather than a loose shared helper.","objdump + caller inspection + resource correlation + page-dispatch correlation + report-tab correlation + row-click-route correlation" +0x004e39e0,19,company_query_display_year_or_current_year,simulation,thiscall,inferred,objdump + caller inspection,4,"Tiny company-side helper that returns the optional display year cached at `[this+0x9c]` when nonzero, otherwise falls back to the current scenario year at `[0x006cec78+0x0d]`. Current grounded callers include the shared governance or economy shell formatter at `0x004e5cf0` and several nearby company-readout helpers in the same shell display family.","objdump + caller inspection + year-fallback correlation" +0x004e1f50,14,shell_has_live_load_screen_window,shell,cdecl,inferred,objdump + global-state inspection + frame-caller inspection,4,"Tiny shell-side presence probe for `LoadScreen.win`. The helper reads the live ledger singleton at `0x006d10a8`, returns `1` when that pointer is nonnull, and returns `0` otherwise. Current grounded callers include the frame-owned cadence at `simulation_frame_accumulate_and_step_world` `0x00439140`, where this branch now sits beside other shell-window service probes rather than any detached gameplay-only input owner.","objdump + global-state inspection + frame-caller inspection + LoadScreen singleton correlation" +0x004e1f60,11,shell_mark_load_screen_window_dirty,shell,cdecl,inferred,objdump + global-state inspection + frame-caller inspection,4,"Tiny shell-side dirty-flag setter paired with `shell_has_live_load_screen_window`. The helper stores `1` into `0x006d10a4`, which current nearby call patterns treat as the `LoadScreen.win` refresh or service request latch once the live ledger singleton at `0x006d10a8` exists. Current grounded caller is the post-step shell-window service ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`.","objdump + global-state inspection + frame-caller inspection + LoadScreen singleton correlation" +0x004e45d0,757,shell_load_screen_profile_stock_holdings_page_handle_message,shell,thiscall,inferred,objdump + RT3.lng strings + control-id inspection,4,"Page-specific message handler for the `LoadScreen.win` stock-holdings slice. The handler owns controls `0x3ef6..0x3f1d` while page-kind `[this+0x80]` selects this branch from the outer dispatcher at `0x004e3a80`. Current grounded state includes the selected profile id `[this+0x8c]`, selected company id `[this+0x88]`, optional display year `[this+0x9c]`, and a local row index `[this+0x118]`. Controls `0x3ef6` and `0x3ef7` step `[this+0x118]` backward or forward within a bounded `0..10` band before re-entering `shell_load_screen_select_page_subject_and_refresh` at `0x004e2c10`; `0x3ef8`, `0x3efb`, and `0x3efc` reuse that same helper to activate or step the current company row and page-local selector state. The later jump-table lane rooted at `0x3f07` also cycles the selected profile through the active-chairman collection at `0x006ceb9c` using `profile_collection_count_active_chairman_records` at `0x00477820`, `0x005184f0`, and `0x00518380`, then refreshes the current page through `0x004e2c10`. The same page branch adjusts the display year `[this+0x9c]` through the company-step helper `0x004e3a00` and the fallback reader `company_query_display_year_or_current_year` at `0x004e39e0`. Current grounded meaning is the stock-holdings page handler beneath `LoadScreen.win`, not the outer window dispatcher.","objdump + RT3.lng strings + control-id inspection + active-profile-cycle correlation + year-step correlation + row-selection correlation" +0x004e4b10,720,shell_load_screen_reset_runtime_state_and_seed_selection,shell,thiscall,inferred,objdump + caller inspection + state-flow correlation,3,"Lower reset or seed helper used by the `LoadScreen.win` opener before the visible ledger loop begins. The helper clears page state `[this+0x78]`, page-local substate `[this+0x7c]`, display year `[this+0x9c]`, selected company `[this+0x88]`, selected chairman profile `[this+0x8c]`, the page-kind cache `[this+0x80]`, the page-strip history stack rooted at `[this+0x0a0]`, and several presentation-side pointers including `[this+0x0b2d]` and `[this+0x0b31]`. It then seeds the selected company and chairman from the current scenario state through `0x004337a0` and `0x004337b0`, allocates the main text surface at `[this+0x0e55]`, builds several descriptor or name caches under `[this+0x0b25]`, `[this+0x0b29]`, `[this+0x0761..]`, `[this+0x0995..]`, and `[this+0x0b35..]`, binds three callback-style controls `0x3ee4`, `0x3ef4`, and `0x3ee5` through the generic shell control path at `0x00540120`, and stores the caller-selected display year into `[this+0x9c]`. Current grounded caller is the higher `LoadScreen` opener at `0x004e4ee0`, which later enters the page-selection refresh path. This now reads as the runtime reset and cache-seed helper beneath ledger opening rather than as a page renderer.","objdump + caller inspection + state-flow correlation + cache-seed correlation" +0x004e4ee0,406,shell_open_or_focus_load_screen_page,shell,thiscall,inferred,objdump + caller inspection + RT3.lng strings + launch-flow correlation,4,"Shared higher-level opener for the shell-side `LoadScreen.win` ledger family. The caller supplies one requested page id in `ECX`. When sandbox flag byte `[0x006cec7c+0x82]` is set the helper does not open the ledger; instead it raises a simple shell modal through `shell_open_custom_modal_dialog_with_callbacks` using localized id `3899` `The ledger is not available in sandbox mode.`. Outside sandbox it first checks for an existing live ledger runtime at `0x006d10a8`: when one is already open and the requested page id is nonzero it simply re-enters `shell_load_screen_select_page_subject_and_refresh` at `0x004e2c10` with that page; when the live runtime exists and the requested page id is zero it leaves the current page unchanged. When no live runtime exists it allocates the transient ledger object into `0x006d10a8`, resets and seeds it through `shell_load_screen_reset_runtime_state_and_seed_selection` at `0x004e4b10`, enters the visible shell modal loop through `0x00538f10`, and then tears the object back down while restoring the surrounding shell presentation state. Current grounded callers include the world-frame command path at `0x0043970f`, the grouped shell command stubs at `0x0044070e..0x0044086e` for pages `1`, `2`, `3`, `4`, `5`, `6`, `7`, `9`, `0x0a`, `0x0c`, `0x0e`, and `0x0f`, and the shell detail-side launcher at `0x004de82b`; no current recovered opener in that family requests page `0x0b` or `0x0d`. This now reads as the shared open-or-focus ledger-page owner rather than an unnamed helper beside the page family.","objdump + caller inspection + RT3.lng strings + launch-flow correlation + sandbox-guard correlation" +0x004e5130,186,shell_load_screen_render_company_stock_data_panel,shell,thiscall,inferred,objdump + RT3.lng strings + helper correlation,4,"Selected-company stock-data page renderer inside `LoadScreen.win`. The helper first validates the current company id at `[this+0x88]` through the live company collection at `0x0062be10`. When no company is active it emits localized id `1299` `No stocks to view at this time...` through the shell text presenter and restyles control `0x3efd` inactive. On the populated path it falls through into the shared stock-data builder at `0x004c0160` using the temporary holdings buffer at `[this+0x995]`, current row or subselector state at `[this+0x0b25]` and `[this+0x0b29]`, and the stock-data descriptor table rooted at `0x00622098`. That lower helper iterates the active chairman roster, ranks the largest positive holders for the selected company, and formats the `Largest Shareholders`, `Shares`, and `Per Share Data` family under localized ids `928..930`. Current grounded caller is page `7` of `shell_load_screen_render_active_page_panel` at `0x004ea060`, so current best page meaning is the `Stock Data` slice rather than another generic company list.","objdump + RT3.lng strings + helper correlation + shareholder-ranking correlation + stock-data fallback correlation" +0x004e51ea,246,shell_load_screen_render_game_status_briefing_panel,shell,thiscall,inferred,objdump + RT3.lng strings + helper correlation,4,"Game-status-side briefing renderer inside `LoadScreen.win`. The helper uses page-local subselector `[this+0x7c]` to build one packed key and then queries the live scenario text store at `0x0062be18` through `0x00432f40` with kind `9`, writing the returned briefing text into a stack buffer before presenting it through the shell text surface rooted at `[this+0x0e55]`. It then appends the localized title or help pair `1772` `Briefing` and `1773` `View the scenario briefing.` through the smaller shell text-widget writer at `0x00563290`. Current grounded caller is page `3` of `shell_load_screen_render_active_page_panel` at `0x004ea060`, so current best meaning is the `Game Status` briefing page or panel rather than a company-owned report list.","objdump + RT3.lng strings + helper correlation + scenario-text-store correlation + briefing-string correlation" +0x004e5300,1899,shell_load_screen_render_player_detail_stock_holdings_panel,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection + page-title-table decode,4,"Renders the selected-profile stock-holdings summary panel inside the shell-side `LoadScreen.win` family. The helper resolves the selected profile id at `[this+0x8c]` through the live chairman collection at `0x006ceb9c`, builds the top summary rows under localized ids `1204` `Stock Value:`, `1205` `Total Assets:`, and `1206` `Stock Holdings:`, then walks the active company roster through `company_collection_count_active_companies` at `0x00429a50` plus `company_collection_get_nth_active_company_id` at `0x00429a90`. For each active company with positive profile holdings in `[profile + company_id*4 + 0x15d]`, it formats one company row under ids `1201` `Click to view details on %1.`, `1207` `%1 Shares`, and `1208` `%1 Value`; when no positive holdings survive the sweep it emits fallback id `1209` `None`. The panel also checks the scenario-selected chairman through `0x004348c0`, and only for that currently selected profile does it append localized id `3029` `Click to change player name and portrait.` together with the adjacent `1941` `Change` affordance through the shell text-widget writer at `0x00563290`. The `LoadScreen.win` page-title descriptor table rooted at `0x006220a4` now ties current grounded caller page `8` to localized title id `1192` `PLAYER DETAIL`, so this renderer is no longer just a generic holdings page.","objdump + RT3.lng strings + caller inspection + active-company-iteration correlation + holdings-slot correlation + selected-profile affordance correlation + page-title-table decode" +0x004e5a80,2368,shell_render_company_overview_panel_header_and_optional_change_affordance,shell,thiscall,inferred,objdump + RT3.lng strings + helper correlation,4,"Broader company-side overview-panel renderer above the shared text-formatting entry later mapped at `0x004e5cf0`. The wrapper first checks the selected company id at `[this+0x88]`. When that id is absent or no longer resolves through the live company collection at `0x0062be10`, it chooses one of three fallback text families `1210` `You haven't started a company yet...`, `3043` `You don't control a company at the moment...`, or `3888` `You don't control a company at the moment.` from current chairman/company state, paints that fallback into the current shell text surface, and styles controls `0x3f06` and `0x3f07` inactive through the generic control path at `0x00540120`. When a valid company is present, it styles those same controls active, falls through into the shared metric/governance body later labeled at `0x004e5cf0`, and on the narrower branch where the selected company matches the scenario-selected company at `0x00434870` it also appends localized id `3044` `Click to change company name and logo.` and publishes the adjacent `1941` `Change` affordance through the shell text-widget writer at `0x00563290`. Current evidence therefore keeps the name/logo affordance outside the normal `CompanyDetail.win` callback dispatcher and makes `0x004e5cf0` read more like the shared text-formatting subentry within this wider overview-panel renderer than like a full standalone owner by itself.","objdump + RT3.lng strings + helper correlation + fallback-text correlation + overview-wrapper correlation" +0x004e5cf0,1844,shell_format_company_governance_and_economy_status_panel,shell,cdecl,inferred,objdump + RT3.lng strings + helper correlation,4,"Shared shell text formatter for one company-side overview panel. The helper first renders a five-line company-metric preamble from the generic stat reader `0x0042a5d0` using display-year-aware company slots `0x2c`, `0x2b`, `0x17`, and `0x26` plus one derived ratio branch. That preamble is now grounded 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 with a safe `1.0` fallback when the load-mile value is nonpositive, and `Average speed` from slot `0x26` rendered through localized value formatter `1216` `%1 m.p.h.`. Its governance branch is now tighter too: when the selected company has no linked chairman it emits localized id `3045` `This company is controlled by the shareholder's committee...`; when the company is wholly owned it emits `3046` `You have complete ownership...` for the scenario-selected chairman or `3047` `This company is wholly owned by %1` for another linked chairman; otherwise it emits the investor-attitude lines `3048` `Investors are %1 your performance.` or `3049` `Investors are %1 the chairman's performance.` using the adjective table at `0x00622170`. The salary branch is bounded now too: it computes a signed salary delta from the company fields at `[company+0x14f]` and `[company+0x0d59]`, formats the absolute change and current salary value through the numeric helpers at `0x0051bfe0`, and then chooses `3050..3052` when the linked chairman is the scenario-selected chairman or `3053..3055` for another linked chairman depending on whether the delta is negative, positive, or zero. The bonus branch is narrower as well: only when the display year from `company_query_display_year_or_current_year` `0x004e39e0` matches the recorded bonus year at `[company+0x34f]` does it append `3056` `You have been awarded a bonus of %1.` or `3057` `The chairman has been awarded a bonus of %1.` using the bonus amount at `[company+0x353]`. The same formatter then appends the localized economy tail caption `1218` `Economy status - %1.` from the current scenario economy state at `[0x006cec78+0x2d]` and continues by staging 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 those report or list labels under `shell_company_detail_window_handle_message` at `0x004c56a0`, so this strip currently reads as staged overview text or help content rather than as a closed dispatcher-owned launcher family. It uses the linked-chairman accessor `0x00426ef0`, the company-ownership test at `0x004768c0`, the display-year bucket helper `0x004240c0`, and the economy-status table at `0x00620cc0`. Current direct shell binding is still open, but the section-0 refresh for `CompanyDetail.win` now routes control `0x947f` through a dedicated stack-built dynamic text path, so this remains the strongest current shared formatter family aligned with that overview widget.","objdump + RT3.lng strings + helper correlation + governance-status string correlation + CompanyDetail overview correlation + metric-preamble correlation + report-launch-strip correlation + ownership-branch correlation + salary-bonus branch correlation + negative-dispatch-boundary correlation + preamble-label-table correlation" +0x004e68e0,1521,shell_load_screen_render_company_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection + page-title-table decode,4,"Renders the active-company comparison page inside `LoadScreen.win`. The helper first rejects the empty-company case with one fallback text branch rooted at localized ids `1210`, `3043`, or `3888`, then clears the shared row buffer at `[this+0x11c]`, stages the visible company-comparison column family `1235..1242`, and iterates the active company roster through `company_collection_count_active_companies` at `0x00429a50` plus `company_collection_get_nth_active_company_id` at `0x00429a90`. The caller-supplied page-local selector chooses which company metric to rank on: revenue through slot `0x2c`, profit through slot `0x2b`, cash through slot `0x0d`, or track mileage through slot `0x25`, all read through the generic company stat reader at `0x0042a5d0`. The emitted row lane also stages the adjacent company-report affordances `1243` `Click to view %1's income statement.`, `1244` `Click to view %1's balance sheet.`, and `1245` `Click to view %1's haulage reports.` on top of the ranked company rows, while applying the stronger highlight path when the row company matches the scenario-selected chairman's current company. The `LoadScreen.win` page-title descriptor table rooted at `0x006220a4` now ties current grounded caller page `2` to localized title id `1186` `COMPANY LIST`, so this renderer is now bounded as the company-list page rather than only a generic financial ranking helper.","objdump + RT3.lng strings + caller inspection + active-company-iteration correlation + company-stat-slot correlation + report-affordance correlation + page-title-table decode" +0x004e6ef0,1879,shell_load_screen_render_player_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection + page-title-table decode,4,"Renders the active-chairman comparison page inside `LoadScreen.win`. The helper clears the shared row buffer at `[this+0x11c]`, stages the visible chairman-comparison headers from the localized family `1237`, `1241`, `1246`, `1247`, `1248`, `1249`, and `1250`, then iterates the active chairman profile collection at `0x006ceb9c` through `profile_collection_count_active_chairman_records` and the `nth active` accessors rooted at `0x00477820`, `0x00477860`, and `0x004778c0`. The caller-supplied selector chooses which chairman-side metric drives the ranking: cash or one direct profile-held total, stock value, one broader total or net-worth lane, and a purchasing-power lane read through the profile helpers at `0x00476320`, `0x00476780`, `0x00476bb0`, and `0x004778c0`. The row builder also uses the profile-side name and portrait-family tables around `0x00622192..0x006221a4`, with special-cased current-player text on the zero-th row and the stronger highlight path when one ranked profile matches the scenario-selected chairman. The `LoadScreen.win` page-title descriptor table rooted at `0x006220a4` now ties current grounded caller page `7` to localized title id `1191` `PLAYER LIST`, so this renderer is now bounded as the player-list page rather than only a chairman-wealth ranking helper.","objdump + RT3.lng strings + caller inspection + active-profile-iteration correlation + profile-metric correlation + wealth-ranking-string correlation + page-title-table decode" +0x004e7670,3033,shell_load_screen_render_company_train_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Renders the company-owned train list page inside `LoadScreen.win`. The helper first rejects missing selected-company state through localized id `1210` and then rejects companies with no trains through id `1251` `This company does not have any trains.` after querying the current company through the live company collection at `0x0062be10` and the train-count helper at `0x004264c0`. On the populated path it clears the `0x190`-dword row buffer at `[this+0x11c]`, reads the optional display year through `company_query_display_year_or_current_year` at `0x004e39e0`, stages the visible column headers and sort-help family `1235..1242`, and then iterates the selected company's live train roster through the company-side train accessors around `0x004264c0`, `0x00426520`, `0x004a7270`, `0x004a77b0`, and `0x0041adb0`. The emitted row family matches the player-facing train-list strip: revenue, profit, cash, track mileage, engine type, age, oil, water, sand, speed, and profit rows from `1252..1266`, plus the per-row camera-centering affordance `1267` `Click to center the camera on %1`. Current grounded caller is the wider `LoadScreen.win` render family around `0x004ea499`, which keeps this as one company-list page sibling beside the holdings, building, station, and cargo pages rather than a `CompanyDetail.win` subpanel.","objdump + RT3.lng strings + caller inspection + company-train-roster correlation + train-list-string correlation" +0x004e8270,2336,shell_load_screen_render_company_industry_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection + page-title-table decode,4,"Renders the selected-company industry list page inside `LoadScreen.win`. The helper rejects missing selected-company state through localized id `1210` and rejects companies with no owned buildings through id `1268` `This company does not own any buildings.` after resolving the current company through `0x0062be10` and the building-count helper at `0x004266c0`. On the populated path it clears the shared row buffer at `[this+0x11c]`, stages the visible header and sort-help family `1269..1278`, and then walks the selected company's owned placed-structure set through the building-side accessors around `0x004266c0`, `0x004267f0`, `0x0062b26c`, `0x0047de00`, `0x0040cac0`, `0x0040ca70`, `0x0040ca80`, and `0x0040d360`. The rendered rows align with the player-facing industry list strip: industry or building type, year built, profitability, loads consumed, loads generated, and the surrounding sort hints. The `LoadScreen.win` page-title descriptor table rooted at `0x006220a4` now ties current grounded caller page `15` to localized title id `1199` `INDUSTRY LIST`, which makes this the industry-list page rather than a generic building-list sibling.","objdump + RT3.lng strings + caller inspection + company-building iteration correlation + building-list-string correlation + page-title-table decode" +0x004e8bb0,2198,shell_load_screen_render_company_station_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Renders the company-owned station list page inside `LoadScreen.win`. The helper rejects missing selected-company state through localized id `1210` and rejects companies with no stations through id `1279` `This company does not have any stations.` after resolving the selected company and probing the company-owned station count through `0x00426590`. On the populated path it clears the shared row buffer at `[this+0x11c]`, stages the station-list header and sort-help family `1280..1288`, and then walks the selected company's owned station or placed-structure set through the station-side accessors around `0x00426620`, `0x006cec20`, `0x0047d7d0`, `0x0047d7c0`, `0x0047d7f0`, `0x0047d7e0`, and `0x0047de00`. The emitted rows match the visible station-list strip: cargo out, cargo in, revenue out, revenue in, and the adjacent sort affordances. Current grounded caller is the wider `LoadScreen.win` render family around `0x004ea499`, which keeps this as the company-station page sibling beside the train, building, and cargo pages.","objdump + RT3.lng strings + caller inspection + company-station iteration correlation + station-list-string correlation" +0x004e9460,1694,shell_load_screen_render_map_cargo_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Renders the map-wide cargo list page inside `LoadScreen.win`. The helper clears the shared row buffer at `[this+0x11c]`, stages the cargo-list header and sort-help family `1289..1298`, and then iterates the live structure-candidate collection at `0x0062ba8c` rather than one selected company roster. It filters candidates through `structure_candidate_is_enabled_for_current_year` at `0x0041e220`, then derives one sortable per-cargo metric from `structure_candidate_query_route_style_or_local_availability_metric` at `0x0041e650` plus the direct candidate fields at `+0x5e`, `+0x62`, `+0x6a`, and route-style flag `+0x46`. That keeps the same candidate split visible on this page too: route-style rows use the normalized route-side availability metric from `0x0041e650`, while ordinary rows can still surface the direct local float at `[candidate+0x5a]`. The resulting rows align with the player-facing cargo page: cargo name, number of loads, new loads, loads used, price, and the surrounding sort hints. Current grounded caller is the wider `LoadScreen.win` render family around `0x004ea499`, which keeps this as the cargo-list page sibling beside the selected-profile holdings page and the selected-company train, building, and station lists.","objdump + RT3.lng strings + caller inspection + cargo-candidate iteration correlation + cargo-list-string correlation + route-style-metric correlation" +0x004e9b20,1330,shell_load_screen_render_company_report_history_panel,shell,cdecl,inferred,objdump + caller inspection + page-jump-table correlation + RT3.lng correlation,4,"Shared multi-year company report-table renderer inside `LoadScreen.win`. The helper validates the selected company through the live company collection at `0x0062be10`, derives a bounded display-year window from current display year `[this+0x9c]` and company founding year `[company+0x157]`, clears and repopulates the shared row buffer at `[this+0x11c]`, and then renders one of three page-local report modes selected by its caller-supplied mode argument. The descriptor table rooted at `0x00622192..0x006221a4` now grounds those modes as page `4` `Income Statement`, page `5` `Balance Sheet`, and page `6` `Haulage Report`: mode `0` walks the revenue and expense family `1301..1315`, mode `1` walks the asset and liability family `2816`, `1317..1322`, and mode `2` walks the haulage and operating-stat family `1323..1335`. Ordinary rows read yearly values through `company_read_year_or_control_transfer_metric_value` at `0x0042a5d0`. The two special row families are tighter now too: they feed the `%1/%2` rate inserts for localized strings `2815` and `2816` through `company_compute_negative_cash_balance_interest_rate` at `0x00425880` and `company_compute_positive_cash_balance_interest_rate` at `0x004258c0`. Current grounded callers are the page `4`, `5`, and `6` arms of `shell_load_screen_render_active_page_panel` at `0x004ea060`, so ownership and page semantics are now both bounded.","objdump + caller inspection + page-jump-table correlation + selected-company validation correlation + report-table mode correlation + RT3.lng row-family correlation + descriptor-table decode + special-rate-row correlation" +0x004ea060,1403,shell_load_screen_render_active_page_panel,shell,thiscall,inferred,objdump + caller inspection + page-jump-table correlation + page-title-table decode,4,"Family-wide render dispatcher beneath the shell-side `LoadScreen.win` singleton `0x006d10b0`. The helper first formats the active page heading from the 13-byte page descriptor table rooted at `0x006220a0` using current page id `[this+0x78]`, specifically the title-string dword at record offset `+0x04`. It then lays out the common panel containers through the shell control family rooted at `[this+0x0b31]`, and conditionally exposes the selected-company header affordance on control `0x3f13` when the descriptor header-flag byte at record offset `+0x0c` is set and the current company `[this+0x88]` still resolves through the live company collection at `0x0062be10`. It then switches on the same page id `[this+0x78]` and dispatches into the active page body. Current grounded routes include page `0` through the localized fallback `1203` `Unable to display page`, page `1` through the broader company-overview wrapper around `0x004e5a70/0x004e5a80`, page `2` through `shell_load_screen_render_company_list_panel` at `0x004e68e0`, page `3` through `shell_load_screen_render_company_report_history_panel` at `0x004e9b20` in `Income Statement` mode, page `4` through the same renderer in `Balance Sheet` mode, page `5` through the same renderer in `Haulage Report` mode, page `6` through `shell_load_screen_render_company_stock_data_panel` at `0x004e5130`, page `7` through `shell_load_screen_render_player_list_panel` at `0x004e6ef0`, page `8` through `shell_load_screen_render_player_detail_stock_holdings_panel` at `0x004e5300`, page `9` through `shell_load_screen_render_game_status_briefing_panel` at `0x004e51ea`, page `0x0a` through `shell_load_screen_render_company_train_list_panel` at `0x004e7670`, page `0x0b` through the same localized `1203` fallback, page `0x0c` through `shell_load_screen_render_company_station_list_panel` at `0x004e8bb0`, page `0x0d` through the same localized `1203` fallback, page `0x0e` through `shell_load_screen_render_map_cargo_list_panel` at `0x004e9460`, and page `0x0f` through `shell_load_screen_render_company_industry_list_panel` at `0x004e8270`. That now makes the rendered title order concrete too: `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`. Current grounded click flow is narrower than that title table: list-page row activation now re-enters page `8` for player detail, but train, station, and industry rows jump out through the shell detail-panel manager instead of switching to page `0x0b` or `0x0d`; no current recovered opener targets `0x0b` or `0x0d`; and no current post-constructor selector path has been recovered for page `0`, whose descriptor remains kind `0`, title `1200` `XXX`, backlink `0`, and header flag `0`. The outer ownership is now clear: this is the shared active-page body renderer above the individual `LoadScreen.win` pages rather than just one more page-local helper.","objdump + caller inspection + page-jump-table correlation + page-table correlation + selected-company header correlation + page-mode decode + page-title-table decode + row-click-route correlation" +0x004ea620,219,shell_load_screen_window_construct,shell,thiscall,inferred,objdump + resource strings + constructor inspection,4,"Constructs the shell-side `LoadScreen.win` family later stored at singleton `0x006d10b0`. The constructor installs vtable `0x005d1194`, binds the random background image `LoadScreen%d.imb` through the format string at `0x005d1180`, binds `LoadScreen.win` through `0x0053fa50`, initializes current page `[this+0x78]` to `0`, stores the singleton at `0x006d10b0`, and seeds the first three visible page-strip controls starting at `0x84d3` through the generic control path at `0x00540120`. It also randomizes one background index into shell state byte `[0x006cec74+0x2c7]` while avoiding the immediately previous choice. Current neighboring helpers at `0x004ea720` and `0x004ea730` provide the live-singleton query and destructor for the same family, which makes this the broad owner-side constructor above the page dispatcher at `0x004e3a80` and the sibling renderers at `0x004e5300`, `0x004e5a80`, and `0x004e5cf0`.","objdump + resource strings + constructor inspection + singleton-state correlation + page-strip correlation" 0x004eb890,381,shell_present_merger_vote_outcome_dialog,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Single-player merger-vote outcome presenter used by the merger result path. The helper resolves the two merger companies from `0x006d10dc` and `0x006d10de`, chooses localized title id `729` `Merger Succeeds!!!` or `730` `Merger Fails!!!`, formats the vote tally labels `731` `Votes In Favor:` and `732` `Votes Against:`, and renders the final result dialog through the shell presentation callback rooted at `0x006d111c`. Current grounded caller is `shell_resolve_merger_vote_and_commit_outcome` at `0x004ebd10` on the single-player branch.","objdump + RT3.lng strings + caller inspection + merger-result dialog correlation" 0x004ebd10,1202,shell_resolve_merger_vote_and_commit_outcome,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Resolves the single merger vote, commits the outcome, and records cooldown state. The helper walks the active chairman profile collection at `0x006ceb9c`, computes weighted votes for and against the proposed merger between companies `0x006d10dc` and `0x006d10de`, accumulates the affirmative share count into `0x006d110c`, compares that total against half the target-company value, and then splits by single-player versus multiplayer. In single-player it presents the result through `shell_present_merger_vote_outcome_dialog` at `0x004eb890`; in multiplayer it formats localized id `3059` `Merger between '%1' and '%2' has %3.` with result strings `3060` or `3061` and routes the payload through the shell transport. On success it commits the merger through `0x00427e20`; on failure it stamps the current year into `[company+0x15f]` as the grounded merger-cooldown field.","objdump + RT3.lng strings + caller inspection + merger-vote resolution correlation" 0x004ec640,732,shell_company_detail_attempt_merger_flow,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` merger-attempt flow. The helper rejects empty worlds through localized id `727`, rejects recent failed merger cooldown cases through id `728`, and then opens the merger offer or vote dialog family rooted at the local globals `0x006d10cc..0x006d1120`. The grounded single-player path checks the proposed premium against company cash through localized id `3889`, can open a premium-confirmation prompt through id `4067`, and on acceptance commits through the company merger helper at `0x00427e20` or the broader vote-resolution path at `0x004ebd10`. When the multiplayer-side shell owner is active it packages the same request through the asynchronous shell transport path rooted at `0x006cd8d8` instead of mutating company state immediately. Current grounded owner is the wider company-detail message dispatcher at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + merger-dialog correlation" @@ -203,6 +355,8 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x005076c0,501,shell_station_pick_window_populate_station_rows,shell,cdecl,inferred,objdump + strings + caller inspection,4,"Populates the visible row set for the shell-side `StationPick.win` helper. The helper iterates collection `0x006cec20`, filters entries through `0x0047fd50`, sorts them by the display-name field at `[entry+0x46b]`, and publishes the resulting station names through the helper list control `0x80ea`. It also mirrors the chosen station ids back into the helper-local scratch arrays, updates one status lane through control event `0xaf`, and refreshes the visible row count through control event `0x66`. Current grounded caller is `shell_station_pick_window_construct` at `0x00507620`.","objdump + strings + caller inspection + collection iteration" 0x004d4500,88,shell_ensure_editor_panel_window,shell,cdecl,inferred,objdump + analysis-context,4,Ensures the shell-side EditorPanel.win helper window rooted at 0x006d07b4 exists. When the panel is absent it allocates a 0x7c-byte window object seeds the vtable at 0x005d0cb8 binds the EditorPanel.win resource through 0x0053fa50 publishes the object to the shell runtime through 0x00538e50 event 0x1e and then runs the shared panel-open helper at 0x004d4160.,objdump + analysis-context + strings 0x004dc670,368,shell_file_options_dialog_construct,shell,thiscall,inferred,objdump + strings,4,Constructs the shared shell file-options dialog rooted at fileopt.win. The helper clears the three downstream branch flags at 0x006d07f8 0x006d07ec and 0x006d07f0 binds the fileopt.win resource through 0x0053fa50 publishes the object to the shell runtime and populates several mode-dependent labels and status text before user input is handled.,objdump + strings +0x004dc7d0,14,shell_has_file_options_dialog,shell,cdecl,inferred,objdump + nearby-constructor correlation + frame-caller inspection,4,"Tiny presence probe for the shared shell file-options dialog rooted at `0x006d0800`. The helper returns `1` when the live `fileopt.win` object is present and `0` otherwise. Current grounded callers include the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, where this check now sits beside the `LoadScreen` and custom-modal probes.","objdump + nearby-constructor correlation + frame-caller inspection + fileopt correlation" +0x004dc7e0,11,shell_mark_file_options_dialog_dirty,shell,cdecl,inferred,objdump + nearby-constructor correlation + frame-caller inspection,4,"Tiny dirty-latch setter paired with `shell_has_file_options_dialog`. The helper stores `1` into `0x006d07fc`, which current nearby call patterns treat as the `fileopt.win` refresh or service request latch once the shared file-options dialog exists. Current grounded caller is the same post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`.","objdump + nearby-constructor correlation + frame-caller inspection + fileopt correlation" 0x004dc7f0,477,shell_file_options_dialog_handle_message,shell,thiscall,inferred,objdump + strings,4,Handles the fileopt.win command flow and selects exactly one downstream branch before the shared detail-panel completion dispatcher runs. Successful commands dismiss the dialog then set 0x006d07f8 for the load or restore side 0x006d07ec for the save or package side or 0x006d07f0 for the sibling settings-window escape. The settings branch gates on shell_has_settings_window at 0x004fe120 and lazily opens the shared SettingsWindow.win object through 0x00501e50 while sibling branches show prerequisite dialogs when the requested file operation is not currently allowed.,objdump + strings + caller xrefs 0x004dd010,890,shell_file_request_dialog_collect_target_path,shell,cdecl,inferred,objdump + strings,4,"Builds the modal filerqst.win request dialog and resolves one chosen target path back into the caller buffer. The helper treats dialog modes 0 1 2 3 and 11 as save-side requests and the paired modes 4 8 9 and 10 as load-side requests then swaps the button and prompt text between localized ids 249 250 and 251 252. On success it appends one extension from the static mode table at 0x005f3d58 where 0 or 8=.gms 1 or 9=.gmc 2 or 10=.gmx 3 or 4=.gmp and 11=.gmt. Current neighboring callers tighten that last mode too: the normal shell map coordinators use the `.gms/.gmc/.gmx/.gmp` families for scenario and editor flows, while save mode 11 is only consumed by the auxiliary `.gmt` preview-surface branch shared with the side owner at 0x006cd8d8. When a live runtime world is already active through 0x004839b0 the helper overrides that non-runtime table and appends .smp instead, which makes it the shared bridge between the broad shell coordinators and the runtime-state serializer or restore path rather than only a generic filename prompt.",objdump + strings + mode-table inspection + caller correlation 0x004ddbd0,1096,shell_detail_panel_transition_manager,shell,thiscall,inferred,objdump + analysis-context,3,Transitions the shell detail-panel controller rooted at 0x006d0818 between many window or panel states tracked in [this+0x8c] with optional selection ids cached at [this+0x78] through [this+0x90]. The manager tears down the prior child panel at [this+0x88] through 0x004dd950 updates selector or status UI through 0x004dd410 conditionally opens helper windows such as EditorPanel.win through 0x004d4500 and then allocates one of many shell-facing detail windows including TrainDetail.win TrainList.win and neighboring panel objects before publishing the new child through the shell runtime at 0x006d401c. shell_transition_mode reaches this manager on one branch but the current evidence keeps it on the shell-detail path rather than the first gameplay-world-entry coordinator.,objdump + analysis-context + strings @@ -215,6 +369,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004e0ba0,95,game_uppermost_window_handle_message,shell,thiscall,inferred,objdump + strings + caller xrefs,4,Message dispatcher for the GameUppermost.win overlay object. It seeds one visual-speed field on the command object returned by 0x0053f830 then switches on the incoming message id through the local jump table at 0x004e0d04. The current grounded cases call game_uppermost_window_service_world_hotspot_band during the recurring service path refresh the overlay controls through game_uppermost_window_refresh_controls on a sibling state-change path and route control 0x7922 into the world-mode toggle helper at 0x004349f0 which also updates the same overlay object at 0x006d0820.,objdump + strings + caller xrefs 0x004e0e40,75,shell_ensure_game_uppermost_window,shell,cdecl,inferred,objdump + strings + caller xrefs,4,Ensures the world-facing GameUppermost.win overlay rooted at 0x006d0820 exists. When absent it allocates a 0xae-byte window object constructs it through game_uppermost_window_construct at 0x004e0b20 stores the result globally and publishes it through the shell runtime at 0x006d401c via 0x00538e50. A grounded caller sits in the shell_transition_mode path near 0x004831c0 immediately after the GameMessage.win bring-up branch which ties this overlay to world-mode entry rather than generic shell UI.,objdump + strings + caller xrefs 0x004fe120,14,shell_has_settings_window,shell,cdecl,inferred,objdump,4,Returns whether the shared settings window object rooted at 0x006d1350 is currently live. The fileopt settings escape branch and direct shell command wrappers both gate on this before opening SettingsWindow.win again.,objdump + caller xrefs +0x004fe130,11,shell_mark_settings_window_dirty,shell,cdecl,inferred,objdump + global-state inspection + frame-caller inspection,4,"Tiny dirty-latch setter paired with `shell_has_settings_window`. The helper stores `1` into `0x006d1360`, which current nearby call patterns treat as the `SettingsWindow.win` refresh or service request latch once the live settings singleton at `0x006d1350` exists. Current grounded callers include the post-step shell-window service ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, and the same latch is also cleared during settings-window open or rebuild paths near `0x00501e50`.","objdump + global-state inspection + frame-caller inspection + settings-window open-path correlation" 0x00500640,487,shell_settings_window_construct,shell,thiscall,inferred,objdump + strings,4,Constructs the shared SettingsWindow.win object later stored at 0x006d1350. The helper binds the SettingsWindow.win resource through 0x0053fa50 allocates a page-selection helper at 0x006d1358 walks the 13-entry category table rooted at 0x00622870 and populates the resulting shell control tree with the page labels and ordering data before the window is shown.,objdump + strings 0x00501e50,201,shell_open_settings_window,shell,cdecl,inferred,objdump + strings,4,Lazily allocates and shows the shared SettingsWindow.win shell object at 0x006d1350. When no settings window is live it allocates a 0x78-byte object constructs it through shell_settings_window_construct publishes it to the shell runtime through 0x00538f10 and then notifies the active shell owner at 0x0062be68. Current grounded callers are the direct shell command wrapper at 0x00482b00 the fileopt settings escape branch and one larger shell UI dispatcher branch near 0x0050366a.,objdump + strings + caller xrefs 0x00468d00,222,multiplayer_update_semicolon_name_list,shell,cdecl,inferred,ghidra-headless,4,Adds or removes one player-name token in the semicolon-delimited moderation list rooted at `[ecx+0x905c]`. With mode `1` it appends the supplied token only when not already present writing `;` as the delimiter; with mode `0` it removes the matched token collapses the remainder left and skips an adjacent delimiter when present.,ghidra + rizin + llvm-objdump + strings @@ -296,6 +451,8 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0053b020,70,bootstrap_reset_locale_state,bootstrap,unknown,inferred,ghidra-headless,2,Calls the locale helper at 0x0053ae70 then frees and clears related global pointers before later shell setup continues.,ghidra + rizin 0x0053b010,11,bootstrap_mark_runtime_started,bootstrap,cdecl,inferred,ghidra-headless,2,Single-purpose bootstrap helper that flips a process-global started flag to one before branding and shell setup continue.,ghidra + rizin 0x0054e6d0,42,bootstrap_capture_keyboard_state,bootstrap,cdecl,inferred,ghidra-headless,4,Single-purpose bootstrap probe that snapshots the host keyboard state through GetKeyboardState.,ghidra + rizin +0x00540a47,75,shell_control_refresh_matching_dynamic_text_payload,shell,unknown,inferred,objdump + caller inspection,3,"Small shell-control helper used on one matching control descriptor during refresh or replacement. When the incoming control id matches `[control+0x4]`, the helper frees any prior heap-backed text payload at `[control+0xce]`, clears that field, optionally copies a replacement payload from the caller descriptor through `0x0051d820`, and then returns `0` when the incoming control type is `0x6f` or `1` otherwise. Current grounded importance is the `CompanyDetail.win` section-0 overview widget `0x947f`: together with the sibling helper at `0x005639d2`, this makes type `0x6f` look like a special heap-backed dynamic-text control rather than an ordinary callback widget.","objdump + caller inspection + type-0x6f control correlation" +0x005639d2,22,shell_control_release_dynamic_text_payload,shell,unknown,inferred,objdump + caller inspection,3,"Tiny shell-control release helper that clears one control's attached payload through `0x0051d820` and then returns `0` when the control type at `[this+0x0]` is `0x6f` or `1` otherwise. Current grounded importance is the same CompanyDetail section-0 overview lane around control `0x947f`, where this reinforces that type `0x6f` is treated as a special dynamic-text family with its own release path instead of a normal callback-style widget.","objdump + caller inspection + type-0x6f control correlation" 0x0055da40,424,bootstrap_probe_system_profile,bootstrap,cdecl,inferred,ghidra-headless,4,Collects GlobalMemoryStatus and CPUID feature bits then stores coarse machine capability flags used by later bootstrap decisions.,ghidra + rizin 0x00507b90,346,station_place_refresh_category_controls,shell,cdecl,inferred,objdump + strings + RT3.lng,4,"Refreshes the StationPlace.win category and mode controls for the current placement mode stored at 0x00622af4. The helper now grounds the six top-level category buttons rooted at 0x697c through 0x6981 as `Place a small station` 2197, `Place a medium station` 2198, `Place a large station` 2199, `Place a service tower` 2200, `Place a maintenance facility` 2201, and `Place a non-station building` 2202. It also refreshes the dependent controls around 0x69c8 0x69c9 0x6985 0x6986 and 0x6983 through 0x00540120; current evidence now bounds 0x6985 and 0x6986 as a two-state station-rotation policy toggle keyed by 0x006d1728, where 0x6985 aligns with `When placing the building, it will rotate itself as needed to orient to track or avoid obstacles.` string 2207 and 0x6986 aligns with `When placing the building, it will strictly adhere to the rotation specified by the circle above.` string 2206. In non-station-building mode 5 it can also seed [this+0x8c] from the active StationPlace list control under 0x006d1720 before preview formatting continues.",objdump + strings + RT3.lng + caller xrefs + callsite inspection 0x00508550,363,station_place_format_selected_site_summary,shell,cdecl,inferred,objdump + strings,3,Formats the selected StationPlace target summary for the live tool object. It looks up the active placement record index [this+0x8c] in 0x0062b2fc follows secondary data through field +0x173 into 0x0062b268 combines that with the current staged world coordinates at 0x006d1738 and 0x006d173c and emits the localized summary block through 0x00540120 into the StationPlace.win status area.,objdump + strings + caller xrefs + callsite inspection diff --git a/docs/control-loop-atlas.md b/docs/control-loop-atlas.md index 756853d..b591fd4 100644 --- a/docs/control-loop-atlas.md +++ b/docs/control-loop-atlas.md @@ -6,82 +6,1511 @@ anchor it, and where control is handed to neighboring subsystems. ## CRT and Process Startup -- Roots: `entry` at `0x005a313b`, CRT helpers in the `0x005a2d..0x005ad4..` range, and `app_bootstrap_main` at `0x00484440`. +- Roots: `entry` at `0x005a313b`, CRT helpers in the `0x005a2d..0x005ad4..` range, and + `app_bootstrap_main` at `0x00484440`. - Trigger/Cadence: single process startup path before shell or engine services exist. -- Key Dispatchers: `startup_init_tls_state`, `startup_init_file_handle_table`, `startup_run_init_callback_table`, `__setenvp`, `startup_build_argv`, `___crtGetEnvironmentStringsA`, then `app_bootstrap_main`. +- Key Dispatchers: `startup_init_tls_state`, `startup_init_file_handle_table`, + `startup_run_init_callback_table`, `__setenvp`, `startup_build_argv`, + `___crtGetEnvironmentStringsA`, then `app_bootstrap_main`. - State Anchors: CRT heap and file-handle tables; process environment and argv storage. -- Subsystem Handoffs: exits the generic CRT path at `app_bootstrap_main`, which becomes the first RT3-owned coordinator. -- Evidence: `artifacts/exports/rt3-1.06/startup-call-chain.md`, `artifacts/exports/rt3-1.06/function-map.csv`. -- Open Questions: exact ownership boundary between compiler CRT shims and the first game-owned bootstrap helper; whether any nontrivial startup callbacks seed game globals before `app_bootstrap_main`. +- Subsystem Handoffs: exits the generic CRT path at `app_bootstrap_main`, which becomes the first + RT3-owned coordinator. +- Evidence: `artifacts/exports/rt3-1.06/startup-call-chain.md`, + `artifacts/exports/rt3-1.06/function-map.csv`. +- Open Questions: exact ownership boundary between compiler CRT shims and the first game-owned + bootstrap helper; whether any nontrivial startup callbacks seed game globals before + `app_bootstrap_main`. ## Bootstrap and Shell Service Bring-Up -- Roots: `app_bootstrap_main` at `0x00484440`, `bootstrap_init_shell_window_services` at `0x004840e0`, and `shell_install_global_controller` at `0x0051ff90`. +- Roots: `app_bootstrap_main` at `0x00484440`, `bootstrap_init_shell_window_services` at + `0x004840e0`, and `shell_install_global_controller` at `0x0051ff90`. - Trigger/Cadence: one-time bootstrap handoff immediately after CRT completion. -- Key Dispatchers: `app_bootstrap_main`, `bootstrap_init_shell_window_services`, `shell_install_global_controller`, `shell_service_pump_iteration`, graphics config load or default-init helpers, runtime capability probes, and early shell service initializers under the `0x004610..0x0053f0..` branch. -- State Anchors: global shell controller pointer `0x006d4024`, sibling display/runtime globals under `0x006d402c` and `0x006d4030`, and host capability flags gathered by `bootstrap_probe_system_profile`. -- Subsystem Handoffs: after the global shell controller has been installed the bootstrap path enters the repeating `shell_service_pump_iteration` loop, which services shell-state work and hands each iteration down into the controller frame path; when the shell lifetime ends this same bootstrap path tears the shell bundle down and returns to `app_bootstrap_main`. -- Evidence: `startup-call-chain.md`, function-map rows for `app_bootstrap_main`, `bootstrap_init_shell_window_services`, `shell_install_global_controller`, `shell_service_pump_iteration`, `shell_load_graphics_config_or_init_defaults`, `shell_reset_display_runtime_defaults`, and related graphics setup helpers. -- Open Questions: whether gameplay or in-engine world stepping later escapes this bootstrap-owned shell loop entirely, or whether gameplay entry still rendezvous with the same outer coordinator before the shell bundle is destroyed. +- Key Dispatchers: `app_bootstrap_main`, `bootstrap_init_shell_window_services`, + `shell_install_global_controller`, `shell_service_pump_iteration`, graphics config load or + default-init helpers, runtime capability probes, and early shell service initializers under the + `0x004610..0x0053f0..` branch. +- State Anchors: global shell controller pointer `0x006d4024`, sibling display/runtime globals under + `0x006d402c` and `0x006d4030`, and host capability flags gathered by + `bootstrap_probe_system_profile`. +- Subsystem Handoffs: after the global shell controller has been installed the bootstrap path enters + the repeating `shell_service_pump_iteration` loop, which services shell-state work and hands each + iteration down into the controller frame path; when the shell lifetime ends this same bootstrap + path tears the shell bundle down and returns to `app_bootstrap_main`. +- Evidence: `startup-call-chain.md`, function-map rows for `app_bootstrap_main`, + `bootstrap_init_shell_window_services`, `shell_install_global_controller`, + `shell_service_pump_iteration`, `shell_load_graphics_config_or_init_defaults`, + `shell_reset_display_runtime_defaults`, and related graphics setup helpers. +- Open Questions: whether gameplay or in-engine world stepping later escapes this bootstrap-owned + shell loop entirely, or whether gameplay entry still rendezvous with the same outer coordinator + before the shell bundle is destroyed. ## Shell UI Command and Deferred Work Flow - Roots: shell callback paths that converge on `shell_dispatch_ui_command` at `0x00464410`. -- Trigger/Cadence: event-driven UI command dispatch plus deferred-message queue flushing during shell activity. -- Key Dispatchers: `shell_dispatch_ui_command`, `shell_enqueue_deferred_work_message`, `shell_post_deferred_message_type5`, `shell_post_deferred_message_type6`, `shell_enqueue_deferred_message_type4`, `shell_enqueue_deferred_message_type1`. -- State Anchors: shell object at `0x0062be68`, queue roots around `[this+0x11369d]`, `[this+0x1136a1]`, and `[this+0x1136a5]`, global routing gates at `0x006d4034`, and the separate detail-panel controller rooted at `0x006d0818`. -- Subsystem Handoffs: routes into graphics config, scenario-text export, overlay generation, multiplayer UI, shell detail windows such as `EditorPanel.win` and `TrainDetail.win`, and presentation-facing deferred work later drained by `shell_service_frame_cycle`. -- Evidence: function-map shell rows around `0x00464410`, `0x004d4500`, `0x004ddbd0`, and `0x0051f1d0..0x0051f460`. -- Open Questions: whether the shell command dispatcher is also used by hotkeys or only by UI callback tables; the current `0x006d0818` detail-panel path looks shell-only and does not yet explain gameplay world entry. +- Trigger/Cadence: event-driven UI command dispatch plus deferred-message queue flushing during + shell activity. +- Key Dispatchers: `shell_dispatch_ui_command`, `shell_enqueue_deferred_work_message`, + `shell_post_deferred_message_type5`, `shell_post_deferred_message_type6`, + `shell_enqueue_deferred_message_type4`, `shell_enqueue_deferred_message_type1`. +- State Anchors: shell object at `0x0062be68`, queue roots around `[this+0x11369d]`, + `[this+0x1136a1]`, and `[this+0x1136a5]`, global routing gates at `0x006d4034`, and the separate + detail-panel controller rooted at `0x006d0818`. +- Subsystem Handoffs: routes into graphics config, scenario-text export, overlay generation, + multiplayer UI, shell detail windows such as `EditorPanel.win` and `TrainDetail.win`, and + presentation-facing deferred work later drained by `shell_service_frame_cycle`. +- Evidence: function-map shell rows around `0x00464410`, `0x004d4500`, `0x004ddbd0`, and + `0x0051f1d0..0x0051f460`. +- Open Questions: whether the shell command dispatcher is also used by hotkeys or only by UI + callback tables; the current `0x006d0818` detail-panel path looks shell-only and does not yet + explain gameplay world entry. ## Presentation, Overlay, and Frame Timing -- Roots: the bootstrap-owned `shell_service_pump_iteration` at `0x00483f70`, the shell-state service pass `shell_state_service_active_mode_frame` at `0x00482160`, the installed global shell controller at `0x006d4024`, the pending frame-cycle owner `shell_service_frame_cycle` at `0x00520620`, and the frame-time history path under `shell_update_frame_time_history` at `0x0051fd70`. -- Trigger/Cadence: recurring bootstrap-owned shell service work once the active mode, controller window, and display runtime are live; special modal or content-building paths can also force immediate frame servicing inside that broader cadence. -- Key Dispatchers: `shell_service_pump_iteration`, `shell_state_service_active_mode_frame`, `shell_service_frame_cycle`, `shell_refresh_presentation_frame`, `shell_update_frame_time_history`, `shell_get_smoothed_frame_scalar`, `shell_set_gamma_ramp_scalar`, and overlay builders such as `shell_queue_single_world_anchor_overlay`, `shell_queue_world_anchor_overlay_list`, and `shell_queue_indexed_world_anchor_marker`. -- State Anchors: shell state at `0x006cec74`, active mode pointer `0x006cec78`, shell frame history ring at `0x006d403c`, display/runtime state inside the controller block near `[this+0x114282]` and `[this+0x11428a]`, presentation service pointer at `[this+0x0c]`, and the native controller window handle at `[this+0x00]`. -- Subsystem Handoffs: the bootstrap-owned pump runs shell-bundle polling and shell-state maintenance before the shell-state pass synchronizes active-mode helpers and modal-status work and dispatches the controller frame cycle, which then consumes world/object state for overlays and presentation refresh, uses the controller window handle for one-time `ShowWindow` and related UI interaction, and drains the deferred work queues at the end of the cycle. -- Evidence: function-map rows for `shell_service_pump_iteration`, `shell_state_service_active_mode_frame`, `shell_service_frame_cycle`, `shell_flush_deferred_work_queues`, frame history, gamma ramp, world-anchor overlay builders, and graphics runtime helpers. -- Open Questions: how simulation cadence rendezvous with the shell presentation cadence once gameplay takes over and whether gameplay stepping exits this shell-owned controller path entirely. +- Roots: the bootstrap-owned `shell_service_pump_iteration` at `0x00483f70`, the shell-state service + pass `shell_state_service_active_mode_frame` at `0x00482160`, the installed global shell + controller at `0x006d4024`, the pending frame-cycle owner `shell_service_frame_cycle` at + `0x00520620`, and the frame-time history path under `shell_update_frame_time_history` at + `0x0051fd70`. +- Trigger/Cadence: recurring bootstrap-owned shell service work once the active mode, controller + window, and display runtime are live; special modal or content-building paths can also force + immediate frame servicing inside that broader cadence. +- Key Dispatchers: `shell_service_pump_iteration`, `shell_state_service_active_mode_frame`, + `shell_service_frame_cycle`, `shell_refresh_presentation_frame`, + `shell_update_frame_time_history`, `shell_get_smoothed_frame_scalar`, + `shell_set_gamma_ramp_scalar`, and overlay builders such as + `shell_queue_single_world_anchor_overlay`, `shell_queue_world_anchor_overlay_list`, and + `shell_queue_indexed_world_anchor_marker`. +- State Anchors: shell state at `0x006cec74`, active mode pointer `0x006cec78`, shell frame history + ring at `0x006d403c`, display/runtime state inside the controller block near `[this+0x114282]` and + `[this+0x11428a]`, presentation service pointer at `[this+0x0c]`, and the native controller window + handle at `[this+0x00]`. +- Subsystem Handoffs: the bootstrap-owned pump runs shell-bundle polling and shell-state maintenance + before the shell-state pass synchronizes active-mode helpers and modal-status work and dispatches + the controller frame cycle, which then consumes world/object state for overlays and presentation + refresh, uses the controller window handle for one-time `ShowWindow` and related UI interaction, + and drains the deferred work queues at the end of the cycle. +- Evidence: function-map rows for `shell_service_pump_iteration`, + `shell_state_service_active_mode_frame`, `shell_service_frame_cycle`, + `shell_flush_deferred_work_queues`, frame history, gamma ramp, world-anchor overlay builders, and + graphics runtime helpers. +- Open Questions: how simulation cadence rendezvous with the shell presentation cadence once + gameplay takes over and whether gameplay stepping exits this shell-owned controller path entirely. ## Map and Scenario Content Load -- Roots: `shell_map_file_entry_coordinator` at `0x00445ac0`, the first grounded world-entry branch `world_entry_transition_and_runtime_bringup` at `0x00443a50`, `shell_map_file_world_bundle_coordinator` at `0x00445de0`, reference-database setup via `map_bundle_open_reference_databases` at `0x00444dd0`, and narrower loaders such as `map_load_geographic_label_database` and `map_load_city_database`. -- Trigger/Cadence: shell tutorial launch, editor or detail-panel file actions through `fileopt.win`, map-scenario open paths, and scenario-text export batch commands. -- Key Dispatchers: `shell_map_file_entry_coordinator`, `world_entry_transition_and_runtime_bringup`, `world_runtime_release_global_services`, `shell_map_file_world_bundle_coordinator`, `map_bundle_open_reference_databases`, `map_load_geographic_label_database`, `map_load_city_database`, `scenario_text_export_build_language_file`, `scenario_text_export_report_language_file`, `scenario_text_export_batch_process_maps`. -- State Anchors: shell-side file staging buffers at `0x0062bee0` and `0x0062bec4`, shell and mode globals at `0x006cec74` and `0x006cec78`, world object root `0x0062c120`, map bundle state allocated through `0x00530c80`, and geography tables rooted at `0x0062b2fc` and `0x0062b268`. -- Subsystem Handoffs: the shared `fileopt.win` dialog rooted at `0x004dc670` now looks like the shell-side selector above the two broad file coordinators. Its message handler sets `0x006d07f8` for the load or restore side or `0x006d07ec` for the save or package side before the detail-panel transition manager routes into `shell_map_file_entry_coordinator` or `shell_map_file_world_bundle_coordinator`. The former unresolved third flag at `0x006d07f0` is now accounted for too: it escapes into the standalone `SettingsWindow.win` path through `shell_open_settings_window` rather than another map or save verb. The broad coordinators now hand their interactive work through the shared `filerqst.win` helper at `0x004dd010`, and that helper gives the extension split a firmer shape. The paired editor-map path is now grounded as `.gmp` through load mode `4` and save mode `3`. The remaining non-editor families are no longer anonymous either: `.gmc` is the campaign-scenario branch, backed both by the campaign-screen resignation prompt on `0x006cec7c+0xc5` and by the numbered `%s%02d.gmc` save helper at `0x00517c70`; `.gmx` is the sandbox branch, backed by the shell-side `The briefing is not available in sandbox games.` restriction on `0x006cec7c+0x82`; and the default `.gms` branch is therefore the standalone scenario family. When a live runtime world is already active the same helper bypasses those non-runtime extensions and forces the `.smp` runtime-state branch instead. The auxiliary save-side mode `11` is tighter now too: it still maps to `.gmt`, but instead of looking like another gameplay save family it conditionally diverts into the same `.gmt` preview-surface pipeline owned by the Multiplayer preview dataset object at `0x006cd8d8`, and only falls back to the normal reference-bundle path when that dataset object is absent. -- Evidence: function-map map/scenario rows, analysis-context exports for `0x00445ac0`, `0x00445de0`, `0x00443a50`, `0x00434300`, and `0x00444dd0`, plus objdump string and mode-table evidence for `.gmp`, `.gmx`, `.gmc`, `.gms`, `.gmt`, `.smp`, `Quicksave`, the `0x004dd010` mode table at `0x005f3d58`, the auxiliary-owner presence check at `0x00434050`, and the `.gmt` handoff through `0x00469d30`, together with localized string evidence from ids `3018` and `3898`. -- Open Questions: bit `0x1` on both broad coordinators now grounds the Quicksave name seed and the former third `fileopt.win` flag has been ruled out as a file-flow question because it just opens `SettingsWindow.win`. The old broad extension question is mostly resolved: `.gmp` is the editor-map pair, `.gms` is the standalone scenario family, `.gmc` is the campaign-scenario family, `.gmx` is the sandbox family, and `.gmt` is at least bounded as an auxiliary preview-surface branch rather than another gameplay save family. The higher-value global question is no longer whether `0x00443a50` is world entry. It is where the long-lived simulation cadence takes over after this bring-up and whether that cadence still rendezvous with the shell-owned frame path or escapes into a separate gameplay loop. +- Roots: `shell_map_file_entry_coordinator` at `0x00445ac0`, the first grounded world-entry branch + `world_entry_transition_and_runtime_bringup` at `0x00443a50`, + `shell_map_file_world_bundle_coordinator` at `0x00445de0`, reference-database setup via + `map_bundle_open_reference_databases` at `0x00444dd0`, and narrower loaders such as + `map_load_geographic_label_database` and `map_load_city_database`. +- Trigger/Cadence: shell tutorial launch, editor or detail-panel file actions through `fileopt.win`, + map-scenario open paths, and scenario-text export batch commands. +- Key Dispatchers: `shell_map_file_entry_coordinator`, `world_entry_transition_and_runtime_bringup`, + `world_runtime_release_global_services`, `shell_map_file_world_bundle_coordinator`, + `map_bundle_open_reference_databases`, `map_load_geographic_label_database`, + `map_load_city_database`, `scenario_text_export_build_language_file`, + `scenario_text_export_report_language_file`, `scenario_text_export_batch_process_maps`. +- State Anchors: shell-side file staging buffers at `0x0062bee0` and `0x0062bec4`, shell and mode + globals at `0x006cec74` and `0x006cec78`, world object root `0x0062c120`, map bundle state + allocated through `0x00530c80`, and geography tables rooted at `0x0062b2fc` and `0x0062b268`. +- Subsystem Handoffs: the shared `fileopt.win` dialog rooted at `0x004dc670` now looks like the + shell-side selector above the two broad file coordinators. Its message handler sets `0x006d07f8` + for the load or restore side or `0x006d07ec` for the save or package side before the detail-panel + transition manager routes into `shell_map_file_entry_coordinator` or + `shell_map_file_world_bundle_coordinator`. The former unresolved third flag at `0x006d07f0` is now + accounted for too: it escapes into the standalone `SettingsWindow.win` path through + `shell_open_settings_window` rather than another map or save verb. The broad coordinators now hand + their interactive work through the shared `filerqst.win` helper at `0x004dd010`, and that helper + gives the extension split a firmer shape. The paired editor-map path is now grounded as `.gmp` + through load mode `4` and save mode `3`. The remaining non-editor families are no longer anonymous + either: `.gmc` is the campaign-scenario branch, backed both by the campaign-screen resignation + prompt on `0x006cec7c+0xc5` and by the numbered `%s%02d.gmc` save helper at `0x00517c70`; `.gmx` + is the sandbox branch, backed by the shell-side `The briefing is not available in sandbox games.` + restriction on `0x006cec7c+0x82`; and the default `.gms` branch is therefore the standalone + scenario family. When a live runtime world is already active the same helper bypasses those + non-runtime extensions and forces the `.smp` runtime-state branch instead. The auxiliary save-side + mode `11` is tighter now too: it still maps to `.gmt`, but instead of looking like another + gameplay save family it conditionally diverts into the same `.gmt` preview-surface pipeline owned + by the Multiplayer preview dataset object at `0x006cd8d8`, and only falls back to the normal + reference-bundle path when that dataset object is absent. +- Evidence: function-map map/scenario rows, analysis-context exports for `0x00445ac0`, `0x00445de0`, + `0x00443a50`, `0x00434300`, and `0x00444dd0`, plus objdump string and mode-table evidence for + `.gmp`, `.gmx`, `.gmc`, `.gms`, `.gmt`, `.smp`, `Quicksave`, the `0x004dd010` mode table at + `0x005f3d58`, the auxiliary-owner presence check at `0x00434050`, and the `.gmt` handoff through + `0x00469d30`, together with localized string evidence from ids `3018` and `3898`. +- Open Questions: bit `0x1` on both broad coordinators now grounds the Quicksave name seed and the + former third `fileopt.win` flag has been ruled out as a file-flow question because it just opens + `SettingsWindow.win`. The old broad extension question is mostly resolved: `.gmp` is the + editor-map pair, `.gms` is the standalone scenario family, `.gmc` is the campaign-scenario family, + `.gmx` is the sandbox family, and `.gmt` is at least bounded as an auxiliary preview-surface + branch rather than another gameplay save family. The higher-value global question is no longer + whether `0x00443a50` is world entry. It is where the long-lived simulation cadence takes over + after this bring-up and whether that cadence still rendezvous with the shell-owned frame path or + escapes into a separate gameplay loop. ## Multiplayer Session and Transport Flow -- Roots: `multiplayer_window_init_globals` at `0x004efe80`, `multiplayer_window_service_loop` at `0x004f03f0`, the Multiplayer.win session-event callback table built by `multiplayer_register_session_event_callbacks` at `0x0046a900`, the active session-event transport object at `0x006cd970`, the Multiplayer preview dataset object at `0x006cd8d8`, and the lower pending-template and text-stream helpers around `0x00597880..0x0059caf0`. -- Trigger/Cadence: shell-owned Multiplayer.win frame service plus event-driven session callbacks and repeated transport pump steps. -- Key Dispatchers: session-event wrappers for actions `1`, `2`, `4`, `7`, `8`; `multiplayer_register_session_event_callbacks`; `multiplayer_dispatch_requested_action`; `multiplayer_reset_preview_dataset_and_request_action`; `multiplayer_preview_dataset_service_frame`; `multiplayer_load_selected_map_preview_surface`; `multiplayer_flush_session_event_transport`; `multiplayer_transport_service_frame`; `multiplayer_transport_service_worker_once`; `multiplayer_transport_service_route_callback_tables`; `multiplayer_transport_service_status_and_live_routes`; `multiplayer_transport_text_stream_service_io`; `multiplayer_transport_dispatch_pending_template_node`; `multiplayer_transport_service_pending_template_dispatch_store`. -- State Anchors: live session globals at `0x006d40d0`, active session-event transport object at `0x006cd970`, status latch at `0x006cd974`, session-event mode latch at `0x006cd978`, retry counter at `0x006cd984`, preview dataset object at `0x006cd8d8`, preview-valid flag at `0x006ce9bc`, staged preview strings at `0x006ce670` and `[0x006cd8d8+0x8f48]`, Multiplayer.win backing block at `0x006d1270`, selector-view store root at `[transport+0xab4]`, selector-view generation counters at `[transport+0xab8]..[transport+0xac0]`, selector-view backing arrays around `[transport+0xad0]..[transport+0xae4]`, selector-view entry probe-request id at `[entry+0x50]`, live-state gate at `[entry+0x58]`, third-slot flag word at `[entry+0x64]`, probe-schedule tick at `[entry+0x68]`, last-success tick at `[entry+0x6c]`, pending-probe latch at `[entry+0x74]`, success generation at `[entry+0x78]`, consecutive-failure counter at `[entry+0x7c]`, rolling average at `[entry+0x80]`, recent sample window at `[entry+0x84..]`, bounded sample-count at `[entry+0x94]`, total-success count at `[entry+0x98]`, pending-template list at `[transport+0x550]`, dispatch store at `[worker+0x54c]`, and text-stream buffers rooted under `[worker+0x1c]`. -- Subsystem Handoffs: the Multiplayer.win initializer seeds the backing block at `0x006d1270`, later reset paths construct the separate preview dataset at `0x006cd8d8`, and the shell-owned active-mode frame services that dataset every frame through `multiplayer_preview_dataset_service_frame`. That preview side publishes roster and status controls through the Multiplayer window control paths, loads `.gmt` preview surfaces through `multiplayer_load_selected_map_preview_surface`, and is even reused by the map/save coordinator’s mode-`11` `.gmt` path when the dataset already exists. In parallel, `multiplayer_register_session_event_callbacks` allocates and registers the separate session-event transport object at `0x006cd970`. The shell-side bridge into that deeper transport cadence is now tighter: `multiplayer_window_service_loop` and neighboring reset or initializer branches call `multiplayer_flush_session_event_transport`, which forces one status flush and then drops into `multiplayer_transport_flush_and_maybe_shutdown`. That wrapper in turn runs `multiplayer_transport_service_frame`, the recurring pump that services one worker step through `multiplayer_transport_service_worker_once`, sweeps the transport-owned callback tables and field caches through `multiplayer_transport_service_route_callback_tables`, services both the auxiliary status route and the current live route through `multiplayer_transport_service_status_and_live_routes`, and then descends one layer farther into the shared GameSpy route helper `multiplayer_gamespy_route_service_frame` at `0x58d040`. The transport also owns a separate selector-view sidecar beneath that route cadence. `multiplayer_transport_ensure_selector_view_store` allocates the keyed selector-view store at `[transport+0xab4]`, `multiplayer_transport_find_selector_view_entry_by_name` resolves entries from that store, `multiplayer_transport_upsert_selector_name_entry` marks per-slot activity and flags inside each entry, and `multiplayer_transport_mark_selector_slot_views_dirty` plus `multiplayer_transport_reset_selector_view_entry_runtime_state` manage the dirty or refresh fields at `+0xa0`, `+0xa4`, and `+0xa8`. That selector-view maintenance path is now split more cleanly too. The recurring owner is `multiplayer_transport_service_selector_view_refresh_cycle`, which first runs the fast deferred-probe lane: `multiplayer_transport_collect_refreshable_selector_view_entries` walks the store through `multiplayer_transport_filter_insert_refreshable_selector_view_entry`, which now shows that `[entry+0x64]` is not a generic flag bucket but the third selector-slot flag word, parallel to `[entry+0x5c]` and `[entry+0x60]`. In that collector, the `g` and `a` mode-letter bits produced by `multiplayer_transport_parse_selector_mode_letters` become mask `0x0c` in the slot-local flag words, and any third-slot entry carrying those bits at `[entry+0x64]` is excluded from the refreshable set. Eligible entries then pass slot-aware retry timing on `[entry+0x68]`, `[entry+0x6c]`, `[entry+0x78]`, and `[entry+0x7c]`, after which the service loop schedules refresh probes through `multiplayer_transport_schedule_selector_view_entry_refresh_probe`. That fast lane is narrower now too: the entry-side match key `[entry+0x50]` is no longer just an opaque request field. The profile-key callback lanes feed `multiplayer_transport_parse_selector_view_probe_marker`, which decodes one local `X%sX|%d` marker into a request id plus companion value, and `multiplayer_transport_arm_selector_view_probe_tracking` stores those into `[entry+0x50]` and `[entry+0x54]` before arming the live probe gate at `[entry+0x58]`. The current-selector callback root at `0x59f8b0` is now bounded as well: it resolves and upserts the active selector name, optionally reuses a cached `username` marker to arm probe tracking immediately, then submits the same profile-key bundle with selector context and forwards that selector through callback slot `17`, with the status-route side able to force route-mode transitions `2 -> 3 -> 4` afterward. One layer lower, `multiplayer_transport_handle_profile_key_query_result` at `0x596970` now bounds the per-key result path itself. It treats `username` as the probe-marker field, `b_flags` as the selector mode-letter field, and `(END)` as a real sentinel that publishes a zeroed slot-`22` payload instead of a marker pair. The same helper also hashes the selector-name, key-name, and resolved value text back into the caller table, so the profile-key bundle now looks like a real bounded handoff rather than an anonymous callback cloud. The deferred callback shim `multiplayer_transport_dispatch_selector_view_refresh_probe_result` then walks the keyed store through `multiplayer_transport_finish_selector_view_refresh_probe_if_matching`, which only completes entries whose pending latch `[entry+0x74]` is still armed and whose parsed marker request id `[entry+0x50]` matches the finished request. A failed result `-1` clears the pending latch and increments the consecutive-failure counter at `[entry+0x7c]`. A nonfailure result clears the pending latch, increments the success generation at `[entry+0x78]` and total-success count `[entry+0x98]`, clears `[entry+0x7c]`, stamps the last-success tick at `[entry+0x6c]`, appends the returned sample into the short rolling history at `[entry+0x84..]`, grows the bounded sample-count `[entry+0x94]` up to four, computes the current average into `[entry+0x80]`, and then publishes that averaged sample through `multiplayer_transport_enqueue_callback_slot24_record`. So the publication boundary is explicit and the request-id ownership is explicit, even though the exact user-facing meaning of the sample and the companion value at `[entry+0x54]` is still open. The same service loop also owns a slower sidecar lane keyed off `[entry+0xa4]`: `multiplayer_transport_select_stale_selector_view_progress_entry` walks the store through `multiplayer_transport_pick_stale_selector_view_progress_entry`, picks one stale entry whose progress latch `[entry+0x9c]` is clear and whose last progress tick `[entry+0x70]` is old enough, and then hands it to `multiplayer_transport_stage_selector_view_progress_snapshot`. That helper now looks more bounded too: it rebuilds the marker text from `[entry+0x50]` through `multiplayer_transport_format_selector_view_probe_marker`, formats one `PNG %s %d` line around that marker and the entry-local selector-view sample at `[entry+0x80]`, appends bounded selector-slot `PNG` fragments for live overlapping slots, marks progress-snapshot state in flight at `[entry+0x9c]`, and stamps both `[entry+0x70]` and the transport-wide throttle tick `[transport+0xaec]`. So the selector-view sidecar no longer looks like one undifferentiated refresh bucket: it has a faster deferred-probe lane plus a slower progress-snapshot lane, both still under the shell-owned multiplayer transport cadence. The two descriptor lanes installed by `multiplayer_transport_attach_callback_table_descriptor` are now tighter too. The first lane rooted at `0x59f5c0` can arm deferred-close state on the owner transport and then forward through callback slot `23`. The second lane is no longer just a loose selector-view bucket: `multiplayer_transport_callback_dispatch_selector_name_payload_lane` at `0x59f650` classifies selector payloads through `multiplayer_transport_is_selector_control_line`, routes `@@@NFO` control lines into `multiplayer_transport_sync_selector_view_nfo_r_flag`, and otherwise publishes either callback slot `13` or the split token-plus-tail callback slot `14` through `multiplayer_transport_split_selector_payload_token_and_tail`. That local `@@@NFO` helper is now bounded more tightly too: it only accepts lines ending in the literal `X\` tail, searches for the field marker `\$flags$\`, and then sets or clears bit `0x2` in the third selector-slot flag word at `[entry+0x64]` depending on whether that field contains the letter `r` before the next backslash. The sibling `multiplayer_transport_callback_dispatch_current_selector_payload_lane` at `0x59f720` first resolves the active selector through `0x5951a0`, then handles the current-selector variants of the same control vocabulary: `@@@NFO` continues into the same local `r`-flag sync helper, `@@@GML` plus mode-`3/4` payloads feed the shared control-token helper `multiplayer_transport_handle_gml_or_png_selector_control`, and the remaining non-control payloads publish callback slot `9`. That shared helper now narrows the `GML` and `PNG` split materially: when the token is `GML` and the tail is `Disconnected`, it requires the active selector-view entry to pass `multiplayer_transport_selector_view_entry_has_gml_disconnect_gate`, which currently means the entry participates in the third selector slot and has bit `0x20` set in `[entry+0x64]`, before it forces one status-pump pass, emits callback slot `16`, and re-enters route mode `5`. Its sibling `PNG` branch resolves a named selector-view entry from the tail text and, when that entry overlaps the active selector-slot ownership, refreshes selector-view runtime state through `0x5948f0` and republishes callback slot `25`. Alongside those dispatchers, one grounded branch at `0x59f560` still updates selector-view runtime state through `0x5948f0` and forwards the same selector-name pair through callback slot `25`, while `0x59f850` resets selector text state through `0x5954b0`, forwards through callback slot `19`, and when selector `2` is active in a nonterminal route mode re-enters `multiplayer_transport_set_route_mode` with mode `1`. The low-level route helper still looks like a two-part cycle: `multiplayer_gamespy_route_service_retry_and_keepalive_timers` handles challenge or retry pressure and periodic outbound control traffic around the `master.gamespy.com`, `PING`, `natneg`, `localport`, `localip%d`, and `statechanged` strings, while `multiplayer_gamespy_route_drain_inbound_packets` drains inbound datagrams and dispatches semicolon lines, backslash-delimited key bundles, and `0xfe 0xfd` GameSpy control packets. The transport-owned callback story is now narrower too. The shared route constructor `multiplayer_gamespy_route_construct_and_seed_callback_vector` seeds `[route+0x88]` through `[route+0x9c]` from the caller-supplied transport callback table, records the owner transport at `[route+0x104]`, and explicitly zeroes `[route+0xa0]`, `[route+0xa4]`, and `[route+0xd4]` before any later patch-up. For the transport-owned status route, `multiplayer_transport_try_connect_status_route` then patches `[route+0xa0]` through `multiplayer_gamespy_route_set_extended_payload_callback` to point at `multiplayer_transport_forward_validated_extended_route_payload` `0x00597330`, which simply forwards the validated payload wrapper into the owner callback at `[transport+0x17f4]` with context `[transport+0x17f8]`. The grounded live-route connect path at `multiplayer_transport_try_connect_live_route` does not currently perform any matching post-construction patch for `[route+0xa0]`, `[route+0xa4]`, or `[route+0xd4]`, and the higher route-mode state machine now looks consistent with that: current grounded mode transitions switch by releasing route objects through `multiplayer_gamespy_route_release_and_free` and rebuilding them through `multiplayer_transport_try_connect_live_route`, not by mutating callback slots in place. The parser behavior is now tighter as well: semicolon lines only dispatch when `[route+0xd4]` is non-null, and the subtype-`6` raw fallback only dispatches when `[route+0xa4]` is non-null. For the currently grounded transport-owned status and live routes, those two branches therefore remain optional and can cleanly no-op instead of implying a hidden mandatory callback path. Inside the packet parser, subtype `4` is no longer an unknown callback hop: after cookie validation it dispatches through `[route+0x9c]`, which the transport-owned status and live routes seed to `multiplayer_transport_handle_validated_route_cookie_event` `0x005972c0`. That helper either marks route progress and re-enters `multiplayer_transport_set_route_mode`, or forwards the event id plus payload into the owner callback at `[transport+0x17f0]` with context `[transport+0x17f8]`. Subtype `6` still validates the same cookie, dedupes one 32-bit cookie or packet id, and then dispatches the trailing payload through the natneg-or-raw callback layer rooted at `[route+0xa0]` and `[route+0xa4]`. This separates the shell-frame preview refresh at `0x006cd8d8` from the actual transport cadence at `0x006cd970`, and also separates that transport cadence from the lower GameSpy route-service and packet-parser layer beneath it. -- Evidence: `function-map.csv`, `pending-template-store-management.md`, `pending-template-store-functions.csv`, plus objdump caller traces showing `multiplayer_window_service_loop` reaching `multiplayer_flush_session_event_transport` and the transport pump chain `multiplayer_flush_session_event_transport -> multiplayer_transport_flush_and_maybe_shutdown -> multiplayer_transport_service_frame -> multiplayer_transport_service_worker_once -> multiplayer_transport_drain_request_text_queue`. -- Open Questions: unresolved request-id semantics for `1`, `2`, `4`, and `7`; whether any non-mode-path helper outside the currently grounded release-and-rebuild flow ever patches `[route+0xa4]` and `[route+0xd4]` for the transport-owned status/live routes, or whether those packet families are simply unused in this stack; and how far the Multiplayer preview-dataset machinery is reused outside `Multiplayer.win` beyond the currently grounded `.gmt` save-mode hook. +- Roots: `multiplayer_window_init_globals` at `0x004efe80`, `multiplayer_window_service_loop` at + `0x004f03f0`, the Multiplayer.win session-event callback table built by + `multiplayer_register_session_event_callbacks` at `0x0046a900`, the active session-event transport + object at `0x006cd970`, the Multiplayer preview dataset object at `0x006cd8d8`, and the lower + pending-template and text-stream helpers around `0x00597880..0x0059caf0`. +- Trigger/Cadence: shell-owned Multiplayer.win frame service plus event-driven session callbacks and + repeated transport pump steps. +- Key Dispatchers: session-event wrappers for actions `1`, `2`, `4`, `7`, `8`; + `multiplayer_register_session_event_callbacks`; `multiplayer_dispatch_requested_action`; + `multiplayer_reset_preview_dataset_and_request_action`; + `multiplayer_preview_dataset_service_frame`; `multiplayer_load_selected_map_preview_surface`; + `multiplayer_flush_session_event_transport`; `multiplayer_transport_service_frame`; + `multiplayer_transport_service_worker_once`; + `multiplayer_transport_service_route_callback_tables`; + `multiplayer_transport_service_status_and_live_routes`; + `multiplayer_transport_text_stream_service_io`; + `multiplayer_transport_dispatch_pending_template_node`; + `multiplayer_transport_service_pending_template_dispatch_store`. +- State Anchors: live session globals at `0x006d40d0`, active session-event transport object at + `0x006cd970`, status latch at `0x006cd974`, session-event mode latch at `0x006cd978`, retry + counter at `0x006cd984`, preview dataset object at `0x006cd8d8`, preview-valid flag at + `0x006ce9bc`, staged preview strings at `0x006ce670` and `[0x006cd8d8+0x8f48]`, Multiplayer.win + backing block at `0x006d1270`, selector-view store root at `[transport+0xab4]`, selector-view + generation counters at `[transport+0xab8]..[transport+0xac0]`, selector-view backing arrays around + `[transport+0xad0]..[transport+0xae4]`, selector-view entry probe-request id at `[entry+0x50]`, + live-state gate at `[entry+0x58]`, third-slot flag word at `[entry+0x64]`, probe-schedule tick at + `[entry+0x68]`, last-success tick at `[entry+0x6c]`, pending-probe latch at `[entry+0x74]`, + success generation at `[entry+0x78]`, consecutive-failure counter at `[entry+0x7c]`, rolling + average at `[entry+0x80]`, recent sample window at `[entry+0x84..]`, bounded sample-count at + `[entry+0x94]`, total-success count at `[entry+0x98]`, pending-template list at + `[transport+0x550]`, dispatch store at `[worker+0x54c]`, and text-stream buffers rooted under + `[worker+0x1c]`. +- Subsystem Handoffs: the Multiplayer.win initializer seeds the backing block at `0x006d1270`, later + reset paths construct the separate preview dataset at `0x006cd8d8`, and the shell-owned + active-mode frame services that dataset every frame through + `multiplayer_preview_dataset_service_frame`. That preview side publishes roster and status + controls through the Multiplayer window control paths, loads `.gmt` preview surfaces through + `multiplayer_load_selected_map_preview_surface`, and is even reused by the map/save coordinator’s + mode-`11` `.gmt` path when the dataset already exists. In parallel, + `multiplayer_register_session_event_callbacks` allocates and registers the separate session-event + transport object at `0x006cd970`. The shell-side bridge into that deeper transport cadence is now + tighter: `multiplayer_window_service_loop` and neighboring reset or initializer branches call + `multiplayer_flush_session_event_transport`, which forces one status flush and then drops into + `multiplayer_transport_flush_and_maybe_shutdown`. That wrapper in turn runs + `multiplayer_transport_service_frame`, the recurring pump that services one worker step through + `multiplayer_transport_service_worker_once`, sweeps the transport-owned callback tables and field + caches through `multiplayer_transport_service_route_callback_tables`, services both the auxiliary + status route and the current live route through + `multiplayer_transport_service_status_and_live_routes`, and then descends one layer farther into + the shared GameSpy route helper `multiplayer_gamespy_route_service_frame` at `0x58d040`. The + transport also owns a separate selector-view sidecar beneath that route cadence. + `multiplayer_transport_ensure_selector_view_store` allocates the keyed selector-view store at + `[transport+0xab4]`, `multiplayer_transport_find_selector_view_entry_by_name` resolves entries + from that store, `multiplayer_transport_upsert_selector_name_entry` marks per-slot activity and + flags inside each entry, and `multiplayer_transport_mark_selector_slot_views_dirty` plus + `multiplayer_transport_reset_selector_view_entry_runtime_state` manage the dirty or refresh fields + at `+0xa0`, `+0xa4`, and `+0xa8`. That selector-view maintenance path is now split more cleanly + too. The recurring owner is `multiplayer_transport_service_selector_view_refresh_cycle`, which + first runs the fast deferred-probe lane: + `multiplayer_transport_collect_refreshable_selector_view_entries` walks the store through + `multiplayer_transport_filter_insert_refreshable_selector_view_entry`, which now shows that + `[entry+0x64]` is not a generic flag bucket but the third selector-slot flag word, parallel to + `[entry+0x5c]` and `[entry+0x60]`. In that collector, the `g` and `a` mode-letter bits produced by + `multiplayer_transport_parse_selector_mode_letters` become mask `0x0c` in the slot-local flag + words, and any third-slot entry carrying those bits at `[entry+0x64]` is excluded from the + refreshable set. Eligible entries then pass slot-aware retry timing on `[entry+0x68]`, + `[entry+0x6c]`, `[entry+0x78]`, and `[entry+0x7c]`, after which the service loop schedules refresh + probes through `multiplayer_transport_schedule_selector_view_entry_refresh_probe`. That fast lane + is narrower now too: the entry-side match key `[entry+0x50]` is no longer just an opaque request + field. The profile-key callback lanes feed + `multiplayer_transport_parse_selector_view_probe_marker`, which decodes one local `X%sX|%d` marker + into a request id plus companion value, and + `multiplayer_transport_arm_selector_view_probe_tracking` stores those into `[entry+0x50]` and + `[entry+0x54]` before arming the live probe gate at `[entry+0x58]`. The current-selector callback + root at `0x59f8b0` is now bounded as well: it resolves and upserts the active selector name, + optionally reuses a cached `username` marker to arm probe tracking immediately, then submits the + same profile-key bundle with selector context and forwards that selector through callback slot + `17`, with the status-route side able to force route-mode transitions `2 -> 3 -> 4` afterward. One + layer lower, `multiplayer_transport_handle_profile_key_query_result` at `0x596970` now bounds the + per-key result path itself. It treats `username` as the probe-marker field, `b_flags` as the + selector mode-letter field, and `(END)` as a real sentinel that publishes a zeroed slot-`22` + payload instead of a marker pair. The same helper also hashes the selector-name, key-name, and + resolved value text back into the caller table, so the profile-key bundle now looks like a real + bounded handoff rather than an anonymous callback cloud. The deferred callback shim + `multiplayer_transport_dispatch_selector_view_refresh_probe_result` then walks the keyed store + through `multiplayer_transport_finish_selector_view_refresh_probe_if_matching`, which only + completes entries whose pending latch `[entry+0x74]` is still armed and whose parsed marker + request id `[entry+0x50]` matches the finished request. A failed result `-1` clears the pending + latch and increments the consecutive-failure counter at `[entry+0x7c]`. A nonfailure result clears + the pending latch, increments the success generation at `[entry+0x78]` and total-success count + `[entry+0x98]`, clears `[entry+0x7c]`, stamps the last-success tick at `[entry+0x6c]`, appends the + returned sample into the short rolling history at `[entry+0x84..]`, grows the bounded sample-count + `[entry+0x94]` up to four, computes the current average into `[entry+0x80]`, and then publishes + that averaged sample through `multiplayer_transport_enqueue_callback_slot24_record`. So the + publication boundary is explicit and the request-id ownership is explicit, even though the exact + user-facing meaning of the sample and the companion value at `[entry+0x54]` is still open. The + same service loop also owns a slower sidecar lane keyed off `[entry+0xa4]`: + `multiplayer_transport_select_stale_selector_view_progress_entry` walks the store through + `multiplayer_transport_pick_stale_selector_view_progress_entry`, picks one stale entry whose + progress latch `[entry+0x9c]` is clear and whose last progress tick `[entry+0x70]` is old enough, + and then hands it to `multiplayer_transport_stage_selector_view_progress_snapshot`. That helper + now looks more bounded too: it rebuilds the marker text from `[entry+0x50]` through + `multiplayer_transport_format_selector_view_probe_marker`, formats one `PNG %s %d` line around + that marker and the entry-local selector-view sample at `[entry+0x80]`, appends bounded + selector-slot `PNG` fragments for live overlapping slots, marks progress-snapshot state in flight + at `[entry+0x9c]`, and stamps both `[entry+0x70]` and the transport-wide throttle tick + `[transport+0xaec]`. So the selector-view sidecar no longer looks like one undifferentiated + refresh bucket: it has a faster deferred-probe lane plus a slower progress-snapshot lane, both + still under the shell-owned multiplayer transport cadence. The two descriptor lanes installed by + `multiplayer_transport_attach_callback_table_descriptor` are now tighter too. The first lane + rooted at `0x59f5c0` can arm deferred-close state on the owner transport and then forward through + callback slot `23`. The second lane is no longer just a loose selector-view bucket: + `multiplayer_transport_callback_dispatch_selector_name_payload_lane` at `0x59f650` classifies + selector payloads through `multiplayer_transport_is_selector_control_line`, routes `@@@NFO` + control lines into `multiplayer_transport_sync_selector_view_nfo_r_flag`, and otherwise publishes + either callback slot `13` or the split token-plus-tail callback slot `14` through + `multiplayer_transport_split_selector_payload_token_and_tail`. That local `@@@NFO` helper is now + bounded more tightly too: it only accepts lines ending in the literal `X\` tail, searches for the + field marker `\$flags$\`, and then sets or clears bit `0x2` in the third selector-slot flag word + at `[entry+0x64]` depending on whether that field contains the letter `r` before the next + backslash. The sibling `multiplayer_transport_callback_dispatch_current_selector_payload_lane` at + `0x59f720` first resolves the active selector through `0x5951a0`, then handles the + current-selector variants of the same control vocabulary: `@@@NFO` continues into the same local + `r`-flag sync helper, `@@@GML` plus mode-`3/4` payloads feed the shared control-token helper + `multiplayer_transport_handle_gml_or_png_selector_control`, and the remaining non-control payloads + publish callback slot `9`. That shared helper now narrows the `GML` and `PNG` split materially: + when the token is `GML` and the tail is `Disconnected`, it requires the active selector-view entry + to pass `multiplayer_transport_selector_view_entry_has_gml_disconnect_gate`, which currently means + the entry participates in the third selector slot and has bit `0x20` set in `[entry+0x64]`, before + it forces one status-pump pass, emits callback slot `16`, and re-enters route mode `5`. Its + sibling `PNG` branch resolves a named selector-view entry from the tail text and, when that entry + overlaps the active selector-slot ownership, refreshes selector-view runtime state through + `0x5948f0` and republishes callback slot `25`. Alongside those dispatchers, one grounded branch at + `0x59f560` still updates selector-view runtime state through `0x5948f0` and forwards the same + selector-name pair through callback slot `25`, while `0x59f850` resets selector text state through + `0x5954b0`, forwards through callback slot `19`, and when selector `2` is active in a nonterminal + route mode re-enters `multiplayer_transport_set_route_mode` with mode `1`. The low-level route + helper still looks like a two-part cycle: + `multiplayer_gamespy_route_service_retry_and_keepalive_timers` handles challenge or retry pressure + and periodic outbound control traffic around the `master.gamespy.com`, `PING`, `natneg`, + `localport`, `localip%d`, and `statechanged` strings, while + `multiplayer_gamespy_route_drain_inbound_packets` drains inbound datagrams and dispatches + semicolon lines, backslash-delimited key bundles, and `0xfe 0xfd` GameSpy control packets. The + transport-owned callback story is now narrower too. The shared route constructor + `multiplayer_gamespy_route_construct_and_seed_callback_vector` seeds `[route+0x88]` through + `[route+0x9c]` from the caller-supplied transport callback table, records the owner transport at + `[route+0x104]`, and explicitly zeroes `[route+0xa0]`, `[route+0xa4]`, and `[route+0xd4]` before + any later patch-up. For the transport-owned status route, + `multiplayer_transport_try_connect_status_route` then patches `[route+0xa0]` through + `multiplayer_gamespy_route_set_extended_payload_callback` to point at + `multiplayer_transport_forward_validated_extended_route_payload` `0x00597330`, which simply + forwards the validated payload wrapper into the owner callback at `[transport+0x17f4]` with + context `[transport+0x17f8]`. The grounded live-route connect path at + `multiplayer_transport_try_connect_live_route` does not currently perform any matching + post-construction patch for `[route+0xa0]`, `[route+0xa4]`, or `[route+0xd4]`, and the higher + route-mode state machine now looks consistent with that: current grounded mode transitions switch + by releasing route objects through `multiplayer_gamespy_route_release_and_free` and rebuilding + them through `multiplayer_transport_try_connect_live_route`, not by mutating callback slots in + place. The parser behavior is now tighter as well: semicolon lines only dispatch when + `[route+0xd4]` is non-null, and the subtype-`6` raw fallback only dispatches when `[route+0xa4]` + is non-null. For the currently grounded transport-owned status and live routes, those two branches + therefore remain optional and can cleanly no-op instead of implying a hidden mandatory callback + path. Inside the packet parser, subtype `4` is no longer an unknown callback hop: after cookie + validation it dispatches through `[route+0x9c]`, which the transport-owned status and live routes + seed to `multiplayer_transport_handle_validated_route_cookie_event` `0x005972c0`. That helper + either marks route progress and re-enters `multiplayer_transport_set_route_mode`, or forwards the + event id plus payload into the owner callback at `[transport+0x17f0]` with context + `[transport+0x17f8]`. Subtype `6` still validates the same cookie, dedupes one 32-bit cookie or + packet id, and then dispatches the trailing payload through the natneg-or-raw callback layer + rooted at `[route+0xa0]` and `[route+0xa4]`. This separates the shell-frame preview refresh at + `0x006cd8d8` from the actual transport cadence at `0x006cd970`, and also separates that transport + cadence from the lower GameSpy route-service and packet-parser layer beneath it. +- Evidence: `function-map.csv`, `pending-template-store-management.md`, + `pending-template-store-functions.csv`, plus objdump caller traces showing + `multiplayer_window_service_loop` reaching `multiplayer_flush_session_event_transport` and the + transport pump chain `multiplayer_flush_session_event_transport -> + multiplayer_transport_flush_and_maybe_shutdown -> multiplayer_transport_service_frame -> + multiplayer_transport_service_worker_once -> multiplayer_transport_drain_request_text_queue`. +- Open Questions: unresolved request-id semantics for `1`, `2`, `4`, and `7`; whether any + non-mode-path helper outside the currently grounded release-and-rebuild flow ever patches + `[route+0xa4]` and `[route+0xd4]` for the transport-owned status/live routes, or whether those + packet families are simply unused in this stack; and how far the Multiplayer preview-dataset + machinery is reused outside `Multiplayer.win` beyond the currently grounded `.gmt` save-mode hook. ## Input, Save/Load, and Simulation -- Roots: the shell controller window-message ingress `shell_controller_window_message_dispatch` at `0x0054e3a0`, the shell input-state object initialized at `0x006d4018` through `shell_input_state_init` `0x0054e710`, the saved-world restore path `world_load_saved_runtime_state_bundle` at `0x00446d40`, the live-world save path `world_runtime_serialize_smp_bundle` at `0x00446240`, `world_entry_transition_and_runtime_bringup` at `0x00443a50`, the frame-owned cadence `simulation_frame_accumulate_and_step_world` at `0x00439140`, the recurring `GameMessage.win` service branch through `game_message_window_service_if_present` `0x004e0720`, the world-facing `GameUppermost.win` overlay branch ensured by `shell_ensure_game_uppermost_window` `0x004e0e40` and serviced through `game_uppermost_window_service_world_hotspot_band` `0x004e0780`, and the lower step family rooted at `simulation_advance_to_target_calendar_point` `0x0040ab50` with periodic branches through `simulation_service_periodic_boundary_work` `0x0040a590`. -- Trigger/Cadence: shell-side input is event-driven by controller-window `WM_*` traffic while save or load work is triggered either directly from shell commands or through the `fileopt.win` branch flags into the `.smp` runtime-state family; post-bring-up world service becomes recurring once a world root exists at `0x0062c120`, but the current grounded top-level cadence still remains the shell-owned `shell_service_pump_iteration` path, which calls `simulation_frame_accumulate_and_step_world` directly and lets it accumulate elapsed wall-clock time into one or more simulation-step quanta. A second ingress is now bounded too: `simulation_run_chunked_fast_forward_burst` at `0x00437b20` repeatedly calls the same lower stepper `simulation_advance_to_target_calendar_point`, but current grounded callers put that helper inside the larger post-load generation pipeline `world_run_post_load_generation_pipeline` at `0x004384d0` under the `Seeding Economy...` phase rather than under the ordinary player-facing speed buttons. That setup pipeline is now clearer at the progress-banner level too: localized id `318` `Computing Transportation and Pricing...` stays visible while the pipeline runs `world_compute_transport_and_pricing_grid` `0x0044fb70`, the early collection-owned staging pass `world_setup_building_collection_phase` `0x0041ea50`, and the conditional region pair `world_region_collection_seed_default_regions` `0x00421b60` plus `world_region_border_overlay_rebuild` `0x004882e0`; only then does the code post id `319` `Setting up Players and Companies...`. That `319` lane is no longer just a shell-state placeholder: its primary grounded work is still the chairman-profile pair `world_seed_default_chairman_profile_slots` `0x004377a0` plus `world_build_chairman_profile_slot_records` `0x00437220`, which seed the 16 selector bytes at `[0x006cec7c+0x87]`, materialize the per-slot chairman records from the scenario selectors, campaign override flag `[0x006cec7c+0xc5]`, and the static persona table at `0x005f2d28`, and then publish the selected chairman-profile and linked company summary pair through `[state+0x25]` and `[state+0x21]`. The local slot-record shape is tighter too because the shell editor panel around `0x004cc2d0` now surfaces it directly: `[slot+0x00]` is the staged chairman profile id, `[slot+0x01]` is the Optional-versus-Mandatory byte with nonzero=`Optional` and zero=`Mandatory`, `[slot+0x02]` combines with the separate per-slot gate at `[world+0x0bc3+slot*9]` to surface `Human`, `Computer`, and `Human or Computer`, `[slot+0x03]` is the special occupied-seat byte, and `[slot+0x04]` is the numeric tuning field. Both the selector seeder and the record materializer treat either `[slot+0x02]` or `[slot+0x03]` as enough to keep a slot live, but current grounded writes only seed `[slot+0x03]` on slot zero and later move it solely by whole-record compaction. That makes `[slot+0x03]` the strongest current anchor for the distinguished primary-human-seat flag rather than a generic role byte. The summary fields are tighter too: current direct accessors now show `[state+0x25]` as the selected chairman profile id in `0x006ceb9c`, while `[state+0x21]` is the linked owning company id copied from `[profile+0x1dd]` through `scenario_state_set_selected_chairman_profile` `0x00434890`. The editor-side scenario setup surface beside that chairman panel is clearer now too. `map_editor_scenario_metadata_panel_refresh_controls` `0x004ca790` republishes the scenario description from `[0x006cec78+0x672e]`, the start-year trio `[+0x66ca]`, `[+0x66d2]`, and `[+0x66ce]`, and the paired boolean toggles `[+0x66de]` plus inverse `[+0x66f3]` across control band `0x5b69..0x5b74`, while `map_editor_scenario_metadata_panel_refresh_briefing_mode` `0x004ca670` now bounds the single-player versus multiplayer briefing switch by flipping selector `0x621f50`, publishing localized headings `1491` and `3586`, and refreshing the two briefing texts from `[state+0x4f30]` and `[+0x5ae9]`. The companion dispatcher `map_editor_scenario_metadata_panel_handle_message` `0x004cb4a0` makes the year semantics tighter too: it commits the description and both briefing texts from edit-control payloads, toggles the same two booleans, and clamps the three year fields to `1829..2100` while maintaining `minimum <= default <= maximum`, which now lines up directly with the editor strings `Description:` `Minimum Start Year:` `Default Start Year:` `Maximum Start Year:` `Briefing` and `Multi-Player Briefing`. The neighboring special-conditions page is clearer as well: `map_editor_scenario_special_conditions_panel_construct` `0x004cb2b0` now grounds the live owner for the `Setup_Options_Buttons.imb` list rooted at `0xa7fa`, walks the 36-entry static rule table at `0x005f3ab0`, counts enabled flags from `[0x006cec78+0x4a7f]`, and publishes the `Special Conditions In Effect` summary from localized id `1053`. The same page now has a bounded live dispatcher too: `map_editor_scenario_special_conditions_panel_handle_message` `0x004cb8e0` handles both bulk selection controls and direct row-state changes, commits them back into `[0x006cec78+0x4a7f]`, and then re-enters the panel constructor to refresh the summary. That table is no longer just a raw id run; it now clearly includes the finance and construction restrictions `2535..2563`, plus later editor toggles such as `Use Bio-Accelerator Cars`, `Disable Cargo Economy`, `Disable Train Crashes`, `Disable Train Crashes AND Breakdowns`, and `AI Ignore Territories At Startup`. The neighboring available-chairman page is tighter too. `map_editor_available_chairman_panel_construct` `0x004ca540` now bounds the shell-side owner for the 40-entry persona-availability surface under `0x5aa0..0x5b03`: it walks the same persona table family at `0x005f2d28`, publishes one localized chairman-name row per profile, counts enabled availability bytes from `[0x006cec78+0x6987..]`, and emits the summary `%1 out of %2 are selected.` from localized id `1035`. The live state owner beside it is now grounded as well: `map_editor_available_chairman_panel_handle_message` `0x004cb6f0` handles three bulk-selection controls `0x5aa1..0x5aa3` by rewriting that same availability-byte array from preset bytes embedded in the persona table, and it also commits direct per-row toggle changes from `0x5aaa..0x5b03` back into `[state+0x6987..]` before refreshing the page. So the editor lane now has three distinct scenario-setup slices rather than one chairman-only blob: chairman slots, scenario metadata and briefings, plus both a rule-toggle matrix and an available-chairman pool. There is now one adjacent company-side lane too: current neighboring setup flow conditionally enters `world_conditionally_seed_named_starting_railroad_companies` `0x0047d440` when the Multiplayer preview owner `0x006cd8d8` is absent and either sandbox flag `[0x006cec7c+0x82]` is set or shell-state flag `[0x006cec74+0x14c]` is set while editor-map mode `[0x006cec74+0x68]` is clear. That helper no longer looks like a generic company refresh. It seeds exactly three fixed named railroad-company records from `RT3.lng` ids `575..577`: `Missouri Pacific`, `New York Central`, and `Grand Trunk Railroad`. The first seeded company is tied back to the selected chairman-profile summary and becomes the selected company id. The second railroad is tighter now too: it only receives a chairman link when `profile_collection_count_active_chairman_records` finds at least two live chairman records, and the helper then binds the zero-based second active chairman through `profile_collection_get_nth_active_chairman_record` with ordinal `1`. The third railroad currently gets no matching chairman-link branch in the grounded setup flow and therefore remains an unchaired named company in the live roster. The shell UI above that setup lane is now tighter as well: `shell_company_list_window_construct` `0x004c7200` builds a live company-list window over the company collection at `0x0062be10`, `shell_company_list_window_refresh_rows` `0x004c6c30` formats the active companies with localized strings `267..270`, and only then conditionally appends one synthetic row id `0x7fff` through `shell_company_list_format_company_or_start_row` `0x004c6b40` so `<>` appears as a separate affordance rather than as part of the seeded trio itself. Current shell paging around that same roster is tighter too because the live company collection now has a grounded active-only ordinal helper family: `company_collection_count_active_companies` `0x00429a50`, `company_collection_count_active_companies_before_company_id` `0x004299f0`, and `company_collection_get_nth_active_company_id` `0x00429990`. Those helpers now anchor the “current company among active companies” math used by shell-side detail and picker flows rather than leaving it as anonymous collection glue. `shell_company_list_window_handle_message` `0x004c6f30` then routes the synthetic row into `start_new_company_dialog_open` `0x0047d080`, whose commit path now grounds through `start_new_company_dialog_commit_create_company` `0x0047d120`. That lower helper unlinks any current chairman-owned company, allocates a fresh company id from the live collection at `0x0062be10`, initializes it through `0x00428420`, and only then publishes the new selected company. The neighboring compact request helper `start_new_company_request_create_company` `0x0047d320` does the same fresh-company path from a request block and is already reached from the startup-company branch at `0x00470e48`. The immediate sibling shell branch below that roster is still station-oriented: current grounded resource names and handlers put one branch on `shell_station_detail_window_construct` `0x005068c0`, another on `shell_station_list_window_construct` `0x005074c0`, and the subordinate selector helper on `shell_station_pick_window_construct` `0x00507620`. But the broader company-detail ownership question is no longer open. There is now a separately grounded `CompanyDetail.win` family rooted at `shell_company_detail_window_construct` `0x004c5540`, with `shell_company_detail_window_handle_message` `0x004c56a0` as its main dispatcher and `shell_company_detail_window_refresh_controls` `0x004c2ca0` as the shared repopulation pass for the selected-company presentation and tabbed control bands around `0x9476..0x9490`. A grounded shell detail-manager caller reaches that constructor at `0x004dde24`, the first finance-action layer beneath it is now bounded through `shell_company_detail_issue_bond_offer_flow` `0x004c3890`, `shell_company_detail_issue_stock_offer_flow` `0x004c3f30`, `shell_company_detail_buyback_stock_flow` `0x004c46d0`, and `shell_company_detail_change_dividend_rate_flow` `0x004c5360`, and the first non-finance layer is now bounded too through `shell_company_detail_resign_chairmanship_flow` `0x004c5a0e`, `shell_company_detail_bankruptcy_flow` `0x004c5b99`, the territory-access family rooted at `shell_company_detail_refresh_selected_territory_access_summary` `0x004c1b60` plus `shell_company_detail_buy_territory_access_rights_flow` `0x004c5fc9`, backed by `company_clear_selected_chairman_if_current_profile` `0x00428a10`, `company_declare_bankruptcy_and_halve_bond_debt` `0x00425a90`, `company_has_territory_access_rights` `0x00424010`, `company_set_territory_access_rights_byte` `0x00424030`, and `company_can_purchase_territory_access_rights` `0x00426be0`, plus the two control-transfer lanes. `shell_company_detail_attempt_chairmanship_takeover_flow` `0x0050ccc0` now grounds the special chairman's election path: it checks the caller's current stock ownership in the target company, rejects insufficient holdings through localized id `623`, rejects recent failed attempts through id `624`, and then opens the confirmation under id `625` before seeding the local takeover-election state or packaging the same request through the multiplayer shell transport. The follow-on resolver `shell_resolve_chairmanship_takeover_vote_and_commit_outcome` `0x0050c940` now closes the single-player election loop too: it walks the active chairman profile collection, computes weighted votes for and against the takeover, compares the affirmative total against half the target-company value, presents the result through `shell_present_chairmanship_takeover_vote_outcome_dialog` `0x0050c500` in single-player or localized id `3082` in multiplayer, and then either transfers chairmanship through `0x00428a30` or stamps the current year into `[company+0x289]` as the grounded takeover-cooldown field. `shell_company_detail_attempt_merger_flow` `0x004ec640` now grounds the merger side too: it rejects empty worlds through id `727`, rejects recent failed attempts through id `728`, checks the proposed premium against company cash through localized id `3889`, and then commits into the resolver family. That merger resolver is now bounded too: `shell_resolve_merger_vote_and_commit_outcome` `0x004ebd10` walks the active chairman profile collection, computes weighted votes for and against the proposed merger, compares the affirmative total against half the target-company value, presents the result through `shell_present_merger_vote_outcome_dialog` `0x004eb890` in single-player or localized id `3059` in multiplayer, and then either commits the merger through `0x00427e20` or stamps the current year into `[company+0x15f]` as the grounded merger-cooldown field. The vote-bias side beneath that resolver is tighter now too: `scenario_state_compute_issue_opinion_multiplier` `0x00436590` is no longer just an abstract issue table lookup because its merger callsite uses issue id `0x3a`, which lines up directly with localized id `726` saying merger votes depend on public attitude toward the management of the two companies. By contrast the public-support helper `company_compute_public_support_vote_scalar` `0x00424fd0` uses the broader issue id `0x37`, which currently looks like a more general company-management or public-sentiment slot rather than the merger-only attitude term. The supporting stat layer is bounded more cleanly now too: the surrounding `0x0b` setup in the merger and takeover offer builders is formatter mode rather than a player-facing issue number, while the company-side stat wrapper `company_read_year_or_control_transfer_metric_value` `0x0042a5d0` now reads as a generic stat-family accessor over year-relative series or the bounded slot family in `company_read_control_transfer_metric_slot` `0x0042a2e0`. Its recurring family token `0x2329` is no longer treated as an issue id here either; it is the stat-family selector paired with localized company-stat label id `2329`. That means the paired raw and scaled helpers at `0x004241e0` and `0x00424200` now read as narrow control-transfer offer policy totals instead of direct issue-argument consumers, and the same broader support-and-governance metric family now also feeds the annual shareholder-revolt and creditor-liquidation lane surfaced by localized ids `300..304`. The editor-side help text cluster around ids `2433..2437` is no longer floating either: current grounded map-editor code now has a live economic tuning family beside the chairman-slot panel. `map_editor_economic_cost_slider_panel_construct` `0x004cadf0` binds six slider controls through `map_editor_economic_cost_slider_dispatch` `0x004ca980` into the scenario-state float block `[0x006cec78+0x0be2..0x0bf6]`, while the surrounding descriptor table at `0x00611c70..0x00612220` pairs that wider editor lane with localized fields `Prime Rate`, `Merger Premium`, and `Build Stations Cost` through `Steam Engine Cost` plus the comparison or help texts `2433..2437`. The broader shell-state master flag at `[0x006cec74+0x68]` still sits above the remaining post-load phases, plus two narrower per-phase gates: `[0x006cec74+0x174]` directly fronts id `320` `Setting Up Buildings...` and the later region-owned structure-demand and placement pass through `world_region_collection_run_building_population_pass` `0x00421c20` plus the deeper per-region worker `world_region_balance_structure_demand_and_place_candidates` `0x004235c0`, while `[0x006cec74+0x178]` directly fronts id `321` `Seeding Economy...` and the chunked burst helper `simulation_run_chunked_fast_forward_burst`; id `322` then fronts `Calculating Heights...`. The master `+0x68` flag is no longer just structural: the shell load/save coordinators now use the same flag to force the editor-map `.gmp` family, so current evidence treats it as the broader editor-map mode above those later setup branches rather than an unnamed generic toggle. That worker is no longer one opaque building bucket: current grounded categories split into `House`, a weighted region-profile family surfaced through the `Industry Weightings` stats path, and a third branch whose low-level fallback token is `Commercial` but whose aligned stats label is `City Support`. The same lower helper also reappears later on a slower simulation-side cadence with scale `1/12`, so it no longer looks like one-time setup glue only. The actual game-speed control family remains separate, rooted at `world_set_game_speed_mode` `0x00434680`, `world_adjust_game_speed_mode_delta` `0x00434850`, and `world_toggle_pause_or_restore_game_speed` `0x00437a60`. -- Key Dispatchers: `shell_controller_window_message_dispatch`, `shell_input_apply_window_key_transition`, `shell_input_snapshot_dispatch_state`, `shell_input_cursor_inside_active_view`, `world_load_saved_runtime_state_bundle`, `world_runtime_serialize_smp_bundle`, `simulation_frame_accumulate_and_step_world`, `game_message_window_service_if_present`, `game_message_window_service_frame`, `game_uppermost_window_handle_message`, `game_uppermost_window_service_world_hotspot_band`, `game_uppermost_window_refresh_controls`, `world_view_service_keyboard_turn_pan_and_zoom_bindings`, `world_view_step_heading_quadrant`, `world_view_step_zoom_bucket`, `world_seed_default_chairman_profile_slots`, `world_build_chairman_profile_slot_records`, `world_conditionally_seed_named_starting_railroad_companies`, `scenario_state_set_selected_chairman_profile`, `scenario_state_get_selected_chairman_profile_record`, `scenario_state_get_selected_chairman_company_record`, `shell_company_list_window_construct`, `shell_company_list_window_refresh_rows`, `shell_company_list_window_handle_message`, `start_new_company_dialog_open`, `start_new_company_dialog_commit_create_company`, `start_new_company_request_create_company`, `shell_station_detail_window_construct`, `shell_station_list_window_construct`, `shell_station_list_window_handle_message`, `shell_station_pick_window_construct`, `shell_station_pick_window_populate_station_rows`, `map_editor_chairman_slot_panel_construct`, `map_editor_chairman_slot_panel_handle_message`, `map_editor_chairman_slot_panel_refresh_selected_slot`, `map_editor_chairman_slot_panel_cycle_selected_slot_profile`, `map_editor_available_chairman_panel_construct`, `map_editor_available_chairman_panel_handle_message`, `map_editor_scenario_metadata_panel_refresh_briefing_mode`, `map_editor_scenario_metadata_panel_refresh_controls`, `map_editor_scenario_metadata_panel_handle_message`, `map_editor_scenario_special_conditions_panel_construct`, `map_editor_scenario_special_conditions_panel_handle_message`, `map_editor_economic_cost_slider_panel_construct`, `map_editor_economic_cost_slider_dispatch`, `station_place_world_surface_sync_and_dispatch`, `station_place_window_handle_message`, `track_lay_window_refresh_controls`, `track_lay_window_service_frame`, `track_lay_window_handle_message`, `simulation_advance_to_target_calendar_point`, the smaller single-step helper at `0x00409e80`, `0x0040a9c0`, `0x0040a910`, and `simulation_service_periodic_boundary_work`. -- State Anchors: shell input object `0x006d4018`, per-key state table starting at `[input+0x100]`, packed shell input flags at `[input+0xa8c]` now grounded as Right Shift `0x1`, Left Shift `0x2`, Control `0x4`, and Alt `0x20`, nested dispatch counter `[input+0xa90]`, global shell controller `0x006d4024`, active world root `0x0062c120`, `GameMessage.win` object `0x006d081c`, `GameUppermost.win` overlay object `0x006d0820`, `StationPlace.win` tool object `0x006d1720`, `TrackLay.win` tool object `0x006d1a8c`, accumulated leftover simulation time at `[this+0x4c80]`, shell and mode globals at `0x006cec74`, `0x006cec78`, and `0x006cec7c`, world manager collections at `0x0062be10`, `0x006ceb9c`, `0x006cfcbc`, `0x006cec20`, `0x0062bae0`, and `0x006acd34`, plus the packed calendar-like tuple fields around `[this+0x0d]`, `[this+0x0f]`, `[this+0x11]`, and `[this+0x14]`. -- Subsystem Handoffs: the controller window dispatcher now looks like the first grounded input ingress. It translates keyboard and mouse `WM_*` traffic into shell controller state and the separate input object at `0x006d4018`; read-side cursor and camera helpers later snapshot that object through `shell_input_snapshot_dispatch_state` and gate world-relative interaction through `shell_input_cursor_inside_active_view`. Current grounded consumers around `0x00478cb0`, `0x004e0780`, `0x0053f450`, and `0x0053fe90` still sit on the shell controller path and consult `0x006d4024` or the world owner at `0x0062be68`, so there is still no evidence for a distinct gameplay-only input object after world entry. Instead, the first deeper world-mode interaction branch now looks like a shared world-view coordinator layered on top of the same shell-fed input state. Shell_transition_mode ensures the `GameUppermost.win` object at `0x006d0820`; its message dispatcher `game_uppermost_window_handle_message` owns the narrow action band `0x7918` through `0x7921`; and the recurring service helper `game_uppermost_window_service_world_hotspot_band` rate-limits those hotspot actions, rechecks `shell_input_cursor_inside_active_view`, and then pans the live world view through `world_view_pan_relative_offset_in_camera_plane` `0x0043d130`. The same lower setter family is also reached from the cursor-drag path through `world_view_apply_screen_delta_to_focus_position` `0x0043d0c0`. Above both of those sits the larger recurring service `world_view_service_shell_input_pan_and_hover` `0x0043db00`, which now has one grounded keyboard branch beneath it: `world_view_service_keyboard_turn_pan_and_zoom_bindings` `0x0043d740`. That helper resolves four binding-pair families from the shell input table via `0x0054e7d0`, and the localized labels are now grounded from `Data/Language/RT3.lng`: `Camera Forward` and `Camera Backward` feed the first signed pan channel, `Camera Left` and `Camera Right` feed the second signed pan channel, `Camera Zoom In` and `Camera Zoom Out` feed the signed zoom-step channel that `0x0043db00` smooths into `world_view_step_zoom_bucket` `0x0043cc30`, and `Camera Rotate Left` plus `Camera Rotate Right` feed the continuous heading-turn branch through `0x0043c810`. The setup side is now better bounded too: `world_view_seed_keyboard_binding_slot_pairs` at `0x00439e40` seeds the eight slot pairs at `[this+0x0a6]` through `[this+0x0e2]` from the global action-binding registry through `0x0045f370` using the distinct registry keys `0x0043d2a0` through `0x0043d310`, and the registration block at `0x00460769` through `0x004608e7` shows those roots are defaulted to the expected Up Down Left and Right virtual keys before runtime polling begins. Beneath that camera stack, the enclosing frame path now has one grounded non-view sidecar: after `0x0043db00` it reads the active controller-view object pointer at `[0x006d4024+0x18]+0x366e`, compares it against the latched target at `[frame_owner+0x66a2]`, fires exit and enter-style vtable callbacks on pointer changes through slots `+0x64` and `+0x60`, and only latches the new object when the object passes its own slot `+0x1c` availability test and shell detail control id `0x07d6` on `0x006d0818` has flag bit `0x4`. That `0x07d6` gate is now more bounded than before: the dedicated `TrackLay.win` tool family rooted at `0x006d1a8c` special-cases the same control id in both `track_lay_window_service_frame` and `track_lay_window_handle_message`, uses world hit tests through `0x00448ac0` to arm and release a drag latch on that surface, and routes the resulting command work through the shared track-lay mode state at `0x00622b0c`. The surrounding `track_lay_window_refresh_controls` pass now shows that this is not just one isolated drag handler: the same tool family owns three mutually exclusive primary mode buttons at `0x985e` `0x985f` and `0x9860`, and current primary evidence now bounds those values as `Lay single track.` `0x1`, `Lay double track.` `0x4`, and `Bulldoze` `0x40` from the localized strings 2054 2055 and 1721 plus the matching control-routing branches in `track_lay_window_handle_message`. The same family also owns a bridge-type preference selector rooted at `0x006cec74+0x138`, two wrapped `Never` through `Common` frequency settings at `0x006cec74+0x140` and `0x006cec74+0x13c`, two boolean track-lay preference toggles, and the electrify-all-track action path. Those last two toggles are now tighter than before: current evidence strongly aligns control `0x986e` and state `0x006cec74+0x144` with `Auto-Hide Trees During Track Lay` from strings 1838 and 1839, while control `0x986d` and state `0x006cec78+0x4c74` align with `Auto-Show Grade During Track Lay` from strings 3904 and 3905. That mapping is still evidence-backed rather than absolutely direct from a recovered resource table, but the state ownership and control order now make it the strongest current fit. That makes `0x07d6` look like the shared main-world interaction surface inside a broader TrackLay world-command subsystem, not an unrelated detail button. The neighboring `StationPlace.win` family is now grounded on that same surface too: the shell detail-panel constructor family allocates it through `station_place_window_construct` at `0x00509d80`, publishes it at `0x006d1720`, services it each frame through `station_place_window_service_frame` at `0x0050a530`, and routes player-facing commands through `station_place_window_handle_message` at `0x005091b0`. That dispatcher special-cases the same `0x07d6` control, and the shared helper `station_place_world_surface_sync_and_dispatch` at `0x00508bb0` either accepts that direct surface traffic or falls back to the same detail-panel control looked up through `0x006d0818`, rechecks flag bit `0x4`, hit-tests the world through `0x00448ac0`, stages world coordinates into `0x006d1738` and `0x006d173c`, refreshes the selected-site summary through `station_place_format_selected_site_summary`, and updates the live station-placement selection state at `0x00622af0`, `0x00622aec`, and `0x006d1740`. Together with `station_place_select_category_and_refresh` `0x00508880`, `station_place_refresh_category_controls` `0x00507b90`, and `station_place_format_preview_panel` `0x00508730`, that makes StationPlace a second grounded consumer of the shared main-world interaction surface rather than only a sibling constructor plus frame hook. The StationPlace control semantics are now tighter too: the top category strip at `0x697c` through `0x6981` now grounds as small station, medium station, large station, service tower, maintenance facility, and non-station building from `RT3.lng` strings 2197 through 2202. For the three station categories only, the secondary strip at `0x6988` and `0x6989` plus display field `0x698c` no longer looks like another placement mode family; it is a building-style scroller. The click handlers on `0x6988` and `0x6989` cycle the style override in `0x00622aec`, and the display path builds the active style token from `StationSml`, `StationMed`, or `StationLrg` plus the localized architecture styles `Victorian`, `Tudor`, `Southwest`, `Persian`, `Kyoto`, and `Clapboard` from `RT3.lng` ids 2672 through 2667. One layer lower, the remaining opaque controls are now much tighter: `0x6985` and `0x6986` are no longer a generic assist toggle but the two station-rotation policy choices from strings 2207 and 2206, switching between auto-orienting the building to track or obstacles and strictly obeying the rotation specified by the circle above. The dedicated control at `0x6987` is the station-rotation circle itself, wired through callback `0x00507a90` and aligned with `Click to rotate the building. You can also use bracket keys [ and ] to rotate buildings.` string 2208. That matches the lower behavior too: when the strict-rotation choice is off, both preview and commit paths route staged coordinates through `0x00508040`, which performs the extra orientation search before validation; when strict rotation is on, that pass is skipped and the current angle in `0x006d172c` is used directly. The direct shell UI also exposes the same discrete view-step family through `world_view_step_heading_quadrant` `0x0043cb00` and `world_view_step_zoom_bucket` `0x0043cc30`. The neighboring gating predicates `world_view_should_drive_primary_pan_channel` and `world_view_should_drive_secondary_pan_channel` test packed shell input bits `0x3`, and `shell_input_apply_window_key_transition` now grounds those bits as the left and right Shift modifiers from scan codes `0x2a` and `0x36`. That means cursor drag, overlay hotspots, held Shift state, direct keyboard turn/pan/zoom bindings, the TrackLay and StationPlace world-command surfaces, and at least one frame-owned hover or focus-target branch all converge under the same shell-fed world-mode input path rather than a separate gameplay-input stack. -- Evidence: function-map rows for `shell_controller_window_message_dispatch`, `shell_drain_pending_window_messages`, `shell_input_state_init`, `shell_input_apply_window_key_transition`, `shell_input_snapshot_dispatch_state`, `shell_input_cursor_inside_active_view`, `world_load_saved_runtime_state_bundle`, `world_runtime_serialize_smp_bundle`, `world_entry_transition_and_runtime_bringup`, `simulation_frame_accumulate_and_step_world`, `game_message_window_service_if_present`, `game_message_window_service_frame`, `shell_ensure_game_uppermost_window`, `game_uppermost_window_construct`, `game_uppermost_window_handle_message`, `game_uppermost_window_service_world_hotspot_band`, `world_view_set_focus_position_xyz`, `world_view_apply_screen_delta_to_focus_position`, `world_view_pan_relative_offset_in_camera_plane`, `world_view_seed_keyboard_binding_slot_pairs`, `world_view_service_keyboard_turn_pan_and_zoom_bindings`, `world_view_step_heading_quadrant`, `world_view_step_zoom_bucket`, `world_view_should_drive_primary_pan_channel`, `world_view_should_drive_secondary_pan_channel`, `world_view_service_shell_input_pan_and_hover`, `world_seed_default_chairman_profile_slots`, `world_build_chairman_profile_slot_records`, `world_conditionally_seed_named_starting_railroad_companies`, `profile_collection_count_active_chairman_records`, `profile_collection_get_nth_active_chairman_record`, `scenario_state_set_selected_chairman_profile`, `scenario_state_get_selected_chairman_profile_record`, `scenario_state_get_selected_chairman_company_record`, `start_new_company_dialog_open`, `start_new_company_dialog_commit_create_company`, `start_new_company_request_create_company`, `shell_company_list_format_company_or_start_row`, `shell_company_list_activate_or_shift_center_company`, `shell_company_list_window_refresh_rows`, `shell_company_list_window_handle_message`, `shell_company_list_window_construct`, `shell_company_detail_window_refresh_controls`, `shell_company_detail_window_construct`, `shell_company_detail_window_handle_message`, `shell_station_detail_window_construct`, `shell_station_list_window_construct`, `shell_station_list_window_handle_message`, `shell_station_pick_window_construct`, `shell_station_pick_window_populate_station_rows`, `map_editor_chairman_slot_panel_construct`, `map_editor_chairman_slot_panel_refresh_slot_list`, `map_editor_chairman_slot_panel_refresh_selected_slot`, `map_editor_chairman_slot_panel_refresh_slot_counters`, `map_editor_chairman_slot_panel_cycle_selected_slot_profile`, `map_editor_chairman_slot_panel_handle_message`, `map_editor_available_chairman_panel_construct`, `map_editor_available_chairman_panel_handle_message`, `map_editor_scenario_metadata_panel_refresh_briefing_mode`, `map_editor_scenario_metadata_panel_refresh_controls`, `map_editor_scenario_metadata_panel_handle_message`, `map_editor_scenario_special_conditions_panel_construct`, `map_editor_scenario_special_conditions_panel_handle_message`, `map_editor_economic_cost_slider_panel_construct`, `map_editor_economic_cost_slider_dispatch`, `station_place_refresh_category_controls`, `station_place_format_selected_site_summary`, `station_place_format_preview_panel`, `station_place_select_category_and_refresh`, `station_place_world_surface_sync_and_dispatch`, `station_place_window_handle_message`, `station_place_window_construct`, `station_place_window_service_frame`, `track_lay_window_refresh_controls`, `track_lay_window_construct`, `track_lay_window_service_frame`, `track_lay_window_handle_message`, and `simulation_service_periodic_boundary_work`, plus the shell-input disassembly around `0x0054f290`, the world-view setup and service branches around `0x00439e40`, `0x0043d740`, `0x0043db00`, `0x0043cb00`, and `0x0043cc30`, the `319` setup-side branches around `0x004377a0`, `0x00437220`, `0x00477820`, `0x00477860`, `0x0047d440`, `0x004c6c30`, `0x004c6f30`, `0x0047d080`, `0x0047d120`, `0x0047d320`, `0x004c2ca0`, `0x004c5540`, `0x004c56a0`, `0x005068c0`, `0x005071e0`, `0x005074c0`, and `0x005076c0`, the direct summary-field helpers around `0x00434870` `0x00434890` and `0x004348c0`, the company-link writers at `0x00427c70` and `0x00427d74`, the company constructor at `0x00428420`, the startup-company branch around `0x00470e48`, the shell company-list strings `266` `<>`, `267` `You are the chairman of the %1!`, `268` `The %1 has no chairman at the moment.`, `269` `%1 is the chairman of the %2.`, `270` `Double-click for details.`, and `2992` `Shift-Click to center on this company's primary station.`, the `CompanyDetail.imb` and `CompanyDetail.win` resource strings in `.rdata`, the `StationDetail.imb`, `StationDetail.win`, `StationList.win`, and `StationPick.win` resource strings in `.rdata`, the shell editor window branches around `0x004c9da0`, `0x004ca010`, `0x004ca1c0`, `0x004ca540`, `0x004ca670`, `0x004ca790`, `0x004ca980`, `0x004cb2b0`, `0x004cb4a0`, `0x004cb6f0`, `0x004cb8e0`, `0x004cc250`, `0x004cc2d0`, `0x004ceb90`, and `0x004cecc0`, the localized chairman-slot strings `2997` through `3001` `Optional` `Mandatory` `Human or Computer` `Computer` and `Human`, the localized scenario-editor strings `1483..1492` `Description:` through `Type the briefing for this map.`, the localized summary strings `1035` `%1 out of %2 are selected.` and `1053` `Special Conditions In Effect`, the 40-entry persona availability page under `0x5aa0..0x5b03`, the 36-entry special-condition table at `0x005f3ab0` covering ids `2535..2563`, `2874`, `3722`, `3835`, `3850`, `3852`, and `3920`, the static persona table at `0x005f2d28`, the selector array at `0x006cec7c+0x87`, the persona collection at `0x006ceb9c`, the localized persona strings in `Data/Language/RT3.lng` including `2730` `Unassigned`, the named-chairman range `2731+`, and the neighboring biography range `2495+`, plus the seeded railroad-name strings `575` `Missouri Pacific`, `576` `New York Central`, and `577` `Grand Trunk Railroad`, the StationPlace.win constructor plus category, dispatcher, rotation-circle, shared-world-surface, preview-build, and recurring service branches around `0x00507a90`, `0x00507b90`, `0x00508550`, `0x00508730`, `0x00508880`, `0x00508bb0`, `0x005091b0`, `0x00509d80`, and `0x0050a530`, the StationPlace string cluster `Place a small station` 2197 `Place a medium station` 2198 `Place a large station` 2199 `Place a service tower` 2200 `Place a maintenance facility` 2201 `Place a non-station building` 2202 `Scroll through building styles.` 2203 `When placing the building, it will strictly adhere to the rotation specified by the circle above.` 2206 `When placing the building, it will rotate itself as needed to orient to track or avoid obstacles.` 2207 `Click to rotate the building. You can also use bracket keys [ and ] to rotate buildings.` 2208 and the architecture-style labels `Clapboard` 2667 `Kyoto` 2668 `Persian` 2669 `Southwest` 2670 `Tudor` 2671 and `Victorian` 2672, the TrackLay.win constructor and dispatcher family around `0x0050d2d0`, `0x0050e400`, `0x0050e1e0`, and `0x0050e5c0`, the localized `Never` through `Common` strings 615 through 618, the track-lay strings `Bulldoze` 1721 `Lay single track.` 2054 `Lay double track.` 2055 and 3114, the TrackLay preference strings `Auto-Hide Trees During Track Lay` 1838 `If 'Auto-Hide Trees During Track Lay' is checked, trees will automatically be reduced to small stumps whenever you are in track laying mode.` 1839 `Auto-Show Grade During Track Lay` 3904 and `If 'Auto-Show Grade During Track Lay' is checked, you'll see the grade number over the track while laying track - useful for trying to keep your slopes to a minimum.` 3905, the electrify-all confirmation and failure strings 3083 3084 3837 and 3900, the binding-registry lookup path at `0x0045f370`, the registration block at `0x00460769` through `0x004608e7`, and the localized labels in `Data/Language/RT3.lng` ids `3466` through `3473`. -- Open Questions: no separate outer gameplay loop is grounded above `simulation_frame_accumulate_and_step_world` yet and no deeper gameplay-only input object is grounded either. The new setup-pipeline evidence narrows that question in one direction: the currently grounded chunked burst path at `0x00437b20` now looks subordinate to `world_run_post_load_generation_pipeline` rather than to the ordinary speed controls, and even there it still reuses the same lower stepper and pumps shell work between chunks instead of revealing a detached gameplay loop owner. The player-facing speed-control family is now cleaner too: `world_set_game_speed_mode` owns the bounded `Paused` through `Very Fast` ladder plus the hidden `Ultra Fast 6..9` extension, `world_toggle_pause_or_restore_game_speed` uses `[this+0x1d]` as the resume slot, and the multiplayer host restriction now looks attached to that same setter family rather than to the setup-side burst helper. The first deeper world-mode interaction branch is now better bounded: `GameUppermost.win` hotspots, cursor drag, held Shift state, discrete shell view-step commands, direct keyboard turn/pan/zoom bindings, the `TrackLay.win` and `StationPlace.win` world-command surfaces, and a frame-owned hover or focus-target transition branch all feed the same shell-controller-backed path. The remaining uncertainty has moved farther from basic ownership: the hover-target branch clearly exists, and `0x07d6` now looks like the shared main-world interaction surface rather than a generic detail button for one tool family only. 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 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 `[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. 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 remaining gaps on this lane are therefore narrower than before: 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 selector helper on `StationPick.win`. 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 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 public-support side is now tighter too because `company_compute_cached_recent_performance_support_score` and `company_compute_public_support_vote_scalar` bound the recent-performance and public-support blend beneath those vote resolvers, `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`, so the remaining gap is now mostly semantic: the exact player-facing names of the support-and-governance metric slots behind issue ids `0x37` and `0x3a`, plus any later chairmanship-control side effects beyond the already grounded success or failure commit points. The packed simulation calendar tuple semantics also remain open. 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. -- 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; `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 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 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 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, and `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`. 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, `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. `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 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. +- Roots: the shell controller window-message ingress `shell_controller_window_message_dispatch` at + `0x0054e3a0`, the shell input-state object initialized at `0x006d4018` through + `shell_input_state_init` `0x0054e710`, the saved-world restore path + `world_load_saved_runtime_state_bundle` at `0x00446d40`, the live-world save path + `world_runtime_serialize_smp_bundle` at `0x00446240`, `world_entry_transition_and_runtime_bringup` + at `0x00443a50`, the frame-owned cadence `simulation_frame_accumulate_and_step_world` at + `0x00439140`, the recurring `GameMessage.win` service branch through + `game_message_window_service_if_present` `0x004e0720`, the world-facing `GameUppermost.win` + overlay branch ensured by `shell_ensure_game_uppermost_window` `0x004e0e40` and serviced through + `game_uppermost_window_service_world_hotspot_band` `0x004e0780`, and the lower step family rooted + at `simulation_advance_to_target_calendar_point` `0x0040ab50` with periodic branches through + `simulation_service_periodic_boundary_work` `0x0040a590`. +- Trigger/Cadence: shell-side input is event-driven by controller-window `WM_*` traffic while save + or load work is triggered either directly from shell commands or through the `fileopt.win` branch + flags into the `.smp` runtime-state family; post-bring-up world service becomes recurring once a + world root exists at `0x0062c120`, but the current grounded top-level cadence still remains the + shell-owned `shell_service_pump_iteration` path, which calls + `simulation_frame_accumulate_and_step_world` directly and lets it accumulate elapsed wall-clock + time into one or more simulation-step quanta. A second ingress is now bounded too: + `simulation_run_chunked_fast_forward_burst` at `0x00437b20` repeatedly calls the same lower + stepper `simulation_advance_to_target_calendar_point`, but current grounded callers put that + helper inside the larger post-load generation pipeline `world_run_post_load_generation_pipeline` + at `0x004384d0` under the `Seeding Economy...` phase rather than under the ordinary player-facing + speed buttons. That setup pipeline is now clearer at the progress-banner level too: localized id + `318` `Computing Transportation and Pricing...` stays visible while the pipeline runs + `world_compute_transport_and_pricing_grid` `0x0044fb70`, the early collection-owned staging pass + `world_setup_building_collection_phase` `0x0041ea50`, and the conditional region pair + `world_region_collection_seed_default_regions` `0x00421b60` plus + `world_region_border_overlay_rebuild` `0x004882e0`; only then does the code post id `319` `Setting + up Players and Companies...`. That `319` lane is no longer just a shell-state placeholder: its + primary grounded work is still the chairman-profile pair + `world_seed_default_chairman_profile_slots` `0x004377a0` plus + `world_build_chairman_profile_slot_records` `0x00437220`, which seed the 16 selector bytes at + `[0x006cec7c+0x87]`, materialize the per-slot chairman records from the scenario selectors, + campaign override flag `[0x006cec7c+0xc5]`, and the static persona table at `0x005f2d28`, and then + publish the selected chairman-profile and linked company summary pair through `[state+0x25]` and + `[state+0x21]`. The local slot-record shape is tighter too because the shell editor panel around + `0x004cc2d0` now surfaces it directly: `[slot+0x00]` is the staged chairman profile id, + `[slot+0x01]` is the Optional-versus-Mandatory byte with nonzero=`Optional` and zero=`Mandatory`, + `[slot+0x02]` combines with the separate per-slot gate at `[world+0x0bc3+slot*9]` to surface + `Human`, `Computer`, and `Human or Computer`, `[slot+0x03]` is the special occupied-seat byte, and + `[slot+0x04]` is the numeric tuning field. Both the selector seeder and the record materializer + treat either `[slot+0x02]` or `[slot+0x03]` as enough to keep a slot live, but current grounded + writes only seed `[slot+0x03]` on slot zero and later move it solely by whole-record compaction. + That makes `[slot+0x03]` the strongest current anchor for the distinguished primary-human-seat + flag rather than a generic role byte. The summary fields are tighter too: current direct accessors + now show `[state+0x25]` as the selected chairman profile id in `0x006ceb9c`, while `[state+0x21]` + is the linked owning company id copied from `[profile+0x1dd]` through + `scenario_state_set_selected_chairman_profile` `0x00434890`. The editor-side scenario setup + surface beside that chairman panel is clearer now too. + `map_editor_scenario_metadata_panel_refresh_controls` `0x004ca790` republishes the scenario + description from `[0x006cec78+0x672e]`, the start-year trio `[+0x66ca]`, `[+0x66d2]`, and + `[+0x66ce]`, and the paired boolean toggles `[+0x66de]` plus inverse `[+0x66f3]` across control + band `0x5b69..0x5b74`, while `map_editor_scenario_metadata_panel_refresh_briefing_mode` + `0x004ca670` now bounds the single-player versus multiplayer briefing switch by flipping selector + `0x621f50`, publishing localized headings `1491` and `3586`, and refreshing the two briefing texts + from `[state+0x4f30]` and `[+0x5ae9]`. The companion dispatcher + `map_editor_scenario_metadata_panel_handle_message` `0x004cb4a0` makes the year semantics tighter + too: it commits the description and both briefing texts from edit-control payloads, toggles the + same two booleans, and clamps the three year fields to `1829..2100` while maintaining `minimum <= + default <= maximum`, which now lines up directly with the editor strings `Description:` `Minimum + Start Year:` `Default Start Year:` `Maximum Start Year:` `Briefing` and `Multi-Player Briefing`. + The neighboring special-conditions page is clearer as well: + `map_editor_scenario_special_conditions_panel_construct` `0x004cb2b0` now grounds the live owner + for the `Setup_Options_Buttons.imb` list rooted at `0xa7fa`, walks the 36-entry static rule table + at `0x005f3ab0`, counts enabled flags from `[0x006cec78+0x4a7f]`, and publishes the `Special + Conditions In Effect` summary from localized id `1053`. The same page now has a bounded live + dispatcher too: `map_editor_scenario_special_conditions_panel_handle_message` `0x004cb8e0` handles + both bulk selection controls and direct row-state changes, commits them back into + `[0x006cec78+0x4a7f]`, and then re-enters the panel constructor to refresh the summary. That table + is no longer just a raw id run; it now clearly includes the finance and construction restrictions + `2535..2563`, plus later editor toggles such as `Use Bio-Accelerator Cars`, `Disable Cargo + Economy`, `Disable Train Crashes`, `Disable Train Crashes AND Breakdowns`, and `AI Ignore + Territories At Startup`. The neighboring available-chairman page is tighter too. + `map_editor_available_chairman_panel_construct` `0x004ca540` now bounds the shell-side owner for + the 40-entry persona-availability surface under `0x5aa0..0x5b03`: it walks the same persona table + family at `0x005f2d28`, publishes one localized chairman-name row per profile, counts enabled + availability bytes from `[0x006cec78+0x6987..]`, and emits the summary `%1 out of %2 are + selected.` from localized id `1035`. The live state owner beside it is now grounded as well: + `map_editor_available_chairman_panel_handle_message` `0x004cb6f0` handles three bulk-selection + controls `0x5aa1..0x5aa3` by rewriting that same availability-byte array from preset bytes + embedded in the persona table, and it also commits direct per-row toggle changes from + `0x5aaa..0x5b03` back into `[state+0x6987..]` before refreshing the page. So the editor lane now + has three distinct scenario-setup slices rather than one chairman-only blob: chairman slots, + scenario metadata and briefings, plus both a rule-toggle matrix and an available-chairman pool. + There is now one adjacent company-side lane too: current neighboring setup flow conditionally + enters `world_conditionally_seed_named_starting_railroad_companies` `0x0047d440` when the + Multiplayer preview owner `0x006cd8d8` is absent and either sandbox flag `[0x006cec7c+0x82]` is + set or shell-state flag `[0x006cec74+0x14c]` is set while editor-map mode `[0x006cec74+0x68]` is + clear. That helper no longer looks like a generic company refresh. It seeds exactly three fixed + named railroad-company records from `RT3.lng` ids `575..577`: `Missouri Pacific`, `New York + Central`, and `Grand Trunk Railroad`. The first seeded company is tied back to the selected + chairman-profile summary and becomes the selected company id. The second railroad is tighter now + too: it only receives a chairman link when `profile_collection_count_active_chairman_records` + finds at least two live chairman records, and the helper then binds the zero-based second active + chairman through `profile_collection_get_nth_active_chairman_record` with ordinal `1`. The third + railroad currently gets no matching chairman-link branch in the grounded setup flow and therefore + remains an unchaired named company in the live roster. The shell UI above that setup lane is now + tighter as well: `shell_company_list_window_construct` `0x004c7200` builds a live company-list + window over the company collection at `0x0062be10`, `shell_company_list_window_refresh_rows` + `0x004c6c30` formats the active companies with localized strings `267..270`, and only then + conditionally appends one synthetic row id `0x7fff` through + `shell_company_list_format_company_or_start_row` `0x004c6b40` so `<>` appears + as a separate affordance rather than as part of the seeded trio itself. Current shell paging + around that same roster is tighter too because the live company collection now has a grounded + active-only ordinal helper family: `company_collection_count_active_companies` `0x00429a50`, + `company_collection_count_active_companies_before_company_id` `0x004299f0`, and + `company_collection_get_nth_active_company_id` `0x00429990`. Those helpers now anchor the “current + company among active companies” math used by shell-side detail and picker flows rather than + leaving it as anonymous collection glue. `shell_company_list_window_handle_message` `0x004c6f30` + then routes the synthetic row into `start_new_company_dialog_open` `0x0047d080`, whose commit path + now grounds through `start_new_company_dialog_commit_create_company` `0x0047d120`. That lower + helper unlinks any current chairman-owned company, allocates a fresh company id from the live + collection at `0x0062be10`, initializes it through `0x00428420`, and only then publishes the new + selected company. The neighboring compact request helper + `start_new_company_request_create_company` `0x0047d320` does the same fresh-company path from a + request block and is already reached from the startup-company branch at `0x00470e48`. The + immediate sibling shell branch below that roster is still station-oriented: current grounded + resource names and handlers put one branch on `shell_station_detail_window_construct` + `0x005068c0`, another on `shell_station_list_window_construct` `0x005074c0`, and the subordinate + selector helper on `shell_station_pick_window_construct` `0x00507620`. But the broader + company-detail ownership question is no longer open. There is now a separately grounded + `CompanyDetail.win` family rooted at `shell_company_detail_window_construct` `0x004c5540`, with + `shell_company_detail_window_handle_message` `0x004c56a0` as its main dispatcher and + `shell_company_detail_window_refresh_controls` `0x004c2ca0` as the shared repopulation pass for + the selected-company presentation and tabbed control bands around `0x9476..0x9490`. A grounded + shell detail-manager caller reaches that constructor at `0x004dde24`, the first finance-action + layer beneath it is now bounded through `shell_company_detail_issue_bond_offer_flow` `0x004c3890`, + `shell_company_detail_issue_stock_offer_flow` `0x004c3f30`, + `shell_company_detail_buyback_stock_flow` `0x004c46d0`, and + `shell_company_detail_change_dividend_rate_flow` `0x004c5360`, and the first non-finance layer is + now bounded too through `shell_company_detail_resign_chairmanship_flow` `0x004c5a0e`, + `shell_company_detail_bankruptcy_flow` `0x004c5b99`, the territory-access family rooted at + `shell_company_detail_refresh_selected_territory_access_summary` `0x004c1b60` plus + `shell_company_detail_buy_territory_access_rights_flow` `0x004c5fc9`, backed by + `company_clear_selected_chairman_if_current_profile` `0x00428a10`, + `company_declare_bankruptcy_and_halve_bond_debt` `0x00425a90`, + `company_has_territory_access_rights` `0x00424010`, `company_set_territory_access_rights_byte` + `0x00424030`, and `company_can_purchase_territory_access_rights` `0x00426be0`, plus the two + control-transfer lanes. `shell_company_detail_attempt_chairmanship_takeover_flow` `0x0050ccc0` now + grounds the special chairman's election path: it checks the caller's current stock ownership in + the target company, rejects insufficient holdings through localized id `623`, rejects recent + failed attempts through id `624`, and then opens the confirmation under id `625` before seeding + the local takeover-election state or packaging the same request through the multiplayer shell + transport. The follow-on resolver `shell_resolve_chairmanship_takeover_vote_and_commit_outcome` + `0x0050c940` now closes the single-player election loop too: it walks the active chairman profile + collection, computes weighted votes for and against the takeover, compares the affirmative total + against half the target-company value, presents the result through + `shell_present_chairmanship_takeover_vote_outcome_dialog` `0x0050c500` in single-player or + localized id `3082` in multiplayer, and then either transfers chairmanship through `0x00428a30` or + stamps the current year into `[company+0x289]` as the grounded takeover-cooldown field. + `shell_company_detail_attempt_merger_flow` `0x004ec640` now grounds the merger side too: it + rejects empty worlds through id `727`, rejects recent failed attempts through id `728`, checks the + proposed premium against company cash through localized id `3889`, and then commits into the + resolver family. That merger resolver is now bounded too: + `shell_resolve_merger_vote_and_commit_outcome` `0x004ebd10` walks the active chairman profile + collection, computes weighted votes for and against the proposed merger, compares the affirmative + total against half the target-company value, presents the result through + `shell_present_merger_vote_outcome_dialog` `0x004eb890` in single-player or localized id `3059` in + multiplayer, and then either commits the merger through `0x00427e20` or stamps the current year + into `[company+0x15f]` as the grounded merger-cooldown field. The vote-bias side beneath that + resolver is tighter now too: `scenario_state_compute_issue_opinion_multiplier` `0x00436590` is no + longer just an abstract issue table lookup because its merger callsite uses issue id `0x3a`, which + lines up directly with localized id `726` saying merger votes depend on public attitude toward the + management of the two companies. By contrast the public-support helper + `company_compute_public_support_vote_scalar` `0x00424fd0` uses the broader issue id `0x37`, which + currently looks like a more general company-management or public-sentiment slot rather than the + merger-only attitude term. The supporting stat layer is bounded more cleanly now too: the + surrounding `0x0b` setup in the merger and takeover offer builders is formatter mode rather than a + player-facing issue number, while the company-side stat wrapper + `company_read_year_or_control_transfer_metric_value` `0x0042a5d0` now reads as a generic + stat-family accessor over year-relative series or the bounded slot family in + `company_read_control_transfer_metric_slot` `0x0042a2e0`. Its recurring family token `0x2329` is + no longer treated as an issue id here either; it is the stat-family selector paired with localized + company-stat label id `2329`. That means the paired raw and scaled helpers at `0x004241e0` and + `0x00424200` now read as narrow control-transfer offer policy totals instead of direct + issue-argument consumers, and the same broader support-and-governance metric family now also feeds + the annual shareholder-revolt and creditor-liquidation lane surfaced by localized ids `300..304`. + The editor-side help text cluster around ids `2433..2437` is no longer floating either: current + grounded map-editor code now has a live economic tuning family beside the chairman-slot panel. + `map_editor_economic_cost_slider_panel_construct` `0x004cadf0` binds six slider controls through + `map_editor_economic_cost_slider_dispatch` `0x004ca980` into the scenario-state float block + `[0x006cec78+0x0be2..0x0bf6]`, while the surrounding descriptor table at `0x00611c70..0x00612220` + pairs that wider editor lane with localized fields `Prime Rate`, `Merger Premium`, and `Build + Stations Cost` through `Steam Engine Cost` plus the comparison or help texts `2433..2437`. The + broader shell-state master flag at `[0x006cec74+0x68]` still sits above the remaining post-load + phases, plus two narrower per-phase gates: `[0x006cec74+0x174]` directly fronts id `320` `Setting + Up Buildings...` and the later region-owned structure-demand and placement pass through + `world_region_collection_run_building_population_pass` `0x00421c20` plus the deeper per-region + worker `world_region_balance_structure_demand_and_place_candidates` `0x004235c0`, while + `[0x006cec74+0x178]` directly fronts id `321` `Seeding Economy...` and the chunked burst helper + `simulation_run_chunked_fast_forward_burst`; id `322` then fronts `Calculating Heights...`. The + master `+0x68` flag is no longer just structural: the shell load/save coordinators now use the + same flag to force the editor-map `.gmp` family, so current evidence treats it as the broader + editor-map mode above those later setup branches rather than an unnamed generic toggle. That + worker is no longer one opaque building bucket: current grounded categories split into `House`, a + weighted region-profile family surfaced through the `Industry Weightings` stats path, and a third + branch whose low-level fallback token is `Commercial` but whose aligned stats label is `City + Support`. The same lower helper also reappears later on a slower simulation-side cadence with + scale `1/12`, so it no longer looks like one-time setup glue only. The actual game-speed control + family remains separate, rooted at `world_set_game_speed_mode` `0x00434680`, + `world_adjust_game_speed_mode_delta` `0x00434850`, and `world_toggle_pause_or_restore_game_speed` + `0x00437a60`. +- CompanyDetail addendum: the shared helper `shell_company_detail_resolve_selected_company` at + `0x004c16f0` now bounds the common current-company accessor beneath the whole pane, and the + read-side owner also has a separate active-company navigation family through + `shell_company_detail_step_selected_active_company_delta` at `0x004c3470` plus the next or + previous wrappers at `0x004c3540` and `0x004c3550`. The section switch in + `shell_company_detail_window_refresh_controls` is now grounded too: section index `0x006cfe60` + selects a chairman/governance slice, a debt-and-capital slice, a per-share slice, or a + territory-access slice, published through the tab band around `0x9472..0x9479`, with adjacent + section-navigation controls around `0x947b..0x947c` and `0x948f..0x9490`. +- Key Dispatchers: `shell_controller_window_message_dispatch`, + `shell_input_apply_window_key_transition`, `shell_input_snapshot_dispatch_state`, + `shell_input_cursor_inside_active_view`, `world_load_saved_runtime_state_bundle`, + `world_runtime_serialize_smp_bundle`, `simulation_frame_accumulate_and_step_world`, + `game_message_window_service_if_present`, `game_message_window_service_frame`, + `game_uppermost_window_handle_message`, `game_uppermost_window_service_world_hotspot_band`, + `game_uppermost_window_refresh_controls`, + `world_view_service_keyboard_turn_pan_and_zoom_bindings`, `world_view_step_heading_quadrant`, + `world_view_step_zoom_bucket`, `world_seed_default_chairman_profile_slots`, + `world_build_chairman_profile_slot_records`, + `world_conditionally_seed_named_starting_railroad_companies`, + `scenario_state_set_selected_chairman_profile`, + `scenario_state_get_selected_chairman_profile_record`, + `scenario_state_get_selected_chairman_company_record`, `shell_company_list_window_construct`, + `shell_company_list_window_refresh_rows`, `shell_company_list_window_handle_message`, + `start_new_company_dialog_open`, `start_new_company_dialog_commit_create_company`, + `start_new_company_request_create_company`, `shell_station_detail_window_construct`, + `shell_station_list_window_construct`, `shell_station_list_window_handle_message`, + `shell_station_pick_window_construct`, `shell_station_pick_window_populate_station_rows`, + `map_editor_chairman_slot_panel_construct`, `map_editor_chairman_slot_panel_handle_message`, + `map_editor_chairman_slot_panel_refresh_selected_slot`, + `map_editor_chairman_slot_panel_cycle_selected_slot_profile`, + `map_editor_available_chairman_panel_construct`, + `map_editor_available_chairman_panel_handle_message`, + `map_editor_scenario_metadata_panel_refresh_briefing_mode`, + `map_editor_scenario_metadata_panel_refresh_controls`, + `map_editor_scenario_metadata_panel_handle_message`, + `map_editor_scenario_special_conditions_panel_construct`, + `map_editor_scenario_special_conditions_panel_handle_message`, + `map_editor_economic_cost_slider_panel_construct`, `map_editor_economic_cost_slider_dispatch`, + `station_place_world_surface_sync_and_dispatch`, `station_place_window_handle_message`, + `track_lay_window_refresh_controls`, `track_lay_window_service_frame`, + `track_lay_window_handle_message`, `simulation_advance_to_target_calendar_point`, the smaller + single-step helper at `0x00409e80`, `0x0040a9c0`, `0x0040a910`, and + `simulation_service_periodic_boundary_work`. +- State Anchors: shell input object `0x006d4018`, per-key state table starting at `[input+0x100]`, + packed shell input flags at `[input+0xa8c]` now grounded as Right Shift `0x1`, Left Shift `0x2`, + Control `0x4`, and Alt `0x20`, nested dispatch counter `[input+0xa90]`, global shell controller + `0x006d4024`, active world root `0x0062c120`, `GameMessage.win` object `0x006d081c`, + `GameUppermost.win` overlay object `0x006d0820`, `StationPlace.win` tool object `0x006d1720`, + `TrackLay.win` tool object `0x006d1a8c`, accumulated leftover simulation time at `[this+0x4c80]`, + shell and mode globals at `0x006cec74`, `0x006cec78`, and `0x006cec7c`, world manager collections + at `0x0062be10`, `0x006ceb9c`, `0x006cfcbc`, `0x006cec20`, `0x0062bae0`, and `0x006acd34`, plus + the packed calendar-like tuple fields around `[this+0x0d]`, `[this+0x0f]`, `[this+0x11]`, and + `[this+0x14]`. +- Subsystem Handoffs: the controller window dispatcher now looks like the first grounded input + ingress. It translates keyboard and mouse `WM_*` traffic into shell controller state and the + separate input object at `0x006d4018`; read-side cursor and camera helpers later snapshot that + object through `shell_input_snapshot_dispatch_state` and gate world-relative interaction through + `shell_input_cursor_inside_active_view`. Current grounded consumers around `0x00478cb0`, + `0x004e0780`, `0x0053f450`, and `0x0053fe90` still sit on the shell controller path and consult + `0x006d4024` or the world owner at `0x0062be68`, so there is still no evidence for a distinct + gameplay-only input object after world entry. Instead, the first deeper world-mode interaction + branch now looks like a shared world-view coordinator layered on top of the same shell-fed input + state. Shell_transition_mode ensures the `GameUppermost.win` object at `0x006d0820`; its message + dispatcher `game_uppermost_window_handle_message` owns the narrow action band `0x7918` through + `0x7921`; and the recurring service helper `game_uppermost_window_service_world_hotspot_band` + rate-limits those hotspot actions, rechecks `shell_input_cursor_inside_active_view`, and then pans + the live world view through `world_view_pan_relative_offset_in_camera_plane` `0x0043d130`. The + same lower setter family is also reached from the cursor-drag path through + `world_view_apply_screen_delta_to_focus_position` `0x0043d0c0`. Above both of those sits the + larger recurring service `world_view_service_shell_input_pan_and_hover` `0x0043db00`, which now + has one grounded keyboard branch beneath it: + `world_view_service_keyboard_turn_pan_and_zoom_bindings` `0x0043d740`. That helper resolves four + binding-pair families from the shell input table via `0x0054e7d0`, and the localized labels are + now grounded from `Data/Language/RT3.lng`: `Camera Forward` and `Camera Backward` feed the first + signed pan channel, `Camera Left` and `Camera Right` feed the second signed pan channel, `Camera + Zoom In` and `Camera Zoom Out` feed the signed zoom-step channel that `0x0043db00` smooths into + `world_view_step_zoom_bucket` `0x0043cc30`, and `Camera Rotate Left` plus `Camera Rotate Right` + feed the continuous heading-turn branch through `0x0043c810`. The setup side is now better bounded + too: `world_view_seed_keyboard_binding_slot_pairs` at `0x00439e40` seeds the eight slot pairs at + `[this+0x0a6]` through `[this+0x0e2]` from the global action-binding registry through `0x0045f370` + using the distinct registry keys `0x0043d2a0` through `0x0043d310`, and the registration block at + `0x00460769` through `0x004608e7` shows those roots are defaulted to the expected Up Down Left and + Right virtual keys before runtime polling begins. Beneath that camera stack, the enclosing frame + path now has one grounded non-view sidecar: after `0x0043db00` it reads the active controller-view + object pointer at `[0x006d4024+0x18]+0x366e`, compares it against the latched target at + `[frame_owner+0x66a2]`, fires exit and enter-style vtable callbacks on pointer changes through + slots `+0x64` and `+0x60`, and only latches the new object when the object passes its own slot + `+0x1c` availability test and shell detail control id `0x07d6` on `0x006d0818` has flag bit `0x4`. + That `0x07d6` gate is now more bounded than before: the dedicated `TrackLay.win` tool family + rooted at `0x006d1a8c` special-cases the same control id in both `track_lay_window_service_frame` + and `track_lay_window_handle_message`, uses world hit tests through `0x00448ac0` to arm and + release a drag latch on that surface, and routes the resulting command work through the shared + track-lay mode state at `0x00622b0c`. The surrounding `track_lay_window_refresh_controls` pass now + shows that this is not just one isolated drag handler: the same tool family owns three mutually + exclusive primary mode buttons at `0x985e` `0x985f` and `0x9860`, and current primary evidence now + bounds those values as `Lay single track.` `0x1`, `Lay double track.` `0x4`, and `Bulldoze` `0x40` + from the localized strings 2054 2055 and 1721 plus the matching control-routing branches in + `track_lay_window_handle_message`. The same family also owns a bridge-type preference selector + rooted at `0x006cec74+0x138`, two wrapped `Never` through `Common` frequency settings at + `0x006cec74+0x140` and `0x006cec74+0x13c`, two boolean track-lay preference toggles, and the + electrify-all-track action path. Those last two toggles are now tighter than before: current + evidence strongly aligns control `0x986e` and state `0x006cec74+0x144` with `Auto-Hide Trees + During Track Lay` from strings 1838 and 1839, while control `0x986d` and state `0x006cec78+0x4c74` + align with `Auto-Show Grade During Track Lay` from strings 3904 and 3905. That mapping is still + evidence-backed rather than absolutely direct from a recovered resource table, but the state + ownership and control order now make it the strongest current fit. That makes `0x07d6` look like + the shared main-world interaction surface inside a broader TrackLay world-command subsystem, not + an unrelated detail button. The neighboring `StationPlace.win` family is now grounded on that same + surface too: the shell detail-panel constructor family allocates it through + `station_place_window_construct` at `0x00509d80`, publishes it at `0x006d1720`, services it each + frame through `station_place_window_service_frame` at `0x0050a530`, and routes player-facing + commands through `station_place_window_handle_message` at `0x005091b0`. That dispatcher + special-cases the same `0x07d6` control, and the shared helper + `station_place_world_surface_sync_and_dispatch` at `0x00508bb0` either accepts that direct surface + traffic or falls back to the same detail-panel control looked up through `0x006d0818`, rechecks + flag bit `0x4`, hit-tests the world through `0x00448ac0`, stages world coordinates into + `0x006d1738` and `0x006d173c`, refreshes the selected-site summary through + `station_place_format_selected_site_summary`, and updates the live station-placement selection + state at `0x00622af0`, `0x00622aec`, and `0x006d1740`. Together with + `station_place_select_category_and_refresh` `0x00508880`, + `station_place_refresh_category_controls` `0x00507b90`, and `station_place_format_preview_panel` + `0x00508730`, that makes StationPlace a second grounded consumer of the shared main-world + interaction surface rather than only a sibling constructor plus frame hook. The StationPlace + control semantics are now tighter too: the top category strip at `0x697c` through `0x6981` now + grounds as small station, medium station, large station, service tower, maintenance facility, and + non-station building from `RT3.lng` strings 2197 through 2202. For the three station categories + only, the secondary strip at `0x6988` and `0x6989` plus display field `0x698c` no longer looks + like another placement mode family; it is a building-style scroller. The click handlers on + `0x6988` and `0x6989` cycle the style override in `0x00622aec`, and the display path builds the + active style token from `StationSml`, `StationMed`, or `StationLrg` plus the localized + architecture styles `Victorian`, `Tudor`, `Southwest`, `Persian`, `Kyoto`, and `Clapboard` from + `RT3.lng` ids 2672 through 2667. One layer lower, the remaining opaque controls are now much + tighter: `0x6985` and `0x6986` are no longer a generic assist toggle but the two station-rotation + policy choices from strings 2207 and 2206, switching between auto-orienting the building to track + or obstacles and strictly obeying the rotation specified by the circle above. The dedicated + control at `0x6987` is the station-rotation circle itself, wired through callback `0x00507a90` and + aligned with `Click to rotate the building. You can also use bracket keys [ and ] to rotate + buildings.` string 2208. That matches the lower behavior too: when the strict-rotation choice is + off, both preview and commit paths route staged coordinates through `0x00508040`, which performs + the extra orientation search before validation; when strict rotation is on, that pass is skipped + and the current angle in `0x006d172c` is used directly. The direct shell UI also exposes the same + discrete view-step family through `world_view_step_heading_quadrant` `0x0043cb00` and + `world_view_step_zoom_bucket` `0x0043cc30`. The neighboring gating predicates + `world_view_should_drive_primary_pan_channel` and `world_view_should_drive_secondary_pan_channel` + test packed shell input bits `0x3`, and `shell_input_apply_window_key_transition` now grounds + those bits as the left and right Shift modifiers from scan codes `0x2a` and `0x36`. That means + cursor drag, overlay hotspots, held Shift state, direct keyboard turn/pan/zoom bindings, the + TrackLay and StationPlace world-command surfaces, and at least one frame-owned hover or + focus-target branch all converge under the same shell-fed world-mode input path rather than a + separate gameplay-input stack. +- Evidence: function-map rows for `shell_controller_window_message_dispatch`, + `shell_drain_pending_window_messages`, `shell_input_state_init`, + `shell_input_apply_window_key_transition`, `shell_input_snapshot_dispatch_state`, + `shell_input_cursor_inside_active_view`, `world_load_saved_runtime_state_bundle`, + `world_runtime_serialize_smp_bundle`, `world_entry_transition_and_runtime_bringup`, + `simulation_frame_accumulate_and_step_world`, `game_message_window_service_if_present`, + `game_message_window_service_frame`, `shell_ensure_game_uppermost_window`, + `game_uppermost_window_construct`, `game_uppermost_window_handle_message`, + `game_uppermost_window_service_world_hotspot_band`, `world_view_set_focus_position_xyz`, + `world_view_apply_screen_delta_to_focus_position`, + `world_view_pan_relative_offset_in_camera_plane`, `world_view_seed_keyboard_binding_slot_pairs`, + `world_view_service_keyboard_turn_pan_and_zoom_bindings`, `world_view_step_heading_quadrant`, + `world_view_step_zoom_bucket`, `world_view_should_drive_primary_pan_channel`, + `world_view_should_drive_secondary_pan_channel`, `world_view_service_shell_input_pan_and_hover`, + `world_seed_default_chairman_profile_slots`, `world_build_chairman_profile_slot_records`, + `world_conditionally_seed_named_starting_railroad_companies`, + `profile_collection_count_active_chairman_records`, + `profile_collection_get_nth_active_chairman_record`, + `scenario_state_set_selected_chairman_profile`, + `scenario_state_get_selected_chairman_profile_record`, + `scenario_state_get_selected_chairman_company_record`, `start_new_company_dialog_open`, + `start_new_company_dialog_commit_create_company`, `start_new_company_request_create_company`, + `shell_company_list_format_company_or_start_row`, + `shell_company_list_activate_or_shift_center_company`, `shell_company_list_window_refresh_rows`, + `shell_company_list_window_handle_message`, `shell_company_list_window_construct`, + `shell_company_detail_window_refresh_controls`, `shell_company_detail_window_construct`, + `shell_company_detail_window_handle_message`, `shell_station_detail_window_construct`, + `shell_station_list_window_construct`, `shell_station_list_window_handle_message`, + `shell_station_pick_window_construct`, `shell_station_pick_window_populate_station_rows`, + `map_editor_chairman_slot_panel_construct`, `map_editor_chairman_slot_panel_refresh_slot_list`, + `map_editor_chairman_slot_panel_refresh_selected_slot`, + `map_editor_chairman_slot_panel_refresh_slot_counters`, + `map_editor_chairman_slot_panel_cycle_selected_slot_profile`, + `map_editor_chairman_slot_panel_handle_message`, `map_editor_available_chairman_panel_construct`, + `map_editor_available_chairman_panel_handle_message`, + `map_editor_scenario_metadata_panel_refresh_briefing_mode`, + `map_editor_scenario_metadata_panel_refresh_controls`, + `map_editor_scenario_metadata_panel_handle_message`, + `map_editor_scenario_special_conditions_panel_construct`, + `map_editor_scenario_special_conditions_panel_handle_message`, + `map_editor_economic_cost_slider_panel_construct`, `map_editor_economic_cost_slider_dispatch`, + `station_place_refresh_category_controls`, `station_place_format_selected_site_summary`, + `station_place_format_preview_panel`, `station_place_select_category_and_refresh`, + `station_place_world_surface_sync_and_dispatch`, `station_place_window_handle_message`, + `station_place_window_construct`, `station_place_window_service_frame`, + `track_lay_window_refresh_controls`, `track_lay_window_construct`, + `track_lay_window_service_frame`, `track_lay_window_handle_message`, and + `simulation_service_periodic_boundary_work`, plus the shell-input disassembly around `0x0054f290`, + the world-view setup and service branches around `0x00439e40`, `0x0043d740`, `0x0043db00`, + `0x0043cb00`, and `0x0043cc30`, the `319` setup-side branches around `0x004377a0`, `0x00437220`, + `0x00477820`, `0x00477860`, `0x0047d440`, `0x004c6c30`, `0x004c6f30`, `0x0047d080`, `0x0047d120`, + `0x0047d320`, `0x004c2ca0`, `0x004c5540`, `0x004c56a0`, `0x005068c0`, `0x005071e0`, `0x005074c0`, + and `0x005076c0`, the direct summary-field helpers around `0x00434870` `0x00434890` and + `0x004348c0`, the company-link writers at `0x00427c70` and `0x00427d74`, the company constructor + at `0x00428420`, the startup-company branch around `0x00470e48`, the shell company-list strings + `266` `<>`, `267` `You are the chairman of the %1!`, `268` `The %1 has no + chairman at the moment.`, `269` `%1 is the chairman of the %2.`, `270` `Double-click for + details.`, and `2992` `Shift-Click to center on this company's primary station.`, the + `CompanyDetail.imb` and `CompanyDetail.win` resource strings in `.rdata`, the `StationDetail.imb`, + `StationDetail.win`, `StationList.win`, and `StationPick.win` resource strings in `.rdata`, the + shell editor window branches around `0x004c9da0`, `0x004ca010`, `0x004ca1c0`, `0x004ca540`, + `0x004ca670`, `0x004ca790`, `0x004ca980`, `0x004cb2b0`, `0x004cb4a0`, `0x004cb6f0`, `0x004cb8e0`, + `0x004cc250`, `0x004cc2d0`, `0x004ceb90`, and `0x004cecc0`, the localized chairman-slot strings + `2997` through `3001` `Optional` `Mandatory` `Human or Computer` `Computer` and `Human`, the + localized scenario-editor strings `1483..1492` `Description:` through `Type the briefing for this + map.`, the localized summary strings `1035` `%1 out of %2 are selected.` and `1053` `Special + Conditions In Effect`, the 40-entry persona availability page under `0x5aa0..0x5b03`, the 36-entry + special-condition table at `0x005f3ab0` covering ids `2535..2563`, `2874`, `3722`, `3835`, `3850`, + `3852`, and `3920`, the static persona table at `0x005f2d28`, the selector array at + `0x006cec7c+0x87`, the persona collection at `0x006ceb9c`, the localized persona strings in + `Data/Language/RT3.lng` including `2730` `Unassigned`, the named-chairman range `2731+`, and the + neighboring biography range `2495+`, plus the seeded railroad-name strings `575` `Missouri + Pacific`, `576` `New York Central`, and `577` `Grand Trunk Railroad`, the StationPlace.win + constructor plus category, dispatcher, rotation-circle, shared-world-surface, preview-build, and + recurring service branches around `0x00507a90`, `0x00507b90`, `0x00508550`, `0x00508730`, + `0x00508880`, `0x00508bb0`, `0x005091b0`, `0x00509d80`, and `0x0050a530`, the StationPlace string + cluster `Place a small station` 2197 `Place a medium station` 2198 `Place a large station` 2199 + `Place a service tower` 2200 `Place a maintenance facility` 2201 `Place a non-station building` + 2202 `Scroll through building styles.` 2203 `When placing the building, it will strictly adhere to + the rotation specified by the circle above.` 2206 `When placing the building, it will rotate + itself as needed to orient to track or avoid obstacles.` 2207 `Click to rotate the building. You + can also use bracket keys [ and ] to rotate buildings.` 2208 and the architecture-style labels + `Clapboard` 2667 `Kyoto` 2668 `Persian` 2669 `Southwest` 2670 `Tudor` 2671 and `Victorian` 2672, + the TrackLay.win constructor and dispatcher family around `0x0050d2d0`, `0x0050e400`, + `0x0050e1e0`, and `0x0050e5c0`, the localized `Never` through `Common` strings 615 through 618, + the track-lay strings `Bulldoze` 1721 `Lay single track.` 2054 `Lay double track.` 2055 and 3114, + the TrackLay preference strings `Auto-Hide Trees During Track Lay` 1838 `If 'Auto-Hide Trees + During Track Lay' is checked, trees will automatically be reduced to small stumps whenever you are + in track laying mode.` 1839 `Auto-Show Grade During Track Lay` 3904 and `If 'Auto-Show Grade + During Track Lay' is checked, you'll see the grade number over the track while laying track - + useful for trying to keep your slopes to a minimum.` 3905, the electrify-all confirmation and + failure strings 3083 3084 3837 and 3900, the binding-registry lookup path at `0x0045f370`, the + registration block at `0x00460769` through `0x004608e7`, and the localized labels in + `Data/Language/RT3.lng` ids `3466` through `3473`. +- Open Questions: no separate outer gameplay loop is grounded above + `simulation_frame_accumulate_and_step_world` yet and no deeper gameplay-only input object is + grounded either. The new setup-pipeline evidence narrows that question in one direction: the + currently grounded chunked burst path at `0x00437b20` now looks subordinate to + `world_run_post_load_generation_pipeline` rather than to the ordinary speed controls, and even + there it still reuses the same lower stepper and pumps shell work between chunks instead of + revealing a detached gameplay loop owner. The player-facing speed-control family is now cleaner + too: `world_set_game_speed_mode` owns the bounded `Paused` through `Very Fast` ladder plus the + hidden `Ultra Fast 6..9` extension, `world_toggle_pause_or_restore_game_speed` uses `[this+0x1d]` + as the resume slot, and the multiplayer host restriction now looks attached to that same setter + family rather than to the setup-side burst helper. The frame-owned shell coupling is tighter now + too: inside `simulation_frame_accumulate_and_step_world` itself, one direct branch opens or + focuses `LoadScreen.win` through `shell_open_or_focus_load_screen_page`, and the post-step + shell-window ladder also probes several sibling shell windows by the same presence-plus-dirty + pattern, including the live `LoadScreen` singleton, the shared callback-driven custom modal, the + shared file-options dialog, `SettingsWindow.win`, the now-grounded `Overview.win` and + `BuildingDetail.win` singletons, and now the shell-side `Trainbuy.win` singleton too. That + train-buy family is no longer just an unnamed probe pair either: the opener path is now grounded + under the same shell-owned cadence through `shell_can_open_trainbuy_window_or_warn` and + `shell_open_or_focus_trainbuy_window`, and its current family semantics already extend beyond a + bare locomotive picker into selected-train upgrade summary and route-edit affordances. The + selected-train side is tighter now too: we have explicit query helpers for the selected train + record, id, validity, and company ownership, plus one explicit ownership-mismatch warning modal. + That same pass also clarified one boundary we should not conflate: the neighboring shell family + rooted at `0x006d3b20` is now grounded separately as `TrainDetail.win`. It reuses the same + selected-train context and some of the same helpers, but it is not the same `Trainbuy.win` + singleton family. The `TrainDetail.win` side now has its own constructor, opener, refresh path, + and message owner above the broader train-command strip. Its inner `0xcb` strip is tighter now + too: one bounded branch is the selected-train engine-replacement or trainbuy handoff lane using + warning ids `593/594`, and another is the selected-train retirement lane using `595/596/597` + with either a local teardown path or multiplayer opcode `0x37`. The remaining train-command + family is narrower too: the shared `0x33`-stride helper trio at `0x004b2f00`, `0x004b3000`, and + `0x004b3160` now looks like a real train route-stop or waypoint list rather than a generic row + buffer, and route-entry flag byte `+0x28` now has one grounded top-level split: sign bit clear + entries are the live placed-structure-backed family, while sign bit set entries use the direct + route-node payload side. The helper `train_route_list_count_live_site_reference_entries` + `0x004b2b80` now counts the first family explicitly. One deeper lower-bit result is grounded too: + both `train_route_list_insert_staged_entry_at_index` and the auxiliary finalize helper + `train_finalize_aux_route_entry_buffer_preserving_subflags` `0x004a94b0` explicitly preserve + bits `0x40`, `0x20`, and `0x10` in the same flag byte during route-entry rewrites. Those bits are + also no longer copy-only: the neighboring shell helper + `shell_building_detail_refresh_flagged_service_capability_rows` `0x004b9a20` now consumes them to + restyle the `BuildingDetail.win` row bands `0x7d07..0x7d1c` and `0x7f58..0x801f`. The exact + player-facing labels for those rows are still open, but the subflags now have one real shell-side + consumer instead of only preservation logic. The broader `BuildingDetail.win` refresh family is + tighter too: `shell_building_detail_refresh_subject_cargo_and_service_rows` `0x004ba3d0` now + clearly owns the selected subject rows around `0x7d06`, `0x7d96..`, and `0x7d0e`, resolving + ordinary ids through the live candidate collection and the special express-side ids through the + embedded `AnyCargo.imb`, `AnyFreight.imb`, and `PassMail.imb` paths. The first fixed triplet is + now table-grounded instead of only inferred: `0x00621df8` seeds the short-label controls + `0x7dc8..0x7dca` with RT3.lng `494..496` `Any Cargo`, `Any Freight`, and `Any Express`, while + `0x00621e10` seeds the adjacent `0x7e90..0x7e92` icon-name triplet with `AnyCargo`, + `AnyFreight`, and `PassMail` before `%1.imb` formatting. RT3.lng also tightens the longer popup + side now: `0x00621e04` feeds the first clickable selector triplet `0x7f58..0x7f5a` with + `494/497/498`, so the help text there is `Any Cargo`, `Any Freight\n(Freight is everything but + Passengers, Mail, and Troops)`, and `Any Express\n(Express is Passengers, Mail, and Troops)`. + The sibling special service rows still align to `Dining Car` and `Caboose`. The extracted + `BuildingDetail.win` blob now sharpens the resource boundary too: its embedded text table is + currently sparse rather than rich, exposing the help line for `0x7d01`, repeated + `BuildingDetail.imb` asset strings, and one standalone caption entry `Cargo`. That makes + `Cargo` the strongest current resource-side anchor for the row header around `0x7d06`. The + ordinary deeper rows are tighter now too: they do not look like hidden caption-table entries, + but like live candidate-derived rows. The current path validates each ordinary id through + `indexed_collection_entry_id_is_live` `0x00517d40`, resolves the concrete candidate record + through `indexed_collection_resolve_live_entry_by_id` `0x00518140`, and then reuses candidate + field `[record+0x04]` as one shared stem for both the row asset `%s.imb` path and the + neighboring display-label lookup through + `localization_lookup_display_label_by_stem_or_fallback` `0x0051c920`. That lookup is now + bounded too: it scans the static stem table at `0x006243c8`, already grounding entries such as + `Alcohol`, `Aluminum Mill`, `Automobiles`, `Bauxite`, and `Big Boy` against RT3.lng + `3202..3220`, and only falls back to localized id `3866` when no table entry matches before the + fixed `0x384..0x386` express-side triplet takes over. One neighboring candidate-side helper is + tighter now too: `structure_candidate_query_route_style_or_local_availability_metric` + `0x0041e650` shares the same route-style byte at `[candidate+0x46]`, returning the cached local + float at `[candidate+0x5a]` for ordinary candidates but switching route-style rows to one + normalized count over the world-side route-link collection `0x006ada90` keyed by candidate class + `[candidate+0x3e]`. That collection is tighter now too: it is constructed during world bring-up + by `placed_structure_route_link_collection_construct` `0x00468110`, and current grounded + creation flow through `placed_structure_route_link_allocate_site_pair_for_candidate_class` + `0x00467f50` seeds class byte `+0x10`, a masked initial state template, and the strongest + current creation-side site-pair fields at `+0x0c` and `+0x0e` before + `placed_structure_route_link_attach_site_owner` `0x00467eb0` links the new route-link record + into the placed-structure-owned chain at `[site+0x272]`. The owner-side split is tighter now + too: route-link field `+0x08` is the separate route-node-style owner anchor used by + `placed_structure_route_link_attach_route_node_owner` `0x00467f20`, while `+0x0a/+0x0c/+0x0e` + now read as the site-reference triple matched by + `placed_structure_route_link_collection_remove_links_touching_site_id` `0x004681f0`. Creation + flow now sharpens that further: `+0x0c` is the strongest current candidate for the stable + first-site field seeded before owner attachment, `+0x0a` is the mutable owner-site anchor + installed by the attach helper, and `+0x0e` is the stable second-site field. One more split is + tighter now too: `placed_structure_route_link_recompute_endpoint_pair_state` `0x00467c30` + currently uses `+0x0a` and `+0x0e` as the active endpoint site pair while recomputing state + byte `+0x12`; `+0x0c` is still not directly read there. The family also has a clearer release + and refresh side now: `placed_structure_route_link_release_and_detach` `0x004680b0` rolls back + the class counters and then tails into `placed_structure_route_link_detach_current_owner_chain` + `0x00467df0`, while + `placed_structure_route_link_collection_recompute_all_endpoint_pair_state` `0x004682c0` + explicitly reruns the per-record endpoint-pair reconciler across the whole live route-link + collection. One layer above that, + `placed_structure_route_link_rebuild_route_style_grid_counters_and_endpoint_state` + `0x00468300` now looks like the full-family refresh owner: it clears three route-style class + lanes in the world-grid tables rooted at `[0x0062c120+0x2129]`, then clears bit `0x2` across + the live route-link records and reruns the endpoint-pair reconciler. That now lines up with the + visible shell split: non-route candidates keep the richer local metric and price lane, while + route-style candidates use one world-side route-link family instead. The emission side is + tighter now too: `placed_structure_try_emit_best_route_style_peer_link_for_candidate_class` + `0x0040fef0` scans the live placed-structure collection for one best peer site by + class-specific weight, distance window, and type gate, then only creates a new route-link + through `placed_structure_route_link_allocate_site_pair_for_candidate_class` `0x00467f50` when + `placed_structure_endpoint_pair_has_shared_route_entry_key` `0x0040fbe0` says the chosen site + pair does not already share a route-entry key. One layer above that, + `placed_structure_rebuild_route_style_candidate_scores_and_peer_links` `0x004101e0` now reads + as the broader per-site owner of this lane: it computes per-class route-style score scalars from + local site state and scenario multipliers, drives the first three route-style emission attempts, + and then continues into a larger descriptor-driven scoring phase. Inside that larger pass, + `placed_structure_accumulate_candidate_metric_or_emit_route_style_peer_link` `0x0042cab0` + now cleanly shows the split between ordinary candidates, which add directly into the local + route-style grid lane at `[site+candidate*4+0x103]`, and remapped route-style candidates, which + re-enter the peer-link emitter. One layer above that, the broader post-create or post-edit site + rebuild `placed_structure_finalize_creation_or_rebuild_local_runtime_state` `0x0040ef10` + conditionally re-enters `0x004101e0` with stack flag `1` when its local latch at `[site+0x29e]` + stays clear, so the route-style lane is no longer floating under an unnamed single-site caller. + The placement side is tighter now too: the direct constructor + `placed_structure_collection_allocate_and_construct_entry` `0x004134d0` is the shared allocator + immediately beneath the current placement-side callers before they hand the new site into + `0x0040ef10`, and the lower constructor + `placed_structure_construct_entry_from_candidate_and_world_args` `0x0040f6d0` now bounds the + actual field-seeding layer beneath that allocator. The old unresolved higher placement chooser is + bounded more cleanly now too: the `0x00403ed5` and `0x0040446b` direct-placement commits sit + inside one larger helper, + `city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0`. That shared + heavy builder is now the common target of the compact wrapper `0x00404640`, the peer-route + candidate builder `0x004046a0`, the region-entry pair wrapper + `city_connection_try_build_route_between_region_entry_pair` `0x00404c60`, and the direct retry + paths inside `simulation_try_select_and_publish_company_start_or_city_connection_news` + `0x00404ce0`. Internally it now has three bounded lanes: + an early explicit route-store attempt through `0x004a01a0`, + a single-endpoint direct-placement lane that scans `Maintenance` and `ServiceTower` candidates + and commits through `0x00403ed5 -> 0x004134d0 -> 0x0040ef10`, + and a later paired-endpoint fallback lane that seeds two endpoint candidates from the same stem + family, walks a temporary route-entry list, and commits through + `0x0040446b -> 0x004134d0 -> 0x0040ef10`. + It can still unwind through route-state cleanup without committing new placed structures, so the + exact lower helper semantics are not fully closed, but the broader chooser is no longer + anonymous and its main policy split is now visible. The two lower helpers directly under those + commit lanes are bounded now too: + `placed_structure_project_candidate_grid_extent_offset_by_rotation` `0x00417840` is the shared + projected-footprint offset helper over candidate bytes `[candidate+0xb8]` and `[candidate+0xb9]`, + and `placed_structure_validate_projected_candidate_placement` `0x004197e0` is the shared + go-or-no-go validator that checks company, territory, world-tile, and footprint occupancy state + before either direct-placement commit is allowed to fire. + The recurring outer owner is tighter now too: + `placed_structure_collection_refresh_quarter_subset_route_style_state` `0x00413580` walks every + fourth live placed structure from a scenario-time-derived offset and re-enters the per-site + rebuild with stack flag `0`, giving the route-style lane a concrete recurring maintenance sweep + under `simulation_service_periodic_boundary_work` rather than only a floating caller note. One + neighboring helper is now bounded on the message side too: + `shell_building_detail_handle_subject_value_row_band_action` `0x004ba270` switches over the + clicked row family `0x7d07..0x7d14`, treats subject bytes `+0x21/+0x22/+0x23` as one current + selection plus one bounded low/high pair, increments the family dirty latch at `0x006cfe0c` on + change, and republishes the refreshed value through the shared shell control helper on code + `0x66`. One neighboring helper is now bounded on the side-list path too: + `shell_building_detail_propagate_selected_subject_state_into_side_list` `0x004b9ec0` walks the + sibling list owner at `0x006cfe08`, copies the active subject state into each side-list record, + mirrors the current service or capability id at `+0x24`, and preserves the `0x40/0x20/0x10` + subflags from the active subject. That means the value-row actions and later selector rows now + read as propagating one shared building-detail state across the sibling list rather than only + mutating one isolated subject record. One neighboring helper is + now bounded separately too: `shell_building_detail_refresh_subject_pair_value_rows` `0x004bad20` + owns the mutually exclusive value-row pairs `0x7d07/0x7d08`, `0x7d11/0x7d12`, and + `0x7d13/0x7d14`, choosing among them from the same selected-subject flag byte and payload fields + at `+0x22/+0x23`, while the larger cargo-or-service row owner also gates the extra visual lanes + `0x7d6a`, `0x7d6b`, and `0x7d9d` from that same subflag family. The asset-string block is tighter + too: that branch family now explicitly uses `AnyCargo.imb`, `AnyFreight.imb`, `PassMail.imb`, + `Caboose.imb`, and `Dining.imb`, with the bit-`0x20` special lane already aligned to + `Caboose.imb` and the sibling bit-`0x10` special lane now aligned to `Dining.imb`. The larger + `0x7f58..0x801f` band is no longer just a styled row family either: + `shell_building_detail_present_flagged_service_capability_popup` `0x004b9fd0` is now grounded as + its explanatory popup callback. It resolves either one fixed express-side row from `0x00621e04` + or one active candidate or service id from `[subject+0x24]`, then formats one popup through the + shell message-box path. The neighboring refresh helper `shell_building_detail_refresh_flagged_service_capability_rows` + `0x004b9a20` is tighter now too: `0x7d07..0x7d1c` is not one anonymous block, but a real mask + partition over subject bits `0x20` and `0x10`, with one zero-mask pair, one bit-`0x20`-only + pair, one exclusive-or pair, and later one-bit and two-bit indicator rows. RT3.lng now closes + the fixed popup text family too: the single-line branch uses + `3922` `%1\nLoads available at %2: %3`, while the richer ordinary-candidate branch uses + `2981` `%1\nLoads available at %2: %3 Current Price: %4` and can append + `2982` `Price at next station, %1: %2 (%3%4)`. The selector band is narrower too: current + refresh-side evidence shows `0x7f58..0x801f` as one selected-ordinal highlight family over the + three fixed express rows plus the ordinary active-candidate rows, not as a generic unstructured + list. The neighboring `0x8020..0x8051` band is tighter too: it is primarily the matching + remove-entry family for the selected subject's live id list, with two special row indices + re-routing into the `0x7d0f/0x7d10` subflag-clearing path instead of ordinary list compaction + when the current `0x20/0x10` service-bit combination demands it. That means the exact captions + are no longer broadly open across the whole selector family: the fixed express-side rows, the + mask partitions, and the add/remove structure are grounded, and the remaining caption gap is + mostly the ordinary candidate rows further down the same band. The top-level toggles are + tighter now too: the paired + `0x7d02/0x7d03` controls are the real mode switch over subject bit `0x40`, choosing between the + bounded pair-value branch and the current-selection/status branch around `0x7d0d/0x7d0e`, while + the smaller `0x7d0f/0x7d10` controls flip the same special-service subflags later rendered as + `Caboose` and `Dining Car`. One adjacent control is tighter now too: the extracted + `BuildingDetail.win` resource contains the plain-English line `Set the initial cargo amount for + 'Disable Cargo Economy' scenarios.`, and the `0x7d01` plus `0x7d09/0x7d0a` message-side branch + can mirror the current subject or selection through + `shell_building_detail_submit_aux_owner_subject_sync_request` `0x004b9e10` into the auxiliary + owner queue at `[0x006cd8d8+0x8f48]`, with side-owner presence now explicitly grounded through + `shell_has_auxiliary_preview_owner` `0x00434050`. That queued request is tighter too: both + current callsites forward the same side-list mirror latch at `[0x006cfe08+0x0c]`, so the + auxiliary owner now clearly sees not just the staged subject but also whether the local + `BuildingDetail` side-list is in mirrored-subject mode. The same `0x7d01` lane also now has one + clear rejection note: localized id `3587` `This option is only available by following the + tutorial.` now sits behind the active tutorial flag at `0x006d3b4c` and the cached previous + tutorial expected-control id at `0x00622b38`, while the neighboring tutorial helper + `tutorial_advance_step_and_refresh_expected_control_ids` `0x00516be0` now grounds + `0x00622b34/0x00622b38/0x00622b3c` as the current and previous expected-control cache rather + than anonymous globals. The last field is tighter now too: `0x00622b3c` is currently best read + as the active tutorial step's alternate-accepted companion control id, because the generic shell + control path compares clicked control ids against it directly and suppresses the `3587` tutorial + rejection when they match. That does not fully close the player-facing caption bind for every + control, but it does bound the neighboring side-owner sync and tutorial-rejection lane instead + of leaving it as anonymous glue. + The extra pre-insert gate is narrower than it + first looked. It is now grounded as tutorial-only: + `tutorial_validate_train_route_station_indicator_step` `0x00516d00` checks the current tutorial + step from the shell tutorial descriptor table at `0x00622b48` before a live station-or-transit + site id can be committed into the staged route entry, and the currently accepted steps align with + localized prompts `3777` and `3778`, the two train-routing tutorial instructions that tell the + player to click the Milan and Turin station indicators. Outside that tutorial state family, the + route-entry insertion path is not gated there. The adjacent validator is tighter now too: + `train_route_list_validate_reachability_and_station_pair` `0x004b2c10` walks that same route list, + resolves placed-structure-backed entries through the live placed-structure and route-node + collections, uses the direct route-node payload branch for the remaining entry family, and fails + with `3089..3091` when the resulting route cannot be traversed or does not preserve a valid + terminal station pair. The post-validation follow-on is bounded too: + `train_current_route_context_uses_strict_reachability_mode` `0x004a9460` is now the small shared + gate above the stricter branch, keyed off the current linked route object's downstream class type, + and `train_set_route_operating_mode_and_scalar` `0x004ab980` now reads as the shared train mode + setter beneath route editing, with the local and multiplayer insertion paths choosing mode + `0x13` only when that stricter second validation succeeds and mode `0x0a` on the looser fallback + path. The first + deeper world-mode interaction branch is now better + bounded: `GameUppermost.win` hotspots, cursor drag, held Shift state, discrete shell view-step + commands, direct keyboard turn/pan/zoom bindings, the `TrackLay.win` and `StationPlace.win` + world-command surfaces, and a frame-owned hover or focus-target transition branch all feed the + same shell-controller-backed path. The remaining uncertainty has moved farther from basic + ownership: the hover-target branch clearly exists, and `0x07d6` now looks like the shared + main-world interaction surface rather than a generic detail button for one tool family only. 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 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 + `[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. 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 remaining gaps on this lane + are therefore narrower than before: 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 selector helper on `StationPick.win`. 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 capital or dividend summary block through + `shell_company_detail_render_capital_and_dividend_summary_panel`, control `0x948a` now grounds the + per-share metrics block through `shell_company_detail_render_per_share_metrics_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 public-support side + is now tighter too because `company_compute_cached_recent_performance_support_score` and + `company_compute_public_support_vote_scalar` bound the recent-performance and public-support blend + beneath those vote resolvers, `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`, so the remaining gap is now mostly + semantic: the exact player-facing names of the support-and-governance metric slots behind issue + ids `0x37` and `0x3a`, plus any later chairmanship-control side effects beyond the already + grounded success or failure commit points. The packed simulation calendar tuple semantics also + remain open. 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. -- 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 `0x005ee4fc` and `0x005ee500`, 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`. The nearby connection-state notes `3872` and `3873` are still tied to adjacent overlay-side ownership checks, but `3879` `Out of Sync` does not currently appear inside `0x0043f640` itself and remains a separate unresolved sibling owner. -- Station-detail overlay, corrected boundary: `3879` `Out of Sync` is no longer an unresolved overlay sibling. It is now 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 adjacent connection-state note lanes. -- Station-detail overlay, 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 overlay compares that id against the active company selector before deciding whether a scanned site should carry the `Already Connected by Another Company` note. The remaining local gap on this branch is the exact branch that emits the neighboring `Not Connected` note. -- Station-detail overlay, 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 and the final `Out of Sync` chooser. +- CompanyDetail, tighter 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. 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. +- 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; `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 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 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 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, and + `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`. 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, + `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. + `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 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. + +- 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 `0x005ee4fc` and `0x005ee500`, 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. +- Station-detail overlay, 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. +- Station-detail overlay, 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. +- Station-detail overlay, 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. +- Station-detail overlay, 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, `company_compute_issue39_opinion_bias_scalar` at + `0x00424580` contributes one smaller issue-`0x39` opinion term, + `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 a rolling shareholder-facing performance lane reused by annual + shareholder-revolt or creditor-pressure checks and a per-share/history formatter, while `0x09` + remains the narrower current governance-pressure term read after those broader gates. The wider + 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. +- Station-detail overlay, 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. ## Next Mapping Passes -- Resolve the owner-side callback roles behind the validated GameSpy packet branches, especially `[route+0x9c]`, `[route+0xa0]`, `[route+0xa4]`, and `[route+0xd4]`. -- Determine whether any later world-mode branch beneath the frame owner bypasses the shell controller input path for non-cursor gameplay input, since the current grounded overlay and cursor helpers still reuse `0x006d4018`. -- Keep detailed pending-template or transport work scoped to the specific atlas edges that remain unresolved. +- Resolve the owner-side callback roles behind the validated GameSpy packet branches, especially + `[route+0x9c]`, `[route+0xa0]`, `[route+0xa4]`, and `[route+0xd4]`. +- Determine whether any later world-mode branch beneath the frame owner bypasses the shell + controller input path for non-cursor gameplay input, since the current grounded overlay and cursor + helpers still reuse `0x006d4018`. +- Keep detailed pending-template or transport work scoped to the specific atlas edges that remain + unresolved.