From b86dbb1e6471a08b3c294d4e86c9b64125f69be4 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Sun, 5 Apr 2026 20:11:47 -0700 Subject: [PATCH] Map auxiliary route-entry tracker helpers --- artifacts/exports/rt3-1.06/function-map.csv | 66 ++++- docs/control-loop-atlas.md | 251 +++++++++++++++++++- 2 files changed, 312 insertions(+), 5 deletions(-) diff --git a/artifacts/exports/rt3-1.06/function-map.csv b/artifacts/exports/rt3-1.06/function-map.csv index caafa37..d07f86e 100644 --- a/artifacts/exports/rt3-1.06/function-map.csv +++ b/artifacts/exports/rt3-1.06/function-map.csv @@ -1,13 +1,30 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,confidence,notes,verified_against 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" +0x004014b0,1194,company_try_buy_unowned_industry_near_city_and_publish_news,simulation,thiscall,inferred,objdump + callsite inspection + RT3.lng strings,2,"Company-side acquisition and headline helper beneath the broader periodic company service pass at `0x004019e0`. The function requires at least two linked transit sites through `company_count_linked_transit_sites` `0x00426590`, rejects when scenario finance toggle `[0x006cec78+0x4abf]` is set, and then scans the live building or structure collection at `0x0062b26c` for the best current acquisition target. Current grounded candidate filters are: the record must not already have an owner in `[site+0x276]`, its linked candidate subtype gate through `0x0040d360` must identify subtype `4`, the company-specific price or affordability metric from `0x0040d540` must stay below the current company metric window, and the record must be at least three years old from `[site+0x3d5]`. Surviving candidates are scored through local profitability or demand helpers around `0x0040cac0`, `0x0042c820`, `0x00455f60`, and the current company support scalar, and the best surviving site id is then committed through `0x004269b0`. On success the helper localizes the acquired structure type through `localization_lookup_display_label_by_stem_or_fallback` `0x0051c920`, resolves the nearby city or region entry through `0x004220b0`, and emits RT3.lng `2880` `%1 has bought a %2 near %3` through the shell news helper at `0x004554e0`. This is now the strongest current match for the acquisition-side sibling beneath the broader company periodic pass, though some lower structure-side helper semantics remain open.","objdump + callsite inspection + RT3.lng strings + acquisition-news correlation + structure-scan correlation" +0x00401860,221,company_query_cached_linked_transit_route_anchor_entry_id,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Returns one cached route-entry anchor id used by the linked-transit company cache family. The helper first validates the cached id at `[this+0x0d35]` against the live route-entry collection `0x006cfca8`, requiring the resolved record to carry this company id in word `[entry+0x22e]` and byte value `2` in `[entry+0x216]`; otherwise it clears the cache to `-1`. When the cache is empty but the three company-side count lanes `[this+0x7664]`, `[this+0x7668]`, and `[this+0x766c]` still sum positive, it scans the route-entry collection for the first record that satisfies those same owner and class predicates and then caches the record's linked anchor id from `[entry+0x202]`. Current grounded caller is `placed_structure_is_linked_transit_site_reachable_from_company_route_anchor` `0x004801a0`, where the returned route-entry id is used as the company-side anchor for the narrower linked-transit reachability gate.","objdump + caller xrefs + callsite inspection + route-entry-anchor correlation" +0x00401940,152,company_reset_linked_transit_caches_and_reseed_empty_train_routes,simulation,thiscall,inferred,objdump + callsite inspection + linked-transit correlation,2,"Small linked-transit reset helper beneath the broader company service family. The function clears the two company-side linked-transit cache timestamps at `[this+0x0d3e]` and `[this+0x0d3a]`, immediately re-enters `company_service_linked_transit_site_caches` `0x00409720`, and then walks the live train collection `0x006cfcbc` for company-owned trains. For owned trains in operating modes `0x0a` or `0x13` it removes every existing route-list entry through `train_route_list_remove_entry_and_compact` `0x004b3000`; when the route list is empty it then re-enters `train_try_append_linked_transit_autoroute_entry` `0x00409770`. Current grounded meaning is a local linked-transit cache reset plus empty-route reseed pass rather than a broader train-service sweep.","objdump + callsite inspection + linked-transit correlation + train-route-reset correlation" +0x004019e0,611,company_service_periodic_city_connection_finance_and_linked_transit_lanes,simulation,thiscall,inferred,objdump + callsite inspection + caller correlation + RT3.lng strings,2,"Broader periodic company-side service pass above the currently grounded city-connection, finance, and linked-transit lanes. The helper first rejects inactive or special-case companies through `[this+0x3f]` and `0x00425b90`, clears the transient company-side latches at `[this+0x0d17]`, `[this+0x0d18]`, and `[this+0x0d56]`, and temporarily mirrors one locomotive-derived byte from `[this+0x0d17]` into scenario field `[0x006cec78+0x4c74]` while the earlier route-building side of the body runs, restoring the original scenario value on exit. Current evidence now bounds those byte latches more narrowly: `[this+0x0d17]` is this transient route-search preference override, currently seeded only when `company_select_preferred_available_locomotive_id` `0x004078a0` resolves one locomotive whose engine-type dword `[record+0x10]` equals `2`; wider engine-type evidence now makes that best-read as the electric lane, since the linked approval helper around `0x0041d550` dispatches the same `0/1/2` field across three scenario opinion slots while the local language family `706..709` and help text `3848` bound the player-facing triplet as `Steam`, `Diesel`, and `Electric`. The route-search side is tighter now too: this mirrored byte is not just reusing a display preference slot abstractly, it feeds the same initial path-sweep branch in `route_entry_collection_run_initial_candidate_path_sweep` `0x0049bd40` that explicit route-policy byte `4` uses, selecting the larger `1.8` quality multiplier instead of `1.4` before the later acceptance checks. `[this+0x0d18]` is the city-connection announcement-side latch reused by `company_evaluate_and_publish_city_connection_bonus_news` `0x00406050`; and `[this+0x0d56]` is the linked-transit train-service latch later set by the train-add, train-upgrade, and route-builder-side cache-refresh family around `0x00409830`, `0x00409300`, and `0x0040457e -> 0x004093d0`. The ordering matters too: this owner clears those latches up front, runs the city-connection and linked-transit branches first, and only later enters `company_evaluate_annual_finance_policy_and_publish_news` `0x00401c50`, so the finance helper is reading same-cycle side-channel state rather than stale long-lived flags. It then gates and schedules several narrower service families: the city-connection announcement side through `simulation_try_select_and_publish_company_start_or_city_connection_news` `0x00404ce0` and `company_evaluate_and_publish_city_connection_bonus_news` `0x00406050`; the acquisition-side sibling through `company_try_buy_unowned_industry_near_city_and_publish_news` `0x004014b0`; the linked-transit train side through `company_balance_linked_transit_train_roster` `0x00409950`; the broader annual finance and governance helper through `company_evaluate_annual_finance_policy_and_publish_news` `0x00401c50`; and the linked-transit cache refresh tail through either `company_rebuild_linked_transit_site_peer_cache` `0x004093d0` or `company_rebuild_linked_transit_autoroute_site_score_cache` `0x00407bd0` depending on current scenario mode byte `[0x006cec78+0x0f]`. This name stays intentionally conservative: it is the broader periodic owner above those lanes, not a fully split policy map yet.","objdump + callsite inspection + caller correlation + RT3.lng strings + linked-transit correlation + city-connection correlation + acquisition correlation + latch correlation + sequencing correlation + temporary-route-preference correlation + locomotive-choice correlation + engine-type correlation + route-search-threshold correlation" +0x004078a0,815,company_select_preferred_available_locomotive_id,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Selects one preferred locomotive id for the current company from the live locomotive collection at `0x006ada84`. The helper iterates the live locomotive records, applies company-and-chairman availability gating through the linked approval family around `0x0041d550`, accumulates one weighted preference score from locomotive fields `[record+0x20]`, `[+0x28]`, `[+0x18]`, `[+0x1c]`, `[+0x0c]`, and the linked class or era record at `[record+0x72]`, and keeps the strongest surviving locomotive id, falling back to `locomotive_collection_select_best_era_matched_non_electric_fallback_id` `0x00461cd0` when no scored candidate survives. Current grounded callers are the periodic company service pass `0x004019e0`, the temporary route-side mode chooser around `0x00402d5f`, the linked-transit train-upgrade news helper `0x00409300`, and the linked-transit train-add helper `0x00409830`. Current evidence now also bounds one route-policy side effect above it: `0x004019e0` only arms its temporary `[company+0x0d17] -> [0x006cec78+0x4c74]` override when the chosen locomotive record carries engine-type value `2` in `[record+0x10]`, which now best aligns with the electric lane rather than an unnamed class slot.","objdump + caller xrefs + callsite inspection + locomotive-collection correlation + preferred-choice correlation + engine-type correlation" +0x00401c50,3016,company_evaluate_annual_finance_policy_and_publish_news,simulation,thiscall,inferred,objdump + callsite inspection + RT3.lng strings,2,"Large annual company finance-policy helper beneath the broader periodic service pass at `0x004019e0`. The earliest creditor-pressure or bankruptcy lane is now bounded more tightly: it requires scenario mode `0x0c`, the bankruptcy toggle `[0x006cec78+0x4a8f]` to be clear, at least `13` years since the last bankruptcy stamp at `[this+0x163]`, and at least `4` years since founding year `[this+0x157]`. It then scans the last three years of shareholder-facing metrics through `company_read_year_or_control_transfer_metric_value` `0x0042a5d0`, accumulating slot `0x2b`, counting one three-year failure condition from slot `0x2c`, selecting one negative debt-pressure ladder `-600000 / -1100000 / -1600000 / -2000000` from the current slot-`0x2c` band split at roughly `120000 / 230000 / 340000`, requiring current public support from `company_compute_public_support_vote_scalar` `0x00424fd0` to be at least `15` or `20` depending on whether all three years failed, checking slot `0x09` against `0.08` times that ladder, and requiring both `edi >= 2` plus the three-year slot-`0x2b` accumulator to clear one final `-60000` threshold before it commits bankruptcy through `company_declare_bankruptcy_and_halve_bond_debt` `0x00425a90` and formats RT3.lng `2881` `%1 has declared bankruptcy!`. The later debt-capital restructuring family mutates the live company through `company_repay_bond_slot_and_compact_debt_table` `0x00423d70`, `company_issue_bond_and_record_terms` `0x004275c0`, `company_repurchase_public_shares_and_reduce_capital` `0x004273c0`, and `company_issue_public_shares_and_raise_capital` `0x00427450`, then formats the RT3.lng `2882..2886` headlines `%1 has refinanced %2 of debt.`, `%1 has refinanced %2 of debt and borrowed %3 on top of that.`, `%1 has refinanced %2 and paid off a further %3 of debt.`, `%1 has paid off %2 of its debt.`, and `%1 has borrowed %2 in debt.` The middle annual bond lane is tighter now too: when the bond toggle `[+0x4a8b]` is clear, it first simulates full bond repayment through repeated `company_repay_bond_slot_and_compact_debt_table` `0x00423d70`, then uses the resulting cash-side window with the fixed `-250000` and `-30000` thresholds plus the broader linked-transit train-service latch `[this+0x0d56]` to decide whether to stage one or more `500000` principal, `30`-year bond issues through `company_issue_bond_and_record_terms` `0x004275c0`. The repurchase lane is distinct from the later share-issue path: when the city-connection announcement-side latch `[this+0x0d18]` is set, editor growth setting `2` does not suppress it, and the stock toggle `[+0x4a87]` is clear, it starts from one `1000`-share batch and one default factor `1.0`, can replace that with a linked-chairman personality scalar `([table byte * 39] + 300) / 400`, scales that factor by `1.6` when growth setting `[0x006cec78+0x4c7c] == 1`, uses the resulting factor in one `800000` stock-value gate and one public-support times factor times `1000` times `1.2` affordability gate, requires enough unassigned shares through `company_count_unassigned_shares_after_active_chairman_holdings` `0x004261b0`, and then commits repeated `1000`-share repurchases through `company_repurchase_public_shares_and_reduce_capital` `0x004273c0`; this is the current strongest threshold owner behind RT3.lng `2887`. The sequencing above this helper now bounds those two latch reads more clearly: `0x004019e0` clears them first, then the city-connection and linked-transit branches may set them earlier in the same periodic pass, so the bond and repurchase lanes are currently best read as same-cycle reaction policy rather than long-term company-state policy. The later stock-issue lane is tighter too: after the earlier debt or bankruptcy outcomes stay inactive, with the bond and stock toggles `[+0x4a8b]` and `[+0x4a87]` clear, at least two bond slots live, and at least one year since founding, it derives one 1000-share batch with floor `2000`, requires public support at least `22`, requires the public-support times batch product to clear `55000`, and then checks a piecewise approval ladder pairing one candidate-side scalar against a normalized support ratio: `0.07/1.3`, `0.08/1.2`, `0.09/1.1`, `0.10/0.95`, `0.11/0.8`, `0.12/0.62`, `0.13/0.5`, and `0.14/0.35` before the share-issue commit path proceeds. The dividend-side branch is now bounded too: it requires the dividend toggle `[0x006cec78+0x4a93]` to be clear, scenario mode `0x0c`, at least `1` year since `[this+0x0d2d]`, and at least `2` years since founding; it then averages the last three years of slot `0x2b`, folds in the unassigned-share pool from `company_count_unassigned_shares_after_active_chairman_holdings` `0x004261b0`, the current slot `0x0d` band, and the map-editor building-density growth setting `[0x006cec78+0x4c7c]`. Current grounded postblend behavior is: growth setting `1` scales the existing dividend by `0.66`, growth setting `2` zeros it, computed deltas at or below `0.1` collapse to zero, larger deltas are quantized in tenths, and the final value is clamped against `company_compute_board_approved_dividend_rate_ceiling` `0x00426260`. The tail also refreshes `CompanyDetail.win` when the selected company matches `[0x006cfe4c]`. This now grounds the main finance verbs and most first-layer threshold constants under the annual policy pass, though some lower policy semantics still remain open.","objdump + callsite inspection + RT3.lng strings + finance-policy correlation + bankruptcy/debt-news correlation + repurchase-news correlation + finance-mutator correlation + threshold correlation + latch correlation + sequencing 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" +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 route-entry search or synthesis lane through `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0` over the global route-entry store `0x006cfca8`, which can seed the builder-state block and succeed 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 external callers are still entirely in the city-connection family: 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 + route-entry search 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" +0x00407bd0,1697,company_rebuild_linked_transit_autoroute_site_score_cache,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Slower per-company follow-on above the fast linked-transit peer cache. The helper stamps the current scenario tick into `[this+0x0d3a]`, then walks the live placed-structure collection and keeps only sites whose company-side cache cell at `[site+0x5bd][company_id]` is present and eligible. For each such site it refreshes the cache-cell tick at `+0x0a`, zeroes the three accumulated float lanes at `+0x0e`, `+0x12`, and `+0x16`, and then rolls candidate-local service metrics into those floats. The first phase uses `placed_structure_count_candidates_with_local_service_metrics` `0x0047e330`, `0x0047e620`, and the issue-opinion helper `0x00437d20` to collect bounded candidate-local metric and scaling bands; the second phase re-enters the per-site peer buffer at cache `+0x06`, compares each peer's stored route-step delta against the live site-side service words from `0x0047de20`, and accumulates the surviving weighted contributions back into `+0x0e` and `+0x12` before promoting the strongest grouped result into `+0x16`. Current grounded callers are the company-side mode gate at `0x00401c2a`, the timed wrapper at `0x00409766`, and the fast-cache tail path at `0x004093cd`. This now reads as the slower autoroute-site score rebuild over the linked-transit peer cache family rather than an unnamed tail call.","objdump + caller xrefs + callsite inspection + linked-transit score-cache correlation" +0x00408280,255,company_select_best_owned_linked_transit_site_by_autoroute_score,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Selects one owned linked transit site from the company-side autoroute cache family. The helper walks the live placed-structure collection, keeps only sites whose company cache cell `[site+0x5bd][company_id]` is present and eligible, whose linked company id matches the current company, and which still pass the station-or-transit gate `0x0047fd50`. It then ranks the surviving sites by cache float `[cell+0x16]`, applying a small bonus when the placed-structure-side lanes `[site+0x5c1]` and `[site+0x5c5]` are both clear, and returns the winning site id or `-1` when no candidate survives. Current grounded caller is `company_build_linked_transit_autoroute_entry` `0x00408380`, where this helper provides the fallback start site when the caller does not already supply one.","objdump + caller xrefs + callsite inspection + linked-transit autoroute correlation" +0x00408380,3215,company_build_linked_transit_autoroute_entry,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Builds one `0x33`-byte train route-list entry from the company-side linked-transit autoroute caches. When the caller-supplied site id is absent or invalid, the helper first falls back to `company_select_best_owned_linked_transit_site_by_autoroute_score` `0x00408280`. It then walks the chosen site's peer buffer from `[site+0x5bd][company_id]+0x06`, recomputes grouped candidate-local deltas against the peer site's service words from `0x0047de20`, chooses the strongest surviving peer site, and finally formats one route-list record into the caller-owned output buffer: it clears the `0x33`-byte record, preserves the low nibble of flag byte `+0x28`, writes the chosen target site id into word `+0x29`, seeds the route-kind dword at `+0x24` with `0x384`, and fills the remaining route-anchor or metadata lanes through the auxiliary route-entry tracker family at `0x006cfcb4` when a linked train record is supplied. Current grounded callers are `train_try_seed_route_list_from_company_linked_transit_sites` `0x00409770` and two neighboring stack-built retry branches in the same family. This now looks like the shared route-entry builder above the linked-transit autoroute cache rather than another raw site query.","objdump + caller xrefs + callsite inspection + route-list-entry correlation + linked-transit autoroute correlation" +0x00408f70,864,company_compute_owned_linked_transit_site_score_total,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Aggregates one company-side linked-transit site score total from the placed-structure cache family. The helper walks the live placed-structure collection at `0x006cec20`, keeps only records whose company-specific cache cell `[site+0x5bd][company_id]` is present and eligible, whose linked company id matches the current company, and which still pass the narrower station-or-transit gate `0x0047fd50`, then accumulates the float at cache offset `+0x12` across the surviving sites while also retaining one or two representative site pointers for neighboring callers. Current grounded caller is the linked-transit train-roster balancer at `0x00409950`, where this returned float is compared against the current owned-train count and train-age heuristics before the add, upgrade, or removal branches run.","objdump + caller xrefs + callsite inspection + linked-transit score-total correlation" +0x00409300,200,company_publish_train_upgrade_news,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection + RT3.lng strings,3,"Formats and publishes the linked-transit train-upgrade news item. After one scenario gate through `[0x006cec78+0x4a97]`, the helper chooses one preferred locomotive id through `0x004078a0`, resolves the caller-supplied train id through the live train collection `0x006cfcbc`, formats the old and new locomotive names through the locomotive collection `0x006ada84` and the name helper at `0x00461ca0`, and then emits RT3.lng id `2897` `%1 has just upgraded a %2 to a %3.` through the shell news helper at `0x004554e0`. It finally sets the byte latch at `[company+0x0d56]`. Current grounded callers are the train-roster balancer at `0x00409950` and one neighboring branch at `0x00409b52`, so this now reads as the shared company-side train-upgrade headline helper rather than an anonymous news formatter.","objdump + caller xrefs + callsite inspection + RT3.lng strings + train-upgrade news correlation" +0x004093d0,837,company_rebuild_linked_transit_site_peer_cache,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Per-company fast refresh over the placed-structure-side linked-transit peer cache. The helper stamps the current scenario tick from `[0x006cec78+0x15]` into `[this+0x0d3e]`, then walks the live placed-structure collection at `0x006cec20`. For each site it resolves the company-specific cache cell from the site's pointer table `[site+0x5bd][company_id]`, marks the cell present, clears its eligible byte, and frees any prior peer-record buffer at `+0x06`. It then marks a site eligible when it passes the station-or-transit gate `0x0047fd50`, the linked-instance class test `0x0047de00 -> 0x0040c990 == 1`, and either already belongs to this company through `placed_structure_query_linked_company_id` `0x0047efe0` or survives the neighboring route-anchor reachability gate `0x004801a0` plus the minimum-distance threshold built from `company_query_min_linked_site_distance_to_xy` `0x00405920`. In the second pass each eligible site receives a zeroed `(eligible_count*0x0d)+1` byte peer buffer at cache offset `+0x06`, and the helper fills one `0x0d`-byte record per eligible peer: byte `+0x00` is a route-side reachability flag, dword `+0x01` stores the peer site id, dword `+0x05` stores the returned route-step delta from `0x004a6630`, and float `+0x09` stores the normalized delta-per-step ratio. The function then tails into the heavier company-side follow-on at `0x00407bd0`. Current grounded callers are the company-side world or service wrapper `0x00409742`, the mode-gated company pass at `0x00401c23`, the route-builder-side company refresh at `0x0040457e`, and the active-company collection sweep `0x00429c5b`.","objdump + caller xrefs + callsite inspection + linked-transit cache correlation + placed-structure cache-cell correlation" +0x00409720,80,company_service_linked_transit_site_caches,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Timed service wrapper above the two company-side linked-transit cache lanes. The helper refreshes the fast peer cache through `company_rebuild_linked_transit_site_peer_cache` `0x004093d0` when `[this+0x0d3e]` is zero or older than `0x7ff80` ticks, and otherwise refreshes the slower follow-on lane at `0x00407bd0` when `[this+0x0d3a]` is zero or older than `0x31380` ticks. Current grounded direct callers are `0x004097b8`, which re-enters it after one larger local mode change, and several neighboring company-side service paths. This now looks like the bounded timed owner for the company-side linked-transit cache family rather than another anonymous small wrapper.","objdump + caller xrefs + callsite inspection + timed-service correlation" +0x00409770,88,train_try_append_linked_transit_autoroute_entry,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Attempts to append one linked-transit autoroute entry onto a live train route list. After validating the train-side state and one current route-kind gate through `0x004a8840`, the helper clears one local staging byte, re-enters `company_service_linked_transit_site_caches` `0x00409720` on the owning company, and then asks `company_build_linked_transit_autoroute_entry` `0x00408380` for a single staged `0x33`-byte route-list record using the current anchor site id at `[this+0x0a0]`. On success it either appends that record through `train_route_list_insert_staged_entry_at_index` `0x004b3160` and refreshes the new trailing selection through `train_route_list_select_entry_and_refresh_linked_site_state` `0x004b2f00`, or when the list is already at the local two-entry cap it rotates the target slot via `[this+0x08] mod [this+0x04]` and overwrites that `0x33`-byte entry in place. Current grounded caller is the company-side service sweep at `0x004019cc`, so this now reads as the single-entry train-side autoroute append helper rather than a two-entry seeding pass.","objdump + caller xrefs + callsite inspection + linked-transit autoroute correlation + train-route-list correlation" +0x00409830,274,company_try_add_linked_transit_train_and_publish_news,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection + RT3.lng strings,3,"Local add-train branch beneath the linked-transit company train-roster balancer. The helper first respects scenario gate `[0x006cec78+0x4aa3]`, clears and seeds one staged route-entry buffer through `0x004b2ba0`, services the owning company's linked-transit caches, asks `company_build_linked_transit_autoroute_entry` `0x00408380` for two route-list entries, inserts those entries through `train_route_list_insert_staged_entry_at_index` `0x004b3160`, chooses one preferred locomotive id through `0x004078a0`, and then hands the staged route plus locomotive choice into the train-construction helper at `0x004b2140`. On success it emits RT3.lng id `2896` `%1 has added a new train (%2) at %3` through `0x004554e0` and sets the byte latch at `[company+0x0d56]`. Current grounded callers are the local add branches inside `company_balance_linked_transit_train_roster` `0x00409950`, while multiplayer callers package opcode `0x75` instead.","objdump + caller xrefs + callsite inspection + RT3.lng strings + linked-transit train-add correlation" +0x00409950,923,company_balance_linked_transit_train_roster,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Balances one company's linked-transit train roster against the linked-site cache family. The helper first requires at least one linked transit site through `company_count_linked_transit_sites` `0x00426590`, then computes one aggregate site score through `company_compute_owned_linked_transit_site_score_total` `0x00408f70` and counts currently owned trains through `company_count_owned_trains` `0x004264c0`. It walks the live train collection `0x006cfcbc`, keeps only trains owned by the current company, and uses current-year age terms from `[train+0x0d4]` plus the aggregate site score to decide whether old trains should be removed outright through the train collection vtable or upgraded in place through `company_publish_train_upgrade_news` `0x00409300`. After pruning, if the owned-train count still trails the target implied by the linked-site score, the helper repeatedly either packages multiplayer opcode `0x75` through `0x00469d30` or locally re-enters `company_try_add_linked_transit_train_and_publish_news` `0x00409830`. Current grounded callers are the company-side service sweep at `0x00401b9d` and a neighboring company wrapper at `0x004097b8`, so this now looks like the live train-balance owner above the linked-transit autoroute and news helpers rather than an unnamed local maintenance pass.","objdump + caller xrefs + callsite inspection + linked-transit train-balance correlation" +0x004264c0,96,company_count_owned_trains,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Counts the live trains owned by the current company. The helper walks the train collection at `0x006cfcbc`, compares each record's owning company byte at `[train+0x51]` against `[this+0x00]`, and returns the number of matches. Current grounded callers are the linked-transit train-roster balancer at `0x00409950` and the `LoadScreen.win` company train-list page at `0x004e7670`, where the count gates the no-trains fallback before the detailed roster rows are built.","objdump + caller xrefs + callsite inspection + company-owned train count 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 @@ -18,9 +35,11 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 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" +0x0041d550,574,locomotive_era_and_engine_type_pass_company_policy_gate,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection + engine-type correlation,2,"Policy gate beneath the preferred-locomotive chooser and its non-electric fallback. The helper operates on one locomotive-era or availability record whose linked locomotive id sits at `[this+0x126]`. On the fuller policy path, reached when record field `[this+0x41]` is `2` or `3`, it first respects several scenario-state locks rooted at `[0x006cec74+0x180]`, `[0x006cec78+0x4c8c]`, `[0x006cec7c+0x82]`, and `[0x006cec74+0x247]`, then resolves the linked locomotive record from `0x006ada84` and dispatches its engine-type dword `[locomotive+0x10]` across three scenario opinion slots through `scenario_state_sum_issue_opinion_terms_raw` `0x00436710`: `0x1c6`, `0x1c7`, and `0x1c8`, which current evidence now best aligns with the steam, diesel, and electric lanes. It also special-cases the locomotive stem at `[locomotive+0x34]` against the local string `WhaleL`; current data-file correlation now ties that stem to the `Orca NX462` locomotive family and its `WhaleL_NE` asset set, and when that compare hits the helper explicitly zeros the accumulated issue-opinion result before the later availability checks, so that family loses the positive-opinion shortcut rather than taking a bonus branch. It then consults one neighboring locomotive-derived issue or policy id through `0x00442a85`, and applies a late scenario availability triplet from `[0x006cec78+0x4c97..0x4c99]` against three per-record bytes `[this+0x30..0x32]` plus record field `[this+0x7b]`. That triplet now has a stronger player-facing read: the same three scenario bytes are the live editor-policy fields owned by `map_editor_locomotive_availability_panel_construct` `0x004cd680` and `map_editor_locomotive_availability_panel_handle_message` `0x004cf0d0`, and their localized labels `2863..2865` are `All Steam Locos Avail.`, `All Diesel Locos Avail.`, and `All Electric Locos Avail.`. The current gate is narrower than a plain override: when the issue-opinion result stays positive and none of those three editor bytes are enabled, that positive result alone seeds the local availability flag; but once any of the editor family bytes is nonzero, the helper instead requires one matching intersection between the per-record family bytes `[this+0x30..0x32]` and the corresponding scenario bytes `0x4c97..0x4c99`. Independent of that family check, record field `[this+0x7b]` can still carry the path into the later year-window gate. On the simpler path it falls straight to an era-window gate using the current scenario year with floor `0x726` against `[this+0x105]` and `[this+0x109]`, plus one current-month-like check from `[0x006cec78+0x0f]`. The helper returns `1` when the era and engine family pass those combined scenario, opinion, availability, and year gates; otherwise `0`. Current grounded callers are `company_select_preferred_available_locomotive_id` `0x004078a0` and `locomotive_collection_select_best_era_matched_non_electric_fallback_id` `0x00461cd0`.","objdump + caller xrefs + callsite inspection + engine-type correlation + year-window correlation + scenario-gate correlation + editor-locomotive-availability correlation + WhaleL carveout correlation + engine-data 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" +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 strongest current subtype-specific branch is `[candidate+0x32] == 1`, where the helper re-enters `placed_structure_project_candidate_grid_extent_offset_by_rotation` `0x00417840`, checks route-entry ownership and company track-laying capacity through `0x004240a0`, tries one explicit track-attachment path through `0x00494cb0`, and then falls back to one steeper world-space sweep through `0x00448bd0`. In that branch the optional failure buffer now has a concrete station-attachment or upgrade-style family: `0x0b55` `2901` not enough room to upgrade the station, `0x0b56` `2902` ground not flat enough for the upgraded station, `0x0b57` `2903` not your track, `0x0b58` `2904` not enough available track laying capacity, `0x0b59` `2905` cannot connect to existing track but too close to lay new track, and `0x0b5a` `2906` ground too steep for this building, with older fallback strings `0x00be/0x00bf` still used on neighboring exits. The helper returns a placement-success boolean and is currently grounded as the shared go-or-no-go gate immediately before direct placement commits, without yet proving that every caller is station-only. 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 + RT3.lng failure-text correlation" +0x00480210,448,placed_structure_construct_linked_site_record_from_anchor_and_coords,map,thiscall,inferred,objdump + caller inspection + constructor inspection,3,"Lower constructor beneath the linked-site allocator at `0x00481390`. The helper writes the new placed-structure id into `[this+0x00]`, stages one anchor or parent placed-structure id at `[this+0x04]`, clears the route-anchor field at `[this+0x08]`, the display-name buffer at `[this+0x46b]`, and several local list or scratch bands rooted at `[this+0x18]`, `[this+0x112]`, and `[this+0x5bd]`, then seeds local world-space state from the anchor site through `0x00455730`, `placed_structure_project_candidate_grid_extent_offset_by_rotation` `0x00417840`, and the grid helper at `0x0040cec0`. It quantizes the caller-supplied coordinate pair into `[this+0x4a8]` and `[this+0x4ac]`, initializes one grid-keyed owner lane through `0x0042bbb0`, and then chooses an initial route-entry anchor into `[this+0x08]` through `0x00417b40` when one compatible route entry already covers the projected point window. When that early anchor path does not hold, the helper falls back into the neighboring literal-policy-`1` route-entry synthesis family around `0x00493cf0`: current caller correlation says that byte is the direct linked-site endpoint-anchor creation or replacement lane, after which the helper rebinds `[this+0x08]` through `0x0048abc0` and updates the boolean marker at `[this+0x46a]`. Current direct caller is `placed_structure_collection_allocate_and_construct_linked_site_record` `0x00481390`, which makes this the clearest current lower constructor for the linked-site records later published through `[site+0x2a8]`.","objdump + caller inspection + constructor inspection + route-anchor correlation + linked-site correlation + linked-site policy-byte split 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" @@ -57,6 +76,8 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00422ee0,884,world_region_try_place_candidate_structure,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Attempts one candidate-structure placement for the current region entry and requested category. It derives one region-ranking bucket from `[region+0x256]` and `[region+0x25e]`, uses the region count at `0x0062bae0` to index the weighting table at `0x005ee1e0`, chooses one trial budget of `10` or `15` depending on the setup latch at `[0x006cec78+0x46c3c]`, and then repeatedly evaluates candidates from the global site pool `0x0062b268`. The chooser matches candidate names and scores against region subcollection entries, rejects over-cap or already-satisfied sites through the placed-instance registry `0x0062b26c`, and when successful either dispatches one direct placement through `0x004134d0` or routes the selected site into the shell-facing side path through `0x004337c0`. Current grounded callers are the region building worker at `0x004235c0` and the separate world-side branch at `0x004d1871`, so this now looks like the core candidate-placement helper beneath the region-owned building-population family.","objdump + caller xrefs + callsite inspection" 0x004235c0,1887,world_region_balance_structure_demand_and_place_candidates,map,thiscall,inferred,objdump + callsite inspection,4,"Core per-region worker beneath world_region_collection_run_building_population_pass. It first checks the broader shell-state master flag at `[0x006cec74+0x68]` and diverts into a separate alternate path when that flag is nonzero. The same flag now aligns with the editor-map `.gmp` family in the shell file coordinators, so the ordinary demand-balancing and placement flow currently looks grounded for the non-editor world mode while the alternate branch likely belongs to the editor-map side. In that ordinary path it aggregates existing category counts and weights through world_region_accumulate_structure_category_totals at `0x00422900`, samples the current region subcollection size through `0x0041f6a0`, and computes target demand for three structure categories by comparing those totals against caller-provided scale and mode inputs plus several randomized clamps. The three grounded category families are now narrower: category `0` uses the fixed fallback label `House` from `0x005c9114`; category `2` is the year-gated weighted region-profile family read through world_region_read_structure_profile_label_and_weight_by_index at `0x0041fac0` and bounded by world_region_count_structure_profiles_before_year_for_category at `0x0041f9b0`, which also feeds the localized `Industry Weightings` report in the region stats UI; and category `3` reaches world_region_pick_commercial_profile_label_by_region_rank at `0x00412ca0`, whose fallback token is `Commercial` but whose aligned region-stats label slot is localized as `City Support`. After subtracting already-placed coverage through world_region_count_placed_structures_for_category at `0x00422be0`, the worker tries placements through world_region_try_place_candidate_structure at `0x00422ee0` until demand is exhausted or the attempt budget runs out. This makes the worker a region structure-demand balancing and placement pass over houses, weighted region profiles, and the broader city-support branch rather than a generic setup loop.","objdump + callsite inspection + region stats disassembly + RT3.lng strings + rdata strings + file-flow correlation" 0x00423d70,176,company_repay_bond_slot_and_compact_debt_table,simulation,thiscall,inferred,objdump + caller inspection,4,"Repays and removes one indexed bond entry from the live company debt table. The helper validates the requested slot against the current bond count at `[this+0x5b]`, compacts the remaining 12-byte entries rooted at `[this+0x5f]`, and then recomputes the dependent finance accumulators through `0x0042a040` and `0x0042a080`. Current grounded shell caller is the repay-bond branch beneath `CompanyDetail.win`, which makes this the company-side debt-table mutator rather than a territory-access helper.","objdump + caller inspection + finance-field correlation" +0x00423ec0,33,company_adjust_available_track_laying_capacity_with_floor_zero,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,2,"Small saturating company-side counter adjuster over `[this+0x7680]`. When that field is not `-1`, the helper adds the caller-supplied delta, clamps the result at zero on underflow, and writes it back. The surrounding lifecycle is tighter now too: nearby company initialization around `0x004285c0` seeds `[this+0x7680]` to `50` when scenario byte `[0x006cec78+0x4aaf]` is enabled and to sentinel `-1` otherwise, while the companion getter `0x004240a0` returns either the live counter or fixed fallback `29999`. Current language-table correlation now gives that scenario byte a stronger player-facing read: it is the live gate behind RT3.lng `2576` `Company track laying is limited...` and event variable label `2358` `Company Track Pieces Buildable`. Current grounded caller is `route_entry_collection_create_endpoint_entry_from_coords_and_policy` `0x00493cf0`, where company-bound endpoint synthesis passes either `-1` or `-2` through this helper before the new route-entry payload is committed. That makes this the strongest current match for available track-laying capacity consumption rather than a generic finance counter.","objdump + caller xrefs + callsite inspection + route-build-capacity correlation + capacity-lifecycle correlation + RT3.lng correlation" +0x004240a0,28,company_query_available_track_laying_capacity_or_unlimited,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,2,"Returns the current company's available track-laying capacity. When scenario byte `[0x006cec78+0x4aaf]` is enabled, the helper returns the live company counter at `[this+0x7680]`; otherwise it returns fixed fallback `29999`, which currently reads as an effectively-unlimited path. Current language-table correlation now ties that scenario byte to RT3.lng `2576` `Company track laying is limited...` and event variable label `2358` `Company Track Pieces Buildable`, so this helper is best read as the live getter beneath that scenario rule rather than only as an internal company counter accessor. Current grounded callers include `placed_structure_validate_projected_candidate_placement` `0x004197e0`, `route_entry_collection_create_endpoint_entry_from_coords_and_policy` `0x00493cf0`, and `route_entry_collection_search_path_between_entry_or_coord_endpoints` `0x0049d380`, where the returned value is used as the company-side track-laying-capacity gate for route synthesis and station-attachment placement.","objdump + caller xrefs + callsite inspection + track-laying-capacity correlation + RT3.lng correlation" 0x00424010,29,company_has_territory_access_rights,simulation,thiscall,inferred,objdump + caller inspection,4,"Returns whether the current company has access rights in one requested territory id. The helper indexes the per-territory access byte at `[this + territory*0x38d + 0x1d9f]` and returns `1` when that byte is nonzero. Current grounded callers are the `CompanyDetail.win` territory-access summary helper at `0x004c1b60` and the territory-access purchase flow at `0x004c5fc9`.","objdump + caller inspection + territory-access table correlation" 0x00424030,22,company_set_territory_access_rights_byte,simulation,thiscall,inferred,objdump + caller inspection,4,"Stores one territory-access byte for the requested company and territory id. The helper writes the supplied byte value into the same per-territory access table rooted at `[this + territory*0x38d + 0x1d9f]`. Current grounded shell caller is the immediate commit path inside `shell_company_detail_buy_territory_access_rights_flow` at `0x004c5fc9`, where the purchase path writes value `1` after the access-rights dialog is accepted.","objdump + caller inspection + territory-access table correlation" 0x004241e0,23,company_sum_control_transfer_offer_policy_fields_raw,simulation,thiscall,inferred,objdump + caller inspection,4,"Returns the raw sum of two company-side floating fields at `[this+0x124f]` and `[this+0x12a7]`. Current grounded callers are the merger-offer builder around `0x004eb5a9` and adjacent control-transfer offer-side stat readers, where the returned value is paired with surrounding formatter setup for mode `0x0b` but is not itself passed an issue argument. This now looks like a narrow raw control-transfer offer policy total rather than a generic finance calculation.","objdump + caller inspection + merger-offer dialog correlation" @@ -65,6 +86,10 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 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" +0x004273c0,132,company_repurchase_public_shares_and_reduce_capital,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Repurchases one caller-supplied quantity of public shares and reduces company capital accordingly. The helper converts the share count into one cash-side total through the current public-support scalar from `company_compute_public_support_vote_scalar` `0x00424fd0` and fixed market-scale constants, posts the resulting negative amount into company stat slots `0x0c` and `0x0d` through `0x0042a080` and `0x0042a040`, and subtracts the same share count from the outstanding-share field `[this+0x47]`. Current grounded callers are the `CompanyDetail.win` stock-buyback flow at `0x004c46d0` and the annual finance-policy helper at `0x00401c50`, where it contributes the RT3.lng `2887` repurchase headline.","objdump + caller xrefs + callsite inspection + stock-buyback correlation + annual-finance correlation" +0x00427450,224,company_issue_public_shares_and_raise_capital,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Issues one caller-supplied quantity of public shares and increases company capital. When the optional pricing flag is clear, the helper derives one implied share-price scalar from `company_compute_public_support_vote_scalar` `0x00424fd0`, the current stock-valuation helper at `0x00425320`, and fixed underwriting constants; when the flag is set it reuses the caller-supplied scalar instead. It then posts the resulting proceeds into company stat slot `0x0c`, records the issued-share quantity in stat slot `0x0d`, optionally snapshots the prior year and tick into `[this+0x16b..0x177]`, and increases the outstanding-share field `[this+0x47]` by the issued quantity. Current grounded callers are the `CompanyDetail.win` stock-issue flow at `0x004c3f30` and the annual finance-policy helper at `0x00401c50`, where it contributes the debt-refinance-plus-borrowing and straight new-borrow capital side.","objdump + caller xrefs + callsite inspection + stock-issue correlation + annual-finance correlation" +0x00427540,76,company_compute_bond_interest_rate_quote,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Computes one company-specific bond interest-rate quote from the requested term and current support or credit state. When the company is active it combines the zero-argument value ladder from `0x00425320`, the current rating helper at `0x00424580`, and one term-dependent adjustment from the caller-supplied year span, then returns the resulting float rate; otherwise it falls back to `1.0`. Current grounded caller is `company_issue_bond_and_record_terms` `0x004275c0`, where this helper supplies the quoted rate when the caller does not already provide one.","objdump + caller xrefs + callsite inspection + bond-rate correlation" +0x004275c0,255,company_issue_bond_and_record_terms,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Issues one new bond and appends its term record to the live company debt table. The helper first rejects companies already at the `0x14` bond-slot cap, computes or accepts one quoted interest rate through `company_compute_bond_interest_rate_quote` `0x00427540`, posts the bond proceeds into company stat slot `0x0c`, posts the principal into stat slot `0x12`, posts the coupon rate into stat slot `0x0d`, and then writes one new three-dword bond record into the next 12-byte entry rooted at `[this+0x5f]`: principal, maturity year, and quoted rate. It increments the bond count at `[this+0x5b]` and returns success. Current grounded callers are the `CompanyDetail.win` bond-issue flow at `0x004c3890` and the annual finance-policy helper at `0x00401c50`, where it supplies both straight new borrowing and refinance-plus-borrow follow-ons.","objdump + caller xrefs + callsite inspection + bond-issue correlation + annual-finance 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" 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" @@ -128,6 +153,26 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 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" +0x004a01a0,789,route_entry_collection_try_build_path_between_optional_endpoint_entries,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Heavy route-entry collection method over the global route store at `0x006cfca8`. The helper accepts up to two optional endpoint-entry pointers or ids, two endpoint coordinate pairs, a route-policy or mode byte, and optional output slots for the chosen endpoint-entry ids. It first resolves any supplied route-entry ids through `0x00518140` and projects them back to compact coordinate pairs through `0x0048a170`, rejects early when either endpoint lands on an invalid world tile through `0x00449980`, and computes one span scalar through `0x004952f0`. When the leading endpoint entry is absent it can synthesize one fresh route entry from the supplied coordinates and policy arguments through `0x00493cf0`; after that it resolves the chosen entry, copies four `3*dword` route-shape or bounding blocks from that entry into the collection-owned builder-state area at `[this+0x139]..[this+0x167]` through `0x005394b0`, stores the chosen endpoint coordinates at `[this+0x11d]` and `[this+0x121]`, latches one active-builder flag at `[this+0x118]`, and stages one linked entry field from `[entry+0x202]` into `[this+0x125]`. On one newly synthesized-entry path and policy bytes `1/2` it also touches the auxiliary route-entry family at `0x006cfcb4` through `0x004a42b0`, `0x00494f00`, and `0x004a4340`. Current caller evidence now narrows one more policy case: both the later world-side caller at `0x00480cd0` and the linked-site refresh helper `placed_structure_refresh_linked_site_display_name_and_route_anchor` `0x00480bb0` enter this helper with both optional endpoint-entry ids unset and literal policy byte `2`, so the strongest current read for that byte is a full linked-site route-anchor rebuild between optional endpoint entries rather than the narrower direct endpoint-anchor creation or replacement lane carried by literal byte `1` in `0x00493cf0`. The helper then resets the collection's transient path-search state through `0x00495480`, re-enters the deeper route-search core at `0x0049d380`, optionally writes the chosen endpoint-entry ids back through the caller-supplied output pointers on success, and finally tears down the transient search state through `0x00495540` and `0x0049ad90`. Current grounded callers are the early route-search lane inside `city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0`, two neighboring retry branches at `0x004030d0` and `0x00403330`, a paired startup-connection branch at `0x00403ac0`, that later world-side caller at `0x00480cd0`, and the linked-site refresh helper at `0x00480bb0`. This now looks like the shared route-entry search or synthesis owner above the deeper path-search core rather than a generic route-store mutator.","objdump + caller xrefs + callsite inspection + route-entry search correlation + builder-state correlation + partial-mode-byte correlation + linked-site refresh correlation + linked-site policy-byte split correlation" +0x00489f80,11,route_entry_assign_aux_tracker_group_id,map,thiscall,inferred,objdump + caller xrefs + field-layout inspection,3,"Tiny route-entry helper that writes the caller-supplied auxiliary tracker id into route-entry field `+0x212`. Current grounded callers include the synthesis-side lane in `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0`, the route-search core `0x0049d380`, the broader regrouping pass `0x004a45f0`, and neighboring tracker-update branches at `0x004996e0`, `0x004a4380`, `0x004a4ce0`, and `0x004a4ff0`. This now looks like the direct route-entry aux-tracker group-id assignment helper rather than a generic field store.","objdump + caller xrefs + field-layout inspection + tracker-family correlation" +0x00493cf0,456,route_entry_collection_create_endpoint_entry_from_coords_and_policy,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Creates one fresh route-entry endpoint record from caller-supplied coordinates and a small policy tuple. The helper rejects when either coordinate pair falls outside the live world bounds in `0x0062c120`, optionally validates the supplied company id through `0x0062be10` and `company_query_available_track_laying_capacity_or_unlimited` `0x004240a0`, allocates a new route-entry-like record from the current collection through `0x00518900` with type `0x257`, applies one company-side setup branch through `company_adjust_available_track_laying_capacity_with_floor_zero` `0x00423ec0` when the company id is nonzero, and then commits the detailed endpoint payload through `0x00490ac0`. It can also re-enter `0x00491e60` when the created record or the owning collection keeps one follow-on latch set, and if the collection field `[this+0x88]` is still unset it seeds that field from the created record's word at `+0x240`. Current mode-byte evidence is still partial but tighter now. Literal policy byte `1` is the strongest current match for direct linked-site endpoint-anchor creation or replacement, because the linked-site constructor and its nearby repair branches at `0x00480463`, `0x00480a77`, and `0x00480b69` all pass that byte before rebinding one chosen anchor through `0x0048abc0`. The TrackLay-side callers at `0x0050df1e` and `0x0050eec6` are tighter now too: they derive the passed policy byte from the shared TrackLay mode `0x00622b0c` through `route_entry_collection_map_track_lay_mode_to_endpoint_policy_byte` `0x004955b0`, which currently gives the strongest read `policy 1 = single-track endpoint synthesis` and `policy 4 = double-track endpoint synthesis`. Bytes `1/2` are also the ones later reused by `0x004a01a0` to enable the auxiliary tracker lane, while the company-side charge split is no longer vague: when a company id is present, ordinary company-bound synthesis passes `-1` into `0x00423ec0`, while byte `4` instead passes `-2`, so the current strongest read is that policy byte `4` consumes a larger company-side available-track-laying-capacity unit rather than skipping the company setup branch outright. The older builder-state path at `0x0046f2d1` still passes a dynamic byte from `[esi+0x05]`. The function returns the newly created route-entry id or `-1` on failure. Current grounded callers include `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0`, those neighboring route-building branches, and the TrackLay-side callers at `0x0050df1e` and `0x0050eec6`, so this now looks like the shared endpoint-entry synthesis helper rather than a generic collection allocator.","objdump + caller xrefs + callsite inspection + route-entry creation correlation + partial-mode-byte correlation + caller-pattern correlation + route-build-capacity correlation + linked-site policy-byte split correlation + TrackLay mode correlation" +0x00494e40,61,aux_route_entry_tracker_reset,map,thiscall,inferred,objdump + caller xrefs + field-layout inspection,2,"Zeroes or reinitializes one small auxiliary route-entry tracker record. The helper seeds the two endpoint-entry ids at `+0x04` and `+0x08` to `-1`, clears the small refcount at `+0x10`, clears the cached route-key and class-signature words at `+0x18` and `+0x1e`, resets the boolean latch at `+0x1c` to `0`, and clears the trailing payload band through `+0x42`. Current grounded callers are the tracker allocator paths at `0x004a42b0` and several neighboring `0x006cfcb4` setup sites, so this is the clearest current initializer for the auxiliary route-entry tracker family.","objdump + caller xrefs + field-layout inspection + tracker-family correlation" +0x00494e90,15,aux_route_entry_tracker_seed_owner_entry_id,map,thiscall,inferred,objdump + caller xrefs + field-layout inspection,2,"Seeds one auxiliary route-entry tracker with its owner or primary route-entry id. The helper writes the caller-supplied id into tracker field `+0x00` and clears the small accumulator fields at `+0x42` and `+0x46`. Current grounded callers are the tracker allocator paths at `0x004a42b0`, which use it immediately after allocating one `0x006cfcb4` record keyed by a route-entry id.","objdump + caller xrefs + field-layout inspection + tracker-family correlation" +0x00494eb0,15,aux_route_entry_tracker_adjust_refcount,map,thiscall,inferred,objdump + caller xrefs + field-layout inspection,2,"Adds the caller-supplied delta into the small refcount field at tracker offset `+0x10` and returns the updated total. Current grounded callers are the collection-side tracker updater `0x004a4340`, where a zero result triggers the tracker's destruction path.","objdump + caller xrefs + field-layout inspection + tracker-family correlation" +0x00494f00,176,aux_route_entry_tracker_merge_or_bind_endpoint_entry,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Binds one route-entry id into the two-endpoint auxiliary tracker record. The helper resolves the supplied route-entry through `0x006cfca8`, derives one route-key-like value through `0x0048aa70`, reads the route-entry signature fields at `+0x22e` and byte `+0x44`, and then either seeds both endpoint slots `+0x04/+0x08` on the first bind or merges the new entry into one side when the signature, route-key, and boolean class latch match the tracker's existing state. On failure it returns `0`; on success it returns `1`. Current grounded callers are the synthesis-side lane in `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0` and several neighboring `0x006cfcb4` tracker update branches around `0x0049f1ce`, `0x0049f38d`, `0x0049f90b`, `0x004a4685`, `0x004a4830`, `0x004a4982`, `0x004a5175`, and `0x004a5189`. This now looks like the tracker-side endpoint bind or merge helper rather than a generic route-entry accessor.","objdump + caller xrefs + callsite inspection + tracker-family correlation" +0x00494fb0,97,aux_route_entry_tracker_refresh_boolean_class_latch_and_notify_owner,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Refreshes the small boolean class latch at tracker offset `+0x1c` and notifies the owning route-entry group when that latch changes. When the route-store latch `[0x006cfca8+0xf1]` is clear, the helper resolves the current endpoint-entry ids from `+0x04` and `+0x08`, recomputes whether the bound endpoint pair carries the nonzero route-entry byte `+0x44` on both sides, writes the resulting boolean back into `+0x1c`, compares it against the previous latch value, and on change calls `0x004a6360` on the auxiliary tracker collection `0x006cfcb4` with the owner entry id at `+0x00`. Current grounded callers are the neighboring route-state branch at `0x004915e0` and the compatible endpoint-slot rewrite helper `aux_route_entry_tracker_replace_matching_endpoint_entry_and_refresh_latch` `0x004950f0`. This now looks like the tracker-side boolean class-latch refresh plus owner-notify path rather than a generic predicate helper.","objdump + caller xrefs + callsite inspection + tracker-family correlation + owner-notify correlation" +0x00495020,188,aux_route_entry_tracker_refresh_cached_match_fields_and_maybe_split_duplicate_pair,map,thiscall,inferred,objdump + caller xrefs + callsite inspection + field-layout inspection,3,"Refreshes one auxiliary tracker's cached match metadata and clears its trailing relationship payload band. Under two scenario-threshold branches keyed by `[0x006cec78+0x46c34]`, the helper seeds or refreshes tracker cache fields from the currently bound endpoint pair: it derives one route-key-like value through `0x0048aa30`, reuses one endpoint signature word from route-entry field `+0x22e`, and falls back to constant `1` when no endpoint slot is available on the active branch. After that it zeroes the trailing payload band at `+0x24..+0x46`. When both endpoint slots `+0x04` and `+0x08` still point to the same route-entry id and the tracker refcount `+0x10` is greater than `1`, it tail-calls the deeper split or reseed path at `0x004a51a0` with the owner route-entry id at `+0x00`. Current grounded caller is the broader tracker-side branch at `0x004a41b0`. The current objdump shape keeps the exact `+0x18/+0x1e` destination split slightly irregular on the second threshold path, so this row stays conservative about the final field assignment while still grounding the helper as cached-match refresh plus duplicate-pair split prep.","objdump + caller xrefs + callsite inspection + field-layout inspection + tracker-family correlation" +0x004950f0,128,aux_route_entry_tracker_replace_matching_endpoint_entry_and_refresh_latch,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Rewrites one matching endpoint slot in an auxiliary tracker after compatibility checks. The helper validates the replacement route-entry id, derives its route-key-like value through `0x0048aa70`, requires that value plus the route-entry signature word `+0x22e` to match the tracker's cached comparison fields, and then only replaces endpoint slot `+0x04` or `+0x08` when the caller-supplied old endpoint id currently occupies that slot. After any replacement it re-enters `aux_route_entry_tracker_refresh_boolean_class_latch_and_notify_owner` `0x00494fb0` so the boolean class latch at `+0x1c` stays in sync. It returns `1` when a slot was replaced and `0` otherwise. Current grounded callers include the route-search core `0x0049d380`, the broader regrouping pass `0x004a45f0`, the neighboring route-state helpers at `0x00490bf0` and `0x004996e0`, and the tracker-side link-rewrite family at `0x004a4ce0`. This now looks like the compatibility-checked endpoint-slot rewrite helper beneath the auxiliary tracker family rather than a generic record mutator.","objdump + caller xrefs + callsite inspection + tracker-family correlation + endpoint-slot rewrite correlation" +0x004955b0,43,route_entry_collection_map_track_lay_mode_to_endpoint_policy_byte,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Small mapper from the live TrackLay primary mode into one of the endpoint-synthesis policy bytes consumed by `route_entry_collection_create_endpoint_entry_from_coords_and_policy` `0x00493cf0`. The helper returns `1` immediately when the caller-supplied mode dword is `1`; otherwise it inspects two route-store state fields at `[this+0x1e1]` and `[this+0x1fd]` before either keeping that same `1` fallback or returning `4`. Current grounded callers are the TrackLay-side branches at `0x0050df00` and `0x0050eea8`, where the input mode comes directly from the shared TrackLay state at `0x00622b0c` already bounded as `Lay single track.` `0x1`, `Lay double track.` `0x4`, and `Bulldoze` `0x40`. That makes the strongest current read `policy 1 = single-track endpoint synthesis` and `policy 4 = double-track endpoint synthesis`, with one route-store-state-dependent fallback still preventing a fully closed user-facing name.","objdump + caller xrefs + callsite inspection + TrackLay mode correlation + partial-policy-byte correlation" +0x004952f0,208,math_compute_quadrant_adjusted_heading_angle_from_xy_pair,map,cdecl,inferred,objdump + caller xrefs + arithmetic inspection,4,"Computes one quadrant-adjusted heading angle from two float XY point pairs. The helper handles the vertical-line degeneracy explicitly by returning `pi/2` or `3*pi/2`, otherwise computes one arctangent ratio through the CRT helper at `0x005a1270` and then adds either `pi` or `2*pi` when the caller's delta pair lands in the corresponding quadrant. The result is a normalized heading-like angle in the `0 .. 2*pi` range. Current grounded callers include the route-entry search family at `0x004a01a0`, `0x0049d380`, and `0x0049c900`, plus several neighboring route and world-side geometry branches.","objdump + caller xrefs + arithmetic inspection + constant correlation" +0x004953c0,95,math_normalize_subtracted_angle_delta_and_report_wrap,map,thiscall,inferred,objdump + caller xrefs + arithmetic inspection,4,"Subtracts one angle from another and normalizes the resulting delta back into the principal `[-pi, pi]` range. When the optional pointer in `ECX` is nonnull the helper clears it to `0`, then sets it to `1` only when the delta had to be wrapped by adding or subtracting `2*pi`. Current grounded callers include the route-entry search family at `0x0049d380` and `0x0049c900`, several route-node or waypoint geometry branches, and neighboring world-side angle tests. This now grounds `0x004953c0` as a reusable wrapped-angle-delta helper rather than another anonymous quality check.","objdump + caller xrefs + arithmetic inspection + constant correlation" +0x0049d380,1134,route_entry_collection_search_path_between_entry_or_coord_endpoints,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Heavy internal route-search core beneath the route-entry synthesis family. The helper accepts a leading route-entry id, one company id, two endpoint coordinate pairs, a route-policy tuple, one optional external target entry id, and several scratch or output buffers. It begins by validating the company id through `0x0062be10` and `company_query_available_track_laying_capacity_or_unlimited` `0x004240a0` when present, then packages the current search context into the collection-owned builder state, including one current-search latch at `[this+0x1d5]` and one distance-like scalar at `[this+0x1d1]`. From there it runs three bounded internal stages. First, it enters the deeper candidate path sweep at `0x0049bd40`; this can return a direct matching route-entry id or leave the search unresolved. Second, when that first stage does not settle the search, it rehydrates the returned route entry through `0x0048a170`, evaluates point-to-point distance, span, and angle-like quality terms through `math_measure_float_xy_pair_distance` `0x0051db80`, `0x004952f0`, `0x004953c0`, and `0x005a152e`, and only accepts the result when those quality gates pass. Third, when the quality gates or initial sweep fail, it can fall back to route-entry extension helpers `0x00494cb0` and `0x0049c900`, plus route-state propagation through `0x0048e600`, while rewriting several collection-side path blocks rooted at `[this+0x169]`, `[this+0x175]`, `[this+0x181]`, `[this+0x18d]`, `[this+0x199]`, `[this+0x1a5]`, `[this+0x1b1]`, and `[this+0x1bd]`. The function returns one resolved route-entry id or `-1`, and current direct callers are only internal route-entry family wrappers at `0x004a0470`, `0x004a0870`, `0x004a0b2a`, and `0x004a0cef`. In current evidence this is the search core that the higher wrapper `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0` hands off to after endpoint reuse or synthesis, rather than a user-facing route mutator by itself.","objdump + caller xrefs + callsite inspection + path-search correlation + builder-state correlation + distance-helper correlation + track-laying-capacity correlation" +0x0049bd40,982,route_entry_collection_run_initial_candidate_path_sweep,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Runs the first candidate route sweep beneath `route_entry_collection_search_path_between_entry_or_coord_endpoints` `0x0049d380`. The helper clears any prior temporary path list through `0x0049ad90`, seeds two caller-owned status dwords, resolves the starting route-entry id through the collection, rejects one trivial or degenerate local-delta case, and then seeds an initial extension attempt through `0x00494cb0`. From there it builds one temporary candidate chain in `[this+0x1cd]`, derives route quality terms from point-to-point distance through `math_measure_float_xy_pair_distance` `0x0051db80`, re-enters the route-node search against the auxiliary tracker collection `0x006cfcb4` through `0x004a6630`, and on a passing result publishes one follow-on route-entry id through the caller-supplied output slot. Current evidence now narrows the internal quality policy too: when the route-state gate at `[this+0xe9]` stays clear the helper selects a larger quality multiplier of `1.8` on route-policy byte `4` or field `[0x006cec78+0x4c74]`, and otherwise uses `1.4`; the same branch also folds in one signed angle-bias term `+/-0.181000038854627` before the later acceptance checks. That field is still the same player-facing TrackLay preference slot grounded elsewhere as `Auto-Show Grade During Track Lay`, but on this route-search lane it now reads more concretely as a temporary search-quality override: the shared city-connection builder `0x00402cb0` and the broader company periodic pass `0x004019e0` both mirror electric-locomotive context into it specifically to force this same larger initial-sweep multiplier branch. Current grounded direct caller is the search core `0x0049d380`, where this helper is the first stage before the later quality-gate and extension fallbacks. This now looks like the initial candidate path sweep rather than a generic collection iterator.","objdump + caller xrefs + callsite inspection + candidate-sweep correlation + tracker-family correlation + quality-threshold constant correlation + distance-helper correlation + temporary-override correlation" +0x0049c900,829,route_entry_collection_try_extend_search_frontier_toward_target_coords,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Tries to extend the current route-search frontier toward one target coordinate pair. The helper starts from two endpoint coordinate pairs plus one caller-owned result slot, initializes that result slot to `-1`, computes span and angle-like quality terms through `0x004952f0`, `0x005a152e`, and the same constant families used by the search core, and then repeatedly advances the search sample window until one candidate route extension passes the quality thresholds. Current evidence now narrows those thresholds too: this helper reuses the same signed angle-bias family `+/-0.181000038854627` seen in the initial candidate sweep before deciding whether to probe a covering entry. On successful passes it re-enters `route_entry_collection_try_find_route_entry_covering_point_window` `0x00494cb0`, verifies the returned entry through `0x0048ba40`, `0x004953c0`, and neighboring state bytes, and publishes the accepted route-entry id through the caller-owned result pointer. On failure it leaves that pointer at `-1`. Current grounded direct callers are the search core `0x0049d380` and the neighboring route wrapper at `0x004a0740`, which together make this the clearest current extension or frontier-advance helper beneath the route-entry search family rather than a free-standing world query.","objdump + caller xrefs + callsite inspection + frontier-extension correlation + quality-threshold constant correlation" +0x00494cb0,398,route_entry_collection_try_find_route_entry_covering_point_window,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Searches the current route-entry collection for one entry whose sampled span covers the caller's point window. The helper rejects immediately when the supplied window radius is nonpositive, quantizes the caller's center coordinates into world-grid bounds, iterates the resulting rectangular tile window inside `0x0062c120`, and repeatedly re-enters `0x004921a0` on each candidate tile or route bucket until it finds one acceptable route-entry id. Current grounded callers include the station-attachment validation lane at `0x00403d30`, the placement validator at `0x00417ba1` and `0x0041a2c9`, the world-side route mutation lane at `0x00480d88`, the initial candidate sweep `0x0049bd40`, the search core `0x0049d724`, and several neighboring route-search branches. This now looks like the shared route-entry point-window coverage query beneath both placement-side track attachment and the heavier route-entry search family rather than a generic tile scan.","objdump + caller xrefs + callsite inspection + world-grid correlation + route-window correlation" +0x004a42b0,79,aux_route_entry_tracker_collection_allocate_entry,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Allocates one new tracker record in the auxiliary route-entry collection at `0x006cfcb4` and seeds it for one owner route-entry id. The helper resets a small local tracker template through `aux_route_entry_tracker_reset` `0x00494e40`, allocates one live record from the collection through `0x00518900`, resolves that record, seeds its owner entry id through `aux_route_entry_tracker_seed_owner_entry_id` `0x00494e90`, and returns the new tracker id. Current grounded callers include `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0` and several neighboring route-state branches at `0x0049e174`, `0x0049e3d8`, `0x0049e427`, `0x0049e45c`, `0x0049f1b0`, `0x0049f3b5`, `0x0049f91a`, `0x004a466d`, `0x004a4814`, `0x004a4966`, and `0x004a5054`, so this is now the clearest current allocator for the auxiliary route-entry tracker family.","objdump + caller xrefs + callsite inspection + tracker-family correlation" +0x004a4340,55,aux_route_entry_tracker_collection_adjust_refcount_or_destroy,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Looks up one tracker record in the auxiliary route-entry collection at `0x006cfcb4`, adjusts its small refcount through `aux_route_entry_tracker_adjust_refcount` `0x00494eb0`, and destroys the record through the collection vtable when the resulting count reaches zero. Current grounded callers include the synthesis-side lane in `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0` and several neighboring route-state branches at `0x00490da5`, `0x0049a9b8`, `0x0049abca`, `0x0049f178`, `0x0049f1a2`, `0x0049f1e0`, `0x0049f37e`, `0x0049f3a7`, `0x004a4f9c`, `0x004a4fb0`, and `0x004a5161`. This now looks like the shared refcount or destroy path for the auxiliary route-entry tracker family rather than another anonymous collection helper.","objdump + caller xrefs + callsite inspection + tracker-family correlation" +0x004a45f0,1420,aux_route_entry_tracker_collection_refresh_route_entry_group_membership,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Heavy regrouping pass over the auxiliary route-entry tracker collection at `0x006cfcb4`. The helper starts from one route-entry record, rejects the trivial case where both adjacent route-entry fields `[entry+0x206]` and `[entry+0x20a]` are unset, optionally runs one broader prepass at `0x004a4380` keyed by the route entry's current tracker id in `[entry+0x212]`, and then refreshes ownership around that id. On the simpler branch it can allocate one fresh tracker through `aux_route_entry_tracker_collection_allocate_entry` `0x004a42b0`, bind one or more route-entry ids into it through `aux_route_entry_tracker_merge_or_bind_endpoint_entry` `0x00494f00`, assign the resulting tracker id back into route-entry field `+0x212` through `route_entry_assign_aux_tracker_group_id` `0x00489f80`, and rebalance tracker refcounts through `aux_route_entry_tracker_adjust_refcount` `0x00494eb0`. The current endpoint-bind semantics are tighter now too: the bind helper groups entries only when their route-key-like value from `0x0048aa70`, route-entry signature word `+0x22e`, and boolean class latch derived from byte `+0x44` all agree. On the larger branch this pass walks adjacent route-entry links through the `+0x206/+0x20a/+0x20e` family, can allocate or reuse additional trackers, uses `aux_route_entry_tracker_replace_matching_endpoint_entry_and_refresh_latch` `0x004950f0` to rewrite compatible endpoint slots between old and new groups, and can re-enter the nearby cached-match refresh path `0x00495020` before dropping empty tracker records through the collection vtable. Current grounded caller is `placed_structure_refresh_linked_site_display_name_and_route_anchor` `0x00480bb0`, where this pass runs immediately after literal-policy-`2` route-anchor rebuild and bind. This now looks like the auxiliary tracker regrouping pass beneath the broader linked-site route-anchor rebuild lane rather than a generic collection sweep.","objdump + caller xrefs + callsite inspection + tracker-family correlation + linked-site refresh correlation + endpoint-match-tuple correlation" 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" @@ -230,6 +275,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004d4130,32,map_editor_event_validation_panel_construct,map,thiscall,inferred,objdump + RT3.lng strings + UI callback inspection,4,"Constructs the shell-side event-validation page in the map-editor control panel. The helper binds the report callback `0x004d3d90`, which checks for missing status or win-lose events and other per-event errors before formatting the result list.","objdump + RT3.lng strings + UI callback inspection + page-constructor correlation" 0x00456920,3247,unit_visual_init_weapon_airframe_and_exhaust_effects,bootstrap,thiscall,inferred,ghidra-headless,4,Initializes one armed-unit visual bundle spanning turret and cannon hardware exhaust emitters and aircraft airframe attachments. The routine creates static Turret Mantlet Cannon and MuzzleFlash assets at [this+0x31a] through [this+0x326] direct JetExhaust and PropExhaust sprite emitters at [this+0x2f6] and [this+0x2fa] a cannon-audio attachment at [this+0x32a] indexed WingL and WingR assets plus plane-audio state at [this+0x32e] through [this+0x346] and cached Aileron Elevator Rudder and Thrust vectors at [this+0x2d1] [this+0x2c5] [this+0x2b9] and [this+0x2dd].,ghidra + rizin + llvm-objdump + strings 0x00461650,120,map_load_geographic_label_database,map,cdecl,inferred,ghidra-headless,3,Loads the geographic-label database branch inside the broader reference-bundle setup. It stages resource ids 0x5209 through 0x520b binds the selected bundle through 0x517d90 iterates the loaded collection with 0x517cf0 0x518380 and 0x518140 and dispatches each record through vtable slot +0x44 using the current map path context.,ghidra + rizin + llvm-objdump + strings +0x00461cd0,298,locomotive_collection_select_best_era_matched_non_electric_fallback_id,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection + engine-type correlation,2,"Fallback locomotive chooser beneath `company_select_preferred_available_locomotive_id` `0x004078a0`. The helper walks the live locomotive collection, explicitly skips records whose engine-type dword `[record+0x10]` is `2`, and then scores the remaining records from the linked era record at `[record+0x72]`: the current grounded score uses the absolute distance from the current scenario year to the era start field `[era+0x105]`, adds `500` when the era has not started yet, adds `50` when the current year has passed the era-end field `[era+0x109]`, and adds `2000` when the linked approval helper `0x0041d550` rejects the era or engine family for the current context. The lowest-penalty locomotive id wins, so the current best read is an era-matched non-electric fallback rather than a general preferred-locomotive chooser. Current grounded caller is `company_select_preferred_available_locomotive_id` `0x004078a0`.","objdump + caller xrefs + callsite inspection + engine-type correlation + fallback-choice correlation" 0x00464410,12679,shell_dispatch_ui_command,shell,cdecl,inferred,ghidra-headless,4,Large shell UI command dispatcher reached from shell-side event callbacks and direct command pushes. It switches over many command ids including 0x7530 through 0x7532 graphics-preset commands that route into 0x0051ebc0 0x00484590 and 0x004853c0; 0x7533 through 0x7534 TigerTank viewer actions; and 0x7540 through 0x7543 scenario-text report build and batch-processing commands that route into 0x00489830 0x004886e0 and 0x00489a20.,ghidra + rizin + llvm-objdump + strings 0x00474610,120,map_load_city_database,map,cdecl,inferred,ghidra-headless,3,Loads the city database branch in the same pattern as the geographic-label loader. It stages resource ids 0x61a9 through 0x61ab binds the selected bundle through 0x517d90 iterates the collection with 0x517cf0 0x518380 and 0x518140 and dispatches each record through vtable slot +0x44.,ghidra + rizin + llvm-objdump + strings 0x00474e20,336,effect_slot_create_attached_sprite_emitter,bootstrap,thiscall,inferred,ghidra-headless,3,Creates or clones one attached sprite emitter for an effect slot on the owning object. Depending on flag bit 0x400 it either clones through 0x00556ce0 or allocates a fresh 0x1fd template through 0x00556920 then attaches the emitter to the owner at [emitter+0x60] and optionally sets persistent flag [emitter+0xbc].,ghidra + rizin + llvm-objdump @@ -439,6 +485,20 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00502220,813,paint_terrain_load_selected_gmt_surface,shell,cdecl,inferred,ghidra-headless,4,Loads or refreshes the currently selected .gmt-backed preview surface for the PaintTerrain tool family rooted at 0x006d14bc and tied to the PaintTerrain.win or GroundTerrain.tga branch. The routine validates the selected filename suffix copies selected strings into the active record updates tool status bytes and counters formats several shell text fields through 0x00540120 and finishes by decoding a 256x256 image through 0x0053f830 and surface_init_rgba_pixel_buffer.,ghidra + rizin + llvm-objdump + strings 0x00502550,456,paint_terrain_refresh_status_panel,shell,cdecl,inferred,ghidra-headless,3,Refreshes the PaintTerrain tool status or selection panel after the active .gmt surface changes. The helper reads the PaintTerrain singleton at 0x006d14bc consults shell selection globals and lookup tables formats several text or numeric fields through 0x00540120 and toggles the side flag at 0x006d14a8 before returning.,ghidra + rizin + llvm-objdump + strings 0x00502720,144,paint_terrain_tool_init_globals,shell,thiscall,inferred,ghidra-headless,4,Initializes the PaintTerrain shell tool singleton rooted at 0x006d14bc. The constructor seeds the tool vtable and default fields registers the active instance globally and is selected directly from shell_transition_mode alongside the neighboring terrain-edit tool constructor at 0x004ee3a0.,ghidra + rizin + llvm-objdump + strings +0x0047d810,182,placed_structure_remove_route_entry_key_and_compact,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Removes one matching `u16` route-entry key from the six-byte route-entry list rooted at `[this+0x462]/[this+0x466]`. The helper scans the current list, copies surviving six-byte entries into a newly allocated compacted buffer, frees the old buffer, stores the replacement pointer back into `[this+0x466]`, and decrements the route-entry count at `[this+0x462]`. Current grounded caller is the linked-site refresh or teardown branch at `0x0040e102`, so this now looks like the keyed remove-and-compact companion to the linked site's route-entry list rather than another generic free helper.","objdump + caller xrefs + callsite inspection + route-entry-list compaction correlation" +0x0047d8e0,346,placed_structure_load_dynamic_side_buffers_from_stream,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Deserializes the variable-size side buffers on one placed-structure record from the caller-supplied persistence stream. The helper reads tagged blocks through `0x00531360` and `0x00531150`, repopulates the six-byte route-entry list at `[this+0x462]/[this+0x466]`, the three five-byte-per-site arrays rooted at `[this+0x24]` from count `[this+0x30]`, the five eight-byte proximity-bucket arrays counted at `[this+0x590..0x5a0]` and rooted at `[this+0x5a4..0x5b4]`, and the trailing twelve-byte scratch band at `[this+0x34]/[this+0x38]`, then clears `[this+0x5bd]` and re-enters `0x00407780`. Current direct caller is the collection-level load pass at `0x00481464`. The real body begins at `0x0047d8e0` even though current recovered calls target the preceding padding slot `0x0047d8d0`.","objdump + caller xrefs + callsite inspection + stream-layout correlation" +0x0047dcd0,64,placed_structure_clear_proximity_bucket_lists,map,thiscall,inferred,objdump + caller xrefs + data-layout inspection,3,"Clears the five proximity-bucket arrays rooted at `[this+0x5a4..0x5b4]`, zeroes the corresponding per-bucket counts at `[this+0x590..0x5a0]`, and resets the total proximity-entry count at `[this+0x5b8]`. Current grounded callers are the linked-site teardown pass at `0x00480590` and the sibling route-anchor refresh family at `0x00480719`, so this now reads as the common clear step for the nearby-site bucket family rather than a generic free helper.","objdump + caller xrefs + data-layout inspection + proximity-bucket correlation" +0x0047dd10,130,placed_structure_remove_site_id_from_proximity_bucket_lists,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Removes one matching site id from every proximity bucket rooted at `[this+0x590..0x5b8]`. The helper scans all five bucket arrays, matches the supplied site id against the first dword of each eight-byte entry, compacts the surviving tail when needed, decrements the per-bucket count, and decrements the total count at `[this+0x5b8]`. Current direct caller is the collection sweep at `0x004814e9`, which makes this the remove-one-site companion to the nearby-site bucket append path rather than a broader route helper.","objdump + caller xrefs + callsite inspection + proximity-bucket correlation" +0x0047fdb0,317,placed_structure_append_nearby_transit_site_distance_bucket_entry,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Appends one nearby station-or-transit site into the current record's five proximity buckets. The helper first requires the caller-supplied peer record to pass `0x0047fd50`, then measures the current-to-peer distance through `0x00455800`, `0x00455810`, and `math_measure_float_xy_pair_distance` `0x0051db80`, rejects peers outside the fixed distance threshold at `0x005c8738`, classifies the surviving peer through `0x0040d350`, and finally appends one `(peer site id, distance)` pair into the corresponding eight-byte bucket array at `[this+bucket*4+0x5a4]` while incrementing both the per-bucket count and total count `[this+0x5b8]`. Current direct caller is the collection sweep at `0x004814a9`.","objdump + caller xrefs + callsite inspection + distance-threshold correlation + proximity-bucket correlation" +0x004801a0,105,placed_structure_is_linked_transit_site_reachable_from_company_route_anchor,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Boolean gate between one linked transit site and one company-side route anchor. The helper first requires the current placed structure to pass the station-or-transit gate `0x0047fd50`, then requires its linked-instance class test through `0x0040c990 == 1`. It resolves the caller-supplied company id through the live company collection `0x0062be10`, asks that company for one cached route-anchor entry id through `company_query_cached_linked_transit_route_anchor_entry_id` `0x00401860`, resolves the site's own route-entry anchor through collection `0x006cfca8`, and finally re-enters `0x0048e3c0` to test whether the two route-entry anchors lie in the same reachable route-side family. Current grounded caller is `company_rebuild_linked_transit_site_peer_cache` `0x004093d0`, where this helper gates whether a foreign linked transit site can still participate in the current company's peer cache.","objdump + caller xrefs + callsite inspection + linked-transit reachability correlation" +0x00480590,371,placed_structure_teardown_linked_site_runtime_state_before_removal,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Tears down the mutable runtime side of one linked placed-structure record before collection removal. The helper clears the route-style scratch lane through `0x004077e0`, clears the proximity buckets through `placed_structure_clear_proximity_bucket_lists` `0x0047dcd0`, frees the trailing scratch buffer at `[this+0x34]`, clears the route-link list through `0x0047f320`, detaches or invalidates the current route-entry anchor at `[this+0x08]` through the route-entry collection `0x006cfca8`, recomputes the current grid-keyed owner lane through `0x0042bbf0`, frees the three per-site byte arrays at `[this+0x24..0x2c]`, clears this record's indexed byte in the corresponding arrays of every later placed-structure record in `0x006cec20`, and finally re-enters the scenario-side follow-on at `0x00436040` with the current site id. Current direct caller is `placed_structure_collection_remove_linked_site_record` `0x004813d0`, so this now looks like the linked-site teardown pass rather than another route-anchor refresh helper.","objdump + caller xrefs + callsite inspection + linked-site teardown correlation" +0x00480bb0,1535,placed_structure_refresh_linked_site_display_name_and_route_anchor,map,thiscall,inferred,objdump + caller xrefs + callsite inspection + RT3.lng strings,3,"Single-site post-create or post-edit refresh helper reached from `placed_structure_finalize_creation_or_rebuild_local_runtime_state` `0x0040ef10` when the current placed structure keeps one linked site id at `[this+0x2a8]`. The helper operates on that linked placed-structure record, optionally rebuilds one route-entry anchor at `[this+0x08]` through `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0` with both optional endpoint-entry ids unset and literal policy byte `2`, then binds the chosen route entry back to the site through `0x0048abc0` and re-enters `aux_route_entry_tracker_collection_refresh_route_entry_group_membership` `0x004a45f0` so the auxiliary tracker family at `0x006cfcb4` can regroup around the refreshed anchor. Current caller correlation makes that byte the strongest current match for the broader linked-site route-anchor rebuild lane, as opposed to the narrower direct endpoint-anchor creation or replacement lane that neighboring repair branches drive through literal byte `1` into `0x00493cf0`. It also rebuilds the display-name buffer at `[this+0x46b]`: when the current site coordinates resolve a city or region entry through `0x0044a830` it copies that entry name from `[entry+0x356]`, optionally appends one civic suffix from RT3.lng ids `585..588` `Township`, `New`, `Modern`, and `Renaissance`, and on special linked-instance class branches appends `589` `Service Tower` or `590` `Maintenance Facility` with per-city counters instead. When no city entry resolves it falls back to `591` `Anytown`. The ordinary non-special branch also rotates through RT3.lng ids `578..584` `Junction`, `Crossing`, `Depot`, `Corners`, `Exchange`, `Point`, and `Center` via the static table at `0x005f2cf8`. After trimming trailing spaces it conditionally re-enters `placed_structure_route_link_collection_recompute_all_endpoint_pair_state` `0x004682c0` when the narrower station-or-transit gate `0x0047fd50` passes, clears or seeds adjacent city-side cached state through `0x004358d0` and `0x00420650`, and returns. Current direct caller is `0x0040f626`, so this now looks like the linked-site display-name and route-anchor refresh beneath placed-structure finalization rather than another city-connection owner.","objdump + caller xrefs + callsite inspection + RT3.lng strings + route-anchor correlation + linked-site refresh correlation + linked-site policy-byte split correlation + tracker-regrouping correlation" +0x00481390,55,placed_structure_collection_allocate_and_construct_linked_site_record,map,thiscall,inferred,objdump + caller xrefs + constructor inspection,3,"Small allocator wrapper over the live placed-structure collection at `0x006cec20`. The helper allocates one fresh collection entry id through `0x00518900`, resolves the new record through `0x00518140`, and then hands the new id plus the caller-supplied anchor site id and coordinate pair into `placed_structure_construct_linked_site_record_from_anchor_and_coords` `0x00480210`. Current direct caller is `placed_structure_construct_entry_from_candidate_and_world_args` `0x0040f6d0`, where the returned id is published into `[site+0x2a8]` when the backing candidate subtype byte `[candidate+0x32]` is `1`. This now looks like the allocator wrapper for the linked-site records used by the later policy-`1` and policy-`2` route-anchor refresh families rather than another anonymous collection helper.","objdump + caller xrefs + constructor inspection + linked-site correlation" +0x004813d0,91,placed_structure_collection_remove_linked_site_record,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Removes one linked-site record from the live placed-structure collection. The helper resolves the supplied site id through `0x006cec20`, derives one station-or-transit or linked-instance-class latch through `0x0047de00 -> 0x0040c990`, runs `placed_structure_teardown_linked_site_runtime_state_before_removal` `0x00480590`, and then removes the collection entry through `0x00518a30`. When scenario field `[0x006cec78+0x4c93]` is clear and the removed record passed the narrower latch, it also re-enters the company-wide follow-on at `0x00429c10`. Current direct caller is the subtype-`1` destruction path around `0x0040f626`.","objdump + caller xrefs + callsite inspection + linked-site removal correlation" +0x00481430,72,placed_structure_collection_load_dynamic_side_buffers_from_stream,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Collection-level load pass for the variable-size side buffers on placed-structure records. When the shell or world-side stream slot at `[0x006cec74+0x1c7]` is present, the helper walks the live placed-structure collection at `0x006cec20`, resolves each record by id, and re-enters `placed_structure_load_dynamic_side_buffers_from_stream` `0x0047d8e0` on it. Current direct caller is the wider post-load world-side refresh path at `0x00433b93`.","objdump + caller xrefs + callsite inspection + stream-load correlation" +0x00481480,64,placed_structure_collection_append_site_into_all_proximity_bucket_lists,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Walks the live placed-structure collection at `0x006cec20` and asks every record to consider one caller-supplied peer site for proximity-bucket insertion. The helper resolves each live record and re-enters `placed_structure_append_nearby_transit_site_distance_bucket_entry` `0x0047fdb0` with the supplied peer placed-structure pointer. Current direct callers are the subtype-`4` update paths at `0x0040ec73` and `0x0040fa11`, so this now reads as the add-peer sweep for the nearby-site bucket family rather than another generic collection iterator.","objdump + caller xrefs + callsite inspection + proximity-bucket correlation" +0x004814c0,64,placed_structure_collection_remove_site_id_from_all_proximity_bucket_lists,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Walks the live placed-structure collection at `0x006cec20` and asks every record to remove one caller-supplied site id from its proximity buckets. The helper resolves each live record and re-enters `placed_structure_remove_site_id_from_proximity_bucket_lists` `0x0047dd10` with the supplied site id. Current direct callers are the subtype-`4` pre-update or pre-destroy paths at `0x0040e0a2` and `0x0040ebc7`.","objdump + caller xrefs + callsite inspection + proximity-bucket correlation" +0x00429c10,88,company_collection_refresh_active_company_linked_transit_site_peer_caches,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Collection-wide company sweep above the linked-transit peer cache family. The helper first counts the active companies in the live company collection at `0x0062be10` by testing `[company+0x3f]`, then walks that active ordinal range through `company_collection_get_nth_active_company_id` `0x00429a90` and re-enters `company_rebuild_linked_transit_site_peer_cache` `0x004093d0` on each resolved company record. Current grounded callers are the linked-site removal follow-on at `0x00481421` and the wider world-side company refresh branch at `0x00444c9c`.","objdump + caller xrefs + callsite inspection + active-company sweep correlation" 0x00481d00,612,bootstrap_parse_command_line_flags,bootstrap,cdecl,inferred,ghidra-headless,4,Parses the startup command line from ECX handling slash and dash switches and writes multiple bootstrap globals and option buffers before shell service init.,ghidra + rizin 0x00481fd0,348,bootstrap_scan_autorun_media,bootstrap,cdecl,inferred,ghidra-headless,4,Scans drive letters for RT3 autorun marker files rt3d1.txt and rt3d2.txt using GetDriveTypeA and open or close helpers before deeper shell init.,ghidra + rizin 0x00482160,101,shell_state_service_active_mode_frame,shell,thiscall,inferred,objdump + analysis-context,4,Acts as the broader shell-state service pass around one active-mode update on the shell state rooted at 0x006cec74. The helper increments nested-service depth at [this+0x64] optionally notifies the active mode object at 0x006cec78 through 0x0051f940 and 0x00434050 primes the shell runtime at 0x006d401c through 0x00538b60 conditionally services the Multiplayer preview-dataset object at 0x006cd8d8 through 0x00469720 and then dispatches shell_service_frame_cycle on the global shell controller at 0x006d4024 before decrementing the depth counter.,objdump + analysis-context + caller xrefs @@ -557,6 +617,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x005521e0,894,world_anchor_project_screen_extent_pair,shell,cdecl,inferred,ghidra-headless,3,Projects one world-anchor object into a paired screen-space extent result. The helper samples the shell zoom table under 0x006d4024 computes integer-scaled axis spans from the anchor geometry converts them through multiple clamp or reciprocal stages and writes two output integers through the caller pointers before later marker builders use the results for anchor presentation sizing.,ghidra + rizin + llvm-objdump 0x00552560,916,shell_queue_world_anchor_marker,shell,cdecl,inferred,ghidra-headless,3,Builds one world-anchor marker packet from the caller point object and optional scale or style inputs. It samples anchor extents from the object fields converts them through 0x0053dde0 0x0053ddf0 and world_anchor_project_screen_extent_pair consults the shell zoom table rooted at [0x006d4024+0x11421e] and [0x006d4024+0x34] and finally enqueues one type-0x01 deferred message through shell_enqueue_deferred_message_type1. mouse_cursor_update_frame_state uses it for one branch of cursor world-relative presentation.,ghidra + rizin + llvm-objdump 0x00552900,1304,shell_queue_projected_world_anchor_quad,shell,cdecl,inferred,ghidra-headless,3,Builds one oriented projected quad around the caller world-anchor object. It derives four projected corner points from the anchor extents and orientation computes edge and diagonal lengths through 0x0051db80 samples the shared presentation phase through shell_step_global_presentation_phase_scalar refines screen-space bounds through world_anchor_project_screen_extent_pair and finally emits two type-0x04 deferred-message posts through shell_enqueue_deferred_message_type4.,ghidra + rizin + llvm-objdump +0x0051db80,32,math_measure_float_xy_pair_distance,support,cdecl,inferred,objdump + caller xrefs + callsite inspection,4,"Tiny shared float distance helper. It subtracts one caller-supplied X or Y point pair from the other, squares both deltas, sums them, and returns the Euclidean distance `sqrt(dx*dx + dy*dy)`. Current grounded callers include the city-connection chooser at `0x00402cb0`, the route-entry search family at `0x0049bd40` and `0x0049d380`, several company and world-side scoring branches, and shell presentation helpers such as `shell_queue_projected_world_anchor_quad` `0x00552900`. This now grounds `0x0051db80` as a generic float XY distance primitive rather than another opaque quality helper.","objdump + caller xrefs + callsite inspection + arithmetic inspection" 0x00554d70,248,billboard_item_build_anchor_point_cache,bootstrap,thiscall,inferred,ghidra-headless,3,Builds or refreshes the cached point list for one billboard item at [this+0x1dd]. When source points exist at [this+0x10] it transforms them through the owner object matrix near [this+0x0c]+0xce; otherwise it seeds a one-point fallback from the baked vector at [this+0xfe..0x106].,ghidra + rizin + llvm-objdump 0x00554e70,680,shell_emit_ranked_sprite_billboard_item,bootstrap,thiscall,inferred,ghidra-headless,4,Emits one ranked sprite-billboard item into the current vertex24 span. The helper computes a distance-weighted fade against shell and world state stores the derived scalar at [item+0xdc] and then walks either the item's linked child list at [item+0x4] or the cached anchor list at [item+0x1dd] to write textured quad geometry through 0x005662a0.,ghidra + rizin + llvm-objdump 0x00555740,49,billboard_item_refresh_child_sprite_colors,bootstrap,thiscall,inferred,ghidra-headless,3,Refreshes packed child-sprite colors for one billboard item by iterating the linked child list at [this+0x4] recomputing each child color through 0x005554f0 and storing the 24-bit result at [child+0x70].,ghidra + rizin + llvm-objdump @@ -587,6 +648,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0058d830,40,multiplayer_transport_disconnect,shell,thiscall,inferred,ghidra-headless,3,Disconnects the session-event transport object from its current live route. The helper flips the internal active state through 0x005965d0 and 0x005961b0 calls the shared teardown block at 0x0058d810 and finally clears byte [this+0x60] and the copied local name at [this+0xaf4].,ghidra + rizin + llvm-objdump 0x0058d860,59,multiplayer_transport_release_worker_and_reset_runtime_state,shell,cdecl,inferred,rizin,3,Small runtime-reset wrapper for the outer session-event transport object. When the owned worker pointer at [this] is present it first tears that worker down through multiplayer_transport_worker_shutdown_gracefully then clears the worker pointer the configured flag byte at [this+0x04] the text-stream owner slots at [this+0x44] and [this+0x48] reruns 0x00593370 and the shared reset block at 0x0058d810 and finally clears the live route and deferred-runtime fields at [this+0x180c] [this+0x1810] and [this+0x1edc].,rizin + llvm-objdump 0x0058d8d0,143,multiplayer_transport_service_frame,shell,cdecl,inferred,objdump + caller xrefs,3,"Recurring service pump for the outer session-event transport object. When the transport is configured through `[this+0x44]` or `[this+0x48]` it first services one worker step through multiplayer_transport_service_worker_once on the owned worker at `[this]`; if deferred reset is armed at `[this+0x1edc]` and the outstanding-work count has reached zero it falls straight into the common reset path at `0x0058de50`. Otherwise it conditionally emits the keepalive text at `0x005e1c24` after roughly `0x493e0` ms of inactivity, services the deeper selector or route helpers through `0x00596210` and `0x00597380`, finalizes deferred reset when the work count at `[this+0x1808]` reaches zero, and finishes by forwarding the caller selector through `0x00592800`. Current grounded callers reach it through multiplayer_transport_flush_and_maybe_shutdown and the immediate-drain submission paths, which places it at the center of the shell-owned multiplayer transport cadence.","objdump + caller xrefs + strings" +0x005a152e,176,math_abs_double_with_crt_special_case_handling,support,cdecl,inferred,objdump + arithmetic inspection + caller xrefs,4,"Returns the absolute value of one caller-supplied `double`. On ordinary finite inputs the helper simply clears the sign bit of the high dword before returning; on NaN or infinity it re-enters the surrounding CRT status machinery before returning either the preserved or sign-flipped value. Current grounded callers include the route-entry search family at `0x0049d380` and `0x0049c900`, where it is used as the absolute-value side of the span and angle quality gates.","objdump + arithmetic inspection + caller xrefs + CRT special-case correlation" 0x0058c340,144,multiplayer_gamespy_decode_triplet_control_payload,shell,cdecl,inferred,objdump,3,"Decodes one length-coded three-part GameSpy control payload and re-emits it through the shared packet-field builder at `0x58c0c0`. The helper reads up to three bounded variable-length slices from the caller payload, then packages them as field classes `0`, `1`, and `2`. The current grounded caller is subtype `0` of multiplayer_gamespy_route_dispatch_inbound_packet's `0xfe 0xfd` switch.",objdump 0x0058c5c0,60,multiplayer_gamespy_build_backslash_query_response,shell,cdecl,inferred,objdump + strings,3,"Builds one backslash-delimited GameSpy query reply into the caller buffer. It seeds the leading `\\`, emits three callback-driven field groups through `0x58c3e0` for selectors `0`, `1`, and `2`, appends the fixed terminator token at `0x005e1b6c`, and leaves the result ready for immediate send. The current grounded caller is the backslash-packet branch inside multiplayer_gamespy_route_dispatch_inbound_packet.",objdump + strings 0x0058c600,142,multiplayer_gamespy_dispatch_natneg_or_raw_callback,shell,cdecl,inferred,objdump + strings,3,"Dispatches one validated extended GameSpy payload into route-owner callbacks. When the payload begins with the six-byte magic `fd fc 1e 66 6a b2` it treats bytes `[payload+6..+9]` as a little-endian value, materializes a small wrapper object through `0x5b31f8`, and forwards it through the route callback at `[route+0xa0]`; otherwise it falls back to the raw payload callback at `[route+0xa4]`. Both slots are optional: the helper tests them for null and returns without dispatch when the selected callback is absent. The current grounded caller is subtype `6` of multiplayer_gamespy_route_dispatch_inbound_packet.",objdump + strings diff --git a/docs/control-loop-atlas.md b/docs/control-loop-atlas.md index b591fd4..afa3a96 100644 --- a/docs/control-loop-atlas.md +++ b/docs/control-loop-atlas.md @@ -638,7 +638,11 @@ anchor it, and where control is handed to neighboring subsystems. 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 + `track_lay_window_handle_message`. The same family also owns the downstream route-entry policy + bridge at `0x004955b0`: current caller evidence says that helper maps the live TrackLay primary + mode into endpoint-synthesis policy `1` or `4` before the tool re-enters `0x00493cf0`, which is + the strongest current bridge from the player-facing single-track versus double-track buttons into + the lower route-builder policy bytes. 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 @@ -921,12 +925,248 @@ anchor it, and where control is handed to neighboring subsystems. `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`, + an early route-entry search or synthesis attempt through + `route_entry_collection_try_build_path_between_optional_endpoint_entries` `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`. + That early lane can now be described more concretely: it can reuse supplied route-entry + endpoints, synthesize a missing leading endpoint from the caller's coordinates, seed the + route-store builder-state block, and then hand off to the deeper path-search core without + placing a new site. The previously vague side family at `0x006cfcb4` is tighter too: current + evidence now bounds it as a small auxiliary route-entry tracker collection with an allocator at + `0x004a42b0`, a refcount or destroy path at `0x004a4340`, a direct route-entry group-id setter + at `0x00489f80`, a boolean-latch refresh or owner-notify path at `0x00494fb0`, and a + two-endpoint merge or bind helper at `0x00494f00`. That bind side is tighter now too: the + trackers group route entries only when a route-key-like value from `0x0048aa70`, the route-entry + signature word `+0x22e`, and the boolean latch derived from byte `+0x44` all agree. The deeper + handoff under that lane is no longer anonymous either: + `route_entry_collection_search_path_between_entry_or_coord_endpoints` `0x0049d380` is now + bounded as the internal search core that runs the first candidate sweep, quality gates, and the + later route-extension fallbacks before returning one resolved route-entry id or `-1`. The first + sweep now has a bounded owner at `0x0049bd40`, and the two later fallback helpers are bounded as + the route-entry point-window coverage query `0x00494cb0` and the frontier-extension helper + `0x0049c900`. The math side is bounded more cleanly now too: the family reuses + `math_measure_float_xy_pair_distance` `0x0051db80` for its direct point-to-point scalar, + `math_compute_quadrant_adjusted_heading_angle_from_xy_pair` `0x004952f0` for heading-angle + construction, `math_normalize_subtracted_angle_delta_and_report_wrap` `0x004953c0` for wrapped + angle-delta checks, and `math_abs_double_with_crt_special_case_handling` `0x005a152e` for the + absolute-value side of the quality gates. Current evidence also bounds the threshold shape a + little more tightly: the initial sweep and later extension path both reuse one signed angle-bias + term `+/-0.181000038854627`, and the first sweep switches between a looser `1.4` and stricter + `1.8` quality multiplier depending on route-policy byte `4` or the broader display-runtime + preference `[0x006cec78+0x4c74]`, already grounded elsewhere as `Auto-Show Grade During Track + Lay`. + The small policy-byte semantics are still not fully closed, but current evidence is tighter than + before. Literal byte `1` is now the strongest current match for direct linked-site + endpoint-anchor creation or replacement, because the linked-site constructor and neighboring + repair branches around `0x00480463`, `0x00480a77`, and `0x00480b69` all feed that byte into + `0x00493cf0` before rebinding one chosen route-entry anchor through `0x0048abc0`. Literal byte + `2` now looks broader: the later world-side caller at `0x00480cd0` and the linked-site refresh + helper `placed_structure_refresh_linked_site_display_name_and_route_anchor` `0x00480bb0` both + reach `0x004a01a0` with both optional endpoint-entry ids unset and that byte, so the strongest + current read is a full linked-site route-anchor rebuild between optional endpoint entries rather + than the narrower direct creation lane. The TrackLay side now gives one tighter user-facing + anchor too: the live mode field `0x00622b0c` is already grounded as `Lay single track.` `0x1` + versus `Lay double track.` `0x4`, and the small mapper `0x004955b0` collapses that state into + the endpoint-policy bytes later passed to `0x00493cf0`, so the strongest current read is + `policy 1 = single-track endpoint synthesis` and `policy 4 = double-track endpoint synthesis`. + Bytes `1/2` are still the ones that enable the + auxiliary tracker lane in `0x004a01a0`, while byte `4` now reads more narrowly as the larger + company-side endpoint-synthesis charge inside `0x00493cf0`, because that helper feeds `-1` + versus `-2` into the saturating company counter helper `0x00423ec0` on `[company+0x7680]` + rather than skipping the company branch entirely. That counter is tighter now too: nearby + company initialization seeds it to `50` when scenario byte `0x4aaf` is enabled and to sentinel + `-1` otherwise, while the companion getter `0x004240a0` returns either the live counter or fixed + fallback `29999`. Current language-table correlation also gives `0x4aaf` a stronger + player-facing meaning: it is the live gate behind `Company track laying is limited...` and the + event variable label `Company Track Pieces Buildable`. So the current strongest read is + available track-laying capacity, not an abstract company route-budget. That site-side helper + also closes one adjacent ownership gap: beneath + `placed_structure_finalize_creation_or_rebuild_local_runtime_state` `0x0040ef10`, it rebuilds + one linked site's route-entry anchor and display-name buffer. That path is tighter now than just + “bind anchor then touch `0x006cfcb4`”: after the literal-policy-`2` rebuild succeeds it + re-enters `aux_route_entry_tracker_collection_refresh_route_entry_group_membership` `0x004a45f0`, + which can repartition adjacent route-entry tracker groups around the refreshed anchor, rewrite + compatible endpoint slots through `0x004950f0`, and refresh one nearby cached-match payload band + through `0x00495020` before the helper resumes the name-buffer work. The remaining display-name + side still matches the earlier + grounded text family: copy the resolved city name when available, append civic suffixes + `Township`, `New`, `Modern`, or `Renaissance`, append `Service Tower` or `Maintenance Facility` + on the linked-instance class branches, and otherwise fall back through the older + `Junction`..`Center` and `Anytown` text families. + The sibling policy-`1` side is tighter now too. The constructor lane no longer stops at “one + linked site id at `[site+0x2a8]`”: the subtype-`1` branch in + `placed_structure_construct_entry_from_candidate_and_world_args` `0x0040f6d0` now clearly + allocates that linked record through + `placed_structure_collection_allocate_and_construct_linked_site_record` `0x00481390`, whose lower + constructor is `placed_structure_construct_linked_site_record_from_anchor_and_coords` + `0x00480210`. That lower constructor seeds the linked record's own id and anchor-site id, clears + the local route-anchor and display-name fields, projects the anchor footprint into world space, + and then either binds an already-covered route entry through `0x00417b40` or falls through into + the neighboring policy-`1` route-entry synthesis family around `0x00493cf0` before rebinding the + chosen route entry through `0x0048abc0`. + The cleanup side is tighter now too. Linked-site removal now has a bounded owner at + `placed_structure_collection_remove_linked_site_record` `0x004813d0`: it resolves the linked + record through `0x006cec20`, runs the per-record teardown + `placed_structure_teardown_linked_site_runtime_state_before_removal` `0x00480590`, removes the + live entry from the collection, and only then re-enters the still-bounded company-wide follow-on + at `0x00429c10` when the removed record passed the narrower transit-like latch. That per-record + teardown is no longer just “clear some scratch fields.” It now clearly clears the route-style + scratch lane, clears the five proximity buckets at `[site+0x590..0x5b8]`, detaches or invalidates + the current route-entry anchor, frees the three per-site byte arrays at `[site+0x24..0x2c]`, + clears this site's indexed byte from the corresponding arrays of later placed-structure records, + and then re-enters `0x00436040` with the current site id. + That company-side follow-on is no longer just one opaque callback either. It is now bounded as + `company_collection_refresh_active_company_linked_transit_site_peer_caches` `0x00429c10`, which + walks the active company roster and re-enters + `company_rebuild_linked_transit_site_peer_cache` `0x004093d0` on each company. That per-company + fast pass stamps a refresh tick at `[company+0x0d3e]`, clears and repopulates the + placed-structure-side cache cells addressed through `[site+0x5bd][company_id]`, marks the + eligible linked transit sites for that company, allocates one `0x0d`-stride peer table for each + eligible site, and fills those peer rows from the route-side sweep through `0x004a6630`. The + adjacent timed wrapper `company_service_linked_transit_site_caches` `0x00409720` now shows the + cadence too: `0x004093d0` is the shorter-interval refresh, while the older heavier sibling at + `0x00407bd0` was only revisited on the longer interval. + That heavier sibling is now bounded too: + `company_rebuild_linked_transit_autoroute_site_score_cache` `0x00407bd0` no longer looks like a + generic tail refresh. It reuses the fast peer tables, rolls candidate-local service metrics and + peer-route deltas back into three per-site cache floats at `+0x0e`, `+0x12`, and `+0x16`, and + then feeds the neighboring selectors + `company_select_best_owned_linked_transit_site_by_autoroute_score` `0x00408280` and + `company_build_linked_transit_autoroute_entry` `0x00408380`. That makes the company-side follow-on + read more like a linked-transit autoroute cache family than a generic company maintenance pass. + The neighboring reachability gate is tighter now too: + `company_query_cached_linked_transit_route_anchor_entry_id` `0x00401860` caches one company-side + route-entry anchor, and + `placed_structure_is_linked_transit_site_reachable_from_company_route_anchor` `0x004801a0` + uses that anchor to decide whether a foreign linked transit site can still participate in the + current company's fast peer cache. + The first direct train-side consumer above that cache family is bounded now too: + `train_try_append_linked_transit_autoroute_entry` `0x00409770`. After servicing the owning + company's caches, it asks `0x00408380` for one staged `0x33`-byte route entry using the train's + current anchor site, then either appends that entry through `0x004b3160` and refreshes the new + trailing selection through `0x004b2f00`, or rotates one existing slot in place when the local + two-entry cap has already been reached. So this edge now reaches an actual train-side autoroute + append lane rather than stopping at anonymous company-side cache cells. + The train-side follow-on above that seed path is bounded now too. The owning company can count + its live roster through `company_count_owned_trains` `0x004264c0`, measure one aggregate linked + transit site pressure through `company_compute_owned_linked_transit_site_score_total` + `0x00408f70`, and then rebalance that roster through + `company_balance_linked_transit_train_roster` `0x00409950`. Current grounded evidence says that + pass prunes or upgrades older company-owned trains, then fills any remaining deficit by either + packaging multiplayer opcode `0x75` or locally re-entering + `company_try_add_linked_transit_train_and_publish_news` `0x00409830`. The two visible news + helpers under it are bounded too: `0x00409830` emits RT3.lng `2896` for a newly added train, + while `company_publish_train_upgrade_news` `0x00409300` emits RT3.lng `2897` for the upgrade + branch. + The subtype-`4` sibling side is bounded now too. The nearby-site bucket family now has: + `placed_structure_append_nearby_transit_site_distance_bucket_entry` `0x0047fdb0`, + `placed_structure_remove_site_id_from_proximity_bucket_lists` `0x0047dd10`, and + `placed_structure_clear_proximity_bucket_lists` `0x0047dcd0`, plus the two collection sweeps + `placed_structure_collection_append_site_into_all_proximity_bucket_lists` `0x00481480` and + `placed_structure_collection_remove_site_id_from_all_proximity_bucket_lists` `0x004814c0`. + Current evidence says those five buckets store `(peer site id, distance)` pairs for nearby + station-or-transit peers, grouped through the five-way classifier at `0x0040d350`. The older + stream-backed side is bounded too: `placed_structure_collection_load_dynamic_side_buffers_from_stream` + `0x00481430` walks the live placed-structure collection and re-enters + `placed_structure_load_dynamic_side_buffers_from_stream` `0x0047d8e0`, which repopulates the + route-entry list, the three per-site byte arrays, the five proximity buckets, and the trailing + scratch band from the caller-supplied persistence stream. + The linked-site route-entry list itself is tighter now too. The refresh or teardown branch at + `0x0040e102` re-enters `placed_structure_remove_route_entry_key_and_compact` `0x0047d810`, which + removes one matching `u16` key from the six-byte list rooted at `[site+0x462]/[site+0x466]`, + compacts the surviving entries into a replacement buffer, and decrements the stored route-entry + count. + The broader company-side owner above these pieces is tighter now too. The periodic service pass + `company_service_periodic_city_connection_finance_and_linked_transit_lanes` `0x004019e0` now + reads as the current outer owner for this branch: it sequences the city-connection announcement + lanes, the linked-transit train-roster balancer, the acquisition-side sibling + `company_try_buy_unowned_industry_near_city_and_publish_news` `0x004014b0`, the annual finance-policy helper + `company_evaluate_annual_finance_policy_and_publish_news` `0x00401c50`, and the shorter-versus- + longer linked-transit cache refresh tail through `0x004093d0` and `0x00407bd0`. That outer pass + also has one tighter temporary-state role now: it clears company bytes `0x0d17/0x0d18/0x0d56`, + mirrors `0x0d17` into scenario field `0x006cec78+0x4c74` only while the earlier route-building + side runs, and restores the original scenario value on exit. Current evidence now ties `0x0d17` + to the shared preferred-locomotive chooser `0x004078a0`: the override is only armed when that + helper picks one locomotive whose engine-type dword is `2`. That engine-type lane now best reads + as electric rather than an unnamed class slot, because the linked approval helper around + `0x0041d550` now reads as a real locomotive-era and engine-type policy gate, dispatching the same + `0/1/2` field across three scenario-opinion lanes while the local player-facing engine-type + family is explicitly `Steam / Diesel / Electric`. That same gate also now ties the later scenario + bytes `0x4c97..0x4c99` back to the editor-side `Locomotives` page rather than treating them as + anonymous availability flags: they are the live `All Steam Locos Avail.`, `All Diesel Locos + Avail.`, and `All Electric Locos Avail.` policy bytes behind `0x004cd680` / `0x004cf0d0`. The + current logic is also tighter than a plain override tier: a positive engine-family opinion result + can carry the gate by itself only while none of those three editor bytes is enabled; once any of + them is nonzero, `0x0041d550` instead requires one matching intersection between the record-local + family bytes and the enabled editor family bytes. The `WhaleL` carveout is narrower now too: + current data-file correlation ties that stem to the `Orca NX462` / `WhaleL_NE` locomotive family, + and it explicitly zeros that positive-opinion result before the later family-availability checks, + so it loses the shortcut rather than gaining a special approval path. The same + chooser now also has a bounded fallback below it, `locomotive_collection_select_best_era_matched_non_electric_fallback_id` + `0x00461cd0`, which explicitly skips engine-type `2` and chooses the lowest-penalty remaining + locomotive by era mismatch and approval gates. The route-search side is tighter too: this + electric-only override now clearly feeds the first path-sweep branch in `0x0049bd40`, forcing the + larger `1.8` initial quality multiplier instead of `1.4`, which is the same branch otherwise + chosen by explicit route-policy byte `4`. So the later annual finance helper is reading + same-cycle side-channel state from the earlier city-connection and linked-transit branches, not + unrelated long-lived finance fields. The inner + finance helper is not debt-only either. Current grounded outcomes include bankruptcy news + `2881`, the debt restructure family `2882..2886`, a later share-repurchase headline `2887`, and + the dividend-side adjustment branch. The main commit verbs under that helper are now grounded too: + `company_repay_bond_slot_and_compact_debt_table` `0x00423d70`, + `company_issue_bond_and_record_terms` `0x004275c0`, + `company_repurchase_public_shares_and_reduce_capital` `0x004273c0`, and + `company_issue_public_shares_and_raise_capital` `0x00427450`. The threshold side is tighter now + too. The earliest creditor-pressure lane requires scenario mode `0x0c`, the bankruptcy toggle + `[0x006cec78+0x4a8f]` to be clear, at least `13` years since `[company+0x163]`, and at least + `4` years since founding year `[company+0x157]`; it then scans the last three years of slots + `0x2b` and `0x2c`, chooses one negative pressure ladder `-600000 / -1100000 / -1600000 / + -2000000` from the current slot-`0x2c` bands around `120000 / 230000 / 340000`, requires public + support at least `15` or `20` depending on whether all three sampled years failed, checks slot + `0x09` against `0.08` times that ladder, and requires the three-year slot-`0x2b` total to clear + one final `-60000` gate before it falls into the bankruptcy commit and RT3.lng `2881` headline. + The middle debt-capital layer is split more clearly now too. With `[+0x4a8b]` clear, one annual + bond lane first simulates full repayment through `company_repay_bond_slot_and_compact_debt_table` + and then uses the post-repayment cash window with fixed `-250000` and `-30000` thresholds plus + the broader linked-transit train-service latch `[company+0x0d56]` to decide whether to append one + or more `500000` principal, `30`-year bonds. The repurchase lane is separate again: when the + city-connection announcement-side latch `[company+0x0d18]` is set, growth setting `2` does not + suppress it, and `[+0x4a87]` is clear, it starts from one `1000`-share batch, can replace its + default `1.0` factor with one linked-chairman personality scalar, scales that by `1.6` when + growth setting `1` is active, and then runs one `800000` stock-value gate plus one + support-times-factor-times-`1000`-times-`1.2` affordability gate before the repeated `1000`-share + buyback commits behind RT3.lng `2887`. The ordering above this helper is tighter now too: + `company_service_periodic_city_connection_finance_and_linked_transit_lanes` clears those latches + first, runs the city-connection and linked-transit branches, and only then enters the annual + finance helper, so these look like same-cycle reaction gates rather than long-lived balance-sheet + flags. + After the earlier debt or bankruptcy outcomes stay inactive, the later stock-capital lane also + has a bounded first threshold layer: with the bond and stock toggles `[+0x4a8b]` and `[+0x4a87]` + clear, at least two bond slots live, and at least one year since founding, it derives one + 1000-share batch with floor `2000`, requires public support at least `22`, requires the support + times batch product to clear `55000`, and then uses a piecewise approval ladder + `0.07/1.3 -> 0.14/0.35` before the share-issue path proceeds. + The dividend side is bounded too: it requires the dividend toggle `[0x006cec78+0x4a93]` to be + clear, mode `0x0c`, at least `1` year since `[company+0x0d2d]`, and at least `2` years since + founding, then averages the last three years of slot `0x2b`, folds in the unassigned-share pool + and the current `0x0d` band, applies the map-editor building-growth setting `[0x006cec78+0x4c7c]`, + treats growth setting `1` as a `0.66` scale-down and setting `2` as a zeroing pass on the current + dividend, quantizes surviving adjustments in tenths, and finally clamps against + `company_compute_board_approved_dividend_rate_ceiling` `0x00426260`. + The linked-transit route-seeding side has one tighter sibling now too: + `company_reset_linked_transit_caches_and_reseed_empty_train_routes` `0x00401940`. It clears the + two company-side linked-transit cache timestamps, forces one immediate cache rebuild through + `0x00409720`, strips route lists from company-owned trains in modes `0x0a/0x13`, and then + re-enters `train_try_append_linked_transit_autoroute_entry` `0x00409770` only when a train's + route list has become empty. + On the wider chooser question, the current evidence is also tighter than before: every recovered + external owner of `0x00402cb0` is still in the city-connection family, so the two later direct + placement lanes currently read as city-connection fallback behavior rather than a broadly shared + world placement service. 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 @@ -935,7 +1175,12 @@ anchor it, and where control is handed to neighboring subsystems. 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. + before either direct-placement commit is allowed to fire. Its strongest current subtype branch is + a station-attachment or upgrade-style lane keyed by `[candidate+0x32] == 1`, which now has the + concrete failure family `2901..2906`: blocked upgrade footprint, ground not flat enough, not + your track, insufficient track-laying capacity, cannot connect to existing track, and ground too + steep. That tightens the chooser materially without yet proving that the validator is + station-only for every caller. 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