85 KiB
Control-Loop Atlas
This atlas is the high-level map for RT3 1.06. It is intentionally broader than the function map: each section explains who owns a loop, where it starts, what dispatches it, which state blocks anchor it, and where control is handed to neighboring subsystems.
CRT and Process Startup
- Roots:
entryat0x005a313b, CRT helpers in the0x005a2d..0x005ad4..range, andapp_bootstrap_mainat0x00484440. - Trigger/Cadence: single process startup path before shell or engine services exist.
- Key Dispatchers:
startup_init_tls_state,startup_init_file_handle_table,startup_run_init_callback_table,__setenvp,startup_build_argv,___crtGetEnvironmentStringsA, thenapp_bootstrap_main. - State Anchors: CRT heap and file-handle tables; process environment and argv storage.
- Subsystem Handoffs: exits the generic CRT path at
app_bootstrap_main, which becomes the first RT3-owned coordinator. - Evidence:
artifacts/exports/rt3-1.06/startup-call-chain.md,artifacts/exports/rt3-1.06/function-map.csv. - Open Questions: exact ownership boundary between compiler CRT shims and the first game-owned bootstrap helper; whether any nontrivial startup callbacks seed game globals before
app_bootstrap_main.
Bootstrap and Shell Service Bring-Up
- Roots:
app_bootstrap_mainat0x00484440,bootstrap_init_shell_window_servicesat0x004840e0, andshell_install_global_controllerat0x0051ff90. - Trigger/Cadence: one-time bootstrap handoff immediately after CRT completion.
- Key Dispatchers:
app_bootstrap_main,bootstrap_init_shell_window_services,shell_install_global_controller,shell_service_pump_iteration, graphics config load or default-init helpers, runtime capability probes, and early shell service initializers under the0x004610..0x0053f0..branch. - State Anchors: global shell controller pointer
0x006d4024, sibling display/runtime globals under0x006d402cand0x006d4030, and host capability flags gathered bybootstrap_probe_system_profile. - Subsystem Handoffs: after the global shell controller has been installed the bootstrap path enters the repeating
shell_service_pump_iterationloop, which services shell-state work and hands each iteration down into the controller frame path; when the shell lifetime ends this same bootstrap path tears the shell bundle down and returns toapp_bootstrap_main. - Evidence:
startup-call-chain.md, function-map rows forapp_bootstrap_main,bootstrap_init_shell_window_services,shell_install_global_controller,shell_service_pump_iteration,shell_load_graphics_config_or_init_defaults,shell_reset_display_runtime_defaults, and related graphics setup helpers. - Open Questions: whether gameplay or in-engine world stepping later escapes this bootstrap-owned shell loop entirely, or whether gameplay entry still rendezvous with the same outer coordinator before the shell bundle is destroyed.
Shell UI Command and Deferred Work Flow
- Roots: shell callback paths that converge on
shell_dispatch_ui_commandat0x00464410. - Trigger/Cadence: event-driven UI command dispatch plus deferred-message queue flushing during shell activity.
- Key Dispatchers:
shell_dispatch_ui_command,shell_enqueue_deferred_work_message,shell_post_deferred_message_type5,shell_post_deferred_message_type6,shell_enqueue_deferred_message_type4,shell_enqueue_deferred_message_type1. - State Anchors: shell object at
0x0062be68, queue roots around[this+0x11369d],[this+0x1136a1], and[this+0x1136a5], global routing gates at0x006d4034, and the separate detail-panel controller rooted at0x006d0818. - Subsystem Handoffs: routes into graphics config, scenario-text export, overlay generation, multiplayer UI, shell detail windows such as
EditorPanel.winandTrainDetail.win, and presentation-facing deferred work later drained byshell_service_frame_cycle. - Evidence: function-map shell rows around
0x00464410,0x004d4500,0x004ddbd0, and0x0051f1d0..0x0051f460. - Open Questions: whether the shell command dispatcher is also used by hotkeys or only by UI callback tables; the current
0x006d0818detail-panel path looks shell-only and does not yet explain gameplay world entry.
Presentation, Overlay, and Frame Timing
- Roots: the bootstrap-owned
shell_service_pump_iterationat0x00483f70, the shell-state service passshell_state_service_active_mode_frameat0x00482160, the installed global shell controller at0x006d4024, the pending frame-cycle ownershell_service_frame_cycleat0x00520620, and the frame-time history path undershell_update_frame_time_historyat0x0051fd70. - Trigger/Cadence: recurring bootstrap-owned shell service work once the active mode, controller window, and display runtime are live; special modal or content-building paths can also force immediate frame servicing inside that broader cadence.
- Key Dispatchers:
shell_service_pump_iteration,shell_state_service_active_mode_frame,shell_service_frame_cycle,shell_refresh_presentation_frame,shell_update_frame_time_history,shell_get_smoothed_frame_scalar,shell_set_gamma_ramp_scalar, and overlay builders such asshell_queue_single_world_anchor_overlay,shell_queue_world_anchor_overlay_list, andshell_queue_indexed_world_anchor_marker. - State Anchors: shell state at
0x006cec74, active mode pointer0x006cec78, shell frame history ring at0x006d403c, display/runtime state inside the controller block near[this+0x114282]and[this+0x11428a], presentation service pointer at[this+0x0c], and the native controller window handle at[this+0x00]. - Subsystem Handoffs: the bootstrap-owned pump runs shell-bundle polling and shell-state maintenance before the shell-state pass synchronizes active-mode helpers and modal-status work and dispatches the controller frame cycle, which then consumes world/object state for overlays and presentation refresh, uses the controller window handle for one-time
ShowWindowand related UI interaction, and drains the deferred work queues at the end of the cycle. - Evidence: function-map rows for
shell_service_pump_iteration,shell_state_service_active_mode_frame,shell_service_frame_cycle,shell_flush_deferred_work_queues, frame history, gamma ramp, world-anchor overlay builders, and graphics runtime helpers. - Open Questions: how simulation cadence rendezvous with the shell presentation cadence once gameplay takes over and whether gameplay stepping exits this shell-owned controller path entirely.
Map and Scenario Content Load
- Roots:
shell_map_file_entry_coordinatorat0x00445ac0, the first grounded world-entry branchworld_entry_transition_and_runtime_bringupat0x00443a50,shell_map_file_world_bundle_coordinatorat0x00445de0, reference-database setup viamap_bundle_open_reference_databasesat0x00444dd0, and narrower loaders such asmap_load_geographic_label_databaseandmap_load_city_database. - Trigger/Cadence: shell tutorial launch, editor or detail-panel file actions through
fileopt.win, map-scenario open paths, and scenario-text export batch commands. - Key Dispatchers:
shell_map_file_entry_coordinator,world_entry_transition_and_runtime_bringup,world_runtime_release_global_services,shell_map_file_world_bundle_coordinator,map_bundle_open_reference_databases,map_load_geographic_label_database,map_load_city_database,scenario_text_export_build_language_file,scenario_text_export_report_language_file,scenario_text_export_batch_process_maps. - State Anchors: shell-side file staging buffers at
0x0062bee0and0x0062bec4, shell and mode globals at0x006cec74and0x006cec78, world object root0x0062c120, map bundle state allocated through0x00530c80, and geography tables rooted at0x0062b2fcand0x0062b268. - Subsystem Handoffs: the shared
fileopt.windialog rooted at0x004dc670now looks like the shell-side selector above the two broad file coordinators. Its message handler sets0x006d07f8for the load or restore side or0x006d07ecfor the save or package side before the detail-panel transition manager routes intoshell_map_file_entry_coordinatororshell_map_file_world_bundle_coordinator. The former unresolved third flag at0x006d07f0is now accounted for too: it escapes into the standaloneSettingsWindow.winpath throughshell_open_settings_windowrather than another map or save verb. The broad coordinators now hand their interactive work through the sharedfilerqst.winhelper at0x004dd010, and that helper gives the extension split a firmer shape. The paired editor-map path is now grounded as.gmpthrough load mode4and save mode3. The remaining non-editor families are no longer anonymous either:.gmcis the campaign-scenario branch, backed both by the campaign-screen resignation prompt on0x006cec7c+0xc5and by the numbered%s%02d.gmcsave helper at0x00517c70;.gmxis the sandbox branch, backed by the shell-sideThe briefing is not available in sandbox games.restriction on0x006cec7c+0x82; and the default.gmsbranch is therefore the standalone scenario family. When a live runtime world is already active the same helper bypasses those non-runtime extensions and forces the.smpruntime-state branch instead. The auxiliary save-side mode11is tighter now too: it still maps to.gmt, but instead of looking like another gameplay save family it conditionally diverts into the same.gmtpreview-surface pipeline owned by the Multiplayer preview dataset object at0x006cd8d8, and only falls back to the normal reference-bundle path when that dataset object is absent. - Evidence: function-map map/scenario rows, analysis-context exports for
0x00445ac0,0x00445de0,0x00443a50,0x00434300, and0x00444dd0, plus objdump string and mode-table evidence for.gmp,.gmx,.gmc,.gms,.gmt,.smp,Quicksave, the0x004dd010mode table at0x005f3d58, the auxiliary-owner presence check at0x00434050, and the.gmthandoff through0x00469d30, together with localized string evidence from ids3018and3898. - Open Questions: bit
0x1on both broad coordinators now grounds the Quicksave name seed and the former thirdfileopt.winflag has been ruled out as a file-flow question because it just opensSettingsWindow.win. The old broad extension question is mostly resolved:.gmpis the editor-map pair,.gmsis the standalone scenario family,.gmcis the campaign-scenario family,.gmxis the sandbox family, and.gmtis at least bounded as an auxiliary preview-surface branch rather than another gameplay save family. The higher-value global question is no longer whether0x00443a50is world entry. It is where the long-lived simulation cadence takes over after this bring-up and whether that cadence still rendezvous with the shell-owned frame path or escapes into a separate gameplay loop.
Multiplayer Session and Transport Flow
- Roots:
multiplayer_window_init_globalsat0x004efe80,multiplayer_window_service_loopat0x004f03f0, the Multiplayer.win session-event callback table built bymultiplayer_register_session_event_callbacksat0x0046a900, the active session-event transport object at0x006cd970, the Multiplayer preview dataset object at0x006cd8d8, and the lower pending-template and text-stream helpers around0x00597880..0x0059caf0. - Trigger/Cadence: shell-owned Multiplayer.win frame service plus event-driven session callbacks and repeated transport pump steps.
- Key Dispatchers: session-event wrappers for actions
1,2,4,7,8;multiplayer_register_session_event_callbacks;multiplayer_dispatch_requested_action;multiplayer_reset_preview_dataset_and_request_action;multiplayer_preview_dataset_service_frame;multiplayer_load_selected_map_preview_surface;multiplayer_flush_session_event_transport;multiplayer_transport_service_frame;multiplayer_transport_service_worker_once;multiplayer_transport_service_route_callback_tables;multiplayer_transport_service_status_and_live_routes;multiplayer_transport_text_stream_service_io;multiplayer_transport_dispatch_pending_template_node;multiplayer_transport_service_pending_template_dispatch_store. - State Anchors: live session globals at
0x006d40d0, active session-event transport object at0x006cd970, status latch at0x006cd974, session-event mode latch at0x006cd978, retry counter at0x006cd984, preview dataset object at0x006cd8d8, preview-valid flag at0x006ce9bc, staged preview strings at0x006ce670and[0x006cd8d8+0x8f48], Multiplayer.win backing block at0x006d1270, selector-view store root at[transport+0xab4], selector-view generation counters at[transport+0xab8]..[transport+0xac0], selector-view backing arrays around[transport+0xad0]..[transport+0xae4], selector-view entry probe-request id at[entry+0x50], live-state gate at[entry+0x58], third-slot flag word at[entry+0x64], probe-schedule tick at[entry+0x68], last-success tick at[entry+0x6c], pending-probe latch at[entry+0x74], success generation at[entry+0x78], consecutive-failure counter at[entry+0x7c], rolling average at[entry+0x80], recent sample window at[entry+0x84..], bounded sample-count at[entry+0x94], total-success count at[entry+0x98], pending-template list at[transport+0x550], dispatch store at[worker+0x54c], and text-stream buffers rooted under[worker+0x1c]. - Subsystem Handoffs: the Multiplayer.win initializer seeds the backing block at
0x006d1270, later reset paths construct the separate preview dataset at0x006cd8d8, and the shell-owned active-mode frame services that dataset every frame throughmultiplayer_preview_dataset_service_frame. That preview side publishes roster and status controls through the Multiplayer window control paths, loads.gmtpreview surfaces throughmultiplayer_load_selected_map_preview_surface, and is even reused by the map/save coordinator’s mode-11.gmtpath when the dataset already exists. In parallel,multiplayer_register_session_event_callbacksallocates and registers the separate session-event transport object at0x006cd970. The shell-side bridge into that deeper transport cadence is now tighter:multiplayer_window_service_loopand neighboring reset or initializer branches callmultiplayer_flush_session_event_transport, which forces one status flush and then drops intomultiplayer_transport_flush_and_maybe_shutdown. That wrapper in turn runsmultiplayer_transport_service_frame, the recurring pump that services one worker step throughmultiplayer_transport_service_worker_once, sweeps the transport-owned callback tables and field caches throughmultiplayer_transport_service_route_callback_tables, services both the auxiliary status route and the current live route throughmultiplayer_transport_service_status_and_live_routes, and then descends one layer farther into the shared GameSpy route helpermultiplayer_gamespy_route_service_frameat0x58d040. The transport also owns a separate selector-view sidecar beneath that route cadence.multiplayer_transport_ensure_selector_view_storeallocates the keyed selector-view store at[transport+0xab4],multiplayer_transport_find_selector_view_entry_by_nameresolves entries from that store,multiplayer_transport_upsert_selector_name_entrymarks per-slot activity and flags inside each entry, andmultiplayer_transport_mark_selector_slot_views_dirtyplusmultiplayer_transport_reset_selector_view_entry_runtime_statemanage the dirty or refresh fields at+0xa0,+0xa4, and+0xa8. That selector-view maintenance path is now split more cleanly too. The recurring owner ismultiplayer_transport_service_selector_view_refresh_cycle, which first runs the fast deferred-probe lane:multiplayer_transport_collect_refreshable_selector_view_entrieswalks the store throughmultiplayer_transport_filter_insert_refreshable_selector_view_entry, which now shows that[entry+0x64]is not a generic flag bucket but the third selector-slot flag word, parallel to[entry+0x5c]and[entry+0x60]. In that collector, thegandamode-letter bits produced bymultiplayer_transport_parse_selector_mode_lettersbecome mask0x0cin the slot-local flag words, and any third-slot entry carrying those bits at[entry+0x64]is excluded from the refreshable set. Eligible entries then pass slot-aware retry timing on[entry+0x68],[entry+0x6c],[entry+0x78], and[entry+0x7c], after which the service loop schedules refresh probes throughmultiplayer_transport_schedule_selector_view_entry_refresh_probe. That fast lane is narrower now too: the entry-side match key[entry+0x50]is no longer just an opaque request field. The profile-key callback lanes feedmultiplayer_transport_parse_selector_view_probe_marker, which decodes one localX%sX|%dmarker into a request id plus companion value, andmultiplayer_transport_arm_selector_view_probe_trackingstores those into[entry+0x50]and[entry+0x54]before arming the live probe gate at[entry+0x58]. The current-selector callback root at0x59f8b0is now bounded as well: it resolves and upserts the active selector name, optionally reuses a cachedusernamemarker to arm probe tracking immediately, then submits the same profile-key bundle with selector context and forwards that selector through callback slot17, with the status-route side able to force route-mode transitions2 -> 3 -> 4afterward. One layer lower,multiplayer_transport_handle_profile_key_query_resultat0x596970now bounds the per-key result path itself. It treatsusernameas the probe-marker field,b_flagsas the selector mode-letter field, and(END)as a real sentinel that publishes a zeroed slot-22payload instead of a marker pair. The same helper also hashes the selector-name, key-name, and resolved value text back into the caller table, so the profile-key bundle now looks like a real bounded handoff rather than an anonymous callback cloud. The deferred callback shimmultiplayer_transport_dispatch_selector_view_refresh_probe_resultthen walks the keyed store throughmultiplayer_transport_finish_selector_view_refresh_probe_if_matching, which only completes entries whose pending latch[entry+0x74]is still armed and whose parsed marker request id[entry+0x50]matches the finished request. A failed result-1clears the pending latch and increments the consecutive-failure counter at[entry+0x7c]. A nonfailure result clears the pending latch, increments the success generation at[entry+0x78]and total-success count[entry+0x98], clears[entry+0x7c], stamps the last-success tick at[entry+0x6c], appends the returned sample into the short rolling history at[entry+0x84..], grows the bounded sample-count[entry+0x94]up to four, computes the current average into[entry+0x80], and then publishes that averaged sample throughmultiplayer_transport_enqueue_callback_slot24_record. So the publication boundary is explicit and the request-id ownership is explicit, even though the exact user-facing meaning of the sample and the companion value at[entry+0x54]is still open. The same service loop also owns a slower sidecar lane keyed off[entry+0xa4]:multiplayer_transport_select_stale_selector_view_progress_entrywalks the store throughmultiplayer_transport_pick_stale_selector_view_progress_entry, picks one stale entry whose progress latch[entry+0x9c]is clear and whose last progress tick[entry+0x70]is old enough, and then hands it tomultiplayer_transport_stage_selector_view_progress_snapshot. That helper now looks more bounded too: it rebuilds the marker text from[entry+0x50]throughmultiplayer_transport_format_selector_view_probe_marker, formats onePNG %s %dline around that marker and the entry-local selector-view sample at[entry+0x80], appends bounded selector-slotPNGfragments for live overlapping slots, marks progress-snapshot state in flight at[entry+0x9c], and stamps both[entry+0x70]and the transport-wide throttle tick[transport+0xaec]. So the selector-view sidecar no longer looks like one undifferentiated refresh bucket: it has a faster deferred-probe lane plus a slower progress-snapshot lane, both still under the shell-owned multiplayer transport cadence. The two descriptor lanes installed bymultiplayer_transport_attach_callback_table_descriptorare now tighter too. The first lane rooted at0x59f5c0can arm deferred-close state on the owner transport and then forward through callback slot23. The second lane is no longer just a loose selector-view bucket:multiplayer_transport_callback_dispatch_selector_name_payload_laneat0x59f650classifies selector payloads throughmultiplayer_transport_is_selector_control_line, routes@@@NFOcontrol lines intomultiplayer_transport_sync_selector_view_nfo_r_flag, and otherwise publishes either callback slot13or the split token-plus-tail callback slot14throughmultiplayer_transport_split_selector_payload_token_and_tail. That local@@@NFOhelper is now bounded more tightly too: it only accepts lines ending in the literalX\tail, searches for the field marker\$flags$\, and then sets or clears bit0x2in the third selector-slot flag word at[entry+0x64]depending on whether that field contains the letterrbefore the next backslash. The siblingmultiplayer_transport_callback_dispatch_current_selector_payload_laneat0x59f720first resolves the active selector through0x5951a0, then handles the current-selector variants of the same control vocabulary:@@@NFOcontinues into the same localr-flag sync helper,@@@GMLplus mode-3/4payloads feed the shared control-token helpermultiplayer_transport_handle_gml_or_png_selector_control, and the remaining non-control payloads publish callback slot9. That shared helper now narrows theGMLandPNGsplit materially: when the token isGMLand the tail isDisconnected, it requires the active selector-view entry to passmultiplayer_transport_selector_view_entry_has_gml_disconnect_gate, which currently means the entry participates in the third selector slot and has bit0x20set in[entry+0x64], before it forces one status-pump pass, emits callback slot16, and re-enters route mode5. Its siblingPNGbranch resolves a named selector-view entry from the tail text and, when that entry overlaps the active selector-slot ownership, refreshes selector-view runtime state through0x5948f0and republishes callback slot25. Alongside those dispatchers, one grounded branch at0x59f560still updates selector-view runtime state through0x5948f0and forwards the same selector-name pair through callback slot25, while0x59f850resets selector text state through0x5954b0, forwards through callback slot19, and when selector2is active in a nonterminal route mode re-entersmultiplayer_transport_set_route_modewith mode1. The low-level route helper still looks like a two-part cycle:multiplayer_gamespy_route_service_retry_and_keepalive_timershandles challenge or retry pressure and periodic outbound control traffic around themaster.gamespy.com,PING,natneg,localport,localip%d, andstatechangedstrings, whilemultiplayer_gamespy_route_drain_inbound_packetsdrains inbound datagrams and dispatches semicolon lines, backslash-delimited key bundles, and0xfe 0xfdGameSpy control packets. The transport-owned callback story is now narrower too. The shared route constructormultiplayer_gamespy_route_construct_and_seed_callback_vectorseeds[route+0x88]through[route+0x9c]from the caller-supplied transport callback table, records the owner transport at[route+0x104], and explicitly zeroes[route+0xa0],[route+0xa4], and[route+0xd4]before any later patch-up. For the transport-owned status route,multiplayer_transport_try_connect_status_routethen patches[route+0xa0]throughmultiplayer_gamespy_route_set_extended_payload_callbackto point atmultiplayer_transport_forward_validated_extended_route_payload0x00597330, which simply forwards the validated payload wrapper into the owner callback at[transport+0x17f4]with context[transport+0x17f8]. The grounded live-route connect path atmultiplayer_transport_try_connect_live_routedoes not currently perform any matching post-construction patch for[route+0xa0],[route+0xa4], or[route+0xd4], and the higher route-mode state machine now looks consistent with that: current grounded mode transitions switch by releasing route objects throughmultiplayer_gamespy_route_release_and_freeand rebuilding them throughmultiplayer_transport_try_connect_live_route, not by mutating callback slots in place. The parser behavior is now tighter as well: semicolon lines only dispatch when[route+0xd4]is non-null, and the subtype-6raw fallback only dispatches when[route+0xa4]is non-null. For the currently grounded transport-owned status and live routes, those two branches therefore remain optional and can cleanly no-op instead of implying a hidden mandatory callback path. Inside the packet parser, subtype4is no longer an unknown callback hop: after cookie validation it dispatches through[route+0x9c], which the transport-owned status and live routes seed tomultiplayer_transport_handle_validated_route_cookie_event0x005972c0. That helper either marks route progress and re-entersmultiplayer_transport_set_route_mode, or forwards the event id plus payload into the owner callback at[transport+0x17f0]with context[transport+0x17f8]. Subtype6still validates the same cookie, dedupes one 32-bit cookie or packet id, and then dispatches the trailing payload through the natneg-or-raw callback layer rooted at[route+0xa0]and[route+0xa4]. This separates the shell-frame preview refresh at0x006cd8d8from the actual transport cadence at0x006cd970, and also separates that transport cadence from the lower GameSpy route-service and packet-parser layer beneath it. - Evidence:
function-map.csv,pending-template-store-management.md,pending-template-store-functions.csv, plus objdump caller traces showingmultiplayer_window_service_loopreachingmultiplayer_flush_session_event_transportand the transport pump chainmultiplayer_flush_session_event_transport -> multiplayer_transport_flush_and_maybe_shutdown -> multiplayer_transport_service_frame -> multiplayer_transport_service_worker_once -> multiplayer_transport_drain_request_text_queue. - Open Questions: unresolved request-id semantics for
1,2,4, and7; whether any non-mode-path helper outside the currently grounded release-and-rebuild flow ever patches[route+0xa4]and[route+0xd4]for the transport-owned status/live routes, or whether those packet families are simply unused in this stack; and how far the Multiplayer preview-dataset machinery is reused outsideMultiplayer.winbeyond the currently grounded.gmtsave-mode hook.
Input, Save/Load, and Simulation
-
Roots: the shell controller window-message ingress
shell_controller_window_message_dispatchat0x0054e3a0, the shell input-state object initialized at0x006d4018throughshell_input_state_init0x0054e710, the saved-world restore pathworld_load_saved_runtime_state_bundleat0x00446d40, the live-world save pathworld_runtime_serialize_smp_bundleat0x00446240,world_entry_transition_and_runtime_bringupat0x00443a50, the frame-owned cadencesimulation_frame_accumulate_and_step_worldat0x00439140, the recurringGameMessage.winservice branch throughgame_message_window_service_if_present0x004e0720, the world-facingGameUppermost.winoverlay branch ensured byshell_ensure_game_uppermost_window0x004e0e40and serviced throughgame_uppermost_window_service_world_hotspot_band0x004e0780, and the lower step family rooted atsimulation_advance_to_target_calendar_point0x0040ab50with periodic branches throughsimulation_service_periodic_boundary_work0x0040a590. -
Trigger/Cadence: shell-side input is event-driven by controller-window
WM_*traffic while save or load work is triggered either directly from shell commands or through thefileopt.winbranch flags into the.smpruntime-state family; post-bring-up world service becomes recurring once a world root exists at0x0062c120, but the current grounded top-level cadence still remains the shell-ownedshell_service_pump_iterationpath, which callssimulation_frame_accumulate_and_step_worlddirectly and lets it accumulate elapsed wall-clock time into one or more simulation-step quanta. A second ingress is now bounded too:simulation_run_chunked_fast_forward_burstat0x00437b20repeatedly calls the same lower steppersimulation_advance_to_target_calendar_point, but current grounded callers put that helper inside the larger post-load generation pipelineworld_run_post_load_generation_pipelineat0x004384d0under theSeeding Economy...phase rather than under the ordinary player-facing speed buttons. That setup pipeline is now clearer at the progress-banner level too: localized id318Computing Transportation and Pricing...stays visible while the pipeline runsworld_compute_transport_and_pricing_grid0x0044fb70, the early collection-owned staging passworld_setup_building_collection_phase0x0041ea50, and the conditional region pairworld_region_collection_seed_default_regions0x00421b60plusworld_region_border_overlay_rebuild0x004882e0; only then does the code post id319Setting up Players and Companies.... That319lane is no longer just a shell-state placeholder: its primary grounded work is still the chairman-profile pairworld_seed_default_chairman_profile_slots0x004377a0plusworld_build_chairman_profile_slot_records0x00437220, which seed the 16 selector bytes at[0x006cec7c+0x87], materialize the per-slot chairman records from the scenario selectors, campaign override flag[0x006cec7c+0xc5], and the static persona table at0x005f2d28, and then publish the selected chairman-profile and linked company summary pair through[state+0x25]and[state+0x21]. The local slot-record shape is tighter too because the shell editor panel around0x004cc2d0now surfaces it directly:[slot+0x00]is the staged chairman profile id,[slot+0x01]is the Optional-versus-Mandatory byte with nonzero=Optionaland zero=Mandatory,[slot+0x02]combines with the separate per-slot gate at[world+0x0bc3+slot*9]to surfaceHuman,Computer, andHuman or Computer,[slot+0x03]is the special occupied-seat byte, and[slot+0x04]is the numeric tuning field. Both the selector seeder and the record materializer treat either[slot+0x02]or[slot+0x03]as enough to keep a slot live, but current grounded writes only seed[slot+0x03]on slot zero and later move it solely by whole-record compaction. That makes[slot+0x03]the strongest current anchor for the distinguished primary-human-seat flag rather than a generic role byte. The summary fields are tighter too: current direct accessors now show[state+0x25]as the selected chairman profile id in0x006ceb9c, while[state+0x21]is the linked owning company id copied from[profile+0x1dd]throughscenario_state_set_selected_chairman_profile0x00434890. The editor-side scenario setup surface beside that chairman panel is clearer now too.map_editor_scenario_metadata_panel_refresh_controls0x004ca790republishes the scenario description from[0x006cec78+0x672e], the start-year trio[+0x66ca],[+0x66d2], and[+0x66ce], and the paired boolean toggles[+0x66de]plus inverse[+0x66f3]across control band0x5b69..0x5b74, whilemap_editor_scenario_metadata_panel_refresh_briefing_mode0x004ca670now bounds the single-player versus multiplayer briefing switch by flipping selector0x621f50, publishing localized headings1491and3586, and refreshing the two briefing texts from[state+0x4f30]and[+0x5ae9]. The companion dispatchermap_editor_scenario_metadata_panel_handle_message0x004cb4a0makes the year semantics tighter too: it commits the description and both briefing texts from edit-control payloads, toggles the same two booleans, and clamps the three year fields to1829..2100while maintainingminimum <= default <= maximum, which now lines up directly with the editor stringsDescription:Minimum Start Year:Default Start Year:Maximum Start Year:BriefingandMulti-Player Briefing. The neighboring special-conditions page is clearer as well:map_editor_scenario_special_conditions_panel_construct0x004cb2b0now grounds the live owner for theSetup_Options_Buttons.imblist rooted at0xa7fa, walks the 36-entry static rule table at0x005f3ab0, counts enabled flags from[0x006cec78+0x4a7f], and publishes theSpecial Conditions In Effectsummary from localized id1053. The same page now has a bounded live dispatcher too:map_editor_scenario_special_conditions_panel_handle_message0x004cb8e0handles both bulk selection controls and direct row-state changes, commits them back into[0x006cec78+0x4a7f], and then re-enters the panel constructor to refresh the summary. That table is no longer just a raw id run; it now clearly includes the finance and construction restrictions2535..2563, plus later editor toggles such asUse Bio-Accelerator Cars,Disable Cargo Economy,Disable Train Crashes,Disable Train Crashes AND Breakdowns, andAI Ignore Territories At Startup. The neighboring available-chairman page is tighter too.map_editor_available_chairman_panel_construct0x004ca540now bounds the shell-side owner for the 40-entry persona-availability surface under0x5aa0..0x5b03: it walks the same persona table family at0x005f2d28, publishes one localized chairman-name row per profile, counts enabled availability bytes from[0x006cec78+0x6987..], and emits the summary%1 out of %2 are selected.from localized id1035. The live state owner beside it is now grounded as well:map_editor_available_chairman_panel_handle_message0x004cb6f0handles three bulk-selection controls0x5aa1..0x5aa3by rewriting that same availability-byte array from preset bytes embedded in the persona table, and it also commits direct per-row toggle changes from0x5aaa..0x5b03back into[state+0x6987..]before refreshing the page. So the editor lane now has three distinct scenario-setup slices rather than one chairman-only blob: chairman slots, scenario metadata and briefings, plus both a rule-toggle matrix and an available-chairman pool. There is now one adjacent company-side lane too: current neighboring setup flow conditionally entersworld_conditionally_seed_named_starting_railroad_companies0x0047d440when the Multiplayer preview owner0x006cd8d8is absent and either sandbox flag[0x006cec7c+0x82]is set or shell-state flag[0x006cec74+0x14c]is set while editor-map mode[0x006cec74+0x68]is clear. That helper no longer looks like a generic company refresh. It seeds exactly three fixed named railroad-company records fromRT3.lngids575..577:Missouri Pacific,New York Central, andGrand Trunk Railroad. The first seeded company is tied back to the selected chairman-profile summary and becomes the selected company id. The second railroad is tighter now too: it only receives a chairman link whenprofile_collection_count_active_chairman_recordsfinds at least two live chairman records, and the helper then binds the zero-based second active chairman throughprofile_collection_get_nth_active_chairman_recordwith ordinal1. The third railroad currently gets no matching chairman-link branch in the grounded setup flow and therefore remains an unchaired named company in the live roster. The shell UI above that setup lane is now tighter as well:shell_company_list_window_construct0x004c7200builds a live company-list window over the company collection at0x0062be10,shell_company_list_window_refresh_rows0x004c6c30formats the active companies with localized strings267..270, and only then conditionally appends one synthetic row id0x7fffthroughshell_company_list_format_company_or_start_row0x004c6b40so<<Start New Company>>appears as a separate affordance rather than as part of the seeded trio itself. Current shell paging around that same roster is tighter too because the live company collection now has a grounded active-only ordinal helper family:company_collection_count_active_companies0x00429a50,company_collection_count_active_companies_before_company_id0x004299f0, andcompany_collection_get_nth_active_company_id0x00429990. Those helpers now anchor the “current company among active companies” math used by shell-side detail and picker flows rather than leaving it as anonymous collection glue.shell_company_list_window_handle_message0x004c6f30then routes the synthetic row intostart_new_company_dialog_open0x0047d080, whose commit path now grounds throughstart_new_company_dialog_commit_create_company0x0047d120. That lower helper unlinks any current chairman-owned company, allocates a fresh company id from the live collection at0x0062be10, initializes it through0x00428420, and only then publishes the new selected company. The neighboring compact request helperstart_new_company_request_create_company0x0047d320does the same fresh-company path from a request block and is already reached from the startup-company branch at0x00470e48. The immediate sibling shell branch below that roster is still station-oriented: current grounded resource names and handlers put one branch onshell_station_detail_window_construct0x005068c0, another onshell_station_list_window_construct0x005074c0, and the subordinate selector helper onshell_station_pick_window_construct0x00507620. But the broader company-detail ownership question is no longer open. There is now a separately groundedCompanyDetail.winfamily rooted atshell_company_detail_window_construct0x004c5540, withshell_company_detail_window_handle_message0x004c56a0as its main dispatcher andshell_company_detail_window_refresh_controls0x004c2ca0as the shared repopulation pass for the selected-company presentation and tabbed control bands around0x9476..0x9490. A grounded shell detail-manager caller reaches that constructor at0x004dde24, the first finance-action layer beneath it is now bounded throughshell_company_detail_issue_bond_offer_flow0x004c3890,shell_company_detail_issue_stock_offer_flow0x004c3f30,shell_company_detail_buyback_stock_flow0x004c46d0, andshell_company_detail_change_dividend_rate_flow0x004c5360, and the first non-finance layer is now bounded too throughshell_company_detail_resign_chairmanship_flow0x004c5a0e,shell_company_detail_bankruptcy_flow0x004c5b99, the territory-access family rooted atshell_company_detail_refresh_selected_territory_access_summary0x004c1b60plusshell_company_detail_buy_territory_access_rights_flow0x004c5fc9, backed bycompany_clear_selected_chairman_if_current_profile0x00428a10,company_declare_bankruptcy_and_halve_bond_debt0x00425a90,company_has_territory_access_rights0x00424010,company_set_territory_access_rights_byte0x00424030, andcompany_can_purchase_territory_access_rights0x00426be0, plus the two control-transfer lanes.shell_company_detail_attempt_chairmanship_takeover_flow0x0050ccc0now grounds the special chairman's election path: it checks the caller's current stock ownership in the target company, rejects insufficient holdings through localized id623, rejects recent failed attempts through id624, and then opens the confirmation under id625before seeding the local takeover-election state or packaging the same request through the multiplayer shell transport. The follow-on resolvershell_resolve_chairmanship_takeover_vote_and_commit_outcome0x0050c940now closes the single-player election loop too: it walks the active chairman profile collection, computes weighted votes for and against the takeover, compares the affirmative total against half the target-company value, presents the result throughshell_present_chairmanship_takeover_vote_outcome_dialog0x0050c500in single-player or localized id3082in multiplayer, and then either transfers chairmanship through0x00428a30or stamps the current year into[company+0x289]as the grounded takeover-cooldown field.shell_company_detail_attempt_merger_flow0x004ec640now grounds the merger side too: it rejects empty worlds through id727, rejects recent failed attempts through id728, checks the proposed premium against company cash through localized id3889, and then commits into the resolver family. That merger resolver is now bounded too:shell_resolve_merger_vote_and_commit_outcome0x004ebd10walks the active chairman profile collection, computes weighted votes for and against the proposed merger, compares the affirmative total against half the target-company value, presents the result throughshell_present_merger_vote_outcome_dialog0x004eb890in single-player or localized id3059in multiplayer, and then either commits the merger through0x00427e20or stamps the current year into[company+0x15f]as the grounded merger-cooldown field. The vote-bias side beneath that resolver is tighter now too:scenario_state_compute_issue_opinion_multiplier0x00436590is no longer just an abstract issue table lookup because its merger callsite uses issue id0x3a, which lines up directly with localized id726saying merger votes depend on public attitude toward the management of the two companies. By contrast the public-support helpercompany_compute_public_support_vote_scalar0x00424fd0uses the broader issue id0x37, which currently looks like a more general company-management or public-sentiment slot rather than the merger-only attitude term. The supporting stat layer is bounded more cleanly now too: the surrounding0x0bsetup in the merger and takeover offer builders is formatter mode rather than a player-facing issue number, while the company-side stat wrappercompany_read_year_or_control_transfer_metric_value0x0042a5d0now reads as a generic stat-family accessor over year-relative series or the bounded slot family incompany_read_control_transfer_metric_slot0x0042a2e0. Its recurring family token0x2329is no longer treated as an issue id here either; it is the stat-family selector paired with localized company-stat label id2329. That means the paired raw and scaled helpers at0x004241e0and0x00424200now read as narrow control-transfer offer policy totals instead of direct issue-argument consumers, and the same broader support-and-governance metric family now also feeds the annual shareholder-revolt and creditor-liquidation lane surfaced by localized ids300..304. The editor-side help text cluster around ids2433..2437is no longer floating either: current grounded map-editor code now has a live economic tuning family beside the chairman-slot panel.map_editor_economic_cost_slider_panel_construct0x004cadf0binds six slider controls throughmap_editor_economic_cost_slider_dispatch0x004ca980into the scenario-state float block[0x006cec78+0x0be2..0x0bf6], while the surrounding descriptor table at0x00611c70..0x00612220pairs that wider editor lane with localized fieldsPrime Rate,Merger Premium, andBuild Stations CostthroughSteam Engine Costplus the comparison or help texts2433..2437. The broader shell-state master flag at[0x006cec74+0x68]still sits above the remaining post-load phases, plus two narrower per-phase gates:[0x006cec74+0x174]directly fronts id320Setting Up Buildings...and the later region-owned structure-demand and placement pass throughworld_region_collection_run_building_population_pass0x00421c20plus the deeper per-region workerworld_region_balance_structure_demand_and_place_candidates0x004235c0, while[0x006cec74+0x178]directly fronts id321Seeding Economy...and the chunked burst helpersimulation_run_chunked_fast_forward_burst; id322then frontsCalculating Heights.... The master+0x68flag is no longer just structural: the shell load/save coordinators now use the same flag to force the editor-map.gmpfamily, so current evidence treats it as the broader editor-map mode above those later setup branches rather than an unnamed generic toggle. That worker is no longer one opaque building bucket: current grounded categories split intoHouse, a weighted region-profile family surfaced through theIndustry Weightingsstats path, and a third branch whose low-level fallback token isCommercialbut whose aligned stats label isCity Support. The same lower helper also reappears later on a slower simulation-side cadence with scale1/12, so it no longer looks like one-time setup glue only. The actual game-speed control family remains separate, rooted atworld_set_game_speed_mode0x00434680,world_adjust_game_speed_mode_delta0x00434850, andworld_toggle_pause_or_restore_game_speed0x00437a60. -
Key Dispatchers:
shell_controller_window_message_dispatch,shell_input_apply_window_key_transition,shell_input_snapshot_dispatch_state,shell_input_cursor_inside_active_view,world_load_saved_runtime_state_bundle,world_runtime_serialize_smp_bundle,simulation_frame_accumulate_and_step_world,game_message_window_service_if_present,game_message_window_service_frame,game_uppermost_window_handle_message,game_uppermost_window_service_world_hotspot_band,game_uppermost_window_refresh_controls,world_view_service_keyboard_turn_pan_and_zoom_bindings,world_view_step_heading_quadrant,world_view_step_zoom_bucket,world_seed_default_chairman_profile_slots,world_build_chairman_profile_slot_records,world_conditionally_seed_named_starting_railroad_companies,scenario_state_set_selected_chairman_profile,scenario_state_get_selected_chairman_profile_record,scenario_state_get_selected_chairman_company_record,shell_company_list_window_construct,shell_company_list_window_refresh_rows,shell_company_list_window_handle_message,start_new_company_dialog_open,start_new_company_dialog_commit_create_company,start_new_company_request_create_company,shell_station_detail_window_construct,shell_station_list_window_construct,shell_station_list_window_handle_message,shell_station_pick_window_construct,shell_station_pick_window_populate_station_rows,map_editor_chairman_slot_panel_construct,map_editor_chairman_slot_panel_handle_message,map_editor_chairman_slot_panel_refresh_selected_slot,map_editor_chairman_slot_panel_cycle_selected_slot_profile,map_editor_available_chairman_panel_construct,map_editor_available_chairman_panel_handle_message,map_editor_scenario_metadata_panel_refresh_briefing_mode,map_editor_scenario_metadata_panel_refresh_controls,map_editor_scenario_metadata_panel_handle_message,map_editor_scenario_special_conditions_panel_construct,map_editor_scenario_special_conditions_panel_handle_message,map_editor_economic_cost_slider_panel_construct,map_editor_economic_cost_slider_dispatch,station_place_world_surface_sync_and_dispatch,station_place_window_handle_message,track_lay_window_refresh_controls,track_lay_window_service_frame,track_lay_window_handle_message,simulation_advance_to_target_calendar_point, the smaller single-step helper at0x00409e80,0x0040a9c0,0x0040a910, andsimulation_service_periodic_boundary_work. -
State Anchors: shell input object
0x006d4018, per-key state table starting at[input+0x100], packed shell input flags at[input+0xa8c]now grounded as Right Shift0x1, Left Shift0x2, Control0x4, and Alt0x20, nested dispatch counter[input+0xa90], global shell controller0x006d4024, active world root0x0062c120,GameMessage.winobject0x006d081c,GameUppermost.winoverlay object0x006d0820,StationPlace.wintool object0x006d1720,TrackLay.wintool object0x006d1a8c, accumulated leftover simulation time at[this+0x4c80], shell and mode globals at0x006cec74,0x006cec78, and0x006cec7c, world manager collections at0x0062be10,0x006ceb9c,0x006cfcbc,0x006cec20,0x0062bae0, and0x006acd34, plus the packed calendar-like tuple fields around[this+0x0d],[this+0x0f],[this+0x11], and[this+0x14]. -
Subsystem Handoffs: the controller window dispatcher now looks like the first grounded input ingress. It translates keyboard and mouse
WM_*traffic into shell controller state and the separate input object at0x006d4018; read-side cursor and camera helpers later snapshot that object throughshell_input_snapshot_dispatch_stateand gate world-relative interaction throughshell_input_cursor_inside_active_view. Current grounded consumers around0x00478cb0,0x004e0780,0x0053f450, and0x0053fe90still sit on the shell controller path and consult0x006d4024or the world owner at0x0062be68, so there is still no evidence for a distinct gameplay-only input object after world entry. Instead, the first deeper world-mode interaction branch now looks like a shared world-view coordinator layered on top of the same shell-fed input state. Shell_transition_mode ensures theGameUppermost.winobject at0x006d0820; its message dispatchergame_uppermost_window_handle_messageowns the narrow action band0x7918through0x7921; and the recurring service helpergame_uppermost_window_service_world_hotspot_bandrate-limits those hotspot actions, rechecksshell_input_cursor_inside_active_view, and then pans the live world view throughworld_view_pan_relative_offset_in_camera_plane0x0043d130. The same lower setter family is also reached from the cursor-drag path throughworld_view_apply_screen_delta_to_focus_position0x0043d0c0. Above both of those sits the larger recurring serviceworld_view_service_shell_input_pan_and_hover0x0043db00, which now has one grounded keyboard branch beneath it:world_view_service_keyboard_turn_pan_and_zoom_bindings0x0043d740. That helper resolves four binding-pair families from the shell input table via0x0054e7d0, and the localized labels are now grounded fromData/Language/RT3.lng:Camera ForwardandCamera Backwardfeed the first signed pan channel,Camera LeftandCamera Rightfeed the second signed pan channel,Camera Zoom InandCamera Zoom Outfeed the signed zoom-step channel that0x0043db00smooths intoworld_view_step_zoom_bucket0x0043cc30, andCamera Rotate LeftplusCamera Rotate Rightfeed the continuous heading-turn branch through0x0043c810. The setup side is now better bounded too:world_view_seed_keyboard_binding_slot_pairsat0x00439e40seeds the eight slot pairs at[this+0x0a6]through[this+0x0e2]from the global action-binding registry through0x0045f370using the distinct registry keys0x0043d2a0through0x0043d310, and the registration block at0x00460769through0x004608e7shows those roots are defaulted to the expected Up Down Left and Right virtual keys before runtime polling begins. Beneath that camera stack, the enclosing frame path now has one grounded non-view sidecar: after0x0043db00it reads the active controller-view object pointer at[0x006d4024+0x18]+0x366e, compares it against the latched target at[frame_owner+0x66a2], fires exit and enter-style vtable callbacks on pointer changes through slots+0x64and+0x60, and only latches the new object when the object passes its own slot+0x1cavailability test and shell detail control id0x07d6on0x006d0818has flag bit0x4. That0x07d6gate is now more bounded than before: the dedicatedTrackLay.wintool family rooted at0x006d1a8cspecial-cases the same control id in bothtrack_lay_window_service_frameandtrack_lay_window_handle_message, uses world hit tests through0x00448ac0to arm and release a drag latch on that surface, and routes the resulting command work through the shared track-lay mode state at0x00622b0c. The surroundingtrack_lay_window_refresh_controlspass now shows that this is not just one isolated drag handler: the same tool family owns three mutually exclusive primary mode buttons at0x985e0x985fand0x9860, and current primary evidence now bounds those values asLay single track.0x1,Lay double track.0x4, andBulldoze0x40from the localized strings 2054 2055 and 1721 plus the matching control-routing branches intrack_lay_window_handle_message. The same family also owns a bridge-type preference selector rooted at0x006cec74+0x138, two wrappedNeverthroughCommonfrequency settings at0x006cec74+0x140and0x006cec74+0x13c, two boolean track-lay preference toggles, and the electrify-all-track action path. Those last two toggles are now tighter than before: current evidence strongly aligns control0x986eand state0x006cec74+0x144withAuto-Hide Trees During Track Layfrom strings 1838 and 1839, while control0x986dand state0x006cec78+0x4c74align withAuto-Show Grade During Track Layfrom strings 3904 and 3905. That mapping is still evidence-backed rather than absolutely direct from a recovered resource table, but the state ownership and control order now make it the strongest current fit. That makes0x07d6look like the shared main-world interaction surface inside a broader TrackLay world-command subsystem, not an unrelated detail button. The neighboringStationPlace.winfamily is now grounded on that same surface too: the shell detail-panel constructor family allocates it throughstation_place_window_constructat0x00509d80, publishes it at0x006d1720, services it each frame throughstation_place_window_service_frameat0x0050a530, and routes player-facing commands throughstation_place_window_handle_messageat0x005091b0. That dispatcher special-cases the same0x07d6control, and the shared helperstation_place_world_surface_sync_and_dispatchat0x00508bb0either accepts that direct surface traffic or falls back to the same detail-panel control looked up through0x006d0818, rechecks flag bit0x4, hit-tests the world through0x00448ac0, stages world coordinates into0x006d1738and0x006d173c, refreshes the selected-site summary throughstation_place_format_selected_site_summary, and updates the live station-placement selection state at0x00622af0,0x00622aec, and0x006d1740. Together withstation_place_select_category_and_refresh0x00508880,station_place_refresh_category_controls0x00507b90, andstation_place_format_preview_panel0x00508730, that makes StationPlace a second grounded consumer of the shared main-world interaction surface rather than only a sibling constructor plus frame hook. The StationPlace control semantics are now tighter too: the top category strip at0x697cthrough0x6981now grounds as small station, medium station, large station, service tower, maintenance facility, and non-station building fromRT3.lngstrings 2197 through 2202. For the three station categories only, the secondary strip at0x6988and0x6989plus display field0x698cno longer looks like another placement mode family; it is a building-style scroller. The click handlers on0x6988and0x6989cycle the style override in0x00622aec, and the display path builds the active style token fromStationSml,StationMed, orStationLrgplus the localized architecture stylesVictorian,Tudor,Southwest,Persian,Kyoto, andClapboardfromRT3.lngids 2672 through 2667. One layer lower, the remaining opaque controls are now much tighter:0x6985and0x6986are no longer a generic assist toggle but the two station-rotation policy choices from strings 2207 and 2206, switching between auto-orienting the building to track or obstacles and strictly obeying the rotation specified by the circle above. The dedicated control at0x6987is the station-rotation circle itself, wired through callback0x00507a90and aligned withClick to rotate the building. You can also use bracket keys [ and ] to rotate buildings.string 2208. That matches the lower behavior too: when the strict-rotation choice is off, both preview and commit paths route staged coordinates through0x00508040, which performs the extra orientation search before validation; when strict rotation is on, that pass is skipped and the current angle in0x006d172cis used directly. The direct shell UI also exposes the same discrete view-step family throughworld_view_step_heading_quadrant0x0043cb00andworld_view_step_zoom_bucket0x0043cc30. The neighboring gating predicatesworld_view_should_drive_primary_pan_channelandworld_view_should_drive_secondary_pan_channeltest packed shell input bits0x3, andshell_input_apply_window_key_transitionnow grounds those bits as the left and right Shift modifiers from scan codes0x2aand0x36. That means cursor drag, overlay hotspots, held Shift state, direct keyboard turn/pan/zoom bindings, the TrackLay and StationPlace world-command surfaces, and at least one frame-owned hover or focus-target branch all converge under the same shell-fed world-mode input path rather than a separate gameplay-input stack. -
Evidence: function-map rows for
shell_controller_window_message_dispatch,shell_drain_pending_window_messages,shell_input_state_init,shell_input_apply_window_key_transition,shell_input_snapshot_dispatch_state,shell_input_cursor_inside_active_view,world_load_saved_runtime_state_bundle,world_runtime_serialize_smp_bundle,world_entry_transition_and_runtime_bringup,simulation_frame_accumulate_and_step_world,game_message_window_service_if_present,game_message_window_service_frame,shell_ensure_game_uppermost_window,game_uppermost_window_construct,game_uppermost_window_handle_message,game_uppermost_window_service_world_hotspot_band,world_view_set_focus_position_xyz,world_view_apply_screen_delta_to_focus_position,world_view_pan_relative_offset_in_camera_plane,world_view_seed_keyboard_binding_slot_pairs,world_view_service_keyboard_turn_pan_and_zoom_bindings,world_view_step_heading_quadrant,world_view_step_zoom_bucket,world_view_should_drive_primary_pan_channel,world_view_should_drive_secondary_pan_channel,world_view_service_shell_input_pan_and_hover,world_seed_default_chairman_profile_slots,world_build_chairman_profile_slot_records,world_conditionally_seed_named_starting_railroad_companies,profile_collection_count_active_chairman_records,profile_collection_get_nth_active_chairman_record,scenario_state_set_selected_chairman_profile,scenario_state_get_selected_chairman_profile_record,scenario_state_get_selected_chairman_company_record,start_new_company_dialog_open,start_new_company_dialog_commit_create_company,start_new_company_request_create_company,shell_company_list_format_company_or_start_row,shell_company_list_activate_or_shift_center_company,shell_company_list_window_refresh_rows,shell_company_list_window_handle_message,shell_company_list_window_construct,shell_company_detail_window_refresh_controls,shell_company_detail_window_construct,shell_company_detail_window_handle_message,shell_station_detail_window_construct,shell_station_list_window_construct,shell_station_list_window_handle_message,shell_station_pick_window_construct,shell_station_pick_window_populate_station_rows,map_editor_chairman_slot_panel_construct,map_editor_chairman_slot_panel_refresh_slot_list,map_editor_chairman_slot_panel_refresh_selected_slot,map_editor_chairman_slot_panel_refresh_slot_counters,map_editor_chairman_slot_panel_cycle_selected_slot_profile,map_editor_chairman_slot_panel_handle_message,map_editor_available_chairman_panel_construct,map_editor_available_chairman_panel_handle_message,map_editor_scenario_metadata_panel_refresh_briefing_mode,map_editor_scenario_metadata_panel_refresh_controls,map_editor_scenario_metadata_panel_handle_message,map_editor_scenario_special_conditions_panel_construct,map_editor_scenario_special_conditions_panel_handle_message,map_editor_economic_cost_slider_panel_construct,map_editor_economic_cost_slider_dispatch,station_place_refresh_category_controls,station_place_format_selected_site_summary,station_place_format_preview_panel,station_place_select_category_and_refresh,station_place_world_surface_sync_and_dispatch,station_place_window_handle_message,station_place_window_construct,station_place_window_service_frame,track_lay_window_refresh_controls,track_lay_window_construct,track_lay_window_service_frame,track_lay_window_handle_message, andsimulation_service_periodic_boundary_work, plus the shell-input disassembly around0x0054f290, the world-view setup and service branches around0x00439e40,0x0043d740,0x0043db00,0x0043cb00, and0x0043cc30, the319setup-side branches around0x004377a0,0x00437220,0x00477820,0x00477860,0x0047d440,0x004c6c30,0x004c6f30,0x0047d080,0x0047d120,0x0047d320,0x004c2ca0,0x004c5540,0x004c56a0,0x005068c0,0x005071e0,0x005074c0, and0x005076c0, the direct summary-field helpers around0x004348700x00434890and0x004348c0, the company-link writers at0x00427c70and0x00427d74, the company constructor at0x00428420, the startup-company branch around0x00470e48, the shell company-list strings266<<Start New Company>>,267You are the chairman of the %1!,268The %1 has no chairman at the moment.,269%1 is the chairman of the %2.,270Double-click for details., and2992Shift-Click to center on this company's primary station., theCompanyDetail.imbandCompanyDetail.winresource strings in.rdata, theStationDetail.imb,StationDetail.win,StationList.win, andStationPick.winresource strings in.rdata, the shell editor window branches around0x004c9da0,0x004ca010,0x004ca1c0,0x004ca540,0x004ca670,0x004ca790,0x004ca980,0x004cb2b0,0x004cb4a0,0x004cb6f0,0x004cb8e0,0x004cc250,0x004cc2d0,0x004ceb90, and0x004cecc0, the localized chairman-slot strings2997through3001OptionalMandatoryHuman or ComputerComputerandHuman, the localized scenario-editor strings1483..1492Description:throughType the briefing for this map., the localized summary strings1035%1 out of %2 are selected.and1053Special Conditions In Effect, the 40-entry persona availability page under0x5aa0..0x5b03, the 36-entry special-condition table at0x005f3ab0covering ids2535..2563,2874,3722,3835,3850,3852, and3920, the static persona table at0x005f2d28, the selector array at0x006cec7c+0x87, the persona collection at0x006ceb9c, the localized persona strings inData/Language/RT3.lngincluding2730Unassigned, the named-chairman range2731+, and the neighboring biography range2495+, plus the seeded railroad-name strings575Missouri Pacific,576New York Central, and577Grand Trunk Railroad, the StationPlace.win constructor plus category, dispatcher, rotation-circle, shared-world-surface, preview-build, and recurring service branches around0x00507a90,0x00507b90,0x00508550,0x00508730,0x00508880,0x00508bb0,0x005091b0,0x00509d80, and0x0050a530, the StationPlace string clusterPlace a small station2197Place a medium station2198Place a large station2199Place a service tower2200Place a maintenance facility2201Place a non-station building2202Scroll through building styles.2203When placing the building, it will strictly adhere to the rotation specified by the circle above.2206When placing the building, it will rotate itself as needed to orient to track or avoid obstacles.2207Click to rotate the building. You can also use bracket keys [ and ] to rotate buildings.2208 and the architecture-style labelsClapboard2667Kyoto2668Persian2669Southwest2670Tudor2671 andVictorian2672, the TrackLay.win constructor and dispatcher family around0x0050d2d0,0x0050e400,0x0050e1e0, and0x0050e5c0, the localizedNeverthroughCommonstrings 615 through 618, the track-lay stringsBulldoze1721Lay single track.2054Lay double track.2055 and 3114, the TrackLay preference stringsAuto-Hide Trees During Track Lay1838If 'Auto-Hide Trees During Track Lay' is checked, trees will automatically be reduced to small stumps whenever you are in track laying mode.1839Auto-Show Grade During Track Lay3904 andIf 'Auto-Show Grade During Track Lay' is checked, you'll see the grade number over the track while laying track - useful for trying to keep your slopes to a minimum.3905, the electrify-all confirmation and failure strings 3083 3084 3837 and 3900, the binding-registry lookup path at0x0045f370, the registration block at0x00460769through0x004608e7, and the localized labels inData/Language/RT3.lngids3466through3473. -
Open Questions: no separate outer gameplay loop is grounded above
simulation_frame_accumulate_and_step_worldyet and no deeper gameplay-only input object is grounded either. The new setup-pipeline evidence narrows that question in one direction: the currently grounded chunked burst path at0x00437b20now looks subordinate toworld_run_post_load_generation_pipelinerather than to the ordinary speed controls, and even there it still reuses the same lower stepper and pumps shell work between chunks instead of revealing a detached gameplay loop owner. The player-facing speed-control family is now cleaner too:world_set_game_speed_modeowns the boundedPausedthroughVery Fastladder plus the hiddenUltra Fast 6..9extension,world_toggle_pause_or_restore_game_speeduses[this+0x1d]as the resume slot, and the multiplayer host restriction now looks attached to that same setter family rather than to the setup-side burst helper. The first deeper world-mode interaction branch is now better bounded:GameUppermost.winhotspots, cursor drag, held Shift state, discrete shell view-step commands, direct keyboard turn/pan/zoom bindings, theTrackLay.winandStationPlace.winworld-command surfaces, and a frame-owned hover or focus-target transition branch all feed the same shell-controller-backed path. The remaining uncertainty has moved farther from basic ownership: the hover-target branch clearly exists, and0x07d6now looks like the shared main-world interaction surface rather than a generic detail button for one tool family only. The next unresolved layer is narrower and more semantic: the setup side now has one grounded owner,world_run_post_load_generation_pipeline, and its building-side branch is no longer just one opaque block. We now have a region family, a region-border overlay rebuild, a region-owned structure-demand and placement dispatcher, and a deeper per-region worker that computes category demand, subtracts existing coverage, and tries candidate placements. The category map is tighter too: category0falls back toHouse, category2is the year-gated weighted region-profile family that also feeds the localizedIndustry Weightingsstats panel, and category3now reaches a separate pool-driven picker whose fallback label isCommercialbut whose aligned player-facing stats bucket isCity Support. The remaining setup-side uncertainty has therefore narrowed again: the region seed and border-overlay pair clearly complete before theSetting up Players and Companies...banner is posted;[0x006cec74+0x174]now looks like the direct building-population gate;[0x006cec74+0x178]now looks like the direct seeding-burst gate; and[0x006cec74+0x68]now aligns with editor-map mode because the same flag forces the.gmpfamily in the shell file coordinators while suppressing the later building and seeding branches and diverting the deeper region worker into alternate logic. The319lane itself is no longer the open structural gap; it now clearly owns chairman-profile slot seeding, profile-record materialization, a shell editor surface over the same local record family, and a separate live-company presentation path through the company-list window. The remaining gaps on this lane are therefore narrower than before: the local slot records are rooted at[world+0x69d8],[slot+0x01]polarity and the external role gate at[world+0x0bc3+slot*9]are now grounded, and[slot+0x03]now looks like the distinguished primary-human-seat marker because current grounded writes seed it only on slot zero and later logic moves it solely by whole-record compaction. The open question is no longer whether the seeded trio lands in the visible shell company roster; current evidence says it does, and ordinaryStart New Companynow looks like a fresh-company allocator throughstart_new_company_dialog_commit_create_companyandstart_new_company_request_create_company, not like the path that claims one of the seeded named railroads. The immediate post-roster station branch is now clearly separate: current grounded resource names and handlers put mode8onStationDetail.win, mode5onStationList.win, and the subordinate selector helper onStationPick.win. The company-side ownership question has therefore moved down a layer rather than staying open. We now have a recoveredCompanyDetail.winowner family throughshell_company_detail_window_refresh_controls,shell_company_detail_window_construct, andshell_company_detail_window_handle_message; the first finance-action layer beneath it is bounded through the bond, stock-issue, stock-buyback, and dividend-rate helpers; the territory-access side is bounded too throughshell_company_detail_refresh_selected_territory_access_summary,shell_company_detail_buy_territory_access_rights_flow, and the underlying company access-rights helpers; and the full takeover and merger vote-result lane is now grounded throughshell_resolve_chairmanship_takeover_vote_and_commit_outcome,shell_present_chairmanship_takeover_vote_outcome_dialog,shell_resolve_merger_vote_and_commit_outcome, andshell_present_merger_vote_outcome_dialog. The remaining company-side uncertainty is therefore narrower than before: the public-support side is now tighter too becausecompany_compute_cached_recent_performance_support_scoreandcompany_compute_public_support_vote_scalarbound the recent-performance and public-support blend beneath those vote resolvers,scenario_state_compute_issue_opinion_multipliernow bounds the next layer of optional company, chairman, and territory-specific opinion overrides on the active scenario state, and the broader stat-reader family aroundcompany_read_control_transfer_metric_slotandcompany_read_year_or_control_transfer_metric_valueis no longer just a merger-premium helper. Current grounded callers show the same metric family feeding the annual shareholder-revolt and creditor-liquidation lane surfaced by localized ids300..304, so the remaining gap is now mostly semantic: the exact player-facing names of the support-and-governance metric slots behind issue ids0x37and0x3a, plus any later chairmanship-control side effects beyond the already grounded success or failure commit points. The packed simulation calendar tuple semantics also remain open. TheTrackLay.winfamily now clearly ownsLay single track.Lay double track.andBulldozeas its three primary modes, its bridge selector, its wrapped frequency preferences, and a strongly aligned pair ofAuto-Hide Trees During Track LayandAuto-Show Grade During Track Laytoggles; theStationPlace.winfamily now clearly owns its six top-level category buttons, the station-style scroller, and the station-rotation controls. The olderBuilding placement centerstring 671 no longer looks like a live StationPlace control label in the current recovered flow, because the active constructor, preview, refresh, and dispatcher paths all use neighboring ids such as 669 and 2208 without a direct recovered lookup of 671. On save or load the broad serialize-versus-restore split is now grounded, the non-Quicksave.gmp/.gmx/.gmc/.gmsfamilies are separated, and the auxiliary.gmtpath is at least bounded to the preview-surface side owner. The higher-value shell-facing gap has therefore shifted upward to the remaining semantics of the post-load generation phases, the later recurring structure-population cadence, the deeper vote-weight formulas inside takeover and merger resolution, and the still-open meaning of the packed simulation calendar tuple. -
Editor breadth: the broader map-editor page owner is now bounded through
map_editor_panel_select_active_section0x004ce070andmap_editor_panel_dispatch_active_section_message0x004cf700, which switch among the grounded setup pages,Cities/Regions,Territories, thePlayersandPlayer Poolsetup slices, the now-groundedBuilding Densitypage, the locomotives-available and industry-availability pages, the economic and special-condition pages, thePort/Warehouse Cargospage, and the later report pages. The mid-editor ownership is materially clearer now too: the chairman-slot editor is thePlayerspage, the available-chairman editor is thePlayer Poolpage, and the former unnamed dual tri-state page now lines up with localized page text997Building Densityplus help text1017and the direct field captions1642Starting Building Density Level:and1644Building Density Growth:. Both controls are now bounded as stored ordinal bytes0/1/2rather than loose labels: the first three-choice control is the map-wide starting-density selector, with its default middle state1matching the documented100%baseline from1643; the second is the paired overall growth selector whose effects later appear in the city-growth side of the simulation.map_editor_city_region_panel_constructandmap_editor_city_region_panel_handle_messageown the city-or-region editing lane with rename and copy-industry-data flows;map_editor_territory_panel_constructandmap_editor_territory_panel_handle_messageown the territory rename and border-remap lane;map_editor_locomotive_availability_panel_constructplusmap_editor_locomotive_availability_panel_handle_messagenow bound the locomotive policy page over0x006ada84;map_editor_industry_availability_panel_constructplusmap_editor_industry_availability_panel_handle_messagedo the same for the industry candidate pool at0x0062b268; andmap_editor_port_warehouse_cargo_panel_constructplusmap_editor_port_warehouse_cargo_panel_handle_messagenow ground the recipe-book page that edits port or warehouse cargo policies through twelve per-book state blocks at[0x006cec78+0x0fe7+index*0x4e1]. Each book now has a shared maximum annual production float atbook+0x3edand five fixed cargo-line entries starting atbook+0x3f1with stride0x30; each line is bounded as a mode dword, annual amount, a supplied-cargo token at+0x08, and a demanded-cargo token at+0x1c. The constructor and handler now make those fields materially tighter too: the row pair shown inSupply OnlyandProduction Demand->Supplyis the+0x08supplied-cargo selector, the row pair shown inDemand OnlyandProduction Demand->Supplyis the+0x1cdemanded-cargo selector, and the single amount field at+0x04is labeledAnnual Demand:only in mode1butAnnual Supply:in modes2/3. The stronger new runtime-side result is now a full chain rather than only the importer:scenario_state_rebuild_port_warehouse_cargo_recipe_runtime_tablesfirst imports those same five lines into one repeated array of identical0xbc-byte runtime descriptors with no row-index special casing, and the candidate-side rebuild pass atstructure_candidate_collection_rebuild_runtime_records_from_scenario_state0x00412d70then projects those descriptors into the live structure collection at0x0062ba8cbeforestructure_candidate_rebuild_cargo_membership_and_scaled_rate_tables0x00411ee0rebuilds the per-cargo runtime summary tables. The player-facing line modes remainDisabled,Demand Only,Supply Only, andProduction Demand->Supply, and the fourth mode is tighter now too: current wording around1674,1675, and504plus the downstream scaling path says it is the production-line mode governed by the shared annual production cap, where the entered annual amount stays on the supply side while the demanded side becomes the normalized input branch. The candidate-side accumulator pass reinforces that split by applying the shared production cap only to the supply-half runtime branch and bypassing that scaling on the normalized demand half. The lower gameplay side is tighter now too:structure_candidate_query_cargo_runtime_summary_channels0x00412650is the first grounded consumer beneath that rebuild chain, because it lazily rebuilds four per-cargo summary banks and returns one direct-supply channel, one cap-normalized supply channel, one demand or input channel, and one scaled production-output subrow channel for a requested cargo id; the sibling helperstructure_candidate_supports_or_references_cargo_id0x004129d0then uses those same banks plus the cached cargo-membership arrays to answer whether a live candidate materially references a cargo at all. One broader collection pass also now ties the editor rule side back into runtime filtering:structure_candidate_collection_refresh_cargo_economy_filter_flags0x0041eac0rebuilds per-candidate flag[candidate+0x56]across the live structure collection, and current grounded callers show it rerunning directly off the runtime cargo-economy latch at[0x006cec74+0x25f], which aligns this lane with the editor'sDisable Cargo Economyspecial condition rather than leaving it as a purely editor-owned recipe page. The first common live gate beneath that filter is now bounded too:structure_candidate_is_enabled_for_current_year0x0041e220is the shared year-and-filter check used by the collection refresh and later candidate-selection branches, whilestructure_candidate_rebuild_local_service_metrics0x0041e2b0is a setup-side local service scorer that already consumes the same enabled candidate records through world-grid sampling. One steady-state world-side consumer is now grounded as well:placed_structure_rebuild_candidate_cargo_service_bitsets0x0042c690walks linked placed structures, filters live category-2candidates throughstructure_candidate_is_enabled_for_current_year, and compacts the direct and scaled supply-side channels from0x00412960and0x004129a0into per-cargo bitsets on the placed-structure record. The next site-side owner layer is tighter now too:placed_structure_refresh_linked_candidate_flag40x0042c8f0refreshes the sibling state bit at[site+0x0e6],placed_structure_refresh_candidate_service_state0x0042cdf0ties that flag refresh to the cargo-service bitset rebuild,placed_structure_rebuild_candidate_local_service_tables0x0042ce00then performs the heavier per-site candidate score rebuild over the aligned float and word tables at[site+0x107],[site+0x02], and[site+0x6c], andplaced_structure_refresh_local_service_score_bundle0x0042d580is now the local wrapper that chains that rebuild into the neighboring post-passes before the world-grid owner continues. Those post-passes are tighter too:placed_structure_apply_route_linked_service_caps0x0042cc50is the first route-backed cap pass over the rebuilt local tables,placed_structure_redistribute_local_service_pressure_from_neighbors0x0042c1b0is the neighboring-site redistribution pass, andplaced_structure_clamp_candidate_service_age_table0x0042cb30is the final recent-service clamp over the primary per-candidate word table. Above that refresh lane,placed_structure_query_candidate_local_service_metrics0x0047e240is the first higher-level query,placed_structure_count_candidates_with_local_service_metrics0x0047e330counts how many candidates currently produce that query, andplaced_structure_query_cached_express_service_class_score0x0047e390caches one parallel class score for the express family now strongly aligned withPassengers,Mail, andTroops. Those site-side scores now have grounded shell read-side consumers too:shell_station_detail_format_freight_and_express_summary0x00506be0formats the visibleFreight: %1andExpress: %1lines inStationDetail.win, and the same station-detail family now has a deeper candidate-service lane:shell_station_detail_set_active_candidate_service_preview0x00504ae0stores the active(station id, candidate id)pair for the world-side preview scan,shell_station_detail_clear_active_candidate_service_preview0x00504a90tears that pair back down,shell_station_detail_update_candidate_service_entry0x00504ba0is the shell-side entry updater above that preview pair,shell_station_detail_format_candidate_local_service_summary0x00504beausesplaced_structure_query_candidate_local_service_metricstogether with localized ids681,682, and2813to build the visible candidate service text,shell_station_detail_build_to_from_haul_summary_widget0x00505150now grounds the pairedToandFromhauled-traffic strip widgets,shell_station_detail_present_to_from_haul_stats_popup0x00504770owns their click-through annual and lifetimehauled TO/FROM this stationpopup,shell_station_detail_refresh_nearby_structure_jump_rows0x00505470owns the five-row nearby-structure jump lane, andshell_station_detail_refresh_candidate_service_rows0x00505760is now the larger row-list owner that enumerates active candidate-service entries and wiresshell_station_detail_update_candidate_service_entryinto the per-row click path.shell_station_list_format_freight_and_express_availability_summary0x00506e50feeds the station-list summary%1 has %2 freight loads and %3 express loads available for hauling..., and the paired modifier helpershell_station_list_handle_center_or_rename_action0x00506d50owns the visible Shift-center and Ctrl-rename row actions. The report side is clearer as well:0x004d3060is the dedicatedStats - Treesconstructor overmap_editor_tree_stats_report,0x004d3080is the actualGeneral Validationconstructor overmap_editor_general_validation_report, and the same page table also now groundsStats - Cargo,Stats - City/Region,Stats - City Count,Event Variable Values, and the neighboring event-validation page. The remaining open editor edge is therefore mostly the deeper gameplay meaning of those site-side service scores and flag bits, not page ownership. -
Station-detail overlay: the shell-side candidate preview pair now has a grounded world consumer too.
world_render_station_candidate_service_map_overlayat0x0043f640reads the active(station id, candidate id)pair from0x005ee4fcand0x005ee500, scans the placed-structure collection, and then splits the legend by candidate mode. When the active candidate carries a nonzero route-style byte at[candidate+0x46], the overlay uses the heavier helperplaced_structure_query_candidate_directional_route_overlay_summaryat0x0047e690in both directions between the preview station and each scanned site and formats the resulting directional rows as3874Coming To %1and3875Going From %1. When that byte is zero, the same overlay falls back to the direct local-service path throughplaced_structure_query_candidate_local_service_metricsand formats the two legend rows instead as3876Current Supply @ < %1and3877Current Demand @ > %1. Empty directional lanes collapse to3878--None--, and one title lane falls back to literalAll. The nearby connection-state notes3872and3873are still tied to adjacent overlay-side ownership checks, but3879Out of Syncdoes not currently appear inside0x0043f640itself and remains a separate unresolved sibling owner. -
Station-detail overlay, corrected boundary:
3879Out of Syncis no longer an unresolved overlay sibling. It is now grounded under the multiplayer preview dataset path instead:multiplayer_preview_dataset_service_launch_state_and_warn_out_of_syncat0x0046b780checks global0x006cd91c, raises theOut of Syncshell status through0x5386e0, and then continues through the wider multiplayer preview launch-state service. So the station-detail overlay currently owns only theComing To,Going From,Current Supply,Current Demand,--None--, and adjacent connection-state note lanes. -
Station-detail overlay, ownership side: one reusable site helper is grounded now too.
placed_structure_query_linked_company_idat0x0047efe0resolves the current placed structure's linked instance through0x0062b26cand returns its company id from[instance+0x276]; the overlay compares that id against the active company selector before deciding whether a scanned site should carry theAlready Connected by Another Companynote. The remaining local gap on this branch is the exact branch that emits the neighboringNot Connectednote. -
Station-detail overlay, route-list side: the neighboring helper
placed_structure_append_unique_route_entryat0x0047f010is now grounded as the append-if-missing builder for the six-byte route-entry list rooted at[site+0x462]and[site+0x466]. That matters here because the directional overlay query at0x0047e690consumes the same list, so the remaining uncertainty is no longer list ownership. It is down to the exact semantics of each entry'su32payload and the finalOut of Syncchooser.
Next Mapping Passes
- Resolve the owner-side callback roles behind the validated GameSpy packet branches, especially
[route+0x9c],[route+0xa0],[route+0xa4], and[route+0xd4]. - Determine whether any later world-mode branch beneath the frame owner bypasses the shell controller input path for non-cursor gameplay input, since the current grounded overlay and cursor helpers still reuse
0x006d4018. - Keep detailed pending-template or transport work scoped to the specific atlas edges that remain unresolved.