From 75de7cec3b479490f49ed3d035617511fc1430c6 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Sat, 4 Apr 2026 00:19:24 -0700 Subject: [PATCH] Ground multiplayer preview dataset ownership --- artifacts/exports/rt3-1.06/function-map.csv | 56 +++++++++++++++++---- docs/control-loop-atlas.md | 37 +++++++------- 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/artifacts/exports/rt3-1.06/function-map.csv b/artifacts/exports/rt3-1.06/function-map.csv index c34b27c..a3a30fb 100644 --- a/artifacts/exports/rt3-1.06/function-map.csv +++ b/artifacts/exports/rt3-1.06/function-map.csv @@ -2,11 +2,23 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0040a590,892,simulation_service_periodic_boundary_work,simulation,cdecl,inferred,objdump + analysis-context,3,Periodic simulation-maintenance dispatcher inside the world-step family. It switches on the local calendar or phase byte at [this+0x0f] routes one heavy mode through the larger recurring service branch at 0x0040a160 falls back to the simpler one-step advance at 0x00409e80 for other modes and runs several global manager sweeps across 0x0062be10 0x006ceb9c 0x006cfcbc 0x006cec20 and 0x0062bae0 before handing control back to the enclosing stepper. One conditional branch also re-enters shell_map_file_world_bundle_coordinator at 0x00445de0 which keeps the save-or-package family connected to the live simulation cadence.,objdump + analysis-context + caller xrefs 0x0040ab50,339,simulation_advance_to_target_calendar_point,simulation,cdecl,inferred,objdump + analysis-context,3,Advances the active world state toward one caller-selected packed calendar target while guarded by the recursion counter at 0x0062b240. The helper compares the current local tuple fields [this+0x0d] [this+0x0f] [this+0x11] and [this+0x14] against a target resolved through 0x0051d550 and 0x0051d5f0 then either recurses in larger 0x168-sized chunks or advances through the smaller periodic step family rooted at 0x00409e80 and 0x0040a9c0. Each successful step notifies the live world root at 0x0062c120 through 0x00450030. Grounded callers include the frame-time accumulator at 0x00439140 the larger fast-forward helper at 0x00437b20 and one shell UI command path.,objdump + analysis-context + caller xrefs 0x00434300,881,world_runtime_release_global_services,map,cdecl,inferred,objdump + analysis-context,3,Releases or clears a broad set of world-runtime global services owned by the current map object before a new world entry or sibling save branch continues. The helper walks the owner collection at [this+0x66b2] and then touches many global manager slots including 0x0062b244 0x0062cfcbc 0x0062be10 0x0062c120 0x0062ba8c 0x0062ba88 0x0062b2fc 0x0062b268 0x006cea4c and 0x006acd34 through repeated release-style calls and nulling writes. Current grounded callers are the heavier world-entry branch at 0x00443a50 the sibling .smp world-state branch at 0x00446d40 and shell_transition_mode at 0x00482ec0.,objdump + analysis-context + caller xrefs -0x00439140,1086,simulation_frame_accumulate_and_step_world,simulation,cdecl,inferred,objdump + analysis-context,4,Frame-owned simulation cadence after world bring-up. The routine samples elapsed time through 0x0051d890 mixes shell and mode scalars into a simulation quantum keeps leftover fractional time in [this+0x4c80] and when enough time has accumulated repeatedly calls simulation_advance_to_target_calendar_point at 0x0040ab50 using the current step quantum from 0x005f2b38. Around those simulation steps it also refreshes shell-facing presentation helpers under 0x006d4024 and 0x006d0818 updates multiple world collections and transport or scenario side structures and then continues into later follow-up work. This is the strongest grounded owner so far for the recurring gameplay simulation cadence that follows world_entry_transition_and_runtime_bringup.,objdump + analysis-context + caller xrefs +0x0043cb00,295,world_view_step_heading_quadrant,shell,thiscall,inferred,objdump + caller xrefs,3,Applies one discrete heading-step command to the live world-view owner at 0x0062be68. The helper quantizes the current heading-like field [this+0x10] into one of four wrapped sectors derives the neighboring sector selected by the signed caller step and writes the resulting snapped heading back before rebuilding the dependent view state through 0x0043a750 0x0052d640 and 0x0043bde0. Current grounded callers are the paired shell UI command branches at 0x004de83d and 0x004de857 so this looks like the discrete rotate-view command family rather than free camera drag.,objdump + caller xrefs + callsite inspection +0x0043cc30,437,world_view_step_zoom_bucket,shell,thiscall,inferred,objdump + caller xrefs,3,Applies one discrete zoom or view-height bucket step to the live world-view owner at 0x0062be68. It derives a seven-entry threshold table under 0x005ee4dc and 0x0062be4c compares the current view-height field [this+0x18] against those thresholds chooses the neighboring bucket selected by the signed caller step clamps the result into the supported range and then rebuilds the dependent view state through 0x0043c610 0x00439820 and 0x0043bde0. Current grounded callers are the signed shell UI command pair at 0x004de871 and 0x004de88b and the keyboard-owned smoothing branch inside world_view_service_shell_input_pan_and_hover at 0x0043dca4.,objdump + caller xrefs + callsite inspection +0x0043d050,111,world_view_set_focus_position_xyz,shell,thiscall,inferred,objdump + caller xrefs,4,Stores one new world-view focus position into the owner at 0x0062be68 by updating [this+0x04] [this+0x08] and [this+0x0c] as the requested X Y and Z coordinates then rebuilding the dependent view state through 0x0043cec0 0x0043a750 0x0052d640 0x00439820 and 0x0043b0e0. The helper also clamps the view-height or distance field at [this+0x18] before recomputing the derived pitch-like field at [this+0x14]. Current grounded callers are the screen-delta wrapper at 0x0043d0c0 the relative pan helper at 0x0043d130 and two larger world-view service branches at 0x0043ee76 and 0x0043f32d.,objdump + caller xrefs +0x0043af60,205,world_view_should_drive_primary_pan_channel,shell,thiscall,inferred,objdump,3,Returns whether the world-view owner should drive its primary pan channel on this pass. The predicate first honors the latched override at [this+0xa2] then checks several shell-view gates through 0x00543e00 0x00543e20 and 0x00543e40 on the active controller node plus one optional guard under 0x006d1a8c and the world-mode flag at [0x006cec74+0x120]. When the controller view is active it also treats packed shell input bits 0x3 in 0x006d4018+0xa8c as one enabling condition; `shell_input_apply_window_key_transition` grounds those bits as the left and right Shift modifiers from scan codes 0x2a and 0x36 which ties held Shift state back into the same world-view pan family. Current grounded callers sit in the larger recurring world-view input service at 0x0043db00 and the smaller motion helper at 0x0043e610.,objdump + callsite inspection +0x0043b030,173,world_view_should_drive_secondary_pan_channel,shell,thiscall,inferred,objdump,3,Returns whether the world-view owner should drive its secondary pan channel on this pass. Like the neighboring primary predicate it combines shell controller view gates through 0x00543e00 0x00543e20 and 0x00543e40 optional suppression under 0x006d1a8c and one world-mode check at [0x006cec74+0x120]; when the active controller view is present it also treats packed shell input bits 0x3 in 0x006d4018+0xa8c as an enabling condition. Those bits are now grounded as the left and right Shift modifiers from scan codes 0x2a and 0x36 rather than an opaque gameplay-only flag source. Current grounded callers sit in the larger recurring world-view input service at 0x0043db00 and in the smaller motion helpers at 0x0043e610 and 0x0043f4f0.,objdump + callsite inspection +0x0043d0c0,111,world_view_apply_screen_delta_to_focus_position,shell,thiscall,inferred,objdump + caller xrefs,4,Converts one screen-relative drag delta into a new world-view focus position and forwards it through world_view_set_focus_position_xyz. When the auxiliary object at [this+0x6e] is live it samples a derived center or height term through 0x00534490 and scales both incoming deltas by the world-view projection constant at 0x005c8700 before calling the lower focus-position setter. The current grounded caller is the cursor-drag helper at 0x00478d31 inside the larger input loop at 0x00478cb0.,objdump + caller xrefs +0x0043d130,292,world_view_pan_relative_offset_in_camera_plane,shell,thiscall,inferred,objdump + caller xrefs,4,Applies one local X/Z pan offset to the world-view owner at 0x0062be68 in the current camera plane and forwards the result through world_view_set_focus_position_xyz. The helper derives a scale from the active view-height field [this+0x18] rotates the incoming offset by the current heading-like field [this+0x10] through sine and cosine calls at 0x005a13e4 and 0x005a1494 adds the rotated result onto the current world focus position in [this+0x04] and [this+0x0c] preserves the current Y term in [this+0x08] and then calls the lower focus-position setter. Current grounded callers are the GameUppermost hotspot path at 0x004e094b and the keyboard-owned service branch inside world_view_service_keyboard_turn_and_pan_bindings at 0x0043dae4 which together indicate a shared world-view pan action rather than a separate gameplay command dispatcher.,objdump + caller xrefs +0x0043d740,937,world_view_service_keyboard_turn_pan_and_zoom_bindings,shell,thiscall,inferred,objdump + callsite inspection,4,"Keyboard-driven world-view interaction helper beneath world_view_service_shell_input_pan_and_hover. It samples elapsed wall-clock time through 0x0051d890 against the previous timestamp at 0x0062be74 clamps the per-pass delta into the 0x08 through 0xc8 range and polls four configurable binding-pair families through the shell input table at 0x006d4018 via 0x0054e7d0. The first two pair families at [this+0x0a6] through [this+0x0b2] and [this+0x0b6] through [this+0x0c2] now ground as the default `Camera Forward` or `Camera Backward` pair and `Camera Left` or `Camera Right` pair. The third family at [this+0x0c6] through [this+0x0d2] produces a signed zoom-step or view-height delta that is returned through the caller-owned out-parameter for later smoothing and grounds as the default `Camera Zoom In` or `Camera Zoom Out` pair, while the fourth family at [this+0x0d6] through [this+0x0e2] applies continuous heading turns through 0x0043c810 and grounds as the default `Camera Rotate Left` or `Camera Rotate Right` pair. When the pan families are active the helper reaches world_view_pan_relative_offset_in_camera_plane at 0x0043d130 after checking the active world-view state. Current grounded caller is world_view_service_shell_input_pan_and_hover at 0x0043db00.",objdump + callsite inspection + caller xrefs + registration xrefs + RT3.lng +0x00439e40,557,world_view_seed_keyboard_binding_slot_pairs,shell,thiscall,inferred,objdump + callsite inspection,4,"Initializes the eight world-view keyboard binding slot pairs rooted at [this+0x0a6] through [this+0x0e2]. The helper zeroes the paired 4-byte fields then queries the global action-binding registry through 0x0045f370 using eight distinct stub roots at 0x0043d2a0 through 0x0043d310. The registration block at 0x00460769 through 0x004608e7 plus `Data/Language/RT3.lng` show those eight roots are seeded as four labeled directional pairs: `Camera Forward` id 0x0d8a on Up, `Camera Backward` id 0x0d8b on Down, `Camera Left` id 0x0d8c on Left, `Camera Right` id 0x0d8d on Right, `Camera Zoom In` id 0x0d8e on Up, `Camera Zoom Out` id 0x0d8f on Down, `Camera Rotate Left` id 0x0d90 on Left, and `Camera Rotate Right` id 0x0d91 on Right. The first bank feeds the pan pairs later consumed at [this+0x0a6] through [this+0x0c2], while the second bank feeds the zoom-step and heading-turn pairs later consumed at [this+0x0c6] through [this+0x0e2]. After the registry lookups the helper normalizes several legacy companion values across all eight pairs by remapping 0x2 to 0x10 0x20 to 0x12 and 0x4 to 0x11 before storing the results back. This now looks like the live world-view setup path above world_view_service_keyboard_turn_pan_and_zoom_bindings at 0x0043d740 rather than a separate config-side binding store.",objdump + callsite inspection + callee inspection + registration xrefs + RT3.lng +0x0043db00,1968,world_view_service_shell_input_pan_and_hover,shell,thiscall,inferred,objdump + callsite inspection,4,Recurring world-view service that fuses shell input state into the live world-view owner at 0x0062be68. It begins by delegating keyboard-bound turn pan and zoom work to world_view_service_keyboard_turn_pan_and_zoom_bindings at 0x0043d740 then samples controller and view state through 0x00543c50 and 0x00543ba0 caches successive shell input coordinates from 0x006d4018 offsets 0xa94 and 0xa98 derives smoothed cursor or hover deltas against [this+0x2f6] [this+0x2fa] and [this+0x2fe] updates one world-under-cursor cache through 0x00448ac0 and 0x00448bd0 and refreshes the GameUppermost overlay through 0x004e0730 when the pan state changes. The helper repeatedly consults world_view_should_drive_primary_pan_channel at 0x0043af60 and world_view_should_drive_secondary_pan_channel at 0x0043b030 drives one of the lower motion branches at 0x0043e610 0x0043f4f0 or 0x0043e2c0 and smooths the keyboard zoom-step channel through the shared accumulator at 0x0062be78 before issuing discrete view-height bucket steps through world_view_step_zoom_bucket at 0x0043cc30. Current grounded callers include the recurring world-frame path at 0x00439730 and two setup or transition loops at 0x00516859 and 0x00516921. This now looks like the shared shell-input coordinator above keyboard turn pan zoom cursor drag and hotspot world-view motion rather than a mouse-only helper.,objdump + callsite inspection + caller xrefs +0x00439140,1086,simulation_frame_accumulate_and_step_world,simulation,cdecl,inferred,objdump + analysis-context,4,"Frame-owned simulation cadence after world bring-up and still directly called from shell_service_pump_iteration at 0x00483f70 rather than a separately grounded outer gameplay loop. The routine samples elapsed time through 0x0051d890 mixes shell and mode scalars into a simulation quantum keeps leftover fractional time in [this+0x4c80] and when enough time has accumulated repeatedly calls simulation_advance_to_target_calendar_point at 0x0040ab50 using the current step quantum from 0x005f2b38. Around those simulation steps it refreshes shell-facing presentation helpers under 0x006d4024 and 0x006d0818 updates multiple world collections and transport or scenario side structures and services the recurring GameMessage.win branch through 0x004e0720 before later follow-up work. One deeper world-mode sidecar inside the same frame path now looks grounded too: after delegating to world_view_service_shell_input_pan_and_hover at 0x0043db00 the frame compares the active controller-view pointer at [0x006d4024+0x18]+0x366e against the latched world object at [this+0x66a2], releases the previous object through vtable slot +0x64, and when the new object passes its own availability test at slot +0x1c plus shell-detail control gate 0x07d6 on 0x006d0818 it latches the new object and calls slot +0x60. That makes the frame owner the first grounded non-camera world-input coordinator for hover or focus-target transitions beneath the shell-fed camera stack, even though click or command semantics are still unresolved. This is the strongest grounded owner so far for the recurring gameplay simulation cadence that follows world_entry_transition_and_runtime_bringup.",objdump + analysis-context + caller xrefs + callsite inspection 0x00443a50,1073,world_entry_transition_and_runtime_bringup,map,cdecl,inferred,objdump + analysis-context,4,First grounded gameplay-world entry coordinator reached from shell_map_file_entry_coordinator. It stages the selected file path into 0x0062bee0 dismisses the shell detail-panel controller at 0x006d0818 drives shell_transition_mode through 0x00482ec0 and shell_state_service_active_mode_frame then marks shell state for the transition and resets the previous world bundle through world_runtime_release_global_services and the neighboring allocator branch at 0x00438890. After the transition wait it builds temporary bundle payloads from %1\\%2 and %1.tmp allocates or serializes several world-entry records through 0x00530c80 0x00531150 and 0x00531360 allocates the new world root at 0x0062c120 from the staged filename through 0x0044e910 notifies the shell owner at 0x0062be68 and then initializes multiple world-facing global managers including 0x0062ba8c 0x0062b2fc 0x0062b26c and 0x006ada90. This now looks like the first real shell-to-gameplay world-entry bring-up path rather than shell-only staging.,objdump + analysis-context + caller xrefs + strings 0x00444dd0,3301,map_bundle_open_reference_databases,map,cdecl,inferred,ghidra-headless,3,Opens and registers a broad reference-database bundle for the active map path. The routine formats %1\\%2 paths allocates bundle state through 0x00530c80 and wires many global datasets including gpdLabelDB gpdCityDB and related city geographic and map reference tables before later shell and map loaders continue.,ghidra + rizin + llvm-objdump + strings -0x00445ac0,790,shell_map_file_entry_coordinator,map,cdecl,inferred,objdump + analysis-context,3,Broad shell-side map or scenario file entry coordinator reached from tutorial launch shell UI editor-panel flows and scenario batch processing. It accepts either an incoming base filename or a generated Quicksave-style name chooses one extension family among .gmp .gmx .gmc .gms and .smp based on current shell state and then routes into either the heavier shell transition branch at 0x00443a50 or the sibling .smp world-state branch at 0x00446d40 while toggling shell event state and controller cleanup fields. This is currently the broadest grounded map-scenario coordinator above the narrower bundle loaders even though the exact user-facing verbs of every branch still need tightening.,objdump + analysis-context + caller xrefs + strings -0x00445de0,1115,shell_map_file_world_bundle_coordinator,map,cdecl,inferred,objdump + analysis-context,3,Lower-level world-bundle coordinator used by scenario batch processing and neighboring shell-editor callers. It derives a target filename or quicksave name chooses the same extension family and then either invokes 0x00446240 for the live-world serialization branch when the current runtime state takes the .smp path or falls back to map_bundle_open_reference_databases at 0x00444dd0 after shell-state gating status work and controller notifications. The function therefore sits directly above both the reference-database load path and one sibling live-world packaging path even though the exact user-facing verb of each branch remains partly unresolved.,objdump + analysis-context + caller xrefs + strings +0x00445ac0,790,shell_map_file_entry_coordinator,map,cdecl,inferred,objdump + analysis-context,4,"Broad shell-side file-open and restore coordinator reached from tutorial launch shell UI editor-panel flows and scenario batch processing. It accepts either an incoming filename seed or a generated Quicksave base name and then chooses between the heavier world-entry branch at 0x00443a50 and the sibling saved-runtime restore branch at 0x00446d40. Bit 0x1 in its flag argument now grounds the Quicksave path from the shared string table at 0x005ca9cc. The non-Quicksave interactive path is tighter now too: it routes through shell_file_request_dialog_collect_target_path at 0x004dd010 using load mode 4=.gmp when EditorPanel.win is live and the paired non-editor open modes 8=.gms 9=.gmc and 10=.gmx. Current surrounding shell evidence now makes that trio much less anonymous: `.gmx` aligns with sandbox mode because the sibling shell branch at 0x004dc923 gates on 0x006cec7c+0x82 and surfaces string 3898 `The briefing is not available in sandbox games`; `.gmc` aligns with campaign scenarios because 0x004dc9cd gates on 0x006cec7c+0xc5 and surfaces string 3018 about resigning back to the campaign screen; the remaining default `.gms` branch is therefore the standalone scenario family. When a live runtime world is already active the helper appends .smp instead of the non-runtime extensions before the restore branch continues.",objdump + analysis-context + caller xrefs + strings + mode-table inspection + string correlation +0x00445de0,1115,shell_map_file_world_bundle_coordinator,map,cdecl,inferred,objdump + analysis-context,4,"Broad shell-side file-save and package coordinator used by direct shell commands scenario batch processing and neighboring shell-editor callers. It accepts either an incoming filename seed a generated Quicksave base name from flag bit 0x1 or the localized `Autosave` seed from flag bit 0x2 string id 387. Its non-Quicksave interactive path is now tighter: it routes through shell_file_request_dialog_collect_target_path at 0x004dd010 using save mode 3=.gmp for the editor-map package path 0=.gms for standalone scenarios 1=.gmc for campaign-scenario saves and 2=.gmx for sandbox saves plus one auxiliary 11=.gmt branch reached only through the separate 0x00434050 check on the side owner at 0x006cd8d8. That `.gmt` path no longer looks like another scenario family: when the auxiliary owner is present the coordinator packages the chosen path into the owner-local request block near 0x006cd8d8+0x8f48 and submits it through 0x00469d30; only when that owner is absent does it fall back to map_bundle_open_reference_databases at 0x00444dd0. The campaign mapping is now backed by the numbered `%s%02d.gmc` helper at 0x00517c70 which formats one campaign-progress slot from 0x006cec7c+0xc4 before re-entering this coordinator, while the sandbox mapping is backed by the neighboring shell restriction string 3898 on 0x006cec7c+0x82. When a live runtime world is active the mainline branch still appends .smp and invokes world_runtime_serialize_smp_bundle at 0x00446240. This makes the helper the save-side sibling of shell_map_file_entry_coordinator rather than another restore dispatcher, with `.gmt` now bounded as an auxiliary preview-surface side path instead of a fourth gameplay save family.",objdump + analysis-context + caller xrefs + strings + mode-table inspection + string correlation + side-owner branch inspection +0x00446240,2807,world_runtime_serialize_smp_bundle,map,cdecl,inferred,objdump + analysis-context,3,Serializes the current live world state into the `.smp` branch used by shell_map_file_world_bundle_coordinator. After dismissing the shell detail controller and running one shell-state service step it allocates a bundle through 0x00530c80 seeds many typed records through repeated 0x00531030 and 0x00531340 calls walks world collections under 0x0062c120 and 0x006ada80 and emits runtime-state payloads through helpers such as 0x00534e50 0x00534ec0 0x00534f00 and 0x00534f40 before finalizing through 0x00530a00. Current grounded caller is 0x00445de0 on the `.smp` path so this looks like the live-world save or package serializer rather than the restore path.,objdump + analysis-context + caller xrefs + strings +0x00446d40,5401,world_load_saved_runtime_state_bundle,map,cdecl,inferred,objdump + analysis-context,4,Loads one saved runtime world-state bundle from the `.smp` branch selected by shell_map_file_entry_coordinator. The helper dismisses the shell detail controller releases the prior world runtime drives shell mode and status transitions builds a bundle through 0x00530c80 and repeated 0x00531150 reads allocates a new world root at 0x0062c120 through 0x0044cf70 and then fills that root through repeated grid and object writes including 0x0044dca0 0x00448c20 0x00448cb0 0x00448d90 0x00448e60 0x00448e90 and 0x0044de30. This is the first grounded gameplay save-load restore dispatcher for `.smp` content rather than the broader reference-database map-entry flow.,objdump + analysis-context + caller xrefs + strings 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 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 @@ -35,7 +47,21 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00489830,496,scenario_text_export_report_language_file,scenario,cdecl,inferred,ghidra-headless,3,Opens one existing MAPS\\%s.lng file for the selected map and reports on its parsed contents without rebuilding it. The routine loads the file into memory iterates numbered entries through 0x00488540 formats summary strings through 0x004895c0 and presents success or failure dialogs when interactive mode is enabled.,ghidra + rizin + llvm-objdump + strings 0x00489a20,1085,scenario_text_export_batch_process_maps,scenario,cdecl,inferred,ghidra-headless,4,Enumerates maps\\*.gmp and batch-processes every scenario through the scenario-text export branch. Command 0x7542 runs the build path through 0x004886e0 while command 0x7543 runs the report path through 0x00489830; the wrapper tracks progress formats per-map status strings and emits a final summary dialog.,ghidra + rizin + llvm-objdump + strings 0x004d4500,88,shell_ensure_editor_panel_window,shell,cdecl,inferred,objdump + analysis-context,4,Ensures the shell-side EditorPanel.win helper window rooted at 0x006d07b4 exists. When the panel is absent it allocates a 0x7c-byte window object seeds the vtable at 0x005d0cb8 binds the EditorPanel.win resource through 0x0053fa50 publishes the object to the shell runtime through 0x00538e50 event 0x1e and then runs the shared panel-open helper at 0x004d4160.,objdump + analysis-context + strings +0x004dc670,368,shell_file_options_dialog_construct,shell,thiscall,inferred,objdump + strings,4,Constructs the shared shell file-options dialog rooted at fileopt.win. The helper clears the three downstream branch flags at 0x006d07f8 0x006d07ec and 0x006d07f0 binds the fileopt.win resource through 0x0053fa50 publishes the object to the shell runtime and populates several mode-dependent labels and status text before user input is handled.,objdump + strings +0x004dc7f0,477,shell_file_options_dialog_handle_message,shell,thiscall,inferred,objdump + strings,4,Handles the fileopt.win command flow and selects exactly one downstream branch before the shared detail-panel completion dispatcher runs. Successful commands dismiss the dialog then set 0x006d07f8 for the load or restore side 0x006d07ec for the save or package side or 0x006d07f0 for the sibling settings-window escape. The settings branch gates on shell_has_settings_window at 0x004fe120 and lazily opens the shared SettingsWindow.win object through 0x00501e50 while sibling branches show prerequisite dialogs when the requested file operation is not currently allowed.,objdump + strings + caller xrefs +0x004dd010,890,shell_file_request_dialog_collect_target_path,shell,cdecl,inferred,objdump + strings,4,"Builds the modal filerqst.win request dialog and resolves one chosen target path back into the caller buffer. The helper treats dialog modes 0 1 2 3 and 11 as save-side requests and the paired modes 4 8 9 and 10 as load-side requests then swaps the button and prompt text between localized ids 249 250 and 251 252. On success it appends one extension from the static mode table at 0x005f3d58 where 0 or 8=.gms 1 or 9=.gmc 2 or 10=.gmx 3 or 4=.gmp and 11=.gmt. Current neighboring callers tighten that last mode too: the normal shell map coordinators use the `.gms/.gmc/.gmx/.gmp` families for scenario and editor flows, while save mode 11 is only consumed by the auxiliary `.gmt` preview-surface branch shared with the side owner at 0x006cd8d8. When a live runtime world is already active through 0x004839b0 the helper overrides that non-runtime table and appends .smp instead, which makes it the shared bridge between the broad shell coordinators and the runtime-state serializer or restore path rather than only a generic filename prompt.",objdump + strings + mode-table inspection + caller correlation 0x004ddbd0,1096,shell_detail_panel_transition_manager,shell,thiscall,inferred,objdump + analysis-context,3,Transitions the shell detail-panel controller rooted at 0x006d0818 between many window or panel states tracked in [this+0x8c] with optional selection ids cached at [this+0x78] through [this+0x90]. The manager tears down the prior child panel at [this+0x88] through 0x004dd950 updates selector or status UI through 0x004dd410 conditionally opens helper windows such as EditorPanel.win through 0x004d4500 and then allocates one of many shell-facing detail windows including TrainDetail.win TrainList.win and neighboring panel objects before publishing the new child through the shell runtime at 0x006d401c. shell_transition_mode reaches this manager on one branch but the current evidence keeps it on the shell-detail path rather than the first gameplay-world-entry coordinator.,objdump + analysis-context + strings +0x004dfdf0,84,shell_ensure_game_message_window,shell,cdecl,inferred,objdump + strings,4,Ensures the standalone GameMessage.win shell object rooted at 0x006d081c exists. When absent it allocates a 0x94-byte window object seeds the vtable at 0x005d0ed0 binds the GameMessage.win resource through 0x0053fa50 stores the result in 0x006d081c and publishes the object to the shell runtime through 0x00538e50.,objdump + strings + caller xrefs +0x004e0210,1217,game_message_window_service_frame,shell,thiscall,inferred,objdump + strings,4,Per-frame service pass for the GameMessage.win object rooted at 0x006d081c. It walks up to seven active message or notification records from the collection at 0x006acd34 populates the window slots around ids 0x8ca8 and neighboring controls chooses icon and portrait assets such as Portrait.imb note.imb smiley.imb and smalleye.imb maps selected message records into shell and world collections including 0x006ceb9c 0x0062be10 0x0062b26c and 0x0062bae0 and updates the visible action entries through repeated 0x00540120 calls. Current grounded caller is the simulation frame path through 0x004e0720.,objdump + strings + caller xrefs +0x004e0720,15,game_message_window_service_if_present,shell,cdecl,inferred,objdump + caller xrefs,4,Services the GameMessage.win branch only when the global object at 0x006d081c is live by tail-calling game_message_window_service_frame. The current grounded caller is simulation_frame_accumulate_and_step_world which keeps this world-facing message overlay inside the shell-owned recurring frame cadence.,objdump + caller xrefs +0x004e0780,468,game_uppermost_window_service_world_hotspot_band,shell,thiscall,inferred,objdump + strings + caller xrefs,4,Per-frame world-facing hotspot service for the GameUppermost.win overlay rooted at 0x006d0820. The helper clears the previously latched hotspot id at [this+0x78] when the shell runtime selection changes then requires an active world-mode branch at [0x006cec74+0x114] a live shell runtime node at [0x006d401c+0xc6d] an unobscured controller view through 0x00543e20 and 0x00543e40 and one selected control id in the narrow band 0x7918 through 0x7921. It rate-limits repeats through the runtime timestamp at [selected+0xd2] remaps the two rightmost ids onto the sibling left-side base actions 0x791c and 0x791e rechecks shell_input_cursor_inside_active_view at 0x0054f540 scales one table-driven coordinate pair from 0x006066c8 and 0x006066e8 and finally pushes that world-relative offset into the live world owner at 0x0062be68 through 0x0043d130. Current grounded caller is game_uppermost_window_handle_message at 0x004e0ba0.,objdump + strings + caller xrefs +0x004e0960,432,game_uppermost_window_refresh_controls,shell,thiscall,inferred,objdump + strings + caller xrefs,4,Refreshes the visible control state for the GameUppermost.win overlay at 0x006d0820. The helper repopulates the hotspot control band 0x7918 through 0x7921 through repeated 0x00540120 calls chooses one of two layout or visibility selectors based on the active world-mode state under 0x006cec74 and resolves the localized label `Hide Bottom Interface (Toggle)` for control 0x7923 before publishing it back into the window tree. Grounded callers include the overlay constructor at 0x004e0b20 the overlay message handler at 0x004e0ba0 and a later world-mode state-change branch at 0x004ff3f5.,objdump + strings + caller xrefs +0x004e0b20,118,game_uppermost_window_construct,shell,thiscall,inferred,objdump + strings + caller xrefs,4,Constructs the GameUppermost.win overlay object later stored at 0x006d0820. The helper seeds the vtable at 0x005d0f3c binds the GameUppermost.win resource through 0x0053fa50 registers the shared control callback at 0x004e0a70 for ids 0x7918 through 0x7921 refreshes the initial control state through game_uppermost_window_refresh_controls and initializes sibling control 0x7922 before returning the live overlay object. The ensure helper at 0x004e0e40 is the current grounded caller.,objdump + strings + caller xrefs +0x004e0ba0,95,game_uppermost_window_handle_message,shell,thiscall,inferred,objdump + strings + caller xrefs,4,Message dispatcher for the GameUppermost.win overlay object. It seeds one visual-speed field on the command object returned by 0x0053f830 then switches on the incoming message id through the local jump table at 0x004e0d04. The current grounded cases call game_uppermost_window_service_world_hotspot_band during the recurring service path refresh the overlay controls through game_uppermost_window_refresh_controls on a sibling state-change path and route control 0x7922 into the world-mode toggle helper at 0x004349f0 which also updates the same overlay object at 0x006d0820.,objdump + strings + caller xrefs +0x004e0e40,75,shell_ensure_game_uppermost_window,shell,cdecl,inferred,objdump + strings + caller xrefs,4,Ensures the world-facing GameUppermost.win overlay rooted at 0x006d0820 exists. When absent it allocates a 0xae-byte window object constructs it through game_uppermost_window_construct at 0x004e0b20 stores the result globally and publishes it through the shell runtime at 0x006d401c via 0x00538e50. A grounded caller sits in the shell_transition_mode path near 0x004831c0 immediately after the GameMessage.win bring-up branch which ties this overlay to world-mode entry rather than generic shell UI.,objdump + strings + caller xrefs +0x004fe120,14,shell_has_settings_window,shell,cdecl,inferred,objdump,4,Returns whether the shared settings window object rooted at 0x006d1350 is currently live. The fileopt settings escape branch and direct shell command wrappers both gate on this before opening SettingsWindow.win again.,objdump + caller xrefs +0x00500640,487,shell_settings_window_construct,shell,thiscall,inferred,objdump + strings,4,Constructs the shared SettingsWindow.win object later stored at 0x006d1350. The helper binds the SettingsWindow.win resource through 0x0053fa50 allocates a page-selection helper at 0x006d1358 walks the 13-entry category table rooted at 0x00622870 and populates the resulting shell control tree with the page labels and ordering data before the window is shown.,objdump + strings +0x00501e50,201,shell_open_settings_window,shell,cdecl,inferred,objdump + strings,4,Lazily allocates and shows the shared SettingsWindow.win shell object at 0x006d1350. When no settings window is live it allocates a 0x78-byte object constructs it through shell_settings_window_construct publishes it to the shell runtime through 0x00538f10 and then notifies the active shell owner at 0x0062be68. Current grounded callers are the direct shell command wrapper at 0x00482b00 the fileopt settings escape branch and one larger shell UI dispatcher branch near 0x0050366a.,objdump + strings + caller xrefs 0x00468d00,222,multiplayer_update_semicolon_name_list,shell,cdecl,inferred,ghidra-headless,4,Adds or removes one player-name token in the semicolon-delimited moderation list rooted at `[ecx+0x905c]`. With mode `1` it appends the supplied token only when not already present writing `;` as the delimiter; with mode `0` it removes the matched token collapses the remainder left and skips an adjacent delimiter when present.,ghidra + rizin + llvm-objdump + strings 0x00468de0,14,multiplayer_session_event_forward_action1_request,shell,unknown,inferred,ghidra-headless,2,Session-event callback wrapper that always forwards request id `1` through multiplayer_set_pending_session_substate with a zero auxiliary payload. The callback clears EDX before the shared setter call and currently lands on a request id that does not yet map to a visible pending substate so this row remains structural.,ghidra + rizin + llvm-objdump 0x00468e00,188,multiplayer_session_event_publish_pair_chat_template,shell,unknown,inferred,ghidra-headless,3,Session-event callback that formats one two-string chat/status line through multiplayer_route_chat_line when the callback status in EDX is zero and the current live session count is not positive. A selector near `[esp+0x214]` chooses the template `%s* %s` `%s %s` or `%s > %s`; the helper length-checks both inputs against the local 0x1f4-byte buffer before formatting and returns without publishing when either string is null or too long.,ghidra + rizin + llvm-objdump + strings @@ -64,6 +90,8 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00469620,52,multiplayer_submit_owner_notified_session_event_text,shell,unknown,inferred,ghidra-headless,3,Submits one caller-supplied text buffer through the active session-event transport using callback multiplayer_session_event_notify_owner_and_queue_action8. The helper first sanitizes the input string into a local 0x100-byte transport record through multiplayer_transport_sanitize_identifier and then forwards that record through multiplayer_transport_submit_text_record with fixed mode arguments `0` and `1`.,ghidra + rizin + llvm-objdump 0x00469660,27,multiplayer_send_session_event_text_selector0,shell,unknown,inferred,ghidra-headless,3,Thin session-event transport wrapper that sends one caller-supplied text pointer through multiplayer_transport_send_selector_text with selector `0` when the pointer is non-null. The current grounded caller is the Multiplayer.win control dispatcher around `0x00469d30`.,ghidra + rizin + llvm-objdump 0x00469680,14,multiplayer_pump_session_event_status,shell,unknown,inferred,ghidra-headless,3,Thin session-event transport wrapper that immediately requests a status pump through multiplayer_transport_request_status_pump on the active transport object at `0x006cd970` and discards one stack argument. Current grounded callers use it after updating Multiplayer.win status text ids `0xe60` and `0xe61`.,ghidra + rizin + llvm-objdump +0x00469700,27,multiplayer_preview_dataset_stage_selected_path,shell,thiscall,inferred,objdump + caller xrefs,3,Small Multiplayer preview-dataset helper that copies one caller-supplied selected path string into the dataset-local staging buffer at `[this+0x8f48]`. Current grounded callers feed it the active session-entry path from the live session list before later preview or launch-side dataset work.,objdump + caller xrefs +0x00469720,221,multiplayer_preview_dataset_service_frame,shell,thiscall,inferred,objdump + caller xrefs,3,"Recurring shell-frame service for the Multiplayer preview dataset rooted at `0x006cd8d8`. When the gating global at `0x006cd910` and the dataset render target at `[this+0x9884]` are live it walks the active session list under `0x006d40d0`, formats one roster or status line per entry through the template at `0x005ce1ac`, and then pushes the accumulated text through the render/update helper at `0x005519f0` with fixed presentation parameters. The current grounded caller is `shell_state_service_active_mode_frame`, which makes this a shell-owned per-frame refresh path for multiplayer preview text rather than a transport I/O loop.",objdump + caller xrefs + strings 0x0046a6c0,307,multiplayer_session_event_publish_registration_field,shell,unknown,inferred,ghidra-headless,3,Switch-driven session-event callback that publishes one Multiplayer.win registration/status field into the destination builder passed on the stack. Depending on selector EDX it emits the local session name from `0x006cec74` the profile text at `0x006cd8d8+0x8e10` the constant `0x2328` the live session count from `0x006d40d0` the field at `[0x006d1270+0x3b6]` the active profile string at `[0x006cec7c+0x44]` or fixed strings such as `Initializing...` `openstaging` and `closedplaying`; unsupported selectors fall back to the fixed token at `0x005c87a8`.,ghidra + rizin + llvm-objdump + strings 0x0046a830,194,multiplayer_session_event_retry_with_random_player_name,shell,unknown,inferred,ghidra-headless,3,Registration-side callback that increments the retry counter at `0x006cd984` and on early retries formats a randomized `RT3Player%d` name into `0x006ae0c0` sanitizes it into a local notification object notifies the current Multiplayer.win owner and forwards that object through multiplayer_transport_set_local_name. On the first retry it also routes request id `5` or `6` through multiplayer_set_pending_session_substate depending on the incoming status flag; after 25 retries it resets `0x006cd984` and `0x006cd974` and calls multiplayer_transport_reset_and_maybe_shutdown instead.,ghidra + rizin + llvm-objdump + strings 0x0046a900,522,multiplayer_register_session_event_callbacks,shell,thiscall,inferred,ghidra-headless,4,Builds and registers the Multiplayer.win session-event callback table rooted at the local block on `[esp+0x28]`. The function seeds slots with multiplayer_session_event_forward_action1_request multiplayer_session_event_publish_pair_chat_template multiplayer_session_event_publish_action2_single_name multiplayer_session_event_publish_action2_pair multiplayer_session_event_forward_action4_request multiplayer_session_event_forward_action7_request multiplayer_session_event_noop_12byte_stub multiplayer_session_event_publish_registration_field multiplayer_session_event_publish_status_value multiplayer_session_event_publish_fixed_status_text multiplayer_session_event_seed_control_id_list multiplayer_session_event_query_session_count multiplayer_session_event_noop_8byte_stub multiplayer_session_event_latch_status_code multiplayer_session_event_notify_owner_and_queue_action8 multiplayer_init_session_event_transport_state and multiplayer_session_event_retry_with_random_player_name. It allocates the transport callback object under `0x006cd970` stages the session name into the local descriptor block and then finishes registration through multiplayer_transport_register_callback_table which in turn routes through multiplayer_transport_attach_callback_table_descriptor multiplayer_transport_enqueue_descriptor_block_record and multiplayer_transport_dispatch_callback_table_binding.,ghidra + rizin + llvm-objdump + strings @@ -75,6 +103,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004ecb20,101,multiplayer_reset_local_session_slot_state,shell,cdecl,inferred,ghidra-headless,4,Resets the local Multiplayer.win session-slot state before window init or add-open-slot flows. The helper marks the local state at `0x006cec7c+0x97` initialized clears the local slot counters at `+0x79` and `+0x7b` zeroes the slot-marker bytes at `+0x87` clears the local summary block at `+0x44` and zero-fills the large session backing block at `0x006d1270` when present.,ghidra + rizin + llvm-objdump 0x004ecb90,191,multiplayer_probe_or_allocate_open_player_slot,shell,cdecl,inferred,ghidra-headless,3,Probes or allocates one open local player-slot marker against the active Multiplayer.win session block at 0x006d1270. In probe mode `ecx=1` the helper checks that the local open-slot count and slot-marker bytes at `0x006cec7c+0x87` still fit within the remote slot counts and occupancy bytes rooted at `session+0x31b` and `session+0x3a3` and returns nonzero only when one additional slot can be claimed. In allocate mode `ecx=0` it finds the first locally empty slot whose remote occupancy byte is nonzero writes marker `0x64+index` into the local slot array increments `0x006cec7c+0x7b` and returns `0xff` on success.,ghidra + rizin + llvm-objdump 0x004ed590,224,multiplayer_sync_staged_text_controls,shell,cdecl,inferred,ghidra-headless,3,Synchronizes the shared Multiplayer.win staged-text buffer into the two mirrored text controls at ids 0xe48 and 0xe5d and then copies the same string back into the active selection buffer at 0x006cec74+0x1ef when it changed. The helper reallocates each control-owned backing string as needed and is used from the larger window initializer pending-status service and one delayed service-loop recovery branch.,ghidra + rizin + llvm-objdump +0x004ed800,109,multiplayer_preview_dataset_construct,shell,thiscall,inferred,objdump + caller xrefs,3,"Constructor-style zero initializer for the large Multiplayer preview-dataset object later stored at `0x006cd8d8`. It clears the leading linkage and mode fields, resets the request and staging words around `0x8f18..0x8f44`, zeroes the shell-mode snapshot slots at `0x9050` and `0x9054`, clears the dataset state word at `0x985c`, seeds `0x9860` to `-1`, and leaves the object ready for the follow-on reset and dispatch paths.",objdump + caller xrefs 0x004ed890,164,multiplayer_schedule_requested_action,shell,cdecl,inferred,ghidra-headless,3,Initializes one requested Multiplayer.win action and resets the shared action globals before later dispatch. The helper writes the requested action id from EDI into 0x006d127c marks the action-active bit at 0x006d1274 clears the pending-step and substate fields at 0x006d1278 0x006d1280 and 0x006d1288 tears down the prior helper object at 0x006d1294 and allocates a fresh 0x10-byte helper. The currently named action writers above it queue action ids 1 and 4 from preview-dataset reset 2 from staged text-entry dialog setup 3 from staged text-entry commit and 5 or 6 from selected-preview follow-up branches.,ghidra + rizin + llvm-objdump 0x004ed940,235,multiplayer_rebuild_open_player_slot_markers,shell,cdecl,inferred,ghidra-headless,3,Rebuilds the local Multiplayer.win open-player slot markers from the active session slot table and republishes the resulting count. The helper clears any existing local slot bytes above `0x64` from `0x006cec7c+0x87` while decrementing `0x006cec7c+0x7b` then walks the remote slot records at `session+0x31b` with count `session+0x3ae`. For each remotely open record it uses multiplayer_probe_or_allocate_open_player_slot to claim the next local marker when capacity remains and then formats the updated open-slot count into shell control `0x6f` with resource id `0xe36`.,ghidra + rizin + llvm-objdump 0x004edc40,145,multiplayer_reset_preview_dataset_and_request_action,shell,cdecl,inferred,ghidra-headless,3,Resets the active Multiplayer.win preview dataset object at 0x006cd8d8 and immediately schedules the next requested action. The helper destroys any existing 0x9898-byte dataset object allocates and constructs a fresh one through 0x004ed800 clears the text control at id 0xe47 and the staged entry buffer at 0x006d11a8 and then queues action id 1 when the caller passes zero or action id 4 when the caller passes a nonzero dataset-related value.,ghidra + rizin + llvm-objdump @@ -101,7 +130,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 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 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 auxiliary 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 +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 0x004821d0,1019,shell_recompute_layout_slots,bootstrap,thiscall,inferred,ghidra-headless,4,Recomputes the shell layout-slot table after resolution or related display selectors change; derives normalized coordinates from static float tables updates 144 slot entries through the shell bundle child at [0x006d4024+0x18] and then commits the refreshed state.,ghidra + rizin 0x00482ec0,1359,shell_transition_mode,bootstrap,thiscall,inferred,ghidra-headless,4,Switches the shell state's active mode at [this+0x08] tearing down any prior mode object selecting one of seven mode-specific handlers and updating globals like 0x006cec78 before notifying the shell bundle through 0x00538e50.,ghidra + rizin 0x005a2d64,101,crt_init_exit_handlers,startup,cdecl,inferred,ghidra-headless,3,Initializes on-exit tables and registers atexit handling before control reaches application startup.,ghidra + rizin @@ -112,10 +141,18 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0053b010,11,bootstrap_mark_runtime_started,bootstrap,cdecl,inferred,ghidra-headless,2,Single-purpose bootstrap helper that flips a process-global started flag to one before branding and shell setup continue.,ghidra + rizin 0x0054e6d0,42,bootstrap_capture_keyboard_state,bootstrap,cdecl,inferred,ghidra-headless,4,Single-purpose bootstrap probe that snapshots the host keyboard state through GetKeyboardState.,ghidra + rizin 0x0055da40,424,bootstrap_probe_system_profile,bootstrap,cdecl,inferred,ghidra-headless,4,Collects GlobalMemoryStatus and CPUID feature bits then stores coarse machine capability flags used by later bootstrap decisions.,ghidra + rizin -0x00507b90,346,geography_info_refresh_category_controls,map,cdecl,inferred,ghidra-headless,3,Refreshes the geography info category controls for the current panel mode stored at 0x00622af4. It emits the six-entry mode selector plus dependent label fields through 0x00540120 and in mode 5 it can seed [this+0x8c] from the current selection path before preview formatting continues.,ghidra + rizin + llvm-objdump -0x00508550,363,geography_info_format_selected_record_summary,map,cdecl,inferred,ghidra-headless,3,Formats the selected geography record summary for the info panel. It looks up the active record index [this+0x8c] in 0x0062b2fc follows secondary data through field +0x173 into 0x0062b268 computes scaled values against current shell state and emits the localized summary block through 0x00540120.,ghidra + rizin + llvm-objdump + strings -0x00508730,292,geography_info_format_preview_panel,map,cdecl,inferred,ghidra-headless,3,Formats the geography info preview panel for the currently selected record stored at [arg_4h+0x8c]. It chooses preview assets like 2DLabel.imb 2DCity.imb 2DVent.imb 2DMist.imb and 2DVolcano.imb and emits localized text blocks through repeated 0x00540120 calls using geography tables rooted at 0x0062b2fc and 0x0062b268.,ghidra + rizin + llvm-objdump + strings -0x00508880,727,geography_info_select_record_and_refresh,map,cdecl,inferred,ghidra-headless,3,Selects one geography record or category then refreshes the preview panel. It stores the requested mode at 0x00622af4 resolves a matching record from the geography tables formats localized headings and detail text calls 0x00508730 and then triggers the surrounding panel refresh path.,ghidra + rizin + llvm-objdump + strings +0x00507b90,346,station_place_refresh_category_controls,shell,cdecl,inferred,objdump + strings + RT3.lng,4,"Refreshes the StationPlace.win category and mode controls for the current placement mode stored at 0x00622af4. The helper now grounds the six top-level category buttons rooted at 0x697c through 0x6981 as `Place a small station` 2197, `Place a medium station` 2198, `Place a large station` 2199, `Place a service tower` 2200, `Place a maintenance facility` 2201, and `Place a non-station building` 2202. It also refreshes the dependent controls around 0x69c8 0x69c9 0x6985 0x6986 and 0x6983 through 0x00540120; current evidence now bounds 0x6985 and 0x6986 as a two-state station-rotation policy toggle keyed by 0x006d1728, where 0x6985 aligns with `When placing the building, it will rotate itself as needed to orient to track or avoid obstacles.` string 2207 and 0x6986 aligns with `When placing the building, it will strictly adhere to the rotation specified by the circle above.` string 2206. In non-station-building mode 5 it can also seed [this+0x8c] from the active StationPlace list control under 0x006d1720 before preview formatting continues.",objdump + strings + RT3.lng + caller xrefs + callsite inspection +0x00508550,363,station_place_format_selected_site_summary,shell,cdecl,inferred,objdump + strings,3,Formats the selected StationPlace target summary for the live tool object. It looks up the active placement record index [this+0x8c] in 0x0062b2fc follows secondary data through field +0x173 into 0x0062b268 combines that with the current staged world coordinates at 0x006d1738 and 0x006d173c and emits the localized summary block through 0x00540120 into the StationPlace.win status area.,objdump + strings + caller xrefs + callsite inspection +0x00508730,292,station_place_format_preview_panel,shell,cdecl,inferred,objdump + strings,4,Formats the StationPlace.win preview panel for the currently selected placement record stored at [arg_4h+0x8c]. It chooses preview assets like 2DLabel.imb 2DCity.imb 2DVent.imb 2DMist.imb and 2DVolcano.imb for control 0x6982 and emits the matching text block through control 0x6984 using the geography tables rooted at 0x0062b2fc and 0x0062b268.,objdump + strings + caller xrefs + callsite inspection +0x00508880,727,station_place_select_category_and_refresh,shell,cdecl,inferred,objdump + strings + RT3.lng,4,"Primary StationPlace.win category and selection refresh helper. It stores the requested placement mode at 0x00622af4, where current grounded evidence now maps 0..5 to small station, medium station, large station, service tower, maintenance facility, and non-station building. For the three station modes it also enables the secondary style strip rooted at 0x6988 0x6989 and 0x698c, where 0x6988 and 0x6989 cycle the current building style and 0x698c displays the active style token built from `StationSml` `StationMed` or `StationLrg` plus one of the six localized architecture styles `Victorian` 2672 `Tudor` 2671 `Southwest` 2670 `Persian` 2669 `Kyoto` 2668 and `Clapboard` 2667; the player-facing tooltip for that strip is `Scroll through building styles.` string 2203. The helper resolves the current selection through 0x00622af0 and 0x00622aec, repopulates the StationPlace list controls at 0x69df and 0x69e3, and then refreshes the preview and category panels through 0x00508730 and 0x00507b90.",objdump + strings + RT3.lng + caller xrefs + callsite inspection +0x00508bb0,510,station_place_world_surface_sync_and_dispatch,shell,thiscall,inferred,objdump + caller xrefs + strings,4,"Shared world-surface helper for the active StationPlace.win tool object. It accepts direct `0x07d6` control traffic from the window dispatcher or falls back to the same shell detail-panel surface looked up through 0x006d0818, rechecks flag bit 0x4 on that control, performs world hit tests through 0x00448ac0, stages world coordinates into 0x006d1738 and 0x006d173c, refreshes the selected-site summary through 0x00508550, and updates the live placement selection globals at 0x00622af0 0x00622aec and 0x006d1740 plus helper objects rooted at [this+0x80] [this+0x84] and [this+0x88]. This makes it the clearest StationPlace-side consumer of the shared main-world interaction surface rather than only a passive status refresh helper.",objdump + caller xrefs + strings + callsite inspection +0x005091b0,967,station_place_window_handle_message,shell,thiscall,inferred,objdump + strings + RT3.lng,4,"Primary message dispatcher for the StationPlace.win tool object at 0x006d1720. It switches over the incoming shell message id then handles the StationPlace control family rooted at category ids 0x697c through 0x6981, now grounded as the player-facing small station, medium station, large station, service tower, maintenance facility, and non-station-building buttons from strings 2197 through 2202. It also handles the style-strip controls at 0x6988 and 0x6989, which cycle the current building-style override used by station categories, the dependent controls around 0x6985 and 0x6986, now bounded as the two station-rotation policy choices from strings 2207 and 2206, the dedicated station-rotation circle control 0x6987, the list controls 0x69df and 0x69e3, and the shared world-surface control 0x07d6. The handler routes category and selection changes through 0x00508880 and 0x00507b90, uses 0x00507d80 for the live station-rotation drag/update branch, and delegates the world-hit-test path through 0x00508bb0. That makes it the clearest grounded owner for StationPlace player-facing tool commands rather than only a constructor plus frame hook.",objdump + strings + RT3.lng + caller xrefs + callsite inspection +0x00509d80,1936,station_place_window_construct,shell,thiscall,inferred,objdump + strings + RT3.lng,4,"Constructs the StationPlace.win world-tool window object later published at 0x006d1720. The constructor seeds the vtable at 0x005d17c0 binds the StationPlace.imb helper asset and StationPlace.win resource through 0x0053d110 and 0x0053fa50 clears local selection and preview fields rooted at [this+0x7c] through [this+0x94], seeds the dedicated station-rotation circle control at 0x6987 through callback 0x00507a90, seeds the list controls 0x69df and 0x69e3, and stores the singleton plus helper handle globally at 0x006d1720 and 0x006d1724. Current evidence ties that 0x6987 branch to the player-facing `Click to rotate the building. You can also use bracket keys [ and ] to rotate buildings.` string 2208 rather than to the older `Building placement center` string 671; current recovered StationPlace code paths do not show a direct live lookup of string id 671 at all, which makes it look more like a stale or legacy label than a surviving control caption in the present window flow. The current grounded caller is the shell detail-panel constructor branch at 0x004dddc4.",objdump + strings + RT3.lng + caller xrefs + callsite inspection +0x0050a530,64,station_place_window_service_frame,shell,thiscall,inferred,objdump + caller xrefs,3,Recurring StationPlace.win service pass for the live station-placement tool object at 0x006d1720. The helper checks the local latch at [this+0x94] plus current shell or world selection state and then delegates one branch into 0x00508bb0 for follow-up station-placement synchronization on the same shared `0x07d6` main-world surface used by the dispatcher when the surrounding world tool remains active. Current grounded callers sit in the same recurring world and shell post-frame hooks used by sibling world-tool windows at 0x004423df 0x00444eda and 0x00445a64.,objdump + caller xrefs + callsite inspection +0x0050d2d0,1245,track_lay_window_refresh_controls,shell,thiscall,inferred,objdump + strings + RT3.lng,4,"Refreshes the visible TrackLay.win control state after mode or preference changes. The helper highlights the three mutually exclusive primary mode buttons rooted at control ids 0x985e 0x985f and 0x9860 from the shared track-lay mode field at 0x00622b0c; current primary evidence now strongly aligns those grounded values as 1=`Lay single track.` string id 2054 4=`Lay double track.` string id 2055 and 0x40=`Bulldoze` string id 1721. The same refresh pass also updates the bridge-type selector family rooted at 0x006cec74+0x138 through controls 0x9861 and above; formats the two wrapped frequency values at 0x006cec74+0x140 and 0x006cec74+0x13c into controls 0x9870 and 0x9871 using the localized `Never` through `Common` string ids 615 through 618; and updates the two boolean preference toggles rooted at 0x006cec74+0x144 and 0x006cec78+0x4c74 through controls 0x986e and 0x986d. Current evidence now strongly aligns that pairing as 0x986e or 0x006cec74+0x144 = `Auto-Hide Trees During Track Lay` strings 1838 and 1839 and 0x986d or 0x006cec78+0x4c74 = `Auto-Show Grade During Track Lay` strings 3904 and 3905: the first toggle lives in the compact track-lay preference block alongside bridge and frequency settings while the second lives in the broader display-runtime block and fits the grade-overlay behavior. The same refresh path also updates the electrify-all action control at 0x9873 and the surrounding status widgets, which makes it the clearest grounded owner for the TrackLay.win status panel rather than only a generic shell redraw.",objdump + strings + RT3.lng + callsite inspection +0x0050e1e0,534,track_lay_window_service_frame,shell,thiscall,inferred,objdump + caller xrefs + strings,4,"Recurring TrackLay.win service pass for the active track-lay tool object at 0x006d1a8c. The helper decrements the local reentry guard at [this+0x87] and when the pass is active it either routes the current track-lay drag state through 0x0050d740 while the grounded `Bulldoze` mode value 0x40 is live in 0x00622b0c or synchronizes the staged world-interaction state back into the live world owner through 0x006cfca8 and 0x0050dce0. The same service family also special-cases control id 0x07d6 through the tool-owned current-control field [this+0x7e], which now strongly suggests that 0x07d6 is the shared main-world interaction surface for TrackLay.win rather than a generic shell-detail button. Current grounded callers sit in the recurring world and shell post-frame hooks at 0x004423ee 0x00444ee9 and 0x00445a73.",objdump + caller xrefs + strings + callsite inspection +0x0050e400,448,track_lay_window_construct,shell,thiscall,inferred,objdump + caller xrefs + strings,4,Constructs the TrackLay.win world-tool window object later published at 0x006d1a8c. The constructor seeds the vtable at 0x005d191c clears the tool-state fields rooted at [this+0x78] [this+0x7d] [this+0x82] and [this+0x87] binds the TrackLay.win resource through 0x0053fa50 refreshes the visible control set through 0x0050dc00 snapshots one world span from 0x0062c120 into 0x006d1a94 and stores the singleton globally before returning. The current grounded caller is the shell detail-panel constructor branch at 0x004ddecd.,objdump + caller xrefs + strings + callsite inspection +0x0050e5c0,3867,track_lay_window_handle_message,shell,thiscall,inferred,objdump + strings + RT3.lng,4,"Primary message dispatcher for the TrackLay.win tool object at 0x006d1a8c. It switches over the incoming shell message id then handles control ids in the TrackLay.win family such as 0x9858 through 0x9874 plus the special world-surface control 0x07d6. The handler uses world hit tests through 0x00448ac0 to arm and release the drag latch at [this+0x7d] on 0x07d6 transitions, routes the active mode through the shared track-lay state at 0x00622b0c including the now-bounded primary values 1=`Lay single track.` 4=`Lay double track.` and 0x40=`Bulldoze`, updates the selected world object path rooted at 0x006cfca8+0x118, and refreshes the tool UI through 0x0050d2d0 0x0050d740 and 0x0050dce0. The same dispatcher also owns the TrackLay.win preference and action controls: it toggles the two boolean track-lay options rooted at 0x006cec74+0x144 and 0x006cec78+0x4c74, where current evidence now strongly aligns the first control branch at 0x985a with `Auto-Hide Trees During Track Lay` and the later `0x006cec78+0x4c74` branch with `Auto-Show Grade During Track Lay`; it also cycles the bridge-type selector family at 0x006cec74+0x138, wraps the two frequency settings at 0x006cec74+0x140 and 0x006cec74+0x13c, and routes the electrify-all command through the localized confirmation and failure strings 3083 3084 3837 and 3900. This makes it the clearest grounded owner for player-facing TrackLay.win commands rather than only a passive status panel.",objdump + strings + RT3.lng + callsite inspection 0x0051d900,155,string_find_substring_ex,support,cdecl,inferred,ghidra-headless,3,Reusable substring finder that returns a pointer to the first matching window in the haystack or null. It precomputes both string lengths then slides across the haystack calling one of two compare helpers depending on the mode flag pushed on the stack; the graphics branch uses it to probe adapter strings for legacy GPU-profile tokens and bootstrap code uses it for startup media or compatibility string checks.,ghidra + rizin + llvm-objdump 0x0051d870,21,bootstrap_seed_tick_count,bootstrap,cdecl,inferred,ghidra-headless,4,Lazily snapshots GetTickCount into a bootstrap-global cache so later subsystems start from a nonzero host tick baseline.,ghidra + rizin 0x0051ebc0,731,shell_reset_display_runtime_defaults,shell,cdecl,inferred,ghidra-headless,3,Resets the global display runtime defaults rooted at 0x006d4024. It clears the large display-settings block under offsets 0x11468a and above seeds default resolution and capability flags from mode 0x006d4028 and reinitializes several shell display toggles before later preset application continues.,ghidra + rizin + llvm-objdump @@ -191,8 +228,9 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0054e3a0,528,shell_controller_window_message_dispatch,shell,stdcall,inferred,objdump,4,Primary window-message ingress for the active shell controller window. The dispatcher branches over low window lifecycle messages handles `WM_KEYDOWN` and `WM_KEYUP` by first updating the shell controller through 0x0051f0c0 or 0x0051f0d0 and then forwarding the transition into shell_input_apply_window_key_transition at 0x0054f290 on the shell input object rooted at 0x006d4018 routes `WM_COMMAND` through 0x0054eb10 routes mouse messages in the `0x0200..0x0208` family through 0x0054ee50 and falls back to `DefWindowProcA` for unhandled cases. This is the first grounded shell-side input ingest path rather than only a generic message drain.,objdump + import table + callsite inspection 0x0054e5d0,88,shell_drain_pending_window_messages,shell,cdecl,inferred,objdump + analysis-context,4,Shared pending-message drain that loops on `PeekMessageA` with remove mode 1 and feeds each dequeued record through `TranslateMessage` and `DispatchMessageA` until the queue is empty. Shell modal waits layout rebuild paths mouse-cursor frame work and the keyboard-toggle helpers all reuse this routine so it sits below the real input handlers rather than serving as the input dispatcher itself.,objdump + analysis-context + import table 0x0054e710,110,shell_input_state_init,shell,thiscall,inferred,objdump + analysis-context,3,Initializes the standalone shell input-state object later stored at 0x006d4018. It zeroes the 0xaa8-byte state block resets counters and flags under +0xa88 through +0xa9c caches host metrics through `GetSystemMetrics` and `GetDoubleClickTime` and clears the per-key state storage that later window-message handlers update.,objdump + analysis-context + import table -0x0054f290,480,shell_input_apply_window_key_transition,shell,thiscall,inferred,objdump + analysis-context,4,Normalizes one `WM_KEYDOWN` or `WM_KEYUP` transition for the shell input object at 0x006d4018. The helper samples `GetKeyboardState` optionally derives an ASCII byte through `ToAscii` updates the 256-byte per-key table starting at [this+0x100] maps selected virtual-key ranges into packed shell input flags at [this+0xa8c] and then forwards the synthesized event record through 0x0054e9c0 for later shell consumers. The shell controller window dispatcher at 0x0054e3a0 is the grounded caller.,objdump + analysis-context + import table + callsite inspection +0x0054f290,480,shell_input_apply_window_key_transition,shell,thiscall,inferred,objdump + analysis-context,4,Normalizes one `WM_KEYDOWN` or `WM_KEYUP` transition for the shell input object at 0x006d4018. The helper samples `GetKeyboardState` optionally derives an ASCII byte through `ToAscii` updates the 256-byte per-key table starting at [this+0x100] and maps selected keyboard scan codes into packed modifier flags at [this+0xa8c]: 0x1d sets or clears bit 0x4 Control 0x2a sets or clears bit 0x2 Left Shift 0x36 sets or clears bit 0x1 Right Shift and 0x38 sets or clears bit 0x20 Alt. It then forwards the synthesized event record through 0x0054e9c0 for later shell consumers. The shell controller window dispatcher at 0x0054e3a0 is the grounded caller.,objdump + analysis-context + import table + callsite inspection 0x0054f4d0,109,shell_input_snapshot_dispatch_state,shell,thiscall,inferred,objdump + analysis-context,3,Captures one filtered snapshot of the current shell input object state into a 0x30-byte caller buffer while temporarily zeroing the nested-dispatch counter at [this+0xa90]. Several shell and cursor consumers use this as the read-side companion to shell_input_apply_window_key_transition optionally passing the snapshot through the callback hook stored at 0x006d4008 before consuming it.,objdump + analysis-context + caller xrefs +0x0054f540,111,shell_input_cursor_inside_active_view,shell,cdecl,inferred,objdump + analysis-context,3,Returns whether the current cursor position should count as being inside the active shell controller view. When controller byte [0x006d4024+0x114226] is already set it returns true immediately; otherwise it samples the host cursor through `GetCursorPos` converts it into client coordinates for the active controller window through `ScreenToClient` and checks that point against the current view bounds selected from the shell controller table at [0x006d4024+0x34] and [0x006d4024+0x11421e]. Current grounded callers are the mouse-cursor mode helper at 0x0053f450 and the shell camera action helper at 0x004e0780 which suggests later world-relative cursor work still reuses the same shell controller path rather than a separate gameplay-only input object.,objdump + analysis-context + import table + caller xrefs 0x0054f640,83,shell_step_global_presentation_phase_scalar,shell,cdecl,inferred,ghidra-headless,2,Steps the shared presentation-phase scalar stored at 0x00d93850 downward by a small constant then clamps the returned value against fixed lower-bound constants. Callout-marker world-anchor and other presentation helpers use this as a common time-varying scalar after one of the nearby setters has seeded the global phase.,ghidra + rizin + llvm-objdump 0x0054f700,12,shell_set_global_presentation_phase_scalar,shell,cdecl,inferred,ghidra-headless,3,Stores one caller-supplied float into the shared presentation-phase scalar at 0x00d93850. Mouse-cursor geographic-label and other presentation helpers seed this global before later batch or marker helpers consume it through 0x0054f640.,ghidra + rizin + llvm-objdump 0x0054f710,729,shell_queue_callout_segment_marker,shell,cdecl,inferred,ghidra-headless,2,Queues one short world-space callout segment or marker packet using the shell zoom table rooted at [0x006d4024+0x11421e] and [0x006d4024+0x34]. The helper derives scaled endpoint deltas from the caller inputs applies flag-controlled clamps from arg_14h and emits three type-0x01 deferred messages through shell_enqueue_deferred_message_type1.,ghidra + rizin + llvm-objdump diff --git a/docs/control-loop-atlas.md b/docs/control-loop-atlas.md index f6a1a70..81b0276 100644 --- a/docs/control-loop-atlas.md +++ b/docs/control-loop-atlas.md @@ -47,37 +47,36 @@ anchor it, and where control is handed to neighboring subsystems. ## Map and Scenario Content Load - Roots: `shell_map_file_entry_coordinator` at `0x00445ac0`, the first grounded world-entry branch `world_entry_transition_and_runtime_bringup` at `0x00443a50`, `shell_map_file_world_bundle_coordinator` at `0x00445de0`, reference-database setup via `map_bundle_open_reference_databases` at `0x00444dd0`, and narrower loaders such as `map_load_geographic_label_database` and `map_load_city_database`. -- Trigger/Cadence: shell tutorial launch, editor or detail-panel file actions, map-scenario open paths, and scenario-text export batch commands. +- Trigger/Cadence: shell tutorial launch, editor or detail-panel file actions through `fileopt.win`, map-scenario open paths, and scenario-text export batch commands. - Key Dispatchers: `shell_map_file_entry_coordinator`, `world_entry_transition_and_runtime_bringup`, `world_runtime_release_global_services`, `shell_map_file_world_bundle_coordinator`, `map_bundle_open_reference_databases`, `map_load_geographic_label_database`, `map_load_city_database`, `scenario_text_export_build_language_file`, `scenario_text_export_report_language_file`, `scenario_text_export_batch_process_maps`. - State Anchors: shell-side file staging buffers at `0x0062bee0` and `0x0062bec4`, shell and mode globals at `0x006cec74` and `0x006cec78`, world object root `0x0062c120`, map bundle state allocated through `0x00530c80`, and geography tables rooted at `0x0062b2fc` and `0x0062b268`. -- Subsystem Handoffs: the broad shell entry coordinator chooses between a full shell mode-transition and world bring-up path versus a sibling `.smp` world-state path. The heavier branch now appears to be the first true shell-to-gameplay handoff: it resets the prior world bundle, allocates the new `0x0062c120` world root from the staged filename, initializes multiple world-facing managers, and only then leaves later map content and runtime stepping to narrower helpers. The lower coordinator still fans into the live-world packaging branch at `0x00446240` or the reference-database bundle load at `map_bundle_open_reference_databases`, which in turn feeds shell preview panels scenario export tooling and later gameplay map state. -- Evidence: function-map map/scenario rows, analysis-context exports for `0x00445ac0`, `0x00445de0`, `0x00443a50`, `0x00434300`, and `0x00444dd0`, plus objdump string evidence for `.gmp`, `.gmx`, `.gmc`, `.gms`, `.smp`, and `Quicksave`. -- Open Questions: the exact user-facing verb split between the `.smp` branch and the `.gmp/.gmx/.gmc/.gms` branch still needs tightening, but the remaining high-value question is no longer whether `0x00443a50` is world entry. It is where the long-lived simulation cadence takes over after this bring-up and whether that cadence still rendezvous with the shell-owned frame path or escapes into a separate gameplay loop. +- Subsystem Handoffs: the shared `fileopt.win` dialog rooted at `0x004dc670` now looks like the shell-side selector above the two broad file coordinators. Its message handler sets `0x006d07f8` for the load or restore side or `0x006d07ec` for the save or package side before the detail-panel transition manager routes into `shell_map_file_entry_coordinator` or `shell_map_file_world_bundle_coordinator`. The former unresolved third flag at `0x006d07f0` is now accounted for too: it escapes into the standalone `SettingsWindow.win` path through `shell_open_settings_window` rather than another map or save verb. The broad coordinators now hand their interactive work through the shared `filerqst.win` helper at `0x004dd010`, and that helper gives the extension split a firmer shape. The paired editor-map path is now grounded as `.gmp` through load mode `4` and save mode `3`. The remaining non-editor families are no longer anonymous either: `.gmc` is the campaign-scenario branch, backed both by the campaign-screen resignation prompt on `0x006cec7c+0xc5` and by the numbered `%s%02d.gmc` save helper at `0x00517c70`; `.gmx` is the sandbox branch, backed by the shell-side `The briefing is not available in sandbox games.` restriction on `0x006cec7c+0x82`; and the default `.gms` branch is therefore the standalone scenario family. When a live runtime world is already active the same helper bypasses those non-runtime extensions and forces the `.smp` runtime-state branch instead. The auxiliary save-side mode `11` is tighter now too: it still maps to `.gmt`, but instead of looking like another gameplay save family it conditionally diverts into the same `.gmt` preview-surface pipeline owned by the Multiplayer preview dataset object at `0x006cd8d8`, and only falls back to the normal reference-bundle path when that dataset object is absent. +- Evidence: function-map map/scenario rows, analysis-context exports for `0x00445ac0`, `0x00445de0`, `0x00443a50`, `0x00434300`, and `0x00444dd0`, plus objdump string and mode-table evidence for `.gmp`, `.gmx`, `.gmc`, `.gms`, `.gmt`, `.smp`, `Quicksave`, the `0x004dd010` mode table at `0x005f3d58`, the auxiliary-owner presence check at `0x00434050`, and the `.gmt` handoff through `0x00469d30`, together with localized string evidence from ids `3018` and `3898`. +- Open Questions: bit `0x1` on both broad coordinators now grounds the Quicksave name seed and the former third `fileopt.win` flag has been ruled out as a file-flow question because it just opens `SettingsWindow.win`. The old broad extension question is mostly resolved: `.gmp` is the editor-map pair, `.gms` is the standalone scenario family, `.gmc` is the campaign-scenario family, `.gmx` is the sandbox family, and `.gmt` is at least bounded as an auxiliary preview-surface branch rather than another gameplay save family. The higher-value global question is no longer whether `0x00443a50` is world entry. It is where the long-lived simulation cadence takes over after this bring-up and whether that cadence still rendezvous with the shell-owned frame path or escapes into a separate gameplay loop. ## Multiplayer Session and Transport Flow -- Roots: Multiplayer.win session-event callback table around `0x00468de0..0x004691d0`, plus the transport object and pending-template paths around `0x00597880..0x0059caf0`. +- Roots: Multiplayer.win session-event callback table around `0x00468de0..0x004691d0`, the Multiplayer preview dataset object at `0x006cd8d8`, and the transport object and pending-template paths around `0x00597880..0x0059caf0`. - Trigger/Cadence: event-driven session callbacks, registered-name updates, and repeated socket I/O service steps. -- Key Dispatchers: session-event wrappers for actions `1`, `2`, `4`, `7`, `8`; `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`, status latch at `0x006cd974`, pending-template list at `[this+0x550]`, dispatch store at `[this+0x55c]`, text-stream buffers at `[this+0x108]` and `[this+0x114]`. -- Subsystem Handoffs: bridges shell/UI status presentation, transport text streams, session state changes, and pending-template completion callbacks. +- Key Dispatchers: session-event wrappers for actions `1`, `2`, `4`, `7`, `8`; `multiplayer_window_init_globals`; `multiplayer_dispatch_requested_action`; `multiplayer_reset_preview_dataset_and_request_action`; `multiplayer_preview_dataset_service_frame`; `multiplayer_load_selected_map_preview_surface`; `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`, preview dataset object at `0x006cd8d8`, preview-valid flag at `0x006ce9bc`, staged preview strings at `0x006ce670` and `[0x006cd8d8+0x8f48]`, Multiplayer.win backing block at `0x006d1270`, status latch at `0x006cd974`, pending-template list at `[this+0x550]`, dispatch store at `[this+0x55c]`, and text-stream buffers at `[this+0x108]` and `[this+0x114]`. +- Subsystem Handoffs: the Multiplayer.win initializer seeds the backing block at `0x006d1270`, later reset paths construct the separate preview dataset at `0x006cd8d8`, and the shell-owned active-mode frame now services that dataset every frame through `multiplayer_preview_dataset_service_frame`. That preview side then publishes roster and status controls through `multiplayer_window_control_dispatch`, loads `.gmt` preview surfaces through `multiplayer_load_selected_map_preview_surface`, and is even reused by the map/save coordinator’s mode-`11` `.gmt` path when the dataset already exists. Beside that preview/UI branch, the transport side still owns text streams, session state changes, and pending-template completion callbacks. - Evidence: `function-map.csv`, `pending-template-store-management.md`, `pending-template-store-functions.csv`. -- Open Questions: unresolved request-id semantics for `1`, `2`, `4`, and `7`; the exact owner loop that repeatedly services transport I/O; and how multiplayer preview data ties back into the shell flow. +- Open Questions: unresolved request-id semantics for `1`, `2`, `4`, and `7`; the exact owner loop that repeatedly services transport I/O; and how far the Multiplayer preview-dataset machinery is reused outside `Multiplayer.win` beyond the currently grounded `.gmt` save-mode hook. ## Input, Save/Load, and Simulation -- Roots: the shell controller window-message ingress `shell_controller_window_message_dispatch` at `0x0054e3a0`, the shell input-state object initialized at `0x006d4018` through `shell_input_state_init` `0x0054e710`, `world_entry_transition_and_runtime_bringup` at `0x00443a50`, the frame-owned cadence `simulation_frame_accumulate_and_step_world` at `0x00439140`, and the lower step family rooted at `simulation_advance_to_target_calendar_point` `0x0040ab50` with periodic branches through `simulation_service_periodic_boundary_work` `0x0040a590`. -- Trigger/Cadence: shell-side input is event-driven by controller-window `WM_*` traffic while post-bring-up gameplay service becomes recurring once a world root exists at `0x0062c120`; elapsed wall-clock time is then accumulated and converted into one or more simulation-step quanta. -- Key Dispatchers: `shell_controller_window_message_dispatch`, `shell_input_apply_window_key_transition`, `shell_input_snapshot_dispatch_state`, `simulation_frame_accumulate_and_step_world`, `simulation_advance_to_target_calendar_point`, the smaller single-step helper at `0x00409e80`, `0x0040a9c0`, `0x0040a910`, and `simulation_service_periodic_boundary_work`. -- State Anchors: shell input object `0x006d4018`, per-key state table starting at `[input+0x100]`, packed shell input flags at `[input+0xa8c]`, nested dispatch counter `[input+0xa90]`, global shell controller `0x006d4024`, active world root `0x0062c120`, accumulated leftover simulation time at `[this+0x4c80]`, shell and mode globals at `0x006cec74`, `0x006cec78`, and `0x006cec7c`, world manager collections at `0x0062be10`, `0x006ceb9c`, `0x006cfcbc`, `0x006cec20`, and `0x0062bae0`, plus the packed calendar-like tuple fields around `[this+0x0d]`, `[this+0x0f]`, `[this+0x11]`, and `[this+0x14]`. -- Subsystem Handoffs: the controller window dispatcher now looks like the first grounded input ingress. It translates keyboard and mouse `WM_*` traffic into shell controller state and the separate input object at `0x006d4018`; read-side cursor and shell consumers later snapshot that object through `shell_input_snapshot_dispatch_state`. After world entry the frame-owned cadence computes how much simulation time should elapse and repeatedly hands that budget into `simulation_advance_to_target_calendar_point`; the step helper then advances the world in coarse or fine increments, enters the periodic maintenance family when boundary conditions hit, notifies the live world root through `0x00450030`, and returns to the frame owner for later shell-facing and world-facing follow-up work. -- 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`, `world_entry_transition_and_runtime_bringup`, `simulation_frame_accumulate_and_step_world`, `simulation_advance_to_target_calendar_point`, and `simulation_service_periodic_boundary_work`, plus analysis-context exports for the shell input cluster and the simulation cluster around `0x00439140`, `0x0040ab50`, and `0x0040a590`. -- Open Questions: whether gameplay continues to reuse this shell controller and input object path or hands off to a deeper world-mode input branch; the exact public semantics of the packed simulation tuple fields need tightening; and the save/load family still needs a cleaner user-facing split between autosave or package work and regular simulation stepping. +- Roots: the shell controller window-message ingress `shell_controller_window_message_dispatch` at `0x0054e3a0`, the shell input-state object initialized at `0x006d4018` through `shell_input_state_init` `0x0054e710`, the saved-world restore path `world_load_saved_runtime_state_bundle` at `0x00446d40`, the live-world save path `world_runtime_serialize_smp_bundle` at `0x00446240`, `world_entry_transition_and_runtime_bringup` at `0x00443a50`, the frame-owned cadence `simulation_frame_accumulate_and_step_world` at `0x00439140`, the recurring `GameMessage.win` service branch through `game_message_window_service_if_present` `0x004e0720`, the world-facing `GameUppermost.win` overlay branch ensured by `shell_ensure_game_uppermost_window` `0x004e0e40` and serviced through `game_uppermost_window_service_world_hotspot_band` `0x004e0780`, and the lower step family rooted at `simulation_advance_to_target_calendar_point` `0x0040ab50` with periodic branches through `simulation_service_periodic_boundary_work` `0x0040a590`. +- Trigger/Cadence: shell-side input is event-driven by controller-window `WM_*` traffic while save or load work is triggered either directly from shell commands or through the `fileopt.win` branch flags into the `.smp` runtime-state family; post-bring-up world service becomes recurring once a world root exists at `0x0062c120`, but the current grounded top-level cadence still remains the shell-owned `shell_service_pump_iteration` path, which calls `simulation_frame_accumulate_and_step_world` directly and lets it accumulate elapsed wall-clock time into one or more simulation-step quanta. +- 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`, `station_place_world_surface_sync_and_dispatch`, `station_place_window_handle_message`, `track_lay_window_refresh_controls`, `track_lay_window_service_frame`, `track_lay_window_handle_message`, `simulation_advance_to_target_calendar_point`, the smaller single-step helper at `0x00409e80`, `0x0040a9c0`, `0x0040a910`, and `simulation_service_periodic_boundary_work`. +- State Anchors: shell input object `0x006d4018`, per-key state table starting at `[input+0x100]`, packed shell input flags at `[input+0xa8c]` now grounded as Right Shift `0x1`, Left Shift `0x2`, Control `0x4`, and Alt `0x20`, nested dispatch counter `[input+0xa90]`, global shell controller `0x006d4024`, active world root `0x0062c120`, `GameMessage.win` object `0x006d081c`, `GameUppermost.win` overlay object `0x006d0820`, `StationPlace.win` tool object `0x006d1720`, `TrackLay.win` tool object `0x006d1a8c`, accumulated leftover simulation time at `[this+0x4c80]`, shell and mode globals at `0x006cec74`, `0x006cec78`, and `0x006cec7c`, world manager collections at `0x0062be10`, `0x006ceb9c`, `0x006cfcbc`, `0x006cec20`, `0x0062bae0`, and `0x006acd34`, plus the packed calendar-like tuple fields around `[this+0x0d]`, `[this+0x0f]`, `[this+0x11]`, and `[this+0x14]`. +- Subsystem Handoffs: the controller window dispatcher now looks like the first grounded input ingress. It translates keyboard and mouse `WM_*` traffic into shell controller state and the separate input object at `0x006d4018`; read-side cursor and camera helpers later snapshot that object through `shell_input_snapshot_dispatch_state` and gate world-relative interaction through `shell_input_cursor_inside_active_view`. Current grounded consumers around `0x00478cb0`, `0x004e0780`, `0x0053f450`, and `0x0053fe90` still sit on the shell controller path and consult `0x006d4024` or the world owner at `0x0062be68`, so there is still no evidence for a distinct gameplay-only input object after world entry. Instead, the first deeper world-mode interaction branch now looks like a shared world-view coordinator layered on top of the same shell-fed input state. Shell_transition_mode ensures the `GameUppermost.win` object at `0x006d0820`; its message dispatcher `game_uppermost_window_handle_message` owns the narrow action band `0x7918` through `0x7921`; and the recurring service helper `game_uppermost_window_service_world_hotspot_band` rate-limits those hotspot actions, rechecks `shell_input_cursor_inside_active_view`, and then pans the live world view through `world_view_pan_relative_offset_in_camera_plane` `0x0043d130`. The same lower setter family is also reached from the cursor-drag path through `world_view_apply_screen_delta_to_focus_position` `0x0043d0c0`. Above both of those sits the larger recurring service `world_view_service_shell_input_pan_and_hover` `0x0043db00`, which now has one grounded keyboard branch beneath it: `world_view_service_keyboard_turn_pan_and_zoom_bindings` `0x0043d740`. That helper resolves four binding-pair families from the shell input table via `0x0054e7d0`, and the localized labels are now grounded from `Data/Language/RT3.lng`: `Camera Forward` and `Camera Backward` feed the first signed pan channel, `Camera Left` and `Camera Right` feed the second signed pan channel, `Camera Zoom In` and `Camera Zoom Out` feed the signed zoom-step channel that `0x0043db00` smooths into `world_view_step_zoom_bucket` `0x0043cc30`, and `Camera Rotate Left` plus `Camera Rotate Right` feed the continuous heading-turn branch through `0x0043c810`. The setup side is now better bounded too: `world_view_seed_keyboard_binding_slot_pairs` at `0x00439e40` seeds the eight slot pairs at `[this+0x0a6]` through `[this+0x0e2]` from the global action-binding registry through `0x0045f370` using the distinct registry keys `0x0043d2a0` through `0x0043d310`, and the registration block at `0x00460769` through `0x004608e7` shows those roots are defaulted to the expected Up Down Left and Right virtual keys before runtime polling begins. Beneath that camera stack, the enclosing frame path now has one grounded non-view sidecar: after `0x0043db00` it reads the active controller-view object pointer at `[0x006d4024+0x18]+0x366e`, compares it against the latched target at `[frame_owner+0x66a2]`, fires exit and enter-style vtable callbacks on pointer changes through slots `+0x64` and `+0x60`, and only latches the new object when the object passes its own slot `+0x1c` availability test and shell detail control id `0x07d6` on `0x006d0818` has flag bit `0x4`. That `0x07d6` gate is now more bounded than before: the dedicated `TrackLay.win` tool family rooted at `0x006d1a8c` special-cases the same control id in both `track_lay_window_service_frame` and `track_lay_window_handle_message`, uses world hit tests through `0x00448ac0` to arm and release a drag latch on that surface, and routes the resulting command work through the shared track-lay mode state at `0x00622b0c`. The surrounding `track_lay_window_refresh_controls` pass now shows that this is not just one isolated drag handler: the same tool family owns three mutually exclusive primary mode buttons at `0x985e` `0x985f` and `0x9860`, and current primary evidence now bounds those values as `Lay single track.` `0x1`, `Lay double track.` `0x4`, and `Bulldoze` `0x40` from the localized strings 2054 2055 and 1721 plus the matching control-routing branches in `track_lay_window_handle_message`. The same family also owns a bridge-type preference selector rooted at `0x006cec74+0x138`, two wrapped `Never` through `Common` frequency settings at `0x006cec74+0x140` and `0x006cec74+0x13c`, two boolean track-lay preference toggles, and the electrify-all-track action path. Those last two toggles are now tighter than before: current evidence strongly aligns control `0x986e` and state `0x006cec74+0x144` with `Auto-Hide Trees During Track Lay` from strings 1838 and 1839, while control `0x986d` and state `0x006cec78+0x4c74` align with `Auto-Show Grade During Track Lay` from strings 3904 and 3905. That mapping is still evidence-backed rather than absolutely direct from a recovered resource table, but the state ownership and control order now make it the strongest current fit. That makes `0x07d6` look like the shared main-world interaction surface inside a broader TrackLay world-command subsystem, not an unrelated detail button. The neighboring `StationPlace.win` family is now grounded on that same surface too: the shell detail-panel constructor family allocates it through `station_place_window_construct` at `0x00509d80`, publishes it at `0x006d1720`, services it each frame through `station_place_window_service_frame` at `0x0050a530`, and routes player-facing commands through `station_place_window_handle_message` at `0x005091b0`. That dispatcher special-cases the same `0x07d6` control, and the shared helper `station_place_world_surface_sync_and_dispatch` at `0x00508bb0` either accepts that direct surface traffic or falls back to the same detail-panel control looked up through `0x006d0818`, rechecks flag bit `0x4`, hit-tests the world through `0x00448ac0`, stages world coordinates into `0x006d1738` and `0x006d173c`, refreshes the selected-site summary through `station_place_format_selected_site_summary`, and updates the live station-placement selection state at `0x00622af0`, `0x00622aec`, and `0x006d1740`. Together with `station_place_select_category_and_refresh` `0x00508880`, `station_place_refresh_category_controls` `0x00507b90`, and `station_place_format_preview_panel` `0x00508730`, that makes StationPlace a second grounded consumer of the shared main-world interaction surface rather than only a sibling constructor plus frame hook. The StationPlace control semantics are now tighter too: the top category strip at `0x697c` through `0x6981` now grounds as small station, medium station, large station, service tower, maintenance facility, and non-station building from `RT3.lng` strings 2197 through 2202. For the three station categories only, the secondary strip at `0x6988` and `0x6989` plus display field `0x698c` no longer looks like another placement mode family; it is a building-style scroller. The click handlers on `0x6988` and `0x6989` cycle the style override in `0x00622aec`, and the display path builds the active style token from `StationSml`, `StationMed`, or `StationLrg` plus the localized architecture styles `Victorian`, `Tudor`, `Southwest`, `Persian`, `Kyoto`, and `Clapboard` from `RT3.lng` ids 2672 through 2667. One layer lower, the remaining opaque controls are now much tighter: `0x6985` and `0x6986` are no longer a generic assist toggle but the two station-rotation policy choices from strings 2207 and 2206, switching between auto-orienting the building to track or obstacles and strictly obeying the rotation specified by the circle above. The dedicated control at `0x6987` is the station-rotation circle itself, wired through callback `0x00507a90` and aligned with `Click to rotate the building. You can also use bracket keys [ and ] to rotate buildings.` string 2208. That matches the lower behavior too: when the strict-rotation choice is off, both preview and commit paths route staged coordinates through `0x00508040`, which performs the extra orientation search before validation; when strict rotation is on, that pass is skipped and the current angle in `0x006d172c` is used directly. The direct shell UI also exposes the same discrete view-step family through `world_view_step_heading_quadrant` `0x0043cb00` and `world_view_step_zoom_bucket` `0x0043cc30`. The neighboring gating predicates `world_view_should_drive_primary_pan_channel` and `world_view_should_drive_secondary_pan_channel` test packed shell input bits `0x3`, and `shell_input_apply_window_key_transition` now grounds those bits as the left and right Shift modifiers from scan codes `0x2a` and `0x36`. That means cursor drag, overlay hotspots, held Shift state, direct keyboard turn/pan/zoom bindings, the TrackLay and StationPlace world-command surfaces, and at least one frame-owned hover or focus-target branch all converge under the same shell-fed world-mode input path rather than a separate gameplay-input stack. +- Evidence: function-map rows for `shell_controller_window_message_dispatch`, `shell_drain_pending_window_messages`, `shell_input_state_init`, `shell_input_apply_window_key_transition`, `shell_input_snapshot_dispatch_state`, `shell_input_cursor_inside_active_view`, `world_load_saved_runtime_state_bundle`, `world_runtime_serialize_smp_bundle`, `world_entry_transition_and_runtime_bringup`, `simulation_frame_accumulate_and_step_world`, `game_message_window_service_if_present`, `game_message_window_service_frame`, `shell_ensure_game_uppermost_window`, `game_uppermost_window_construct`, `game_uppermost_window_handle_message`, `game_uppermost_window_service_world_hotspot_band`, `world_view_set_focus_position_xyz`, `world_view_apply_screen_delta_to_focus_position`, `world_view_pan_relative_offset_in_camera_plane`, `world_view_seed_keyboard_binding_slot_pairs`, `world_view_service_keyboard_turn_pan_and_zoom_bindings`, `world_view_step_heading_quadrant`, `world_view_step_zoom_bucket`, `world_view_should_drive_primary_pan_channel`, `world_view_should_drive_secondary_pan_channel`, `world_view_service_shell_input_pan_and_hover`, `station_place_refresh_category_controls`, `station_place_format_selected_site_summary`, `station_place_format_preview_panel`, `station_place_select_category_and_refresh`, `station_place_world_surface_sync_and_dispatch`, `station_place_window_handle_message`, `station_place_window_construct`, `station_place_window_service_frame`, `track_lay_window_refresh_controls`, `track_lay_window_construct`, `track_lay_window_service_frame`, `track_lay_window_handle_message`, and `simulation_service_periodic_boundary_work`, plus the shell-input disassembly around `0x0054f290`, the world-view setup and service branches around `0x00439e40`, `0x0043d740`, `0x0043db00`, `0x0043cb00`, and `0x0043cc30`, the StationPlace.win constructor plus category, dispatcher, rotation-circle, shared-world-surface, preview-build, and recurring service branches around `0x00507a90`, `0x00507b90`, `0x00508550`, `0x00508730`, `0x00508880`, `0x00508bb0`, `0x005091b0`, `0x00509d80`, and `0x0050a530`, the StationPlace string cluster `Place a small station` 2197 `Place a medium station` 2198 `Place a large station` 2199 `Place a service tower` 2200 `Place a maintenance facility` 2201 `Place a non-station building` 2202 `Scroll through building styles.` 2203 `When placing the building, it will strictly adhere to the rotation specified by the circle above.` 2206 `When placing the building, it will rotate itself as needed to orient to track or avoid obstacles.` 2207 `Click to rotate the building. You can also use bracket keys [ and ] to rotate buildings.` 2208 and the architecture-style labels `Clapboard` 2667 `Kyoto` 2668 `Persian` 2669 `Southwest` 2670 `Tudor` 2671 and `Victorian` 2672, the TrackLay.win constructor and dispatcher family around `0x0050d2d0`, `0x0050e400`, `0x0050e1e0`, and `0x0050e5c0`, the localized `Never` through `Common` strings 615 through 618, the track-lay strings `Bulldoze` 1721 `Lay single track.` 2054 `Lay double track.` 2055 and 3114, the TrackLay preference strings `Auto-Hide Trees During Track Lay` 1838 `If 'Auto-Hide Trees During Track Lay' is checked, trees will automatically be reduced to small stumps whenever you are in track laying mode.` 1839 `Auto-Show Grade During Track Lay` 3904 and `If 'Auto-Show Grade During Track Lay' is checked, you'll see the grade number over the track while laying track - useful for trying to keep your slopes to a minimum.` 3905, the electrify-all confirmation and failure strings 3083 3084 3837 and 3900, the binding-registry lookup path at `0x0045f370`, the registration block at `0x00460769` through `0x004608e7`, and the localized labels in `Data/Language/RT3.lng` ids `3466` through `3473`. +- Open Questions: no separate outer gameplay loop is grounded above `simulation_frame_accumulate_and_step_world` yet and no deeper gameplay-only input object is grounded either, but the first deeper world-mode interaction branch is now better bounded: `GameUppermost.win` hotspots, cursor drag, held Shift state, discrete shell view-step commands, direct keyboard turn/pan/zoom bindings, the `TrackLay.win` and `StationPlace.win` world-command surfaces, and a frame-owned hover or focus-target transition branch all feed the same shell-controller-backed path. The remaining uncertainty has moved farther from basic ownership: the hover-target branch clearly exists, and `0x07d6` now looks like the shared main-world interaction surface rather than a generic detail button for one tool family only. The next unresolved layer is narrower and more semantic: the `TrackLay.win` family now clearly owns `Lay single track.` `Lay double track.` and `Bulldoze` as its three primary modes, its bridge selector, its wrapped frequency preferences, and a strongly aligned pair of `Auto-Hide Trees During Track Lay` and `Auto-Show Grade During Track Lay` toggles; the `StationPlace.win` family now clearly owns its six top-level category buttons, the station-style scroller, and the station-rotation controls; and the packed simulation tuple fields remain semantically open. The older `Building placement center` string 671 no longer looks like a live StationPlace control label in the current recovered flow, because the active constructor, preview, refresh, and dispatcher paths all use neighboring ids such as 669 and 2208 without a direct recovered lookup of 671. On save or load the broad serialize-versus-restore split is now grounded, the non-Quicksave `.gmp/.gmx/.gmc/.gms` families are separated, and the auxiliary `.gmt` path is at least bounded to the preview-surface side owner. The higher-value shell-facing gap has therefore shifted upward to subsystem ownership, especially the outer multiplayer transport and service cadence. ## Next Mapping Passes -- Clarify the user-facing split between the `.smp` branch and the `.gmp/.gmx/.gmc/.gms` branch under `shell_map_file_entry_coordinator`. +- Identify the exact transport-side owner loop that repeatedly services multiplayer I/O and dispatch-store work now that the preview dataset is grounded under `Multiplayer.win`. - Identify the owner loop that repeatedly services multiplayer transport I/O and dispatch-store work. -- Determine whether gameplay keeps using `shell_controller_window_message_dispatch` and the `0x006d4018` input object or hands off to a deeper world-mode input branch after world entry. -- Ground the first gameplay save/load dispatcher and tie it back to the already-mapped `.smp` and live-world packaging branch. +- 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.