diff --git a/RT2.LOG b/RT2.LOG new file mode 100644 index 0000000..d2703fc Binary files /dev/null and b/RT2.LOG differ diff --git a/artifacts/exports/rt3-1.06/function-map.csv b/artifacts/exports/rt3-1.06/function-map.csv index f750c22..89a4512 100644 --- a/artifacts/exports/rt3-1.06/function-map.csv +++ b/artifacts/exports/rt3-1.06/function-map.csv @@ -78,6 +78,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0041d550,574,locomotive_era_and_engine_type_pass_company_policy_gate,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection + engine-type correlation,2,"Policy gate beneath the preferred-locomotive chooser and its non-electric fallback. The helper operates on one locomotive-era or availability record whose linked locomotive id sits at `[this+0x126]`. On the fuller policy path, reached when record field `[this+0x41]` is `2` or `3`, it first respects several scenario-state locks rooted at `[0x006cec74+0x180]`, `[0x006cec78+0x4c8c]`, `[0x006cec7c+0x82]`, and `[0x006cec74+0x247]`, then resolves the linked locomotive record from `0x006ada84` and dispatches its engine-type dword `[locomotive+0x10]` across three scenario opinion slots through `scenario_state_sum_issue_opinion_terms_raw` `0x00436710`: `0x1c6`, `0x1c7`, and `0x1c8`, which current evidence now best aligns with the steam, diesel, and electric lanes. It also special-cases the locomotive stem at `[locomotive+0x34]` against the local string `WhaleL`; current data-file correlation now ties that stem to the `Orca NX462` locomotive family and its `WhaleL_NE` asset set, and when that compare hits the helper explicitly zeros the accumulated issue-opinion result before the later availability checks, so that family loses the positive-opinion shortcut rather than taking a bonus branch. It then consults one neighboring locomotive-derived issue or policy id through `0x00442a85`, and applies a late scenario availability triplet from `[0x006cec78+0x4c97..0x4c99]` against three per-record bytes `[this+0x30..0x32]` plus record field `[this+0x7b]`. That triplet now has a stronger player-facing read: the same three scenario bytes are the live editor-policy fields owned by `map_editor_locomotive_availability_panel_construct` `0x004cd680` and `map_editor_locomotive_availability_panel_handle_message` `0x004cf0d0`, and their localized labels `2863..2865` are `All Steam Locos Avail.`, `All Diesel Locos Avail.`, and `All Electric Locos Avail.`. The current gate is narrower than a plain override: when the issue-opinion result stays positive and none of those three editor bytes are enabled, that positive result alone seeds the local availability flag; but once any of the editor family bytes is nonzero, the helper instead requires one matching intersection between the per-record family bytes `[this+0x30..0x32]` and the corresponding scenario bytes `0x4c97..0x4c99`. Independent of that family check, record field `[this+0x7b]` can still carry the path into the later year-window gate. On the simpler path it falls straight to an era-window gate using the current scenario year with floor `0x726` against `[this+0x105]` and `[this+0x109]`, plus one current-month-like check from `[0x006cec78+0x0f]`. The helper returns `1` when the era and engine family pass those combined scenario, opinion, availability, and year gates; otherwise `0`. Current grounded callers are `company_select_preferred_available_locomotive_id` `0x004078a0` and `locomotive_collection_select_best_era_matched_non_electric_fallback_id` `0x00461cd0`.","objdump + caller xrefs + callsite inspection + engine-type correlation + year-window correlation + scenario-gate correlation + editor-locomotive-availability correlation + WhaleL carveout correlation + engine-data correlation" 0x00417790,160,map_angle_rotate_grid_offset_pair_into_world_offset_pair,map,cdecl,inferred,objdump + callsite inspection + math-table correlation,2,"Small angle-table rotation helper beneath the placement projection family. The helper normalizes the caller-supplied heading float into the engine's cyclic angle domain, indexes one sine or cosine-like basis table under `0x006d4024`, and then applies that basis pair to the caller-supplied X or Y grid offsets before writing the rotated world-space offset pair through the two out-pointers. Current grounded caller is `placed_structure_project_candidate_grid_extent_offset_by_rotation` `0x00417840`, so this now looks like the low-level offset-rotation helper rather than a generic trig wrapper.","objdump + callsite inspection + math-table correlation" 0x00417840,205,placed_structure_project_candidate_grid_extent_offset_by_rotation,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Projects one candidate-sized local grid extent into rotated world-space X or Y offsets for placement and mutation previews. The helper resolves the caller-supplied placed-structure id through the current collection, pulls one local grid basis pair through `0x00413d80`, reads the linked candidate footprint bytes `[candidate+0xb8]` and `[candidate+0xb9]`, converts those grid extents into local offset terms, and then re-enters `map_angle_rotate_grid_offset_pair_into_world_offset_pair` `0x00417790` with the caller-supplied heading float to produce the rotated output pair. Current grounded callers include the city-connection placement chooser `0x00402cb0`, the placed-structure local rebuild lane at `0x0040de78`, subtype-`1` placement validation inside `0x004197e0`, and later world-side update branches at `0x00417b6f`, `0x00417e27`, `0x0041a250`, `0x0041a615`, `0x004802c6`, `0x00480875`, and `0x00480d50`. This now looks like the shared projected-footprint offset helper beneath placement validation rather than an unnamed geometry routine.","objdump + caller xrefs + callsite inspection + placement-correlation" +0x00417b40,986,route_entry_collection_try_reuse_covering_entry_for_site_coords_and_heading,map,thiscall,inferred,objdump + caller xrefs + local disassembly + callsite inspection,3,"Tries to reuse one already-existing route entry from the global route-entry collection `0x006cfca8` for a caller-supplied site id, world-space point, and heading instead of synthesizing a new endpoint entry. The helper first projects the current candidate footprint through `placed_structure_project_candidate_grid_extent_offset_by_rotation` `0x00417840`, probes the route-entry collection through `0x00494cb0`, and then subjects the returned entry plus its linked neighbors at `[entry+0x206/+0x20a/+0x20e]` to a tighter compatibility screen: `[entry+0x226]` must be clear, `[entry+0x222]` must be unset or already owned by the same site id, `[entry+0x20e]` must be `-1`, and the neighboring entries cannot already point back through the same side-link pattern selected by byte `[entry+0x201]`. When a candidate survives, the helper computes one accepted local heading and anchor offset through `0x0048bb40`, `0x005a1390`, `0x005a152e`, `0x0048a1a0`, `0x0048a1c0`, and `0x0051db80`, writes the accepted world-space pair and heading back through the caller out-pointers, optionally stores the reused route-entry id through stack arg `+0x2c`, and returns `1`; otherwise it returns `0`. Current grounded callers are the linked-site constructor `0x00480210`, the linked-site runtime refresh owner `0x00480710`, the broader route-anchor chooser around `0x0041a137`, and the StationPlace orientation-search helper `0x00508040`, so this is the safest current read for the reusable covering-route-entry search path rather than another route-synthesis owner.","objdump + caller xrefs + local disassembly + route-entry reuse correlation + linked-site correlation + station-place correlation" 0x004185a0,100,world_grid_toggle_flagged_mask_bit0_for_nonsentinel_rect_samples,map,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Small world-grid mask helper beneath the neighboring projected-rectangle raster family. The helper walks one caller-supplied rectangle from the four dwords rooted at stack arg `+0x04`, reads the aligned float sample band from the caller buffer at stack arg `+0x08`, skips cells whose sample is still the sentinel `0x497423f0`, and otherwise toggles bit `0x01` in the grid-byte mask rooted at `[0x0062c120+0x2135]` by XORing it with the low bit of the caller-supplied byte flag at stack arg `+0x0c`. Current grounded callers are the higher projected-rectangle workers at `0x00418610`, `0x00418a60`, and `0x00418d40`, so this is now bounded as a non-sentinel mask-toggle helper rather than another generic grid writer.","objdump + caller inspection + local disassembly + grid-mask correlation" 0x00418610,584,world_grid_refresh_projected_rect_sample_band_and_flag_mask,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared projected-rectangle world-grid helper above the flagged-region float-stats refresher `0x00415020` and the non-sentinel mask-toggle helper `0x004185a0`. The function resolves one placed-structure record from the caller-supplied id, optionally clears an out flag, validates the current global scan rectangle at `0x0062b7a8..0x0062b7b4` against the live world bounds, and then derives the two boolean mode inputs for `0x00415020` from the linked candidate helpers `0x0040cc80`, `0x0040cc60`, and `0x0040cc40`. On success it repopulates the temporary float band at `0x0062b7d0` by sampling every cell in the rectangle through `0x00448aa0`, publishes the rectangle through `0x0044d410`, and on the single-sample path re-enters `0x004185a0` to toggle the corresponding bit-mask cells. The richer branch also probes the current candidate subtype and per-candidate flags, checks local neighborhood acceptance through `0x00414c50`, samples one midpoint float through `0x00448bd0`, and stamps one or more world-grid cells through `0x0044dca0`. Current grounded callers are the neighboring placed-structure runtime helper at `0x00418be0` and the placement validator `placed_structure_validate_projected_candidate_placement` `0x004197e0`, so the safest current read is a projected-rectangle sample-band and flag-mask refresh pass rather than a generic float scan.","objdump + caller inspection + local disassembly + world-grid sample-band correlation + placement-validator correlation" 0x00419110,234,placed_structure_collection_refresh_local_runtime_side_state_in_rect_from_cell_bucket_map,map,cdecl,inferred,objdump + caller xrefs + local disassembly + bucket-map correlation,3,"Rectangular placed-structure refresh wrapper over a hashed per-cell bucket map. The helper clamps the caller rectangle against live world dimensions `[0x0062c120+0x2155/+0x2159]`, packs each cell key as `(row << 16) | col`, resolves one bucket head through the caller-supplied map root at `[arg0+0x88]` and the shared hash lookup `0x0053dae0`, and then walks the returned linked chain. For every resolved bucket entry it forwards the stored coordinate pair from `[entry+0x04/+0x08]` plus two zero stack flags into `placed_structure_set_world_coords_and_refresh_local_runtime_side_state` `0x0040eba0` on the current placed-structure owner carried by that entry, so the current effect is a local-runtime side-state refresh across every bucketed site in the rectangle rather than a generic collection iterator. Current grounded caller is the edit-side branch at `0x004bc851`, immediately after the neighboring nibble and companion-float mutations, so this is the safest current read for the bucket-map-driven rect refresh wrapper rather than another world-grid brush helper.","objdump + caller xrefs + local disassembly + bucket-map correlation + local-runtime-side-state correlation" @@ -93,7 +94,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0041ac40,6,city_database_entry_true_stub_vtable_5c9750_slot0,map,thiscall,inferred,objdump + vtable scan + local disassembly,1,"Tiny literal-true virtual slot adjacent to `0x0041ac30` in the city-database-entry table `0x005c9750`. The helper returns `1` in `EAX` and exits immediately. Current evidence grounds it only as a constant-return slot.","objdump + vtable scan + local disassembly" 0x0041ac50,6,city_database_entry_true_stub_vtable_5c9750_slot1,map,thiscall,inferred,objdump + vtable scan + local disassembly,1,"Second tiny literal-true virtual slot adjacent to `0x0041ac30` in the city-database-entry table `0x005c9750`. The helper returns `1` in `EAX` and exits immediately. Current evidence grounds it only as a constant-return slot.","objdump + vtable scan + local disassembly" 0x0041f5c0,134,runtime_object_vtable_5c9a60_load_tagged_payload_and_build_dynamic_helper_field_0x37f,map,thiscall,inferred,objdump + vtable scan + local disassembly + sibling-table correlation,2,"Payload-side virtual slot in the sibling runtime-object table rooted at `0x005c9a60`. The helper clamps scalar `[this+0x31b]` to at least `1.0`, clears `[this+0x317]` when that clamp fires, reloads the shared tagged string-triplet payload through `0x00455fc0`, allocates one `0x88`-byte helper through `0x0053b070`, constructs that helper through `0x00518b90`, stores it into `[this+0x37f]`, and then forwards the caller-supplied bundle or stream context into that helper through `0x00518680`. The function returns the accumulated size from the payload reload plus helper load. Current evidence keeps the subtype name open, but the ownership of dynamic helper field `[this+0x37f]` is now grounded.","objdump + vtable scan + local disassembly + sibling-table correlation + dynamic-helper correlation" -0x0041f650,31,runtime_object_vtable_5c9a60_load_tagged_string_triplet_and_forward_stream_to_dynamic_helper_0x37f,map,thiscall,inferred,objdump + vtable scan + local disassembly + sibling-table correlation,2,"Small load-side virtual slot in the same sibling runtime-object table `0x005c9a60`. The helper reloads the tagged string-triplet payload through `0x004559d0`, then forwards the same caller-supplied bundle or stream context into helper `[this+0x37f]` through `0x00517d90`. The safest current read is a tagged string-triplet load plus dynamic-helper import wrapper over field `[this+0x37f]`, not a broader collection rebuild.","objdump + vtable scan + local disassembly + sibling-table correlation + dynamic-helper correlation" +0x0041f650,31,runtime_object_vtable_5c9a60_serialize_tagged_string_triplet_and_forward_stream_to_dynamic_helper_0x37f,map,thiscall,inferred,objdump + vtable scan + local disassembly + sibling-table correlation,2,"Small stream-side virtual slot in the same sibling runtime-object table `0x005c9a60`. The helper first emits the tagged string-triplet payload through `0x004559d0`, then forwards the same caller-supplied bundle or stream context into helper `[this+0x37f]` through `0x00517d90`. Current evidence now only grounds it as a tagged string-triplet serializer plus dynamic-helper wrapper over field `[this+0x37f]`, not as a broader collection rebuild.","objdump + vtable scan + local disassembly + sibling-table correlation + dynamic-helper correlation" 0x0041f680,25,runtime_object_vtable_5c9a60_refresh_global_preview_helper_and_dispatch_mode1_with_field_0x23a,map,thiscall,inferred,objdump + vtable scan + local disassembly + sibling-table correlation,2,"Small virtual slot in the sibling runtime-object table `0x005c9a60`. The helper first re-enters `0x00455de0`, which refreshes the current global preview or helper owner from the runtime object's normalized coordinates and anchor triplet. It then loads owner handle `[this+0x23a]`, sets `ECX = 1`, and tails into `0x004cf830`, which allocates or refreshes one `0xa0`-byte helper object before forwarding both values into `0x004cf550`. The exact user-facing subtype remains open, so the current note stays structural around the global-preview refresh plus mode-1 dispatch using field `[this+0x23a]`.","objdump + vtable scan + local disassembly + sibling-table correlation + global-preview-helper correlation" 0x0041f6a0,11,runtime_object_query_dynamic_helper_slot_count_field_0x37f,map,thiscall,inferred,objdump + local disassembly + sibling-table correlation,2,"Tiny sibling-family helper that treats field `[this+0x37f]` as one indexed collection and returns its current slot count through `indexed_collection_slot_count` `0x00517cf0`. Current grounded caller is `world_region_balance_structure_demand_and_place_candidates` `0x004235c0`, where it bounds one region-local profile or structure-count loop.","objdump + local disassembly + sibling-table correlation + slot-count correlation" 0x0041f6b0,40,runtime_object_query_world_scalar_at_rounded_normalized_coords,map,thiscall,inferred,objdump + local disassembly + shared-coordinate-helper correlation,2,"Small shared helper over the broader `0x23a` runtime-object family. It queries the normalized secondary and primary coordinates through `0x00455810` and `0x00455800`, rounds both through `0x005a10d0`, then forwards the resulting integer pair plus the active world root `0x0062c120` into `0x0044afa0`. Current evidence is strong enough only for the rounded-coordinate world-scalar query shape, not for a more semantic name for the returned scalar.","objdump + local disassembly + shared-coordinate-helper correlation + world-scalar-query correlation" @@ -112,14 +113,17 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00412b70,35,indexed_collection_resolve_live_entry_by_casefolded_name_at_field_0x04,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Small resolve-by-name wrapper over `indexed_collection_find_live_entry_id_by_casefolded_name_at_field_0x04` `0x00412af0`. It searches the current collection for the caller-supplied casefolded name, and when a live id is found it resolves and returns the backing record through `indexed_collection_resolve_live_entry_by_id` `0x00518140`; otherwise it returns null. Current grounded callers are the region-profile helpers `0x0041f940` and `0x0041f9b0`, where it resolves structure-candidate records from region-profile labels against the global candidate pool `0x0062b268`.","objdump + local disassembly + caller correlation + collection-name-lookup correlation" 0x0041f940,88,world_region_count_structure_profiles_passing_availability_gate,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Counts the current region subcollection entries at `[region+0x37f]` whose backing candidate resolves through `0x00412b70` and passes the neighboring availability gate `0x0041f998`. The helper walks the live subcollection backward through `indexed_collection_slot_count` `0x00517cf0`, `indexed_collection_get_nth_live_entry_id` `0x00518380`, and `indexed_collection_resolve_live_entry_by_id` `0x00518140`, increments the running count only for candidates that survive both gates, and returns that total. Current grounded caller is the editor-side region panel family around `0x004cbe19`, where it acts as the ungated companion to the stricter year-filtered counter `0x0041f9b0`.","objdump + local disassembly + caller correlation + region-subcollection correlation" 0x0041f998,23,structure_candidate_availability_gate_reject_subtype2_without_availability_word_or_recipe_runtime,map,cdecl,inferred,objdump + local disassembly + caller correlation,2,"Tiny flag-setting predicate over one structure-candidate record. Candidates whose subtype byte `[candidate+0x32]` is not `2` pass immediately. Subtype-`2` candidates only pass when availability word `[candidate+0xba]` is nonzero or runtime recipe latch `[candidate+0x7ac]` is nonzero; when both are zero the helper leaves the zero flag set so its callers reject the candidate. Current grounded callers are the two region-profile counters `0x0041f940` and `0x0041f9b0`.","objdump + local disassembly + caller correlation + candidate-availability correlation" +0x0041f9b0,126,world_region_count_structure_profiles_matching_subtype_and_max_year_after_availability_gate,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Counts the current region subcollection entries at `[region+0x37f]` whose backing candidate resolves through `0x00412b70`, passes the neighboring availability gate `0x0041f998`, has subtype byte `[candidate+0x32]` equal to the caller-supplied subtype, and has year word `[candidate+0x26]` less than or equal to the caller-supplied max-year threshold. The helper walks the same live subcollection as `0x0041f940` through `0x00517cf0/0x00518380/0x00518140`, increments only when all four gates pass, and returns that stricter count. Grounded callers include the editor region panel around `0x004cbd41`, where it supplies the subtype-`2`, year-`0x726` companion count, and the later summary or warning pass at `0x004d0b1f`.","objdump + local disassembly + caller correlation + region-subcollection correlation + editor-panel correlation" +0x0041fa30,133,world_region_query_profile_weight_by_casefolded_label,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Linearly scans the current region subcollection `[region+0x37f]`, compares each live profile label against the caller-supplied casefolded string through `0x005a57cf`, and returns float field `[entry+0x1e]` from the first match. When no label matches, the helper returns the shared zero float at `0x005c8598`. The editor copy-industry and region-summary paths already ground `[entry+0x1e]` as the mutable profile-weight lane, so the safest read is a casefolded profile-weight query by label rather than a broader scalar lookup.","objdump + local disassembly + caller correlation + region-subcollection correlation + profile-weight correlation" +0x0041fac0,59,world_region_copy_nth_profile_label_and_weight_by_1_based_ordinal,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Resolves the caller-requested 1-based ordinal out of the current region subcollection root `[region+0x37f]`, copies the matched live profile label string into the caller buffer, and stores float field `[entry+0x1e]` through the caller-supplied out pointer. The helper uses `0x00518380/0x00518140` beneath the same subcollection root as `0x0041f940/0x0041fa30`, and grounded editor callers around `0x00421db7`, `0x00421ec7`, and `0x004d1817` use it as the ordinal enumerator for region profile labels plus weights. The current evidence is strong enough for a 1-based ordinal copy helper, not for a broader iterator name.","objdump + local disassembly + caller correlation + region-subcollection correlation + profile-weight correlation" 0x0041fb00,1130,world_region_class0_stamp_local_secondary_overlay_and_scored_refinement_pass,map,thiscall,inferred,objdump + caller xrefs + local disassembly + raster-helper correlation,3,"Heavy per-region helper used only on class-0 region records. The function skips any region whose class dword `[region+0x23e]` is nonzero, rounds the region's normalized coordinates through `0x00455800`, `0x00455810`, and `0x005a10d0`, derives one orientation bucket from `(x+y)&3`, and then runs two bounded local passes around that center. The first pass walks one orientation-dependent ring pattern from the static offset tables `0x00624b28/0x00624b48`, probes quarter-resolution secondary-raster cells through `0x00534e10`, and when that predicate stays clear marks the local secondary overlay through `0x004497a0(world, x, y, 1, 3, 1)`. The second pass scans a bounded square around the same center, scores each in-bounds cell through `math_measure_float_xy_pair_distance` `0x0051db80`, and then combines the local helper cluster `0x00534040`, `0x005340a0`, `0x00534100`, and `0x00533fe0` before returning. Current grounded callers are the region collection walk at `0x00421d04` and the earlier world-build special case at `0x0044308e`, where the same helper runs immediately before `world_region_collection_clear_cell_region_word_and_assign_nearest_region_ids` `0x00421730`.","objdump + caller xrefs + local disassembly + raster-helper correlation + region-build correlation" 0x0041fff0,61,world_query_shell_mode2_or_thresholded_preview_scalar_gate,map,cdecl,inferred,objdump + caller xrefs + local disassembly + global-field correlation,2,"Small global gate over shell state `0x006cec74` and preview owner `0x0062be68`. The helper reads dword `[shell+0x2bb]` and returns `1` immediately when that mode equals `2`; when the mode is nonzero but not `2` it instead compares preview scalar `[0x0062be68+0x20]` against float threshold `0x005c9a9c` and returns `1` only when that comparison passes. Zero mode returns `0`. Current grounded callers are the scored world-scalar helper `0x0044afa0` and the city-connection status formatter band around `0x00420b09`, so the safest current read is the shared shell-mode-or-thresholded-preview gate rather than a region-only predicate.","objdump + caller xrefs + local disassembly + global-field correlation + threshold-gate correlation" 0x00455660,131,runtime_object_publish_world_anchor_triplet_from_normalized_xy_and_height_bias,map,thiscall,inferred,objdump + caller xrefs + local disassembly + sibling-vtable correlation,2,"Shared helper over the broader `0x23a` runtime-object family. The function scales the caller-supplied normalized coordinate pair through `0x005c8700`, converts that pair through world-basis owner `0x006d4024` plus `0x0051f090` and `0x00534490`, adds one caller-supplied integer height bias, optionally rounds that height when `shell_has_auxiliary_preview_owner` `0x00434050` is active, and publishes the resulting world-anchor triplet through `0x00530720`. It is used directly from both the city-entry side (`0x00455d09`, `0x00474253`) and the placed-structure specialization side through `0x0045b110`, so the safest current read is one shared world-anchor triplet publisher from normalized XY plus height bias rather than a city-only geometry helper.","objdump + caller xrefs + local disassembly + sibling-vtable correlation + world-anchor correlation" 0x004557b0,64,record_collection_release_global_iteration_root_0x6acd40_if_present,map,cdecl,inferred,objdump + caller xrefs + local disassembly,2,"Small release-side helper over the current global iteration root at `0x006acd40`. When that root is live the helper clears companion dword `0x006acd3c`, re-enters `0x0045b160` and `0x0045b040` on the pointed record, frees the record through `0x0053b080`, and finally clears `0x006acd40` itself. Current grounded callers include the shell detail-panel manager `0x004ddfc1`, the earlier world-side branch `0x00434a8c`, the building-detail side branch `0x004b6f64`, and later shell constructors at `0x00505dc6` and `0x005147e4`, so the safest current read is one shared global-iteration-root release helper rather than a tool-window-specific cleanup path.","objdump + caller xrefs + local disassembly + global-root correlation" 0x00455800,13,runtime_object_query_normalized_primary_coord,map,thiscall,inferred,objdump + caller xrefs + field inspection + sibling-vtable correlation,2,"Tiny float getter shared across the broader `0x23a` runtime-object family. The helper loads the float at `[this+0x1e2]`, divides it by scale constant `0x005c8700`, and returns the normalized result. It is used pervasively beside `0x00455810` from city-side, placed-structure, route-link, and world-grid callers, and now also appears under both the city-entry table `0x005c9750` and the sibling `Infrastructure` table `0x005cfd00`, so the safest current read is one normalized primary coordinate getter rather than a fully named X/Y accessor.","objdump + caller xrefs + field inspection + sibling-vtable correlation" 0x00455810,13,runtime_object_query_normalized_secondary_coord,map,thiscall,inferred,objdump + caller xrefs + field inspection + sibling-vtable correlation,2,"Tiny float getter paired with `0x00455800` across the broader `0x23a` runtime-object family. The helper loads the float at `[this+0x1ea]`, divides it by scale constant `0x005c8700`, and returns the normalized result. It is used pervasively beside `0x00455800` and appears under both the city-entry table `0x005c9750` and the sibling `Infrastructure` table `0x005cfd00`, so the safest current read is one normalized secondary coordinate getter rather than a fully named X/Y accessor.","objdump + caller xrefs + field inspection + sibling-vtable correlation" -0x00455930,148,runtime_object_serialize_two_triplet_scalar_bands,map,thiscall,inferred,objdump + local disassembly + serializer symmetry + sibling-vtable correlation,2,"Shared serializer over the broader `0x23a` runtime-object family. The helper first queries two triplet-like scalar bands through `0x0052e720` and `0x0052e880`, then writes the six resulting dwords to the caller-supplied bundle or stream through `0x00531030`. The recovered load-side counterpart at `0x004559d0` restores the same `[this+0x206/+0x20a/+0x20e]` band beneath tags `0x55f1..0x55f3`, and the same serializer slot appears in both the city-entry table `0x005c9750` and the sibling `Infrastructure` table `0x005cfd00`, so the safest current read is one shared serializer for two triplet scalar bands rather than a city-only stream helper.","objdump + local disassembly + serializer symmetry + sibling-vtable correlation" -0x004559d0,102,runtime_object_load_tagged_string_triplet_and_dispatch_slot_0x4c,map,thiscall,inferred,objdump + local disassembly + serializer symmetry + sibling-vtable correlation,2,"Shared tagged load-side mirror beneath the broader `0x23a` runtime-object family. The helper opens tags `0x55f1/0x55f2/0x55f3`, restores the three string lanes `[this+0x206/+0x20a/+0x20e]` through `0x00531410`, dispatches vtable slot `+0x4c`, then re-enters `0x0052ec50` before closing the tagged bracket. It is the strongest current tagged load-side counterpart to `runtime_object_serialize_two_triplet_scalar_bands` `0x00455930`, not an unrelated bundle helper.","objdump + local disassembly + serializer symmetry + sibling-vtable correlation" +0x00455930,148,runtime_object_serialize_two_triplet_scalar_bands,map,thiscall,inferred,objdump + local disassembly + serializer symmetry + sibling-vtable correlation,2,"Shared serializer over the broader `0x23a` runtime-object family. The helper first queries two triplet-like scalar bands through `0x0052e720` and `0x0052e880`, then writes the six resulting dwords to the caller-supplied bundle or stream through `0x00531030`. The grounded load-side stream counterpart is `0x00455870`, which reads those same six four-byte lanes back through `0x00531150` and republishes the resulting triplets. The same serializer slot appears in both the city-entry table `0x005c9750` and the sibling `Infrastructure` table `0x005cfd00`, so the safest current read is one shared serializer for two triplet scalar bands rather than a city-only stream helper.","objdump + local disassembly + serializer symmetry + sibling-vtable correlation" +0x004559d0,102,runtime_object_serialize_tagged_string_triplet_and_dispatch_slot_0x4c,map,thiscall,inferred,objdump + local disassembly + serializer symmetry + sibling-vtable correlation,2,"Shared tagged string-triplet serializer beneath the broader `0x23a` runtime-object family. The helper writes bracket tags `0x55f1/0x55f2/0x55f3` through `0x00531340`, emits the three string lanes `[this+0x206/+0x20a/+0x20e]` through `0x00531410`, dispatches vtable slot `+0x4c`, then re-enters `0x0052ec50` before writing the closing tag. Current grounded callers include the common placed-structure serializer path `0x0045b560` and the sibling-table wrapper `0x0041f650`, so this is the safest current read for the tagged string-triplet save-side helper rather than a load-side mirror.","objdump + local disassembly + serializer symmetry + sibling-vtable correlation + tagged-string correlation" 0x00455a40,3,record_collection_dispatch_entry_virtual_slot_0x44,map,thiscall,inferred,objdump + caller xrefs + local disassembly,1,"Tiny collection-side dispatcher that jumps directly through the current entry vtable slot `+0x44`. Current grounded caller is the linked-list sweep at `0x0048a766`, where it is used while iterating sibling records under `0x00556ef0/0x00556f00`. The safest current read is a raw `slot+0x44` dispatch helper rather than a more semantic serializer name.","objdump + caller xrefs + local disassembly + linked-list sweep correlation" 0x00455a50,28,record_collection_dispatch_entry_virtual_slot_0x40_and_clear_global_iteration_roots,map,thiscall,inferred,objdump + caller xrefs + local disassembly,1,"Small collection-side wrapper that pushes one caller argument into current entry vtable slot `+0x40`, then clears the three global roots at `0x006acd38`, `0x006acd3c`, and `0x006acd40`. Current grounded caller is the object-construction path at `0x0048dd77`, so the safest current read is a raw `slot+0x40` dispatch plus global-iteration-root reset helper rather than a more semantic load or attach name.","objdump + caller xrefs + local disassembly + global-root reset correlation" 0x00455a70,135,runtime_object_publish_current_position_triplet_with_height_bias,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Small runtime-object helper that queries the current position pair through `0x0052e720`, converts that pair through `0x006d4024 -> 0x0051f090 -> 0x00534490`, adds one caller-supplied integer height bias, optionally rounds the result through `0x005a10d0` when `shell_has_auxiliary_preview_owner` `0x00434050` is active, and publishes the resulting triplet through `0x00530720`. Current grounded callers are the bounded-region sweeps at `0x00421fef` and `0x00461808`, which makes this the safest current read for a generic current-position triplet publisher rather than a city-entry-only helper.","objdump + caller xrefs + local disassembly + position-triplet correlation" @@ -209,6 +213,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0041fac0,60,world_region_read_structure_profile_label_and_weight_by_index,map,thiscall,inferred,objdump + caller xrefs + strings,4,"Reads one 1-based structure-profile entry from the current region subcollection `[region+0x37f]`. It copies the profile label string into the caller buffer and writes the float-like weight at `[profile+0x1e]` into the caller-provided out-slot. This is the label/value helper used beneath the region structure-demand worker and the adjacent UI or telemetry callers. The grounded profile-name block around `0x005c9100` now includes labels such as `House`, `Hotel`, `Iron Mine`, `Furniture Factory`, and `Fertilizer Factory`.","objdump + caller xrefs + rdata strings" 0x00422320,1320,world_region_normalize_cached_structure_balance_scalars,map,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Collection-wide region normalization pass over the live region manager `0x0062bae0`. The helper first early-outs in sandbox/editor-side mode through `[0x006cec7c+0x82]` and the active-mode latch `[0x006cec78+0x4aef]`, then runs one per-region prepass through `0x00420d40`, and finally performs two cohort sweeps split by region live byte `[region+0x23e]`. Across those sweeps it accumulates the cached scalar bands `[region+0x2b2/+0x2b6/+0x2ba/+0x2be/+0x2c2/+0x2c6]`, derives bounded normalization ratios, and writes the resulting cached growth-balance band back to `[region+0x2e2/+0x2e6/+0x2ea/+0x2ee]`. The player-facing meaning is tighter now from the editor growth report at `0x004d1d60`: `[region+0x2e2]` is the cached weighted-profit-margin scalar and `[region+0x2ee]` is the cached annual-density-adjust scalar later formatted as a percent, while `[region+0x2e6]` and `[region+0x2ea]` are the intermediate normalized-delta and clamped companion slots beneath that final annual-density adjust. The helper also uses world_region_count_linked_placed_structures_by_category `0x004228b0` as the direct category-count companion during the writeback sweep, and it applies one final live-value adjustment into `[region+0x25e]` when the shell latch `[0x006cec78+0x46c38]` is clear. Current grounded caller is the recurring simulation-maintenance branch at `0x0040a265` inside `simulation_service_periodic_boundary_work` `0x0040a590`, so this is now the safest current read for the region cached growth-balance normalization pass rather than a one-time setup helper.","objdump + local disassembly + caller inspection + recurring-maintenance correlation + editor-growth-report correlation" 0x004228b0,68,world_region_count_linked_placed_structures_by_category,map,thiscall,inferred,objdump + local disassembly,3,"Counts linked placed-structure records in the current region entry whose category byte matches one caller-supplied value. The helper walks the placed-instance chain rooted at `[region+0x383]` through the global registry `0x0062b26c`, resolves each live record's category byte through the vtable `+0x80` object view, and increments one simple match count without applying the heavier cap or availability filters used by `0x00422be0`. The current grounded local caller is the broader region-side worker around `0x00422320`, where this helper is used as the direct category-count companion to the later aggregate and placement passes rather than as a full demand-balancing gate.","objdump + local disassembly + local caller correlation" +0x00422850,91,world_region_count_class0_regions_passing_city_connection_peer_probe_variant,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Counts live class-0 regions in the current region collection that pass one specific `city_connection_bonus_exists_matching_peer_site` variant through `0x00420030`. The helper skips non-class-0 records, calls `0x00420030` with fixed boolean flags `(1,1,1)` plus one caller-supplied trailing dword, and increments a simple count only when that probe returns nonzero. Current grounded callers are the script or query dispatch at `0x0042f856` and the region-stats formatter at `0x004d2088`, so the safest current read is the narrow class-0 count wrapper over that peer-probe variant rather than a broader city-growth metric.","objdump + local disassembly + caller correlation + city-connection-probe correlation" 0x00422900,352,world_region_accumulate_structure_category_totals,map,thiscall,inferred,objdump + callsite inspection,3,"Aggregates the current structure-category totals for one region entry. The helper walks the placed-instance chain rooted at `[region+0x383]` through the global registry `0x0062b26c`, resolves each live record's category byte through the vtable `+0x80` object view, and returns both counts and accumulated weight-like totals across four categories via the caller-provided out-pointers. Current grounded caller is world_region_balance_structure_demand_and_place_candidates at `0x004235c0`, where the outputs feed the later demand-balancing logic for the region-owned building-population pass.","objdump + callsite inspection" 0x00422a70,355,world_region_validate_and_commit_candidate_placement,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Shared placement-validation and commit gate beneath the region candidate-placement family. The helper takes one region entry in `ECX`, one candidate or profile id on the stack, one candidate world-coordinate pair, one caller-controlled side flag, one direct-versus-staged commit flag, and one optional out-pointer for the created placed-structure id. It first clears the optional out-slot, conditionally snaps the candidate coordinate pair to integers under the preview gate `0x434050 -> 0x46d2b0`, then validates projected placement through `placed_structure_validate_projected_candidate_placement` `0x004197e0`. On the direct-commit lane it additionally resolves the candidate world cell through `0x0044a800` and requires that cell's region id to match `[region+0x23a]`. When placement is allowed and the shell-side latch `[0x006cec78+0x46c3c]` is clear, one branch emits the staged side path through `0x0046d260`; otherwise it commits directly through `placed_structure_collection_allocate_and_construct_entry` `0x004134d0` and stores the resulting placed-structure id in the caller's out-slot. Current grounded callers are `world_region_try_place_candidate_structure` `0x00422ee0` and the world-side randomized batch helper `world_try_place_random_structure_batch_from_compact_record` `0x00430270`, so this is best read as the shared region-side candidate-placement validator and commit gate rather than as one region-worker-private helper.","objdump + local disassembly + caller correlation + placement-validator correlation" 0x00422be0,768,world_region_count_placed_structures_for_category,map,thiscall,inferred,objdump + callsite inspection,3,"Counts already-placed structures in one requested category for the current region entry. It walks the placed-instance chain rooted at `[region+0x383]` through `0x0062b26c`, filters live records by the requested category byte, and applies several additional placement gates including one cap on `[record+0x276]`, one disable byte at `[record+0x390]`, and special handling for category `2`. Current grounded caller is world_region_balance_structure_demand_and_place_candidates at `0x004235c0`, where the result is subtracted from the region's computed category demand before more candidates are chosen.","objdump + callsite inspection" @@ -286,9 +291,34 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 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 +0x0043b2c0,133,world_view_store_camera_view_slot_snapshot,shell,thiscall,inferred,objdump + caller inspection + world-view correlation,4,"Stores one live camera-view snapshot into a fixed slot family rooted inside the world-view owner at `0x0062be68`. The helper expands the caller slot selector into one `0x30`-byte record, sets slot-valid dword `[slot+0x10e]`, copies the current scenario-side focus-kind pair from `[0x006cec78+0x45/+0x49]` into `[slot+0x112/+0x116]`, and then mirrors the live world-view focus and camera fields `[view+0x04/+0x08/+0x0c/+0x18/+0x10/+0x14/+0x1c/+0x20/+0x24]` into `[slot+0x11a..+0x13a]`. Current grounded caller is the shell-side assignment owner `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`, which uses this helper for the ten-slot `Assign Camera View` family. This is therefore the safest current read for the fixed camera-view snapshot writer rather than a generic view-state copier.","objdump + caller inspection + world-view correlation + slot-layout correlation" +0x0043ca20,223,world_view_restore_camera_view_slot_snapshot_if_populated,shell,thiscall,inferred,objdump + caller inspection + world-view correlation,4,"Restores one previously saved camera-view snapshot from the fixed slot family inside the live world-view owner at `0x0062be68`. The helper expands the caller slot selector into the same `0x30`-byte record used by `world_view_store_camera_view_slot_snapshot` `0x0043b2c0`, rejects immediately when slot-valid dword `[slot+0x10e]` is zero, re-enters `0x004349f0` to clear or normalize scenario-side focus state, restores the saved focus and camera fields back into `[view+0x04/+0x08/+0x0c/+0x18/+0x10/+0x14/+0x1c/+0x20/+0x24]`, clamps the restored heading through `0x005a1390`, optionally replays the saved focus-kind pair `[slot+0x112/+0x116]` through `shell_world_focus_selected_subject_kind_and_id` `0x00437a90`, and finally rebuilds the dependent view state through `0x0043db00` and `0x0043bde0` before returning `1`. Empty slots return `0` without side effects. Current grounded caller is the shell-side selection owner `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`, which uses this helper for the ten-slot `Select Camera View` family. This is therefore the safest current read for the fixed camera-view snapshot restore helper rather than a generic world-view reset.","objdump + caller inspection + world-view correlation + slot-layout correlation + focus-replay correlation" 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 +0x0045ea90,365,shell_input_binding_format_display_label_from_registry_entry,shell,cdecl,inferred,objdump + local disassembly + registry correlation,4,"Formats one user-facing binding label directly from a live registry entry. The helper clears the destination buffer, rejects entries whose primary binding code `[entry+0x0c]` is `0xff`, prepends up to three localized prefix fragments from ids `0xdef`, `0xdf0`, and `0xdf1` according to bits `0x4`, `0x2`, and `0x1` in mode field `[entry+0x94]`, then scans the static binding-descriptor table rooted at `0x005f0a34` for the current action id `[entry+0x0c]`. When the descriptor-side localized caption id at `[row+0x04]` exists and `0x0051c900` accepts it, the helper appends that localized caption through `0x005193f0`; otherwise it appends the fallback literal stem at `[row+0x08]`. Current grounded caller is `shell_input_binding_registry_format_display_label_by_action_stem` `0x0045f3d0`, which uses this helper beneath the camera-view modal family and the hotkey report path. This is therefore the safest current read for the lower binding-label formatter rather than a generic string helper.","objdump + local disassembly + registry correlation + descriptor-table correlation + localized-prefix correlation" +0x0045ec00,108,shell_input_binding_split_plus_prefixed_label_into_primary_and_modifier_fragments,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Splits one compound binding label into a primary token plus one optional modifier fragment. The helper copies the caller source string into the primary destination unchanged when the string either begins with `+`, does not contain the localized token from id `0xdf2`, or contains no later `+` delimiter. Otherwise it trims the source at the first `+`, copies the suffix after that delimiter into the primary destination, and copies the preserved prefix fragment into the secondary destination buffer. Current grounded caller is the hotkey import worker `0x0045f420`, where it prepares one imported binding label for action lookup and modifier parsing before the rebucket helper `0x0045ef00`. This is therefore the safest current read for the localized plus-split helper rather than a generic string tokenizer.","objdump + caller inspection + local disassembly + hotkey-import correlation" +0x0045ec70,88,shell_input_binding_descriptor_query_action_id_by_localized_label,shell,cdecl,inferred,objdump + local disassembly + descriptor-table correlation,4,"Resolves one action id from the binding-descriptor table rooted at `0x005f0a34` by matching a user-facing label. The helper rejects empty input with `0xff`, then walks the descriptor rows and compares the caller text against either the localized caption at `[row+0x04]` when `0x0051c900` accepts that id or the fallback literal stem at `[row+0x08]` otherwise. On success it returns the descriptor action id at `[row+0x00]`; failure returns `-1`. Current grounded caller is the hotkey import worker `0x0045f420`, which uses this helper after `shell_input_binding_split_plus_prefixed_label_into_primary_and_modifier_fragments` `0x0045ec00` to recover the target action id for one imported binding row.","objdump + local disassembly + descriptor-table correlation + localized-caption correlation + hotkey-import correlation" +0x0045e940,216,placed_structure_build_attached_emitter_variant_list_by_owner_stem,map,cdecl,inferred,objdump + local disassembly + literal inspection + caller inspection,2,"Builds a repeated attached-emitter list for one owner stem on top of the global emitter table. The helper rejects literal `Stadium` immediately, clears caller flag bit `0x10` when the owner stem matches `ParticleCar`, then iterates `effect_emitter_table_select_next_existing_formatted_3dp_variant` `0x00474860` first with reset mode `1` and then resume mode `0`. For each accepted formatted variant it creates one attached sprite emitter through `effect_slot_create_attached_sprite_emitter` `0x00474e20`, optionally ORs flag `0x10000` when startup latch `[0x006cec78+0x46c3c]` is live, ORs emitter flag `0x02` for literal `Nuclear`, appends the created emitter into the caller output array when that array is present, and terminates the list with a trailing null when at least one output slot was available. Current grounded callers are the heavier placed-structure transient builders around `0x0045b828` and `0x0045e23e`, so this is best read as the owner-stem-driven attached-emitter variant-list builder rather than a one-off specialization stub.","objdump + local disassembly + literal inspection + caller inspection + formatted-variant correlation + transient-family correlation" +0x0045ea20,61,shell_emit_indexed_audio_feedback_nudge_if_live,shell,cdecl,inferred,objdump + caller correlation + local disassembly,4,"Small indexed audio-feedback helper used by shell command paths and tutorial guidance. When selector `ECX` is in the bounded range `2..0x40` and the two audio override gates at `0x00ccba14` and the service-side `0x00531e10` checks remain clear, the helper looks up one pair of table-driven dwords from `0x005f0828/0x005f082c`, forwards them together with the caller scalar and three zero trailing arguments into the shell audio service at `0x006d402c` through `0x00531e10`, and otherwise returns without side effects. Current grounded callers include the pause-toggle shell command `0x00440880` with selector `0x2c` and the tutorial-step advance path `0x00516be0`, which makes this the reusable indexed feedback-nudge owner rather than a one-off pause-only stub.","objdump + caller correlation + local disassembly + audio-service correlation" +0x0045ecd0,155,shell_input_binding_parse_modifier_fragment_to_compact_mode_code,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Parses one binding-label modifier fragment into a small compact mode code. The helper normalizes the caller text through `0x005a2abe`, probes it for one localized header token from `0xdf3` and the follow-on localized fragments `0xdf4` and `0xdf5`, and then returns one of four compact codes: default `1` when the header token is absent, `4` when only the middle fragment is absent, `2` when the trailing fragment is absent, and `0` for the fully matched final branch. Current grounded caller is the hotkey import worker `0x0045f420`, which uses this compact code immediately before `shell_input_binding_expand_compact_mode_code_to_registry_mask` `0x0045ed70` and the rebucket helper `0x0045ef00`. This is therefore the safest current read for the localized modifier-fragment parser rather than a stronger semantic mode-name decoder.","objdump + local disassembly + caller inspection + hotkey-import correlation" +0x0045ed70,26,shell_input_binding_expand_compact_mode_code_to_registry_mask,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Tiny compact-mode projector for the input-binding family. The helper expands the caller compact code in `ECX` into the registry-facing mode mask over bits `0x1`, `0x2`, and `0x4` using the low two bits plus one high nibble bit, then returns that mask in `EAX`. Current grounded caller is the hotkey import path at `0x00500205`, where it immediately feeds the result into `shell_input_binding_registry_rebucket_entry_by_stem_to_action_id_and_mode_mask` `0x0045ef00`.","objdump + local disassembly + caller inspection + hotkey-import correlation" +0x0045ed90,69,shell_input_binding_descriptor_query_bucket_key_for_action_id_when_mode_mask_is_singular,shell,cdecl,inferred,objdump + local disassembly + descriptor-table correlation,4,"Descriptor-side bucket-key query for the shell input-binding registry. The helper scans the static descriptor table rooted at `0x005f0a34` for the caller action id in `ECX`, counts the number of set bits in the caller mode mask in `EDX`, and only when that bit count is `0` or `1` returns the descriptor-side bucket key at `[row-0x04]` / `[row+0x30]`; multi-bit masks return `0`. Current grounded callers are `shell_input_register_action_binding_with_mode_specific_defaults` `0x0045f6d0`, the hotkey message path at `0x005001e1`, and the rebucket helper `0x0045ef00`, which all use this helper as the singular-mode bucket discriminator above the live registry buckets. This is therefore the safest current read for the descriptor-side bucket-key query rather than a generic action-table scan.","objdump + local disassembly + descriptor-table correlation + mode-mask correlation + bucket-key correlation" +0x0045f370,95,shell_input_binding_registry_lookup_primary_code_and_mode_bits_by_action_id,shell,cdecl,inferred,objdump + caller inspection + registry correlation,4,"Lookup helper over the shell input-binding registry rooted at `0x006acd78..0x006ad960`. The helper scans each linked per-bucket list for a record whose action id at `[entry+0xa0]` matches the caller key in `ECX`; on success it writes the entry's primary binding code `[entry+0x0c]` through the first out-parameter and packs three mode bits from `[entry+0x94]` into a small output mask through the second out-parameter before returning `1`. Failure returns `0`. Current grounded caller is `world_view_seed_keyboard_binding_slot_pairs` `0x00439e40`, where this helper resolves the default `Camera Forward/Backward/Left/Right/Zoom/Rotate` action ids before the resulting codes are normalized into the world-view slot-pair band. This is therefore the safest current read for the action-binding query helper rather than a generic shell hash-table scan.","objdump + caller inspection + registry correlation + output-mask correlation" +0x0045ede0,88,shell_input_binding_registry_resolve_entry_by_action_stem,shell,cdecl,inferred,objdump + local disassembly + registry correlation,4,"Resolves one shell input-binding registry entry by stem text. The helper copies the caller string into a local `0x80`-byte buffer, normalizes it through `0x0053d810`, hashes or canonicalizes that normalized stem, and then scans the linked registry buckets rooted at `0x006acd78..0x006ad960` for an entry whose cached normalized token at `[entry+0x90]` matches the derived value. On success it returns the live registry entry pointer; otherwise it returns null. Current grounded callers are `shell_input_binding_registry_format_display_label_by_action_stem` `0x0045f3d0` and `shell_input_binding_registry_query_primary_code_by_action_stem` `0x0045f400`, which use this helper as the shared action-stem lookup beneath the camera-view modal family. This is therefore the safest current read for the stem-to-binding-entry resolver rather than a generic string hash helper.","objdump + local disassembly + registry correlation + normalized-stem correlation" +0x0045ef00,568,shell_input_binding_registry_rebucket_entry_by_stem_to_action_id_and_mode_mask,shell,cdecl,inferred,objdump + local disassembly + caller inspection + registry correlation,4,"Rehomes one existing binding entry into a different action bucket and mode-mask family while preserving its current binding data. The helper first resolves the target descriptor bucket through `shell_input_binding_descriptor_query_bucket_key_for_action_id_when_mode_mask_is_singular` `0x0045ed90` unless the requested action id is `0xff`, then resolves the source live entry by stem through `shell_input_binding_registry_resolve_entry_by_action_stem` `0x0045ede0`, allocates one fresh record from the pool owner at `0x006acd6c`, copies the source entry payload into that fresh record, overwrites the new action id `[entry+0x0c]` and mode mask `[entry+0x94]`, unlinks the old record from its current per-bucket list, optionally moves the old record into the detached `0xff` side list rooted at `0x006ad96c..0x006ad974`, and finally links the new record into the requested target bucket at `0x006acd78..0x006ad960`. Failure at either the descriptor-bucket or source-entry step returns `0`; success returns `1`. Current grounded caller is the hotkey message path at `0x0050020f`, where this helper commits one imported or reassigned binding row after the local label split and modifier decode. This is therefore the safest current read for the binding-entry rebucket helper rather than a generic pool copier.","objdump + local disassembly + caller inspection + registry correlation + pool-allocation correlation + detached-list correlation" +0x0045f250,278,shell_input_binding_report_iterate_next_entry_in_sorted_priority_order,shell,cdecl,inferred,objdump + caller inspection + local disassembly + registry correlation,4,"Iterates the next live binding entry in one temporary sorted report order. On first use when sentinel `0x005f0fe0 == 1`, the helper allocates a small queue owner at `0x006acd74`, initializes it through `0x0053d740`, walks every live registry bucket at `0x006acd78..0x006ad960`, and pushes each entry into that queue with priority `0x7ffffffe - [entry+0x9c]`. Each call then pops one entry through `0x0053d540`; when one record is available it formats the user-facing label into scratch `0x006ad980` through `shell_input_binding_format_display_label_from_registry_entry` `0x0045ea90`, copies the action stem from `[entry+0x10]` into `0x006ada00`, mirrors the binding code and companion field into `0x006ad978` and `0x006ad97c`, and returns `0x006ad978`. When the queue is exhausted it destroys the temporary owner, resets `0x006acd74` to null, restores sentinel `0x005f0fe0` to `1`, and returns `0`. Current grounded callers are the hotkey-report writer `0x0045f550` and the hotkeys-window refresh path at `0x004fed16/0x004fedb2`, which makes this the current sorted binding-report iterator rather than a generic priority-queue wrapper.","objdump + caller inspection + local disassembly + registry correlation + temporary-queue correlation + report-scratch correlation" +0x0045f3d0,33,shell_input_binding_registry_format_display_label_by_action_stem,shell,cdecl,inferred,objdump + caller inspection + registry correlation,3,"Small display-label helper above `shell_input_binding_registry_resolve_entry_by_action_stem` `0x0045ede0`. The helper resolves the caller action stem into one registry entry, then forwards the destination buffer plus that entry into `0x0045ea90` to format the user-facing label string. Success returns `1`; unresolved stems return `0`. Current grounded callers are the camera-view command owners `0x004408f0` and `0x004409c0`, where it formats the optional current focus labels embedded in the assignment and unassigned-view modals.","objdump + caller inspection + registry correlation + modal-text correlation" +0x0045f400,18,shell_input_binding_registry_query_primary_code_by_action_stem,shell,cdecl,inferred,objdump + local disassembly + registry correlation,3,"Tiny primary-code accessor above `shell_input_binding_registry_resolve_entry_by_action_stem` `0x0045ede0`. The helper resolves the caller action stem into one registry entry and, on success, returns that entry's primary binding code from `[entry+0x0c]`; unresolved stems return `0`. Current local evidence only grounds the raw field access, not a stronger player-facing meaning beyond the shared binding-registry lane.","objdump + local disassembly + registry correlation + field-access correlation" +0x0045f420,296,shell_input_import_hotkeys_file_and_rebucket_registry_entries_from_compound_labels,shell,thiscall,inferred,objdump + local disassembly + caller correlation + import-file correlation,4,"Imports one saved hotkeys file and rehomes matching live binding entries into the requested action or mode buckets. The helper first loads one parsed text resource through the small loader pair `0x00557320 -> 0x00557630`, retrying with the secondary `(0x28,0x29)` selector pair when the primary `(0x21,0x7e)` load fails. On the success path it walks the resulting nested record lists at `[root] -> [group+0x108] -> [entry+0x104]`, splits each imported `foo+bar` label through `shell_input_binding_split_plus_prefixed_label_into_primary_and_modifier_fragments` `0x0045ec00`, normalizes both fragments through `0x00557280/0x005572e0`, resolves the target action id from the descriptor table through `shell_input_binding_descriptor_query_action_id_by_localized_label` `0x0045ec70`, decodes the modifier fragment through `shell_input_binding_parse_modifier_fragment_to_compact_mode_code` `0x0045ecd0`, and finally commits the rebucket through `shell_input_binding_registry_rebucket_entry_by_stem_to_action_id_and_mode_mask` `0x0045ef00` using the preserved stem at `[entry+0x04]`. A fully successful import returns `1`; early parse or load failures return the loader status unchanged. Current grounded caller is the registry constructor `0x00461120`, which tail-jumps here with the fixed path `hotkeys\\hotkeys.txt` when the caller requests saved-hotkey import. This is therefore the safest current read for the hotkeys-file import worker rather than a generic text-resource walker.","objdump + local disassembly + caller correlation + import-file correlation + nested-record-walk correlation + rebucket correlation" +0x0045f550,382,shell_input_write_hotkeys_report_file,shell,cdecl,inferred,objdump + caller inspection + local disassembly + literal correlation,4,"Writes the current hotkey report to the fixed output path `hotkeys\\hotkeys.txt`. The helper opens that file through mode string `wt`, writes the fixed report header `!Hotkeys~\\n`, appends the localized heading strip from ids `0xdf6` through `0xdfc`, then iterates the current binding set through `shell_input_binding_report_iterate_next_entry_in_sorted_priority_order` `0x0045f250`. For each returned record it copies the action stem at `[entry+0x08]` into a local `0x20`-byte padded column, falls back to the localized empty-label string `0x0b3e` when the stem is empty, and formats each output line through the fixed template `%s = %s\\n`; rows whose leading dword is zero instead use the alternate template `%s = %s\\n` with the shifted value pointer at `[entry+0x08]`. Current grounded callers are the shell command path at `0x00461082` and the hotkeys-window message path at `0x00500153/0x0050021d`, which makes this the current shared hotkey-report writer rather than a generic file dump helper.","objdump + caller inspection + local disassembly + literal correlation + report-iterator correlation + hotkeys-path correlation" +0x0045f6d0,334,shell_input_register_action_binding_with_mode_specific_defaults,shell,cdecl,inferred,objdump + caller inspection + registry correlation,4,"Shared registration helper over the shell input-binding registry rooted at `0x006acd78..0x006ad960`. The helper first selects one mode-specific `(binding_code, companion_value)` pair from the caller's four fallback pairs according to shell mode dword `0x006d3c84`; when the selected binding code is not `0xff`, it re-enters `0x0045ed90` to resolve or create the target registry bucket, optionally updates an existing entry for the same companion discriminator `[entry+0x94]` through `0x0045f8a0`, or allocates and links a fresh entry from the pool owner at `0x006acd6c` and the monotonic id source `0x006acd68`. The new or updated record stores the action id, mode flags, callback pointer, localized label string, and the selected default pair before it is linked back into the per-action bucket family. Current grounded callers include the camera-view command registration block at `0x00460903..0x00460cac` and the world-view keyboard registration block at `0x00460720..0x004608e7`, which makes this the current shared action-binding registration helper rather than a camera-specific leaf.","objdump + caller inspection + registry correlation + allocation-pool correlation + mode-specific-default correlation" +0x0045f8a0,315,shell_input_binding_registry_replace_existing_entry_by_action_bucket_and_mode_mask,shell,cdecl,inferred,objdump + local disassembly + caller inspection + registry correlation,4,"Updates one existing binding entry for a specific action bucket plus mode-mask discriminator. The helper first scans the requested live bucket at `0x006acd78..0x006ad960` for an entry whose stored mode mask `[entry+0x94]` matches the caller value in `EDX`; when found it copies the full record to a local stack frame, unlinks and releases the live record from both its bucket and the pool owner at `0x006acd6c`, then re-enters `shell_input_register_action_binding_with_mode_specific_defaults` `0x0045f6d0` with the preserved callback pointer, localized label pointer, default-pair payload, and the copied companion values while forcing the binding-code selector to `0xff`. Current grounded caller is the registration helper `0x0045f6d0`, which uses this path when a same-bucket same-mode entry already exists for the target action. This is therefore the safest current read for the existing-entry replacement helper rather than a generic free-and-realloc wrapper.","objdump + local disassembly + caller inspection + registry correlation + preserved-payload correlation" +0x0045f9e0,598,shell_input_seed_default_binding_registry_entries_from_static_table,shell,cdecl,inferred,objdump + local disassembly + static-table inspection,4,"Seeds the shell input-binding registry from the static default table rooted at `0x005ecadc`. The helper walks `0x71` eight-byte rows, localizes each row label id at `+0x04`, decodes the packed row policy word at `+0x06` into the mode-specific default tuple expected by `shell_input_register_action_binding_with_mode_specific_defaults` `0x0045f6d0`, and installs each resulting binding into the live registry. After the fixed table pass it appends a smaller manual post-table strip for adjacent shell commands such as the wrappers at `0x00441a00`, `0x00441940`, `0x00441980`, `0x00482b00`, `0x004408b0`, `0x00441ac0`, `0x004408d0`, and `0x00441af0`, using localized ids `0x0d4a` through the neighboring `0x0d53` band. Current grounded caller is the registry initializer `0x00461120`, which runs this helper after rebuilding the pool and queue roots. This is therefore the safest current read for the default binding seeder rather than a generic command-registration batch.","objdump + local disassembly + static-table inspection + post-table registration-strip correlation" +0x00461000,52,shell_input_register_localized_binding_command_id_0xdb6_to_action_0x6d,shell,cdecl,inferred,objdump + local disassembly + installer correlation,2,"Tiny registration wrapper above `shell_input_register_action_binding_with_mode_specific_defaults` `0x0045f6d0`. The helper localizes command label id `0x0db6`, then installs one default binding row with action id `0x6d`, callback `0x00441d20`, zero modifier defaults, and no explicit fallback override pairs. Current grounded caller is the broader registry setup strip at `0x00460769..0x00461168`, where it sits beside the other fixed shell input command registrations. The exact user-facing command name is still open, so the current annotation stays at the concrete localized-id plus action-id level.","objdump + local disassembly + installer correlation + registration-strip correlation" +0x00461040,40,shell_input_register_localized_binding_command_id_0xdb7_to_action_0x6a,shell,cdecl,inferred,objdump + local disassembly + installer correlation,2,"Tiny registration wrapper above `shell_input_register_action_binding_with_mode_specific_defaults` `0x0045f6d0`. The helper localizes command label id `0x0db7`, then installs one default binding row with action id `0x6a`, callback `0x004413e0`, zero modifier defaults, and no explicit fallback override pairs. Current grounded caller is the broader registry setup strip at `0x00460769..0x00461168`, where it sits beside the other fixed shell input command registrations. The exact user-facing command name is still open, so the current annotation stays at the concrete localized-id plus action-id level.","objdump + local disassembly + installer correlation + registration-strip correlation" +0x00461070,170,shell_input_binding_registry_destroy_all_roots_and_reset_globals,shell,cdecl,inferred,objdump + local disassembly + global-field correlation,4,"Destroys the live shell input-binding registry and clears all of its global roots. The helper first re-enters `shell_input_write_hotkeys_report_file` `0x0045f550` when the main pool owner at `0x006acd6c` is present, then releases the main pool owner `0x006acd6c`, the companion owner at `0x006acd70`, zeroes every bucket head/tail/count triple across `0x006acd78..0x006ad974`, and finally releases the temporary report queue owner at `0x006acd74` if it is still live. Current grounded caller is the setup helper `0x00461120`, which uses this as the hard reset before rebuilding the registry state. This is therefore the safest current read for the binding-registry teardown and global reset owner rather than a one-off file export command.","objdump + local disassembly + global-field correlation + teardown correlation + hotkey-report correlation" +0x00461120,171,shell_input_binding_registry_initialize_roots_seed_defaults_and_optionally_import_hotkeys_file,shell,thiscall,inferred,objdump + local disassembly + caller correlation,4,"Constructs the live shell input-binding registry, seeds the default action set, and optionally imports the saved hotkeys file. The helper first hard-resets the old registry through `shell_input_binding_registry_destroy_all_roots_and_reset_globals` `0x00461070`, zeros the monotonic id source `0x006acd68`, allocates and clears the primary pool owner at `0x006acd6c`, allocates the two companion owners at `0x006acd70` and `0x006acd74`, seeds the default bindings through `shell_input_seed_default_binding_registry_entries_from_static_table` `0x0045f9e0`, and when the caller flag in `ECX` equals `1` immediately tail-jumps into the hotkey import worker `0x0045f420` using the fixed path literal `hotkeys\\hotkeys.txt`. This is therefore the safest current read for the binding-registry constructor and optional hotkey-import owner rather than a generic allocator batch.","objdump + local disassembly + caller correlation + pool-allocation correlation + default-seed correlation + hotkey-import correlation" 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 0x00420030,578,city_connection_bonus_exists_matching_peer_site,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Reusable placed-structure scan beneath the city-connection bonus note family. The helper walks the live placed-structure collection at `0x006cec20`, first requiring each candidate peer to match one site-class token from the caller's local six-byte class table through `0x0042b2d0`, then applying four bounded caller-controlled filters before returning success on the first matching peer. Current filter roles are tighter now: the first stack flag enables the station-or-transit site-type gate through `0x0047fd50`; the second stack flag enables the linked-instance class-byte test through `0x0047de00 -> 0x0040c990 == 1`; the third stack flag enables the deeper route or peer-reachability sweep through `0x0047f310` and `0x0048e3c0`; and the fourth stack dword is an optional owning-company id that is matched through `placed_structure_query_linked_company_id` at `0x0047efe0`. Current grounded callers include the adjacent city bonus or status formatter around `0x004207d0`, where the helper's boolean combinations choose localized ids `3868` through `3873`, plus wider world-side sweeps at `0x00404d66`, `0x004221ea`, `0x00422264`, `0x00435930`, and `0x00435944`. This now looks like the common city-connection peer probe rather than a generic anonymous scan.","objdump + caller xrefs + callsite inspection + city-bonus note correlation + filter-role decoding" @@ -296,7 +326,12 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004207d0,1053,city_site_format_connection_bonus_status_label,map,thiscall,inferred,objdump + caller inspection + RT3.lng strings,4,"Adjacent city-site label formatter above the city-connection peer helpers at `0x00420030` and `0x00420280`. When the preview-global `0x0062be84` is armed or the city-side subtype field `[this+0x23e]` is nonzero the function falls back into the neighboring virtual-style formatter at `0x00455860`; otherwise it builds one visible text block from the base city label at `[this+0x356]`, optionally appends the numeric value in `[this+0x276]`, and can append localized id `207` `(Connected)` when the active linked world object and city class checks succeed. If `[this+0x276]` is nonzero it then chooses one of the city-connection bonus note strings `3868` through `3873` by calling `city_connection_bonus_exists_matching_peer_site` at `0x00420030` with three meaningful filter combinations: a deeper peer-reachability pass, an active-company-only pass using `scenario_state_get_selected_chairman_company_record` at `0x004337a0`, and a broader any-company pass. After those boolean note checks it also re-enters `city_connection_bonus_select_first_matching_peer_site` at `0x00420280` to recover one representative matching peer site, resolves that peer's linked company through `placed_structure_query_linked_company_id` at `0x0047efe0`, and uses the selected company record when formatting the follow-on company-oriented text lane. That current grounded split is enough to tie `3869` `Connected By Another Station`, `3870` `Already Connected`, `3871` `Connected By Another Company`, `3872` `Already Connected by Another Company`, and `3873` `Not Connected` to this formatter boundary rather than to the station-detail overlay body. The helper also writes one caller-owned color field and label-priority scalar before returning style code `3`, so it currently reads as a world-label or hover-summary formatter for city connection-bonus state rather than a generic text helper.","objdump + caller inspection + RT3.lng strings + city-bonus note correlation + filter-combination decoding + peer-selector correlation" 0x0043f640,3797,world_render_station_candidate_service_map_overlay,render,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Renders the world-side map overlay behind the active `StationDetail.win` candidate-service preview. The helper reads the currently previewed `(station id, candidate id)` pair from `0x005ee4fc` and `0x005ee500`, rejects early when shell preview mode or cargo-economy gates are inactive, re-enters `placed_structure_query_candidate_local_service_metrics` at `0x0047e240`, and then scans the placed-structure collection at `0x006cec20` through either the direct local-service path or the heavier route-side helper at `0x0047e690`. The candidate byte at `[candidate+0x46]` now looks like the key legend split: when it is nonzero the overlay formats the directional route rows `3874` `Coming To %1` and `3875` `Going From %1`; when it is zero the same two legend lanes instead format `3876` `Current Supply @ < %1` and `3877` `Current Demand @ > %1`. Empty directional lanes collapse to `3878` `--None--`, and the title lane falls back to literal `All` when no specific candidate label is active. The neighboring connection-state notes `3872` `Already Connected by Another Company` and `3873` `Not Connected` no longer look like direct overlay-body emits; current grounded disassembly keeps them in the adjacent city bonus or status formatter `city_site_format_connection_bonus_status_label` at `0x004207d0`, which reuses `city_connection_bonus_exists_matching_peer_site` at `0x00420030` plus `placed_structure_query_linked_company_id` at `0x0047efe0` before choosing those strings. `3879` `Out of Sync` is also outside this function body and belongs to the multiplayer preview dataset path at `0x0046b780`. This now looks like the first grounded world-side owner above the shell preview pair armed by `shell_station_detail_set_active_candidate_service_preview` at `0x00504ae0` rather than a generic hidden scanner.","objdump + RT3.lng strings + caller inspection + preview-overlay correlation + legend-branch correlation + adjacent-formatter boundary check" 0x00439140,1086,simulation_frame_accumulate_and_step_world,simulation,cdecl,inferred,objdump + analysis-context,4,"Frame-owned simulation cadence after world bring-up and still directly called from shell_service_pump_iteration at 0x00483f70 rather than a separately grounded outer gameplay loop. The routine samples elapsed time through 0x0051d890 mixes shell and mode scalars into a simulation quantum keeps leftover fractional time in [this+0x4c80] and when enough time has accumulated repeatedly calls simulation_advance_to_target_calendar_point at 0x0040ab50 using the current step quantum from 0x005f2b38. Around those simulation steps it refreshes shell-facing presentation helpers under 0x006d4024 and 0x006d0818 updates multiple world collections and transport or scenario side structures and services the recurring GameMessage.win branch through `game_message_window_service_if_present` `0x004e0720` before later follow-up work. The shell-owned cadence evidence is tighter here now too: one direct frame-side branch at `0x0043970f` opens or focuses `LoadScreen.win` through `shell_open_or_focus_load_screen_page` `0x004e4ee0`, and the post-step shell-window ladder then services several sibling shell windows by presence-probe plus dirty-latch pairs instead of any detached gameplay-only owner. Current grounded members of that ladder now include the shared custom modal through `shell_has_live_custom_modal_dialog` `0x004c8680` plus `shell_mark_custom_modal_dialog_dirty` `0x004c8670`, the file-options dialog through `shell_has_file_options_dialog` `0x004dc7d0` plus `shell_mark_file_options_dialog_dirty` `0x004dc7e0`, `LoadScreen.win` through `shell_has_live_load_screen_window` `0x004e1f50` plus `shell_mark_load_screen_window_dirty` `0x004e1f60`, `SettingsWindow.win` through `shell_has_settings_window` `0x004fe120` plus `shell_mark_settings_window_dirty` `0x004fe130`, `Overview.win` through `shell_has_live_overview_window` `0x004f2e80` plus `shell_mark_overview_window_dirty` `0x004f2e90`, `BuildingDetail.win` through `shell_has_live_building_detail_window` `0x004b9d70` plus `shell_mark_building_detail_window_dirty` `0x004b9d80`, and now `Trainbuy.win` through `shell_has_live_trainbuy_window` `0x0050f740` plus `shell_mark_trainbuy_window_dirty` `0x0050f750`. One deeper world-mode sidecar inside the same frame path now looks grounded too: after delegating to world_view_service_shell_input_pan_and_hover at 0x0043db00 the frame compares the active controller-view pointer at [0x006d4024+0x18]+0x366e against the latched world object at [this+0x66a2], releases the previous object through vtable slot +0x64, and when the new object passes its own availability test at slot +0x1c plus shell-detail control gate 0x07d6 on 0x006d0818 it latches the new object and calls slot +0x60. That makes the frame owner the first grounded non-camera world-input coordinator for hover or focus-target transitions beneath the shell-fed camera stack, even though click or command semantics are still unresolved. This is the strongest grounded owner so far for the recurring gameplay simulation cadence that follows world_entry_transition_and_runtime_bringup.","objdump + analysis-context + caller xrefs + callsite inspection + frame-disassembly correlation" +0x00433a40,82,shell_can_open_company_list_or_detail_panel_or_warn,shell,thiscall,inferred,objdump + caller inspection + shell-detail correlation,4,"Shared availability gate above the shell-side company-list and selected-company-detail lanes. The helper reads scenario toggle `[0x006cec78+0x4aef]`; when that dword is nonzero it raises the shared shell modal rooted at localized id `334` through `0x005193f0 -> 0x004c98a0` and returns `0`, otherwise it returns `1`. Current grounded callers are the direct shell command branches `0x004405b3` and `0x0044062c`, plus the broader shell-strip and page-side handlers `0x004de2e3` and `0x004de3ae`, all of which open company-list or selected-company-detail panels only on success. This is therefore the safest current read for the company list/detail availability gate rather than a generic scenario-action blocker.","objdump + caller inspection + shell-detail correlation + modal-path correlation" +0x00433aa0,95,shell_can_open_stockbuy_window_or_warn,shell,thiscall,inferred,objdump + caller inspection + stockbuy correlation,4,"Shared availability gate above the shell-side `StockBuy.win` family. The helper first rejects scenario states where toggle `[0x006cec78+0x4aa7]` is nonzero, surfacing the same shared shell modal rooted at localized id `334` through `0x005193f0 -> 0x004c98a0`. When the scenario toggle allows the action, it still requires a nonzero selected-company id at `[scenario+0x21]`; if no company is currently selected it raises the sibling shell modal rooted at localized id `335` and returns `0`. Only the success path returns `1` to the callers at `0x00440673` and `0x004de50f`, both of which immediately open detail-panel mode `0x0c` that later refreshes through the `StockBuy.win` family. This is therefore the safest current read for the stock-buy availability gate rather than a generic company-selection check.","objdump + caller inspection + stockbuy correlation + modal-path correlation" 0x00433b00,117,shell_can_open_trainbuy_window_or_warn,shell,thiscall,inferred,objdump + caller inspection + RT3.lng strings,4,"Shared availability gate above the shell-side `Trainbuy.win` family. The helper first rejects scenario states where the train-buy action is globally disabled through `[0x006cec78+0x4aa3]`, surfacing localized id `334` `That action is not allowed in this scenario.` through the shared shell modal path when blocked. It then checks whether the active company or world object state supplied by the caller allows train purchase; if no company is active it raises id `337` `You can't buy a train without starting a company first!`, and if no track has been placed it raises id `338` `You can't buy a locomotive until some track has been placed!`. Only the success path returns nonzero to the callers at `0x004406d3` and `0x004de7d9`, both of which immediately enter `shell_open_or_focus_trainbuy_window` at `0x00512c50`.","objdump + caller inspection + RT3.lng strings + train-buy gate correlation" +0x00434db0,91,shell_can_open_detail_panel_mode_0x0b_or_warn,shell,thiscall,inferred,objdump + caller inspection + shell-detail correlation,3,"Shared availability gate above one still-unresolved shell detail-panel mode `0x0b`. The helper first re-enters `shell_can_open_company_list_or_detail_panel_or_warn` `0x00433a40`; only when that broader company-family gate succeeds does it consult the additional scenario toggle `[0x006cec78+0x4a7f]`. When that second toggle is nonzero it raises the shared shell modal rooted at localized id `334` through `0x005193f0 -> 0x004c98a0` and returns `0`; otherwise it returns `1`. Current grounded callers are the direct shell command branch `0x00440543` and the page-side launcher `0x004de4a0`, both of which immediately open detail-panel mode `0x0b` on success. This is therefore the safest current read for the mode-`0x0b` availability gate rather than a tighter family name we have not yet recovered.","objdump + caller inspection + shell-detail correlation + modal-path correlation" +0x00434e20,128,shell_can_open_detail_panel_mode_0x06_or_warn,shell,thiscall,inferred,objdump + caller inspection + shell-detail correlation,3,"Shared availability gate above one still-unresolved shell detail-panel mode `0x06`. The helper first checks the three scenario toggles `[0x006cec78+0x4ab3]`, `[+0x4ab7]`, and `[+0x4abf]`; only when all three are nonzero does it raise the shared shell modal rooted at localized id `334` and return `0`. Otherwise it checks editor-map mode `[0x006cec74+0x68]`; outside editor mode it also requires a nonzero selected-company id at `[scenario+0x21]`, raising the sibling shell modal rooted at localized id `336` when that company selection is absent. Only the success path returns `1` to the callers at `0x004406a3` and `0x004de280`, both of which immediately open detail-panel mode `0x06`. This is therefore the safest current read for the mode-`0x06` availability gate rather than a tighter family name we have not yet grounded.","objdump + caller inspection + shell-detail correlation + modal-path correlation + editor-mode gating correlation" +0x00433b80,69,scenario_state_run_optional_collection_refresh_hooks_when_mutation_depth_zero,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Runs a small dispatcher of optional collection-side refresh hooks, but only when global mutation depth `0x0062be40` has fallen back to zero. On the active path it conditionally refreshes four live collection families through shell-state-controlled gates: the placed-structure collection at `0x006cec20` through `0x00481430`, the sibling placed-structure helper family at `0x0062b26c` through `0x00413860`, the train-side collection at `0x006cfcbc` through `0x004b2a90`, and the route-entry collection at `0x006cfca8` through `0x004931e0`. Current grounded callers include the periodic maintenance branch at `0x0040a914`, the placed-structure finalize path at `0x0040f6b4` after it decrements `0x0062be40`, and several shell or editor mutation branches around `0x0049d3a8` and `0x00508f97/0x0050900a`. This is therefore the safest current read for the zero-depth optional collection-refresh dispatcher rather than a single collection owner.","objdump + local disassembly + caller correlation + zero-depth-dispatch correlation + collection-refresh correlation" 0x0050f740,6,shell_has_live_trainbuy_window,shell,cdecl,inferred,objdump + caller inspection + strings correlation,4,"Tiny presence probe for the shell-side `Trainbuy.win` singleton rooted at `0x006d3ac8`. The helper returns the live-flag dword at `0x006d3ae4`, which is set during `shell_open_or_focus_trainbuy_window` at `0x00512c50` and cleared after that family tears the singleton down. Current grounded callers include the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, where it sits beside the sibling overview, building-detail, load-screen, settings, custom-modal, and file-options probes.","objdump + caller inspection + strings correlation + singleton correlation" 0x0050f750,11,shell_mark_trainbuy_window_dirty,shell,cdecl,inferred,objdump + caller inspection + nearby-family correlation,4,"Tiny dirty-latch setter paired with `shell_has_live_trainbuy_window`. The helper stores `1` into `0x006d3adc`, which current nearby call patterns treat as the `Trainbuy.win` refresh or service request latch once the live singleton family rooted at `0x006d3ac8` exists. Current grounded callers include the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, and the same latch is consumed on the message-`0` service path inside the family handler at `0x00512202` through the `0x00512c09` branch.","objdump + caller inspection + nearby-family correlation + singleton correlation + service-path inspection" 0x0050f760,45,shell_trainbuy_window_query_selected_locomotive_id,shell,cdecl,inferred,objdump + caller inspection + strings correlation,4,"Returns the currently selected locomotive id or `0` when the shell-side `Trainbuy.win` family has no valid active selection. The helper first checks whether the live singleton at `0x006d3ac8` exists and whether control resource `0x2afe` exposes one nonnegative selected row through `0x0055fba0`; on success it returns that selected locomotive id. Current grounded callers include the route, upgrade-cost, and purchase-confirmation branches inside `shell_trainbuy_window_handle_message`, where this value is then resolved through the locomotive collection at `0x006ada84`.","objdump + caller inspection + strings correlation + selected-row correlation" @@ -399,17 +434,25 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004bc350,1496,shell_world_surface_brush_handle_message_for_control_0x07d6_and_mode_family_0x0fa0_0x0faf,shell,thiscall,inferred,objdump + local disassembly + control-family correlation,3,"Shell-side message owner for one world-surface brush family whose current grounded controls are the shared main-world surface `0x07d6`, the ordinal strip `0x0fa0..0x0fa7`, and the mode buttons `0x0faa..0x0faf`. The `0x07d6` branch first resolves world coordinates through `0x00448ac0`, latches drag-active byte `[this+0x7c]`, stores the accepted world coordinate pair into `[this+0x80/+0x84]`, and caches the incoming scalar at `[this+0x88]`. When that latch is active, the helper dispatches the current mode dword `[0x006d0818+0x8c]` across six grounded edit branches: mode `0x0e` and `0x13` re-enter `world_raise_companion_float_grid_local_peak_in_rect_with_optional_class_3_5_bias` `0x0044da70`; mode `0x0f` re-enters `world_relax_companion_float_grid_cross_average_in_rect_with_raster_bit0_gate` `0x0044d4e0`; modes `0x10` and `0x11` re-enter `world_raise_companion_float_grid_toward_center_sample_in_rect` `0x0044d880`; and mode `0x12` toggles the secondary-raster low nibble through `world_secondary_raster_xor_cell_byte2_low_nibble_mask` `0x00448e20` before re-entering `placed_structure_collection_refresh_local_runtime_side_state_in_rect_from_cell_bucket_map` `0x00419110`. The same owner also routes the ordinal strip `0x0fa0..0x0fa7` through `0x004bc210/0x004bc290` and updates the shared brush ordinal at `0x00621e20`, while the mode buttons `0x0faa..0x0faf` dispatch `0x004ddbd0` with mode ids `0x0e..0x13`. Current evidence is strong enough to treat this as a shell world-surface brush and mode dispatcher even though the exact window-family resource name is still open.","objdump + local disassembly + control-family correlation + world-surface correlation + brush-mode correlation" 0x004384d0,570,world_run_post_load_generation_pipeline,map,cdecl,inferred,objdump + strings + caller xrefs,4,"Large post-load world-generation pipeline reached after world entry and shell-side file-load success paths. It increments the world-root generation counter at `[0x0062c120+0x2205]` and, on the caller-selected setup path, first runs the preliminary candidate-availability prepass at `0x00437743` before the visible progress phases begin. The visible phase order is now grounded directly from the function body instead of only from scattered callers: id `318` `Computing Transportation and Pricing...` is posted first and remains active while the pipeline runs `world_compute_transport_and_pricing_grid` `0x0044fb70`, the early collection pass `world_setup_building_collection_phase` `0x0041ea50`, and the conditional region pair `world_region_collection_seed_default_regions` `0x00421b60` plus `world_region_border_overlay_rebuild` `0x004882e0`; if shell-state gate `[0x006cec74+0x174]` is set, id `320` `Setting Up Buildings...` then drives `world_region_collection_run_building_population_pass` `0x00421c20`; if `[0x006cec74+0x178] > 0`, id `321` `Seeding Economy...` then drives `simulation_run_chunked_fast_forward_burst` `0x00437b20`; only after those setup-side gates does the pipeline post id `319` `Setting up Players and Companies...`; and id `322` `Calculating Heights...` finally tails into `0x0044d410`. That `319` lane is no longer just gate plumbing: the primary grounded work there is still the chairman-profile pair `world_seed_default_chairman_profile_slots` `0x004377a0` plus `world_build_chairman_profile_slot_records` `0x00437220`, and current neighboring setup flow also exposes one conditional company-side helper at `0x0047d440` under sandbox or non-editor shell-state conditions. The later interior ordering of the same `319` lane is tighter now too: after the route-entry collection refresh on `0x006cfca8` through `0x00493be0`, the pipeline refreshes the auxiliary route-entry tracker collection `0x006cfcb4` through `0x004a41b0`, then re-enters `placed_structure_collection_refresh_local_runtime_records_and_position_scalars` `0x004133b0`, runs a flagged world-grid cleanup sweep through `0x00448af0/0x00533fe0`, and only after that re-enters the route-entry post-pass `0x00491c20` before continuing into later persona, route-style, region, and world-manager setup families. Current evidence is tighter on the remaining gates too: `[0x006cec74+0x68]` now aligns with the editor-map `.gmp` mode in the shell file coordinators and acts as the broader master editor-mode flag that suppresses both later world-generation branches and diverts region-side calculations into alternate paths. The body fans into the live world root at `0x0062c120`, manager collections `0x0062ba8c`, `0x0062bae0`, `0x006cfca8`, `0x006cfcb4`, and `0x006cfc9c`. Current grounded callers are the world-entry side around `0x004390ea` and the shell file-load side around `0x004dccfc`.","objdump + RT3.lng strings + caller xrefs + callsite inspection + file-flow correlation + post-load-stage-order correlation" 0x00437743,93,world_preseed_named_candidate_availability_records_from_live_pool,map,cdecl,inferred,objdump + local disassembly + caller correlation,3,"Preliminary post-load candidate-availability prepass reached only from `world_run_post_load_generation_pipeline` `0x004384d0` when the caller requests the fuller setup path. The helper iterates the live candidate pool at `0x0062b268` in reverse order, derives one small boolean mode from candidate bytes `[candidate+0xba]` and `[candidate+0x32]`, and then re-enters `scenario_state_upsert_named_candidate_availability_record_and_refresh_runtime_filters` `0x00434f20` on the active scenario state `0x006cec78` using the candidate name at `+0x04`. The whole pass is skipped once global threshold `0x00620e94` reaches `0x26ad`. Current evidence is therefore strongest for an early scenario-side named candidate-availability seeding pass rather than another visible progress phase.","objdump + local disassembly + caller correlation + candidate-pool correlation" -0x00438890,644,shell_active_mode_run_profile_startup_and_load_dispatch,map,thiscall,inferred,objdump + caller xrefs + debugger comparison,4,"Large active-mode startup and profile-dispatch owner rooted at the live mode object in `0x006cec78`. At entry it clears local state at `[this+0x00]` and `[this+0x4c80]`, posts several shell progress or status updates through `0x5193f0/0x540120`, enumerates one shell-managed list off `0x006d4020+0x429b0`, and then switches over the runtime-profile selector at `[0x006cec7c+0x01]`, which is now clearly a separate seven-way startup selector rather than the shell mode id itself. The jump table has four grounded branch bodies: selector values `1` and `7` share the tutorial map lane at `0x00438f67`, which writes `[0x006cec74+0x6c]=2` and calls shell_map_file_entry_coordinator `0x00445ac0` with `Tutorial_2.gmp` or `Tutorial_1.gmp`; selector `2` is a world-root initialization lane at `0x00438fbe` that allocates `0x0062c120` when absent, runs `0x0044faf0`, and then forces the selector to `3`; selector `4` is the setup-side world reset or regeneration lane at `0x00439038`, which tears down and reallocates `0x0062c120` from setup globals `0x006d14cc/0x006d14d0`, then runs `0x00535100` and `0x0040b830`; and selector values `3`, `5`, and `6` collapse into the same profile-seeded file-load lane at `0x004390b0..0x004390ea`. The write side is tighter now too: `Campaign.win` writes selector `6` at `0x004b8a2f`; `Multiplayer.win` writes selector `3` on one pending-status branch at `0x004f041e`; and the larger `Setup.win` dispatcher around `0x005033d0..0x00503b7b` writes selectors `2`, `3`, `4`, and `5` on several validated launch branches, including the setup-size path through `0x0050394c`, the generation branch at `0x00503a12`, and the profile-file validation branch at `0x00503a74/0x00503a7d`. The shared file-load lane is therefore no longer anonymous: selector `6` is the grounded campaign-side variant and selectors `3/5` are grounded setup or multiplayer variants, while selector `6` is also the only variant that first writes `[0x006cec74+0x6c]=1` before all three values call shell_map_file_entry_coordinator `0x00445ac0` with `([0x006cec7c]+0x11, 4, &out_success)`, re-enter shell service `0x004834e0`, conditionally run world_run_post_load_generation_pipeline `0x004384d0` when `out_success != 0`, drain the counter object at `0x00ccbb20` through `0x0053f310`, and service `0x004834e0` again. The caller split above that branch is tighter now too: `0x004830ca` is the shell startup or `LoadScreen.win` lane and calls this owner as `(1, 0)` after publishing `0x006cec78`, while `0x00443b57` world entry and `0x00446d7f` saved-runtime restore both enter with `(0, 0)` immediately after dismissing the current detail panel and servicing `0x004834e0(0, 0)`. `0x0046b8bc` remains the distinct multiplayer-preview relaunch owner, also entering as `(0, 0)` before a later staged `0x00445ac0` call.","objdump + caller xrefs + manual-load breakpoint comparison + owner-tail disassembly + caller-shape comparison + selector-jump-table decode + tutorial-string correlation + selector-writer correlation" +0x00438890,644,shell_active_mode_run_profile_startup_and_load_dispatch,map,thiscall,inferred,objdump + caller xrefs + debugger comparison,4,"Large active-mode startup and profile-dispatch owner rooted at the live mode object in `0x006cec78`. At entry it clears local state at `[this+0x00]` and `[this+0x4c80]`, posts several shell progress or status updates through `0x5193f0/0x540120`, enumerates one shell-managed list off `0x006d4020+0x429b0`, and then switches over the runtime-profile selector at `[0x006cec7c+0x01]`, which is now clearly a separate seven-way startup selector rather than the shell mode id itself. The jump table has four grounded branch bodies: selector values `1` and `7` share the tutorial map lane at `0x00438f67`, which writes `[0x006cec74+0x6c]=2` and calls shell_map_file_entry_coordinator `0x00445ac0` with `Tutorial_2.gmp` or `Tutorial_1.gmp`; selector `2` is a world-root initialization lane at `0x00438a66..0x00438c00` that first refreshes one support-family type-`7` record from setup path buffer `0x006d1370` through `global_banked_type7_record_refresh_from_openable_path_basename_and_stem` `0x0053d130`, strips the basename extension into a local label buffer, briefly drops the nested mouse-cursor selection hold through `0x0053f310`, builds three progress-text payloads, re-enters the hold through `0x0053f2f0`, and only then allocates `0x0062c120` when absent, runs `0x0044faf0`, and forces the selector to `3`; selector `4` is the setup-side world reset or regeneration lane at `0x00439038`, which tears down and reallocates `0x0062c120` from setup globals `0x006d14cc/0x006d14d0`, then runs `0x00535100` and `0x0040b830`; and selector values `3`, `5`, and `6` collapse into the same profile-seeded file-load lane at `0x004390b0..0x004390ea`. The write side is tighter now too: `Campaign.win` writes selector `6` at `0x004b8a2f`; `Multiplayer.win` writes selector `3` on one pending-status branch at `0x004f041e`; and the larger `Setup.win` dispatcher around `0x005033d0..0x00503b7b` writes selectors `2`, `3`, `4`, and `5` on several validated launch branches, including the setup-size path through `0x0050394c`, the generation branch at `0x00503a12`, and the profile-file validation branch at `0x00503a74/0x00503a7d`. The shared file-load lane is therefore no longer anonymous: selector `6` is the grounded campaign-side variant and selectors `3/5` are grounded setup or multiplayer variants, while selector `6` is also the only variant that first writes `[0x006cec74+0x6c]=1` before all three values call shell_map_file_entry_coordinator `0x00445ac0` with `([0x006cec7c]+0x11, 4, &out_success)`, re-enter shell service `0x004834e0`, conditionally run world_run_post_load_generation_pipeline `0x004384d0` when `out_success != 0`, drain the counter object at `0x00ccbb20` through `0x0053f310`, and service `0x004834e0` again. The caller split above that branch is tighter now too: `0x004830ca` is the shell startup or `LoadScreen.win` lane and calls this owner as `(1, 0)` after publishing `0x006cec78`, while `0x00443b57` world entry and `0x00446d7f` saved-runtime restore both enter with `(0, 0)` immediately after dismissing the current detail panel and servicing `0x004834e0(0, 0)`. `0x0046b8bc` remains the distinct multiplayer-preview relaunch owner, also entering as `(0, 0)` before a later staged `0x00445ac0` call.","objdump + caller xrefs + manual-load breakpoint comparison + owner-tail disassembly + caller-shape comparison + selector-jump-table decode + tutorial-string correlation + selector-writer correlation + selector2-support-record correlation + cursor-hold choreography correlation" 0x00435603,10,scenario_state_ensure_derived_year_threshold_band,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Tiny guard wrapper over one derived scenario-state year-threshold band rooted at `[this+0x3a/+0x51/+0x55/+0x59/+0x5d/+0x61]`. When the small mode or threshold byte at `[this+0x3a]` is already `>= 2` the helper returns immediately; otherwise it falls back into the heavier rebuild body at `0x004351c0`, which refreshes those companion thresholds from the current year and shell-controller-side values before continuing. Current grounded callers are the post-fast-forward selected-year tail at `0x00437170`, the later staged-profile rehydrate band inside `world_entry_transition_and_runtime_bringup` `0x00443a50`, the compact runtime-effect side branch at `0x00431e03`, and the shell-command lane at `0x004661c0/0x004661e9`, so this is the safest current read for the small year-threshold ensure wrapper rather than a generic boolean probe.","objdump + local disassembly + caller correlation + year-threshold-band correlation" 0x00435630,648,scenario_state_rebuild_port_warehouse_cargo_recipe_runtime_tables,map,thiscall,inferred,objdump + caller xrefs + state-layout inspection,4,"Rebuilds the runtime port-or-warehouse cargo-line tables from the scenario-side recipe-book state rooted at `[this+0x0fe7]`. The helper first biases into the recipe-book payload at `[this+0x13d4]`, then iterates all `12` recipe-book blocks in `0x4e1`-byte steps. For each book it clamps the shared maximum annual production float that precedes the first line, counts active lines across five repeated `0x30`-byte line records, and then imports those five lines into one parallel runtime array of `0xbc`-byte descriptors. The importer treats every line slot symmetrically rather than special-casing any row index: each slot reads one mode dword, one annual amount, and two cargo-token strings, resolves nonempty cargo strings through the global cargo collection at `0x0062ba8c`, and builds paired runtime halves for the mode families `2/3` and `1/3`. Current mode gating is now tight enough to treat the polarity as grounded rather than provisional: the source token at `line+0x08` is the supplied-cargo field because it is the branch activated for `Supply Only` and `Production Demand->Supply`, while the source token at `line+0x1c` is the demanded-cargo field because it is the branch activated for `Demand Only` and `Production Demand->Supply`. The constructor and handler now tighten the amount semantics too: `line+0x04` is the per-line annual-demand field only in mode `1`, but it becomes the annual-supply field in modes `2/3`. The importer matches that split by copying `line+0x04` directly into the supply-side runtime half for modes `2/3`, while the production-mode demand half is normalized to `1.0` rather than reusing the entered amount. That makes the five editor-side row entries look like generic cargo-line slots rather than five fixed named production roles. Current grounded callers include the scenario-state initializer at `0x00436ee0`, world-load or map-entry side branches at `0x00443ebc`, `0x00444ac1`, and `0x00448126`, plus the live editor page constructor at `0x004cf935`.","objdump + caller xrefs + state-layout inspection + cargo-collection correlation + mode-table correlation + constructor correlation" 0x00437b20,218,simulation_run_chunked_fast_forward_burst,simulation,thiscall,inferred,objdump,3,"Shell-mediated burst advance helper above simulation_advance_to_target_calendar_point. It marks a local fast-forward latch at `[this+0x46c38]`, derives one loop count from shell-state `0x006cec74+0x178` and active-mode flag `[0x006cec78+0x4af7]`, then repeatedly advances the world toward fixed target `0x05a0` through simulation_advance_to_target_calendar_point while pumping the shell-side service helper at `0x004834e0` between chunks. After the burst it clears the latch, sweeps the world collection at `0x0062bae0`, and tails into the neighboring cleanup path at `0x00434d40`. The current grounded owner is world_run_post_load_generation_pipeline at `0x004384d0`, where the helper sits behind shell-state gate `[0x006cec74+0x178]` under the localized `Seeding Economy...` phase after the earlier transportation-pricing and building-setup work has already run. This keeps the helper on the map or scenario setup side rather than the ordinary player-facing speed-control path.","objdump + caller context + RT3.lng strings + phase ordering" 0x00434680,435,world_set_game_speed_mode,simulation,thiscall,inferred,objdump + strings,3,"Primary game-speed setter for the live world object. It clamps the requested mode against the normal `0..5` range or the wider `0..9` range when shell-state gate `[0x006cec74+0x2c8]` is active, stores the current mode at `[this+0x19]`, preserves the nonzero resume mode at `[this+0x1d]`, updates the shell detail control `0x74` when `0x006d0818` is live, and can format the localized status line `Game Speed: %1` using speed labels `Paused` through `Very Fast` and the hidden `Ultra Fast 6..9` strings. When the caller requests propagation and the multiplayer preview path is active it also routes the new speed through the multiplayer-side handoff around `0x00407870`, which matches the localized restriction `Only the host may change the game speed.`","objdump + RT3.lng strings + multiplayer handoff" 0x00434850,19,world_adjust_game_speed_mode_delta,simulation,thiscall,inferred,objdump,3,"Small relative front end over world_set_game_speed_mode. It adds the signed caller delta to the current mode at `[this+0x19]` and then re-enters world_set_game_speed_mode with both notification and propagation flags enabled.","objdump + callee inspection" +0x004338c0,12,shell_mode_gate_is_active,shell,cdecl,inferred,objdump + local disassembly + caller correlation,3,"Tiny boolean wrapper over the shell-side gate at `0x006d07b4`. The helper simply forwards `0x004d4150`, normalizes the result to `0/1`, and returns. Current grounded callers use it as a coarse mode gate before trusting several scenario-side and runtime-object fields, including the flag-byte readers at `0x0041f910`, `0x00461500`, and `0x00474430`, plus broader world or shell-side branches such as `0x004197e0`, `0x00440e4d`, and `0x0044ccdc`. The exact player-facing owner of `0x006d07b4` is still open, so the safest current name stays structural around one active shell-mode gate.","objdump + local disassembly + caller correlation + gate reuse correlation" +0x00433790,8,scenario_state_set_selected_chairman_company_id,map,thiscall,inferred,objdump + global-state inspection + caller correlation,4,"Tiny raw setter over the shell-side scenario state object at `0x006cec78`. The helper stores the caller-supplied company id directly into `[this+0x21]` and returns. Current grounded callers are the company and chairman reassignment flows at `0x00426dd4`, `0x00427d06`, `0x00427d93`, and the startup-company seeding or rotation paths around `0x0047d282`, `0x0047d409`, and `0x0047d609`, where it keeps the raw selected-company summary in sync with later chairman or ownership changes. This is therefore the direct id-level companion to the higher record accessor `scenario_state_get_selected_chairman_company_record` `0x00434870` rather than a broader state mutator.","objdump + global-state inspection + caller correlation + selected-company-summary correlation" +0x004337a0,4,scenario_state_get_selected_chairman_company_id,map,thiscall,inferred,objdump + global-state inspection + caller correlation,4,"Tiny raw getter over the shell-side scenario state object at `0x006cec78`. The helper returns company id field `[this+0x21]` directly without resolving it through the live company collection. Current grounded callers include the linked-site status formatter `0x0040e4e0`, the company or chairman reassignment families around `0x00426dd4`, `0x004427aac`, and `0x0047d462`, the startup-company seeding branches around `0x0047d4ed`, and many shell-side overview or ledger renderers that compare the current row against the scenario-selected company before choosing text or style. This is therefore the raw selected-company-id accessor beneath the higher record resolver `scenario_state_get_selected_chairman_company_record` `0x00434870`.","objdump + global-state inspection + caller correlation + selected-company-summary correlation" +0x004337b0,4,scenario_state_get_selected_chairman_profile_id,map,thiscall,inferred,objdump + global-state inspection + caller correlation,4,"Tiny raw getter over the shell-side scenario state object at `0x006cec78`. The helper returns chairman profile id field `[this+0x25]` directly without resolving it through the global persona collection. Current grounded callers include the company-detail and load-screen style selectors, chairman rotation or reassignment branches around `0x00427cf4`, `0x00427d80`, `0x004295ef`, and `0x0047d3f9`, and many shell-side renderers that compare the current row's linked chairman against the scenario-selected chairman before choosing visible styling. This is therefore the raw selected-chairman-profile-id accessor beneath the higher record resolver `scenario_state_get_selected_chairman_profile_record` `0x004348c0`.","objdump + global-state inspection + caller correlation + selected-chairman-summary correlation" +0x00433900,160,shell_world_view_center_on_object_with_mode_specific_zoom_policy,shell,cdecl,inferred,objdump + caller xrefs + local disassembly,3,"Mode-aware world-view centering helper above the live world-view owner at `0x0062be68`. The helper takes one object pointer plus one small mode argument. Except for the early mode-`2` no-op path, it first refreshes shell control `0x7922`, derives one `(distance,height)` preset from the target object's virtual classification through slots `+0x70`, `+0x6c`, and `+0x28`, optionally overrides that preset for mode `1`, and then re-enters `world_view_center_on_runtime_object` `0x0043c9a0` with the chosen preset and object pointer. Current grounded callers include the shell station and company list modifier paths, several detail-panel and window-side center actions, the tutorial or event-follow branches around `0x00435b2d` and `0x0044c75e`, and broader shell-side center helpers around `0x00505e0c`, `0x005060f7`, and `0x0051486b`. This is therefore the shared shell-facing center-on-object helper with one caller-selected zoom-policy mode rather than a station-only centering path.","objdump + caller xrefs + local disassembly + world-view-center correlation" +0x004339b0,144,scenario_state_set_investor_confidence_issue_lane_and_refresh_company_support_scalars,simulation,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Clamps one small scenario-side issue lane and refreshes the company-side support scalar family derived from it. The helper clamps the incoming value to `0..4`, stores the result in `[this+0x2d]`, derives one companion float in `[this+0x29]` through the fixed affine mapping at `0x005c85b8/0x005c8658`, and then walks the live company collection at `0x0062be10`, re-entering `company_compute_public_support_adjusted_share_price_scalar` `0x00424fd0` on every live company to refresh the dependent support-side cache. Current grounded callers include the compact runtime-effect dispatcher branch at `0x00431db2`, the local setup or reset lane at `0x00436e05`, and the neighboring scenario-side text or collection refresh branch at `0x00434d23`, which keeps this helper bounded as the shared setter for the investor-confidence-style issue lane beneath equity-support and share-price logic rather than a generic scalar write.","objdump + local disassembly + caller correlation + company-support-refresh correlation" +0x00433850,109,scenario_state_refresh_active_chairman_profiles_with_reentrancy_guard,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Re-entrant-safe refresh dispatcher over the active chairman-profile family. The helper uses globals `0x0062be20` and `0x0062be1c` as a guard plus rerun latch: when no refresh is in progress it raises the guard, clears the rerun latch, walks the global persona collection at `0x006ceb9c` through `profile_collection_count_active_chairman_records` `0x00477820` and `profile_collection_get_nth_active_chairman_record` `0x00477860`, and re-enters `0x004771e0` on each active chairman record before dropping the guard. If any nested path re-raises the rerun latch, the outer loop repeats until the latch stays clear. Current grounded callers include the periodic service branch at `0x0040a7ae`, the chairman cash or tuning adjustment paths at `0x00476541` and `0x004771ca`, and several neighboring company-side mutation branches, so this is the safest current read for the shared active-chairman refresh pass rather than a one-off persona walker.","objdump + local disassembly + caller correlation + active-chairman refresh correlation + reentrancy-guard correlation" 0x00437220,279,world_build_chairman_profile_slot_records,map,thiscall,inferred,objdump + strings + caller xrefs,4,"Post-load chairman-profile materialization pass reached under banner id `319` `Setting up Players and Companies...`. The helper first refreshes one local occupancy map through `0x0047bc80`, optionally waits on the multiplayer preview owner at `0x006cd8d8`, then walks the 16 selector bytes at `[0x006cec7c+0x87]` together with the per-slot staging table rooted at `[this+0x69d8]`. Current slot-field semantics are tighter now: `[slot+0x00]` is the staged chairman profile id, `[slot+0x01]` is the Optional-versus-Mandatory byte with nonzero=`Optional` and zero=`Mandatory`, `[slot+0x02]` is the ordinary seat-enable byte that combines with the separate per-slot gate at `[this+0x0bc3+slot*9]` to surface `Human`, `Computer`, and `Human or Computer`, `[slot+0x03]` is the special occupied-seat byte, and `[slot+0x04]` is the numeric tuning field copied into the resolved profile. Zero selectors take the random unused-profile path; nonzero selectors map directly onto one persona index; and campaign mode at `[0x006cec7c+0xc5]` can override back through the scenario slot table. Each resolved profile record is pulled from the global persona collection at `0x006ceb9c`, formatted through `0x0050a16f`, and seeded from the static persona table at `0x005f2d28`, whose localized ids include `2730` `Unassigned`, the named-chairman range `2731+`, and the adjacent biography range `2495+`. Both this helper and the neighboring selector seeder treat either `[slot+0x02]` or `[slot+0x03]` as enough to keep a slot live, but current grounded writes only seed `[slot+0x03]` on slot zero and later move it solely by whole-record compaction. That makes `[slot+0x03]` the strongest current anchor for the distinguished primary-human-seat marker rather than a generic role byte. The helper leaves one per-slot record family live in the resolved persona objects, stores per-profile numeric tuning from `[slot+0x04]` into `[profile+0x154]` and `[profile+0x158]`, and finishes by writing the selected profile id to `[this+0x25]` plus the linked owner-company id from `[profile+0x1dd]` to `[this+0x21]`. Current grounded callers are the main post-load generation pipeline at `0x004384d0` and the saved-runtime tail inside `world_entry_transition_and_runtime_bringup` `0x00443a50`.","objdump + RT3.lng strings + caller xrefs + table inspection + shell editor cross-check" 0x004377a0,693,world_seed_default_chairman_profile_slots,map,thiscall,inferred,objdump + caller xrefs + strings,4,"Seeds the 16 scenario-side chairman selector bytes at `[0x006cec7c+0x87]` from the local chairman-slot table rooted at `[this+0x69d8]` before the later profile-record materialization pass runs. In editor-map mode the helper first compacts the 16 local 9-byte slot records so occupied slots bubble forward whenever a later slot has either the ordinary seat-enable byte `[slot+0x02]` or the special occupied-seat byte `[slot+0x03]` set and an earlier slot has neither; it then clears selectors for empty slots and assigns deterministic defaults for occupied ones, using selector `1` for the first occupied slot and selector `0x64+n` for later occupied slots. The same slot layout is now bounded more tightly by the editor window family around `0x004cc2d0`: `[slot+0x00]` is the staged chairman profile id, `[slot+0x01]` is the Optional-versus-Mandatory flag with nonzero=`Optional` and zero=`Mandatory`, `[slot+0x02]` is the ordinary seat-enable byte, `[slot+0x03]` is the special occupied-seat byte, and `[slot+0x04]` is the numeric tuning field. Current grounded writes seed `[slot+0x03]` on slot zero and the compaction pass moves it only by swapping whole 9-byte records, which matches the selector policy: one distinguished first slot gets selector `1`, and the remaining occupied slots get the `0x64+n` opponent range. After the selector seeding pass it walks the selector array, resolves each chosen persona through the global collection at `0x006ceb9c`, constructs or refreshes the per-profile record through `0x00476140`, copies the numeric tuning field from `[slot+0x04]` into `[profile+0x154]` and `[profile+0x158]`, and finally seeds the scenario-state summary pair from the first persona entry: `[this+0x25]` becomes the selected profile id while `[this+0x21]` becomes the linked owner-company id through `[profile+0x1dd]`. Current grounded caller is the neighboring world bring-up path around `0x00438692`, where this helper runs after the setup-side burst branch and immediately before the localized `Calculating Heights...` progress update.","objdump + caller xrefs + RT3.lng strings + slot-table inspection + shell editor cross-check" 0x00434870,23,scenario_state_get_selected_chairman_company_record,map,thiscall,inferred,objdump + global-state inspection,4,"Returns the currently selected company record for the shell-side scenario state object at `0x006cec78`. The helper reads `[this+0x21]` as a company id and resolves that id through the live company collection at `0x0062be10`; zero or negative ids return null. This is the clearest direct accessor yet for the summary field written by the post-load chairman-profile lane.","objdump + global-state inspection + caller correlation" 0x00434890,35,scenario_state_set_selected_chairman_profile,map,thiscall,inferred,objdump + global-state inspection,4,"Sets the currently selected chairman profile on the shell-side scenario state object at `0x006cec78`. The helper stores the incoming persona id into `[this+0x25]`, resolves that persona through the global profile collection at `0x006ceb9c`, and then copies the linked owner-company id from `[profile+0x1dd]` into `[this+0x21]`. This grounds the summary pair used by the post-load chairman-profile setup lane: `[state+0x25]` is the selected chairman profile id and `[state+0x21]` is the corresponding owning company id.","objdump + global-state inspection + caller correlation" 0x004348c0,23,scenario_state_get_selected_chairman_profile_record,map,thiscall,inferred,objdump + global-state inspection,4,"Returns the currently selected chairman profile record for the shell-side scenario state object at `0x006cec78`. The helper reads `[this+0x25]` as a profile id and resolves it through the global persona collection at `0x006ceb9c`; zero or negative ids return null. This pairs directly with scenario_state_set_selected_chairman_profile at `0x00434890`.","objdump + global-state inspection + caller correlation" +0x004337c0,128,scenario_state_append_runtime_effect_or_queue_record,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Allocates one zeroed `0x20`-byte node through `0x005a125d`, copies one caller-supplied string or payload seed into `[node+0x04..]` through `0x0051d820`, stores six further caller dwords at `[node+0x08..+0x1c]`, and appends the finished node to the singly linked list rooted at `[this+0x66a6]`. Current grounded callers include `world_region_collection_pick_periodic_candidate_region_and_queue_scaled_event_record` `0x00422100`, which appends literal-kind-`7` records keyed by one chosen class-0 region id and scaled amount, plus the shell-facing side path inside `world_region_try_place_candidate_structure` `0x00422ee0`, several startup-company branches around `0x0047d282/0x0047d409/0x0047d609`, and the broader runtime-effect service family. The exact gameplay label of this linked `0x20`-byte record family is still open, so the safest current name stays structural around appending one runtime-effect or queue record node beneath scenario state.","objdump + local disassembly + caller correlation + queue-node-list correlation" 0x00436590,372,scenario_state_compute_issue_opinion_multiplier,simulation,thiscall,inferred,objdump + caller inspection,4,"Computes one bounded opinion multiplier for a caller-selected issue slot on the active scenario or shell state rooted at `0x006cec78`. The helper starts from the base issue term at `[this + issue*4 + 0x8a]`, clamps that raw value to a floor of `-99`, normalizes it into a multiplier around `1.0`, and then optionally folds in up to three issue-specific override tables: a company-side term from `[company + issue*4 + 0x35b]`, a chairman-profile term from `[profile + issue*4 + 0x2ab]`, and a territory-side term from `[territory + issue*4 + 0x3b5]`. When the profile argument is omitted but a valid company is supplied, it implicitly reuses that company's linked chairman id from `[company+0x3b]`. The final multiplier is clamped to a small positive floor near `0.01` before return. Current grounded callers include the broader support-adjusted share-price helper at `0x00424fd0`, the merger vote resolver at `0x004ebd10` with issue id `0x3a`, and several other company-policy and shell-side opinion branches. The merger-side `0x3a` use now lines up directly with `RT3.lng` id `726`, which says public merger votes depend on their attitude toward the management of the two companies, so this issue slot is now best read as the merger-management-attitude multiplier.","objdump + caller inspection + issue-table correlation + merger-text correlation" 0x004768c0,53,chairman_profile_owns_all_company_shares,simulation,thiscall,inferred,objdump + caller inspection,4,"Boolean ownership predicate over one chairman profile and company id. The helper resolves the requested company through the live company collection at `0x0062be10`, reads the company's full outstanding-share count from `[company+0x47]`, and compares it against the current profile's holding slot for that same company at `[profile + company_id*4 + 0x15d]`. It returns `1` only when the profile holds the full outstanding-share band and `0` otherwise. Current grounded caller is the CompanyDetail section-0 overview formatter at `0x004e5cf0`, where this is the decision point between the wholly-owned text family `3046/3047` and the investor-attitude text family `3048/3049`.","objdump + caller inspection + ownership-predicate correlation" 0x00436710,163,scenario_state_sum_issue_opinion_terms_raw,simulation,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Raw additive companion to `scenario_state_compute_issue_opinion_multiplier` on the active scenario or shell state rooted at `0x006cec78`. The helper starts from the base issue term at `[this + issue*4 + 0x8a]`, then optionally adds the company override term at `[company + issue*4 + 0x35b]`, the chairman-profile override term at `[profile + issue*4 + 0x2ab]`, and the territory override term at `[territory + issue*4 + 0x3b5]` without normalizing or clamping the result into a multiplier. When the profile argument is omitted but a valid company is supplied, it implicitly reuses that company's linked chairman id from `[company+0x3b]`. Current grounded callers include the city-connection bonus lane through `company_compute_issue39_opinion_bias_scalar` at `0x00424580` and several neighboring policy or setup branches that treat the returned integer as one raw issue-opinion total rather than a finished probability or vote scalar.","objdump + caller xrefs + callsite inspection + issue-table correlation + raw-sum correlation" @@ -436,6 +479,55 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00444dc5,11,world_query_global_stage_counter_reached_late_reactivation_threshold,map,cdecl,inferred,objdump + caller inspection + threshold correlation,3,"Tiny signed compare helper over the shared stage counter at `0x00620e94`. It returns the raw comparison against threshold `0x9901`, so current callers only test whether the counter is still below that later reactivation threshold. Grounded callers are the two late world-entry checkpoints at `0x00444044` and `0x00444a83` inside `world_entry_transition_and_runtime_bringup` `0x00443a50`, where a negative result clears `[world+0x39]`. Nearby evidence also shows the same global is seeded to `0x26ad` by `map_bundle_open_reference_databases` `0x00444dd0`, copied into save-side payload state around `0x00441ec5`, and reused as the earlier preseed cutoff by `world_preseed_named_candidate_availability_records_from_live_pool` `0x00437743`, so the safest current read is a shared stage-threshold comparator rather than a one-off world-field helper.","objdump + caller inspection + threshold correlation + global-stage-counter correlation" 0x0044c670,2544,world_service_secondary_grid_marked_cell_overlay_cache,map,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Recurring world-side service pass over the secondary raster rooted at `[this+0x2135]` after `world_scan_secondary_grid_marked_cell_bounds` `0x0044ce60` has cached min/max/count bounds into `[this+0x21c6..+0x21d6]`. The helper first requires shell-state gate `[0x006cec78+0x4af3]`, then consumes the cached bounds to normalize the marked-cell band and rewrite per-cell bits in the same secondary raster. Its later overlay side is tighter now too: after resolving scaled surface dimensions through `shell_world_presentation_query_scaled_surface_dimensions` `0x00534c50`, it walks one local 3-by-32 sample lattice through the static offset tables at `0x00624b28/0x00624b48`, keeps only secondary-raster classes `4..0x0d`, folds several interpolated samples through repeated `0x0051db80` evaluation into one strongest local score, writes packed overlay pixels into the staged surface buffer, and only then publishes that staged overlay through `shell_world_presentation_publish_staged_overlay_surfaces_and_release_buffer` `0x00534af0`. The lower helper cluster beneath that owner is now explicit too: `0x00533e70` clears coarse overlay chunks in a rectangle, `0x00534160` ensures one coarse chunk and seeds local marks, and `0x00534e90` is the neighboring marked-bit predicate over the same 3-byte raster family. Current grounded callers are the recurring simulation-maintenance route-style branch at `0x0040a9f4` inside `simulation_service_periodic_boundary_work` `0x0040a590` and one startup-side world branch at `0x00448168`, so this is the safest current read for the shared secondary-grid marked-cell overlay-cache service rather than a one-shot startup helper or a fully player-facing panel renderer.","objdump + local disassembly + caller inspection + secondary-raster correlation + recurring-maintenance correlation + staged-overlay publish correlation" 0x00443a50,4979,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` `0x00445ac0`. The function boundary is now grounded as the full `0x00443a50..0x00444dc2` bringup span rather than just the early transition head. It stages the selected file path into `0x0062bee0`, dismisses the shell detail-panel controller at `0x006d0818`, drives `shell_transition_mode` through `0x00482ec0`, and resets the previous world bundle through `world_runtime_release_global_services` plus the neighboring startup-profile owner `0x00438890`. After the transition wait it builds temporary bundle payloads from `%1\\%2` and `%1.tmp`, allocates or serializes 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 continues through the larger post-load generation pipeline instead of returning immediately. The later `319` tail is tighter now too: before the final world and shell reactivation it runs one post-bundle status-and-runtime-refresh phase that posts shell progress ids `0x196` and `0x197` through `0x005193f0/0x00540120` with paired `0x004834e0` follow-ons, refreshes event runtime records through `scenario_event_collection_refresh_runtime_records_from_packed_state` `0x00433130`, rebuilds the scenario-side port-or-warehouse cargo recipe runtime tables through `scenario_state_rebuild_port_warehouse_cargo_recipe_runtime_tables` `0x00435630`, runs the named-candidate availability preseed through `world_preseed_named_candidate_availability_records_from_live_pool` `0x00437743`, and then enters one later staged-profile or availability rehydrate band before the broader reactivation sweep. That rehydrate band posts progress ids `0x32dc/0x3714/0x3715`, reads one `0x108`-byte packed profile block through `0x00531150`, conditionally copies staged runtime-profile bytes from the loaded bundle back into `0x006cec7c` when latch `[profile+0x97]` is set, mirrors the grounded campaign-scenario bit `[profile+0xc5]` and sandbox bit `[profile+0x82]` into world bytes `[world+0x66de]` and `[world+0x66f2]`, restores the selected year or profile choice lane through `[profile+0x77]` into `[world+0x05/+0x09/+0x15]`, and then rehydrates the named locomotive-availability collection at `[world+0x66b6]` before the later world-wide service passes continue. That later reactivation tail is narrower now too: it includes `world_clear_and_reseed_region_center_world_grid_flag_bit` `0x0044c4b0`, then `world_rebuild_all_grid_cell_candidate_cargo_service_bitsets` `0x0044c450`, then `world_scan_secondary_grid_marked_cell_bounds` `0x0044ce60`, then the recurring secondary-raster overlay-cache service `world_service_secondary_grid_marked_cell_overlay_cache` `0x0044c670`, before the later route-style rebuild, shell-window, and briefing branches. Only after that later tail does it re-enter the one-shot world-entry runtime-effect service through `scenario_event_collection_service_runtime_effect_records_for_trigger_kind` `0x00432f40` with kind `8`, after which shell-profile latch `[0x006cec7c+0x97]` is cleared. This is therefore the current safest read for the full shell-to-gameplay world-entry transition and runtime bringup owner rather than only the front half of file staging and world allocation.","objdump + analysis-context + caller xrefs + strings + post-load-pipeline correlation + late-tail phase-order correlation + staged-profile-rehydrate correlation" +0x00440530,46,shell_open_or_focus_detail_panel_mode_0x0b_if_allowed,shell,cdecl,inferred,objdump + caller inspection + shell-detail correlation,3,"Direct shell command branch that opens one still-unresolved shell detail-panel mode `0x0b`. The helper first requires the live detail-panel controller at `0x006d0818` and active scenario root `0x006cec78`, then re-enters `shell_can_open_detail_panel_mode_0x0b_or_warn` `0x00434db0`; on success it forwards `(-1, 0x0b)` into `shell_detail_panel_transition_manager` `0x004ddbd0`. Current grounded companion caller is the page-side launcher at `0x004de49a`, which uses the same gate and mode. This is therefore the safest current read for the direct mode-`0x0b` opener rather than a tighter family name we have not yet grounded.","objdump + caller inspection + shell-detail correlation + mode-transition correlation" +0x00440560,22,shell_open_or_focus_detail_panel_mode_0x01_if_present,shell,cdecl,inferred,objdump + local disassembly + shell-detail correlation,2,"Tiny direct shell command stub over the live detail-panel controller at `0x006d0818`. When that controller exists, the helper forwards `(-1, 1)` into `shell_detail_panel_transition_manager` `0x004ddbd0` and otherwise returns immediately. Current local evidence is only strong enough for the structural mode-`1` opener, not for a tighter family name.","objdump + local disassembly + shell-detail correlation" +0x00440580,22,shell_open_or_focus_detail_panel_mode_0x04_if_present,shell,cdecl,inferred,objdump + local disassembly + shell-detail correlation,2,"Tiny direct shell command stub over the live detail-panel controller at `0x006d0818`. When that controller exists, the helper forwards `(-1, 4)` into `shell_detail_panel_transition_manager` `0x004ddbd0` and otherwise returns immediately. Current local evidence is only strong enough for the structural mode-`4` opener, not for a tighter family name.","objdump + local disassembly + shell-detail correlation" +0x004405a0,46,shell_open_or_focus_company_list_panel_if_allowed,shell,cdecl,inferred,objdump + caller inspection + shell-detail correlation,4,"Direct shell command branch that opens the company-list panel through detail-panel mode `7`. The helper first requires the live detail-panel controller at `0x006d0818` and active scenario root `0x006cec78`, then re-enters `shell_can_open_company_list_or_detail_panel_or_warn` `0x00433a40`; on success it forwards `(-1, 7)` into `shell_detail_panel_transition_manager` `0x004ddbd0`. Current grounded companion caller is the page-side command strip at `0x004de2dd`, which uses the same gate and mode. This is therefore the safest current read for the direct company-list opener rather than a generic mode-toggle stub.","objdump + caller inspection + shell-detail correlation + mode-transition correlation" +0x004405d0,126,shell_open_or_focus_selected_company_detail_panel_with_start_company_fallback,shell,cdecl,inferred,objdump + caller inspection + company-detail correlation,4,"Direct shell command branch above the selected-company `CompanyDetail.win` lane. The helper first requires the live detail-panel controller at `0x006d0818`; if no selected-company id is available through `scenario_state_get_selected_chairman_company_id` `0x004337a0`, it raises localized id `368` through the shared shell modal path and, when the current chairman still passes `0x00476d10`, it offers the `Start New Company` dialog through `0x0047d080` before retrying the selected-company lookup. Once a selected-company id exists it re-enters `shell_can_open_company_list_or_detail_panel_or_warn` `0x00433a40` and then forwards `(selected_company_id, 8)` into `shell_detail_panel_transition_manager` `0x004ddbd0`. Current grounded companion caller is the load-screen side launcher strip at `0x004de3a8`, which shares the same gate, fallback dialog, and selected-company handoff. This is therefore the safest current read for the direct selected-company-detail opener with start-company fallback rather than a generic company-command branch.","objdump + caller inspection + company-detail correlation + start-company fallback correlation + mode-transition correlation" +0x00440660,46,shell_open_or_focus_stockbuy_window_for_selected_company_if_allowed,shell,cdecl,inferred,objdump + caller inspection + stockbuy correlation,4,"Direct shell command branch that opens the shell-side `StockBuy.win` family through detail-panel mode `0x0c`. The helper first requires the live detail-panel controller at `0x006d0818` and active scenario root `0x006cec78`, then re-enters `shell_can_open_stockbuy_window_or_warn` `0x00433aa0`; on success it forwards `(-1, 0x0c)` into `shell_detail_panel_transition_manager` `0x004ddbd0`. The later same-mode refresh tail inside `0x004ddbd0` also special-cases mode `0x0c` through `0x00493150`, which keeps this on the `StockBuy.win` family rather than another company-side page. Current grounded companion caller is the page-side launcher at `0x004de50f`.","objdump + caller inspection + stockbuy correlation + mode-transition correlation + same-mode-refresh correlation" +0x00440690,46,shell_open_or_focus_detail_panel_mode_0x06_if_allowed,shell,cdecl,inferred,objdump + caller inspection + shell-detail correlation,3,"Direct shell command branch that opens one still-unresolved shell detail-panel mode `0x06`. The helper first requires the live detail-panel controller at `0x006d0818` and active scenario root `0x006cec78`, then re-enters `shell_can_open_detail_panel_mode_0x06_or_warn` `0x00434e20`; on success it forwards `(-1, 0x06)` into `shell_detail_panel_transition_manager` `0x004ddbd0`. Current grounded companion caller is the page-side launcher at `0x004de27a`, which uses the same gate and mode. This is therefore the safest current read for the direct mode-`0x06` opener rather than a tighter family name we have not yet grounded.","objdump + caller inspection + shell-detail correlation + mode-transition correlation" +0x004406c0,51,shell_open_or_focus_trainbuy_window_if_allowed,shell,cdecl,inferred,objdump + caller inspection + trainbuy correlation,4,"Direct shell command branch above the shell-side `Trainbuy.win` family. The helper first requires the live detail-panel controller at `0x006d0818` and active scenario root `0x006cec78`, then re-enters `shell_can_open_trainbuy_window_or_warn` `0x00433b00`; on success it calls `shell_open_or_focus_trainbuy_window` `0x00512c50` with the fixed singleton-open argument set used by the same family elsewhere. Current grounded companion caller is the page-side launcher at `0x004de7d9`, which shares the same gate and opener. This is therefore the safest current read for the direct train-buy opener rather than a generic shell command stub.","objdump + caller inspection + trainbuy correlation + singleton-open correlation" +0x00440700,22,shell_open_or_focus_load_screen_page_1_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `1` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table already grounds page `1` as the company-overview wrapper.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440720,22,shell_open_or_focus_load_screen_page_3_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `3` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `3` as the income-statement slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440740,22,shell_open_or_focus_load_screen_page_4_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `4` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `4` as the balance-sheet slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440760,22,shell_open_or_focus_load_screen_page_5_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `5` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `5` as the haulage-report slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440780,22,shell_open_or_focus_load_screen_page_6_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `6` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `6` as the stock-data slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x004407a0,22,shell_open_or_focus_load_screen_page_0x0a_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `0x0a` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `0x0a` as the train-list slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x004407c0,22,shell_open_or_focus_load_screen_page_0x0c_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `0x0c` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `0x0c` as the station-list slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x004407e0,22,shell_open_or_focus_load_screen_page_0x0f_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `0x0f` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `0x0f` as the industry-list slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440800,22,shell_open_or_focus_load_screen_page_0x0e_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `0x0e` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `0x0e` as the cargo-list slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440820,22,shell_open_or_focus_load_screen_page_2_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `2` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `2` as the company-list slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440840,22,shell_open_or_focus_load_screen_page_7_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `7` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `7` as the player-list slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440860,22,shell_open_or_focus_load_screen_page_9_if_scenario_active,shell,cdecl,inferred,objdump + local disassembly + load-screen correlation,3,"Tiny direct shell command stub above `shell_open_or_focus_load_screen_page` `0x004e4ee0`. When the active scenario root `0x006cec78` exists, the helper requests ledger page `9` and otherwise returns immediately. The later `LoadScreen.win` page descriptor table grounds page `9` as the game-status slice.","objdump + local disassembly + load-screen correlation + page-table correlation" +0x00440880,35,shell_toggle_pause_or_restore_game_speed_and_emit_feedback_nudge,shell,cdecl,inferred,objdump + caller inspection + game-speed correlation,2,"Tiny shell command stub over the active scenario root `0x006cec78`. When the scenario object exists, the helper first re-enters `world_toggle_pause_or_restore_game_speed` `0x00437a60` with caller flag `1`, then immediately re-enters the indexed shell feedback helper `0x0045ea20` with selector `0x2c` and scalar `0.5f`. Current local evidence is only strong enough for the pause-toggle plus feedback-nudge structure, not for a tighter player-facing label for the second helper.","objdump + caller inspection + game-speed correlation + feedback-helper correlation" +0x004408b0,21,shell_invoke_world_bundle_coordinator_with_zero_flag_triplet_if_scenario_active,shell,cdecl,inferred,objdump + caller inspection + bundle-coordinator correlation,2,"Tiny shell command stub above `shell_map_file_world_bundle_coordinator` `0x00445de0`. When the active scenario root `0x006cec78` exists, the helper forwards three zero stack arguments into that coordinator and otherwise returns immediately. Current local evidence is only strong enough for the structural zero-flag-triplet wrapper, not for the exact user-facing command name.","objdump + caller inspection + bundle-coordinator correlation" +0x004408d0,21,shell_invoke_world_bundle_coordinator_with_flag_triplet_0_1_0_if_scenario_active,shell,cdecl,inferred,objdump + caller inspection + bundle-coordinator correlation,2,"Tiny shell command stub above `shell_map_file_world_bundle_coordinator` `0x00445de0`. When the active scenario root `0x006cec78` exists, the helper forwards stack flags `(0, 1, 0)` into that coordinator and otherwise returns immediately. Current local evidence is only strong enough for that structural flag-triplet wrapper, not for the exact user-facing command name.","objdump + caller inspection + bundle-coordinator correlation" +0x004408f0,207,shell_assign_camera_view_slot_and_publish_confirmation,shell,cdecl,inferred,objdump + command-registration correlation + world-view correlation,4,"Direct shell command branch for the camera-view assignment family. The helper requires the live world-view owner at `0x0062be68`, stores one camera-view snapshot into the selected slot through `world_view_store_camera_view_slot_snapshot` `0x0043b2c0`, formats one slot label through `0x0051b700`, localizes ids `369` and `370` through `0x005193f0`, resolves one optional current focus label through `0x0045f3d0`, and finally publishes a two-line shell modal through the shared shell modal owner `0x004554e0`. Current direct wrappers `0x00440b00..0x00440b90` map the slot selector in `ECX` to camera views `1..9` and `0`, and the shell command-registration block at `0x0046092f..0x00460cab` ties those wrappers to the localized `Assign Camera View 1..9` and `Assign Camera View 0` command strip. This is therefore the safest current read for the shared camera-view assignment owner rather than a generic world-view modal helper.","objdump + command-registration correlation + world-view correlation + shell-modal correlation + slot-wrapper correlation" +0x004409c0,303,shell_select_camera_view_slot_or_publish_unassigned_warning,shell,cdecl,inferred,objdump + command-registration correlation + world-view correlation,4,"Direct shell command branch for the camera-view selection family. The helper first requires the live world-view owner at `0x0062be68`, then re-enters `world_view_restore_camera_view_slot_snapshot_if_populated` `0x0043ca20`. When the selected slot is populated the restore helper updates the live world-view immediately and this wrapper returns without opening a modal. When the slot is still unassigned, the wrapper formats one slot label through `0x0051b700`, localizes ids `371`, `372`, and `373` through `0x005193f0`, resolves up to two optional focus-label strings through repeated `0x0045f3d0` calls, and then publishes the resulting three-line warning through `0x004554e0`. Current direct wrappers `0x00440ba0..0x00440c30` map the slot selector in `ECX` to camera views `1..9` and `0`, and the shell command-registration block at `0x00460903..0x00460c7a` ties those wrappers to the localized `Select Camera View 1..9` and `Select Camera View 0` command strip. This is therefore the safest current read for the shared camera-view selection owner rather than a generic world-view restore path.","objdump + command-registration correlation + world-view correlation + shell-modal correlation + slot-wrapper correlation" +0x00440b00,12,shell_assign_camera_view_1,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `1` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x00460939` ties this wrapper to localized command id `3475`, the `Assign Camera View 1` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b10,12,shell_assign_camera_view_2,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `2` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x0046099c` ties this wrapper to localized command id `3477`, the `Assign Camera View 2` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b20,12,shell_assign_camera_view_3,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `3` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x004609fe` ties this wrapper to localized command id `3479`, the `Assign Camera View 3` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b30,12,shell_assign_camera_view_4,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `4` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x00460a60` ties this wrapper to localized command id `3481`, the `Assign Camera View 4` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b40,12,shell_assign_camera_view_5,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `5` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x00460ac2` ties this wrapper to localized command id `3483`, the `Assign Camera View 5` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b50,12,shell_assign_camera_view_6,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `6` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x00460b24` ties this wrapper to localized command id `3485`, the `Assign Camera View 6` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b60,12,shell_assign_camera_view_7,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `7` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x00460b86` ties this wrapper to localized command id `3487`, the `Assign Camera View 7` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b70,12,shell_assign_camera_view_8,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `8` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x00460be8` ties this wrapper to localized command id `3489`, the `Assign Camera View 8` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b80,12,shell_assign_camera_view_9,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `9` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x00460c4a` ties this wrapper to localized command id `3491`, the `Assign Camera View 9` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440b90,9,shell_assign_camera_view_0,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_assign_camera_view_slot_and_publish_confirmation` `0x004408f0`. It fixes slot selector `0` in `ECX` before tail-jumping into the shared assignment owner. The command-registration block at `0x00460cac` ties this wrapper to localized command id `3493`, the `Assign Camera View 0` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440ba0,12,shell_select_camera_view_1,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `1` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x00460909` ties this wrapper to localized command id `3474`, the `Select Camera View 1` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440bb0,12,shell_select_camera_view_2,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `2` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x0046096b` ties this wrapper to localized command id `3476`, the `Select Camera View 2` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440bc0,12,shell_select_camera_view_3,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `3` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x004609cd` ties this wrapper to localized command id `3478`, the `Select Camera View 3` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440bd0,12,shell_select_camera_view_4,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `4` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x00460a2f` ties this wrapper to localized command id `3480`, the `Select Camera View 4` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440be0,12,shell_select_camera_view_5,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `5` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x00460a91` ties this wrapper to localized command id `3482`, the `Select Camera View 5` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440bf0,12,shell_select_camera_view_6,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `6` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x00460af3` ties this wrapper to localized command id `3484`, the `Select Camera View 6` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440c00,12,shell_select_camera_view_7,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `7` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x00460b55` ties this wrapper to localized command id `3486`, the `Select Camera View 7` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440c10,12,shell_select_camera_view_8,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `8` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x00460bb7` ties this wrapper to localized command id `3488`, the `Select Camera View 8` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440c20,12,shell_select_camera_view_9,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `9` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x00460c19` ties this wrapper to localized command id `3490`, the `Select Camera View 9` slot.","objdump + command-registration correlation + wrapper inspection" +0x00440c30,9,shell_select_camera_view_0,shell,cdecl,inferred,objdump + command-registration correlation + wrapper inspection,2,"Tiny wrapper over `shell_select_camera_view_slot_or_publish_unassigned_warning` `0x004409c0`. It fixes slot selector `0` in `ECX` before tail-jumping into the shared selection owner. The command-registration block at `0x00460c7b` ties this wrapper to localized command id `3492`, the `Select Camera View 0` slot.","objdump + command-registration correlation + wrapper inspection" +0x004422d0,96,shell_status_stack_push_four_shell_dwords_and_startup_byte,shell,cdecl,inferred,objdump + caller xrefs + local disassembly,3,"Small status-stack push helper rooted at the local ring or stack `0x0062be90` with depth index `0x0062bedc`. The helper snapshots five live status lanes into one `5`-byte slot selected by the current depth: shell dwords `[0x006cec74+0x140]`, `[+0x13c]`, `[+0x138]`, and `[+0x144]`, plus startup byte `[0x006cec78+0x4c74]`, then increments the depth. Current grounded callers include the heavier wrappers `0x004423a0`, the live-world save path inside `world_entry_transition_and_runtime_bringup` `0x00443a50`, and one neighboring save-load branch at `0x00446d40`, so this is the safest current read for the shared shell or startup status-band push beneath save-load and world-tool choreography rather than a file-family-specific helper.","objdump + caller xrefs + local disassembly + status-stack correlation" +0x00442330,112,shell_status_stack_pop_restore_four_shell_dwords_and_startup_byte,shell,cdecl,inferred,objdump + caller xrefs + local disassembly,3,"Small status-stack pop helper paired with `shell_status_stack_push_four_shell_dwords_and_startup_byte` `0x004422d0`. The helper decrements stack depth `0x0062bedc`, restores the same five status lanes from the selected `0x0062be90` slot back into shell dwords `[0x006cec74+0x140/+0x13c/+0x138/+0x144]` and startup byte `[0x006cec78+0x4c74]`, and returns. Current grounded callers include the higher wrapper `0x004423d0`, the live-world save path inside `world_entry_transition_and_runtime_bringup` `0x00443a50`, and one neighboring save-load branch at `0x00446d40`, so this is the safest current read for the shared status-band restore beneath save-load and world-tool choreography rather than an ordinary shell-mode setter.","objdump + caller xrefs + local disassembly + status-stack correlation" +0x004423a0,48,shell_status_stack_push_and_service_active_tracklay_and_stationplace_tools,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Shared higher wrapper over the same shell/startup status-band stack. It first re-enters `shell_status_stack_push_four_shell_dwords_and_startup_byte` `0x004422d0`, then, when the live TrackLay.win tool object at `0x006d1a8c` is present, calls `0x0050e070`, and when the live StationPlace.win tool object at `0x006d1720` is present, tail-jumps into `0x00507a50`. Current grounded callers include the city-connection route builder `0x00402cb0`, the periodic simulation-side tool wrapper `0x0040a9c0`, the live `.smp` serializer `0x00446240`, and the neighboring collection-side world branch `0x0046b9f0`, so this is the safest current read for pushing the shared status band and then bracketing active world-tool windows rather than another generic shell transition helper.","objdump + caller xrefs + local disassembly + tool-window correlation + status-stack correlation" +0x004423d0,48,shell_status_stack_pop_restore_and_service_active_stationplace_and_tracklay_tools,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Shared higher restore wrapper paired with `0x004423a0`. It first re-enters `shell_status_stack_pop_restore_four_shell_dwords_and_startup_byte` `0x00442330`, then, when the live StationPlace.win tool object at `0x006d1720` is present, calls `station_place_window_service_frame` `0x0050a530`, and when the live TrackLay.win tool object at `0x006d1a8c` is present, tail-jumps into `track_lay_window_service_frame` `0x0050e1e0`. Current grounded callers include the periodic simulation-side tool wrapper `0x0040a9c0`, the live `.smp` serializer `0x00446240`, the neighboring save-load path `0x00446d40`, and the collection-side world branch `0x0046b9f0`, so this is the safest current read for restoring the shared shell/startup status band and then servicing active world-tool windows rather than a generic post-frame notifier.","objdump + caller xrefs + local disassembly + tool-window correlation + status-stack correlation" 0x00442400,930,shell_setup_load_selected_profile_bundle_into_payload_record,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Setup-side payload loader beneath `shell_setup_window_publish_selected_profile_labels_and_preview_surface` `0x00502220`. The helper takes one staged profile-path seed in `ECX`, one destination payload record in `EDX`, and one small caller flag on the stack; clears the full `0x100f2`-byte payload record; builds one rooted input path from either the default setup file-root query at `0x004839e0` or the caller's alternate root override; opens that bundle through `0x00530c80`; and then branches on `shell_setup_query_file_list_uses_map_extension_pattern` `0x004839b0` to read the structured chunk families through `0x00531150` and `0x00531360`. The ordinary saved-profile side reads the smaller startup payload and preview-surface chunks rooted at ids `0x0001` and `0x03c2`, while the map-style side reads the larger setup payload chunks rooted at ids `0x0004`, `0x2ee0`, and `0x2ee1`, with the exact chunk mix gated by the parsed bundle-header word in the local scratch. Current grounded caller is `0x00502220`, which immediately follows this helper by copying payload fields `+0x14/+0x3b2/+0x3ba/+0x20` into the staged runtime profile through `0x0047be50`.","objdump + local disassembly + caller inspection + chunk-family correlation" 0x004425d0,139,shell_setup_validate_selected_profile_bundle_and_stage_launch_profile,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Validated setup-profile launch helper above shell request `0x0cc`. It allocates one large local scratch block, re-enters `shell_setup_load_selected_profile_bundle_into_payload_record` `0x00442400` on the caller path seed, and only proceeds when the loaded payload carries a nonzero leading byte. On success it force-stages runtime-profile byte `[0x006cec7c+0xc5] = 1`, copies payload byte `+0x22` into profile `+0xc4`, copies payload byte `+0x33` into profile `+0x7d`, mirrors the payload token block `+0x23..+0x32` into profile `+0xc6..+0xd5`, and then issues shell request `0x0cc` through `0x0054e790`. Current grounded callers are the validated setup launch controls inside `shell_setup_window_handle_message` `0x005033d0`, where selector-`3` and selector-`5` siblings share this same staging bridge before the later startup-profile owner runs.","objdump + local disassembly + caller inspection + setup-launch correlation + runtime-profile-staging correlation" 0x0044c450,96,world_rebuild_all_grid_cell_candidate_cargo_service_bitsets,map,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Late world-reactivation sweep inside `world_entry_transition_and_runtime_bringup` `0x00443a50`. The helper walks the full live world grid rooted at `[this+0x2129]` through dimensions `[this+0x2145/+0x2149]`, resolves each cell pointer, and re-enters `placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` on every cell record. Current grounded caller is the later world-entry tail at `0x444b24`, immediately after `world_clear_and_reseed_region_center_world_grid_flag_bit` `0x0044c4b0` and before the route-style link rebuild at `0x468300`, so this is the current safest read for the world-wide grid-cell cargo-service-bitset refresh wrapper rather than another generic world-grid loop.","objdump + local disassembly + caller inspection + world-grid correlation + cargo-service correlation" @@ -443,6 +535,9 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0044c570,256,world_mark_secondary_raster_clear_cell_mask_0x3e_as_class_2_and_cache_bounds,map,thiscall,inferred,objdump + caller xrefs + local disassembly + secondary-raster correlation,3,"Small secondary-raster mutation helper beneath the later marked-cell scan and overlay-cache family. After clamping the caller cell coordinates against the current secondary-grid dimensions, the helper resolves the byte raster rooted at `[this+0x2135]` using row stride `[this+0x2155] + 1` and only proceeds when the target byte has no bits in mask `0x3e` and the parallel class predicate `world_secondary_raster_query_cell_class_in_set_1_3_4_5` `0x00534e10` also reports false. On the admit path it widens cached min/max bounds `[this+0x21c6..+0x21d2]`, increments the marked-cell count `[this+0x21d6]`, and then rewrites the target raster byte with `(byte & 0xc3) | 0x02`, i.e. it preserves the outer two bits and the low bit while forcing the masked class field to `0x02`. Current grounded caller is the later radial mutation branch at `0x0044e8e7`, and the written bounds/count fields are the same ones later scanned by `world_scan_secondary_grid_marked_cell_bounds` `0x0044ce60`, so this is the safest current read for the small secondary-raster cell-marker helper rather than another generic bounds updater.","objdump + caller xrefs + local disassembly + secondary-raster correlation + marked-cell-bound correlation" 0x0044ce60,272,world_scan_secondary_grid_marked_cell_bounds,map,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Secondary world-raster bounds scan beneath the later world-entry reactivation tail. The helper clears cached fields `[this+0x21c6/+0x21ca/+0x21ce/+0x21d2/+0x21d6]`, requires the shell-state gate `[0x006cec78+0x4af3]` to be nonzero, and then scans the byte raster rooted at `[this+0x2135]` through dimensions `[this+0x2155/+0x2159]`. Every cell whose byte has any bits in mask `0x3e` contributes to the cached min-X, min-Y, max-X, max-Y, and marked-cell-count slots at those same `0x21c6..0x21d6` fields. Current grounded callers are the later world-entry tail at `0x444c36`, one neighboring startup-side world branch at `0x448168`, and the small count accessor at `0x42f8d8`, so this is the safest current read for the shared marked-cell bounding-box scan over the secondary world raster rather than a fully player-facing overlay owner.","objdump + local disassembly + caller inspection + secondary-raster correlation" 0x0044cfb0,1120,world_load_runtime_grid_and_secondary_raster_tables_from_bundle,map,thiscall,inferred,objdump + caller xrefs + local disassembly + bundle-tag correlation,3,"Heavy world-root bundle-load body beneath `world_construct_root_and_load_bundle_payload_thunk` `0x0044e910`. After the immediate base setup and neighboring local initializers `0x00449270` and `0x00448260`, the helper reads one rooted payload through repeated `0x00531150/0x00531360` calls, storing the core grid and stride scalars into `[this+0x2145/+0x2149/+0x214d/+0x2151/+0x2155/+0x2159/+0x215d/+0x2161/+0x2201]`. It allocates the route-entry collection `0x006cfca8` through `0x00491af0`, allocates or zero-fills the main world arrays `[this+0x2139/+0x213d/+0x2141/+0x2131/+0x2135/+0x212d/+0x2129]` from chunk families `0x2ee2/0x2ee3/0x2ef4/0x2ef5/0x2ef6/0x2ee4/0x2ee5/0x2f43/0x2f44`, and on one loaded-raster path clears low bit `0x01` across every byte in `[this+0x2135]` after the bundle read succeeds. The tail then seeds every live world-grid cell record through `0x0042ae50`, re-enters `world_compute_transport_and_pricing_grid` `0x0044fb70`, refreshes neighboring presentation state through `0x00449f20`, and issues one shell-mode pulse through `0x00484d70` before returning. Current grounded caller is the world-root constructor thunk `0x0044e910` at `0x0044e931`, reached from the world-allocation branch inside `world_entry_transition_and_runtime_bringup` `0x00443a50`, so this is the safest current read for the heavy world-grid and secondary-raster bundle-load body rather than the broader bringup owner.","objdump + caller xrefs + local disassembly + bundle-tag correlation + world-grid-array correlation" +0x0044e270,63,world_resolve_secondary_raster_class_record_at_float_xy,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Small float-XY lookup over the live world secondary-raster class table. The helper rounds the two caller-supplied float coordinates through `0x005a10d0`, indexes the active byte raster at `[world+0x2131]` with row stride `[world+0x2155]`, shifts the selected byte right by three, and resolves the resulting class token through collection `0x006cfc9c`. Current grounded callers include `city_compute_connection_bonus_candidate_weight` `0x004010f0` and the linked-instance wrapper `0x0047f1f0`, so this is the safest current read for the world-side secondary-raster class-record lookup rather than a city-only predicate.","objdump + caller xrefs + local disassembly + secondary-raster-class correlation" +0x00491af0,295,route_entry_collection_construct_indexed_owner_and_zero_slot_array,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Concrete constructor for the route-entry collection rooted at `0x006cfca8`. The helper installs vtable `0x005cfe18`, re-enters the shared indexed-collection constructor path `0x00518570` with capacity-like scalars `0x3e8` and `0x1f4`, zeros the local side bands `[this+0x88..+0x10a]`, seeds `[this+0x88]` to `-1` and `[this+0x206]` to `-1.0f`, clears the small trailing triplet at `[this+0x10b]`, and allocates then zero-fills the separate slot-array pointer `[this+0x8c]` from caller count argument `arg0 * 4`. Current grounded caller is the world bundle-load body `world_load_runtime_grid_and_secondary_raster_tables_from_bundle` `0x0044cfb0`, so this is the safest current read for the route-entry collection constructor rather than a generic list init.","objdump + caller inspection + local disassembly + indexed-collection correlation + route-entry-collection correlation" +0x00491c20,56,route_entry_collection_refresh_all_live_entries_derived_visual_bands,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small collection-wide post-pass over the route-entry collection `0x006cfca8`. The helper enumerates all live entries through `indexed_collection_slot_count` `0x00517cf0`, `indexed_collection_get_nth_live_entry_id` `0x00518380`, and `indexed_collection_resolve_live_entry_by_id` `0x00518140`, then re-enters `route_entry_recompute_derived_visual_scalar_bands_and_optional_display_buffer` `0x00539640` on each resolved route entry. Current grounded caller is the later `319`-lane post-load pipeline inside `world_run_post_load_generation_pipeline` `0x004384d0`, where the same pass runs after placed-structure local-runtime refresh and flagged world-grid cleanup, so this is the safest current read for the collection-wide route-entry visual-band refresh pass rather than an anonymous indexed sweep.","objdump + caller inspection + local disassembly + indexed-collection correlation + post-load-pipeline correlation" 0x0044d4e0,512,world_relax_companion_float_grid_cross_average_in_rect_with_raster_bit0_gate,map,thiscall,inferred,objdump + caller xrefs + local disassembly + float-grid correlation,3,"Local five-pass relaxer over the companion float grid rooted at `[this+0x1605]`. The helper clamps the caller rectangle inward against the live world bounds, derives one radial falloff from the supplied center and radius through `0x0051dc00` when the caller radius is nonzero, averages the four cardinal neighbors around each admitted cell, subtracts the current cell, scales that delta by the falloff, the fixed coefficient at `0x005c8628`, and the caller gain, and only then accumulates the result back into the current float cell. The admit gate is explicit: cells whose paired raster byte in `[this+0x2135]` still has bit `0x01` set are skipped. After the five local passes it always re-enters `world_calculate_height_support_fields_in_rect_and_notify_dependents` `0x0044d410` on the same surviving rectangle. Current grounded caller is the neighboring world-side branch at `0x004bc5d3`, so this is the safest current read for the local cross-neighbor relaxer under the same height-support family rather than a broader global smoothing owner.","objdump + caller xrefs + local disassembly + float-grid correlation + local-relaxation correlation" 0x0044d6e0,912,world_relax_companion_float_grid_cross_average_in_rect_with_acceptance_gate,map,thiscall,inferred,objdump + caller xrefs + local disassembly + float-grid correlation,3,"Second local five-pass relaxer over the same companion float grid rooted at `[this+0x1605]`. Like the sibling at `0x0044d4e0`, it clamps the caller rectangle, averages the four cardinal neighbors, subtracts the current cell, and scales the resulting delta by a fixed coefficient before optionally accumulating it back into the current float slot. The admit path is tighter here: the cell is skipped whenever the paired raster byte in `[this+0x2135]` still has bit `0x01` set, and otherwise it also consults the neighboring acceptance gate `0x004499c0` before applying the delta. The final caller flag then decides whether the helper tails into `world_calculate_height_support_fields_in_rect_and_notify_dependents` `0x0044d410` on the same rectangle or returns immediately. Current grounded caller is the world-side branch at `0x004190b4`, where it is dispatched once per admitted local cell before the outer owner re-enters `0x0044d410`, so this is the safest current read for the acceptance-gated local cross-neighbor relaxer rather than another generic scalar write.","objdump + caller xrefs + local disassembly + float-grid correlation + acceptance-gate correlation" 0x0044d880,496,world_raise_companion_float_grid_toward_center_sample_in_rect,map,thiscall,inferred,objdump + caller xrefs + local disassembly + float-grid correlation,3,"Local neighborhood raise helper over the companion float grid rooted at `[this+0x1605]`. The function first validates the caller center cell against live dimensions, optionally seeds one baseline value from the current center sample when the caller gain is positive, expands a square neighborhood around that center by the caller radius, and then for each admitted cell derives one radial falloff through `0x0051dc00`. The body computes a delta from the current cell toward that baseline center sample, scales it by the falloff, the fixed coefficient at `0x005c8628`, and the caller gain, and accumulates the result back into the current float slot. After the neighborhood pass it always re-enters `world_calculate_height_support_fields_in_rect_and_notify_dependents` `0x0044d410` on the same surviving rectangle. Current grounded callers are the nearby world-side branches at `0x004bc676` and `0x004bc716`, so this is the safest current read for the center-sample-biased companion-float raise helper rather than another generic brush or setter.","objdump + caller xrefs + local disassembly + float-grid correlation + center-sample correlation" @@ -461,7 +556,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 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. The shell-state master flag `[0x006cec74+0x68]` now reinforces that same mapping on the direct Quicksave branch too: when it is nonzero the coordinator appends the `.gmp` token immediately instead of choosing among the scenario families, which makes the flag the strongest current shell-side anchor for editor-map mode rather than a generic post-load toggle. Current surrounding shell evidence now makes the non-editor 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 + Quicksave branch inspection 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. The shell-state master flag `[0x006cec74+0x68]` now reinforces that editor mapping on the direct save and Quicksave side too: when it is nonzero the coordinator chooses the `.gmp` package mode immediately before the scenario-family checks, which makes the flag the strongest current shell-side anchor for editor-map mode rather than a generic setup toggle. 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 + direct save branch inspection 0x00455f60,96,world_region_resolve_center_world_grid_cell,map,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small region-to-grid resolver that converts one region's cached center coordinate pair into a pointer into the live world-grid cell table rooted at `[0x0062c120+0x2129]`. It reads the cached floats at `[this+0x1ea]` and `[this+0x1e2]`, scales and rounds them through `0x005a10d0`, multiplies the Y-like term by world width `[0x0062c120+0x2145]`, adds the X-like term, and returns the corresponding grid-cell pointer. Current grounded callers include the world-entry region-center flag reseed pass `0x0044c4b0` and several older site- or route-style world-grid query helpers, so this is now the safest current read for the shared region-center world-grid-cell resolver.","objdump + local disassembly + caller inspection + world-grid correlation" -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; the raster side is tighter now too, because the serializer writes the two one-byte overlay mask planes separately through chunk ids `0x2cee` for `[world+0x1655]` and `0x2d51` for `[world+0x1659]`, then re-enters world_serialize_four_sidecar_byte_planes_into_runtime_bundle `0x00448fe0` to write four additional byte planes under chunk family `0x9471..0x9472` from the world-owned pointer band at `[world+0x1631 + index*4]` before finalizing through 0x00530a00. One late fixed-band save is tighter now too: at version `>= 0x400` the serializer writes `49` dwords from `[world+0x4a7f..+0x4b3f]` and one trailing dword from `[world+0x4b43]`, which grounds a direct `.smp` save of the editor-side scenario-rule band rather than only the smaller fixed matrix inferred from checked `gmp/gms/gmx` files. 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 + sidecar-plane correlation + mask-plane bundle-tag correlation + fixed-runtime-band correlation" +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 first pushes the nested mouse-cursor selection hold through `0x0053f2f0`, snapshots one startup-side status band through `0x004423a0`, 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`; at the tail it mirrors the paired status follow-on through `0x004423d0`, pops the same mouse-cursor hold through `0x0053f310`, and posts the fixed shell status line through `0x00538c70`. The status-band choreography is tighter now too: `0x004423a0/0x004423d0` bracket the same four shell dwords `[0x006cec74+0x140/+0x13c/+0x138/+0x144]` plus startup byte `[0x006cec78+0x4c74]` through the `0x0062be90` stack while also servicing active TrackLay.win and StationPlace.win tool windows. The raster side is tighter now too, because the serializer writes the two one-byte overlay mask planes separately through chunk ids `0x2cee` for `[world+0x1655]` and `0x2d51` for `[world+0x1659]`, then re-enters world_serialize_four_sidecar_byte_planes_into_runtime_bundle `0x00448fe0` to write four additional byte planes under chunk family `0x9471..0x9472` from the world-owned pointer band at `[world+0x1631 + index*4]` before finalizing through `0x00530a00`. One late fixed-band save is tighter now too: at version `>= 0x400` the serializer writes `49` dwords from `[world+0x4a7f..+0x4b3f]` and one trailing dword from `[world+0x4b43]`, which grounds a direct `.smp` save of the editor-side scenario-rule band rather than only the smaller fixed matrix inferred from checked `gmp/gms/gmx` files. 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 + sidecar-plane correlation + mask-plane bundle-tag correlation + fixed-runtime-band correlation + cursor-hold choreography correlation + status-stack correlation" 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 the secondary-raster class mutators world_secondary_raster_reclass_cell_to_low3bit_1_or_4_and_clear_primary_companion_plane `0x00448c20` and world_secondary_raster_reclass_cell_to_low3bit_3_or_5_and_clear_primary_companion_plane `0x00448cb0`, the byte2-flag and companion-byte writers `0x00448d90`, `0x00448e60`, and `0x00448e90`, and the broader restore-side world-cell helper `0x0044de30`; the raster side is tighter now too, because the loader restores the two one-byte overlay mask planes separately from chunk ids `0x2cee` into `[world+0x1655]` and `0x2d51` into `[world+0x1659]`, and then, for versioned bundles at `>= 0x3ec`, re-enters world_load_four_sidecar_byte_planes_from_runtime_bundle `0x00448f60` to restore four extra byte planes under chunk family `0x9471..0x9472` into the world-owned pointer band `[world+0x1631 + index*4]`. One later fixed-band restore is tighter now too: at version `>= 0x3fc` the loader reads `49` dwords directly into `[world+0x4a7f..+0x4b3f]` and one trailing dword into `[world+0x4b43]`, which grounds a direct `.smp` restore of the editor-side scenario-rule band rather than only the smaller fixed matrix inferred in the checked `gmp/gms/gmx` families. 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 + sidecar-plane correlation + mask-plane bundle-tag correlation + fixed-runtime-band correlation" 0x0044f840,176,world_build_transport_pricing_preview_surface_from_secondary_raster,map,thiscall,inferred,objdump + caller inspection + local disassembly + secondary-raster correlation,3,"Small transport/pricing-side preview builder beneath `world_compute_transport_and_pricing_grid` `0x0044fb70`. The helper allocates one default presentation target through `0x00534930`, queries its dimensions through `0x00534c50`, seeds five fallback palette entries through repeated `0x0051de10` calls, and then walks the target pixels. Each pixel is mapped back into the live secondary raster `[this+0x165d]` through `0x00533970/0x00533980`; low-3-bit classes other than `1/4` get one fixed fallback color, while class-`1/4` pixels scan a local `+/-4` neighborhood for zero-tag cells, score those through the radial falloff helper `0x0051db80`, and then choose either one of the seeded palette entries or the alternate fallback color `0x5f040566`. After filling the whole surface it re-enters `world_rebuild_secondary_raster_derived_surface_and_companion_planes_in_rect` `0x0044e940` on the full `0..0x270f` rectangle rooted at that target. Current grounded caller is the null-build path at `0x0044fb31` inside `world_compute_transport_and_pricing_grid`, so this is the safest current read for the transport/pricing preview-surface builder rather than another generic overlay helper.","objdump + caller inspection + local disassembly + secondary-raster correlation + preview-surface correlation" 0x0044faf0,128,world_ensure_transport_pricing_preview_surface_and_publish_if_missing,map,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Thin world-side ensure/publish wrapper above `world_build_transport_pricing_preview_surface_from_secondary_raster` `0x0044f840`. The helper first forwards the caller rectangle and output pointer into `0x00538060`, then samples shell state through `0x0040b830` and the paired shell notifier `0x004834e0`. When the returned preview handle is null it rebuilds the preview surface by re-entering `0x0044f840`; in either case it then refreshes neighboring world presentation through `0x00449f80`, re-enters the region-border overlay refresh `0x004881b0`, posts the same shell notifier again, and finally issues one mode pulse through `0x00484d70` before returning the ensured handle. Current grounded caller is the world-side path at `0x0043901a`, so this is the safest current read for the transport/pricing preview ensure-and-publish wrapper rather than another generic surface allocator.","objdump + caller inspection + local disassembly + world-presentation correlation" @@ -473,10 +568,47 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004882e0,199,world_region_border_overlay_rebuild,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Rebuilds the border-overlay companion for the numbered region set owned by `0x0062bae0`. After pumping shell progress through `0x004834e0` the helper seeds or refreshes the companion record family at `0x006cfc9c`, using world_region_border_overlay_reset_companion_record_and_assign_region_id `0x00487650` to reset each resolved record before folding active contribution counts back into `[entry+0x3d]+[entry+0x41]`. It then refreshes the raw per-region cell-count band through world_region_border_overlay_refresh_raw_region_cell_counts_from_world_grid `0x004881b0`, and only after that hands the actual world-grid border-segment emission to `world_region_border_overlay_emit_segment_geometry_from_region_grid` `0x00487de0`. Current grounded callsites are the post-load generation pipeline at `0x004384d0` and the broader world-build path around `0x00447560`, which makes this look like a region-border overlay rebuild rather than another generic player or company manager pass.","objdump + caller xrefs + RT3.lng strings + grid-neighbor inspection" 0x00533cf0,180,world_region_border_overlay_clear_all_chunk_segment_queues,map,thiscall,inferred,objdump + caller xrefs + queue teardown inspection,4,"One-owner teardown helper under world_region_border_overlay_emit_segment_geometry_from_region_grid. The helper walks every coarse chunk bucket in the world-presentation table `[this+0x167d]`, and for each bucket with queued nodes it repeatedly pops the queued payload pointers through `0x00556ef0/0x00556f00`, frees those segment records through `0x005a1145`, and then resets the bucket through `0x005570b0`. Current grounded caller is `0x00487df8`, which uses it to clear the prior border-overlay segment queues before rebuilding them from the live region grid.","objdump + caller xrefs + queue teardown inspection" 0x00536ea0,96,world_region_border_overlay_allocate_and_queue_segment_record,map,thiscall,inferred,objdump + caller xrefs + intrusive-queue inspection,4,"One-owner record allocator under world_region_border_overlay_emit_segment_geometry_from_region_grid. The helper allocates one `0x31`-byte segment record through `0x005a125d`, copies the caller-supplied endpoint and orientation fields into that record, optionally expands cached float coordinates through repeated `0x00534490` calls when the final byte flag is nonzero, resolves one coarse bucket in `[this+0x167d]` from the segment midpoint, and appends the finished record to that bucket through `intrusive_queue_push_back` `0x00556e10`. Current grounded caller is `0x00488072` inside the border-overlay geometry emitter.","objdump + caller xrefs + intrusive-queue inspection + segment midpoint bucketing" +0x00533100,16,runtime_object_set_indexed_f32_field_family_0x14e4,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny indexed float setter under the broader `0x23a` runtime-object family. The helper stores the caller float into `[this+0x14e4 + index*4]` and returns. Current grounded callers are the paired setup strips around `0x0043c442/0x0043c479` and `0x00484e6b/0x00484e90`, so the safest current read is an indexed `f32` field-family store rather than a named gameplay scalar.","objdump + caller inspection + local disassembly + field-family correlation" +0x00533120,13,runtime_object_get_indexed_f32_field_family_0x14e4,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny indexed float getter for the same `0x23a` runtime-object field family rooted at `[this+0x14e4]`. The helper loads one caller-selected float slot and returns it on the FPU stack. Current grounded caller is `runtime_object_quantize_world_position_sample_group_metric_and_select_subrecord` `0x0052f370`, where it contributes one sampled scalar to the grouped-subrecord selection metric.","objdump + caller inspection + local disassembly + field-family correlation + quantized-selector correlation" +0x00533130,11,runtime_object_set_dword_field_0x1534,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword setter for field `[this+0x1534]` under the shared runtime-object or presentation-owner family. Current grounded callers are the setup strips around `0x0043b807`, `0x00484eb3`, `0x0052be9a`, `0x0052bf04`, and `0x0052cb83`, so the safest current read is a direct field setter rather than a higher-level mode helper.","objdump + caller inspection + local disassembly + field correlation" +0x00533140,7,runtime_object_get_dword_field_0x1534,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword getter for field `[this+0x1534]` in the same shared runtime-object family. Current grounded callers include `0x005294e7`, `0x0052be8f`, `0x0052c23b`, and `0x0052cb6f`, which keep this safely bounded as the read-side companion to `0x00533130`.","objdump + caller inspection + local disassembly + field correlation" +0x00533150,11,runtime_object_set_dword_field_0x1540,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword setter for field `[this+0x1540]` under the shared runtime-object family. Current grounded callers are the setup strips around `0x00484ef9`, `0x0052bfb0`, and `0x0052bfc1`.","objdump + caller inspection + local disassembly + field correlation" +0x00533160,7,runtime_object_get_dword_field_0x1540,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword getter for field `[this+0x1540]` in the same shared runtime-object family. Current grounded callers include `0x005246b7`, `0x00524754`, `0x0052a346`, `0x0052bf82`, and `0x0052c262`; together with `0x00533180`, this forms the currently grounded threshold pair sampled by `shell_emit_ranked_overlay_cell_items` `0x00524780`.","objdump + caller inspection + local disassembly + field correlation + ranked-overlay correlation" +0x00533170,11,runtime_object_set_dword_field_0x153c,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword setter for field `[this+0x153c]` under the shared runtime-object family. Current grounded callers are the setup strips around `0x00484f1c`.","objdump + caller inspection + local disassembly + field correlation" +0x00533180,7,runtime_object_get_dword_field_0x153c,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword getter for field `[this+0x153c]` in the same shared runtime-object family. Current grounded callers include `0x005247b2`, and together with `0x00533160` this forms the currently grounded two-dword threshold pair sampled by `shell_emit_ranked_overlay_cell_items` `0x00524780`.","objdump + caller inspection + local disassembly + field correlation + ranked-overlay correlation" +0x00533190,11,runtime_object_set_dword_field_0x1544,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword setter for field `[this+0x1544]` under the shared runtime-object family. Current grounded callers are the setup strips around `0x0043b89d`.","objdump + caller inspection + local disassembly + field correlation" +0x005331a0,7,runtime_object_get_dword_field_0x1544,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword getter for field `[this+0x1544]` in the same shared runtime-object family. Current grounded callers include `0x0052bf99` and `0x0052bfa8`, which keep this bounded as the direct read-side companion to `0x00533190`.","objdump + caller inspection + local disassembly + field correlation" +0x005331b0,11,runtime_object_set_f32_field_0x14e0,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny float setter for field `[this+0x14e0]` under the shared runtime-object family. Current grounded caller is the setup strip around `0x00484e2e`.","objdump + caller inspection + local disassembly + field correlation" +0x005331c0,7,runtime_object_get_f32_field_0x14e0,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny float getter for field `[this+0x14e0]` in the same shared runtime-object family. Current grounded callers include `0x0043b468`, `0x0043b48a`, `0x00484de9`, and `0x00484e07`, which keep this bounded as the direct read-side companion to `0x005331b0`.","objdump + caller inspection + local disassembly + field correlation" +0x005331d0,7,runtime_object_get_dword_field_0x1548,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny dword getter for field `[this+0x1548]` under the shared runtime-object family. Current grounded callers include `0x0052bd13`, `0x0052bd41`, and `0x0052bd6f`. The matching setter remains outside the current local strip.","objdump + caller inspection + local disassembly + field correlation" 0x005331e0,592,world_rebuild_overlay_sample_triplet_cell_for_scale,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Scale-specific local reducer under the secondary-overlay multiscale support family. Given one selected cell plus one scale index, the helper clamps a local neighborhood to the live world bounds, walks the per-scale float surface rooted at `[this+0x15ed + scale*4]`, accumulates three float channels across that neighborhood, normalizes by sample count, rescales the local vector magnitude against shared constants, and writes one packed three-float sample record into the matching per-scale triplet buffer family rooted at `[this+0x15f1 + (scale-1)*4]`. Current grounded callers are `0x00533845` and `0x00533929`, both inside `world_rebuild_secondary_overlay_multiscale_support_surfaces_in_rect` `0x00533890`.","objdump + caller inspection + field correlation + multiscale-support correlation" +0x00532310,80,world_presentation_store_seven_dword_overlay_companion_block_and_mark_live,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small local setter in the world-presentation overlay family. The helper copies seven caller-supplied dwords into the companion block `[this+0x15b5..+0x15cd]` and then marks byte `[this+0x15b4] = 1`. Current grounded caller is the neighboring overlay-family setup strip, so the safest current read is a seven-dword companion-block store plus live mark rather than a broader reset.","objdump + caller inspection + local disassembly + overlay-companion-block correlation" +0x00532360,16,world_presentation_clear_overlay_companion_block_live_flag,map,thiscall,inferred,objdump + local disassembly,1,"Tiny companion to `world_presentation_store_seven_dword_overlay_companion_block_and_mark_live` `0x00532310`. The helper clears byte `[this+0x15b4]` and returns immediately. Current evidence grounds it only as the live-flag clear side of the same local seven-dword block.","objdump + local disassembly + overlay-companion-block correlation" +0x00532370,16,world_presentation_query_overlay_companion_block_live_flag,map,thiscall,inferred,objdump + local disassembly,1,"Tiny getter for overlay-family live flag byte `[this+0x15b4]`. The helper returns that byte as an integer without additional side effects. Current evidence grounds it only as the direct live-flag query for the neighboring seven-dword companion block.","objdump + local disassembly + overlay-companion-block correlation" +0x00532380,96,world_presentation_copy_seven_dword_overlay_companion_block_out,map,thiscall,inferred,objdump + local disassembly,1,"Small read-side companion to the local seven-dword overlay companion block `[this+0x15b5..+0x15cd]`. The helper copies those seven dwords into caller output storage and returns. Current evidence grounds it only as the direct copy-out helper for the same block set by `0x00532310`.","objdump + local disassembly + overlay-companion-block correlation" +0x005323e0,16,world_presentation_overlay_family_trivial_ret_0x14_stub,map,stdcall,inferred,objdump + local disassembly,1,"Tiny five-argument stdcall stub that only executes `ret 0x14`. The function currently has no grounded side effects or local ownership beyond sitting inside the same overlay-family strip, so the safest current read is a literal no-op vtable or callback stub.","objdump + local disassembly + stdcall-stub correlation" +0x005323f0,112,world_presentation_lazy_ensure_cached_surface_root_0x478_and_stage_saved_dims,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Lazy ensure helper over cached surface root `[this+0x478]` in the world-presentation overlay family. When that root is null, the helper allocates one backing object through `0x00543980` using saved dimensions `[this+0x159c/+0x15a0]`, stores the result into `[this+0x478]`, and then dispatches the live root through `0x00541970`. Current grounded callers are the neighboring cached-surface service strip and broader overlay rebuild paths, so the safest current read is a cached-surface ensure plus staged-dimension setup owner rather than a generic allocator.","objdump + caller inspection + local disassembly + cached-surface correlation" +0x00532460,48,world_presentation_service_cached_surface_root_0x478_and_publish,map,thiscall,inferred,objdump + local disassembly,1,"Small service companion to the cached surface root `[this+0x478]`. The helper dispatches that root through `0x00541970` and then through `0x005438d0`, which makes it the publish or finalize side of the same cached-surface strip rather than another allocator.","objdump + local disassembly + cached-surface correlation" +0x00532490,80,world_presentation_query_from_cached_surface_root_for_saved_dims,map,thiscall,inferred,objdump + local disassembly,1,"Read-side helper over cached surface root `[this+0x478]` plus saved dimensions `[this+0x159c/+0x15a0]`. The helper resolves one current result from the live root using those dimensions and forwards the answer back through caller out-storage. Current evidence grounds it only as a cached-surface query sibling of `0x005323f0` and `0x00532460`.","objdump + local disassembly + cached-surface correlation" +0x005324e0,32,world_presentation_mark_cached_surface_live_flag_if_root_present,map,thiscall,inferred,objdump + local disassembly,1,"Tiny cached-surface flag helper. When root `[this+0x478]` is nonnull, the helper marks byte `[this+0x159b] = 1`; otherwise it leaves that byte unchanged. Current evidence grounds it only as the live-flag set side for the cached-surface strip.","objdump + local disassembly + cached-surface-flag correlation" +0x00532500,16,world_presentation_clear_cached_surface_live_flag,map,thiscall,inferred,objdump + local disassembly,1,"Tiny companion to `world_presentation_mark_cached_surface_live_flag_if_root_present` `0x005324e0`. The helper clears byte `[this+0x159b]` and returns. Current evidence grounds it only as the cached-surface live-flag clear path.","objdump + local disassembly + cached-surface-flag correlation" +0x00532510,16,world_presentation_store_overlay_mode_byte_0x159a,map,thiscall,inferred,objdump + local disassembly,1,"Tiny setter for overlay-family mode byte `[this+0x159a]`. The helper stores caller byte arg0 and returns immediately. Current evidence grounds it only as a direct local mode-byte setter.","objdump + local disassembly + local-mode-byte correlation" +0x00532520,48,world_presentation_store_saved_overlay_dimension_quad,map,thiscall,inferred,objdump + local disassembly,1,"Small setter over the saved dimension quad `[this+0x15a4..+0x15b0]` in the world-presentation overlay family. The helper copies four caller-supplied dwords into that quad and returns. Current evidence grounds it only as the direct saved-dimension store for the neighboring cached-surface strip.","objdump + local disassembly + saved-dimension correlation" +0x00532550,64,world_presentation_copy_saved_overlay_dimension_quad_out,map,thiscall,inferred,objdump + local disassembly,1,"Read-side companion to `world_presentation_store_saved_overlay_dimension_quad` `0x00532520`. The helper copies the four saved dwords from `[this+0x15a4..+0x15b0]` into caller output storage and returns. Current evidence grounds it only as the direct copy-out helper for that saved-dimension quad.","objdump + local disassembly + saved-dimension correlation" 0x00532590,455,world_presentation_reset_overlay_runtime_state_and_pointer_roots,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Broad hard-reset owner beneath the world-presentation overlay family. The helper clears the live overlay-state bytes `[this+0x1588/+0x1599/+0x159b/+0x15b4]`, reseeds `[this+0x159a]` to `1`, resets scalar fields like `[this+0x154c/+0x155c/+0x15d9/+0x15d5]`, nulls the main pointer roots `[this+0x478]`, `[this+0x1558..+0x1570]`, `[this+0x159c/+0x15a0]`, `[this+0x15e1]`, the support-family roots `[this+0x1605/+0x15f1/+0x1619/+0x162d]`, the four sidecar byte planes `[this+0x1631..+0x163d]`, both mask planes `[this+0x1655/+0x1659]`, the packed raster `[this+0x165d]`, the vector byte planes `[this+0x1661/+0x1665]`, and the neighboring overlay tables `[this+0x1669..+0x1685]`, then zero-fills the local `0x100` slot band at `[this+0x08]` and the `0x1b`-entry companion slot table at `[this+0x40c]`. Current grounded callers are the local constructor at `0x00534f73` and the broader presentation reinitializer `0x00537e70`, so this is the safest current read for the shared overlay-family hard reset rather than a narrow resize helper.","objdump + caller inspection + field correlation + overlay-reset correlation" +0x00532760,64,world_presentation_release_current_overlay_slot_root_by_index_0x1558,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small release helper in the same world-presentation overlay family. When selector dword `[this+0x1558]` is nonzero, the helper resolves one slot root from `[this+0x08 + [this+0x1558]*4]`, releases that object through `0x00542c90` plus `0x0053b080`, and clears the slot pointer back to `0`. Current grounded caller is the neighboring setup strip at `0x00534fe3`, so the safest current read is a current-slot release helper rather than a broader reset.","objdump + caller inspection + local disassembly + overlay-slot-release correlation" +0x005327a0,192,world_presentation_clamp_two_surface_dimensions_to_supported_power_of_two_and_display_caps,map,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Shared surface-dimension clamp beneath the world-presentation overlay family. The helper first derives one minimum supported dimension from shell memory-budget queries `0x0051fa40` and `0x0055d430`, choosing either `0x100` or `0x400`, then round-down-clamps the two caller dimension pointers to exact powers of two through `0x0051df50`, and finally enforces shell display caps from `[0x006d4024+0x114243]` and `[0x006d4024+0x114247]` after converting those cap lanes back into four-pixel units. Current grounded callers are the local overlay rebuild paths `0x00535115` and `0x00535492`, so the safest current read is a shared supported-surface dimension clamp rather than a one-shot texture allocator.","objdump + caller inspection + local disassembly + power-of-two correlation + display-cap correlation" +0x00532860,243,world_presentation_stitch_12_overlay_slot_surfaces_from_parallel_bands_and_finalize_primary,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Local stitching pass over twelve consecutive overlay-slot families starting at selector `[this+0x155c]`. For each of those twelve entries the helper queries buffer pointers and row geometry from the parallel slot roots in the `[this+0x08 + index*4]` and `[this+0x18 + index*4]` bands through `0x00541970`, copies one terminal row from the latter buffer into the former, and on indices whose local position is not `3 mod 4` it also queries the sibling root in `[this+0x0c + index*4]` and copies one leading-column dword from that sibling into the right edge of the `[this+0x18 + index*4]` buffer. After each local stitch it finalizes the primary root through `0x00541c10`. Current grounded callers are the two neighboring rebuild branches `0x00527d05` and `0x00527d6a`, so the safest current read is a twelve-slot surface-edge stitching pass rather than a generic allocator or publish helper.","objdump + caller inspection + local disassembly + parallel-slot-band correlation + surface-stitch correlation" +0x00532960,115,world_presentation_project_two_out_offsets_from_grid_pair_through_4x4_and_16x16_quanta,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small paired projection helper beneath the same overlay family. The function rounds live grid dimensions `[this+0x15d9/+0x15d5]` up to both `16`-cell and `4`-cell quanta, scales the two caller input dwords by `4`, divides each by the corresponding `16`-cell quantum, multiplies by the opposite-axis `4`-cell quantum, and writes the resulting projected offsets back through the two caller out-pointers. Current grounded caller is the neighboring branch `0x00525ce9`, so the safest current read is a paired coarse-offset projection helper rather than a more semantic placement or cell-query owner.","objdump + caller inspection + local disassembly + coarse-projection correlation" +0x005329e0,48,world_presentation_map_xy_into_coarse_4x4_overlay_region_index,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small coordinate packer beneath the same overlay family. The helper rounds live grid dimensions `[this+0x15d9/+0x15d5]` up to `16`-cell quanta, scales the two caller coordinates by `4`, divides them by those rounded quanta, and returns one `1`-based coarse region index laid out as a `4x4` grid. Current grounded caller is the neighboring builder branch `0x00526f8a`, so the safest current read is a reusable `(x,y) -> coarse 4x4 overlay region id` helper rather than a broader geometry transform.","objdump + caller inspection + local disassembly + coarse-region-index correlation" +0x00532a30,7,world_presentation_query_overlay_slot_band_live_count_or_tag_0x1554,map,thiscall,inferred,objdump + caller inspection + field correlation,1,"Tiny direct getter over dword `[this+0x1554]` in the same overlay family. The field is cleared by the slot-band reset owner `0x00532b30`, feeds the primary companion-plane write helper `0x00448d40`, and is also sampled by neighboring world-presentation branches around `0x00525c07`, `0x0052b3b5`, and `0x0052ba0d`. Current evidence supports only the structural read that this dword is the live count or tag for the local overlay slot band, not a tighter semantic label yet.","objdump + caller inspection + field correlation + overlay-slot-band correlation" 0x00532d90,464,world_normalize_secondary_overlay_float_summary_plane_globally,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Global normalization pass over the base secondary-overlay float summary plane rooted at `[this+0x1605]`. The helper first scans the full live plane across `[this+0x15d9/+0x15d5]` to find one global maximum, clamps that maximum into a stable range, synthesizes a `0..100` weight table from the resulting scale factor, and then reruns the full plane to remap every positive cell through that table. Current grounded caller is `0x005385ea` inside the larger secondary-overlay rebuild owner around `0x00538360`, immediately before the companion radius-expansion pass `0x00532f60`.","objdump + caller inspection + field correlation + global-normalization correlation" 0x00532f60,403,world_expand_positive_secondary_overlay_float_summary_by_radius,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Radius-style expansion pass over the same base secondary-overlay float summary plane rooted at `[this+0x1605]`. Given one caller radius, the helper walks the full live plane, keeps only positive source cells, samples their local neighborhood with distance falloff, and writes back the strongest surviving propagated value into the same float plane. Current grounded caller is `0x005385fd` inside the larger secondary-overlay rebuild owner around `0x00538360`, immediately after `world_normalize_secondary_overlay_float_summary_plane_globally` `0x00532d90`.","objdump + caller inspection + field correlation + radius-expansion correlation" +0x00532a40,80,world_presentation_query_time_selected_slot_from_first_seeded_overlay_band,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Time-selected query over the first template-seeded overlay slot band. The helper samples one shared tick source through function pointer `0x005c8068`, scales that tick against count field `[this+0x156c]`, caches the resulting local index in `[this+0x1570]`, adds base slot index `[this+0x1568]`, and returns the corresponding slot root from `[this+0x08 + slot*4]`. Current grounded caller is the neighboring world-presentation branch `0x0052c41a`, and the stored fields align with the first slot-band seeder `0x005356e0`, so the safest current read is a time-selected query over that first seeded overlay band rather than a generic random picker.","objdump + caller inspection + local disassembly + seeded-slot-band correlation" +0x00532a90,16,world_presentation_query_trailing_fallback_slot_from_first_seeded_overlay_band,map,thiscall,inferred,objdump + local disassembly + field correlation,1,"Tiny getter for trailing fallback slot index `[this+0x1578]` in the first template-seeded overlay slot band. The corresponding fallback slot is seeded by `world_presentation_seed_first_overlay_slot_band_from_static_templates` `0x005356e0`, so the safest current read is a direct fallback-slot query rather than an independent selector.","objdump + local disassembly + field correlation + seeded-slot-band correlation" +0x00532aa0,48,world_presentation_query_time_selected_slot_from_second_seeded_overlay_band,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Time-selected query over the second template-seeded overlay slot band. The helper samples the same shared tick source, folds that tick through the reciprocal divide sequence keyed by count field `[this+0x1564]`, adds base slot index `[this+0x1560]`, and returns the corresponding slot root from `[this+0x08 + slot*4]`. Current grounded caller is shell-side branch `0x0054e2f0`, and the stored fields align with the second slot-band seeder `0x00535890`, so the safest current read is a time-selected query over that second seeded overlay band rather than another generic slot accessor.","objdump + caller inspection + local disassembly + seeded-slot-band correlation" +0x00532b30,332,world_presentation_release_overlay_slot_band_and_reset_band_indices,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared release or reset owner for the local overlay slot band at `[this+0x08]`. The helper first releases slot `0` through either `0x00542c90 + 0x0053b080` or `0x0053c000` depending on shell flag `[0x006d4024+0x11422e]`, then walks slots `1..count-1` where count comes from `[this+0x1554]`, releasing each live root with the same split except that the special forced-direct range `1..0x10` always goes through `0x00542c90 + 0x0053b080`. After the sweep it clears the live slot pointers and resets the controlling band fields `[this+0x1554]`, `[this+0x1568]`, `[this+0x1570]`, `[this+0x155c]`, `[this+0x1560]`, and `[this+0x1564]`. Current grounded caller is the default companion-set refresh path `0x00537356`, so the safest current read is a shared overlay-slot-band release plus band-index reset owner rather than another broad world reset.","objdump + caller inspection + local disassembly + overlay-slot-band correlation + release-path split correlation" +0x00527ce0,243,world_presentation_ensure_dim_tag_matched_stitched_overlay_helper_and_clear_global_scratch_planes,map,thiscall,inferred,objdump + local disassembly + cache-field correlation,2,"Broader owner directly above the stitched overlay-slot family. The helper queries current grid extents from the world presentation object through `0x00533970/0x00533980`, compares those against cached globals `0x00624d40/0x00624d3c` and the world-side tag `[world+0x2121]` mirrored in `0x00624d38`, and when any of those differ it re-enters the twelve-slot stitch pass `0x00532860`, rebuilds local helper `[this+0x65]` through `0x0053b070` and `0x00565370`, or releases the prior helper through `0x00565440` plus `0x0053b080`. Whether rebuilt or unchanged, it then clears the two large global scratch planes rooted at `0x008f2520` and `0x00b33530`. Current evidence keeps the helper structural rather than fully semantic, but it is clearly the dimension-and-tag-matched stitched-overlay ensure owner above `0x00532860`.","objdump + local disassembly + cache-field correlation + stitched-overlay correlation" 0x00532ad0,81,world_presentation_allocate_overlay_slot_from_static_template,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Small shared slot allocator over the local `0x100` overlay pointer band at `[this+0x08]`. The helper finds the first empty slot, forwards the caller-supplied static template row into `0x0053c1c0` together with the fixed tuple `(0, 0, 0x7f)`, stores the resulting object pointer into `[this+0x08 + slot*4]`, and increments live count `[this+0x04]`. Current grounded callers are the neighboring setup owners `0x00535070`, `0x005356e0`, and `0x00535890`, the broader reinitializer `0x00537e60`, and one earlier world-presentation branch at `0x00454f40`, so this is the safest current read for the shared static-template overlay-slot allocator rather than one narrow UI control helper.","objdump + caller inspection + field correlation + static-template correlation" 0x00532c80,529,world_allocate_base_secondary_overlay_planes_for_current_dimensions,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Lower secondary-overlay allocator or reset owner for the current world-grid dimensions. The helper clears shift field `[this+0x15e1]`, optionally overwrites live grid dimensions `[this+0x15d9/+0x15d5/+0x15dd]` from caller width and height, allocates the base float-summary plane `[this+0x1605]`, the four sidecar byte planes `[this+0x1631..+0x163d]`, the two one-byte mask planes `[this+0x1655]` and `[this+0x1659]`, and the packed secondary 3-byte raster `[this+0x165d]`, then seeds those planes with their default byte patterns: `0x02` for the primary mask plane, `0x01` for the secondary mask plane, and zero for the packed raster. Current grounded callers are the broader presentation reinitializer `0x00537e60` and the shell-side size-reset path around `0x00537f1a`, so this is the safest current read for the base secondary-overlay plane allocator rather than the wider multiscale support owner.","objdump + caller inspection + field correlation + mask-plane default correlation" 0x00533430,368,world_rebuild_overlay_float_plane_cell_for_scale,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Scale-specific float-plane sibling under the secondary-overlay multiscale support family. The helper clamps one local neighborhood around the selected cell, reads the contributing float samples from the per-scale plane rooted at `[this+0x1601 + (scale-1)*4]`, averages that neighborhood, and stores the resulting float into the companion per-scale summary plane family rooted at `[this+0x1605 + (scale-1)*4]` for the same cell. Current grounded callers are `0x0053384f` and `0x00533933`, both inside `world_rebuild_secondary_overlay_multiscale_support_surfaces_in_rect` `0x00533890`.","objdump + caller inspection + field correlation + multiscale-support correlation" @@ -484,6 +616,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00533890,224,world_rebuild_secondary_overlay_multiscale_support_surfaces_in_rect,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Rectangle-wide multiscale support-surface rebuild above the raw secondary-overlay byte planes. The helper clamps the caller rectangle to the live world bounds, then for scale levels `1..4` downshifts that rectangle and re-enters three scale-specific reducers: `world_rebuild_overlay_sample_triplet_cell_for_scale` `0x005331e0` refreshes the five-entry packed sample-triplet buffer family rooted at `[this+0x15f1..+0x1601]`, `world_rebuild_overlay_float_plane_cell_for_scale` `0x00533430` refreshes the five-entry float summary family rooted at `[this+0x1605..+0x1615]`, and `world_rebuild_overlay_rank_u16_plane_cell_for_scale` `0x005335a0` refreshes the five-entry smoothed unsigned-word family rooted at `[this+0x1619..+0x1629]`. Current grounded caller is `0x005375b2` inside the larger rect owner `0x005374d0`, and the same helper also has one tiny local wrapper at `0x00533845..0x00533859`, so this is the safest current read for the shared multiscale secondary-overlay support rebuild rather than another raw cell accessor.","objdump + caller inspection + field correlation + multiscale-support correlation" 0x00533970,7,world_query_world_grid_max_x_cell_index,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Tiny dimension getter over the live world-grid family. The helper returns the cached maximum X cell index from `[this+0x15d9]` directly. Current grounded callers are shell-side presentation and staging branches around `0x0043b0ea`, `0x0044d893`, `0x00523edd`, `0x00524e9b`, `0x00525b4c`, `0x005266ae`, and `0x0056935e`, which consistently pair it with `world_query_world_grid_max_y_cell_index` `0x00533980` rather than treating it as a more player-facing world metric.","objdump + caller inspection + field correlation" 0x00533980,7,world_query_world_grid_max_y_cell_index,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Y-axis sibling of world_query_world_grid_max_x_cell_index. The helper returns the cached maximum Y cell index from `[this+0x15d5]` directly. Current grounded callers are the same shell-side presentation and staging branches that pair it with `0x00533970`, including `0x0043b101`, `0x0044d8af`, `0x00523eeb`, `0x00524ea6`, `0x00525b57`, `0x005273e9`, and `0x00569368`.","objdump + caller inspection + field correlation" +0x00533990,11,world_store_secondary_overlay_shift_field_0x15e1,map,thiscall,inferred,objdump + local disassembly + field correlation,2,"Tiny setter for the secondary-overlay shift or scale-selector dword `[this+0x15e1]`. Current local evidence grounds it only as the direct write-side accessor under the broader multiscale overlay family.","objdump + local disassembly + field correlation" 0x00533ae0,7,world_query_secondary_raster_root,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Tiny root-pointer getter for the packed secondary 3-byte cell raster at `[this+0x165d]`. Current grounded callers include shell-side staging branches around `0x00524eb1` and `0x00569351`, while the same root is also consumed directly by the neighboring secondary-raster read/write helpers `0x00448eec..0x00448f57` and several world-side scans, so this is the safest current read for the raw secondary-raster base accessor.","objdump + caller inspection + field correlation + secondary-raster correlation" 0x00533af0,7,world_query_secondary_overlay_vector_x_byte_plane_root,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Tiny root-pointer getter for the signed X-component overlay vector byte plane at `[this+0x1661]`. Current grounded callers are the shell-side staging path around `0x0056933d`, while neighboring byte read/write helpers at `0x00448e60` and `0x00448ec0` plus the rectangle rebuild pass `0x00536710` use the same root directly.","objdump + caller inspection + field correlation + vector-plane correlation" 0x00533b00,7,world_query_secondary_overlay_vector_y_byte_plane_root,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Tiny root-pointer getter for the signed Y-component overlay vector byte plane at `[this+0x1665]`. Current grounded callers are the shell-side staging path around `0x00569347`, and the same root is consumed directly by `world_secondary_overlay_vector_y_byte_plane_query_cell_value` `0x00448ee0`, `world_secondary_overlay_vector_y_byte_plane_set_cell_value` `0x00448e90`, and the rectangle rebuild pass `0x00536710`.","objdump + caller inspection + field correlation + vector-plane correlation" @@ -495,6 +628,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00533b60,7,world_query_secondary_overlay_secondary_mask_byte_plane_root,map,thiscall,inferred,objdump + caller inspection + allocation-path inspection,3,"Tiny root-pointer getter for the second one-byte overlay mask plane at `[this+0x1659]`. The plane is allocated in the same setup path around `0x00537799` and initialized to byte value `0x01`. The only grounded getter caller is the shell-side overlay staging branch at `0x00525bad`, and that branch immediately discards the returned pointer before calling `0x005458a0`. Beyond that, current local evidence only grounds allocation, default-seed, bulk copy, bundle save-load, zero-fill, rectangle-clear, teardown, and existence-gate behavior on this plane, not a distinct semantic reader comparable to the primary mask plane at `[this+0x1655]`. Taken together with the asymmetry in `0x00538360`, the safest current read is that this is the separately persisted secondary mask-plane base accessor, not a second actively rebuilt runtime mask root.","objdump + caller inspection + allocation-path inspection + field correlation + negative-consumer correlation + persisted-sibling-plane correlation" 0x00536710,1660,world_rebuild_secondary_overlay_vector_byte_planes_in_rect,map,thiscall,inferred,objdump + caller inspection + field correlation,4,"Rectangle-wide rebuild pass over the secondary overlay byte-plane family. The helper clamps the caller rectangle to the live world bounds, scans the packed secondary raster at `[this+0x165d]` together with the primary mask plane `[this+0x1655]`, clears or preserves local state according to the low-3-bit class families, writes signed distance-scaled byte components into the paired vector planes `[this+0x1661]` and `[this+0x1665]`, and invalidates four neighboring sidecar byte planes at `[this+0x1631/+0x1635/+0x1639/+0x163d]` where needed. Current grounded callers are the post-build world-side rectangle refresh around `0x0044f6d7` and the two local owner passes at `0x005374bf` and `0x0053759b`, so this is the safest current read for the shared overlay-vector rebuild owner rather than another tiny cell helper.","objdump + caller inspection + field correlation + vector-plane correlation + sidecar-plane invalidation correlation" 0x00535070,138,world_presentation_ensure_primary_overlay_surface_or_fallback_template_slot,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Small setup owner under the broader world-presentation reinitializer. The helper clears the local `0x100` overlay slot band `[this+0x08]`, resets live count `[this+0x04]`, and then splits on the shell presentation gate at `[0x006d4024+0x11422e]`: when that gate is armed it allocates one `0xec`-byte surface object, initializes it through `0x00541b00` and `0x005417e0` with the current shell root plus fixed `0x100 x 0x100` dimensions, stores the resulting object in slot `0`, and updates byte `[0x006d4024+0x1146eb]` on failure; otherwise it falls back to one static-template slot allocation through `world_presentation_allocate_overlay_slot_from_static_template` `0x00532ad0` using template row `0x005dd26c`. Current grounded caller is `world_presentation_apply_grid_dimensions_and_reinitialize_secondary_overlay_family` `0x00537e60`, so this is the safest current read for the primary overlay-surface-or-template setup owner rather than a more specific player-facing panel builder.","objdump + caller inspection + field correlation + static-template correlation" +0x00535100,816,world_presentation_apply_requested_dimensions_and_rebuild_four_overlay_surface_slots,map,thiscall,inferred,objdump + caller inspection + local disassembly + field correlation,3,"Broader world-presentation resize or rebuild owner above the short four-slot surface band rooted at `[this+0x08 + [this+0x155c]*4]`. The helper first clamps the caller-supplied dimensions through `0x005327a0`, stores the resulting quarter-scaled widths into `[this+0x157c/+0x1580]`, ensures or reuses a contiguous four-slot output band under selector `[this+0x155c]`, and then builds one temporary RGBA buffer sized from the new scaled dimensions. When the optional third argument is non-null it samples that source through `0x00541970` and resamples it into the temporary buffer; otherwise it fills the buffer with the fixed pattern seeded through `0x557f50`. It then allocates four `0xec`-byte destination surfaces through `0x00543980` and stores them into the selected four-slot band. Current grounded callers include the setup-side world reset or regeneration branch at `0x004390a0`, the load-side bundle path at `0x004473d4`, and the neighboring owner wrappers at `0x00535654` and `0x005356a9`, so this is the safest current read for the shared requested-dimension apply and four-slot overlay-surface rebuild owner rather than a smaller slot allocator.","objdump + caller inspection + local disassembly + field correlation + four-slot-band correlation + optional-source-resample correlation" 0x005356e0,428,world_presentation_seed_first_overlay_slot_band_from_static_templates,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Static-template slot-band seeder under the broader world-presentation reinitializer. The helper allocates or reuses one anchor slot through `world_presentation_allocate_overlay_slot_from_static_template` `0x00532ad0` using template row `0x005dd2b0`, records that anchor index and running count in `[this+0x1568]` and `[this+0x156c]`, then seeds a contiguous slot band from template rows `0x005dd2a4` upward for ids `0x66..0x84`. After that first series it revisits the created slots, clears byte `[slot+0x05]`, runs `0x00542550` on the earlier series, and fills two trailing fallback slots from template rows `0x005dd298` and `0x005dd28c`, storing the resulting indices in `[this+0x1574]` and `[this+0x1578]`. Current grounded caller is `world_presentation_apply_grid_dimensions_and_reinitialize_secondary_overlay_family` `0x00537e60`, so this is the safest current read for the first template-driven overlay slot-band seeder rather than a stronger UI-label owner.","objdump + caller inspection + field correlation + static-template correlation" 0x00535890,177,world_presentation_seed_second_overlay_slot_band_from_static_templates,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Second static-template slot-band seeder under the broader world-presentation reinitializer. The helper allocates one anchor slot through `world_presentation_allocate_overlay_slot_from_static_template` `0x00532ad0` using template row `0x005dd2d0`, stores that anchor index in `[this+0x1560]`, then seeds a contiguous slot band from template rows rooted at `0x005dd2bc` for ids `2..0x20`, finally storing the terminal count `0x20` in `[this+0x1564]`. Current grounded caller is `world_presentation_apply_grid_dimensions_and_reinitialize_secondary_overlay_family` `0x00537e60`, so this is the safest current read for the second template-driven overlay slot-band seeder rather than a more player-facing overlay panel owner.","objdump + caller inspection + field correlation + static-template correlation" 0x00535430,687,world_presentation_rebuild_four_overlay_surface_slots_from_source_or_fallback,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Broader four-slot overlay-surface rebuild owner under the world-presentation reinitializer. The helper derives local dimensions through `0x005327a0`, increments the shared shell-side progress counter at `[0x006d4024+0x11427e]`, allocates one temporary RGBA buffer sized from the quarter-scaled dimensions in `[this+0x157c/+0x1580]`, and then fills that buffer either by resampling the caller-supplied source surface or by falling back to a global descriptor at `0x0062bed4` when present. It uses several shell-side resource and range queries through `0x00518de0` and `0x0053c930`, can stage a temporary source surface through `0x0053c1c0`, `0x00541930`, and `0x00541970`, and then emits up to four `0xec`-byte destination surface objects through `0x00543980`, storing them into the local overlay slot band starting at `[this+0x08 + [this+0x155c]*4]`. Current grounded callers are the broader world-presentation reinitializer `0x00537e60` and one neighboring owner at `0x00538060`, so this is the safest current read for the shared four-slot overlay-surface rebuild owner rather than a more specific UI panel constructor.","objdump + caller inspection + field correlation + temporary-surface correlation" @@ -502,7 +636,49 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00536044,468,world_presentation_release_secondary_overlay_support_buffers,map,thiscall,inferred,objdump + local inspection + field correlation,3,"Teardown owner for the secondary-overlay support family. The helper frees the five-entry packed sample-triplet family rooted at `[this+0x15f1..+0x1601]`, the five-entry float summary family rooted at `[this+0x1605..+0x1615]`, the five-entry smoothed unsigned-word family rooted at `[this+0x1619..+0x1629]`, the packed local-byte staging buffer `[this+0x162d]`, the four sidecar byte planes `[this+0x1631..+0x163d]`, the neighboring coarse-cell and support tables, both one-byte mask planes `[this+0x1655]` and `[this+0x1659]`, the packed secondary raster `[this+0x165d]`, and the signed vector byte planes `[this+0x1661]` and `[this+0x1665]`, then nulls the corresponding pointers. The body also re-enters several neighboring support-family destructors `0x00535b40/0x00535c70/0x00535d30/0x00535df0/0x00535a10/0x00535f20`, so this is the safest current read for the shared overlay-support teardown owner rather than another generic presentation reset.","objdump + local inspection + field correlation + multiscale-support correlation + teardown correlation" 0x005375c0,2144,world_presentation_ensure_secondary_overlay_support_buffers_and_seed_defaults,map,thiscall,inferred,objdump + caller inspection + allocation-path inspection,3,"Broad setup or ensure-owner above the secondary-overlay support family. When the caller-supplied enable byte is nonzero, the helper allocates and zero-fills the five-entry packed sample-triplet family rooted at `[this+0x15f1..+0x1601]`, the five-entry float summary family rooted at `[this+0x1605..+0x1615]`, the five-entry smoothed unsigned-word family rooted at `[this+0x1619..+0x1629]`, the packed local-byte staging buffer `[this+0x162d]`, the four neighboring sidecar byte planes `[this+0x1631..+0x163d]`, the packed secondary 3-byte raster `[this+0x165d]`, the signed vector byte planes `[this+0x1661]` and `[this+0x1665]`, the ranked-overlay and geographic-label coarse cell tables `[this+0x1685]` and `[this+0x1675]`, plus several neighboring support tables. The same body also allocates and seeds the two one-byte mask planes with different defaults: `[this+0x1655]` is filled with byte `0x02`, while `[this+0x1659]` is filled with byte `0x01`. Later in the same body it rebuilds the local support surfaces through `0x00536230`, `0x00536420`, `0x00537420`, and the neighbor object allocator `0x005337f0`. Current grounded callers are the shell world-mode branch at `0x00484e47`, the world-presentation resize or rebuild tail at `0x00537f44`, one neighboring world-side refresh at `0x00538629`, and the `.smp`-side restore or reload branch at `0x00553539`, so this is the safest current read for the shared secondary-overlay support-buffer ensure and default-seed owner rather than a narrower vector-field helper.","objdump + caller inspection + allocation-path inspection + multiscale-support correlation + mask-plane default correlation" 0x00537e60,503,world_presentation_apply_grid_dimensions_and_reinitialize_secondary_overlay_family,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Broader world-presentation reinitializer above the secondary-overlay family. The helper publishes one shell progress step, stores the incoming live grid dimensions into `[this+0x15d9/+0x15d5/+0x15dd]`, re-enters `world_allocate_base_secondary_overlay_planes_for_current_dimensions` `0x00532c80` when the dimensions are nonzero, then re-enters `world_presentation_ensure_secondary_overlay_support_buffers_and_seed_defaults` `0x005375c0` and several neighboring overlay initializers or constant-table publishers (`0x00535070`, `0x00535430`, `0x00532ad0`, `0x005356e0`, `0x00534fc0`, `0x00535890`, `0x005373b0`) before returning. Current grounded callers are the world-side reattach branch at `0x0044922a` and the `.smp` restore-side presentation rebuild path at `0x005532d7`, so this is the safest current read for the shared dimension-apply and secondary-overlay-family reinitializer rather than one narrow resize helper.","objdump + caller inspection + field correlation + overlay-reinitialization correlation" +0x00538060,992,world_load_named_tga_into_secondary_overlay_float_summary_and_publish_transport_preview,map,thiscall,inferred,objdump + caller inspection + local disassembly + field correlation,3,"Transport/pricing-preview-side owner beneath `world_ensure_transport_pricing_preview_surface_and_publish_if_missing` `0x0044faf0`. The helper first builds a short descriptor around literal `C_` through `0x00518de0`, re-enters `world_presentation_rebuild_four_overlay_surface_slots_from_source_or_fallback` `0x00535430` to seed one preview handle, temporarily overrides shell globals `[0x006d4024+0x11423b/+0x11423f/+0x114254/+0x114255]`, and then loads `%1.tga` through `0x0053c1c0 -> 0x00541970`. After clamping the sampled dimensions into the `0x401 x 0x401` range, it rewrites the base secondary-overlay float summary plane `[this+0x1605]` together with mask planes `[this+0x1655/+0x1659]` and the packed raster `[this+0x165d]` from the sampled image, optionally re-enters `world_normalize_secondary_overlay_float_summary_plane_globally` `0x00532d90` and `world_expand_positive_secondary_overlay_float_summary_by_radius` `0x00532f60`, republishes the preview handle through `0x0053c000`, re-enters `world_presentation_ensure_secondary_overlay_support_buffers_and_seed_defaults` `0x005375c0(1, 0, 0)`, and returns the handle originally produced by `0x00535430`. Current grounded caller is `0x0044faf0`, so this is the safest current read for the named-TGA preview loader plus secondary-overlay summary rebuild owner rather than a generic surface import helper.","objdump + caller inspection + local disassembly + field correlation + named-tga correlation + transport-preview correlation" 0x00538360,732,world_rebuild_secondary_overlay_base_float_summary_and_primary_mask,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Broader rebuild owner for the base secondary-overlay float-summary plane rooted at `[this+0x1605]` and the paired one-byte mask planes `[this+0x1655]` and `[this+0x1659]`. The helper samples one caller-supplied coarse lookup field, writes one unclamped float score per live cell into the base summary plane, clears both mask planes across the same rectangle, and updates the packed secondary raster at `[this+0x165d]` as it goes. The later interior pass is the useful asymmetry: after the clear, the helper only repopulates the primary mask plane `[this+0x1655]` for low-3-bit class-`1` cells whose neighboring float-summary samples cross the positive threshold, while the second mask plane `[this+0x1659]` remains only reset or preserved for later owners. After that interior sweep it re-enters `world_normalize_secondary_overlay_float_summary_plane_globally` `0x00532d90`, then `world_expand_positive_secondary_overlay_float_summary_by_radius` `0x00532f60`, calls the neighboring refresh owner `0x0053c000`, and finally re-enters `world_presentation_ensure_secondary_overlay_support_buffers_and_seed_defaults` `0x005375c0`. This asymmetry now closes the local split: the helper actively rebuilds only the primary runtime mask, while the second plane stays as the separately persisted sibling for later setup, restore, or compatibility paths.","objdump + caller inspection + field correlation + mask-plane asymmetry correlation + local-split-closure correlation" +0x00538640,160,shell_control_status_owner_construct_and_zero_active_token_tables,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Constructor for the shell-global owner stored at `0x006d401c` during the bootstrap path around `0x0052130b`. The helper zero-fills the `1000`-byte active-token table `[this+0x20]`, clears byte `[this+0xc68]`, allocates one `0x88`-byte helper through `0x0053b070 -> 0x00518b90` into `[this+0xc69]`, clears the remaining text, handle, and deadline fields `[this+0x00..+0x1c]`, `[this+0xc58/+0xc60/+0xc64]`, and seeds scalar `[this+0xc5c] = 0.25f`. Current grounded caller is the bootstrap-side allocation path at `0x0052130b`, so this is the safest current read for the shell status/control owner constructor rather than a generic list-model initializer.","objdump + caller inspection + local disassembly + bootstrap-global correlation" +0x005386e0,192,shell_control_status_owner_publish_primary_text_with_timeout,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Primary timed-text publisher over the shell-global owner at `0x006d401c`. Guarded by reentrancy latch `0x00ccba18`, the helper refreshes owned string field `[this+0x14]` through `0x0051d820`, ensures or releases helper handle `[this+0x18]` through `0x0053c6f0(7)` or `0x0053c000` depending on whether the new text is non-empty, and then writes deadline `[this+0x1c]` as `shell_get_elapsed_tick_count_since_bootstrap_seed` `0x0051d890` plus the caller-supplied timeout or zero when the timeout is absent. Current grounded callers include the shell-side status publishers at `0x00434785`, `0x004829e1`, `0x00482ab7`, `0x00483948`, `0x00538a80`, and `0x00538b94`, so this is the safest current read for the owner's primary timed-text lane rather than a generic string setter.","objdump + caller inspection + local disassembly + timed-text correlation + global-owner correlation" +0x005387a0,112,shell_control_status_owner_publish_secondary_text_with_fixed_10s_timeout,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Secondary timed-text publisher over the same shell-global owner at `0x006d401c`. Guarded by reentrancy latch `0x00ccba1c`, the helper writes deadline `[this+0x08] = shell_get_elapsed_tick_count_since_bootstrap_seed() + 0x2710`, refreshes owned string field `[this+0x10]` through `0x0051d820`, and leaves the lane untouched when the guard is already armed. Current grounded callers include the shell-side publishers at `0x0046d1b3`, `0x0046d4f7`, `0x00483a93`, `0x00483ab3`, `0x00483ad5`, `0x00489b52`, `0x00489c16`, and `0x004df7a7`, so this is the safest current read for the owner's fixed-10-second secondary text lane rather than another generic string setter.","objdump + caller inspection + local disassembly + timed-text correlation + global-owner correlation" +0x00538810,48,shell_find_registered_window_containing_child_control_id,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Search helper over the shell-global owner at `0x006d401c`. The helper walks the registered shell-window list rooted at `[this+0x00]`, asks each window whether it owns the requested child control id through `shell_window_find_registered_child_control_by_id` `0x0053f830`, and returns the first matching window pointer or null. Current grounded callers include the `Setup.win`-adjacent shell paths at `0x004beeb1`, `0x004c9ade`, `0x004c9b30`, `0x004c9b58`, `0x004e07a2`, and `0x0056301f`, so this is the safest current read for the global window-by-child-control-id lookup rather than another child-list walker.","objdump + caller inspection + local disassembly + child-control correlation + global-owner correlation" +0x00538840,64,shell_control_status_owner_clear_active_tokens_for_child_control_id,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Clears every active token-table entry in the shell-global owner whose recorded 16-bit child control id matches the caller input. The helper linearly scans the `1000`-entry id table `[this+0x408]` together with the parallel active-byte table `[this+0x20]`, and for each active matching entry clears the corresponding active byte. Current grounded callers are the two child-control teardown or replacement paths at `0x0055fc8a` and `0x00561632`, so this is the safest current read for the owner's control-id-based token invalidation helper rather than a generic list clear.","objdump + caller inspection + local disassembly + token-table correlation + child-control teardown correlation" +0x00538880,16,shell_control_status_owner_release_active_token_handle,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny release companion for the shell-global active token table. The helper treats the caller dword as one previously returned token handle and clears the corresponding active-byte slot in `[this+0x20]`. Current grounded callers are the local shell-control paths at `0x0055a0fe`, `0x0055a12a`, and `0x00561652`, so this is the safest current read for the owner's token-handle release helper rather than a broader table reset.","objdump + caller inspection + local disassembly + token-table correlation" +0x00538890,64,shell_control_status_owner_allocate_active_token_handle_for_child_control_id,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Allocates one active token-table slot for the caller-supplied 16-bit child control id. The helper linearly scans the `1000`-entry active-byte table `[this+0x20]` for the first clear slot, marks it active, stores the control id into the parallel id table `[this+0x408]`, and returns the opaque token handle `0xea60 + slot_index`; when no free slot exists it returns `0`. Current grounded callers are the shell-control allocation or replacement paths at `0x0055a3cd`, `0x0055a4a4`, `0x00560140`, `0x00561322`, and `0x00561428`, so this is the safest current read for the owner's control-id-scoped token allocator rather than a generic id registry.","objdump + caller inspection + local disassembly + token-table correlation + child-control correlation" +0x005388d0,177,shell_dispatch_12_dword_descriptor_across_registered_windows_with_optional_override,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Dispatch owner for one stack- or caller-supplied `12`-dword shell descriptor. The helper first copies the descriptor into a local work buffer, then consults the optional override validator at `[0x006d401c+0xc75]` through vtable slot `+0x04`; when that override vetoes the descriptor it falls back to the registered shell-window list rooted at `[this+0x00]` and forwards the same descriptor through `0x0053fe90` on each window until one handler returns the stop code. When the incoming kind dword is `6`, the helper also recursively redispatches a rewritten copy with kind `0xb7`. Current grounded callers include the higher publishers `0x00538c70`, `0x00538e00`, and `0x00538f10`, so this is the safest current read for the shared shell descriptor dispatcher rather than a window-family-local callback.","objdump + caller inspection + local disassembly + registered-window correlation + descriptor-rewrite correlation" +0x00538990,48,shell_registered_window_list_call_virtual_slot_0_until_one_returns_zero,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small list-walk gate over the registered shell-window list rooted at `[this+0x00]`. The helper walks each node through link field `+0x58`, calls that node's vtable slot `+0x00` with the caller payload, and stops on the first zero return; when the list is empty it returns `1`. Current grounded caller is the shell dispatch gate at `0x00483a47`, which uses the helper as an early allow or veto pass before deeper message handling, so this is the safest current read for the registered-window virtual-slot gate rather than a generic iterator.","objdump + caller inspection + local disassembly + shell-window-list correlation" +0x005389c0,80,shell_registered_window_list_unlink_node_and_optionally_release,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Unlinks one shell-window or shell-node record from the doubly linked list rooted at `[this+0x00/+0x04]`. When the caller-supplied node is non-null the helper first re-enters `0x005400c0(node)` to run the node's local release or reset path, then repairs predecessor and successor links through fields `+0x54/+0x58`, and updates the list root or tail when the removed node occupied either end. Current grounded callers include the shell-window teardown paths at `0x00482f17`, `0x004830d9`, `0x004bc19c`, `0x004c9b92`, `0x004cf8cc`, `0x004ddc56`, `0x004e1c99`, `0x004e5010`, `0x00501ef2`, `0x00507942`, and `0x00517512`, so this is the safest current read for the shared registered-window unlink helper rather than a window-family-specific destructor.","objdump + caller inspection + local disassembly + shell-window-list correlation + doubly-linked-list correlation" +0x00538a10,16,shell_control_status_owner_query_float_scalar_0xc5c,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny x87 getter over float scalar `[this+0xc5c]` in the shell-global owner at `0x006d401c`. Current grounded caller is `0x0053decb`, which multiplies the returned value into one presentation-side scalar chain, so the safest current read stays structural around the direct float getter.","objdump + caller inspection + local disassembly" +0x00538a20,16,shell_control_status_owner_set_float_scalar_0xc5c,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny setter companion for float scalar `[this+0xc5c]` in the shell-global owner at `0x006d401c`. Current grounded callers are the shell-mode branches at `0x00483025`, `0x00483182`, `0x00483294`, `0x004832c2`, `0x004832f0`, `0x0048331e`, `0x00483348`, and `0x00483372`, so the safest current read stays structural around the direct float setter.","objdump + caller inspection + local disassembly" +0x00538a30,16,shell_control_status_owner_increment_counter_0xc60,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny increment helper over counter dword `[this+0xc60]` in the shell-global owner at `0x006d401c`. Current grounded callers include shell and world-side branches at `0x00437d99`, `0x004416dd`, `0x004561ba`, `0x00464548`, `0x004b92a3`, `0x004c7ff9`, `0x004ed8a8`, `0x004fec80`, `0x00517512`, and `0x0055c0bd`, so the safest current read stays structural around the direct counter bump rather than a stronger semantic label.","objdump + caller inspection + local disassembly" +0x00538a40,19,shell_control_status_owner_decrement_counter_0xc60_clamped_to_zero,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny decrement companion for counter dword `[this+0xc60]` in the shell-global owner at `0x006d401c`. The helper decrements the counter in place and clamps the stored value back to `0` when the subtraction would underflow below zero. Current local context keeps this as the direct counter-decrement helper rather than a stronger named semaphore owner.","objdump + caller inspection + local disassembly" +0x00538a60,16,shell_control_status_owner_query_counter_0xc60_is_zero,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny boolean gate over counter dword `[this+0xc60]` in the shell-global owner at `0x006d401c`. The helper returns `1` when that counter is zero and `0` otherwise. Current grounded callers include the shell dispatch-side branches at `0x0043d753`, `0x00483a2b`, `0x00483b20`, `0x004fe485`, `0x004fec71`, and `0x00500423`, so the safest current read stays structural around the zero-counter predicate.","objdump + caller inspection + local disassembly" +0x00538a70,272,shell_control_status_owner_publish_reset_text_and_release_registered_windows,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Broader teardown owner over the shell-global status/control object at `0x006d401c`. The helper first republishes the fixed text payload `0x005c87a8` through `shell_control_status_owner_publish_primary_text_with_timeout` `0x005386e0(0xbb8)`, then walks the registered shell-window list rooted at `[this+0x00/+0x04]`, releasing each node through `0x005400c0` and unlinking it from the list. After that it frees the counted pointer band `[this+0xbd8]` using count `[this+0xc58]`, clears the owned text buffers rooted at `[this+0x10]` and `[this+0x14]`, and releases payload handle `[this+0x0c]` through `0x0053c000` when present. Current grounded caller is the bootstrap-side teardown path at `0x0052146e`, which immediately follows by freeing the owner and nulling `0x006d401c`, so this is the safest current read for the global status/control owner reset-and-release body rather than a generic shell shutdown.","objdump + caller inspection + local disassembly + bootstrap-teardown correlation + shell-window-list correlation" +0x00538b60,272,shell_runtime_prime_service_registered_windows_and_timed_text_lanes,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Primary service owner over the shell-global runtime object at `0x006d401c`. When disable byte `[this+0xc68]` is clear, the helper first re-enters `0x0054f6a0`, refreshes the primary timed-text lane by comparing deadline `[this+0x1c]` against `shell_get_elapsed_tick_count_since_bootstrap_seed` `0x0051d890` and republishing fixed payload `0x005c87a8` through `0x005386e0(0xbb8)` when that deadline has expired, then walks the registered shell-window list from tail `[this+0x04]` through link field `+0x54`, servicing each node through `shell_service_one_object_child_queue_and_deferred_state` `0x0053fda0` and `0x0051f1d0`. After the walk it conditionally presents the secondary lane `[this+0x10/+0x0c]` while deadline `[this+0x08]` is still live, and then presents the primary lane `[this+0x14/+0x18]` when its text is non-empty. Current grounded callers are the shell-state service branches at `0x0048218e`, `0x004835ed`, and `0x00483d2e`, so this is the safest current read for the shell runtime-prime service owner rather than a narrow text-only publisher.","objdump + caller inspection + local disassembly + shell-runtime-prime correlation + timed-text correlation + registered-window-service correlation" +0x00538c70,400,shell_control_status_owner_publish_prioritized_cached_text_and_dispatch_descriptor_0xae,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Broader cached-text publisher on the shell-global owner at `0x006d401c`. Guarded first by shell-global byte `[0x006d4024+0x57]`, the helper falls back to default text pointer `0x00624d64` when the caller passes null, compares the new request against the currently cached text band `[this+0xbd8/+0xbdc/+0xbe0/+0xbe4]`, and suppresses the update when one still-live cached entry of equal-or-higher priority is already active. Otherwise it replaces the owned cached string at `[this+0xbd8]`, stores the caller priority at `[this+0xbdc]`, stores the caller style or lane token at `[this+0xbe0]`, derives one near or long-lived deadline into `[this+0xbe4]`, and then emits the corresponding shell descriptor by rewriting local kind `0xae` through `shell_dispatch_12_dword_descriptor_across_registered_windows_with_optional_override` `0x005388d0`. Current grounded callers include the linked-peer status publishers at `0x0040e4e0`, `0x0041f720`, `0x0041f7b0`, `0x004b84f0`, and several shell detail or popup builders, so this is the safest current read for the prioritized status-text-plus-descriptor owner rather than a plain string cache.","objdump + caller inspection + local disassembly + priority-cache correlation + descriptor-dispatch correlation + shell-status correlation" +0x00538e00,77,shell_dispatch_synthetic_12_dword_descriptor_from_five_scalars,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small descriptor-synthesis wrapper above `shell_dispatch_12_dword_descriptor_across_registered_windows_with_optional_override` `0x005388d0`. The helper zero-fills one local `12`-dword descriptor, copies the caller's five scalar arguments into the leading five slots, and then forwards that synthetic descriptor into `0x005388d0`. Current grounded callers include `shell_transition_mode` `0x00482ec0` and the route-entry collection follow-on at `0x004c3470`, which use it to post compact shell events without building a full descriptor structure by hand.","objdump + caller inspection + local disassembly + descriptor-synthesis correlation" +0x00538e50,100,shell_registered_window_list_insert_node_sorted_by_priority_and_optionally_prepare_node,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Insertion owner for the registered shell-window list rooted at `[this+0x00/+0x04]`. When the caller-supplied prepare flag is nonzero, the helper first re-enters `0x0053f7f0(node, 1)` on the node itself, then inserts that node into the doubly linked list using sort key dword `[node+0x21]`, walking backward from the current tail through link field `+0x54` until the insertion point is found and repairing predecessor or successor fields `+0x54/+0x58`. Current grounded callers include `shell_transition_mode` `0x00482ec0`, several shell window ensure paths, and the broader blocking loop `0x00538f10`, so this is the safest current read for the shared registered-window insert owner rather than a window-family-local show helper.","objdump + caller inspection + local disassembly + doubly-linked-list correlation + sort-key correlation" +0x00538ec0,72,shell_control_status_owner_refresh_indexed_helper_collection_c69,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Refresh sweep over the indexed helper collection rooted at `[this+0xc69]` in the shell-global owner `0x006d401c`. The helper enumerates live entries through `indexed_collection_slot_count` `0x00517cf0`, `indexed_collection_get_nth_live_entry_id` `0x00518380`, and `indexed_collection_resolve_live_entry_by_id` `0x00518140`, then forwards each resolved entry into `0x0053e2b0`. Current grounded callers are shell-global setter paths such as `0x00464e4f`, `0x00464e7c`, `0x0051f9d4`, and `0x0051f9f4`, so this is the safest current read for the owner's helper-collection refresh sweep after selection-state changes rather than a generic collection walk.","objdump + caller inspection + local disassembly + indexed-collection correlation + shell-selection correlation" +0x00538f10,657,shell_publish_optional_window_and_run_blocking_descriptor_loop,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Broader blocking shell loop owner over the shell-global runtime object at `0x006d401c`. The helper first increments nested-loop counter `[this+0xc64]`, optionally seeds one caller-supplied shell window by writing sort key `[window+0x21]` and auxiliary dword `[window+0x6c]` before publishing it through `shell_registered_window_list_insert_node_sorted_by_priority_and_optionally_prepare_node` `0x00538e50`, optionally resolves and nudges one child control id through `shell_find_registered_window_containing_child_control_id` `0x00538810` and `0x0055c8b0`, snapshots shell controller state through `0x0054e7e0/0x0054f4d0`, and then loops on one `12`-dword descriptor buffer. Inside that loop it special-cases descriptor kind `6` into `0xb7` through `0x005388d0`, consults the optional global override validator at `[0x006d401c+0xc75]`, lets one optional global filter at `0x006d3b4c` and the caller-supplied window's vtable slot `+0x04` inspect the descriptor, pumps the shell controller through `0x0051f950`, and exits when the descriptor reaches one of the explicit completion kinds `0xc9` or `0xcd`, deriving the final return code from descriptor word `+0x04` or from `0x0054e9c0`. Current grounded callers include the modal window openers at `0x004d9dc0` and `0x004d9e40`, the shell settings opener `0x00501e50`, and several broader shell teardown or transition branches, so this is the safest current read for the optional-window publish plus blocking descriptor loop rather than a simple show-window helper.","objdump + caller inspection + local disassembly + descriptor-loop correlation + modal-loop correlation + registered-window correlation" +0x005391b0,121,route_entry_release_optional_world_space_attachment_and_owned_buffer_then_dispatch_vtable_slot_0,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Release-side helper in the broader route-entry family. When the caller-supplied boolean is nonzero and shell-global gate `[0x006d4024+0x114256]` is clear, the helper projects current world-space floats `[this+0x0c/+0x10]` into local integers, forwards them together with byte `[this+0x55]` into `0x00533e00` on attachment root `[this+0x04]`, then frees owned pointer `[this+0x1e3]` through `0x005a1145` when present and finally dispatches the object's vtable slot `+0x00`. Current grounded callers include the route-entry-side branches at `0x00490f6e` and `0x0053a598`, so this is the safest current read for the optional world-space attachment release plus virtual teardown helper rather than a generic destructor.","objdump + caller inspection + local disassembly + route-entry correlation + attachment-release correlation" +0x00539230,336,route_entry_apply_local_visual_scalar_preset_by_state_byte,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Applies one of several local visual-scalar presets to a route-entry-family object from one small state byte. The helper writes the chosen state into byte `[this+0x5a]` and then seeds paired float bands at `[this+0x73/+0x77/+0x8b/+0x8f/+0xa3/+0xa7/+0xbb/+0xbf/+0xd3/+0xd7/+0xeb/+0xef/+0x103/+0x107/+0x11b/+0x11f]`, with distinct layouts for the grounded caller states `0`, `1`, `2`, and `3`. Current grounded callers include the route-entry-side update branches at `0x0048a003`, `0x0048a00f`, `0x0048b5ab`, and `0x0048b61e`, so this is the safest current read for the route-entry local visual-scalar preset setter rather than a generic float initializer.","objdump + caller inspection + local disassembly + route-entry correlation + visual-scalar correlation" +0x00539380,295,route_entry_apply_table_driven_visual_profile_and_optional_display_latch,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Table-driven profile setter in the same route-entry family. The helper first normalizes the caller's state byte into one compact profile index, optionally maps the 'display-latched' byte `[this+0x44]` from that index, and then copies several static table-driven dwords into the object's higher visual bands, including `[this+0x1f5/+0x1f9]`, `[this+0x17b..+0x1af]`, `[this+0x193/+0x197]`, `[this+0x1c3/+0x1c7]`, `[this+0x1db/+0x1df]`, and `[this+0x1fd]`. Current grounded callers include `0x0048f59d`, `0x0049154a`, `0x004916ae`, and `0x0053ae23`, where the same helper runs immediately before the neighboring route-entry visual refresh `0x00539640`, so this is the safest current read for the route-entry table-driven visual profile loader rather than a generic palette setter.","objdump + caller inspection + local disassembly + route-entry correlation + table-driven-profile correlation" +0x005394b0,112,route_entry_copy_four_3d_triplet_bands_out,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small export helper over four consecutive `3*dword` triplet bands in the route-entry-family object. The helper copies the optional output triplets from `[this+0x14]`, `[this+0x20]`, `[this+0x2c]`, and `[this+0x38]` into up to four caller-supplied output pointers. Current grounded caller is `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0`, which uses the helper to stage the current route-entry shape or bounding triplets into its builder-state area before deeper search continues, so this is the safest current read for the four-triplet export helper rather than a generic memcpy wrapper.","objdump + caller inspection + local disassembly + route-entry-builder correlation + triplet-band correlation" +0x00539580,77,route_entry_broadcast_three_scalar_args_to_each_attached_handle_in_list_8,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small broadcast helper over the optional attached-handle list rooted at `[this+0x08]` in the same route-entry-family object. When that list exists and yields live entries through `0x00556ef0/0x00556f00`, the helper forwards the caller's three scalar arguments into `0x00530720` on each resolved attached handle. Current grounded caller is `0x0053a5b0`, which forwards current scalar lanes `[this+0x0c/+0x10]` plus one caller argument through this helper, so this is the safest current read for the route-entry attached-handle broadcast owner rather than a generic collection walk.","objdump + caller inspection + local disassembly + route-entry correlation + attached-handle-list correlation" +0x005395d0,112,route_entry_ensure_attached_handle_list_add_handle_and_publish_aggregate_scalar,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Attach-and-publish helper in the same route-entry-family object. The helper ensures attached-handle list root `[this+0x08]` through `0x0053b070(0x18) -> 0x00556db0`, adds the caller-supplied handle into that list through `0x00556e10`, derives one aggregate scalar from the four local scalar lanes `[this+0x18/+0x24/+0x30/+0x3c]` plus one caller-supplied height or bias term, and then publishes the resulting three-scalar packet through `0x00530720` using the local head lanes `[this+0x0c/+0x10]`. Current grounded caller is the small wrapper `0x0053a5b0`, which keeps the safest current read structural around attached-handle registration plus aggregate-scalar publish rather than a stronger subtype label.","objdump + caller inspection + local disassembly + route-entry correlation + attached-handle-list correlation + aggregate-scalar correlation" +0x00539640,1854,route_entry_recompute_derived_visual_scalar_bands_and_optional_display_buffer,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Heavy derived-band rebuild in the same route-entry family. The helper first treats the four stored `3*dword` triplet bands at `[this+0x14]`, `[+0x20]`, `[+0x2c]`, and `[+0x38]` as two endpoint pairs, derives midpoint and half-delta scalars on each axis, and then uses profile weights `[this+0x1f5/+0x1f9/+0x1fd]` plus repeated root query `0x00534490([this+0x04], x, y)` to populate the larger derived visual bands rooted at `[this+0x63]`, `[+0x7b]`, `[+0x93]`, `[+0xab]`, `[+0xc3]`, `[+0xdb]`, `[+0xf3]`, `[+0x10b]`, `[+0x123]`, `[+0x13b]`, `[+0x153]`, `[+0x16b]`, `[+0x183]`, `[+0x19b]`, `[+0x1b3]`, and `[+0x1cb]`. It also updates one global sample lane through `0x00624e00` selected by `0x00ccba24`, clamps several rebuild results against constants `0x005c8c18` and `0x005c8888`, refreshes the center scalars `[this+0x0c/+0x10]`, and conditionally maintains the optional owned `0xc0`-byte display buffer at `[this+0x1e3]`: display-state byte `[this+0x44] == 0` frees it, state `1` writes a compact two-column layout from the raw triplet endpoints and local offset dwords `[this+0x45/+0x49/+0x4d/+0x51]`, and states `2/3` populate the same buffer from weighted midpoint and half-delta bands. Current grounded callers include the route-entry profile setters `0x0048f5aa`, `0x00491599`, `0x004916bf`, collection-wide post-pass `0x00491c20`, and the local rebuild wrappers `0x0053a7f9`, `0x0053a910`, `0x0053a94c`, and `0x0053ac90`, so this is the safest current read for the main route-entry derived-visual-band and optional-display-buffer rebuild rather than a generic interpolation helper.","objdump + caller inspection + local disassembly + route-entry correlation + weighted-derived-band correlation + optional-display-buffer correlation" +0x0053a520,63,global_replace_optional_shell_owned_root_0xccba20_from_single_payload_ptr,bootstrap,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Small global replace helper over root `0x00ccba20`. When the caller-supplied payload pointer is non-null, the helper first releases any existing owned root at `0x00ccba20` through shell owner `0x006d4020` plus `0x0053c000`, then rebuilds that root through `0x0053c1c0(payload,0,0,0x7f)` and stores the result back into `0x00ccba20`. Current grounded caller is the broader bootstrap-side branch at `0x0055e739`, so this is the safest current read for the small replace-in-global-root helper rather than a route-entry-local constructor.","objdump + caller inspection + local disassembly + global-root correlation" +0x0053a560,32,global_release_optional_shell_owned_root_0xccba20,bootstrap,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Tiny release-side companion over global root `0x00ccba20`. When that root is live, the helper releases it through shell owner `0x006d4020` plus `0x0053c000` and then clears `0x00ccba20` back to null. Current grounded caller is the broader shutdown branch at `0x0055e171`, so this is the safest current read for the focused global-root release helper rather than a family-local destructor.","objdump + caller inspection + local disassembly + global-root correlation" +0x0053a590,13,route_entry_vtable_5dd3d8_release_thunk_set_vtable_and_reenter_optional_attachment_teardown,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny release thunk in the route-entry object family. The helper reinstalls vtable `0x005dd3d8`, pushes release flag `1`, and immediately re-enters `route_entry_release_optional_world_space_attachment_and_owned_buffer_then_dispatch_vtable_slot_0` `0x005391b0`. This is the safest current read for the route-entry release thunk rather than a standalone destructor body.","objdump + caller inspection + local disassembly + route-entry correlation" +0x0053a5b0,18,route_entry_broadcast_current_head_lanes_and_caller_scalar_to_attached_handles,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny wrapper above `route_entry_broadcast_three_scalar_args_to_each_attached_handle_in_list_8` `0x00539580`. The helper forwards current head lanes `[this+0x0c/+0x10]` together with the caller-supplied scalar to every live attached handle in `[this+0x08]`. This is the safest current read for the simple attached-handle broadcast wrapper rather than a broader update owner.","objdump + caller inspection + local disassembly + route-entry correlation" +0x0053a5d0,247,route_entry_attach_handle_ensure_list_and_optionally_clone_seed_from_first_live_entry,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Broader attached-handle add helper in the same route-entry family. When attached-handle list root `[this+0x08]` is null, the helper ensures that list and falls straight through to `route_entry_ensure_attached_handle_list_add_handle_and_publish_aggregate_scalar` `0x005395d0`. When the list already exists, it resolves the first live entry, clones one temporary helper from that seed through `0x0052e880/0x0052e8b0/0x0052e720`, releases the temporary source through `0x00530680 + 0x0053b080`, publishes the cloned handle through `0x00530720`, and finally inserts that cloned handle back into `[this+0x08]` through `0x00556e10`. Current grounded caller is the optional `Infrastructure` child-attach branch `0x0048a325`, so this is the safest current read for the attached-handle ensure plus seed-clone path rather than a plain list add.","objdump + caller inspection + local disassembly + route-entry correlation + attached-handle-clone correlation" +0x0053a6d0,101,route_entry_release_attached_handle_list_and_entries,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Release helper over the optional attached-handle list rooted at `[this+0x08]` in the same route-entry family. The helper walks every live attached handle through `0x00556ef0/0x00556f00`, releases each one through `0x00530680`, frees it through `0x0053b080`, tears the list root down through `0x005570b0` and `0x005571d0`, and finally clears `[this+0x08]` back to null. This is the safest current read for the attached-handle-list teardown owner rather than a broader route-entry destructor.","objdump + caller inspection + local disassembly + route-entry correlation + attached-handle-release correlation" +0x0053a740,322,route_entry_copy_four_triplets_refresh_attachment_tile_and_recompute_center_scalars,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Primary four-triplet setter in the route-entry family. The helper copies up to four caller-supplied triplet buffers into the local bands `[this+0x14]`, `[+0x20]`, `[+0x2c]`, and `[+0x38]`, and when shell-global gate `[0x006d4024+0x114256]` is clear and root `[this+0x04]` is present it quantizes current world-space floats `[this+0x0c/+0x10]` into coarse tile coords, re-enters `route_entry_recompute_derived_visual_scalar_bands_and_optional_display_buffer` `0x00539640`, and refreshes optional attachment id `[this+0x55]` by releasing the previous attachment through `0x00533e00(root, old_id, old_x, old_y)` and acquiring the new one through `0x00533dd0(root, this, new_x, new_y)`. It finally recomputes center scalars `[this+0x1ed/+0x1f1]` from the second and fourth triplets. Current grounded callers include `0x0053ac82` and `0x0053ae53`, so this is the safest current read for the shared four-triplet setter plus attachment refresh owner rather than another raw memcpy wrapper.","objdump + caller inspection + local disassembly + four-triplet correlation + attachment-refresh correlation" +0x0053a890,137,route_entry_reproject_all_four_triplet_midlines_and_rebuild,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small route-entry rebuild wrapper above `0x00539640`. The helper reprojects the Y component of all four stored triplets by re-entering `0x00534490([this+0x04], x, z)` on each pair, normalizes the second and fourth triplets so each pair collapses to its lower or upper member when inverted, recomputes center scalars `[this+0x1ed/+0x1f1]`, and then re-enters `route_entry_recompute_derived_visual_scalar_bands_and_optional_display_buffer` `0x00539640`. Current grounded callers are the route-entry world-refresh branches around `0x0053a5b0`, so this is the safest current read for the local reproject-and-rebuild wrapper rather than a generic sort helper.","objdump + caller inspection + local disassembly + root-height-query correlation + route-entry-rebuild correlation" +0x0053a920,51,route_entry_fill_all_four_triplets_and_center_scalars_from_uniform_scalar_then_rebuild,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Uniform-scalar reset wrapper in the route-entry family. The helper writes the same caller-supplied dword into all four triplet bands rooted at `[this+0x18]`, copies that same scalar into center lanes `[this+0x1ed/+0x1f1]`, and then re-enters `route_entry_recompute_derived_visual_scalar_bands_and_optional_display_buffer` `0x00539640`. This is the safest current read for the uniform triplet-fill reset path rather than another scalar setter.","objdump + caller inspection + local disassembly + uniform-triplet-fill correlation" +0x0053ac40,91,route_entry_rebind_root_reset_attachment_and_optionally_rebuild_from_current_triplets,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Root-rebind reset helper in the route-entry family. The helper detaches and forgets optional display buffer `[this+0x1e3]`, current root `[this+0x04]`, and current attachment id `[this+0x55]`, resolves one fresh root through `0x0051f090`, re-enters `route_entry_copy_four_triplets_refresh_attachment_tile_and_recompute_center_scalars` `0x0053a740` with the current local triplet bands, clears attached-handle list pointer `[this+0x08]`, and only re-enters `route_entry_recompute_derived_visual_scalar_bands_and_optional_display_buffer` `0x00539640` when an owned display buffer was present before the reset. This is the safest current read for the route-entry root rebind plus optional rebuild helper rather than a bare clear routine.","objdump + caller inspection + local disassembly + root-rebind correlation + optional-rebuild correlation" +0x0053aca0,357,route_entry_construct_default_state_and_seed_visual_profile_tables,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Concrete constructor for the same route-entry object family. The helper installs vtable `0x005dd3d8`, clears root, attachment, and optional display-buffer pointers `[this+0x04/+0x55/+0x1e3]`, seeds local style bytes `[this+0x44]=0` and `[this+0x5a]=0xff`, initializes the larger visual-color bands to repeated packed default `0xff7f7f7f`, seeds four local offset dwords `[this+0x45/+0x49/+0x4d/+0x51]`, seeds several default scalar bands such as `[this+0x73/+0x77/+0x8b/+0x8f/+0xa3/+0xa7/+0xbb/+0xbf/+0xd3/+0xd7/+0xeb/+0xef/+0x103/+0x107/+0x11b/+0x11f]`, loads default profile-table dwords from `0x00624d88..0x00624dd4` into `[this+0x17b..]`, `[+0x163..]`, `[+0x133..]`, `[+0x14b..]`, and `[+0x1fd]`, clears the triplet bands and center scalars `[this+0x0c/+0x10/+0x1ed/+0x1f1]`, and normalizes style byte `[this+0x59]` to keep the low nibble while forcing bit `0x10`. This is the safest current read for the default route-entry constructor rather than a generic visual preset helper.","objdump + caller inspection + local disassembly + constructor-state correlation + default-profile-table correlation" +0x0053ae10,85,route_entry_bind_root_apply_state_profile_copy_four_triplets_and_reset_style_latch,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small construction-time binder above the route-entry helpers. The helper stores caller root at `[this+0x04]`, applies the requested state byte through `route_entry_apply_table_driven_visual_profile_and_optional_display_latch` `0x00539380`, zeroes live center scalars `[this+0x0c/+0x10]` and attachment id `[this+0x55]`, copies four caller-supplied triplets through `route_entry_copy_four_triplets_refresh_attachment_tile_and_recompute_center_scalars` `0x0053a740`, then clears the low-nibble style bits in `[this+0x59]` and resets packed color dword `[this+0x5f]` to `0xff7f7f7f`. This is the safest current read for the root-bind plus profile-and-triplet initialization wrapper rather than another plain setter.","objdump + caller inspection + local disassembly + root-bind correlation + state-profile correlation" 0x005373b0,112,world_presentation_seed_default_overlay_companion_record_set,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Seeds the default static overlay-companion record set after a broader presentation reinit. The helper zero-fills the local `0x1b`-entry companion slot table at `[this+0x40c]`, clears live count `[this+0x408]`, and then invokes `world_presentation_allocate_overlay_companion_record_from_static_template` `0x00535950` seven times with the static template rows `0x005dd300`, `0x005dd314`, `0x005dd328`, `0x005dd33c`, `0x005dd350`, `0x005dd364`, and `0x005dd378`. Current grounded caller is `0x0053804e` inside `world_presentation_apply_grid_dimensions_and_reinitialize_secondary_overlay_family` `0x00537e60`, so this is the safest current read for the shared default companion-record seeder rather than a later border-overlay rebuild owner.","objdump + caller inspection + field correlation + static-template correlation" 0x005374d0,240,world_refresh_secondary_overlay_support_surfaces_and_vector_field_in_rect,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Rectangle-wide owner above the secondary-overlay support family. The helper clamps the caller rectangle to the live world bounds, clears shift field `[this+0x15e1]`, runs `0x00536230` across the selected cells to refresh one packed three-float local sample field rooted at `[this+0x15f1]`, runs `0x00536420` across the same rectangle to rebuild one companion unsigned-word field rooted at `[this+0x1619]`, then rebuilds the signed vector byte planes through `world_rebuild_secondary_overlay_vector_byte_planes_in_rect` `0x00536710`, and finally regenerates the multiscale support surfaces through `world_rebuild_secondary_overlay_multiscale_support_surfaces_in_rect` `0x00533890`. Current grounded callers are the late world-side rectangle branch at `0x0044d45c` and the shell-side scan or brush branch at `0x004fc4bf`, so this is the safest current read for the shared secondary-overlay rectangle refresh owner rather than a one-shot startup allocator.","objdump + caller inspection + field correlation + multiscale-support correlation + vector-plane correlation" 0x00533b70,7,world_query_overlay_strip_offset_lut_ptr,map,thiscall,inferred,objdump + caller inspection + allocation-path inspection,3,"Tiny root-pointer getter for the overlay strip-offset lookup table at `[this+0x15e5]`. The table is allocated in the world-presentation setup path around `0x00537b68` and filled with `i * 0x5c` offsets in `0x00537cb0..0x00537ccc`. Current grounded callers are shell-side presentation and staging branches around `0x00524e92`, `0x00525b7e`, `0x0052ae90`, `0x0052b4ef`, and `0x0054dd50`, which consume it together with the normalized coordinate LUTs and sample-record roots.","objdump + caller inspection + allocation-path inspection + field correlation" @@ -553,16 +729,37 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004d4110,32,map_editor_event_variable_values_panel_construct,map,thiscall,inferred,objdump + RT3.lng strings + UI callback inspection,4,"Constructs the shell-side `Event Variable Values` tracking page in the map-editor control panel. The helper binds the report callback `0x004d38c0` and sits beside the neighboring event-validation page in the active-section page table.","objdump + RT3.lng strings + UI callback inspection + page-constructor correlation" 0x004d4130,32,map_editor_event_validation_panel_construct,map,thiscall,inferred,objdump + RT3.lng strings + UI callback inspection,4,"Constructs the shell-side event-validation page in the map-editor control panel. The helper binds the report callback `0x004d3d90`, which checks for missing status or win-lose events and other per-event errors before formatting the result list.","objdump + RT3.lng strings + UI callback inspection + page-constructor correlation" 0x00456920,3247,unit_visual_init_weapon_airframe_and_exhaust_effects,bootstrap,thiscall,inferred,ghidra-headless,4,Initializes one armed-unit visual bundle spanning turret and cannon hardware exhaust emitters and aircraft airframe attachments. The routine creates static Turret Mantlet Cannon and MuzzleFlash assets at [this+0x31a] through [this+0x326] direct JetExhaust and PropExhaust sprite emitters at [this+0x2f6] and [this+0x2fa] a cannon-audio attachment at [this+0x32a] indexed WingL and WingR assets plus plane-audio state at [this+0x32e] through [this+0x346] and cached Aileron Elevator Rudder and Thrust vectors at [this+0x2d1] [this+0x2c5] [this+0x2b9] and [this+0x2dd].,ghidra + rizin + llvm-objdump + strings +0x0045a700,240,placed_structure_specialization_accumulate_anim_record_anchor_delta_for_key,map,cdecl,inferred,objdump + local disassembly + field correlation,2,"Small shared helper beneath the specialization `%1_Anim.3dp` transient family. Starting from either the base or alternate basis bands rooted at `0x006acd4c+0x04/+0x34` and `0x006acd4c+0x40/+0x70`, the helper scans every live `0x168`-byte row in the current shared collection `0x006acd50`, filters rows whose key dword matches the supplied id and whose `[row+0x8c]` does not carry bit `0x400`, converts the paired integer triplets through the current basis floats, and accumulates the resulting three-float offset into the caller output vector. Current grounded callers are the heavier shared animation-record service body at `0x0045a9c0`, so this is the safest current read for a keyed anchor-delta accumulator rather than a constructor or renderer.","objdump + local disassembly + field correlation + shared-collection correlation" +0x0045a7f0,453,placed_structure_specialization_replace_anim_record_key_rebind_references_and_activate_selected_effect_slot,map,thiscall,inferred,objdump + local disassembly + global-state correlation,2,"Keyed replace-or-publish helper for the same shared `%1_Anim.3dp` transient family. After validating the caller object through `0x00459c30`, the helper scans the current shared record collection rooted at `0x006acd50/0x006acd4c`, replaces every matching record key dword with the supplied replacement pointer, and also rewrites that same key through the embedded four-lane pointer bands inside each live row while setting row flag bit `0x40` when the top-level record key changes. When the current mode gate in global state `0x006acd48` is negative and the replacement row is not already linked, it inserts that row into the intrusive active list rooted at `0x006acd5c`, stores the caller object at `[row+0x04]`, mirrors the replacement pointer into `[0x006acd48-0x04]`, conditionally dispatches vtable slot `+0x10` on the replacement object, clears byte bit `0x20` when the current shared controller says no emitter owner is active, and if selector table `0x006acd44` is live it allocates one selector-`0` effect slot through `0x00475ed0` before forwarding that slot into `0x00475240(-1,0)`. Current grounded caller is the specialization animation-record build pass at `0x0045b760`, so this is the safest current owner for keyed anim-record replacement plus selected effect-slot activation rather than a generic container insert helper.","objdump + local disassembly + global-state correlation + shared-collection correlation + effect-slot correlation" +0x0045a9c0,1043,placed_structure_specialization_service_shared_anim_record_for_owner_and_publish_two_triplets,map,thiscall,inferred,objdump + local disassembly + global-state correlation,2,"Heavier per-record service body beneath the shared `%1_Anim.3dp` transient family. After validating the caller object through `0x00459c30`, the helper first honors the current controller gates in `0x006acd48/0x006acd58`: when the active selector-owner list `0x006acd44` is live it clears and re-arms flag bit `0x01000000` plus `0x555e50(0)` across those effect slots, and it also mirrors one caller dword into row field `[row+0x80]` when controller bit `0x20` is armed. It then resolves two current world-anchor triplets for the owner through `0x0052e880` and `0x0052e720`, scans every matching row in the current shared collection `0x006acd50/0x006acd4c`, updates each row's timing or countdown fields, derives three local scalar deltas through `0x0045a280`, accumulates those deltas into two caller-facing triplets, optionally subtracts keyed anchor-delta corrections through `0x0045a700`, and finally republishes the finished triplets through `0x0052e8b0` and `0x00530720`. Current grounded caller is the shared 15-tick service loop at `0x0045ade0`, so this is the safest current owner for per-owner anim-record service and triplet republish rather than a constructor or generic transform helper.","objdump + local disassembly + global-state correlation + shared-collection correlation + triplet-publish correlation" +0x0045ade0,158,placed_structure_specialization_service_shared_anim_record_list_in_15_tick_windows,map,cdecl,inferred,objdump + local disassembly + global-state correlation,2,"Shared service loop for the `%1_Anim.3dp` transient list rooted at `0x006acd5c`. On first entry it seeds the current tick cursor `0x006acd60` from `[0x006cec78+0x15]`; thereafter it marks reentrancy latch `0x006acd58 = 1`, advances the cursor in `0x0f`-tick windows until it catches the current world tick, and for every linked record whose owner pointer at `[record+0xf0]` is live it dispatches the heavier per-record service body at `0x0045a9c0(owner, cursor, 0)`. Once the cursor catches the current tick it clears the latch again. Current evidence is strongest for a windowed shared anim-record service loop rather than another global constructor or teardown helper.","objdump + local disassembly + global-state correlation + shared-list correlation" +0x0045ae80,206,placed_structure_specialization_load_shared_anim_payload_root_if_percent1_anim_present,map,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Bootstrap side for the shared `%1_Anim.3dp` payload root used by the specialization animation-record family. The helper formats literal `%1_Anim.3dp`, probes the named-bank owner `0x006d4020` through `0x0053c930`, resolves the matched entry handle through `0x0053b5c0`, queries its payload length through `0x0053c9c0`, reads the raw bytes through `0x0053bd40`, copies them into a fresh heap buffer through `0x0053b7c0`, and lazily allocates the intrusive list root `0x006acd5c` when it does not already exist. On success it returns the loaded payload buffer; otherwise it returns null. Current grounded caller is the specialization build pass at `0x0045b760`, so this is the safest current read for `%1_Anim.3dp` payload-root bootstrap rather than a generic bank read helper.","objdump + local disassembly + literal inspection + named-bank correlation + shared-list correlation" +0x0045af50,232,placed_structure_specialization_bind_shared_anim_row_collection_and_prune_owner_active_records,map,thiscall,inferred,objdump + local disassembly + global-state correlation,2,"Shared collection bind or reset helper for the same `%1_Anim.3dp` transient family. The helper clears globals `0x006acd44/48/54`, publishes the caller row collection into `0x006acd50`, computes the current row-data base into `0x006acd4c`, and scans every row header to mirror the last seen row selector into `0x006acd44` while releasing any oversize selector root through `0x00475100` when the per-row count exceeds `0x0f`. It then walks the intrusive active list rooted at `0x006acd5c`, removes every linked record whose owner pointer at `[record+0xf0]` matches the current collection owner, and frees the list root itself when the list becomes empty. Current grounded callers are the specialization release and rebuild family around `0x0045b160`, so this is the safest current read for shared anim-row collection bind plus owner-prune rather than a generic destructor.","objdump + local disassembly + global-state correlation + shared-list correlation + collection-bind correlation" +0x0045b040,11,placed_structure_specialization_demote_to_base_vtable_and_tail_into_common_cleanup,map,thiscall,inferred,objdump + caller correlation,2,"Tiny specialization-to-base cleanup thunk. The helper overwrites the current vtable with base table `0x005cb4c0` and then tails directly into the common placed-structure cleanup path at `0x00455650`. Current grounded callers are the specialization teardown wrappers at `0x0040c970` and `0x0045b160`, so this is the safest current read for a direct demote-to-base cleanup leaf rather than another constructor or publish helper.","objdump + caller correlation + vtable-demotion correlation" +0x0045b050,86,placed_structure_specialization_reset_payload_and_transient_fields_and_optionally_clear_base_state,map,thiscall,inferred,objdump + local disassembly + field correlation,2,"Small reset helper for the concrete placed-structure specialization. The function clears payload roots `[this+0x23e]` and `[this+0x242]`, transient handles `[this+0x246]`, `[this+0x24a]`, and `[this+0x24e]`, resets `[this+0x262] = -1`, zeroes timer or state fields `[this+0x266]` and `[this+0x26a]`, clears the packed flag band at `[this+0x23a..+0x23d]`, and when the caller argument is nonzero it re-enters the common placed-structure clear path at `0x00455610`. This is the safest current read for specialization field reset plus optional base-state clear rather than another constructor or destructor thunk.","objdump + local disassembly + field correlation + specialization-family correlation" +0x0045b0b0,53,placed_structure_specialization_publish_integer_triplet_to_owner_and_primary_transient_if_live,map,thiscall,inferred,objdump + local disassembly + field correlation,2,"Small publish-side helper in the same concrete placed-structure specialization family. The function forwards one caller-supplied integer triplet plus fixed mode `1` through `0x0052e680` on the specialization owner itself, then repeats the same publish into the primary transient handle `[this+0x246]` when that handle is live. Current evidence is strongest for one integer-triplet publish leaf shared by the owner and its primary transient rather than a builder or teardown helper.","objdump + local disassembly + field correlation + triplet-publish correlation" +0x0045b0f0,23,placed_structure_specialization_forward_packed_rgb_triplet_into_vtable_slot_0x58,map,thiscall,inferred,objdump + local disassembly,2,"Tiny packed-color forwarder in the concrete placed-structure specialization family. The helper splits one caller-supplied packed dword into its low, middle, and high bytes and dispatches those three components through vtable slot `+0x58` on the current object. Current evidence is only strong enough for a packed RGB-triplet forwarder, not a stronger user-facing semantic name.","objdump + local disassembly + packed-byte-split correlation" +0x0045b110,5,placed_structure_specialization_tail_into_shared_world_anchor_triplet_publisher,map,thiscall,inferred,objdump + caller correlation,2,"Tiny tail-call wrapper into `runtime_object_publish_world_anchor_triplet_from_normalized_xy_and_height_bias` `0x00455660`. Current grounded callers are the nearby specialization-side rebuild and refresh branches, so this is safest as a direct wrapper into the shared world-anchor triplet publisher rather than as a distinct geometry owner.","objdump + caller correlation + world-anchor-wrapper correlation" 0x0045b120,64,placed_structure_specialization_publish_small_payload_record_from_arg_string,map,thiscall,inferred,objdump + local disassembly + allocator correlation,2,"Small specialization-side publisher beneath the concrete placed-structure table `0x005c8c50`. The helper allocates a fixed `0x35`-byte record through `0x0053b070`, populates that record from the caller-supplied string plus `this` through `0x00553ac0`, and then forwards the resulting pointer into `0x0052d9a0`; on allocation failure it forwards `null` through that same sink. Current local evidence grounds the fixed-size allocation and the arg-string forwarding, but not the exact semantic role of the published record, so this note stays at the payload-record level.","objdump + local disassembly + allocator correlation + specialization-table correlation" 0x0045b160,176,placed_structure_specialization_release_transient_handles_and_payload_strings,map,thiscall,inferred,objdump + local disassembly + field-release inspection,3,"Release-side cleanup helper in the concrete placed-structure specialization family. The function sets bit `0` in `[this+0x23a]`, clears `[this+0x24a]`, conditionally tears down the transient handles rooted at `[this+0x256]`, `[this+0x25a]`, `[this+0x25e]`, and `[this+0x24e]` through `0x0045af50`, `0x00475100`, and `0x00418d40`, then re-enters vtable slot `+0x78`, the common placed-structure cleanup slice `0x00455d20`, and finally frees the two payload strings rooted at `[this+0x23e]` and `[this+0x242]` through `0x0053aff0`. This is the strongest current owner for releasing the specialization's transient handles and payload strings rather than a base destructor.","objdump + local disassembly + field-release inspection + cleanup-chain correlation" 0x0045b210,352,placed_structure_specialization_build_ambient_transient_from_candidate_payload,map,thiscall,inferred,objdump + local disassembly + string correlation,2,"Transient-build helper beneath the concrete placed-structure specialization table `0x005c8c50`. The function requires a live candidate through vtable slot `+0x80`, formats one payload string around the literal `amb_%1_01.wav` through `0x00518de0`, allocates a `0x141`-byte transient object through `0x0053b070`, initializes that object through `0x00554830`, `0x00554340`, and `0x00554450`, stores the result at `[this+0x24a]`, and registers it through `0x0052da00`. The `amb_%1_01.wav` literal grounds this as one ambient-side transient builder, but not the exact user-facing subtype name of the owning specialization.","objdump + local disassembly + string correlation + transient-build correlation" 0x0045b5f0,123,placed_structure_specialization_refresh_ambient_transient_from_current_world_position,map,thiscall,inferred,objdump + local disassembly + world-position correlation,2,"Ambient-transient refresh helper for the same concrete placed-structure specialization. The function resolves the current local position through `0x0052e720`, converts that position through the world or view helpers `0x0051f090` and `0x00534490`, then forwards the derived scalar plus one caller-supplied argument into `placed_structure_specialization_build_ambient_transient_from_candidate_payload` `0x0045b210`. When the resulting ambient transient at `[this+0x24a]` is live it immediately re-enters `0x005543f0(0)`. Current evidence grounds this as a refresh of the ambient-side transient from current world position rather than the primary transient-handle builder.","objdump + local disassembly + world-position correlation + ambient-transient correlation" 0x0045b6f0,694,placed_structure_specialization_rebuild_named_variant_descriptors_and_effect_handles,map,thiscall,inferred,objdump + local disassembly + string-table correlation,2,"Large subtype-specific rebuild helper beneath the concrete placed-structure specialization table `0x005c8c50`. The function first clears the optional handles at `[this+0x25a]` and `[this+0x25e]`, then builds and probes multiple named variant families rooted in `[this+0x23e]` through format strings such as `%1_`, `%1_Upgrade1`, `%1_Anim%2.3dp`, `%1_Upgrade1Anim%2.3dp`, and `%1_Upgrade1Light%2.3dp`. It loops over numbered variants `1..0xfe`, probes resource existence through `0x0053c930`, materializes follow-on records through `0x00530640`, publishes them through `0x0052d8a0`, and couples the ambient-side refresh path through `placed_structure_specialization_refresh_ambient_transient_from_current_world_position` `0x0045b5f0` plus the ambient builder `0x0045b210`. The exact subtype semantics remain open, but this is now the strongest current owner for rebuilding the specialization's named animation, light, and sibling effect descriptors rather than a generic serializer-side helper.","objdump + local disassembly + string-table correlation + descriptor-rebuild correlation" +0x0045b760,583,placed_structure_specialization_build_base_or_upgrade_variant_descriptors_emitters_and_anim_records,map,thiscall,inferred,objdump + local disassembly + literal inspection,2,"Broader specialization-side builder beneath the same `0x005c8c50` family. The helper first scans one base-or-upgrade descriptor family rooted in `[this+0x23e]` through `%1_` or `%1_Upgrade1`, probing each numbered variant through `0x0053c930` and dispatching every accepted hit through vtable slot `+0x7c`. It then builds the matching attached-emitter list through `placed_structure_build_attached_emitter_variant_list_by_owner_stem` `0x0045e940`, ensures transient root `[this+0x256]` exists through `0x0045ae80`, and finally scans one animation family through `%1_Anim%2.3dp` or `%1_Upgrade1Anim%2.3dp`, materializing each accepted hit into a `0x206` record through `0x00530640`, publishing that record through `0x0052d8a0`, hashing the generated name through `0x0053d810`, and forwarding the result into `[this+0x256]` through `0x0045a7f0`. Current evidence is strongest for a base-or-upgrade descriptor, emitter, and animation-record build pass rather than a serializer or teardown helper.","objdump + local disassembly + literal inspection + specialization-family correlation + transient-record correlation" 0x0045baf0,850,placed_structure_specialization_service_timed_anim_light_and_random_sound_variants,map,thiscall,inferred,objdump + local disassembly + string-table correlation + timer-field inspection,2,"Timed service or emission helper for the same concrete placed-structure specialization. The function updates the two timer-like fields `[this+0x26a]` and `[this+0x266]`, derives local world-grid and distance terms from `[this+0x1e2/+0x1e6/+0x1ea]`, gates on candidate availability through vtable slot `+0x80` and the nearby candidate-side workers `0x00411e10/0x00411e50`, and when the local timing and distance checks pass it formats one output around the literal `rnd_%1_%2.wav` together with the neighboring anim or light string family `%1_Anim%2.3dp`, `%1_Upgrade1Anim%2.3dp`, and `%1_Upgrade1Light%2.3dp`. The final dispatch goes through `0x00531e50` under owner `0x006d402c`. Current evidence is strongest for a timed anim, light, or random-sound variant service lane rather than another payload loader or steady-state scalar updater.","objdump + local disassembly + string-table correlation + timer-field inspection + random-sound correlation" 0x0045be50,768,placed_structure_specialization_service_runtime_scalar_and_transient_state,map,thiscall,inferred,objdump + local disassembly + field correlation,2,"Recurring runtime-service helper for the same concrete placed-structure specialization. The function consults transient handle `[this+0x256]`, site-side link `[this+0x75]`, scenario globals under `0x006cec78`, and the iterator pair `0x00556ef0/0x00556f00`; it then updates the derived scalar triplet `[this+0x22e]`, `[this+0x232]`, and `[this+0x236]`, republishes that triplet through `0x00530720`, and re-enters `0x0052e8e0` for the final side-effect. The exact high-level behavior remains open, but the field ownership is strong enough to ground this as the runtime scalar and transient-state service slice for the specialization rather than another serializer or constructor.","objdump + local disassembly + field correlation + service-loop correlation" 0x0045c150,448,placed_structure_specialization_load_payload_and_rebuild_transients,map,thiscall,inferred,objdump + local disassembly + serializer-tag correlation,3,"Primary payload-loader counterpart to `0x0045b560` in the concrete placed-structure specialization family. The helper reseeds the derived field band `[this+0x23a..+0x26a]`, re-enters the common placed-structure initializers `0x00455610` and `0x00455fc0`, opens the derived payload bracket tagged `0x5dc1`, reads two string-like payload fields through `0x00531380`, copies them into `[this+0x23e]` and `[this+0x242]` via `0x0051d820`, clears the transient handle roots `[this+0x24e]`, `[this+0x256]`, `[this+0x25a]`, and `[this+0x25e]`, rebuilds follow-on specialization state through `0x0045b5f0` and `0x0045b6f0`, conditionally dispatches vtable slot `+0x74`, reads back `[this+0x24e]` and `[this+0x252]`, and finally closes the bracket tagged `0x5dc2`. This is now the strongest current owner for specialization payload load plus transient rebuild rather than a generic stem-refresh helper.","objdump + local disassembly + serializer-tag correlation + transient-rebuild correlation" 0x0045c310,176,placed_structure_specialization_build_primary_transient_handle_from_payload_strings,map,thiscall,inferred,objdump + local disassembly + field correlation,2,"Specialization-side transient builder rooted in payload strings `[this+0x23e]` and `[this+0x242]`. The helper formats one payload around the literal family at `0x005cb5d4`, allocates a `0x23a`-byte object through `0x0053b070`, initializes it through `0x00456100`, stores the handle at `[this+0x246]`, registers it through `0x00530720`, re-enters `0x0045b6f0(1)`, forwards the handle into `0x0052d8a0`, and when the current placed structure is active through `0x004557f0` it also dispatches vtable slot `+0x5c`. This is the strongest current owner for the primary specialization transient-handle build path rather than the ambient-side `[this+0x24a]` builder.","objdump + local disassembly + field correlation + transient-build correlation" 0x0045c3c0,160,placed_structure_specialization_release_primary_transient_handle_and_siblings,map,thiscall,inferred,objdump + local disassembly + field-release inspection,2,"Release-side companion to `0x0045c310`. When `[this+0x246]` is live the helper re-enters `0x00455d20`, iterates the linked transient family through `0x00556ef0/0x00556f00`, destroys every sibling object except the current `[this+0x246]` through `0x00530680` and `0x0053b080`, conditionally re-enters `0x0045b6f0(0)` when bit `0` in `[this+0x23a]` is clear, then destroys `[this+0x246]` through `0x00455650`, frees it, clears the field, and tails into `0x005570b0`. Current evidence grounds this as the primary transient-handle release path for the specialization rather than another base cleanup thunk.","objdump + local disassembly + field-release inspection + transient-release correlation" +0x0045cc90,677,train_visual_toggle_three_selector_effect_slots_and_reseed_shared_anchors,map,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Paired build-or-release owner for three selector-driven effect slots stored at `[table+0x34]`, `[table+0x38]`, and `[table+0x3c]` inside the train visual row table rooted at `[this+0x316]`. In build mode `arg0 == 1`, the helper derives one mode scale from current local geometry, allocates selector `1`, `2`, and `3` bundles through `0x00475ed0`, writes those handles into the three table fields, reseeds their shared anchors through `0x00475010/0x00475030`, and then enables every live attached emitter in the main row-object list by writing byte `1` into `[emitter+0x1d8]`. In release mode it tears those same three slot handles down through `0x00475100`, clears the table fields, and disables the same emitter list by writing byte `0` into `[emitter+0x1d8]`. Current grounded callers include the train visual-family teardown `0x0045e3d6` and later world-side service branches `0x004ad841` and `0x004b1944`, so this is best read as the shared three-slot train-effect toggle rather than a generic emitter helper.","objdump + local disassembly + caller inspection + train-visual correlation + effect-slot correlation" +0x0045cf40,224,train_visual_toggle_selector5_effect_slot_and_row_emitter_enable_state,map,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Sibling build-or-release owner for the selector-`5` effect slot stored at `[table+0x40]` inside the same train visual row table rooted at `[this+0x316]`. In build mode `arg0 == 1`, the helper derives one mode scale from current local geometry, allocates selector `5` through `0x00475ed0`, stores that handle into `[table+0x40]`, and then enables every live emitter in the main row-object list by writing byte `1` into `[emitter+0x1d8]`. In release mode it tears that one slot down through `0x00475100`, clears `[table+0x40]`, and disables the same emitter list by writing byte `0` into `[emitter+0x1d8]`. Current grounded callers include the train visual-family teardown `0x0045e3de` and later world-side service branches `0x004ab942`, `0x004adaa1`, and `0x004b18d6`, so this is best read as the selector-`5` sibling toggle for the train visual family rather than another generic emitter-slot wrapper.","objdump + local disassembly + caller inspection + train-visual correlation + effect-slot correlation" +0x0045d130,176,train_effect_attach_named_handle_by_owner_profile_and_register,map,thiscall,inferred,objdump + local disassembly + literal inspection + caller inspection,2,"Builds and registers one named train-effect handle beneath the adjacent train-side transient family. The helper first resolves one owner-side profile through the collection at `0x006ada84`, allocates a `0x141`-byte object through `0x0053b070`, and initializes it through `0x00554830` using one mode-selected stem from the small selector at `0x0045d22e`, the caller's owner and anchor parameters, and one fixed mode byte `1`. It then writes two fixed float-like parameters through `0x00554340` and `0x00554450`, stores the live handle at `[this+0x336]`, and finally forwards that handle into `0x0052da00`. Current grounded caller is the broader train-side effect builder at `0x0045e375`, so this is best read as the shared attach-and-register builder for one named train effect handle rather than a generic pool allocation stub.","objdump + local disassembly + literal inspection + caller inspection + train-effect correlation" +0x0045d260,120,train_effect_update_live_handle_rate_distance_and_optional_mode,map,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Updates one previously attached train-effect handle stored at `[this+0x336]`. When that handle is live, the helper queries one current scalar through `0x00554230`, multiplies it by the caller float, clamps the result into `0x1f40..0xac44`, writes the clamped value through `0x005542c0`, pushes the caller gain through `0x00554450`, and when the live handle mode at `[handle+0x138]` equals `1` also forwards zero through `0x005543f0`. Current grounded caller is the later world-side service path at `0x004a8cf9`, so the safest current read is a live train-effect parameter updater rather than a constructor.","objdump + local disassembly + caller inspection + handle-parameter correlation" +0x0045d2e0,451,train_effect_refresh_breakdown_or_burning_sound_handle,map,thiscall,inferred,objdump + local disassembly + literal inspection + caller inspection,2,"Owns the sound-side branch above the adjacent train-effect handle helpers. The function first republishes the current world anchor triplet through `0x0052e720`; when an attached sound handle already exists at `[this+0x346]` it updates that live handle's anchor fields `[+0x10/+0x14/+0x18]` through `0x00531ef0` and marks flag bit `0x02`. Otherwise it selects one sound stem according to the current train-state latches `[this+0x33a/+0x33e/+0x342]`: fixed `Train_Burning.wav`, fixed `Train_Breakdown_loop.wav`, or one dynamic stem from the table at `0x005f3a84` after the `0x0041b8f0 -> 0x004a8840` branch. It then creates a fresh sound handle through `0x00531e50`, stores it into `[this+0x346]`, sets fixed flag bits `0x18`, seeds two scale fields from the chosen mode factor through constants at `0x005c8c48` and `0x005cb698`, and finally clears the three state latches again. Current grounded caller is the train-side world service branch at `0x004acf5d`, so this is best read as the breakdown-or-burning train sound-handle refresh owner rather than another generic transient setter.","objdump + local disassembly + literal inspection + caller inspection + train-effect correlation + sound-handle correlation" +0x0045d4b0,1684,train_visual_preload_variant_tables_and_service_point_body_handles,map,thiscall,inferred,objdump + local disassembly + literal inspection + caller inspection,2,"Large train-side preload owner above the adjacent sound and handle helpers. The function optionally clears prior state through `0x00455610`, copies the caller primary and secondary stems into `[this+0x32e]` and `[this+0x332]`, probes the named-bank owner `0x006d4020` for the secondary stem, then falls back through the primary stem and the suffixed `_C.tga` form at `0x005cb7e8`. It resolves one `ServicePoint.3dp` payload into `[this+0x23e/+0x23a]`, one `Body.3dp` payload into `[this+0x242/+0x246]`, counts existing `%1_Truck%2.3dp` variants into `[this+0x31a]`, allocates the larger per-variant table at `[this+0x316]`, and then enters the later subloops that populate the cargo-icon, bogie, drivewheel, piston, connecting-rod, coupling-bar, body, and track-point bands. Current grounded callers are the train-side setup or refresh branches at `0x0041ce2f`, `0x0042acc6`, and `0x0045e653`, so this is best read as the train visual variant-table and service-point or body preload owner rather than a small local helper.","objdump + local disassembly + literal inspection + caller inspection + train-visual correlation + variant-table correlation" +0x0045e390,415,train_visual_release_sound_handle_variant_table_and_payload_strings,map,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Release-side owner for the same train visual family. The helper drops the optional sound handle `[this+0x346]` through `0x00531ef0` plus the mode-gated `0x005317b0` path, clears the live train-effect handle root `[this+0x336]` by re-entering `0x0045cc90(0)` and `0x0045cf40(0)`, iterates the variant table at `[this+0x316]` to free per-row pointer arrays, the two per-row heap buffers at offsets `+0x98/+0x9c`, and any nested owned list rooted at `[row+0x0c]->[+0x75]`, then frees the main table itself and finally releases the two payload strings at `[this+0x32e]` and `[this+0x332]`. Current grounded caller is the train-side teardown branch at `0x0042ac49`, so this is best read as the train visual-family release owner rather than another generic destructor.","objdump + local disassembly + caller inspection + train-visual correlation + teardown correlation" +0x0045e530,855,train_visual_load_payload_rebuild_variant_table_and_optional_child_records,map,thiscall,inferred,objdump + local disassembly + serializer-tag correlation + local disassembly,2,"Load-side owner for the same train visual family. The helper clears the current table and string roots, opens bundle tags `0x61a9` and `0x61aa` through `0x00531360`, reads two variable-length heap strings through `0x00531380`, optionally rewrites the first caller string by scanning the live collection at `[0x006d4020+0x429b8]`, then rebuilds the train visual family through `train_visual_preload_variant_tables_and_service_point_body_handles` `0x0045d4b0` with unit scale `1.0f`. After that it republishes the early per-row handles through `0x005548d0`, frees the temporary heap strings, and when scenario latch `[0x006cec78+0x46c34] > 0x2585` is true it enters the optional child-record branch under tag `0x61b2`, dispatching vtable slot `+0x48` across the rebuilt row collection before closing tag `0x61ab`. This is the clearest current load-side owner for the train visual payload plus optional child-record branch rather than another small table helper.","objdump + local disassembly + serializer-tag correlation + train-visual correlation + load-branch correlation" +0x0045e8c0,124,train_visual_service_row_object_strip_and_optionally_refresh_selected_entry,map,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Small service helper over the fixed 32-entry row-object strip rooted at `[this+0x277]`. The function first walks all 32 slots and, for every live row object pointer, dispatches vtable slot `+0x10`. When the caller passes a valid row index instead of `-1`, it then resolves that selected row again, dispatches vtable slot `+0x0c`, and when the paired per-row flag byte in the neighboring strip is nonzero it also pushes `0,0,1.0f,1.0f` through `0x0052eab0` on that selected row object. Current grounded callers are the two train-side update branches at `0x0041c680` and `0x0041c69a`, which derive the selected index from byte `[cargo+0x20]`, so this is best read as the row-object service plus optional selected-entry refresh helper rather than a generic list walk.","objdump + local disassembly + caller inspection + train-visual correlation + row-object-strip correlation" 0x004614d0,40,runtime_object_vtable_wrapper_query_local_companion_float_relief_score_at_rounded_coords,map,thiscall,inferred,objdump + local disassembly + wrapper correlation,2,"Tiny virtual-style wrapper over `world_query_local_companion_float_relief_score_at_cell_with_distance_and_mode_bias` `0x0044afa0`. It rounds the current object's normalized secondary and primary coordinates through `0x00455810`, `0x00455800`, and `0x005a10d0`, then forwards the resulting cell pair plus world root `0x0062c120` into `0x0044afa0`. Current evidence grounds it only as the table-local wrapper over the heavier world-scalar query, not the owning subtype name.","objdump + local disassembly + wrapper correlation + world-scalar-query correlation" 0x00461500,39,runtime_object_query_flag_byte_0x42_with_class0_true_fallback_when_mode_gate_inactive,map,thiscall,inferred,objdump + local disassembly + mode-gate correlation,2,"Small mode-gated flag query on the same virtual-family boundary as `0x004614d0`. The helper first checks shell mode gate `0x004338c0` on scenario root `0x006cec78`; when that gate is active it returns byte `[this+0x42]` directly. When the gate is inactive it returns literal `1` only for class-0 records with `[this+0x23e] == 0`, and otherwise falls back to the same byte `[this+0x42]`. Current evidence is strong enough only for that structural fallback rule, not for a tighter semantic name for the flag or owning subtype.","objdump + local disassembly + mode-gate correlation + field inspection" 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 @@ -581,16 +778,104 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004744a0,101,city_database_entry_collection_allocate_and_construct_entry,map,thiscall,inferred,objdump + local disassembly + caller xrefs + collection-layout correlation,2,"Shared allocator and constructor beneath the city-database entry collection. The helper initializes one stack-local temporary entry through `0x00474110`, allocates a `0x250`-byte live record through `0x00518900`, resolves that record through `0x00518140`, then constructs it through `0x00474130` with the caller-supplied entry id plus three caller arguments, and finally tears down the temporary entry through `0x004743d0`. Current grounded caller is the collection load or clone lane at `0x004744ed`.","objdump + local disassembly + caller xrefs + collection-layout correlation + temp-entry correlation" 0x00474510,32,city_database_entry_collection_remove_entry_by_id_and_release,map,thiscall,inferred,objdump + local disassembly + collection-layout correlation,2,"Small collection-side removal helper for the current city-database entry family. The function resolves the caller-supplied entry id through `0x00518140`, releases the resolved entry through `0x00474400`, and then removes the id from the collection through `0x00518a30`.","objdump + local disassembly + collection-layout correlation + removal-path correlation" 0x00474540,197,city_database_entry_collection_load_records_from_bundle_context,map,thiscall,inferred,objdump + caller xrefs + local disassembly + collection-load correlation,2,"Underlying collection-owned load loop beneath `map_load_city_database` `0x00474610`. The helper opens tag family `0x61a9/0x61aa/0x61ab` on the caller-supplied bundle, binds the selected path context through `0x00518680`, iterates every live record in the current collection, seeds a stack-local temporary entry through `0x00474110`, dispatches each record's vtable slot `+0x40` with the current bundle context, accumulates the returned byte count, tears the temporary entry down through `0x004743d0`, and finally closes tag `0x61ab`. Current grounded caller is the map-load branch at `0x00444834`, so this is now the safest current read for the collection-owned city-database record load loop.","objdump + caller xrefs + local disassembly + collection-load correlation + bundle-tag correlation" -0x00474610,120,map_load_city_database,map,cdecl,inferred,ghidra-headless,3,Loads the city database branch in the same pattern as the geographic-label loader. It stages resource ids 0x61a9 through 0x61ab binds the selected bundle through 0x517d90 iterates the collection with 0x517cf0 0x518380 and 0x518140 and dispatches each record through vtable slot +0x44.,ghidra + rizin + llvm-objdump + strings -0x00474e20,336,effect_slot_create_attached_sprite_emitter,bootstrap,thiscall,inferred,ghidra-headless,3,Creates or clones one attached sprite emitter for an effect slot on the owning object. Depending on flag bit 0x400 it either clones through 0x00556ce0 or allocates a fresh 0x1fd template through 0x00556920 then attaches the emitter to the owner at [emitter+0x60] and optionally sets persistent flag [emitter+0xbc].,ghidra + rizin + llvm-objdump -0x00474f70,97,effect_slot_update_attached_sprite_emitters,bootstrap,thiscall,inferred,ghidra-headless,3,Advances every sprite emitter stored in one effect-slot container by iterating its pointer list and calling 0x00555e50 with update mode zero. When the caller passes null it instead walks the global linked slot list rooted at 0x006cea74.,ghidra + rizin + llvm-objdump +0x00474610,120,city_database_entry_collection_reload_records_from_bound_bundle_context,map,cdecl,inferred,objdump + local disassembly + collection-load correlation,2,"Bundle-side reload owner for the live city-database entry collection. The helper opens tag family `0x61a9/0x61aa/0x61ab` on the caller bundle through `0x00531340`, binds the selected path or payload context into the collection through `0x00517d90`, walks every live record through `0x00517cf0/0x00518380/0x00518140`, and dispatches each record through vtable slot `+0x44` with the same bundle context before finally closing tag `0x61ab`. This is the strongest current read for the direct bundle-reload companion to the collection-owned load loop `0x00474540`, rather than a generic map-load stub.","objdump + local disassembly + collection-load correlation + bundle-tag correlation" +0x00474690,107,effect_emitter_table_publish_mode1_ratio_labels,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Walks the global emitter-definition table rooted at `0x006cea60` and, for each live entry whose mode dword `[entry+0x30]` equals `1`, derives one rounded ratio from float fields `[entry+0x00] / [entry+0x08]`, combines that with keyed field `[entry+0x34] | 0x10000` through `0x0053d810`, and forwards the resulting token into owner `0x006d4030` through `0x00556c50`. Current evidence grounds the iteration and derived ratio shape, but not the exact user-facing caption of the published label lane.","objdump + local disassembly + literal inspection + emitter-table correlation" +0x00474700,133,effect_table_load_particles_dat_into_global_root_and_register_particles_texture,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Reloads the global particle-data table from banked file `particles.dat`. The helper frees any previous root at `0x006cea5c`, checks for the named banked record through `0x0053c930`, resolves its keyed handle and payload length through `0x0053b5c0/0x0053c9c0`, allocates a new payload slab, reads that payload through `0x0053b7c0`, stores the resulting root at `0x006cea5c`, and finally registers literal `ParticlesTexture` through `0x00556370` on owner `0x006d4030`. This is the clearest current owner for the `particles.dat` load path rather than a generic banked-record fetch helper.","objdump + local disassembly + literal inspection + banked-record correlation + particle-table correlation" +0x00474790,133,effect_table_load_emitters_dat_into_global_root,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Reloads the global emitter-definition table from banked file `emitters.dat`. The helper frees any previous root at `0x006cea60`, checks for the named banked record through `0x0053c930`, resolves its keyed handle and payload length through `0x0053b5c0/0x0053c9c0`, allocates a new payload slab, reads that payload through `0x0053b7c0`, and stores the resulting root at `0x006cea60`. This is the clearest current owner for the `emitters.dat` load path rather than a generic banked-record fetch wrapper.","objdump + local disassembly + literal inspection + banked-record correlation + emitter-table correlation" +0x00474820,58,effect_emitter_table_find_entry_by_hashed_name,bootstrap,thiscall,inferred,objdump + local disassembly + literal inspection,2,"Hashes the caller-supplied NUL-terminated name through `0x0053d810(…,1)` and linearly scans the global emitter-definition table rooted at `0x006cea60` for the first entry whose leading dword matches that hash. On success it returns the matched entry root; otherwise `0`. Current grounded callers are the emitter-builder families at `0x00475420`, `0x00475550`, and their neighbors, where the names come from literal stems such as `steam`.","objdump + local disassembly + literal inspection + emitter-table correlation + hashed-name correlation" +0x00474860,257,effect_emitter_table_select_next_existing_formatted_3dp_variant,bootstrap,thiscall,inferred,objdump + local disassembly + literal inspection + caller inspection,2,"Selector-style iterator over the global emitter-definition table rooted at `0x006cea60`. When the caller passes `EDX = 1`, the helper resets global scan state `0x005f2c30` and row ordinal `0x006ceb94`; otherwise it resumes from that saved state. For each remaining emitter row it formats one candidate name into the local stack buffer through format string `%s%s%i.3dp` at `0x005ce4e8`, using the caller-supplied owner stem, the current row suffix at `[row+0x04]`, and the current ordinal. It then probes that formatted name through `0x0053c930`; on the first accepted variant it stores the chosen row root into `0x006cea90`, copies the formatted name into `0x006cea94`, advances the saved ordinal state, and returns `0x006cea90`. On exhaustion it restores the scan state to `(1,0)` and returns `0`. Current grounded caller is the attached-emitter build loop at `0x0045e940`, so this is best read as the formatted `*.3dp` variant enumerator above the emitter instantiator rather than a general banked-record lookup helper.","objdump + local disassembly + literal inspection + caller inspection + emitter-table correlation + formatted-variant correlation" +0x00474970,39,effect_handle_array_release_all_handles,bootstrap,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Linear release helper over one simple handle-array root whose live handle count sits at `[this+0x08]` and whose first handle pointer sits at `[this+0x0c]`. The helper forwards each live handle into `0x00554d50` and returns. Current grounded caller is the broader emitter-template teardown path at `0x00474db0`.","objdump + local disassembly + caller inspection + handle-array correlation" +0x004749a0,33,effect_name_matches_literal_steam,bootstrap,thiscall,inferred,objdump + local disassembly + literal inspection,1,"Tiny literal-compare predicate that tests the caller string at `[this+0x44]` against literal `steam` at `0x005ce4f4` through `0x005a57cf` and returns `1` only on an exact match.","objdump + local disassembly + literal inspection + string-compare correlation" +0x004749d0,653,effect_apply_emitter_definition_to_attached_sprite_handle,bootstrap,cdecl,inferred,objdump + local disassembly + caller inspection + table correlation,2,"Lower emitter-definition applicator beneath `effect_slot_create_attached_sprite_emitter` `0x00474e20`. The helper copies multiple scaled float bands and packed dword fields from the caller emitter-definition row into the target attached-emitter handle, seeds the handle transform or extent bands at `[handle+0x70..+0x90]` and `[handle+0xf0..+0x108]`, resolves the particle-data row named by the emitter definition through `0x0053d810` against the global `particles.dat` table rooted at `0x006cea5c` and mirrors that row into `[handle+0x10c..]`, applies several flag-sensitive scalar adjustments from definition fields `[+0xc0]` and `[+0xc8]`, and writes one referenced owner-side template or handle field into `[handle+0x1ac]`. Current grounded callers are the flagged emitter-template prebuild `0x00474c60` and the broader attached-emitter creator `0x00474e20`, so this is the safest current read for the concrete definition-to-handle materialization body rather than another table lookup or slot allocator.","objdump + local disassembly + caller inspection + emitter-table correlation + particle-table correlation + handle-layout correlation" +0x00474c60,114,effect_emitter_table_build_attached_emitter_templates_for_flagged_entries,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection + caller inspection,2,"Walks the global emitter-definition table rooted at `0x006cea60` and, for each live entry whose build-flag dword `[entry+0xb8]` equals `1`, hashes its inline name at `[entry+0x04]`, resolves or reuses one owner-side template through `0x00556ce0` on `0x006d4030`, mirrors emitter flags `[entry+0xbc] | 0x10004` into both that owner-side template and the later attached-emitter build call, and then creates the attached emitter through `effect_slot_create_attached_sprite_emitter` `0x004749d0` with scale `1.0f`. Current grounded caller is the global bootstrap path `0x00474ce0`, so this is the clearest current owner for the flagged emitter-template prebuild pass.","objdump + local disassembly + literal inspection + caller inspection + emitter-table correlation + bootstrap correlation" +0x00474ce0,195,effect_system_bootstrap_particle_tables_slot_pool_and_flagged_emitter_templates,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection + caller inspection,2,"Global bootstrap owner for the particle or emitter subsystem rooted at `0x006cea54..0x006cea98`. The helper reloads `emitters.dat` through `0x00474790`, reloads `particles.dat` through `0x00474700`, publishes current mode-`1` ratio labels through `0x00474690`, lazily allocates one pooled slot descriptor root of size `0x1c` at `0x006cea58`, allocates the backing slab `0x88b80` into `0x006cea54`, seeds that slab into the pooled descriptor through `0x0053dcf0(…,0x38,0x2710,1)`, clears the global linked-slot heads `0x006cea74/78/7c` and shared anchor globals `0x006cea68/6c/70/80/84/88`, marks latch `0x006ceb98 = 1`, rebuilds flagged emitter templates through `0x00474c60`, and finally publishes enable state `1` through owner `0x006d4030` via `0x00556500`. This is the clearest current bootstrap owner for the grounded `particles.dat` and `emitters.dat` globals rather than another small table loader.","objdump + local disassembly + literal inspection + caller inspection + pooled-slot correlation + particle-table correlation + emitter-table correlation" +0x00474db0,112,effect_system_teardown_particle_tables_and_pooled_slot_root,bootstrap,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Global teardown companion for the same particle or emitter subsystem rooted at `0x006cea54..0x006cea60`. The helper frees backing slab `0x006cea54`, particle table root `0x006cea5c`, and emitter-definition table root `0x006cea60` through `0x005a1145`; then, when the pooled slot descriptor root `0x006cea58` is live, it resets that descriptor through `0x0053dcb0`, frees it through `0x0053b080`, and clears the global root. Current grounded callers include the emitter data reload family around `0x00474700/0x00474790`, so this is the clearest current owner for subsystem teardown rather than a slot-local release helper.","objdump + local disassembly + caller inspection + pooled-slot correlation + particle-table correlation + emitter-table correlation" +0x00474e20,336,effect_slot_create_or_clone_attached_sprite_emitter_from_definition_and_optional_owner_template,bootstrap,thiscall,inferred,objdump + local disassembly + caller inspection + table correlation,2,"Creates one attached sprite emitter from one emitter-definition row, either by cloning an owner-side template or by constructing a fresh runtime handle. The helper first seeds or allocates the optional `0x206` owner record when the caller did not supply one, strips high flag bits from `CargoMoney_DollarSign`, clears incoming flag bit `0x400` when definition gate `[def+0xb8]` is zero, and then takes one of two branches. When final flags still carry `0x400`, it hashes the definition name at `[def+0x04]` together with owner token `[def+0x84]`, resolves or reuses one owner-side template through `0x00556ce0` on `0x006d4030`, and uses that clone as the live emitter. Otherwise it derives one rounded scale index from `[def+0x88] / [def+0x90]`, allocates a fresh `0x1fd` emitter through `0x0053b070`, constructs it through `0x00556920`, and then materializes the definition fields into that handle through `effect_apply_emitter_definition_to_attached_sprite_handle` `0x004749d0`. On success it publishes the created emitter through `0x0052d950`, stores the owner definition pointer into `[emitter+0x60]`, and when the final flags carry `0x02000000` it forces persistent flag dword `[emitter+0xbc] = 1`. Current grounded callers are the slot builders under `0x004752d0..0x00475e30` plus the owner-stem loop at `0x0045e940`, so this is the safest current owner for attached sprite-emitter creation or clone selection rather than a generic slot helper.","objdump + local disassembly + caller inspection + emitter-table correlation + template-clone correlation + handle-construction correlation" +0x00474f70,112,effect_slot_service_emitters_or_all_globally_linked_slots_with_update_mode_zero,bootstrap,thiscall,inferred,objdump + local disassembly + global-list correlation,2,"Shared update sweep for attached sprite emitters. When the caller supplies one slot container, the helper iterates that slot's live emitter pointer band `[slot+0x0c..]` and dispatches each emitter through `0x00555e50(0)`. When the caller passes null instead, it walks the global linked slot list rooted at `0x006cea74` and runs the same per-emitter `0x00555e50(0)` sweep across every linked slot. This is the clearest current owner for the common emitter service pass rather than just another slot-local iterator.","objdump + local disassembly + global-list correlation + emitter-slot correlation" +0x00474fe0,38,effect_slot_write_emitter_flag_dword_to_all_emitters,bootstrap,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Small per-slot flag writer over the attached-emitter container. The helper iterates every live emitter pointer in `[this+0x0c..]` and writes the caller-supplied dword from `EDX` directly into each emitter's flag field `[emitter+0xbc]`. Current grounded callers are the placed-structure transient rebuild branches `0x0040cf79`, `0x0040f137`, `0x0040f35c`, and the later world-side service path `0x004a87e8`, so this is best read as the shared emitter-flag broadcast helper rather than a fuller update pass.","objdump + local disassembly + caller inspection + emitter-slot correlation + flag-field correlation" +0x00475010,25,effect_slot_cache_shared_anchor_triplet,bootstrap,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Caches the caller-supplied world-anchor triplet into globals `0x006cea68`, `0x006cea6c`, and `0x006cea70`. Current grounded callers are the attached-emitter setup paths `0x0040cf00` and several higher emitter-slot builders starting at `0x004752d0`.","objdump + local disassembly + caller inspection + shared-triplet correlation" +0x00475030,101,effect_slot_apply_cached_shared_anchor_triplet_to_all_or_one_emitters,bootstrap,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Copies the cached triplet globals `0x006cea68/0x006cea6c/0x006cea70` into the per-emitter triplet band at `[emitter+0x1b0..+0x1b8]` for either all emitters in the current slot container or one selected emitter index. When the caller passes `-1` in `EDX`, the helper updates every live emitter pointer in `[this+0x0c..]`; otherwise it updates only the selected slot index. Current grounded callers include the placed-structure transient builder `0x0040cf00`.","objdump + local disassembly + caller inspection + shared-triplet correlation + emitter-slot correlation" +0x00475100,308,effect_slot_release_emitters_unlink_global_list_and_recycle_or_free_slot,bootstrap,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Release-side owner for one attached-emitter slot container. The helper walks any owner-side intrusive list reachable from `[this+0x04]->[+0x79]`, releasing matching attached emitters stored in `[this+0x0c..]` through the `0x00556ef0/0x00556f00/0x00556f20` sweep; when slot flag dword `[this+0x34] == 1` it also unlinks the current slot from the global linked list rooted at `0x006cea74/0x006cea78/0x006cea7c`. Finally it either recycles the slot into the pooled descriptor rooted at `0x006cea58` when the slot address falls inside that pool range or frees it directly through `0x0053b080`. Current grounded callers are the placed-structure and city-entry helper release paths at `0x0045b160`, `0x004743d0`, and `0x00474400`.","objdump + local disassembly + caller inspection + emitter-slot correlation + pooled-slot correlation" +0x00475240,108,effect_slot_set_emitter_enabled_state_for_all_or_one,bootstrap,thiscall,inferred,objdump + local disassembly,2,"Toggles the per-emitter enable byte at `[emitter+0x1d8]` for either all emitters in the current slot container or one selected emitter index. When caller mode `EDX == 1`, the helper writes byte `0` to the selected emitters; otherwise it writes byte `1`. Passing index `-1` applies the update to every live emitter pointer in `[this+0x0c..]`. Current evidence is strongest for an enabled-state setter because the paired query `0x004752b0` reports true only when this byte stays zero.","objdump + local disassembly + emitter-slot correlation + enable-flag correlation" +0x004752b0,31,effect_slot_query_emitter_is_enabled_by_index,bootstrap,thiscall,inferred,objdump + local disassembly,1,"Returns `1` when the selected emitter pointer in `[this+0x0c + index*4]` exists and its enable byte `[emitter+0x1d8]` is zero; otherwise returns `0`. This is the paired boolean query beside `effect_slot_set_emitter_enabled_state_for_all_or_one` `0x00475240`.","objdump + local disassembly + emitter-slot correlation + enable-flag correlation" +0x004752d0,340,effect_slot_construct_broken_down_steam_flame_and_crash_smoke_bundle,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a three-emitter slot bundle beneath the same pooled effect-slot family rooted at `0x006cea58`. After acquiring one slot container, the helper resolves emitter definitions `BrokenDown_Steam`, `FlamespoutB`, and `Crash_SmokeA` from the global emitter table `0x006cea60` through `effect_emitter_table_find_entry_by_hashed_name` `0x00474820`, creates three attached emitters through `effect_slot_create_attached_sprite_emitter` `0x00474e20`, stores those emitters into `[slot+0x0c/+0x10/+0x14]`, and sets slot count `[slot+0x08] = 3`. This is the clearest current owner for the named broken-down fire/steam/crash-smoke bundle rather than a generic slot allocator.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475420,302,effect_slot_construct_tier_selected_volcano_lava_and_black_smoke_bundle,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a two-emitter volcano bundle in the pooled effect-slot family rooted at `0x006cea58`. The helper first selects one literal pair from `Volcano_BlackSmoke1..4` plus `Volcano_Lava1..4` or the untiered `Volcano_BlackSmoke` plus `Volcano_Lava`, based on the caller float tier `0.5f`, `0.75f`, `1.0f`, `1.5f`, or `2.0f`; it then resolves those emitter definitions through `effect_emitter_table_find_entry_by_hashed_name` `0x00474820`, creates the black-smoke emitter first with flags `arg3 | 0x10000`, copies the selected black-smoke descriptor field `[def+0xc8]` into the created emitter at `[emitter+0x94]`, creates the paired lava emitter second, stores the two emitters into `[slot+0x0c/+0x10]`, stamps one fixed dword `0x371c0732` into the second emitter at `[emitter+0x1e9]`, and sets slot count `[slot+0x08] = 2`. This is the clearest current owner for the tier-selected volcano lava or smoke pair rather than a generic two-emitter allocator.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475550,244,effect_slot_construct_broken_down_steam_and_smoke_bundle,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a two-emitter slot bundle in the same pooled effect-slot family. After acquiring one slot container, the helper resolves `BrokenDown_Steam` and `BrokenDown_Smoke` from the global emitter table `0x006cea60` through `0x00474820`, creates the two attached emitters through `effect_slot_create_attached_sprite_emitter` `0x00474e20`, stores them into `[slot+0x0c/+0x10]`, and sets slot count `[slot+0x08] = 2`. This is the current grounded two-emitter broken-down steam/smoke bundle owner.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475650,339,effect_slot_construct_service_tower_water_triple_bundle,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a three-emitter service-tower water bundle in the same pooled effect-slot family. After acquiring one slot container, the helper resolves the literal pairs `ServiceTower_Water2` plus `ServiceTower_Anim2#water.3dp`, `ServiceTower_Water` plus `ServiceTower_Anim3#water.3dp`, and `ServiceTower_Water3` plus `ServiceTower_Anim4#water.3dp` from the global emitter table `0x006cea60`; it creates three attached emitters through `effect_slot_create_attached_sprite_emitter` `0x00474e20`, threads the default attachment token from the first emitter into the second and third builds when the caller did not supply one, stores the resulting emitters into `[slot+0x0c/+0x10/+0x14]`, and sets slot count `[slot+0x08] = 3`. This is the clearest current owner for the named three-stage service-tower water bundle rather than another anonymous effect-slot builder.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x004757b0,339,effect_slot_construct_fireworks_rocket_triple_bundle,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a three-emitter fireworks bundle in the pooled effect-slot family. After acquiring one slot container, the helper resolves `Rocket_Flame` plus `Fireworks_Anim2#water.3dp`, `Rocket_Smoke` plus `Fireworks_Anim3#water.3dp`, and `Rocket_Sparkle` plus `Fireworks_Anim4#water.3dp` from the global emitter table `0x006cea60`; it creates the three attached emitters through `effect_slot_create_attached_sprite_emitter` `0x00474e20`, threads the first emitter's default attachment token into the later two builds when the caller did not supply one, stores the resulting emitters into `[slot+0x0c/+0x10/+0x14]`, and sets slot count `[slot+0x08] = 3`. This is the clearest current owner for the named fireworks rocket bundle rather than a generic multi-emitter constructor.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475910,218,effect_slot_construct_random_fireworks_single_emitter,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a one-emitter fireworks slot bundle with one randomized named variant. The helper advances the shared PRNG state at `0x00624324`, rejects the immediately previous residue stored at `0x005f2c2c`, selects one of the three emitter names `Fireworks1`, `Fireworks2`, or `Fireworks3`, resolves that emitter from the global emitter table `0x006cea60`, creates one attached emitter through `effect_slot_create_attached_sprite_emitter` `0x00474e20` using literal `Fireworks_Anim5#water.3dp`, stores the emitter into `[slot+0x0c]`, writes fixed dword `0x3c` into `[emitter+0xbc]`, and sets slot count `[slot+0x08] = 1`. This is the clean local owner for the randomized single-firework effect bundle.","objdump + local disassembly + literal inspection + PRNG-state correlation + emitter-table correlation + named-bundle correlation" +0x004759f0,154,effect_slot_construct_cargo_money_dollar_sign_emitter,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a one-emitter slot bundle around literal `CargoMoney_DollarSign`. After acquiring one slot container, the helper resolves that named emitter from the global emitter table `0x006cea60`, creates one attached emitter through `effect_slot_create_attached_sprite_emitter` `0x00474e20` with flags `arg2 | 0xc000`, stores the emitter into `[slot+0x0c]`, and sets slot count `[slot+0x08] = 1`. This is the clean local owner for the cargo-money dollar-sign effect bundle.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475a90,154,effect_slot_construct_select_object_emitter,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a one-emitter slot bundle around literal `SelectObject`. After acquiring one slot container, the helper resolves that named emitter from the global emitter table `0x006cea60`, creates one attached emitter through `effect_slot_create_attached_sprite_emitter` `0x00474e20`, stores it into `[slot+0x0c]`, and sets slot count `[slot+0x08] = 1`. This is the current grounded owner for the standalone select-object effect bundle.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475b30,154,effect_slot_construct_spend_money_dollar_sign_emitter,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a one-emitter slot bundle around literal `SpendMoney_DollarSign`. After acquiring one slot container, the helper resolves that named emitter from the global emitter table `0x006cea60`, creates one attached emitter through `effect_slot_create_attached_sprite_emitter` `0x00474e20` with flags `arg2 | 0xc000`, stores the emitter into `[slot+0x0c]`, and sets slot count `[slot+0x08] = 1`. This is the clean local owner for the spend-money dollar-sign effect bundle.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475bd0,480,effect_slot_construct_construct_pos_left_right_back_forward_bundle,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a five-emitter slot bundle from the directional construction literals `Construct_Pos`, `Construct_Left`, `Construct_Right`, `Construct_Back`, and `Construct_Forward`. After acquiring one slot container, the helper resolves each named emitter from the global emitter table `0x006cea60`, creates the five attached emitters through `effect_slot_create_attached_sprite_emitter` `0x00474e20` with flags `arg2 | 0xc000`, threads the first emitter's default attachment token into the later four builds when the caller did not supply one, stores the resulting emitters into `[slot+0x0c/+0x10/+0x14/+0x18/+0x1c]`, and sets slot count `[slot+0x08] = 5`. This is the clearest current owner for the directional construction effect bundle rather than a generic multi-emitter constructor.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475dc0,106,effect_slot_construct_mist_or_mist_small_emitter,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a one-emitter slot bundle around either `Mist` or `MistSmall`. After acquiring one slot container, the helper chooses `Mist` when the caller float argument differs from `1.0f` and chooses `MistSmall` when it equals `1.0f`, resolves that named emitter from the global emitter table `0x006cea60`, creates one attached emitter through `effect_slot_create_attached_sprite_emitter` `0x00474e20`, stores it into `[slot+0x0c]`, and sets slot count `[slot+0x08] = 1`. This is the clean local owner for the mist-effect single-emitter bundle.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475e30,152,effect_slot_construct_vent_emitter,bootstrap,cdecl,inferred,objdump + local disassembly + literal inspection,2,"Constructs a one-emitter slot bundle around literal `Vent`. After acquiring one slot container, the helper resolves that named emitter from the global emitter table `0x006cea60`, creates one attached emitter through `effect_slot_create_attached_sprite_emitter` `0x00474e20`, stores it into `[slot+0x0c]`, and sets slot count `[slot+0x08] = 1`. This is the current grounded owner for the standalone vent effect bundle.","objdump + local disassembly + literal inspection + emitter-table correlation + named-bundle correlation" +0x00475ed0,315,effect_slot_construct_named_bundle_by_selector_and_optionally_link_globally,bootstrap,thiscall,inferred,objdump + local disassembly + caller inspection + literal inspection,2,"Selector-dispatch owner above the current named effect-slot builders. The helper treats `EDX-1` as a small selector spanning the broken-down, volcano, service-tower, money-sign, construction, fireworks, select-object, mist, and vent bundle constructors rooted at `0x004752d0`, `0x00475420`, `0x00475550`, `0x00475650`, `0x004757b0`, `0x00475910`, `0x004759f0`, `0x00475a90`, `0x00475b30`, `0x00475bd0`, `0x00475dc0`, and `0x00475e30`. After building the selected slot bundle it mirrors the first emitter's attachment token into `[slot+0x04]`, stores caller mode into `[slot+0x34]`, and when that mode equals `1` pushes the finished slot onto the global linked active list rooted at `0x006cea74/0x006cea78/0x006cea7c`. This is the clearest current local owner for selector-driven named effect-slot construction rather than another low-level emitter helper.","objdump + local disassembly + caller inspection + literal inspection + named-bundle correlation + global-linked-list correlation" +0x00476050,31,profile_entry_add_signed_integer_delta_into_qword_field_0x154,shell,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Tiny signed-accumulate helper over one profile-style object field. The helper converts the caller-supplied integer delta into floating-point and adds it into qword field `[this+0x154]`, then returns. Current grounded callers are the preset multiplayer normalization passes `0x00470ed0` and `0x00470fa0` over the guarded named-profile table `0x006ceb9c`, and the new-company commit path `0x0047d120`, so the safest current read is a signed additive update for field `0x154` rather than a more semantic metric name.","objdump + local disassembly + caller inspection + qword-field correlation + named-profile correlation" +0x004760a0,35,profile_entry_resolve_company_dword_slot_0x2ab_by_index_and_optionally_refresh_generation,shell,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Small raw field helper over one named-profile record. The function compares the caller-supplied generation or stamp dword against `[this+0xc43]`; when they already match or the caller stamp is zero it returns `0`, otherwise it updates `[this+0xc43]` and returns the address of the indexed dword slot `[this + company_index*4 + 0x2ab]`. Current evidence only grounds the raw field relationship and the optional generation-stamp write, not the higher semantic meaning of either field.","objdump + local disassembly + caller correlation + raw-field correlation" +0x004760c6,29,profile_entry_store_company_dword_slot_0x2ab_by_index_and_optionally_refresh_generation,shell,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Companion raw setter for the same named-profile record family. The helper stores the caller dword into indexed slot `[this + company_index*4 + 0x2ab]` and, when the caller-supplied stamp in `EDX` is nonzero, also writes that stamp into `[this+0xc43]`. Current evidence grounds it only as the paired store-side helper beside `0x004760a0`.","objdump + local disassembly + caller correlation + raw-field correlation" +0x004760f0,77,profile_static_persona_table_allocate_wrapped_unused_row_flag,map,cdecl,inferred,objdump + local disassembly + table correlation + caller inspection,2,"Allocates one wrapped unused row out of the static persona table rooted at `0x005f2d28`. Starting from one bounded pseudo-random seed from `0x00518be0(0,0x28)`, the helper walks the row flag byte at stride `0x27` until it finds a zero entry, wrapping modulo `0x29` across the table. It then marks that row flag byte to `1` and returns the chosen row index. Current grounded caller is the named-profile constructor `0x00476140`, so this is the safest current read for the static persona-row allocator rather than a broader profile generator.","objdump + local disassembly + table correlation + caller inspection + static-persona correlation" +0x00476140,471,named_profile_record_construct_with_default_fields_strings_and_static_persona_row,shell,thiscall,inferred,objdump + local disassembly + caller correlation + table correlation,3,"Broad constructor for one named-profile record in the collection rooted at `0x006ceb9c`. The helper seeds several fixed state bytes under `[this+0x291..+0x295]`, stores the caller profile id at `[this+0x00]`, marks the record live through `[this+0x04] = 1`, zeros several local counters and state dwords including `[this+0x154]`, `[this+0x296]`, `[this+0x29a]`, `[this+0x2a7]`, and `[this+0x29e]`, seeds `[this+0x158]` to `7.763f`, zeroes the large record band `[this+0x1e9..]`, mirrors the special `id == 1` case into guard dword `[this+0x1e1]`, allocates one static persona-row flag through `0x004760f0`, copies the caller byte into `[this+0x15c]`, formats a localized fallback name through `0x005193f0(0x0b87)` when the caller name string is empty or otherwise copies that name into `[this+0x08]`, copies the caller biography string into `[this+0x27]`, seeds one random multiple-of-`0x5a0` scalar into `[this+0x1e5]`, and finally clears the per-company dword band `[this+0x2ab..]` plus the trailing state strip `[this+0xc66..]`. Current grounded callers are the chairman-profile seeding and materialization passes `0x004377a0` and `0x00437220`, so this is the clearest current owner for named-profile record construction rather than a generic string-copy helper.","objdump + local disassembly + caller correlation + table correlation + chairman-profile seeding correlation" +0x00476320,131,profile_entry_sum_per_company_holding_value_using_selected_company_scalar_source,simulation,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Accumulates one direct weighted sum across the per-company dword band `[this+0x15d..+0x1d9]`. For each positive entry, the helper resolves the matching live company record from `0x0062be10`; when the caller stack flag is nonzero it queries the cached company scalar through `0x00423eb0`, otherwise it queries the broader company scalar through `0x00424fd0(0,0)`. It then multiplies that company scalar by the corresponding profile holding dword and adds the result into one running floating accumulator. Current grounded caller is the `LoadScreen.win` player-list renderer `0x004e6ef0`, where this is one of the chairman-side ranking metrics.","objdump + local disassembly + caller correlation + per-company-holding correlation + player-list metric correlation" +0x004763b0,166,profile_entry_sum_threshold_adjusted_per_company_holding_value_using_selected_company_scalar_source,simulation,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Companion weighted accumulator over the same per-company holding band `[this+0x15d..+0x1d9]`. For each positive entry, the helper resolves the matching live company record from `0x0062be10`, queries either `0x00423eb0` or `0x00424fd0(0,0)` by the same caller flag split as `0x00476320`, and then folds the resulting per-company contribution through a thresholded transform using constants `0x005c8608` and `0x005c85d0` before adding it into one running floating accumulator. Current grounded caller is again the `LoadScreen.win` player-list renderer `0x004e6ef0`, so the safest current read is a threshold-adjusted holding-value accumulator rather than a fully named finance metric.","objdump + local disassembly + caller correlation + per-company-holding correlation + player-list metric correlation" +0x00476460,243,profile_entry_sell_company_holding_units_and_add_cash_metric,map,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Sell-side mutation over one named-profile record's per-company holding slot. The helper resolves the target company from `0x0062be10`, clamps the caller-requested unit count against current slot `[this + company_id*4 + 0x15d]` and, on the negative-holding branch, against company-side limit query `0x00429910(0)`. It then queries the company scalar through `0x00424fd0(-units,1)`, rounds the resulting proceeds twice through `0x005a10d0`, subtracts the sold unit count from `[this + company_id*4 + 0x15d]`, adds the scaled proceeds into qword cash-like field `[this+0x154]`, and finally refreshes scenario-side chairman state through `0x00433850` and `0x0050a670`. Current grounded callers are the two shell-side trade branches around `0x0050bf82` and `0x0050c24e`, plus the earlier policy branch at `0x0040722f`, so this is the clearest current sell or liquidation helper over the chairman holding band rather than another raw slot mutator.","objdump + local disassembly + caller inspection + holding-slot correlation + cash-metric correlation + trade-branch correlation" +0x00476560,539,profile_entry_apply_issue39_tiered_cash_metric_adjustment,simulation,thiscall,inferred,objdump + local disassembly + caller inspection + issue-39 correlation,3,"Applies one issue-39-driven periodic adjustment to qword cash-like field `[this+0x154]`. When scenario gate `[0x006cec78+0x46c38]` is clear, the helper first reads one scenario baseline through `0x00433740`, adds the raw issue-39 total through `scenario_state_sum_issue_opinion_terms_raw` `0x00436710(issue=0x39, company=0, profile=this[0], territory=0)`, and then clamps the resulting factor against several current-cash thresholds using constants `0x005c8608`, `0x005ce820`, `0x005ce818`, `0x005ce810`, and `0x005c8810`. The tail multiplies that factor by `[this+0x154]`, divides by `0x005c8978`, rounds through `0x005a10d0`, and adds the resulting integer delta back into `[this+0x154]`. Current grounded caller is the collection sweep at `0x0040a760`, which applies this adjustment to every active chairman profile before firing trigger kind `2` through `0x00432f40`, so this is the safest current read for an issue-39-tiered periodic cash-metric adjustment rather than a generic profile scaler.","objdump + local disassembly + caller inspection + issue-39 correlation + cash-metric correlation + collection-sweep correlation" +0x00476780,21,profile_entry_query_direct_holding_total_plus_cash_metric,simulation,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Tiny wrapper that queries the direct per-company holding total through `0x00476320` and then adds qword cash-like field `[this+0x154]` before returning the resulting floating total. Current grounded callers are the player-list renderer `0x004e6ef0`, the ratio-style helper at `0x00406da9`, and the later support branch at `0x0050acc7`, so this is the clean direct-total-plus-cash sibling beside the threshold-adjusted path at `0x00476c20`.","objdump + local disassembly + caller inspection + cash-metric correlation + holdings-total correlation" +0x00476950,224,profile_entry_query_start_new_company_funding_scale_factor,simulation,thiscall,inferred,objdump + local disassembly + caller correlation + field correlation,2,"Queries one bounded funding-scale factor from the current chairman profile for the `Start New Company` dialog family. The helper defaults to a constant factor when profile gate `[this+0x1e1]` is clear; otherwise it optionally adjusts one local score from owner-company field `[company+0x43]` and selected-chairman lane `[0x006cec78+0x0d]`, folds that delta into profile dword `[this+0x28d]`, converts the result through the local float constants at `0x005c85d8/0x005c85f0`, and clamps the final factor into a bounded positive range before returning it. Current grounded caller is the funding-band helper `0x0047bea0`, so this is the clean profile-side scale-factor source for the start-company funding UI rather than a general wealth metric.","objdump + local disassembly + caller correlation + field correlation + start-company funding correlation" +0x004767a0,96,profile_entry_query_cash_or_direct_holding_metric_by_selector,simulation,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Small selector wrapper over the same chairman profile metric strip. Selector `0` returns qword cash-like field `[this+0x154]` directly, selector `1` returns the direct holding-value total from `0x00476320(0)`, selector `2` returns their sum by recursively combining selectors `0` and `1`, and all other selectors return the constant floor at `0x005c8608`. Current grounded callers are the local cache refresher `0x00476810`, the player-list renderer `0x004e5577/0x004e561f`, and the policy-side branch `0x0042ebb5/0x0042ebd4`, so this is the safest current read for the direct cash-versus-holdings metric selector rather than a broader ranking owner.","objdump + local disassembly + caller inspection + cash-metric correlation + selector-branch correlation" +0x00476810,170,profile_entry_refresh_cached_cash_and_direct_holding_metric_pair,simulation,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Refreshes two cached qword metric lanes under one named-profile record. After clearing the local cache band `[this+0x1e9..+0x278]`, the helper stores selector `0` and selector `1` outputs from `profile_entry_query_cash_or_direct_holding_metric_by_selector` `0x004767a0` into the two qword slots rooted at `[this+0x1e9]` and `[this+0x1f1]`. Current grounded caller is the active-profile sweep at `0x0040a3fe`, so this is the strongest current read for the cash-plus-direct-holdings cache refresh pass rather than a generic record reset.","objdump + local disassembly + caller inspection + cache-band correlation + selector-branch correlation" +0x00476a60,80,scenario_state_query_named_profile_trade_or_replace_gate_enabled,map,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Small scenario-side gate used by the named-profile transaction and replacement family. The helper returns true when any of three scenario conditions is active: toggle `[0x006cec78+0x4acb]` with `0x004337a0` returning nonzero, toggle `[0x006cec78+0x4ad7]` with the selected chairman profile record from `0x004348c0` having `[profile+0x2a7] >= 1`, or toggle `[0x006cec78+0x4ad3]`. Otherwise it returns false. Current grounded callers are the broader profile-side owner `0x00476d10` and two shell renderers `0x004e5ab6` and `0x004e6911`, so the safest current read is a named-profile trade-or-replace gate rather than a stronger user-facing policy name.","objdump + local disassembly + caller inspection + scenario-toggle correlation + selected-profile correlation" +0x00476ab0,122,profile_static_persona_row_query_string_ptr_0x40_by_profile_byte_0x15c_or_fallback,shell,thiscall,inferred,objdump + local disassembly + caller inspection + table correlation,2,"Resolves one pointer into the static persona table rooted at `[0x006d4020+0x429b4]` by matching the profile stem buffer `[this+0xc47]` against each row and then returns the matching row's `+0x40` field; on lookup failure it falls back to `[this+0x40]`. Current grounded caller is the load-screen renderer branch at `0x004e207e`, where the returned string is copied into a local buffer before the surrounding shell payload build continues. The safest current read is therefore a structural `+0x40` persona-row string-pointer query rather than a more semantic biography or title name.","objdump + local disassembly + caller inspection + table correlation + string-buffer correlation" +0x00476b30,122,profile_static_persona_row_query_asset_stem_ptr_by_profile_byte_0x15c_or_fallback,shell,thiscall,inferred,objdump + local disassembly + caller inspection + table correlation,2,"Resolves one pointer into the static persona table rooted at `[0x006d4020+0x429b4]` by matching the profile stem buffer `[this+0xc47]` against each row and then returns the matching row's `+0x20` field; on lookup failure it falls back to `[this+0x20]`. Current grounded callers are the CompanyDetail chairman portrait band at `0x004c2ec9/0x004c2ef0` and the load-screen side renderers, where the returned string is passed onward as a banked asset key through `0x0053c930`, so this is the safest current read for the persona-row asset-stem pointer query rather than a generic string helper.","objdump + local disassembly + caller inspection + table correlation + asset-key correlation" +0x00476bb0,112,profile_static_persona_table_query_row_index_by_profile_byte_0x15c_and_stem,shell,thiscall,inferred,objdump + local disassembly + caller inspection + table correlation,2,"Resolves the zero-based row index inside the static persona table rooted at `[0x006d4020+0x429b4]` whose row key matches profile stem buffer `[this+0xc47]`. The helper returns `-1` when no row matches. Current grounded callers are the load-screen player-detail and shell status renderers around `0x004e5332`, `0x004e72d8`, `0x004e736d`, `0x0050a932`, and `0x0050a994`, where the resulting row index is folded into the visible persona byte at `[profile+0x15c]`. This is therefore the current row-index query sibling beside the pointer-returning helpers at `0x00476ab0` and `0x00476b30`.","objdump + local disassembly + caller inspection + table correlation + persona-byte correlation" +0x00476c20,21,profile_entry_query_threshold_adjusted_holding_total_plus_cash_metric,simulation,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Tiny wrapper that queries the threshold-adjusted holding-value total through `0x004763b0` and then adds qword cash-like field `[this+0x154]` before returning the resulting floating total. Current grounded callers are the player-list renderer `0x004e7133/0x004e74cc`, the overview-side branch `0x0047c085`, and the later support path `0x0050acd0`, so this is the clean threshold-adjusted-total-plus-cash sibling beside `0x00476780`.","objdump + local disassembly + caller inspection + threshold-adjusted correlation + cash-metric correlation" +0x00476c40,208,profile_entry_query_can_reduce_company_holding_slot_by_units_with_optional_threshold_fallback,simulation,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Sell-side or reduction-side feasibility gate over one chairman profile and company slot. The helper resolves the target company from `0x0062be10`, defaults the requested unit count through `0x00476e50(company_id,0)` when the caller passes zero, and succeeds immediately when current slot `[this + company_id*4 + 0x15d]` already covers that reduction. When the direct slot check fails, the helper only continues on the caller's fallback branch; there it rejects reductions against the profile's own company id `[company+0x3b] == [this+0x00]`, requires the requested units to remain below company-side limit query `0x00429910(arg4)`, and then compares `company_scalar(0,0) * units` against the threshold-adjusted-total-plus-cash lane from `0x00476c20(1)`. Current grounded callers are the trade-block helper `0x00476e50`, the ratio or policy branch `0x00406e13`, and several shell-side sell branches around `0x0050b681`, `0x0050b747`, and `0x0050beaf`, so this is the safest current read for the reduction-feasibility sibling beside the buy gate `0x00476ff0`.","objdump + local disassembly + caller inspection + holding-slot correlation + threshold-fallback correlation + trade-branch correlation" +0x00476d10,318,profile_entry_query_can_start_new_company_or_publish_failure_notice,shell,thiscall,inferred,objdump + local disassembly + caller inspection + RT3.lng correlation,3,"Start-new-company eligibility gate above the shell dialog paths. The helper first checks scenario gate `0x00476a60`; when that gate is active it formats localized id `0x0b88` `2952` `You're not able to start a new company.` and routes the result through `0x004c98a0` as a notice, then returns failure. Otherwise it queries the caller profile's threshold-adjusted-total-plus-cash value through `0x004763b0(1) + [this+0x154]` and succeeds immediately when that result reaches threshold `0x005c8830`. When the threshold fails, it resolves the currently selected chairman profile through `0x004348c0`, formats localized id `0x010f` `271` `You don't have enough money to start a new company!...` with the required threshold and the selected chairman's current purchasing-power figure, publishes that notice through `0x004c98a0`, and returns failure. Current grounded callers are the company-list and load-screen branches at `0x004c7134` and `0x004de3f0`, so this is the clearest current owner for the start-new-company eligibility check plus failure-notice path rather than a generic purchasing-power helper.","objdump + local disassembly + caller inspection + RT3.lng correlation + purchasing-power correlation + start-company dialog correlation" +0x00476e50,407,profile_entry_compute_rounded_company_trade_block_size_by_mode,simulation,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Computes one rounded trade-block size for a caller-selected company slot. When profile guard `[this+0x1e1]` is clear the helper returns the floor block `1000`. Otherwise it derives a tentative block size from the current holding slot `[this + company_id*4 + 0x15d]`, rounds that size to the nearest `1000` through the shared `0x10624dd3` divide sequence, and then constrains it through either the buy-feasibility helper `0x00476ff0` or the sell-feasibility helper `0x00476c40` depending on the caller mode flag. On the positive path it also clamps against company-side availability query `0x004261b0`, then rounds the final result back to a `1000`-sized block with midpoint bias `+500`. Current grounded callers are the buy-feasibility and buy-commit path at `0x00476ff0/0x00477110` and the shell-side commit branches at `0x0050c16d/0x0050c20d`, so this is the safest current read for the rounded trade-block-size helper rather than a general metric scaler.","objdump + local disassembly + caller inspection + holding-slot correlation + trade-block correlation" +0x00476ff0,275,profile_entry_query_can_buy_company_holding_units_with_optional_cash_fallback,simulation,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Buy-side feasibility gate over one chairman profile and company slot. The helper resolves the target company from `0x0062be10`, defaults the requested unit count through `0x00476e50(company_id,1)` when the caller passes zero, clamps that request to at least `1`, and rejects it when company-side availability query `0x004261b0` is smaller. It then compares the cash-like field `[this+0x154]` against the current purchase cost derived from `0x00424fd0(0,0)` times the requested units. When that cash test fails and the caller's fallback flag is nonzero, it retries the same comparison after adding the direct holdings total from `0x00476320(1)` to `[this+0x154]`. Current grounded callers are the buy commit path `0x00477110`, the ratio branch `0x00406df1`, and several shell-side trade branches around `0x0050b3ba`, `0x0050b4b4`, and `0x0050bcf0`, so this is the clearest current owner for the company-holding buy-affordability gate rather than a generic transaction predicate.","objdump + local disassembly + caller inspection + trade-affordability correlation + cash-metric correlation + holding-total fallback correlation" +0x00477110,202,profile_entry_buy_company_holding_units_and_subtract_cash_metric,map,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Buy-side mutation over one named-profile record's per-company holding slot. Unless the caller explicitly bypasses the precheck, the helper first requires `profile_entry_query_can_buy_company_holding_units_with_optional_cash_fallback` `0x00476ff0` to succeed for the requested company and unit count. It then resolves the target company from `0x0062be10`, applies the company-side update path through `0x00424fd0(1, units)` and `0x00424fd0(0,0)`, adds the requested units into holding slot `[this + company_id*4 + 0x15d]`, converts the resulting purchase cost through `0x005a10d0` and constant `0x005c8930`, subtracts that scaled cost from qword cash-like field `[this+0x154]`, and finally refreshes scenario-side chairman state through `0x00433850` and `0x0050a670`. Current grounded callers are the shell-side buy branches around `0x0050c1ae` and the broader transaction family beside `0x00476460`, so this is the clearest current buy companion to the sell-side helper.","objdump + local disassembly + caller inspection + holding-slot correlation + cash-metric correlation + trade-branch correlation" 0x00477820,59,profile_collection_count_active_chairman_records,map,thiscall,inferred,objdump + callsite inspection,4,"Counts active chairman-profile records in the global persona collection at `0x006ceb9c`. The helper iterates the collection and increments the result only for entries whose live flag at `[profile+0x4]` is nonzero. Current grounded caller is `world_conditionally_seed_named_starting_railroad_companies` at `0x0047d440`, where count `>= 2` gates whether the second seeded railroad can be bound to another active chairman profile.","objdump + callsite inspection + caller correlation" 0x00477860,90,profile_collection_get_nth_active_chairman_record,map,thiscall,inferred,objdump + callsite inspection,4,"Returns one zero-based active chairman-profile record from the global persona collection at `0x006ceb9c`. The helper skips any entry whose live flag `[profile+0x4]` is zero and decrements the requested ordinal across the remaining active entries until it resolves one record or returns null. Current grounded caller is `world_conditionally_seed_named_starting_railroad_companies` at `0x0047d440`, which requests ordinal `1` to bind the second seeded railroad to the second active chairman profile when present.","objdump + callsite inspection + caller correlation" -0x00478200,291,shell_queue_single_world_anchor_overlay,shell,cdecl,inferred,ghidra-headless,3,Builds one world-anchor overlay packet for the current owner object. It samples the owner transform through 0x00455800 and 0x00455810 derives projected half-height and half-width through 0x00477a10 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and then enqueues the finished marker through shell_queue_world_anchor_marker.,ghidra + rizin + llvm-objdump -0x00478330,2432,shell_queue_world_anchor_overlay_list,shell,cdecl,inferred,ghidra-headless,3,Builds and queues a repeated world-anchor overlay list for one owner-managed collection. The routine iterates several owner sublists and state branches repeatedly derives projected extents through 0x00477a10 0x004779c0 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and emits one shell_queue_world_anchor_marker packet per accepted overlay entry.,ghidra + rizin + llvm-objdump +0x004778c0,84,profile_collection_get_nth_active_chairman_record_id,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Returns the live collection id of the zero-based active chairman-profile entry selected by the caller ordinal. The helper walks the global persona collection at `0x006ceb9c`, skips any entry whose live flag `[profile+0x4]` is zero, decrements the requested ordinal across the remaining active entries, and returns the matched live record id through `indexed_collection_get_nth_live_entry_id` `0x00518380`; on failure it returns `0`. Current grounded caller is the `LoadScreen.win` player-list renderer `0x004e6ef0`.","objdump + local disassembly + caller correlation + active-chairman correlation" +0x00477920,91,profile_collection_count_active_chairmen_before_record_id,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Counts how many active chairman-profile records appear before one caller-supplied live record id in the global persona collection at `0x006ceb9c`. The helper walks the live collection in order, stops when the current live id equals the target id, increments the running count only for entries whose live flag `[profile+0x4]` is nonzero, and returns that active-prefix count; missing targets return `0`. Current grounded caller is the `LoadScreen.win` player-list renderer `0x004e6ef0`, where it provides the active-rank position for one selected profile id.","objdump + local disassembly + caller correlation + active-chairman correlation" +0x00477a70,94,shell_overlay_state_measure_scaled_max_world_span_with_min_floor,shell,thiscall,inferred,objdump + local disassembly + field correlation,2,"Small scalar helper over the local shell overlay-state strip. The function compares the current world-cell span widths `[this+0xbb]-[this+0xb3]` and `[this+0xbf]-[this+0xb7]`, clamps the larger span upward to minimum floor `[this+0x11f]`, scales that result by factor `[this+0xdb]`, rounds through `0x005a10d0`, and returns the final floating-point span. Current grounded caller is the nearby clamp-and-refresh owner `0x00479510`, so this is the safest current read for the overlay state's scaled max-span query rather than a generic arithmetic helper.","objdump + local disassembly + field correlation + caller correlation" +0x00477ad0,16,shell_overlay_try_get_primary_active_mode_collection,shell,thiscall,inferred,objdump + local disassembly + flag correlation,1,"Tiny mode-gated accessor over shell flag band `[this+0x33]`. When bit `0x00010000` is set it tail-jumps into `0x005130f0` and returns that active-mode collection root; otherwise it returns `0`. Current grounded caller is the broader overlay-list family around `0x00478330`.","objdump + local disassembly + flag correlation + caller correlation" +0x00477af0,272,shell_overlay_state_reset_default_world_bounds_and_normalized_rect,shell,thiscall,inferred,objdump + local disassembly + field correlation,2,"Constructor-style reset for the local shell overlay-state strip used by the world-anchor overlay builders. The helper seeds type word `[this+0x06] = 0x1000`, clears several cached ids and bounds lanes `[this+0xa3..+0xb7]` and `[this+0x10f..+0x11b]`, clamps minimum span floor `[this+0x11f]` against current world dims `0x0062c120+0x2155/+0x2159` with ceiling `0xa0`, seeds default cell bounds `[this+0xbb/+0xbf/+0xcb/+0xcf] = 10`, seeds scalar bands `[this+0xdb/+0xd3/+0xd7/+0xf3/+0x103/+0x10b] = 1.0`, and seeds the paired integer lanes `[this+0xdf/+0xe3/+0xe7/+0xeb] = 5`. Current grounded callers sit in the adjacent overlay owner family, so this is the safest current read for the overlay-state default reset rather than a generic shell constructor.","objdump + local disassembly + field correlation + world-dimension correlation" +0x00477c10,353,shell_overlay_map_screen_point_to_world_cell_pair_under_current_bounds,shell,thiscall,inferred,objdump + local disassembly + caller correlation + field correlation,2,"Maps one screen-space point into a world-cell pair under the current shell overlay-state bounds. When flag band `[this+0x33]` carries `0x02030000`, the helper uses the current bound rectangle `[this+0xc3..+0xcf]`, world-anchor bias `[this+0x86]+0x05/+0x09`, local offsets `[this+0x0b/+0x0f]`, and scale lanes `[this+0x13/+0x17]` to convert the caller point into two output floats. Otherwise it falls back to live world dims `0x0062c120+0x2155/+0x2159`, compensates for aspect mismatch, and derives the same two outputs from the broader full-world view. Current grounded caller is the drag-side owner `0x00478cb0`, so this is the safest current read for the overlay screen-point mapper rather than a generic projection helper.","objdump + local disassembly + caller correlation + field correlation + world-dimension correlation" +0x00478200,291,shell_queue_single_city_database_owner_world_anchor_overlay,shell,cdecl,inferred,objdump + local disassembly + caller-side field correlation,2,"Builds and queues one world-anchor marker for the city-database-style owner referenced by id `[this+0x11b]` in collection `0x0062bae0`. The helper first validates that owner id through `0x00517d40`, resolves the live owner through `0x00518140`, samples its normalized XY through `0x00455800/0x00455810`, derives one localized overlay label through `0x0053de00([this+0xaf],2)`, measures projected half-height through `0x00477a10` using caller bounds `[this+0xc3/+0xcb]`, local height bias `[this+0x0b]`, scale `[this+0x13]`, and owner-side vertical bias `[this+0x86]+0x05`, and finally queues the finished marker through `0x005521a0/0x00552160/0x00552560`. This is the strongest current read for the single-owner city-database overlay builder rather than a generic object marker wrapper.","objdump + local disassembly + caller-side field correlation + city-database collection correlation + world-anchor marker correlation" +0x00478330,2432,shell_queue_world_anchor_overlay_markers_for_active_mode_collections_and_optional_region_focus,shell,cdecl,inferred,objdump + local disassembly + caller-side field correlation + collection correlation,2,"Broad shell-side overlay marker owner above `shell_queue_single_city_database_owner_world_anchor_overlay` `0x00478200`. The helper first chooses one active-mode source collection through flags `[this+0x33] & 0x00010000/0x00020000` and derives the current world-space view box from `[this+0xc3/+0xc7/+0xcb/+0xcf]` plus live world dims `[0x0062c120+0x2155/+0x2159]`. It then runs six category passes `0..5`: one pass walks the active-mode collection returned by `0x005130f0 -> 0x004b2b70` or `0x0050f600` and emits bounded label ids `0x3d..0x44` for accepted rows; the other passes walk live placed structures in `0x006cec20`, filter them through station-or-transit gate `0x0047fd50`, owner/category tests, and local bounds queries `0x0047df30/0x0047df50`, and then emit category-specific overlay labels through `0x0053de00` and marker builders `0x00477a10/0x004779c0/0x005521a0/0x00552160/0x00552560`. After those six passes it also walks collection `0x006cfcbc` and, when optional focused region id `[this+0x113]` resolves in `0x006cfca8`, emits one final label-`0x3c` marker from `0x0048a170`. This is the strongest current read for the active-mode world-anchor overlay list owner rather than a single collection iterator.","objdump + local disassembly + caller-side field correlation + collection correlation + world-anchor marker correlation" +0x00478cb0,272,shell_overlay_drag_loop_apply_view_focus_updates_and_refresh_overlay_state,shell,thiscall,inferred,objdump + local disassembly + caller correlation + state correlation,2,"Interactive drag-side owner above the local shell overlay-state strip. The helper snapshots the initial controller cursor position from `[0x006d4018+0xa94/+0xa98]`, enters the surrounding shell input or capture mode through `0x0054e7e0`, repeatedly maps the current cursor through `shell_overlay_map_screen_point_to_world_cell_pair_under_current_bounds` `0x00477c10`, applies the resulting screen delta to the world view through `world_view_apply_screen_delta_to_focus_position` `0x0043d0c0`, pumps the shell-side timing or input path through `0x0054f4d0` and `0x0051d890`, and exits through `0x0054e7f0` once the current drag state reaches terminal value `7`. Current grounded sibling is the later clamp-and-refresh pass `0x00479510`, so this is the safest current read for the overlay drag loop rather than a generic modal input helper.","objdump + local disassembly + caller correlation + state correlation + world-view correlation" +0x00478dc0,1855,shell_overlay_state_rebuild_world_cell_bounds_and_normalized_rect_from_mode_flags,shell,thiscall,inferred,objdump + local disassembly + field correlation,2,"Heavy rebuild pass over the same shell overlay-state strip used by the world-anchor overlay builders. When shell flag band `[this+0x33]` lacks bits `0x02030000`, the helper leaves the derived screen rect at defaults `[this+0xef/+0xf3/+0xf7/+0xfb] = (0,1,0,1)` and returns. Otherwise it rebuilds current cell bounds `[this+0xb3..+0xbf]` either from full-world dims or by scanning world raster byte `0x0062c120+0x2131` for flag bit `0x02`, derives extent and density scalars into `[this+0xd3/+0xd7/+0xdb/+0xdf/+0xe3]`, optionally checks live placed structures in `0x006cec20` against the rebuilt bounds through `0x0047efe0`, `0x0047df00`, and `0x0047ded0`, and finally projects the resulting cell rectangle into normalized screen rect `[this+0xef/+0xf3/+0xf7/+0xfb]` using scalar bands `[this+0xff/+0x103/+0x107/+0x10b]`. This is the strongest current read for the overlay-state rebuild owner above the marker-list builders rather than a generic shell geometry helper.","objdump + local disassembly + field correlation + world-raster correlation + placed-structure correlation" +0x00479510,1134,shell_overlay_state_clamp_recenter_bounds_and_refresh_normalized_rect,shell,thiscall,inferred,objdump + local disassembly + field correlation + caller correlation,2,"Clamp-and-refresh companion for the same shell overlay-state strip. When flag band `[this+0x33]` lacks bits `0x02030000`, the helper resets normalized rect `[this+0xef/+0xf3/+0xf7/+0xfb]` to `(0,1,0,1)` and returns. Otherwise it copies current derived bounds `[this+0xb3..+0xbf]` into working bounds `[this+0xc3..+0xcf]`, uses `shell_overlay_state_measure_scaled_max_world_span_with_min_floor` `0x00477a70` plus scalar bands `[this+0xdf/+0xe3/+0xdb]` to expand or recenter those bounds when needed, clamps the resulting rectangle back inside live world dims `0x0062c120+0x2155/+0x2159`, refreshes scale lane `[this+0xd7]`, and reprojects the clamped cell rectangle into normalized rect `[this+0xef/+0xf3/+0xf7/+0xfb]` through `[this+0xff/+0x103/+0x107/+0x10b]`. Current grounded caller is the drag-or-zoom-side owner `0x00478cb0`, so this is the safest current read for the overlay-state clamp and normalized-rect refresh sibling rather than a second constructor.","objdump + local disassembly + field correlation + caller correlation + world-dimension correlation" +0x00479b50,475,shell_overlay_find_nearest_placed_structure_or_region_within_pick_radius,shell,thiscall,inferred,objdump + local disassembly + field correlation + collection correlation,2,"Nearest-target query under the same shell overlay-state family. The helper zeroes the caller's optional placed-structure and region out-ids, derives one pick radius from the current overlay width `[this+0xcb]-[this+0xc3]`, scales that radius by current shell metric `[0x006d4018+0xa8c]`, then scans live placed structures in `0x006cec20` using local coordinates `0x0047df30/0x0047df50` and Euclidean distance `0x0051db80`; when the candidate passes `0x0047fd50` it applies one extra weighting before comparing against the current best radius and writing the winning placed-structure id through the first out-pointer. When no placed structure wins and shell metric flag bit `0x4` is set, it then scans regions in `0x006cfca8` through `0x0048a170`, applies the same nearest-distance test, and writes winning region-like field `[region+0x202]` through the second out-pointer. The function returns success when either out-id becomes nonzero. Current grounded caller is the click-side owner `0x00479d30`, so this is the safest current read for the nearest overlay target query rather than a generic distance helper.","objdump + local disassembly + field correlation + collection correlation + nearest-target correlation" +0x00479d30,1519,shell_overlay_handle_click_target_dispatch_or_preview_request,shell,thiscall,inferred,objdump + local disassembly + caller correlation + request-packet correlation,2,"Click-side dispatch owner for the same shell overlay family. The helper first maps the caller screen point through `shell_overlay_map_screen_point_to_world_cell_pair_under_current_bounds` `0x00477c10`, resolves the nearest placed-structure or region target through `shell_overlay_find_nearest_placed_structure_or_region_within_pick_radius` `0x00479b50`, and then takes one of three bounded paths. Under the active-mode collection path it can reject the clicked region through `0x0048e3c0` and publish restriction notices `0x0c12/0x0c13` through `0x004c98a0`. Otherwise it packages one small local request block rooted at stack id `0x384`, populates that block from the resolved target, and either forwards it to the Multiplayer preview owner `0x006cd8d8` through `0x00407870(selector 0x41)` or dispatches it through the local active-mode handlers `0x004b3160`, `0x004b2c10`, and `0x004ab980`. The tail always eases one shell scalar through `0x0045ea20(0x38,0.5f)`. This is the strongest current read for the overlay click-dispatch owner rather than a generic modal or point-query wrapper.","objdump + local disassembly + caller correlation + request-packet correlation + active-mode dispatch correlation + multiplayer-preview correlation" +0x0047a120,3919,shell_overlay_rasterize_visible_map_classification_buffer_and_stage_rect,shell,thiscall,inferred,objdump + local disassembly + field correlation + caller correlation,2,"Broad rasterization owner above the same shell overlay-state family. The helper first resolves or stages one visible overlay rect through `0x00534930/0x00534c50`, optionally allocates a caller-owned RGBA buffer when the caller did not supply one, and then, when live world root `0x0062c120` is present, rasterizes the visible map window into that buffer. Under caller flag `0x00400000` it builds two temporary `0x100`-entry lookup tables from collection `0x006cfc9c` and helper `0x004c16f0`, then fills the visible rect by sampling world classification helpers such as `0x00534e50`, `0x00534f00`, `0x00449bd0`, and `0x00448aa0`, mapping the resulting classes through palette table `0x005f2c34`, and finally marking city-database owners from `0x0062bae0` into the same raster. When the caller supplied staging out-pointers it finishes by publishing the staged rect through `0x00534af0(1)`. This is the strongest current read for the shell-side visible overlay rasterizer rather than a small per-cell helper or the later marker builders.","objdump + local disassembly + field correlation + caller correlation + visible-raster correlation + rect-staging correlation" +0x0047b070,83,shell_overlay_state_construct_from_controller_template_copy,shell,thiscall,inferred,objdump + local disassembly + caller correlation + field correlation,2,"Small constructor beneath the shell overlay rasterizer family. The helper seeds base state through `0x00558580`, installs vtable `0x005ce840`, resets local overlay defaults through `shell_overlay_state_reset_default_world_bounds_and_normalized_rect` `0x00477af0`, allocates one temporary `0x60`-byte slab through `0x005a125d`, fills that slab from controller-owned source `0x006d4020` through `0x0053b7c0`, copies it into the live overlay state through `0x00557f80`, mirrors trailing byte `[template+0x5f]` into `[this+0xa2]`, and frees the temporary slab. This is the safest current read for the controller-template copy constructor rather than a generic allocator.","objdump + local disassembly + caller correlation + field correlation + constructor correlation" +0x0047b0d0,47,shell_overlay_state_construct_from_supplied_template_block,shell,thiscall,inferred,objdump + local disassembly + field correlation,2,"Direct copy-constructor sibling for the same shell overlay-state family. The helper seeds base state through `0x00558580`, installs vtable `0x005ce840`, reuses `shell_overlay_state_reset_default_world_bounds_and_normalized_rect` `0x00477af0`, copies trailing template byte `[src+0x5f]` into `[this+0xa2]`, and then returns the constructed overlay state. Compared with `0x0047b070`, this sibling assumes the caller already owns the source `0x60`-byte template block.","objdump + local disassembly + field correlation + constructor correlation" +0x0047b110,87,shell_overlay_state_release_template_handle_and_surface_then_tail_into_base_release,shell,thiscall,inferred,objdump + local disassembly + field correlation,2,"Primary release body for the same `0x005ce840` overlay-state family. The helper reinstalls vtable `0x005ce840`, drops optional template handle `[this+0xaf]` through `0x0053c000` on controller-owned root `0x006d4020`, releases optional surface or payload root `[this+0xab]` through `0x00542c90` and `0x0053b080`, clears both fields, and then tail-jumps into common base release `0x00558000`.","objdump + local disassembly + field correlation + release-path correlation" +0x0047b170,591,shell_overlay_state_service_surface_and_queue_overlay_markers,shell,thiscall,inferred,objdump + local disassembly + field correlation + caller correlation,2,"Main service or render owner for the `0x005ce840` overlay-state family. When the state is active and live world root `0x0062c120` exists, the helper checks whether the current overlay bounds intersect the visible world rectangle through `0x0051f2b0`, refreshes the clamped normalized rect through `shell_overlay_state_clamp_recenter_bounds_and_refresh_normalized_rect` `0x00479510`, draws the current overlay surface `[this+0xab]` through `0x0054f640/0x0051f460`, and then queues one of the overlay marker families depending on shell flag band `[this+0x33]`: the repeated active-mode list `0x00478330`, the single city-database owner marker `0x00478200`, or the fallback quad builder `0x00477d80`. When controller mask `[0x006d401c+0xc79]` includes this state's type word `[this+0x06]`, it also pushes one or two extra framed quads through `0x0054f9f0` from the local offset bands `[this+0x0b..+0x27]`. On the positive visibility path it exits through `0x0051f320` to restore the shell view state. This is the strongest current read for the overlay-state service and draw owner rather than a generic per-frame helper.","objdump + local disassembly + field correlation + caller correlation + overlay-marker correlation" +0x0047b3d0,123,shell_overlay_state_rasterize_into_surface_handle,shell,thiscall,inferred,objdump + local disassembly + caller correlation + field correlation,2,"Surface-rasterization wrapper for the same overlay-state family. When surface handle `[this+0xab]` is live, the helper acquires one temporary raster target through `0x00541970`, forwards the current overlay bounds, flags, cached ids, and normalized rect bands into `shell_overlay_rasterize_visible_map_classification_buffer_and_stage_rect` `0x0047a120`, and then commits that rasterized payload back into the live surface through `0x005438d0`. This is the safest current read for the overlay-state rasterize-to-surface wrapper rather than a second constructor or free helper.","objdump + local disassembly + caller correlation + field correlation + raster-wrapper correlation" +0x0047b450,27,shell_overlay_state_destructor_thunk_with_optional_free,shell,thiscall,inferred,objdump + local disassembly + caller correlation,1,"Destructor thunk for the `0x005ce840` overlay-state family. It re-enters `shell_overlay_state_release_template_handle_and_surface_then_tail_into_base_release` `0x0047b110` and, when the caller's low flag bit is set, frees the state object through `0x0053b080`.","objdump + local disassembly + caller correlation + destructor-thunk correlation" +0x0047b470,360,shell_overlay_state_ensure_surface_allocated_with_zoom_scaled_power_of_two_dims,shell,thiscall,inferred,objdump + local disassembly + field correlation + caller correlation,2,"Surface-allocation owner for the same `0x005ce840` overlay-state family. When live surface handle `[this+0xab]` is absent, the helper derives requested width and height either from the caller or from the current shell zoom table rooted at `[0x006d4024+0x11421e/+0x34]`, scales those dimensions by local float bands `[this+0x13]` and `[this+0x17]`, rounds them through `0x005a10d0`, and then grows each axis as a power of two starting at `0x40` until it reaches the scaled threshold bounded by the controller caps `[0x006d4024+0x11423b/+0x11423f]`. It stores the selected dimensions in `[this+0xa3/+0xa7]`, allocates one `0xec`-byte surface-like owner through `0x0053b070 -> 0x00543980(0,width,height,1)`, stores that root in `[this+0xab]`, and immediately reruns `shell_overlay_state_rasterize_into_surface_handle` `0x0047b3d0`. If the surface already exists it simply returns it. This is the strongest current read for the overlay-state ensure-surface owner rather than another constructor or draw helper.","objdump + local disassembly + field correlation + caller correlation + shell-zoom-table correlation + surface-allocation correlation" +0x0047b5e0,304,shell_overlay_state_update_hover_target_or_class_cell_and_forward_cursor_state,shell,thiscall,inferred,objdump + local disassembly + field correlation + caller correlation,2,"Pointer-move or hover-update owner for the same shell overlay-state family. The helper first maps the current screen point through `shell_overlay_map_screen_point_to_world_cell_pair_under_current_bounds` `0x00477c10`. Under overlay flag `0x00400000`, it rounds the mapped cell pair, validates it through `0x00534e50/0x00534f00`, resolves one classification-word pointer through `0x0044ade0`, and compares the resulting hovered class id against cached field `[this+0x117]`; when that class changes it stores the new id and reruns `shell_overlay_state_rasterize_into_surface_handle` `0x0047b3d0`. Otherwise it resolves the nearest placed-structure or region target through `shell_overlay_find_nearest_placed_structure_or_region_within_pick_radius` `0x00479b50`, clears cached target ids `[this+0x10f/+0x113]`, and when a hit exists stores those two resolved ids. The tail always forwards the caller coordinates plus the mapped world pair into `0x00558760`. This is the safest current read for the overlay-state hover or cursor-state updater rather than a general click dispatcher.","objdump + local disassembly + field correlation + caller correlation + hover-class correlation + nearest-target correlation" +0x0047b720,613,shell_overlay_state_handle_message,shell,thiscall,inferred,objdump + local disassembly + caller correlation + message-switch correlation,2,"Main message dispatcher for the `0x005ce840` overlay-state family. The helper switches on a small sparse message-id set rooted at `msg_id-6`, with current grounded cases for id `6`, the refresh pair `0xba/0xbb`, and the scalar-update id `0xbc`. On id `6` it first checks the state's live interaction gates through vtable slots `+0x30` and `+0x20` plus `0x005586c0`; if optional callback `[this+0x9a]` is present it forwards local-space coordinates derived from `[this+0x86]` and offset bands `[this+0x0b/+0x0f]`, otherwise it either enters `shell_overlay_handle_click_target_dispatch_or_preview_request` `0x00479d30` under flag mask `0x00030000` or the drag or focus-update owner `0x00478cb0`. On `0xba/0xbb` it toggles global gate `0x006ceba0` only for `0xbb`, ensures or rerasterizes the live surface through `0x0047b470/0x0047b3d0`, and rebuilds bounds through `0x00478dc0`. On `0xbc` it rescales cached world-span bands `[this+0xdf/+0xe3]` from message floats through `shell_overlay_state_measure_scaled_max_world_span_with_min_floor` `0x00477a70`. Every live case exits through `0x00558a10` with the original message. This is the strongest current read for the overlay-state message owner rather than a loose callback trampoline.","objdump + local disassembly + caller correlation + message-switch correlation + overlay-interaction correlation" +0x0047ba60,17,shell_overlay_reset_global_pointer_marker_slots,shell,cdecl,inferred,objdump + caller correlation + global-state correlation,2,"Clears the ten-entry global pointer-marker slot table rooted at `0x006ceba4`. The helper simply zeroes ten dwords and returns. Current grounded caller is the world-side setup or rebuild branch at `0x00449252`, so this is the clean global reset sibling for the later pointer-marker slot constructors rather than a generic scratch clear.","objdump + caller correlation + global-state correlation + pointer-marker slot-table correlation" +0x0047ba80,268,shell_overlay_rebuild_global_pointer_marker_slot,shell,thiscall,inferred,objdump + caller correlation + local disassembly + literal correlation,2,"Rebuilds one indexed global pointer-marker slot in the ten-entry table rooted at `0x006ceba4`. The caller supplies the slot index in `ECX`, one variant selector in `EDX`, two world-space anchor coordinates on the stack, and one scalar lane that is rounded through `0x005a10d0`. If the indexed slot already owns a live marker object, the helper releases it through `0x0045b160`, `0x0045b040`, and `0x0053b080`. It then allocates one `0x26e`-byte placed-structure-specialization-like object through `0x0053b070 -> 0x0045b680`, seeds it through `0x0045b9b0` from one of the three literal roots `pointer`, `pointer2`, or `pointer3`, publishes the caller world anchor through `0x004556f0`, applies scalar `0.8f` through `0x00455720`, and clears bit `0x20` in the derived state byte `[slot+0x20]`. Current grounded callers are the clustered world-side branches at `0x0051677b`, `0x00516797`, `0x005167df`, and `0x005167fe`, which makes this the indexed global pointer-marker slot builder rather than a general placed-structure constructor.","objdump + caller correlation + local disassembly + literal correlation + slot-table correlation + specialization-constructor correlation" +0x0047bb90,60,shell_overlay_release_global_pointer_marker_slots,shell,cdecl,inferred,objdump + caller correlation + global-state correlation,2,"Releases the ten-entry global pointer-marker slot table rooted at `0x006ceba4`. The helper walks each slot, and for any live marker object re-enters `0x0045b160`, `0x0045b040`, and `0x0053b080` before clearing the slot pointer. Current grounded callers are the world-side teardown branches at `0x00449292` and `0x005166d8`, so this is the matching global release loop for `shell_overlay_rebuild_global_pointer_marker_slot` `0x0047ba80`.","objdump + caller correlation + global-state correlation + slot-release correlation" +0x0047bbf0,95,runtime_profile_reset_default_setup_and_campaign_seed_fields,shell,thiscall,inferred,objdump + caller correlation + field correlation,2,"Resets the staged `0x108`-byte runtime-profile record to its default setup or campaign seed state. The helper clears the whole record, seeds compact option byte `[this+0x7d] = 1`, selected-year lane `[this+0x77] = 0x726`, live-row threshold `[this+0x79] = 1`, scroll lane `[this+0x7b] = 0`, clears bytes `[this+0x82]`, `[this+0xc4]`, `[this+0xc5]`, and `[this+0x01]`, writes one bounded random-like dword from `0x00518d70(0,0x7fff)` into `[this+0x83]`, and forces bytes `[this+0x87] = 1` plus `[this+0x97] = 1`. Current grounded callers are the setup constructor side at `0x005040aa` and the late world-entry branch at `0x004440f1`, so this is the clean default-profile reset helper rather than a setup-only local clear.","objdump + caller correlation + field correlation + staged-profile correlation" +0x0047bc50,37,runtime_profile_query_first_campaign_selector_byte_below_2,shell,cdecl,inferred,objdump + caller correlation + field correlation,2,"Scans the staged campaign selector band `[0x006cec7c+0xc6..+0xd5]` and returns the first index whose byte value is below `2`, or `16` if none match. Current grounded caller is the campaign-window side branch at `0x004b908e`, which keeps this on the staged campaign selector or unlock side of the profile rather than the earlier setup payload fields.","objdump + caller correlation + field correlation + campaign-selector-band correlation" +0x0047bea0,368,start_new_company_dialog_rebuild_primary_funding_band_and_publish_card,shell,cdecl,inferred,objdump + local disassembly + caller correlation + field correlation,2,"Rebuilds the primary funding-band globals for the `Start New Company` dialog and republishes the matching summary controls. The helper resolves the selected chairman profile through `0x004348c0`, queries one profile-side scale factor through `profile_entry_query_start_new_company_funding_scale_factor` `0x00476950`, multiplies that factor by current funding lane `0x006cec14`, chooses a step-size bucket, derives a bounded snapped band into globals `0x006cebcc`, `0x006cebd0`, and count `0x005f2c50`, and then formats the resulting range summary into controls `0x73` and `0x66` on window root `0x006cec18` through localized id `0x7150`. Current grounded callers are the dialog open path at `0x0047d051/0x0047d062/0x0047d070`, the snap-and-republish helper `0x0047c220`, and the child-control callback gate `0x0047c360`, so this is the clean primary funding-band builder beneath the dialog rather than a generic slider formatter.","objdump + local disassembly + caller correlation + field correlation + funding-band correlation" +0x0047c070,273,start_new_company_dialog_rebuild_secondary_funding_band_and_publish_card,shell,cdecl,inferred,objdump + local disassembly + caller correlation + field correlation,2,"Rebuilds the secondary funding-band globals for the `Start New Company` dialog and republishes the matching summary controls. The helper resolves the selected chairman profile through `0x004348c0(1)`, queries the threshold-adjusted total-plus-cash lane through `profile_entry_query_threshold_adjusted_holding_total_plus_cash_metric` `0x00476c20`, chooses a bounded step-size bucket, writes the resulting snapped band into globals `0x006cebd4`, `0x006cec0c`, and count `0x005f2c4c`, and then formats the summary into controls `0x73` and optionally `0x66` through localized id `0x714f` on window root `0x006cec18`. Current grounded caller is the start-company open path at `0x0047d047`, so this is the secondary funding-band sibling beside `0x0047bea0`.","objdump + local disassembly + caller correlation + field correlation + funding-band correlation" +0x0047c190,138,start_new_company_dialog_publish_current_funding_pair_labels,shell,cdecl,inferred,objdump + local disassembly + caller correlation + control-id correlation,2,"Publishes the two current funding-lane values for the `Start New Company` dialog. The helper formats current globals `0x006cec14` and `0x006cec10` through `0x0051c000` and writes them into controls `0x6f:0x7149` and `0x6f:0x714a` on the live dialog root `0x006cec18`. Current grounded caller is the funding snap-and-republish helper `0x0047c220`, so this is the narrow current-value label publisher beneath the broader funding-band builders.","objdump + local disassembly + caller correlation + control-id correlation + funding-label correlation" +0x0047c220,314,start_new_company_dialog_snap_current_funding_pair_to_band_steps_and_republish,shell,thiscall,inferred,objdump + local disassembly + caller correlation + control-id correlation,2,"Snaps the two current funding lanes for the `Start New Company` dialog into their currently computed band steps and republishes the affected labels. The helper first realigns current value `0x006cec14` inside the primary band rooted at `0x006cebd4..0x006cec0c` using the live control extent for id `0x714f`; it then optionally rebuilds the primary funding band through `0x0047bea0(0)`, realigns current value `0x006cec10` inside the secondary band rooted at `0x006cebcc..0x006cebd0` using the live control extent for id `0x7150`, rebuilds that band through `0x0047bea0(0)`, and finally republishes the current pair labels through `0x0047c190`. Current grounded callers are the dialog open path at `0x0047d058/0x0047d069` and the child-control callback gate `0x0047c360`, so this is the funding-lane snap-and-refresh owner beneath the start-company dialog.","objdump + local disassembly + caller correlation + control-id correlation + funding-band correlation" +0x0047c360,52,start_new_company_dialog_child_control_callback_refresh_funding_bands,shell,thiscall,inferred,objdump + local disassembly + caller correlation + control-id correlation,2,"Small child-control callback gate for the `Start New Company` funding dialog. The helper uses recursion latch `0x006cec1c`, checks whether the callback owner control id is `0x714f`, and then re-enters `start_new_company_dialog_snap_current_funding_pair_to_band_steps_and_republish` `0x0047c220` with the corresponding primary-band flag before clearing the latch. Current grounded caller is the dialog constructor `0x0047c590`, which installs this beneath the same funding-label family.","objdump + local disassembly + caller correlation + control-id correlation + callback-latch correlation" +0x0047c3a0,1573,start_new_company_dialog_handle_message,shell,thiscall,inferred,objdump + local disassembly + caller correlation + control-id correlation,2,"Primary message dispatcher for the `Start New Company` dialog family. The current grounded control split is narrower now: the helper handles shell messages `0xca/0xcb`, routes control `0x714b` into the staged company-name buffer at `0x006cebd8`, routes the two funding-step controls `0x714c/0x714d` through the local step selector around `0x005f2c48` and the `0x714e` summary lane, and keeps the confirmation or warning branch rooted at ids `0x03f2/0x03f4` on the modal-notice side through `0x004c98a0`. The handler also reuses the funding-band family through `0x0047c220` and the staged funding globals `0x006cec14/0x006cec10`, so the safest current read is the dialog's main message owner rather than a narrow name-field callback.","objdump + local disassembly + caller correlation + control-id correlation + funding-band correlation + modal-notice correlation" +0x0047c590,2631,start_new_company_dialog_construct,shell,thiscall,inferred,objdump + local disassembly + caller correlation + control-id correlation,2,"Constructs the modal `Start New Company` dialog instance used by `0x0047d080`. The constructor publishes the live dialog root at `0x006cec18`, builds the staged funding summary controls `0x714f`, `0x7150`, `0x7149`, and `0x714a`, installs the funding callback `0x0047c360` on the two band controls, seeds the staged company-name field `0x714b`, the step or arrow family `0x714c/0x714d`, and the companion summary lane `0x714e`, and allocates the required child-control payload blocks through the `0x0053b070 -> 0x0055ba70/0x0055ab50/0x0055a040/0x00540430` constructor strip before registering them through `0x0053f9c0`. Current grounded caller is the pre-open modal path at `0x0047d0fd`, so this is the clean dialog constructor above the funding-band and name-buffer helpers rather than a generic shell child builder.","objdump + local disassembly + caller correlation + control-id correlation + constructor-strip correlation" +0x0047d020,92,start_new_company_dialog_prepare_name_buffer_and_funding_bands,shell,cdecl,inferred,objdump + local disassembly + caller correlation + field correlation,2,"Pre-open preparation helper for the `Start New Company` dialog. The helper optionally resolves one staged name buffer through `0x0055ba70`, publishes that text through `0x0053f9c0`, frees the temporary heap copy through `0x005a1145`, and then rebuilds the dialog's funding-band state through the clustered sequence `0x0047c070(1) -> 0x0047bea0(1) -> 0x0047c220(0) -> 0x0047bea0(1) -> 0x0047c220(0) -> 0x0047bea0(0)`. This is the strongest current read for the start-company pre-open seed path directly above `start_new_company_dialog_open` `0x0047d080`.","objdump + local disassembly + caller correlation + field correlation + pre-open funding-band correlation" 0x0047d080,186,start_new_company_dialog_open,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Opens the shell-side `Start New Company...` dialog rooted at localized id `574`. The helper rolls one persona-dependent shell color or portrait token through a small static table, allocates the modal shell window through the constructor/callback pair `0x0047c590` and `0x0047c3a0`, increments the scenario-side start-company generation counter at `[0x006cec78+0x41]`, and enters the shared callback-driven modal path through `shell_open_custom_modal_dialog_with_callbacks` at `0x004c98a0`. Current grounded caller is the company-list window handler at `0x004c6f30`, which reaches this helper from the synthetic company-row id `0x7fff` after optional resignation confirmation through localized string `272` `You're currently chairman of the %1... Proceed?`. The older claim that this helper stored one live dialog owner at `0x006d3b4c` is no longer supported by direct disassembly; current stronger evidence treats `0x006d3b4c` as part of the broader shell tutorial state family instead.","objdump + RT3.lng strings + caller inspection + modal-path inspection + tutorial-state correction" 0x0047d120,509,start_new_company_dialog_commit_create_company,shell,cdecl,inferred,objdump + caller inspection + company-constructor inspection,4,"Commits the shell-side `Start New Company...` dialog and creates one fresh live company record rather than claiming one of the pre-seeded named railroads. After validating the dialog state it resolves the selected chairman-profile summary from `0x006cec78`, unlinks any existing company from that chairman through `0x00427c70`, allocates a new company id from the live company collection at `0x0062be10`, formats the dialog-owned company-name buffer at `0x006cebd8`, and initializes the new company through `0x00428420`. It then clamps one startup-funding lane against the new company's local limit fields, writes the chosen funding back to `0x006cec14`, updates one per-profile financing slot at `[profile+company_id*4+0x15d]`, applies the resulting debt through `0x00476050`, publishes the new selected company id through `0x00433790`, and triggers one shell refresh through `scenario_event_collection_service_runtime_effect_records_for_trigger_kind` `0x00432f40` with trigger kind `7`. When the dialog instead diverts into the `0x3f2` side path, it packages the same staged company payload into the Multiplayer preview request owner at `0x006cd8d8` through `0x00469d30`.","objdump + caller inspection + company-constructor inspection + global-state correlation + runtime-effect trigger-kind correlation" 0x0047d320,280,start_new_company_request_create_company,map,thiscall,inferred,objdump + caller inspection + company-constructor inspection,4,"Creates one fresh company record from a compact startup-company request block. The request layout is now partly grounded: `[this+0x0]` is the chairman profile id in `0x006ceb9c`, `[this+0x4]` is the localized railroad-name id or equivalent name token, `[this+0x8]` plus `[this+0xc]` form the startup-funding total later divided by the new company rate lane, and `[this+0x10]` is the staged company-name buffer. The helper unlinks any existing company from the referenced chairman through `0x00427c70`, allocates a fresh company id from the live company collection at `0x0062be10`, initializes that company through `0x00428420`, and updates one per-profile financing slot at `[profile+company_id*4+0x15d]`. If the request chairman matches the current selected chairman summary from `0x006cec78`, it also publishes the new selected company id through `0x00433790`. The surrounding startup-company owner is tighter now too: the neighboring post-create branch at `0x0047d42b` immediately re-enters `scenario_event_collection_service_runtime_effect_records_for_trigger_kind` `0x00432f40` with trigger kind `7`. Current grounded caller is the neighboring startup-company branch at `0x00470e48`, which reaches this helper when the request cannot be resolved to an existing company record.","objdump + caller inspection + company-constructor inspection + global-state correlation + runtime-effect trigger-kind correlation" +0x0047df70,208,placed_structure_service_candidate_local_service_comparison_cache_decay_and_row_propagation,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Broad aging and propagation pass over the placed-structure local service-comparison cache bands. The helper first resolves the optional linked placed instance through `0x00455f60`, then walks all `0x35` candidate lanes in the paired float tables rooted at `[this+0x3e]` and `[this+0x112]`, comparing their age stamps at `[this+0x1e6]` against the current scenario tick `[0x006cec78+0x15]`: entries older than `0x1d8800` are zeroed, while younger positive entries are decayed by the fixed scales at `0x005ce900` and `0x005ce8f8`. It then walks the three five-float row bands referenced by `[this+0x24]`, `[this+0x28]`, and `[this+0x2c]`, bumps active rows by the small constant at `0x005c9f18`, and propagates stronger marked row values back into the current site when the peer row-marker bytes at offsets `+0x04`, `+0x09`, `+0x0e`, or `+0x13` are set. Current grounded caller is the world-side sweep at `0x0040a6aa`, immediately before the same pass re-enters `scenario_event_collection_service_runtime_effect_records_for_trigger_kind` `0x00432f40` with trigger kind `3`, so this is the safest current read for the recurring local-service comparison-cache service pass rather than a one-off overlay helper.","objdump + caller xrefs + local disassembly + cache-age correlation + marked-row propagation correlation" 0x0047e240,240,placed_structure_query_candidate_local_service_metrics,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Queries one candidate-specific local service metric pair for the current placed-structure or site context. The helper first resolves the requested candidate index through the live structure collection at `0x0062ba8c` and rejects entries that fail `structure_candidate_is_enabled_for_current_year` at `0x0041e220`; on rejection it returns `0`, writes count `0` to the optional first out-pointer, and writes fallback float `1.0` to the optional second out-pointer. For live candidates it resolves the optional linked placed instance at `[this+0x04]`, passes that context through `0x00455f60`, and queries the base integer metric through `0x0042c960`; when the caller has a nonzero local sample list at `[this+0x38]` and `[this+0x34]`, it then accumulates matching per-cell float contributions from the world-grid table rooted at `[0x0062c120+0x2129]` into the second out-value. Current grounded callers include the shell or world-side branches at `0x0043f72e`, `0x0043f936`, `0x0047e365`, `0x0047ecd3`, `0x0047faff`, `0x004ba072`, `0x004bb51c`, and `0x00504d0f`, so this now looks like the first higher-level site query above the cargo-service bitset lane rather than another raw editor-runtime helper.","objdump + caller xrefs + callsite inspection + world-grid correlation" 0x0047e330,96,placed_structure_count_candidates_with_local_service_metrics,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Counts how many live structure candidates currently produce a valid local service-metric result for the current placed-structure or site context. The helper walks the full candidate collection at `0x0062ba8c`, resolves each entry id through `0x00518380`, and reuses `placed_structure_query_candidate_local_service_metrics` at `0x0047e240` with null out-pointers; it increments the return value only when that lower query succeeds. Current grounded callers keep this in the same site-query family as `0x0047e240`, so it now looks like the bounded count wrapper above the candidate-local service-metric lane.","objdump + caller xrefs + callsite inspection" 0x0047e390,656,placed_structure_query_cached_express_service_class_score,map,thiscall,inferred,objdump + caller xrefs + string correlation + callsite inspection,3,"Cached site-side query for one express-service class score. The helper special-cases request ids `0x384`, `0x385`, and `0x386` through three cached float-plus-timestamp pairs at `[this+0x14]/[+0x20]`, `[this+0x10]/[+0x1c]`, and `[this+0x0c]/[+0x18]`; when a cached value is younger than `0x0b40` ticks it returns immediately. On a cold path it scans all `0x35` live structure candidates, uses `0x0041e260` to keep only candidates that match the requested class, and then accumulates local per-cell contributions from the repeated sample list at `[this+0x34]` and the same world-grid tables under `[0x0062c120+0x2129]`. Nearby strings now strongly align the three class ids with the express cargo family `Passengers`, `Mail`, and `Troops`, but current grounded callers still treat this as a generic class-score query rather than a fully named UI lane. Current grounded callers include the shell or world-side branches at `0x00506c2d`, `0x00506c3d`, `0x00506e97`, and `0x00506ebf`.","objdump + caller xrefs + string correlation + callsite inspection + express-family correlation" @@ -599,10 +884,19 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0047f910,1080,placed_structure_select_best_candidate_id_by_local_service_score,map,thiscall,inferred,objdump + caller xrefs + local disassembly + callsite inspection,3,"Selects the strongest candidate id for the current placed-structure or site context under one caller-supplied candidate-class filter. The helper scans the live candidate collection at `0x0062ba8c`, keeps only candidates allowed by `0x0041e260`, and scores each survivor through either the direct local-service query `0x0047e240` or the heavier directional-route helper `0x0047e690` when route-backed state is present. It then applies the current shell or world-mode gates from `0x006cec74`, `0x006cec78`, and `0x006cec7c`, tracks the best candidate id and one parallel winner flag, and optionally writes the selected id or winner-state back through caller-owned out-pointers. Current grounded callers at `0x004ac8d6` and `0x004ac917` use it as a best-candidate selector inside a larger service-summary or preview family, which keeps it on the read-side selection path rather than the mutation path.","objdump + caller xrefs + local disassembly + callsite inspection + route-helper correlation + shell-gate correlation" 0x0047dda0,83,placed_structure_linked_route_entry_dispatch_primary_or_secondary_vfunc_if_anchor_slots_empty,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Linked-peer route-entry dispatcher beneath the placed-structure linked-site maintenance family. The helper reads route-entry anchor id `[this+0x08]` from the caller-supplied linked peer, resolves that anchor through the live route-entry collection `0x006cfca8`, and then re-enters `0x0048a090` with stack flag `1`. Only when that gate reports false does it dispatch one of two route-entry vtable calls on the resolved route-entry object: stack flag nonzero takes vtable `+0x4`, stack flag zero takes vtable `+0x8`. Current grounded callers are the paired placed-structure helpers `0x0040dba0` and `0x0040dbf0`, so this is the safest current read for the narrower linked-peer route-entry state dispatcher rather than a route builder.","objdump + caller xrefs + local disassembly + linked-route-entry-dispatch correlation" 0x0047fd50,60,placed_structure_is_station_or_transit_site_class,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Boolean class allowlist over one linked placed-structure record. The helper resolves the linked peer id at `[this+0x04]` through the live placed-structure collection `0x0062b26c`, re-enters that peer's candidate vtable `+0x80`, reads candidate class byte `[candidate+0x8c]`, and returns true only for class values `0`, `1`, or `2`; values `3`, `4`, and anything above `4` fail. Current grounded callers include the linked-transit company cache family at `0x00408280`, `0x00408f70`, and `0x004093d0`, the `cargo id 0` bypass branch inside the placed-structure sweep at `0x00452e60`, the nearby-site bucket builder `0x0047fdb0`, the linked-transit reachability gate `0x004801a0`, and the linked-site display-name or route-anchor refresh at `0x00480bb0`, so this is the safest current read for the narrower station-or-transit class gate rather than a route-reachability helper.","objdump + caller xrefs + callsite inspection + candidate-class correlation" +0x0047f320,1511,placed_structure_rebuild_local_service_sampled_cell_list_and_reset_route_link_scratch,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Broader linked-site runtime rebuild owner over the sampled local-service cell list rooted at `[this+0x34]/[this+0x38]`. The helper resolves the effective comparison mode from the linked candidate class byte `[candidate+0x8c]` unless the caller overrides it, derives one radius threshold from current world coordinates `[this+0x4a8/+0x4ac]`, frees the prior sampled-cell buffer at `[this+0x34]`, always clears the route-link scratch pair `[this+0x462/+0x466]`, and then scans one bounded world-grid rectangle through `[0x0062c120+0x2129]` with per-cell distance measured by `math_measure_float_xy_pair_distance` `0x0051db80`. For accepted cells it emits one temporary twelve-byte `(grid x, grid y, sampled score)` row through `0x0042b190`, `0x0042c530`, and `0x0042c580`; when caller arg0 is zero it then compacts one representative subset of those temporary rows into a newly allocated persistent list at `[this+0x34]` and stores the surviving row count in `[this+0x38]`, while nonzero arg0 callers use the same helper as a clear-and-scan companion without the final materialization step. Current grounded callers are the linked-site refresh and teardown strip at `0x00480542`, `0x004805c2`, `0x00480727`, and `0x004807e2`, so this is the safest current read for the local sampled-cell list rebuild plus route-link scratch reset rather than a plain route-entry-list clear helper.","objdump + caller xrefs + callsite inspection + local-service sampled-cell correlation + linked-site-runtime correlation" 0x0047e690,784,placed_structure_query_candidate_directional_route_overlay_summary,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Builds the heavier directional route-summary channel used by the station-detail candidate-service overlay when the active candidate carries a nonzero route-style byte at `[candidate+0x46]`. The helper converts one caller-supplied distance or bucket limit into a capped step count up to `0x28`, resolves the requested candidate's grouped routing class from `0x0062ba8c+0x9a`, then walks the current placed structure's linked route list at `[this+0x466]` and follows each route-linked placed structure through the live instance collections at `0x0062b26c` and the route-link collection `0x006ada90`. For matching class entries it re-enters `0x004676a0` to measure one directional route value against the peer placed-structure argument, keeps the strongest bounded values in a sorted local lane, and finally accumulates those kept route values into the caller-owned out-pointers. Current grounded overlay callers at `0x0043f89a` and `0x0043f8ee` invoke it in both directions between the preview station and each scanned placed structure before `world_render_station_candidate_service_map_overlay` turns those two returned channels into the `Coming To` and `Going From` legend rows.","objdump + caller xrefs + callsite inspection + overlay-caller correlation + legend-correlation + route-link-collection correlation" +0x0047e9a0,315,placed_structure_query_candidate_route_or_local_service_comparison_score,map,thiscall,inferred,objdump + caller xrefs + local disassembly + callsite inspection,2,"Bridges the heavier directional-route overlay summary path and the simpler local-service comparison lane. When the requested candidate carries a grouped routing class at `0x0062ba8c+0x9a`, the helper forwards the full query to `placed_structure_query_candidate_directional_route_overlay_summary` `0x0047e690` with the final flag forced to `0`. Otherwise it resolves the current placed structure's linked instance through `0x00455f60`, samples the current site's local float table at `[cell+0x103]` for the requested candidate lane, optionally re-enters `0x0042c080` on each local sample record at `[this+0x34/+0x38]`, and writes the bounded result back into the same comparison-cache bands rooted at `[this+0x1e6]`, `[this+0x2ba]`, and `[this+0x38e]`. Current grounded caller is the candidate-side score branch at `0x0041bbe2`, so this is the safest current read for the route-or-local comparison wrapper above `0x0047e690` rather than another route-list helper.","objdump + caller xrefs + local disassembly + callsite inspection + cache-band correlation" 0x0047d440,845,world_conditionally_seed_named_starting_railroad_companies,map,cdecl,inferred,objdump + caller xrefs + global-state inspection,4,"Conditional company-side setup helper adjacent to the `Setting up Players and Companies...` lane. Current grounded callers are the neighboring bring-up flow after world_seed_default_chairman_profile_slots at `0x004377a0` and a second setup-side branch around `0x00438300`, both under the same sandbox or non-editor shell-state conditions: it runs only when the Multiplayer preview dataset owner at `0x006cd8d8` is absent and either sandbox flag `[0x006cec7c+0x82]` is set or shell-state flag `[0x006cec74+0x14c]` is set while editor-map mode `[0x006cec74+0x68]` is clear. The helper first realigns the selected company from the chosen chairman profile when the current summary pair points at a missing company, then iterates exactly three fixed localized railroad-name ids through `0x00428420`: `0x23f` `Missouri Pacific`, `0x240` `New York Central`, and `0x241` `Grand Trunk Railroad` from `RT3.lng` ids `575..577`. That makes the branch look like a seeded trio of named starting railroad companies rather than a generic company refresh. The first seeded company is tied to the selected chairman-profile summary from `0x006cec78`, tuned from that selected chairman's per-profile fields `[profile+0x154]` and `[profile+0x158]`, and then written back as the selected company id through `0x00433790`. The second company is narrower now too: it only binds when `profile_collection_count_active_chairman_records` at `0x00477820` reports at least two live chairman records, and it then links through `profile_collection_get_nth_active_chairman_record` at `0x00477860` with ordinal `1`, so the second railroad is specifically the second active chairman-owned company rather than an arbitrary extra bind. The third railroad currently gets no matching chairman-link branch in the grounded code and therefore remains an unchaired named company in the live roster. All three records are constructed or refreshed from the live company collection at `0x0062be10` through `0x00428420`, while chairman-to-company ownership links are applied through `0x00427c70` and neighboring writes to `[profile+0x1dd]`. The tail is tighter now too: once at least three startup companies have been considered, the branch at `0x0047d6de` re-enters `scenario_event_collection_service_runtime_effect_records_for_trigger_kind` `0x00432f40` with trigger kind `7`.","objdump + caller xrefs + global-state inspection + state-accessor correlation + RT3.lng strings + company-constructor inspection + profile-helper inspection + runtime-effect trigger-kind correlation" 0x0047efe0,28,placed_structure_query_linked_company_id,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Returns the owning company id for one placed structure when a linked placed-instance record is present. The helper resolves `[this+0x04]` through the live placed-instance collection at `0x0062b26c` and then returns the company-like field at `[instance+0x276]`; when no linked instance is present it falls back to `0`. Current grounded callers include the station candidate-service overlay at `0x0043fff7`, where the returned company id is compared against the active company selector before the overlay chooses whether a scanned site should carry the `Already Connected by Another Company` note.","objdump + caller xrefs + callsite inspection + overlay-owner correlation" 0x0047f010,195,placed_structure_append_unique_route_entry,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,4,"Appends one unique six-byte route-entry record onto the placed-structure route list rooted at `[this+0x462]` and `[this+0x466]`. The helper first scans the existing list for the incoming leading `u16` key and returns early on duplicates; otherwise it allocates a new `(count*6)+6` byte buffer, copies the existing records, writes the new `u16` key at offset `+0x0` and the caller-supplied `u32` payload at `+0x2`, frees the previous buffer, and increments the route-entry count. Current grounded callers include the placed-structure side at `0x0042c554`, which walks the linked instance chain through `[site+0x0d6]` and `[instance+0x2a2]` while appending entries, and the world-side branch at `0x0040db7d`, which appends one selected placed-structure id plus a companion payload from a route-like table. This is therefore the current reusable append-if-missing helper above the route-entry list later consumed by `placed_structure_query_candidate_directional_route_overlay_summary` at `0x0047e690`.","objdump + caller xrefs + callsite inspection + buffer-layout correlation" +0x0047f0e0,131,placed_structure_resolve_linked_instance_secondary_raster_class_record,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Resolves one secondary-raster class record for the current placed structure's linked instance coordinates. The helper resolves `[this+0x04]` through the live placed-instance collection `0x0062b26c`, reads the linked instance's normalized coordinate pair through `0x00455800` and `0x00455810`, indexes the active secondary-raster byte plane at `[0x0062c120+0x2131]`, shifts the selected byte right by three, and resolves the resulting class token through collection `0x006cfc9c`. Current grounded callers are the world-side station or site branches at `0x004ac0bd` and `0x004ac11b`, so this is the safest current read for the direct linked-instance secondary-raster class-record wrapper rather than a generic terrain query.","objdump + caller xrefs + local disassembly + linked-instance-coordinate correlation + secondary-raster-class correlation" +0x0047f170,119,placed_structure_query_linked_instance_secondary_raster_class_id,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Returns the raw secondary-raster class id for the current placed structure's linked instance coordinates. The helper resolves `[this+0x04]` through `0x0062b26c`, reads the same linked-instance coordinate pair through `0x00455800` and `0x00455810`, indexes the live secondary-raster byte plane at `[0x0062c120+0x2131]`, and returns the selected byte shifted right by three without resolving it through `0x006cfc9c`. Current grounded callers at `0x004816dd` and `0x00487aa6` use it as the raw class gate beneath the station-or-transit and linked-company filters, so this is the safest current read for the linked-instance secondary-raster class-id query rather than a route-anchor helper.","objdump + caller xrefs + local disassembly + linked-instance-coordinate correlation + secondary-raster-class correlation" +0x0047f1f0,95,placed_structure_resolve_linked_instance_secondary_raster_class_record_via_world_query,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Thin linked-instance wrapper over the world-side secondary-raster class lookup `0x0044e270`. The helper resolves `[this+0x04]` through `0x0062b26c`, samples the linked instance's normalized coordinate pair through `0x00455800` and `0x00455810`, and then forwards those coordinates into the live world root at `0x0062c120`. Current grounded callers at `0x00487af1` and `0x00487b2c` use the returned class record as the companion object-side discriminator beside the raw class-id gate `0x0047f170`, so this is the safest current read for the record-returning linked-instance terrain wrapper.","objdump + caller xrefs + local disassembly + linked-instance-coordinate correlation + world-query correlation" +0x0047f250,60,placed_structure_route_anchor_matches_or_reaches_route_entry_id,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Boolean route-entry-anchor gate over one placed structure. The helper first compares the caller-supplied route-entry id against the current site's cached route-entry anchor at `[this+0x08]`; on a direct match it returns true immediately. Otherwise it resolves that cached anchor through the live route-entry collection `0x006cfca8` and re-enters `0x0048e050` with mode `2` and fallback `-1`, then normalizes the result to a strict boolean. Current grounded callers include the world-side branches at `0x0042ff29` and `0x0044bc0e`, where it gates later linked-instance or route-style work, so this is the safest current read for the placed-structure route-anchor match-or-reachability gate rather than a plain id compare.","objdump + caller xrefs + local disassembly + route-entry-anchor correlation + reachability-helper correlation" +0x0047f290,59,placed_structure_set_overlay_mark_byte_and_refresh_linked_peer_overlay_if_changed,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Small setter over placed-structure byte `[this+0x5bc]`. When the caller-supplied byte differs from the current value, the helper stores the new byte and then resolves the linked instance at `[this+0x04]` through `0x0062b26c` before re-entering `placed_structure_refresh_linked_peer_overlay_when_linked_peer_flagged` `0x0040d2d0`. Current grounded callers include the world-side branches at `0x004ae424` and `0x004b2260`, which use it while toggling selected-site or route-preview state, so this is the safest current read for the shared overlay-mark setter rather than a route-entry mutation helper.","objdump + caller xrefs + local disassembly + linked-peer-overlay correlation" +0x0047f2d0,47,route_link_route_entry_reaches_peer_site_route_group,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Boolean route-group compatibility gate over one route-link record. The helper resolves the caller-supplied peer site id through the live placed-structure collection `0x006cec20`, reads that site's cached route-entry anchor from `[site+0x08]`, resolves the current route-link record's own anchor from `[this+0x08]` through the live route-entry collection `0x006cfca8`, and then re-enters `0x0048e3c0` to test whether the two anchors belong to the same reachable route-side family. Current grounded caller is `placed_structure_route_link_recompute_endpoint_pair_state` `0x00467c30`, so this is the safest current read for the route-link-side peer reachability check beneath the endpoint-pair state reconciler.","objdump + caller xrefs + local disassembly + route-link correlation + route-group correlation" +0x0047f310,15,placed_structure_resolve_route_entry_anchor_record,map,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Tiny cached-record resolver over the placed structure's route-entry anchor id at `[this+0x08]`. The helper resolves that id directly through the live route-entry collection `0x006cfca8` and returns the resulting route-entry record. Current grounded callers include the linked-peer status and action branches `0x0040e54f` and `0x0040e907`, the city bonus filter at `0x004201aa`, and the later peer-route scan at `0x00487b6a`, so this is the safest current read for the direct route-entry-anchor resolver rather than a route-builder owner.","objdump + caller xrefs + local disassembly + route-entry-anchor correlation" 0x0048a090,65,route_entry_has_any_bound_anchor_slot_pair_or_triplet,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Small boolean gate over one route-entry record. With caller flag `0`, the helper returns true when either route-entry dword `[this+0x206]` or `[this+0x20a]` is not `-1`; with caller flag nonzero, it only returns false when all three dwords `[this+0x206]`, `[this+0x20a]`, and `[this+0x20e]` equal `-1`. Current grounded callers include the linked-peer route-entry dispatcher `0x0047dda0`, the placed-structure rebuild lane inside `0x0040ef10`, several linked-site route-anchor refresh branches around `0x00480603/0x00480927/0x00480993/0x00480be5`, the route builder family near `0x0049bbf2/0x0049d5a8/0x0049dc50/0x0049ded9`, and one later shell-side branch at `0x0050de1a`. This is therefore the safest current read for a route-entry anchor-slot occupancy gate rather than a placement or cargo predicate.","objdump + caller xrefs + local disassembly + route-entry-anchor-slot correlation" 0x00483f70,352,shell_service_pump_iteration,shell,thiscall,inferred,objdump + analysis-context,4,Executes one outer shell-service iteration on the shell state rooted at 0x006cec74. The helper can queue service event 0xcc through the shell bundle at 0x006d4018 polls that bundle through 0x00483ea0 refreshes active-mode or shell-state flags ensures the controller work pointer [0x006d4024+0x28] defaults to 0x0062be68 runs several global maintenance helpers and auxiliary cleanup then dispatches shell_state_service_active_mode_frame; when shell-state flag [this+0x501] is set it also marks the controller layout dirty through 0x0051f070 before returning the loop-continue result. bootstrap_init_shell_window_services calls it in the repeating shell loop that appears to own the observed shell lifetime before teardown.,objdump + analysis-context + caller xrefs 0x00485750,14,shell_has_tiger_tank_viewer,shell,cdecl,inferred,ghidra-headless,4,Returns whether the dedicated TigerTank shell viewer object at 0x006cfc8c is currently active. The 0x7533 open and 0x7534 close commands both gate on this global before showing status text or mutating viewer state.,ghidra + rizin + llvm-objdump + strings @@ -719,7 +1013,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004e5a80,2368,shell_render_company_overview_panel_header_and_optional_change_affordance,shell,thiscall,inferred,objdump + RT3.lng strings + helper correlation,4,"Broader company-side overview-panel renderer above the shared text-formatting entry later mapped at `0x004e5cf0`. The wrapper first checks the selected company id at `[this+0x88]`. When that id is absent or no longer resolves through the live company collection at `0x0062be10`, it chooses one of three fallback text families `1210` `You haven't started a company yet...`, `3043` `You don't control a company at the moment...`, or `3888` `You don't control a company at the moment.` from current chairman/company state, paints that fallback into the current shell text surface, and styles controls `0x3f06` and `0x3f07` inactive through the generic control path at `0x00540120`. When a valid company is present, it styles those same controls active, falls through into the shared metric/governance body later labeled at `0x004e5cf0`, and on the narrower branch where the selected company matches the scenario-selected company at `0x00434870` it also appends localized id `3044` `Click to change company name and logo.` and publishes the adjacent `1941` `Change` affordance through the shell text-widget writer at `0x00563290`. Current evidence therefore keeps the name/logo affordance outside the normal `CompanyDetail.win` callback dispatcher and makes `0x004e5cf0` read more like the shared text-formatting subentry within this wider overview-panel renderer than like a full standalone owner by itself.","objdump + RT3.lng strings + helper correlation + fallback-text correlation + overview-wrapper correlation" 0x004e5cf0,1844,shell_format_company_governance_and_economy_status_panel,shell,cdecl,inferred,objdump + RT3.lng strings + helper correlation,4,"Shared shell text formatter for one company-side overview panel. The helper first renders a five-line company-metric preamble from the generic stat reader `0x0042a5d0` using display-year-aware company slots `0x2c`, `0x2b`, `0x17`, and `0x26` plus one derived ratio branch. That preamble is now grounded through localized ids `1211..1215`: `Revenues` from slot `0x2c`, `Profits` from slot `0x2b`, `Load miles hauled` from slot `0x17`, `Revenue per load mile` from the derived `slot 0x2c / slot 0x17` branch with a safe `1.0` fallback when the load-mile value is nonpositive, and `Average speed` from slot `0x26` rendered through localized value formatter `1216` `%1 m.p.h.`. Its governance branch is now tighter too: when the selected company has no linked chairman it emits localized id `3045` `This company is controlled by the shareholder's committee...`; when the company is wholly owned it emits `3046` `You have complete ownership...` for the scenario-selected chairman or `3047` `This company is wholly owned by %1` for another linked chairman; otherwise it emits the investor-attitude lines `3048` `Investors are %1 your performance.` or `3049` `Investors are %1 the chairman's performance.` using the adjective table at `0x00622170`. The salary branch is bounded now too: it computes a signed salary delta from the company fields at `[company+0x14f]` and `[company+0x0d59]`, formats the absolute change and current salary value through the numeric helpers at `0x0051bfe0`, and then chooses `3050..3052` when the linked chairman is the scenario-selected chairman or `3053..3055` for another linked chairman depending on whether the delta is negative, positive, or zero. The bonus branch is narrower as well: only when the display year from `company_query_display_year_or_current_year` `0x004e39e0` matches the recorded bonus year at `[company+0x34f]` does it append `3056` `You have been awarded a bonus of %1.` or `3057` `The chairman has been awarded a bonus of %1.` using the bonus amount at `[company+0x353]`. The same formatter then appends the localized economy tail caption `1218` `Economy status - %1.` from the current scenario economy state at `[0x006cec78+0x2d]` and continues by staging the adjacent selected-company report or list help-title pairs `1219/1220` `Income Statement`, `1221/1222` `Balance Sheet`, `1223/1224` `Haulage Report`, `1225/1226` `Stock Report`, `1227/1228` `Train List`, `1229/1230` `Station List`, `1231/1232` `Industry List`, and `1233/1234` `Cargo List`. Current evidence still does not recover separate `CompanyDetail.win` action controls for those report or list labels under `shell_company_detail_window_handle_message` at `0x004c56a0`, so this strip currently reads as staged overview text or help content rather than as a closed dispatcher-owned launcher family. It uses the linked-chairman accessor `0x00426ef0`, the company-ownership test at `0x004768c0`, the display-year bucket helper `0x004240c0`, and the economy-status table at `0x00620cc0`. Current direct shell binding is still open, but the section-0 refresh for `CompanyDetail.win` now routes control `0x947f` through a dedicated stack-built dynamic text path, so this remains the strongest current shared formatter family aligned with that overview widget.","objdump + RT3.lng strings + helper correlation + governance-status string correlation + CompanyDetail overview correlation + metric-preamble correlation + report-launch-strip correlation + ownership-branch correlation + salary-bonus branch correlation + negative-dispatch-boundary correlation + preamble-label-table correlation" 0x004e68e0,1521,shell_load_screen_render_company_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection + page-title-table decode,4,"Renders the active-company comparison page inside `LoadScreen.win`. The helper first rejects the empty-company case with one fallback text branch rooted at localized ids `1210`, `3043`, or `3888`, then clears the shared row buffer at `[this+0x11c]`, stages the visible company-comparison column family `1235..1242`, and iterates the active company roster through `company_collection_count_active_companies` at `0x00429a50` plus `company_collection_get_nth_active_company_id` at `0x00429a90`. The caller-supplied page-local selector chooses which company metric to rank on: revenue through slot `0x2c`, profit through slot `0x2b`, cash through slot `0x0d`, or track mileage through slot `0x25`, all read through the generic company stat reader at `0x0042a5d0`. The emitted row lane also stages the adjacent company-report affordances `1243` `Click to view %1's income statement.`, `1244` `Click to view %1's balance sheet.`, and `1245` `Click to view %1's haulage reports.` on top of the ranked company rows, while applying the stronger highlight path when the row company matches the scenario-selected chairman's current company. The `LoadScreen.win` page-title descriptor table rooted at `0x006220a4` now ties current grounded caller page `2` to localized title id `1186` `COMPANY LIST`, so this renderer is now bounded as the company-list page rather than only a generic financial ranking helper.","objdump + RT3.lng strings + caller inspection + active-company-iteration correlation + company-stat-slot correlation + report-affordance correlation + page-title-table decode" -0x004e6ef0,1879,shell_load_screen_render_player_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection + page-title-table decode,4,"Renders the active-chairman comparison page inside `LoadScreen.win`. The helper clears the shared row buffer at `[this+0x11c]`, stages the visible chairman-comparison headers from the localized family `1237`, `1241`, `1246`, `1247`, `1248`, `1249`, and `1250`, then iterates the active chairman profile collection at `0x006ceb9c` through `profile_collection_count_active_chairman_records` and the `nth active` accessors rooted at `0x00477820`, `0x00477860`, and `0x004778c0`. The caller-supplied selector chooses which chairman-side metric drives the ranking: cash or one direct profile-held total, stock value, one broader total or net-worth lane, and a purchasing-power lane read through the profile helpers at `0x00476320`, `0x00476780`, `0x00476bb0`, and `0x004778c0`. The row builder also uses the profile-side name and portrait-family tables around `0x00622192..0x006221a4`, with special-cased current-player text on the zero-th row and the stronger highlight path when one ranked profile matches the scenario-selected chairman. The `LoadScreen.win` page-title descriptor table rooted at `0x006220a4` now ties current grounded caller page `7` to localized title id `1191` `PLAYER LIST`, so this renderer is now bounded as the player-list page rather than only a chairman-wealth ranking helper.","objdump + RT3.lng strings + caller inspection + active-profile-iteration correlation + profile-metric correlation + wealth-ranking-string correlation + page-title-table decode" +0x004e6ef0,1879,shell_load_screen_render_player_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection + page-title-table decode,4,"Renders the active-chairman comparison page inside `LoadScreen.win`. The helper clears the shared row buffer at `[this+0x11c]`, stages the visible chairman-comparison headers from the localized family `1237`, `1241`, `1246`, `1247`, `1248`, `1249`, and `1250`, then iterates the active chairman profile collection at `0x006ceb9c` through `profile_collection_count_active_chairman_records` and the `nth active` accessors rooted at `0x00477820`, `0x00477860`, and `0x004778c0`. The caller-supplied selector chooses which chairman-side metric drives the ranking: cash, one direct profile-held total, one direct-total-plus-cash lane, one threshold-adjusted-total-plus-cash lane, or the active-rank lane read through `0x00476320`, `0x00476780`, `0x00476c20`, and `0x004778c0`. The row builder also uses the profile-side name and portrait-family tables around `0x00622192..0x006221a4`, with special-cased current-player text on the zero-th row and the stronger highlight path when one ranked profile matches the scenario-selected chairman. The `LoadScreen.win` page-title descriptor table rooted at `0x006220a4` now ties current grounded caller page `7` to localized title id `1191` `PLAYER LIST`, so this renderer is now bounded as the player-list page rather than only a chairman-wealth ranking helper.","objdump + RT3.lng strings + caller inspection + active-profile-iteration correlation + profile-metric correlation + wealth-ranking-string correlation + page-title-table decode" 0x004e7670,3033,shell_load_screen_render_company_train_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Renders the company-owned train list page inside `LoadScreen.win`. The helper first rejects missing selected-company state through localized id `1210` and then rejects companies with no trains through id `1251` `This company does not have any trains.` after querying the current company through the live company collection at `0x0062be10` and the train-count helper at `0x004264c0`. On the populated path it clears the `0x190`-dword row buffer at `[this+0x11c]`, reads the optional display year through `company_query_display_year_or_current_year` at `0x004e39e0`, stages the visible column headers and sort-help family `1235..1242`, and then iterates the selected company's live train roster through the company-side train accessors around `0x004264c0`, `0x00426520`, `0x004a7270`, `0x004a77b0`, and `0x0041adb0`. The emitted row family matches the player-facing train-list strip: revenue, profit, cash, track mileage, engine type, age, oil, water, sand, speed, and profit rows from `1252..1266`, plus the per-row camera-centering affordance `1267` `Click to center the camera on %1`. Current grounded caller is the wider `LoadScreen.win` render family around `0x004ea499`, which keeps this as one company-list page sibling beside the holdings, building, station, and cargo pages rather than a `CompanyDetail.win` subpanel.","objdump + RT3.lng strings + caller inspection + company-train-roster correlation + train-list-string correlation" 0x004e8270,2336,shell_load_screen_render_company_industry_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection + page-title-table decode,4,"Renders the selected-company industry list page inside `LoadScreen.win`. The helper rejects missing selected-company state through localized id `1210` and rejects companies with no owned buildings through id `1268` `This company does not own any buildings.` after resolving the current company through `0x0062be10` and the building-count helper at `0x004266c0`. On the populated path it clears the shared row buffer at `[this+0x11c]`, stages the visible header and sort-help family `1269..1278`, and then walks the selected company's owned placed-structure set through the building-side accessors around `0x004266c0`, `0x004267f0`, `0x0062b26c`, `0x0047de00`, `0x0040cac0`, `0x0040ca70`, `0x0040ca80`, and `0x0040d360`. The rendered rows align with the player-facing industry list strip: industry or building type, year built, profitability, loads consumed, loads generated, and the surrounding sort hints. The `LoadScreen.win` page-title descriptor table rooted at `0x006220a4` now ties current grounded caller page `15` to localized title id `1199` `INDUSTRY LIST`, which makes this the industry-list page rather than a generic building-list sibling.","objdump + RT3.lng strings + caller inspection + company-building iteration correlation + building-list-string correlation + page-title-table decode" 0x004e8bb0,2198,shell_load_screen_render_company_station_list_panel,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Renders the company-owned station list page inside `LoadScreen.win`. The helper rejects missing selected-company state through localized id `1210` and rejects companies with no stations through id `1279` `This company does not have any stations.` after resolving the selected company and probing the company-owned station count through `0x00426590`. On the populated path it clears the shared row buffer at `[this+0x11c]`, stages the station-list header and sort-help family `1280..1288`, and then walks the selected company's owned station or placed-structure set through the station-side accessors around `0x00426620`, `0x006cec20`, `0x0047d7d0`, `0x0047d7c0`, `0x0047d7f0`, `0x0047d7e0`, and `0x0047de00`. The emitted rows match the visible station-list strip: cargo out, cargo in, revenue out, revenue in, and the adjacent sort affordances. Current grounded caller is the wider `LoadScreen.win` render family around `0x004ea499`, which keeps this as the company-station page sibling beside the train, building, and cargo pages.","objdump + RT3.lng strings + caller inspection + company-station iteration correlation + station-list-string correlation" @@ -733,6 +1027,12 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004eb890,381,shell_present_merger_vote_outcome_dialog,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Single-player merger-vote outcome presenter used by the merger result path. The helper resolves the two merger companies from `0x006d10dc` and `0x006d10de`, chooses localized title id `729` `Merger Succeeds!!!` or `730` `Merger Fails!!!`, formats the vote tally labels `731` `Votes In Favor:` and `732` `Votes Against:`, and renders the final result dialog through the shell presentation callback rooted at `0x006d111c`. Current grounded caller is `shell_resolve_merger_vote_and_commit_outcome` at `0x004ebd10` on the single-player branch.","objdump + RT3.lng strings + caller inspection + merger-result dialog correlation" 0x004ebd10,1202,shell_resolve_merger_vote_and_commit_outcome,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Resolves the single merger vote, commits the outcome, and records cooldown state. The helper walks the active chairman profile collection at `0x006ceb9c`, computes weighted votes for and against the proposed merger between companies `0x006d10dc` and `0x006d10de`, accumulates the affirmative share count into `0x006d110c`, compares that total against half the target-company value, and then splits by single-player versus multiplayer. In single-player it presents the result through `shell_present_merger_vote_outcome_dialog` at `0x004eb890`; in multiplayer it formats localized id `3059` `Merger between '%1' and '%2' has %3.` with result strings `3060` or `3061` and routes the payload through the shell transport. On success it commits the merger through `0x00427e20`; on failure it stamps the current year into `[company+0x15f]` as the grounded merger-cooldown field.","objdump + RT3.lng strings + caller inspection + merger-vote resolution correlation" 0x004ec640,732,shell_company_detail_attempt_merger_flow,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` merger-attempt flow. The helper rejects empty worlds through localized id `727`, rejects recent failed merger cooldown cases through id `728`, and then opens the merger offer or vote dialog family rooted at the local globals `0x006d10cc..0x006d1120`. The grounded single-player path checks the proposed premium against company cash through localized id `3889`, can open a premium-confirmation prompt through id `4067`, and on acceptance commits through the company merger helper at `0x00427e20` or the broader vote-resolution path at `0x004ebd10`. When the multiplayer-side shell owner is active it packages the same request through the asynchronous shell transport path rooted at `0x006cd8d8` instead of mutating company state immediately. Current grounded owner is the wider company-detail message dispatcher at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + merger-dialog correlation" +0x005042c0,170,shell_station_detail_clear_dynamic_rows_and_haul_widgets_if_dirty,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Small dirty-clear helper beneath `StationDetail.win`. When global dirty latch `0x006d16f0` is set and the live station-detail singleton `0x006d16d8` exists, the helper clears the candidate-service and nearby-structure row bands through `0x0053fe00` over control ranges `0xb414..0xb4db`, `0xb4dc..0xb5a3`, `0xb40a..0xb413`, and `0xb400..0xb409`, disables the paired haul-summary widgets `0xb3f6` and `0xb3f7`, and then resets `0x006d16f0` back to `0`. Current grounded caller is `shell_station_detail_window_refresh_controls` `0x00506610`, so this is the safest current read for the dirty-clear owner beneath the broader station-detail refresh family.","objdump + local disassembly + caller inspection + StationDetail dirty-clear correlation" +0x00504370,24,shell_station_detail_has_valid_selected_station,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Tiny validity probe for the currently selected station id in detail-manager state `[0x006d0818+0x90]`. The helper checks that id against the live placed-structure collection `0x006cec20` through `0x00517d40` and returns the boolean result. Current grounded callers are the neighboring StationDetail helper strip beneath `0x00506610`, where this is the narrow selected-station presence gate rather than a general collection query.","objdump + local disassembly + caller inspection + selected-station correlation" +0x00504390,96,shell_station_detail_selected_station_belongs_to_selected_company,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Small selected-station ownership predicate for `StationDetail.win`. The helper validates the current station id from detail-manager state, resolves the live station from collection `0x006cec20`, compares its owner through `0x0047efe0` against the currently selected company id from `0x004337a0`, and returns `1` only when they match. Current grounded callers are the neighboring station-detail action helpers, so this is the safest current read for the selected-company ownership gate beneath the broader station-detail refresh family.","objdump + local disassembly + caller inspection + StationDetail ownership correlation" +0x005043f0,179,shell_station_detail_present_selected_station_not_controlled_notice,shell,cdecl,inferred,objdump + RT3.lng strings + local disassembly,3,"Ownership-blocked notice helper beneath the `StationDetail.win` action family. After validating the current selected station id, the helper resolves the station owner through `0x0047efb0`; if that owner resolves it formats localized id `3595` `You can't take that action, because this station is owned by a railroad (%1) that you do not control.` with the owner's display name, otherwise it falls back to the empty-string root `0x005c87a8`. It then presents the result through the shell message-box path at `0x004c98a0`. Current grounded callers are the neighboring station-detail action branches that first test `shell_station_detail_selected_station_belongs_to_selected_company` `0x00504390`, so this is the safest current read for the not-controlled notice rather than a general station popup helper.","objdump + RT3.lng strings + local disassembly + ownership-block correlation" +0x005044b0,221,shell_station_detail_refresh_class_gated_action_controls_0xb3bb_to_0xb3bf,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Refreshes the lower class-gated action controls inside `StationDetail.win`. After validating the current selected station id, the helper resolves the linked candidate class byte `[candidate+0x8c]` and uses that class to restyle controls `0xb3bb`, `0xb3bc`, `0xb3bd`, `0xb3be`, and `0xb3bf` between the shell affordance states rooted at `0x65` and `0x87` through repeated `0x00540120` calls. Current grounded caller is the `StationDetail.win` constructor `0x005068c0`, so this is the safest current read for the class-gated lower-action refresh strip rather than a station-detail message owner.","objdump + local disassembly + caller inspection + StationDetail lower-action correlation" +0x00504590,468,shell_station_detail_present_scenario_station_connection_triplet_popup,shell,cdecl,inferred,objdump + local disassembly + caller inspection + format-string correlation,3,"Formats and presents the scenario-latched `StationDetail.win` popup beneath action controls `0xb3b7` and `0xb3b8`. After validating the current station from detail-manager state `0x006d0818+0x90`, the helper walks the selected station's per-destination table rooted at `[station+0x30]`, skips invalid or self station ids, copies each other station name into the local text buffer, and then appends three per-destination scalar lanes from the current station's five-byte-stepped metric arrays. Active lanes format through the local `%1 : ` and ` %5.2f` helpers at `0x005d16f0` and `0x005d16e8`, while missing lanes fall back to `N/C` at `0x005d16e0`; the stacked result is then published through `shell_publish_text_callout_presentation` `0x005519f0` using helper root `0x006d16e8`. Current grounded caller is `shell_station_detail_window_refresh_controls` `0x00506610` when scenario latch `[0x006cec74+0x1db]` is set, so the safest current read is a scenario-side station connection triplet popup rather than an ordinary haul or candidate-service branch.","objdump + local disassembly + caller inspection + format-string correlation + scenario-latch correlation" 0x00504770,786,shell_station_detail_present_to_from_haul_stats_popup,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Formats and presents the `StationDetail.win` hauled-traffic popup for one of the two `To` or `From` summary widgets. The helper validates the current station from detail-manager state `0x006d0818+0x90`, resolves the selected station record through `0x006cec20`, and then chooses the localized direction strings `676` `...hauled TO this station.` or `679` `...hauled FROM this station.` plus the singular or plural `load` and `loads` labels `677/678` based on the triggering control id `0xb3f6` versus `0xb3f7`. It formats the current-year and lifetime load and value totals through the station haul-stat helpers at `0x0047d7e0` or `0x0047d7f0`, then presents the final popup text through the shell message-box path at `0x00538c70`. Current grounded owner is the neighboring `To` or `From` summary-widget builder at `0x00505150`.","objdump + RT3.lng strings + caller inspection + hauled-traffic popup correlation" 0x00504a90,70,shell_station_detail_clear_active_candidate_service_preview,shell,thiscall,inferred,objdump + caller inspection + state correlation,4,"Clears the active candidate-service preview owned by `StationDetail.win`. The helper first resets the shared `(placed-structure id, candidate id)` pair at `0x005ee4fc` and `0x005ee500` through `0x0043f610`, then tears down the local station-detail preview latch at `[this+0x7c]` and decrements the sibling global refcount `0x0062be84` when that preview was armed. When the live world owner at `0x0062c120` is in the matching preview-capable mode gate rooted at `[+0x2171]` and `[+0x2175]`, it tails into the neighboring world-side clear path at `0x00452d30`. Current grounded callers are the station-detail selection reset branches around `0x00504bca`, `0x00504bda`, and the later cleanup family at `0x00505bff` and `0x00505c0a`.","objdump + caller inspection + world-preview correlation" 0x00504ae0,174,shell_station_detail_set_active_candidate_service_preview,shell,thiscall,inferred,objdump + caller inspection + state correlation,4,"Arms the active candidate-service preview for `StationDetail.win`. The helper begins by clearing the old preview through `shell_station_detail_clear_active_candidate_service_preview` at `0x00504a90`, then when the supplied candidate id is nonzero and the live world owner at `0x0062c120` is in the matching preview-capable mode gate it routes the current detail-panel station id through the world-side preview family at `0x00452f60`, `0x00452d80`, `0x00452db0`, and `0x00452ca0`. On success it latches the preview-active bit at `[this+0x7c]`, increments the sibling global refcount `0x0062be84`, and stores the active `(station id, candidate id)` pair into `0x005ee4fc` and `0x005ee500` through `0x0043f620`. This is the shell-side owner that feeds the broader world scanner rooted at `0x0043f640` with the currently inspected station-detail candidate pair.","objdump + caller inspection + world-preview correlation + global-pair correlation" @@ -741,6 +1041,8 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00505150,796,shell_station_detail_build_to_from_haul_summary_widget,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Builds one of the two `To` or `From` hauled-traffic summary widgets inside `StationDetail.win`. The helper chooses the localized heading `686` `To` or `687` `From` from its first argument, paints a bounded 10-step summary strip from the supplied float lane and the paired station haul-stat queries at `0x0047d7e0` or `0x0047d7f0`, and formats the one-line direction-specific labels and totals through the same `load` or `loads` family later used by the popup callback. On first build it also registers the matching control id `0xb3f6` or `0xb3f7` through callback `shell_station_detail_present_to_from_haul_stats_popup` at `0x00504770`, so the same widget owns both the visible `To` or `From` strip and the click-through stats popup. Current grounded caller is the larger station-detail refresh pass at `0x00506610`, which constructs the `To` and `From` widgets back to back.","objdump + RT3.lng strings + caller inspection + control registration correlation" 0x00505470,738,shell_station_detail_refresh_nearby_structure_jump_rows,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,3,"Refreshes the five-row nearby-structure jump lane inside `StationDetail.win`. The helper validates the current station, iterates the fixed five nearby-structure categories, counts matching nearby entries through `0x0047dc90`, and formats the player-facing jump text from localized ids `688` `This station has %1 %2(s) nearby...` and `689` `first ` together with the per-category name table rooted at `0x00620dc4`. It then builds the paired per-row controls and descriptive text blocks under the `0xb400..0xb413` control band that the later station-detail message handler uses to center the map or jump into the matching nearby structure detail. This currently looks like the shell-side owner of the nearby-structure lane that sits beside the later candidate-service preview rows.","objdump + RT3.lng strings + caller inspection + nearby-structure correlation" 0x00505760,1159,shell_station_detail_refresh_candidate_service_rows,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Refreshes the visible candidate-service row lane inside `StationDetail.win`. The helper counts currently active candidate-service entries through `placed_structure_count_candidates_with_local_service_metrics` at `0x0047e330`, resolves each visible row candidate through the neighboring ordinal helper at `0x0047e620`, and then colors and formats the row from the candidate-local-service metrics, the candidate display name, and the same localized strings `681`, `682`, and `2813` used by `shell_station_detail_update_candidate_service_entry`. It registers the per-row click path through callback `shell_station_detail_update_candidate_service_entry` at `0x00504ba0`, keeps the selected and hovered candidate ids in the globals `0x006d16f8` and `0x006d16f4`, and toggles the current preview highlight as rows are rebuilt. Current grounded caller is the broader station-detail refresh pass at `0x00506610`.","objdump + RT3.lng strings + caller inspection + candidate-service row correlation" +0x00504ec0,644,shell_station_detail_refresh_class_3_or_4_train_service_matrix,shell,thiscall,inferred,objdump + local disassembly + caller inspection + RT3.lng string-id correlation,3,"Alternate `StationDetail.win` refresh branch for selected station classes `3` and `4`. After validating the current station and republishing the station name through helper root `0x006d16e4`, the helper rebuilds a five-row by two-column train-service matrix: the column headers come from localized ids `684` `Trains Serviced` and `685` `Trains Maintained`, the per-row category labels resolve through the world-side lookup table at `0x006cec78+0x46a84` plus `0x0053de00/0x00552560`, and the underlying counts come from the station-side integer lanes at `0x0047d800`. When the detail view is not already marked live it also rebuilds the shared popup-capable haul widget lane and reuses `shell_station_detail_present_to_from_haul_stats_popup` `0x00504770` as the click-through callback. Current grounded caller is `shell_station_detail_window_refresh_controls` `0x00506610`, which routes class-`3/4` stations into this helper instead of the ordinary nearby-structure, haul-summary, and candidate-service strip.","objdump + local disassembly + caller inspection + RT3.lng string-id correlation + class-3-4-branch correlation" +0x00506610,688,shell_station_detail_window_refresh_controls,shell,cdecl,inferred,objdump + local disassembly + caller inspection + child-helper correlation,4,"Broad refresh owner for the shell-side `StationDetail.win` family. The helper first validates the currently selected station id from detail-manager state `[0x006d0818+0x90]`, resolves the live station from collection `0x006cec20`, and publishes the upper summary lane through `shell_publish_text_callout_presentation` `0x005519f0` using helper root `0x006d16ec`. When scenario-side latch `[0x006cec74+0x1db]` is set it re-enters `shell_station_detail_clear_dynamic_rows_and_haul_widgets_if_dirty` `0x005042c0` and `shell_station_detail_present_scenario_station_connection_triplet_popup` `0x00504590` for the paired action controls `0xb3b7` and `0xb3b8`; otherwise it checks the resolved candidate class byte `[candidate+0x8c]`, routes classes `3` and `4` into `shell_station_detail_refresh_class_3_or_4_train_service_matrix` `0x00504ec0`, and for the ordinary branch it publishes the station name, rebuilds the nearby-structure jump lane through `shell_station_detail_refresh_nearby_structure_jump_rows` `0x00505470`, rebuilds the `To` and `From` hauled-traffic widgets through `shell_station_detail_build_to_from_haul_summary_widget` `0x00505150`, rebuilds the candidate-service rows through `shell_station_detail_refresh_candidate_service_rows` `0x00505760`, and finally marks the detail view live through `0x006d16f0 = 1`. Current grounded callers are the constructor-side control wiring under `shell_station_detail_window_construct` `0x005068c0` and the paired action-control callbacks on `0xb3b7/0xb3b8`, so this is the safest current read for the main StationDetail refresh owner rather than a narrower popup callback.","objdump + local disassembly + caller inspection + child-helper correlation + StationDetail control correlation" 0x0050c500,426,shell_present_chairmanship_takeover_vote_outcome_dialog,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Single-player chairmanship-takeover outcome presenter used by the special election path. The helper resolves the target company from `0x006d1a0c`, chooses localized title id `626` `New Chairman Takes Over!!!` or `627` `Chairmanship Takeover Fails!!!`, formats the tally labels `628` `Votes in favor` and `629` `Votes Against`, and renders the final result dialog through the shell presentation callback rooted at `0x006d1a34`. Current grounded caller is `shell_resolve_chairmanship_takeover_vote_and_commit_outcome` at `0x0050c940` on the single-player branch.","objdump + RT3.lng strings + caller inspection + takeover-result dialog correlation" 0x0050c940,880,shell_resolve_chairmanship_takeover_vote_and_commit_outcome,shell,cdecl,inferred,objdump + RT3.lng strings + caller inspection,4,"Resolves the special chairman's election, commits the outcome, and records cooldown state. The helper walks the active chairman profile collection at `0x006ceb9c`, computes weighted votes for and against the takeover of company `0x006d1a0c` by chairman profile `0x006d1a0e`, accumulates the affirmative share count into `0x006d1a30`, compares that total against half the target-company value, and then splits by single-player versus multiplayer. In single-player it presents the result through `shell_present_chairmanship_takeover_vote_outcome_dialog` at `0x0050c500`; in multiplayer it formats localized id `3082` `Takeover attempt of '%1' by '%2' has %3.` with result strings `3060` or `3061` and routes the payload through the shell transport. On success it transfers chairmanship through `0x00428a30`; on failure it stamps the current year into `[company+0x289]` as the grounded takeover-cooldown field.","objdump + RT3.lng strings + caller inspection + takeover-vote resolution correlation" 0x0050ccc0,709,shell_company_detail_attempt_chairmanship_takeover_flow,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Runs the `CompanyDetail.win` chairmanship-takeover flow against the currently selected company. The helper reads the caller's current share ownership in the target company, rejects insufficient holdings through localized id `623`, rejects recent failed takeover cooldown cases through id `624`, and otherwise opens the special chairman's election confirmation under id `625`. The grounded single-player path seeds the local takeover-election state at `0x006d1a08..0x006d1a38` and launches the follow-on election helper at `0x0050c940`; when the multiplayer-side shell owner is active it instead packages the same request through the asynchronous shell transport path rooted at `0x006cd8d8`. Current grounded owner is the wider company-detail message dispatcher at `0x004c56a0`.","objdump + RT3.lng strings + caller inspection + takeover-election correlation" @@ -749,14 +1051,20 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004c6c30,765,shell_company_list_window_refresh_rows,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Rebuilds the shell company-list window rows. The helper clears the two mirrored list controls under ids `0x2ee1` and `0x2ee2`, iterates the live company collection at `0x0062be10`, and formats each company row with one of three localized status strings: id `267` `You are the chairman of the %1!` for the currently selected chairman company from `0x00434870`, id `268` `The %1 has no chairman at the moment.` when `[company+0x3b]` is zero, or id `269` `%1 is the chairman of the %2.` plus suffix id `270` `Double-click for details.` when another chairman profile is attached. When the row also has a primary station, the helper appends localized help id `2992` `Shift-Click to center on this company's primary station.` After the live-company rows are rebuilt, it conditionally appends the synthetic row id `0x7fff` through `shell_company_list_format_company_or_start_row` so `<>` appears as a separate affordance rather than as part of the seeded trio itself. It also refreshes the currently selected list index at `[this+0x78]`.","objdump + RT3.lng strings + caller inspection + company-list iteration" 0x004c6f30,704,shell_company_list_window_handle_message,shell,thiscall,inferred,objdump + RT3.lng strings + caller inspection,4,"Message dispatcher for the shell company-list window. Selection changes on controls `0x2ee1` and `0x2ee2` toggle the mirrored list selection state and the local start-company affordance latch at `0x006cfe7c`. Activating one live company row routes through `shell_company_list_activate_or_shift_center_company` at `0x004c6bb0` or opens its detail path through the shell detail-panel manager `0x004ddbd0`. Activating the synthetic row id `0x7fff` instead checks whether the current chairman can start a new company, optionally shows localized confirmation id `272` `You're currently chairman of the %1... Proceed?`, and then opens the dedicated `Start New Company...` dialog through `start_new_company_dialog_open` at `0x0047d080`. When that dialog closes while the company-list window remains active, the handler rebuilds the rows through `shell_company_list_window_refresh_rows` at `0x004c6c30`.","objdump + RT3.lng strings + caller inspection + dialog correlation" 0x004c7200,212,shell_company_list_window_construct,shell,thiscall,inferred,objdump + caller inspection + strings,4,"Constructs the shell company-list window rooted at globals `0x006cfe70..0x006cfe7c`. The helper allocates two mirrored list widgets under ids `0x2ee1` and `0x2ee2`, attaches the row formatter `shell_company_list_format_company_or_start_row` at `0x004c6b40`, the live-row activation handler `shell_company_list_activate_or_shift_center_company` at `0x004c6bb0`, publishes the current selected-index storage at `[this+0x78]`, and then calls `shell_company_list_window_refresh_rows` at `0x004c6c30`. It also toggles the start-company affordance controls `0x2ee3` and `0x2ee4` from the global latch `0x006cfe7c`, which matches the handler-side selection logic for the synthetic `<>` row.","objdump + caller inspection + control wiring" -0x005068c0,443,shell_station_detail_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `StationDetail.win` panel owned by detail-manager mode `8`. The constructor installs the singleton at `0x006d16d8`, binds `StationDetail.imb` and `StationDetail.win` through `0x0053d110` and `0x0053fa50`, seeds the paired action controls `0xb3b7` and `0xb3b8` through callback `0x00506610`, toggles the adjacent navigation controls `0xb3b3` and `0xb3b4`, and conditionally refreshes the gated action control `0xb3f8` through `0x005044b0`. This corrects the older company-browser reading: current grounded resource names and control wiring put mode `8` on a station-detail lane rather than on a company-detail browser.","objdump + strings + detail-manager correlation + caller inspection" +0x005068c0,443,shell_station_detail_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `StationDetail.win` panel owned by detail-manager mode `8`. The constructor installs the singleton at `0x006d16d8`, binds `StationDetail.imb` and `StationDetail.win` through `0x0053d110` and `0x0053fa50`, seeds the paired action controls `0xb3b7` and `0xb3b8` through callback `0x00506610`, toggles the adjacent navigation controls `0xb3b3` and `0xb3b4`, conditionally restyles the special action control `0xb3f8` from the editor latch `[0x006cec74+0x68]`, special-condition slot `[0x006cec78+0x4af7]`, and selected-station byte `[station+0x5c9]`, and then refreshes the lower class-gated action strip `0xb3bb..0xb3bf` through `0x005044b0`. This corrects the older company-browser reading: current grounded resource names and control wiring put mode `8` on a station-detail lane rather than on a company-detail browser.","objdump + strings + detail-manager correlation + caller inspection + special-action-control correlation + lower-action-strip correlation" +0x00506a80,64,shell_station_list_window_destruct_release_helpers_and_clear_singleton,shell,thiscall,inferred,objdump + vtable scan + local disassembly,2,"Primary `StationList.win` destructor. The helper restores vtable `0x005d177c`, releases the two helper handles rooted at `0x006d1704` and `0x006d170c` through the shared owner `0x006d4020 -> 0x0053c000`, clears singleton `0x006d1708`, and then tail-jumps into the common shell-window teardown at `0x0053f7d0`. Current evidence comes from the StationList constructor or vtable pair, so this is the safest current read for the concrete list-window destroy path rather than another shared shell stub.","objdump + vtable scan + local disassembly + StationList destructor correlation" +0x00506ac0,656,shell_station_list_row_callback_publish_station_callout_card,shell,cdecl,inferred,objdump + local disassembly + caller inspection + callout correlation,3,"Row-side callout publisher beneath the visible `StationList.win` controls `0x61a9` and `0x61aa`. Given one selected station id and one caller-supplied screen anchor tuple, the helper resolves the live station from collection `0x006cec20`, derives one category or type label through the linked record path `0x0062b26c -> 0x0040cec0`, builds one localized header through `0x0053de00` and `0x00552560`, copies the station display name from `[station+0x46b]`, queries the weighted freight lane through `0x005519f0`, queries the cached express or freight class totals through `placed_structure_query_cached_express_service_class_score` `0x0047e390` for ids `0x0386` and `0x0385`, and then publishes the resulting stacked text card through repeated `shell_publish_text_callout_presentation` `0x005519f0` calls using the helper payload roots at `0x006d1704` and `0x006d170c`. Current grounded caller is `shell_station_list_window_refresh_rows_selection_and_status` `0x00506f30`, which wires this callback onto both station row controls with event `0x7a`.","objdump + local disassembly + caller inspection + callout correlation + StationList row-callback correlation" 0x00506be0,360,shell_station_detail_format_freight_and_express_summary,shell,cdecl,inferred,objdump + strings + caller inspection,4,"Formats the visible freight and express summary lines on the shell-side `StationDetail.win` panel. The helper resolves the selected placed-structure record, builds the weighted freight total through the neighboring cargo-summary helper at `0x005519f0`, queries the cached express-side service totals through `placed_structure_query_cached_express_service_class_score` at `0x0047e390` for class ids `0x0385` and `0x0386`, and then writes the localized lines `Freight: %1` and `Express: %1` through string ids `239` and `240`. This is the first grounded shell-detail consumer of the local service bundle rebuilt beneath `0x0042d580`.","objdump + strings + caller inspection + service-query correlation" 0x00506d50,252,shell_station_list_handle_center_or_rename_action,shell,cdecl,inferred,objdump + strings + caller inspection,4,"Handles the station-list row modifier actions after the active station row is resolved from collection `0x006cec20`. The helper reads the packed shell input modifier bits from `0x006d4018+0xa8c`; with Shift it recenters the world view on the selected station through `0x0047de00` and `0x00433900`, and with Control it opens the station rename prompt through localized id `3732` `Enter station name:`. This helper is the modifier-aware side-action lane paired with the visible freight or express station-row summaries.","objdump + strings + caller inspection + input-state correlation" 0x00506e50,221,shell_station_list_format_freight_and_express_availability_summary,shell,cdecl,inferred,objdump + strings + caller inspection,4,"Formats the visible `StationList.win` row summary for one selected station. The helper resolves the placed-structure record from collection `0x006cec20`, queries the cached express-side service totals through `placed_structure_query_cached_express_service_class_score` at `0x0047e390` for class ids `0x0385` and `0x0386`, and then emits the localized composite summary `3890` `%1 has %2 freight loads and %3 express loads available for hauling...`. This is the first grounded shell-list consumer of the same service-score lane used by `shell_station_detail_format_freight_and_express_summary`.","objdump + strings + caller inspection + service-query correlation" -0x005071e0,494,shell_station_list_window_handle_message,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Primary message dispatcher for the shell-side `StationList.win` family rooted at vtable `0x005d177c`. The helper owns the paired station-row controls `0x61a9` and `0x61aa`, the side selector controls `0x61ab` and `0x61ac`, and the two status labels `0x61af` and `0x61b0`. It periodically updates the currently highlighted station id through `0x00622ae4`, mirrors row selections into `0x006cec78+0x4cba`, and on activation resolves the selected station object through collection `0x006cec20`, optionally recenters the world view through `0x00433900`, then re-enters the shell detail-panel manager with mode `5` and that same station id. The `0x61ab` and `0x61ac` controls toggle the active side bit at `0x006d1710` and reopen the station-pick helper rooted at `0x00507620`.","objdump + strings + detail-manager correlation + UI dispatch inspection" -0x005074c0,235,shell_station_list_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `StationList.win` panel later published at `0x006d1708`. The constructor binds the paired station-row controls `0x61a9` and `0x61aa`, seeds the side-selector controls `0x61ab` and `0x61ac` from the current active-side bit at `0x006d1710`, stores the selected-entry latch at `[this+0x78]`, and then calls the row-refresh helper at `0x00506f30`. Current grounded evidence places this panel on a station-oriented shell lane below the company roster rather than on a direct company-detail or chairmanship-claim path.","objdump + strings + detail-manager correlation + caller inspection" -0x00507620,656,shell_station_pick_window_construct,shell,thiscall,inferred,objdump + strings + caller inspection,4,"Constructs the shell-side `StationPick.win` helper window. The constructor binds the list control `0x80ea`, the scroll or selector controls `0x80e8` and `0x80e9`, publishes the helper at `0x006d1718`, and then populates the visible station rows from collection `0x006cec20`. The same family feeds the selected station id through `0x00622ae8` and returns it to the caller when the helper closes. Current grounded callers put this helper under the `StationList.win` selector branch rather than under the startup-company flow.","objdump + strings + caller inspection + helper correlation" +0x00506f30,672,shell_station_list_window_refresh_rows_selection_and_status,shell,thiscall,inferred,objdump + caller inspection + local disassembly + collection scan,4,"Broad row and status refresh owner for the shell-side `StationList.win` panel. The helper clears the two visible row controls `0x61a9` and `0x61aa`, scans collection `0x006cec20`, filters candidate rows through `placed_structure_is_station_or_transit_site_class` `0x0047fd50`, the linked-site class check at `0x0040c990`, and the current selected-company gate `0x004337a0 == 0x0047efe0`, then republishes matching station ids into both row controls. It also wires the visible summary callback `shell_station_list_format_freight_and_express_availability_summary` `0x00506e50`, the row-activation callback `0x00506ac0`, and the modifier-action callback `shell_station_list_handle_center_or_rename_action` `0x00506d50`, restores the highlighted row from `0x00622ae4`, mirrors the shared selected station latch `0x006cec78+0x4cba` when it still belongs to the current company, and refreshes the two status labels `0x61af` and `0x61b0`. Current grounded caller is `shell_station_list_window_construct` `0x005074c0`, and the same body is re-entered from the later message owner.","objdump + caller inspection + local disassembly + collection scan + row-refresh correlation" +0x005071e0,494,shell_station_list_window_handle_message,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Primary message dispatcher for the shell-side `StationList.win` family rooted at vtable `0x005d177c`. The helper owns the paired station-row controls `0x61a9` and `0x61aa`, the side selector controls `0x61ab` and `0x61ac`, and the two status labels `0x61af` and `0x61b0`. It periodically updates the currently highlighted station id through `0x00622ae4`, mirrors row selections into `0x006cec78+0x4cba`, and on activation resolves the selected station object through collection `0x006cec20`, optionally recenters the world view through `0x00433900`, then re-enters the shell detail-panel manager with mode `5` and that same station id. The `0x61ab` and `0x61ac` controls toggle the active side bit at `0x006d1710`, refresh the side-selector affordances, and reopen the modal station-pick helper through `shell_station_pick_window_open_modal_and_return_selected_station_id` `0x005078c0`.","objdump + strings + detail-manager correlation + UI dispatch inspection + station-pick-modal correlation" +0x005074c0,235,shell_station_list_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `StationList.win` panel later published at `0x006d1708`. The constructor binds the paired station-row controls `0x61a9` and `0x61aa`, seeds the side-selector controls `0x61ab` and `0x61ac` from the current active-side bit at `0x006d1710`, stores the selected-entry latch at `[this+0x78]`, and then calls `shell_station_list_window_refresh_rows_selection_and_status` `0x00506f30`. Current grounded evidence places this panel on a station-oriented shell lane below the company roster rather than on a direct company-detail or chairmanship-claim path.","objdump + strings + detail-manager correlation + caller inspection + row-refresh correlation" +0x005075b0,16,shell_station_pick_window_noop_list_aux_callback,shell,cdecl,inferred,objdump + constructor wiring,1,"Tiny no-op callback that immediately returns. Current grounded caller is `shell_station_pick_window_construct` `0x00507620`, which wires it onto list control `0x80ea` with event `0x79`, so this is best read as the inert auxiliary callback slot for the StationPick list rather than as a meaningful command owner.","objdump + constructor wiring + no-op correlation" +0x005075c0,96,shell_station_pick_window_rewrite_list_and_scroll_messages_to_primary_select_event,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Tiny `StationPick.win` message normalizer over one incoming shell message record. The helper recognizes the helper's list and scroll messages `0xc9`, `0xca`, and `0xcb`; rewrites list control `0x80ea` and scroll controls `0x80e8/0x80e9` onto the primary select message `0xc9`; and when the rewritten branch comes from control `0x80e9` it also clears the staged station-id latch `0x00622ae8` back to `-1`. This is the safest current read for the StationPick list-or-scroll normalization helper rather than an independent command owner.","objdump + caller inspection + local disassembly + StationPick message normalization" +0x00507620,656,shell_station_pick_window_construct,shell,thiscall,inferred,objdump + strings + caller inspection,4,"Constructs the shell-side `StationPick.win` helper window. The constructor binds the list control `0x80ea`, the scroll or selector controls `0x80e8` and `0x80e9`, publishes the helper at `0x006d1718`, and then populates the visible station rows from collection `0x006cec20`. The same family feeds the selected station id through `0x00622ae8`, normalizes list and scroll messages through `shell_station_pick_window_rewrite_list_and_scroll_messages_to_primary_select_event` `0x005075c0`, and returns the chosen id to the caller when the modal opener closes. Current grounded callers put this helper under the `StationList.win` selector branch rather than under the startup-company flow.","objdump + strings + caller inspection + helper correlation + StationPick normalization correlation" 0x005076c0,501,shell_station_pick_window_populate_station_rows,shell,cdecl,inferred,objdump + strings + caller inspection,4,"Populates the visible row set for the shell-side `StationPick.win` helper. The helper iterates collection `0x006cec20`, filters entries through `0x0047fd50`, sorts them by the display-name field at `[entry+0x46b]`, and publishes the resulting station names through the helper list control `0x80ea`. It also mirrors the chosen station ids back into the helper-local scratch arrays, updates one status lane through control event `0xaf`, and refreshes the visible row count through control event `0x66`. Current grounded caller is `shell_station_pick_window_construct` at `0x00507620`.","objdump + strings + caller inspection + collection iteration" +0x005078c0,192,shell_station_pick_window_open_modal_and_return_selected_station_id,shell,fastcall,inferred,objdump + caller inspection + local disassembly,3,"Modal StationPick helper opener above `shell_station_pick_window_construct` `0x00507620`. If the live station collection `0x006cec20` is empty the helper returns `-1` immediately. Otherwise it allocates one `0x78`-byte helper object through `0x0053b070`, constructs the `StationPick.win` window, stores the live helper at `0x006d1718`, optionally nudges one presentation float at `[helper+0x05]` when caller flag `CL` is nonzero, brackets the modal show path through `0x00483450`, `0x00538f10`, `0x004834a0`, and `0x005389c0`, then destroys the helper, clears `0x006d1718`, and returns the selected station id from `0x00622ae8`. Current grounded caller is the side-selector branch inside `shell_station_list_window_handle_message` `0x005071e0`.","objdump + caller inspection + local disassembly + modal-helper correlation" 0x004d4500,88,shell_ensure_editor_panel_window,shell,cdecl,inferred,objdump + analysis-context,4,Ensures the shell-side EditorPanel.win helper window rooted at 0x006d07b4 exists. When the panel is absent it allocates a 0x7c-byte window object seeds the vtable at 0x005d0cb8 binds the EditorPanel.win resource through 0x0053fa50 publishes the object to the shell runtime through 0x00538e50 event 0x1e and then runs the shared panel-open helper at 0x004d4160.,objdump + analysis-context + strings 0x004dc670,368,shell_file_options_dialog_construct,shell,thiscall,inferred,objdump + strings,4,Constructs the shared shell file-options dialog rooted at fileopt.win. The helper clears the three downstream branch flags at 0x006d07f8 0x006d07ec and 0x006d07f0 binds the fileopt.win resource through 0x0053fa50 publishes the object to the shell runtime and populates several mode-dependent labels and status text before user input is handled.,objdump + strings 0x004dc7d0,14,shell_has_file_options_dialog,shell,cdecl,inferred,objdump + nearby-constructor correlation + frame-caller inspection,4,"Tiny presence probe for the shared shell file-options dialog rooted at `0x006d0800`. The helper returns `1` when the live `fileopt.win` object is present and `0` otherwise. Current grounded callers include the post-step shell-window ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, where this check now sits beside the `LoadScreen` and custom-modal probes.","objdump + nearby-constructor correlation + frame-caller inspection + fileopt correlation" @@ -809,7 +1117,25 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004fcb80,400,shell_paint_territory_window_refresh_control_bands,shell,thiscall,inferred,objdump + constructor correlation + message-owner inspection,4,"Owner-side refresh pass for the shell-side `PaintTerritory.win` family. The helper first restyles the seven ordinal controls `0xbb81..0xbb87` from `[this+0x78]` and the 24-entry territory row band `0xbb94..0xbbab` from `[this+0x80]`, then resolves the live territory collection at `0x006cfc9c` and republishes the dynamic-text rows `0xbbf8..0xbc0f` through the special type-`0x6f` control path. It derives the row label from territory name bytes near `[entry+0x04]`, derives the paired summary metrics from fields `[entry+0x3d]` and `[entry+0x41]`, and formats those metrics through the same numeric-text family `0x0051b700/0x005193f0` used by sibling tool windows. Current grounded callers are the constructor `0x004fcf30` and the message owner `0x004fcd10`, which makes this the current `PaintTerritory.win` refresh owner rather than a company-access refresh lane.","objdump + constructor correlation + message-owner inspection + dynamic-text control correlation + territory-collection correlation" 0x004fcd10,530,shell_paint_territory_window_handle_message,shell,thiscall,inferred,objdump + constructor correlation + caller inspection,4,"Primary message dispatcher for the shell-side `PaintTerritory.win` tool window. Under message `0xc8`, controls `0xbb94..0xbbab` update the current territory row in `[this+0x80]` and global `0x0062284c`, then route the world-side tool state through `0x00450520` when live world mode is `0x1e` or through `0x00452fa0` with mode id `0x1e` otherwise before re-entering `shell_paint_territory_window_refresh_control_bands` `0x004fcb80`. Controls `0xbb81..0xbb87` update the ordinal lane through `shell_paint_territory_window_select_ordinal_and_refresh_caption` `0x004fcaf0`, store the ordinal in global `0x00622850`, and refresh. Control `0x07d6` owns the shared world-surface latch `[this+0x7c]`; while that latch is live, the helper hit-tests through `0x00448ac0`, resolves the current ordinal value through table `0x00622854`, and forwards the staged world coordinates plus the current territory row through `0x0044a560` before mirroring the row pointer back through `0x00450520` or `0x00452fa0`. Current grounded owner correlation is the constructor `0x004fcf30` and the live shell message loop, which keeps this on the `PaintTerritory.win` side of the shared world-surface family rather than the company-detail territory-access dispatcher.","objdump + constructor correlation + caller inspection + world-surface latch correlation + tool-state dispatch correlation" 0x004fcf30,224,shell_paint_territory_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `PaintTerritory.win` tool window. The constructor installs vtable `0x005d1480`, binds `PaintTerritory.win` through `0x0053fa50`, seeds the current ordinal and the paired scalar or selection lane from globals `0x0062284c..0x00622854`, refreshes the visible selection band through `0x004fcb80`, and then routes the initial world-side tool state through `0x00450520` or `0x00452fa0` with world-mode constant `0x1e`. Current grounded caller is the detail-panel manager branch at `0x004ddf86`, which keeps this on the shell tool-window side rather than the later territory-access and company-governance families.","objdump + strings + detail-manager correlation + singleton correlation + tool-state dispatch correlation" +0x0050a570,104,shell_stock_buy_window_render_selected_company_stock_data_panel,shell,thiscall,inferred,objdump + local disassembly + constructor correlation,3,"Control callback beneath the shell-side `StockBuy.win` family that renders the selected-company stock-data panel through the shared formatter `0x004c0160`. The helper first validates current selected company id `0x00622b00` against company-count query `0x00429a50`, then forwards that selected company together with the cached panel roots `0x006d19dc/0x006d19e0`, the holdings-name table `0x006d1748`, and toggle byte band `0x00622b04` into the stock-data formatter using localized token `0x3e4e`. Current grounded owner correlation is the `StockBuy.win` constructor `0x0050c290`, which wires this helper into control `0x3aa0`.","objdump + local disassembly + constructor correlation + stock-data formatter correlation + selected-company correlation" +0x0050a5e0,29,shell_stock_buy_window_invalidate_selected_company_summary_control_unconditionally,shell,cdecl,inferred,objdump + constructor correlation + local disassembly,3,"Tiny invalidation callback under the shell-side `StockBuy.win` family. The helper re-enters the shared shell tick `0x00563250` and then unconditionally republishes the standard shell invalidation triple `(0x3b60, 0x3e7f, 0)` through `0x0053fe00` using the live window singleton at `0x006d19f0`. Current grounded owner correlation is the constructor-side callback wiring at `0x0050ba9f`, which binds this helper to control `0x3a9a` with selector `0x83`, so this is the cleanest current selected-company summary invalidation callback rather than a post-trade helper.","objdump + constructor correlation + local disassembly + control-0x3a9a correlation + summary-invalidation correlation" +0x0050a600,93,shell_stock_buy_window_buy_confirmation_modal_tutorial_gate_callback,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Small callback-driven tutorial gate beneath the shell-side `StockBuy.win` buy-confirmation modal. The helper only intercepts shell message `0xcb` on control `0x03f4`; when that exact button path fires while tutorial flag `0x006d3b4c` is live, it opens one sibling shell modal rooted at localized id `0x0e8c` through `0x005193f0 -> 0x004c98a0` and returns `0`. All other message or control combinations return `1` immediately. Current grounded owner correlation is the local stock-buy dispatcher `0x0050bbe0`, which pushes this helper as the callback argument when it opens the buy-side confirmation modal rooted at localized id `0x0292`.","objdump + caller inspection + local disassembly + modal-callback correlation + tutorial-flag correlation" +0x0050a660,10,shell_stock_buy_window_set_selected_chairman_row_index,shell,cdecl,inferred,objdump + caller inspection,3,"Tiny setter under the shell-side `StockBuy.win` family. The helper stores the caller-supplied row index directly into global `0x006d19f4`, which the window constructor `0x0050c290` and later refresh paths use as the current selected chairman-row lane. Current grounded caller `0x004e017e` derives that row index through `0x00477920` from one player-list profile id before publishing it here, so this is the cleanest current raw selected-row setter for `StockBuy.win`.","objdump + caller inspection + selected-row correlation" +0x0050a670,33,shell_stock_buy_window_refresh_if_live,shell,cdecl,inferred,objdump + caller inspection,3,"Small refresh-if-live wrapper for the shell-side `StockBuy.win` singleton rooted at `0x006d19f0`. The helper first re-enters the shared shell state tick `0x00563250`, then when the window object is live it republishes the standard shell invalidation triple `(0x3b60, 0x3e7f, 0)` through `0x0053fe00`. Current grounded callers are the buy and sell chairman-profile mutation helpers `0x00477110` and `0x00476460`, so this is the clearest current post-trade refresh hook for the live stock-buy window rather than a general finance-panel redraw.","objdump + caller inspection + singleton correlation + post-trade refresh correlation" +0x0050a6a0,33,shell_stock_buy_window_invalidate_after_local_trade_message_branch,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Unconditional invalidation sibling beneath the shell-side `StockBuy.win` family. The helper mirrors the same shell tick `0x00563250` and standard invalidation triple `(0x3b60, 0x3e7f, 0)` used by `0x0050a670`, but it does not first guard on the live-window singleton. Current grounded callers are the two local trade message branches at `0x0050bddf` and `0x0050bf8b`, immediately after they commit rounded buy or sell blocks through `0x00477110` and `0x00476460`, so this is the clearest current unconditional refresh hook for the in-window trade path.","objdump + caller inspection + local disassembly + local-trade correlation + summary-invalidation correlation" +0x0050a6d0,86,shell_stock_buy_window_publish_selected_company_or_none_and_refresh_affordance,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Publishes one selected company id into the shell-side `StockBuy.win` family and refreshes the paired availability affordance. The helper compares the caller-supplied company id against current company-count query `0x00429a50`; valid ids are stored into global `0x00622b00`, while out-of-range ids collapse to `-1`. It then maps that validity test onto control-style selector `0x6d/0x86`, republishes control `0x3a9b` through `0x00540120`, and invalidates the same `StockBuy.win` shell triple through `0x0053fe00`. Current grounded callers are the player-list handoff at `0x004e01a0`, the stock-buy window bring-up tail at `0x0050ba0a`, and the local buy/sell selection branches at `0x0050c013/0x0050c037`, so this is the clearest current selected-company publisher beneath `StockBuy.win`.","objdump + caller inspection + local disassembly + selected-company correlation + affordance refresh correlation" +0x0050a730,757,shell_stock_buy_window_refresh_profile_rows_and_metric_cards,shell,thiscall,inferred,objdump + local disassembly + constructor correlation,3,"Broad refresh owner for the shell-side `StockBuy.win` profile-row and metric-card surface. The helper iterates the active chairman-profile collection through `0x00477820/0x00477860`, lays out the selected row and the remaining visible row cards using the cached widget roots at `0x006d19d8`, `0x006d19dc`, `0x006d19e8`, and `0x006d19ec`, formats persona or name labels through `0x00476bb0` and `0x0053de00`, and pulls the currently grounded chairman metric lanes through `0x00476320`, `0x00476780`, and `0x00476c20`. The same pass also formats selected-company ownership text and several numeric card values before publishing them into the live `StockBuy.win` widget tree. Current grounded owner correlation is the `StockBuy.win` constructor `0x0050c290`, which wires this function into the control family as one of the primary refresh callbacks.","objdump + local disassembly + constructor correlation + active-profile correlation + metric-card correlation" +0x0050ae50,1810,shell_stock_buy_window_render_selected_company_summary_panel,shell,thiscall,inferred,objdump + local disassembly + constructor correlation,3,"Broad renderer for the selected-company summary panel beneath the shell-side `StockBuy.win` family. The helper resolves the current selected company through `0x00518140(0x0062be10, company_id)`, resolves the currently selected chairman row through `0x00477860(0x006ceb9c, 0x006d19f4)`, chooses one of the cached panel roots at `0x006d19e8/0x006d19ec`, and then formats a large mixed text-plus-metric surface using company-side share and stock helpers such as `0x00423eb0`, `0x00426b10`, and `0x00426ef0` together with localized ownership-status ids `0x0e0d/0x0e0e/0x0e0f`. Current grounded owner correlation is the `StockBuy.win` constructor `0x0050c290`, which binds this body to control `0x3a9a` with selector `0x7a`, so the safest current read is the main selected-company summary renderer rather than another narrow status-line helper.","objdump + local disassembly + constructor correlation + selected-company correlation + summary-panel correlation" +0x0050b910,216,shell_stock_buy_window_publish_selected_company_ownership_status_line,shell,thiscall,inferred,objdump + local disassembly + constructor correlation,3,"Publishes one selected-company ownership or status line for the shell-side `StockBuy.win` family. The helper first validates current selected company id `0x00622b00` against company-count query `0x00429a50`, resolves the live company record through `0x00429a90`, and then formats one of three localized text records `0x0e10`, `0x0e11`, or `0x0e12` depending on company owner field `[company+0x3b]` relative to the currently selected chairman id `[0x006cec78+0x25]`. When the company has an owning profile it also queries that owner label through `0x00426ef0` and appends the company display name from `[company+0x04]` before publishing the final line through shell presenter `0x00538c70`. Current grounded owner correlation is the `StockBuy.win` constructor `0x0050c290`, which wires this helper into the live control family.","objdump + local disassembly + constructor correlation + selected-company correlation + ownership-status correlation" +0x0050ba00,57,shell_stock_buy_window_refresh_selected_company_summary_tail,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Internal summary-refresh tail beneath the shell-side `StockBuy.win` family. The helper republishes current selected company id `0x00622b00` through `shell_stock_buy_window_publish_selected_company_or_none_and_refresh_affordance` `0x0050a6d0`, invalidates the standard `StockBuy.win` shell triple through `0x0053fe00`, and then republishes companion control `0x3a9a` through `0x00540120` with fixed selector `0x8b`. Current grounded callers are the mode-`0x0b` stock-buy refresh wrapper `0x0050c130` and the broader company-selection setter `0x0050c470`, so this is the clearest current shared refresh tail for the selected-company summary pane.","objdump + caller inspection + local disassembly + selected-company correlation + summary-pane correlation" +0x0050bac0,293,shell_stock_buy_window_destroy,shell,thiscall,inferred,objdump + local disassembly + constructor correlation,4,"Destructor for the shell-side `StockBuy.win` family rooted at `0x006d19f0`. The helper restores vtable `0x005d18f0`, releases the cached widget or selector roots at `0x006d19d8..0x006d19ec` through `0x0053c000`, walks the live company collection under `0x006d4020+0x429b4` to release the per-company stock-data handles cached in `0x006d1748`, invalidates the standard shell triple `(0x3b60, 0x3e7f, 0)` plus the stock-data control `0x3e4e`, clears singleton `0x006d19f0`, and then tails into the common shell-object teardown `0x0053f7d0`. This is the clear destructor-side counterpart to `shell_stock_buy_window_construct` `0x0050c290`.","objdump + local disassembly + constructor correlation + singleton correlation + destructor correlation" +0x0050bbe0,1357,shell_stock_buy_window_handle_message,shell,thiscall,inferred,objdump + local disassembly + constructor correlation,4,"Primary message dispatcher for the shell-side `StockBuy.win` family. Under message `0xcb`, controls `0x3aa1..0x3aa3` wrap the selected company id in `0x00622b00` across the live company count, controls `0x3d54..0x3db7` select one company row through `0x004299f0` and then re-enter `shell_stock_buy_window_publish_selected_company_or_none_and_refresh_affordance` `0x0050a6d0`, controls `0x3afc..0x3b5f` select one chairman row into `0x006d19f4` and mirror that chosen profile back into the live scenario-selected chairman path when world-mode gates allow it, and controls `0x3aad..0x3ab2` write one incoming byte straight into the toggle band `0x00622b04..0x00622b09`. Under message `0xca`, the buy row band `0x3c8c..0x3cef` resolves one company slot, optionally raises tutorial or confirmation modals, and on success commits the rounded buy through `0x00477110` before re-entering `0x0050a6a0`; the sell row band `0x3cf0..0x3d53` mirrors the same pattern through `0x00476460`; and control `0x3a9a` routes into the same shared summary family beside `0x0050ba00`. Current grounded owner correlation is the constructor `0x0050c290`, which wires the surrounding control family onto this dispatcher.","objdump + local disassembly + constructor correlation + control-band correlation + buy-sell row correlation + selected-company correlation" +0x0050c130,21,shell_stock_buy_window_refresh_if_detail_panel_mode_0x0b_is_active,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Small shell-side refresh wrapper for the live `StockBuy.win` detail-panel mode `0x0b`. The helper re-enters the shared shell state tick `0x00563250`, and when singleton `0x006d19f0` is live it jumps into the broader stock-buy refresh tail at `0x0050ba00` instead of returning directly. Current grounded callers are the two mode-sensitive shell refresh wrappers at `0x0043609f` and `0x00436139`, both of which first verify that the detail-panel manager `0x006d0818` is currently in mode `0x0b`.","objdump + caller inspection + local disassembly + detail-panel-mode correlation + stock-buy refresh correlation" +0x0050c150,155,shell_stock_buy_window_apply_payload_buy_rounded_company_block,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Applies one payload-driven buy transaction beneath the shell-side `StockBuy.win` family. The helper treats payload dwords `[this+0x00]` and `[this+0x04]` as chairman-profile id and company id, resolves the live chairman record through `0x00518140`, derives the rounded buy block through `0x00476e50(company_id,1)`, optionally emits the local selected-chairman shell cue through `0x0045ea20(0x36,1.0)` plus `0x0053f000(1,0,0)`, and then commits the transaction through `0x00477110(company_id, block, 1, 0)`. The tail re-enters the shared shell tick `0x00563250` and refresh path through `0x0053fe00` when the `StockBuy.win` singleton at `0x006d19f0` is still live. Current grounded callers are the multiplayer selector wrapper `0x0046c9f0` and the local stock-buy message family, so this is the clearest current payload-side rounded buy-block commit owner.","objdump + local disassembly + caller inspection + rounded-trade correlation + shell-cue correlation" +0x0050c1f0,155,shell_stock_buy_window_apply_payload_sell_rounded_company_block,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Applies one payload-driven sell transaction beneath the shell-side `StockBuy.win` family. The helper treats payload dwords `[this+0x00]` and `[this+0x04]` as chairman-profile id and company id, resolves the live chairman record through `0x00518140`, derives the rounded sell block through `0x00476e50(company_id,0)`, optionally emits the local selected-chairman shell cue through `0x0045ea20(0x37,1.0)` plus `0x0053f000(1,0,0)`, and then commits the transaction through `0x00476460(company_id, block, 1, 0)`. The tail mirrors the same shared shell tick `0x00563250` and refresh path through `0x0053fe00` used by the buy-side sibling `0x0050c150`. Current grounded callers are the multiplayer selector wrapper `0x0046ca10` and the local stock-buy message family, so this is the clearest current payload-side rounded sell-block commit owner.","objdump + local disassembly + caller inspection + rounded-trade correlation + shell-cue correlation" 0x0050c290,624,shell_stock_buy_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `StockBuy.win` family. The constructor installs vtable `0x005d18f0`, binds `StockBuy.win` plus the companion `GameWindow.imb` resource through `0x0053d110` and `0x0053fa50`, seeds live singleton `0x006d19f0`, scans the chairman-profile collection at `0x006ceb9c` to identify the currently selected chairman index in `0x006d19f4`, seeds several cached list or selector handles at `0x006d19d8..0x006d19ec`, and wires the control family through callbacks such as `0x0050a730`, `0x0050a570`, and `0x0050b910`. Current grounded caller is the detail-panel manager branch at `0x004ddeaa`, which keeps this on the shell finance/detail side rather than the company-detail action dispatcher itself.","objdump + strings + detail-manager correlation + collection-scan correlation + control-wiring correlation + singleton correlation" +0x0050c470,103,shell_stock_buy_window_clamp_selected_company_and_rebuild_summary,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Clamps the current selected company id for the shell-side `StockBuy.win` family and rebuilds the selected-company summary pane. The helper validates global company id `0x00622b00` against company-count query `0x00429a50`, stores the clamped id back into that same global, republishes control `0x3a9b` through `0x00540120`, invalidates the standard shell triple through `0x0053fe00`, and then re-enters the shared summary-refresh tail `0x0050ba00`. Current grounded owner correlation is the same local stock-buy refresh family rooted at `0x0050c290`; the helper is also the strongest current direct caller of `0x0050ba00`.","objdump + local disassembly + caller inspection + selected-company correlation + summary-refresh correlation" +0x0050c4e0,19,shell_store_ten_dword_chairmanship_takeover_vote_bitmap_state,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Tiny cache setter for local chairmanship-takeover vote bitmap state rooted at `0x006d1a08`. The helper copies exactly ten dwords from the caller-supplied buffer into that global block. Current grounded caller is multiplayer selector body `0x00471fd0`, which builds two ten-slot bitmap arrays from selector-`0x4b` payload bytes `[+0x04]`, `[+0x05]`, and bitmask dword `[+0x06]` before forwarding the resulting block here immediately ahead of `shell_resolve_chairmanship_takeover_vote_and_commit_outcome` `0x0050c940`.","objdump + caller inspection + local disassembly + selector-0x4b correlation + takeover-vote-state correlation" 0x004dfd70,57,shell_game_window_destroy,shell,thiscall,inferred,objdump + strings + caller xrefs,4,"Destructor for the shell-side `Game.win` detail window rooted at `0x006d0818`. It restores vtable `0x005d0eb8`, clears the singleton global, releases the child panel or selector object stored at `[this+0x8c]` through `0x004dd950`, and then tails into the common shell object destructor path. `shell_transition_mode` now uses this as the old-mode teardown branch when leaving mode `1`.","objdump + strings + caller xrefs + destructor correlation" 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 @@ -821,9 +1147,74 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004e0e40,75,shell_ensure_game_uppermost_window,shell,cdecl,inferred,objdump + strings + caller xrefs,4,Ensures the world-facing GameUppermost.win overlay rooted at 0x006d0820 exists. When absent it allocates a 0xae-byte window object constructs it through game_uppermost_window_construct at 0x004e0b20 stores the result globally and publishes it through the shell runtime at 0x006d401c via 0x00538e50. A grounded caller sits in the shell_transition_mode path near 0x004831c0 immediately after the GameMessage.win bring-up branch which ties this overlay to world-mode entry rather than generic shell UI.,objdump + strings + caller xrefs 0x004fe120,14,shell_has_settings_window,shell,cdecl,inferred,objdump,4,Returns whether the shared settings window object rooted at 0x006d1350 is currently live. The fileopt settings escape branch and direct shell command wrappers both gate on this before opening SettingsWindow.win again.,objdump + caller xrefs 0x004fe130,11,shell_mark_settings_window_dirty,shell,cdecl,inferred,objdump + global-state inspection + frame-caller inspection,4,"Tiny dirty-latch setter paired with `shell_has_settings_window`. The helper stores `1` into `0x006d1360`, which current nearby call patterns treat as the `SettingsWindow.win` refresh or service request latch once the live settings singleton at `0x006d1350` exists. Current grounded callers include the post-step shell-window service ladder inside `simulation_frame_accumulate_and_step_world` `0x00439140`, and the same latch is also cleared during settings-window open or rebuild paths near `0x00501e50`.","objdump + global-state inspection + frame-caller inspection + settings-window open-path correlation" -0x00500640,487,shell_settings_window_construct,shell,thiscall,inferred,objdump + strings,4,Constructs the shared SettingsWindow.win object later stored at 0x006d1350. The helper binds the SettingsWindow.win resource through 0x0053fa50 allocates a page-selection helper at 0x006d1358 walks the 13-entry category table rooted at 0x00622870 and populates the resulting shell control tree with the page labels and ordering data before the window is shown.,objdump + strings +0x004fd730,415,shell_settings_window_refresh_miscellaneous_input_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation,3,"Refreshes the later `Miscellaneous` page selected by page index `11` in the `SettingsWindow.win` category table. The helper first republishes container controls `0x7546`, `0x7547`, `0x7593`, `0x7594`, `0x759f`, and `0x75a0`, installs four option labels from the paired localized-id table `0x006228d8/0x006228dc` into control `0x7546`, clamps shell field `[0x006cec74+0x10c]` into the visible selector slot for that same control, then mirrors additional shell and world fields through controls `0x7547`, `0x7593`, `0x7594`, `0x759f`, and `0x75a0` using the current values at `[0x006d4024+0x1146d7]`, `[0x006cec74+0x283]`, `[0x006cec74+0x28b]`, `[0x006cec74+0x311]`, and `[0x006cec74+0x315]`. The exact player-facing semantics of those fields are still open, but the page ownership and control strip are now grounded.","objdump + local disassembly + settings-window page correlation + control-strip correlation" +0x004fd8d0,104,shell_settings_window_refresh_sandbox_options_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the `Sandbox Options` page selected by page index `12` in the `SettingsWindow.win` category table. The helper republishes container control `0x759e`, installs five localized option labels from `0x00622a08` into that control, and mirrors the current world-side selector from `[0x006d4024+0x11474e]` back into the visible selection slot. This is the current direct page-refresh owner for the page rooted at localized id `0x55d` `Sandbox Options`, even though the deeper semantics of the underlying selector values are still open.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + selector-mirror correlation" +0x004fd940,223,shell_settings_window_refresh_dialogs_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the `Dialogs` page selected by page index `10` in the `SettingsWindow.win` category table. The helper republishes controls `0x7545` and `0x758c..0x7590`, mirrors one shell scalar from `[0x006cec74+0xf8]` into control `0x7545`, and then writes the five dialog-toggle booleans derived from shell fields `[0x006cec74+0x26b]`, `[+0x26f]`, `[+0x273]`, `[+0x277]`, and `[+0x27b]` into controls `0x758c` through `0x7590`. This is therefore the direct dialogs-page refresh owner rather than a generic checkbox helper.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + toggle-band correlation" +0x004fda20,368,shell_settings_window_refresh_gameplay_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,3,"Refreshes the `Gameplay` page selected by page index `0` in the `SettingsWindow.win` category table. The helper republishes container controls `0x7548`, `0x7591`, `0x7592`, `0x7599`, `0x759c`, and `0x7544`, installs six option labels from `0x006228f8` into control `0x7548` and three paired labels from `0x00622910/0x00622914` into control `0x7591`, then mirrors several current shell or world values through those controls from `[0x006cec74+0xf4]`, `[+0x22f]`, `[+0x263]`, `[+0x2cc]`, `[+0x309]`, `[+0x0a8]`, and `[0x006d4024+0x114742]`. The exact gameplay-setting meanings of the individual fields are still open, but the page ownership and control strip are now grounded.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + control-strip correlation" +0x004fdb90,480,shell_settings_window_refresh_sound_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the `Sound` page selected by page index `1` in the `SettingsWindow.win` category table. The helper first queries the active sound backend through `0x005314b0`; when no backend is available it disables the main controls `0x7534` and `0x753f`. On the live-backend path it republishes control families `0x7551` and `0x754f`, enumerates six backend labels from `0x006229e4`, mirrors one backend selection through `0x00531640/0x005316d0`, installs the localized sample-rate or quality label rooted at id `0x584`, and then writes the derived backend scalar or enable state back into the visible controls. This is now the direct sound-page refresh owner rather than an unnamed backend probe loop.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + audio-backend correlation" +0x004fd550,250,shell_settings_window_refresh_draw_distance_companion_controls,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + localized-label correlation,4,"Refreshes the companion selector strip beneath the main `Draw Distance` page choice. The helper republishes controls `0x7566`, `0x7596`, `0x7560`, `0x7562`, and `0x7564`, then mirrors the current shell graphics-option slots selected through `0x00484ae0(8)`, `0x00484ae0(0x0d)`, `0x00484ae0(7)`, and `0x00484ae0(9)` back into those controls. The `0x7566` label family uses the localized quality table rooted at ids `0x578..0x57d` plus `0x269`, and control `0x7596` shows the inverted small scalar `4 - option(0x0d)`. Current grounded caller is `shell_settings_window_refresh_draw_distance_page` `0x004feb20`, and the local graphics-selector callback strip also re-enters this helper, so the safest current read is the draw-distance companion-control refresh owner rather than a generic selector helper.","objdump + local disassembly + settings-window page correlation + localized-label correlation + selector-mirror correlation" +0x004fd650,211,shell_settings_window_refresh_textures_companion_controls,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + selector-mirror correlation,4,"Refreshes the companion selector strip beneath the main `Textures` page choice. The helper republishes controls `0x756e`, `0x756a`, `0x756c`, and `0x7570`, then mirrors the current shell graphics-option slots selected through `0x00484ae0(6)`, `0x00484ae0(4)`, `0x00484ae0(5)`, and `0x00484ae0(3)` into those visible controls. Current grounded caller is the textures-side selector callback path immediately below the settings dispatcher, so this is the strongest current read for the textures companion-control refresh helper rather than a generic selector mirror.","objdump + local disassembly + settings-window page correlation + selector-mirror correlation" +0x004fe770,490,shell_settings_window_refresh_graphics_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the top-level `Graphics` page selected by page index `2` in the `SettingsWindow.win` category table. The helper mirrors world byte `[0x006d4024+0x114226]` into control `0x7554`, probes the graphics backend rooted at `0x00ccbb20` through `0x0053ef60` and `0x0053ef70` to derive the availability state for controls `0x757c` and `0x759a`, mirrors shell field `[0x006cec74+0x2c3]` into control `0x7595`, mirrors world dword `[0x006d4024+0x114206]` into control `0x7556`, conditionally formats the graphics-range fields through `0x0051fd40` and `0x0051fd60` into controls `0x7555` and `0x7578` when graphics mode byte `[0x006d4024+0x114226]` is nonzero, and then installs six localized labels from `0x00622964` into control `0x7557` plus the current selector derived from `0x00484ae0(0)`. This is therefore the direct graphics-page refresh owner rather than a generic backend capability probe.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + graphics-backend correlation" +0x004fe960,446,shell_settings_window_refresh_model_detail_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the `Model Detail` page selected by page index `3` in the `SettingsWindow.win` category table. The helper installs five localized labels from `0x00622940` into control `0x755a` and mirrors the current selector derived from `0x00484ae0(0x0a)` into that control, installs four localized labels from `0x00622954` into control `0x755b` and mirrors the selector from `0x00484ae0(0x0b)`, conditionally republishes control `0x7558` from world float `[0x006d4024+0x1146b9]` when the graphics-mode byte `[0x006d4024+0x114226]` is nonzero, mirrors world byte `[0x006d4024+0x1146eb]` into control `0x755c`, mirrors world byte `[0x006d4024+0x1146e9]` into control `0x755d`, mirrors world dword `[0x006d4024+0x114697]` into control `0x755e`, and republishes the shared six-label family at `0x7557` through the local companion helper `0x004fe4c0`. This is therefore the direct model-detail-page refresh owner rather than another generic graphics helper.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + selector-family correlation" +0x004fe4c0,560,shell_settings_window_rebuild_custom_resolution_list_control,shell,thiscall,inferred,objdump + local disassembly + settings-window callback correlation + string-format inspection,4,"Rebuilds the custom-resolution list control `0x7553` used by the graphics-side settings family. The helper clears the list, walks the live display-mode table rooted at `[0x006d4024+0x34]` with count `[+0x30]` through `0x0051f830`, filters modes to the bounded range `640x480 .. 1600x1200`, deduplicates repeated width-height pairs unless the earlier retained mode uses a non-`0x20` third lane, formats the surviving entries through the literal `%1x%2` at `0x005d14b0`, appends them to control `0x7553`, and finally mirrors the selected row index back into field `0x66`. Current grounded dispatcher-side caller is the graphics/custom-resolution settings branch at `0x004ffbdc`, which first persists the display-runtime block through `0x0051eea0` and then re-enters this helper. This is therefore the custom-resolution list rebuild owner rather than a generic mode-enumerator.","objdump + local disassembly + settings-window callback correlation + string-format inspection + display-mode-table correlation" +0x004fe6f0,53,shell_settings_window_refresh_draw_distance_primary_selector,shell,thiscall,inferred,objdump + local disassembly + settings-window callback correlation,4,"Small selector-mirror helper for the main `Draw Distance` control `0x755f`. The helper reads shell graphics option slot `1` through `0x00484ae0`, remaps non-`-1` selections through the compact table at `0x00622990`, and republishes the resulting visible selector index into field `0x66` on control `0x755f`. Current grounded caller is the graphics-settings callback branch at `0x004ff1f3` immediately after `shell_set_graphics_option_with_fanout` stores option `9`, so this is the draw-distance primary-selector refresh sibling rather than a generic table lookup.","objdump + local disassembly + settings-window callback correlation + selector-remap correlation" +0x004fe730,53,shell_settings_window_refresh_textures_primary_selector,shell,thiscall,inferred,objdump + local disassembly + settings-window callback correlation,4,"Small selector-mirror helper for the main `Textures` control `0x7569`. The helper reads shell graphics option slot `2` through `0x00484ae0`, remaps non-`-1` selections through the same compact table at `0x00622990`, and republishes the resulting visible selector index into field `0x66` on control `0x7569`. Current grounded caller is the neighboring graphics-settings callback branch at `0x004ff30c` immediately after `shell_set_graphics_option_with_fanout` stores option `3`, so this is the textures primary-selector refresh sibling rather than a generic table lookup.","objdump + local disassembly + settings-window callback correlation + selector-remap correlation" +0x004feb20,176,shell_settings_window_refresh_draw_distance_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the `Draw Distance` page selected by page index `4` in the `SettingsWindow.win` category table. The helper installs the shared six-label selector family from `0x00622964` into control `0x755f`, mirrors the current selector derived from `0x00484ae0(1)` into that control, re-enters `0x004fd550` for the paired companion refresh, and mirrors world byte `[0x006d4024+0x1146b8]` into control `0x7568`. This is now the direct draw-distance-page refresh owner rather than a generic selector helper.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + selector-family correlation" +0x004febd0,112,shell_settings_window_refresh_textures_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the `Textures` page selected by page index `5` in the `SettingsWindow.win` category table. The helper installs the shared six-label selector family from `0x00622964` into control `0x7569`, mirrors the current selector derived from `0x00484ae0(2)` into that control, and re-enters `0x004fe730` to republish the compact visible selector state. This is now the direct textures-page refresh owner rather than another generic selector helper.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + selector-family correlation" +0x004fdd70,432,shell_settings_window_refresh_graphics_misc_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation,3,"Refreshes the first `Miscellaneous` page selected by page index `6` in the `SettingsWindow.win` category table. The helper republishes control families `0x7573` and `0x7574`, installs three paired localized option rows from ids `0xe18..0xe1d`, mirrors one world selector from `[0x006d4024+0x114736]`, mirrors another from `[0x006d4024+0x1146b3]`, compares world float `[0x006d4024+0x1146af]` against the fixed threshold at `0x005c8628`, mirrors world byte `[0x006d4024+0x1146a8]`, mirrors world byte `[0x006d4024+0x1146e3]`, and finally mirrors one shell-side gate derived through `0x00484af0(0x0c)` into control `0x7586`. The exact player-facing names of those toggles remain open, but the page ownership and world-field strip are now grounded.","objdump + local disassembly + settings-window page correlation + control-strip correlation + world-field correlation" +0x004fdf20,164,shell_settings_window_refresh_scrolling_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the `Scrolling` page selected by page index `8` in the `SettingsWindow.win` category table. The helper mirrors four shell-side scalar settings from `[0x006cec74+0x114]`, `[+0x118]`, `[+0x11c]`, and `[+0x120]` into controls `0x757d`, `0x757f`, `0x7581`, and `0x7584`, and then mirrors the boolean companion derived from `[0x006cec74+0x120]` into control `0x7585`. This is therefore the direct scrolling-page refresh owner rather than a generic slider helper.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + shell-scalar correlation" +0x004fdfd0,421,shell_settings_window_refresh_camera_controls_page,shell,thiscall,inferred,objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation,4,"Refreshes the `Camera Controls` page selected by page index `9` in the `SettingsWindow.win` category table. The helper republishes control families `0x7587` and `0x7588`, installs twenty-five localized labels from `0x00620dd8` into control `0x7587`, mirrors the current shell-side selector from `[0x006cec74+0x233]` plus companion `[+0x237]` back into that control, then installs ten localized labels `0x0a9f..0x0aa8` from `0x00620e3c` into control `0x7588` and mirrors the paired shell-side selector from `[0x006cec74+0x23b]` plus companion `[+0x23f]`. The current label tables now ground `0x7587` as the day-night cycling selector rooted at `Normal day/night cycling` through `Frozen at 11pm`, and `0x7588` as the weather-cycling selector rooted at `Normal weather cycling` through `Frozen at storms`. This is therefore the direct camera-controls page refresh owner rather than a partially anonymous page helper.","objdump + local disassembly + settings-window page correlation + RT3.lng page-label correlation + label-table correlation + selector-family correlation" +0x004fec60,383,shell_settings_window_rebuild_hotkeys_list_control_from_sorted_binding_report,shell,thiscall,inferred,objdump + local disassembly + settings-window correlation,4,"Rebuilds one `SettingsWindow.win` list control from the current sorted hotkey report. The helper first resolves the live settings window shell object through control id `0x757a`, caches the current selection dword from `[control+0x1e2]`, destroys and reallocates the temporary list owner at `0x006d1354`, and seeds that owner as an `0x88`-stride list model through `0x00518b90`. It then iterates the current binding report through `shell_input_binding_report_iterate_next_entry_in_sorted_priority_order` `0x0045f250`, formats the action-stem column and the display-label column into local strings, appends each row through the list-model vtable at `[0x006d1354]+0x04`, and republishes the finished row into the live window through `0x00540120(control_id=0x757a, field_id=0x88, ...)`. After the rebuild it restores the saved selection through `0x00561840`. Current grounded caller is the `SettingsWindow.win` hotkeys side around `0x004fed16`, so the safest current read is the hotkeys-list rebuild body rather than a generic shell list refresher.","objdump + local disassembly + settings-window correlation + list-model correlation + hotkey-report correlation" +0x004fede0,5680,shell_settings_window_handle_message,shell,thiscall,inferred,objdump + local disassembly + settings-window correlation,3,"Primary message or command dispatcher for the shared `SettingsWindow.win` singleton at `0x006d1350`. The handler normalizes incoming control ids into the `0x8ab7..` band and switches through the local jump tables at `0x004ff47c` and `0x004ff4c0`. The fully grounded hotkeys side now does three concrete things: one branch at `0x00500147` hard-resets the live binding registry through `shell_input_binding_registry_initialize_roots_seed_defaults_and_optionally_import_hotkeys_file` `0x00461120(0)`, immediately rewrites `hotkeys\\hotkeys.txt` through `shell_input_write_hotkeys_report_file` `0x0045f550`, and rebuilds the hotkeys list through `shell_settings_window_rebuild_hotkeys_list_control_from_sorted_binding_report` `0x004fec60`; another branch at `0x00500186..0x0050022b` resolves the selected hotkeys row from control `0x757a` and model `0x006d1354`, validates the requested action bucket through `shell_input_binding_descriptor_query_bucket_key_for_action_id_when_mode_mask_is_singular` `0x0045ed90`, skips the Enter and Escape keys, expands the compact modifier code through `shell_input_binding_expand_compact_mode_code_to_registry_mask` `0x0045ed70`, commits the rebucket through `shell_input_binding_registry_rebucket_entry_by_stem_to_action_id_and_mode_mask` `0x0045ef00`, and then rewrites the report file plus rebuilds the same list; and the surrounding settings cases toggle several persisted shell or world flags such as `[0x006cec74+0x247]`, `[0x006cec74+0x24b]`, `[0x006cec74+0x243]`, `[0x006cec74+0x120]`, and world byte `[0x006d4024+0x1146e3]`, forwarding their persistence or refresh tails through `0x00484910`, `0x0051eea0`, `0x00531560`, and `0x0051f510`. The full switch table is still broader than the current annotation, but this is now safely the `SettingsWindow.win` message owner rather than an unplaced UI body.","objdump + local disassembly + settings-window correlation + hotkeys-branch correlation + toggle-branch correlation" +0x004fe140,32,shell_graphics_backend_query_primary_or_fallback_status_nonzero,shell,thiscall,inferred,objdump + settings-window caller correlation,3,"Composite predicate over the graphics backend. The helper returns true when either `graphics_backend_query_primary_status_dword_18` `0x0053ef60` is nonzero or `graphics_backend_query_both_status_slots_clear` `0x0053ef70` returns true; otherwise it returns false. Current grounded caller is the timer-gated graphics settings service branch near `0x004ffb1d`, which uses this predicate to choose between the paired backend follow-on calls `0x0053f170` and `0x0053f2c0` before republishing the graphics page.","objdump + settings-window caller correlation + backend-branch correlation" +0x004fe160,76,shell_audio_backend_change_follow_on_refresh,shell,cdecl,inferred,objdump + sound-settings caller correlation,3,"Follow-on refresh path used after the sound-backend selector changes. The helper first re-enters two subordinate runtime owners rooted at `0x006cec78` through `0x0040b7d0` and `0x0040b830` when that global is live, then re-enters shell object `[0x006cec74+0x14]` through `0x004686d0`, and finally resolves one shell controller subobject through `0x0051f070` before conditionally tail-calling `0x00563ed0`. Current grounded caller is `shell_settings_window_handle_sound_backend_selection_change` `0x004fefb0`, so the safest current read is the sound-backend follow-on refresh owner rather than a general shell service helper.","objdump + sound-settings caller correlation + global-owner correlation" +0x004fe270,84,shell_apply_custom_resolution_tuple_if_changed_and_persist,shell,cdecl,inferred,objdump + graphics-settings callback correlation,4,"Helper beneath the custom-resolution selector path. The function rejects re-entrant refreshes, compares the requested packed width-height tuple in `EDX` against the current live display-mode tuple at `[0x006d4024+0x34 + mode_index*0x15]`, and when they differ re-enters `shell_apply_display_mode_tuple_and_optional_graphics_mode` `0x005206b0` with the new width and height before persisting the larger display-runtime block through `0x0051eea0`. Current grounded caller is `shell_settings_window_handle_custom_resolution_selection_change` `0x004ff070`.","objdump + graphics-settings callback correlation + display-mode-apply correlation + persistence correlation" +0x004fe2d0,220,shell_apply_graphics_primary_selector_and_republish_backend_controls,shell,cdecl,inferred,objdump + graphics-settings callback correlation,4,"Helper beneath the top-level graphics selector callback. The function rejects re-entrant refreshes, remaps the chosen visible selector through the compact table `0x006211d0`, stores it through `shell_set_graphics_option_with_fanout` `0x00485060`, re-arms the graphics service through `0x00484910(1)`, and then repopulates the backend-dependent controls `0x757c` and `0x759a` using the live graphics backend via `0x0053ef60` and `0x0053ef70`. Current grounded caller is `shell_settings_window_handle_graphics_primary_selector_change` `0x004ff0d0`.","objdump + graphics-settings callback correlation + backend-control republish correlation" +0x004fe3b0,75,shell_apply_draw_distance_selector_and_refresh_companion_controls,shell,cdecl,inferred,objdump + graphics-settings callback correlation,4,"Helper beneath the draw-distance selector callback. The function rejects re-entrant refreshes, remaps the chosen visible selector through table `0x006211d0`, stores it through `shell_set_graphics_option_with_fanout` `0x00485060` as option family `1`, raises the local refresh latch `0x006d135c`, refreshes the draw-distance companion strip through `0x004fd550`, clears the latch again, and then re-arms the graphics service through `0x00484910(1)`. Current grounded caller is `shell_settings_window_handle_draw_distance_selector_change` `0x004ff1b0`.","objdump + graphics-settings callback correlation + companion-refresh correlation" +0x004fe400,75,shell_apply_textures_selector_and_refresh_companion_controls,shell,cdecl,inferred,objdump + graphics-settings callback correlation,4,"Helper beneath the textures selector callback. The function rejects re-entrant refreshes, remaps the chosen visible selector through table `0x006211d0`, stores it through `shell_set_graphics_option_with_fanout` `0x00485060` as option family `2`, raises the local refresh latch `0x006d135c`, refreshes the textures companion strip through `0x004fd650`, clears the latch again, and then re-arms the graphics service through `0x00484910(1)`. Current grounded caller is the textures-selector change path adjacent to `0x004ff2e0`.","objdump + graphics-settings callback correlation + companion-refresh correlation" +0x004fefb0,179,shell_settings_window_handle_sound_backend_selection_change,shell,thiscall,inferred,objdump + local disassembly + settings-window callback correlation,4,"Settings-window callback for the sound-backend selector family. The helper rejects `-1` selections and re-entrant refreshes, updates the active sound-backend selection on shell service `0x006d402c` through `0x00532230`, republishes the visible selector on control `0x7551` when the backend normalizes differently through `0x00531640`, mirrors the derived availability flag from `0x005316d0` into control `0x7550`, stores the resolved backend index into world field `[0x006d4024+0x114706]`, triggers the sound-runtime follow-on through `0x004fe160`, and then persists the larger display-runtime block through `0x0051eea0` plus the adjacent save tail `0x00484910`. Current grounded control family is the `Sound` page row rooted at `0x7551/0x7550`, which makes this the backend-selection change owner rather than a generic shell list callback.","objdump + local disassembly + settings-window callback correlation + sound-backend correlation + persistence-tail correlation" +0x004ff070,85,shell_settings_window_handle_custom_resolution_selection_change,shell,cdecl,inferred,objdump + local disassembly + settings-window callback correlation,4,"Settings-window callback for the custom-resolution list under control `0x7553`. The helper rejects `-1` selections and re-entrant refreshes, decodes the packed width-height pair from the incoming selector payload, compares it against the current live display-mode tuple at `[0x006d4024+0x34 + mode_index*0x15]`, and when the pair changed re-enters `shell_apply_display_mode_tuple_and_optional_graphics_mode` `0x005206b0` with the new width and height. This is therefore the compact custom-resolution selection owner rather than another generic selector wrapper.","objdump + local disassembly + settings-window callback correlation + display-mode-apply correlation" +0x004ff0d0,220,shell_settings_window_handle_graphics_primary_selector_change,shell,cdecl,inferred,objdump + local disassembly + settings-window callback correlation,4,"Settings-window callback for the top-level `Graphics` page selector family rooted at the compact remap table `0x006211d0`. The helper rejects `-1` selections and re-entrant refreshes, remaps the chosen visible selector through `shell_set_graphics_option_with_fanout` `0x00485060`, re-arms the graphics service through `0x00484910(1)`, and then republishes the backend-dependent controls `0x757c` and `0x759a` using `0x0053ef60` and `0x0053ef70` before returning. This is now the clearest owner for the graphics primary-selector change branch rather than an anonymous settings callback.","objdump + local disassembly + settings-window callback correlation + graphics-backend republish correlation" +0x004ff1b0,115,shell_settings_window_handle_draw_distance_selector_change,shell,cdecl,inferred,objdump + local disassembly + settings-window callback correlation,4,"Settings-window callback for the main `Draw Distance` selector. The helper packages the chosen visible selector through `shell_set_graphics_option_with_fanout` `0x00485060` as option slot `9`, skips further work when the local refresh latch `0x006d135c` is armed, and otherwise re-enters `shell_settings_window_refresh_draw_distance_primary_selector` `0x004fe6f0`. Current grounded dispatcher-side callsite sits at `0x004ff1f3`, which makes this the draw-distance selector-change owner rather than a generic option setter.","objdump + local disassembly + settings-window callback correlation + selector-refresh correlation" +0x004ff2e0,52,shell_settings_window_handle_textures_selector_change,shell,cdecl,inferred,objdump + local disassembly + settings-window callback correlation,4,"Settings-window callback for the main `Textures` selector. The helper packages the chosen visible selector through `shell_set_graphics_option_with_fanout` `0x00485060` as option slot `3`, skips the follow-on when local latch `0x006d135c` is armed, and otherwise re-enters `shell_settings_window_refresh_textures_primary_selector` `0x004fe730`. Current grounded dispatcher-side callsite sits at `0x004ff30c`, which makes this the textures selector-change owner rather than another compact remap stub.","objdump + local disassembly + settings-window callback correlation + selector-refresh correlation" +0x004ff58a,33,shell_settings_window_toggle_misc_input_page_display_runtime_byte_1146d7,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for the later `Miscellaneous` input page field mirrored from display-runtime byte `[0x006d4024+0x1146d7]` into control `0x7547`. The helper flips the byte and persists the display-runtime block through `0x0051eea0`. This is therefore the direct toggle owner for that page-owned byte rather than an anonymous dispatcher leaf.","objdump + local disassembly + settings-window page correlation + persistence correlation" +0x004ff5b6,37,shell_settings_window_toggle_misc_input_page_shell_flag_28b,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for the later `Miscellaneous` input page field `[0x006cec74+0x28b]`, currently mirrored into control `0x7594`. The helper flips the dword between `0` and `1`, raises the shared shell config-save tail through `0x00484910(1)`, and returns. Current evidence keeps the label field-based because the exact caption is still open.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x004ff5e6,70,shell_settings_window_toggle_misc_input_page_shell_flag_283_and_refresh_game_window_affordance,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,4,"Toggle branch for the later `Miscellaneous` input page field `[0x006cec74+0x283]`, currently mirrored into control `0x7593`. The helper flips the dword, persists shell config through `0x00484910(1)`, and when the live `Game.win` singleton at `0x006d0818` exists it republishes one page-local affordance through `0x004dd8d0` using the new boolean value. This is therefore the direct owner for the `+0x283` settings toggle plus its `Game.win` follow-on refresh.","objdump + local disassembly + settings-window page correlation + config-save correlation + Game.win follow-on correlation" +0x004ff637,37,shell_settings_window_toggle_dialogs_page_shell_scalar_f8,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for the `Dialogs` page scalar `[0x006cec74+0xf8]`, mirrored into control `0x7545`. The helper flips the dword between `0` and `1`, persists shell config through `0x00484910(1)`, and returns. Current evidence keeps the label structural because the caption is not yet grounded.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x004ff667,37,shell_settings_window_toggle_dialogs_page_flag_26b,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for `Dialogs` page field `[0x006cec74+0x26b]`, currently mirrored into the checkbox strip rooted at control `0x758c`. The helper flips the dword and persists shell config through `0x00484910(1)`.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x004ff697,37,shell_settings_window_toggle_dialogs_page_flag_26f,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for `Dialogs` page field `[0x006cec74+0x26f]`, currently mirrored into the checkbox strip rooted at control `0x758d`. The helper flips the dword and persists shell config through `0x00484910(1)`.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x004ff6c7,37,shell_settings_window_toggle_dialogs_page_flag_273,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for `Dialogs` page field `[0x006cec74+0x273]`, currently mirrored into the checkbox strip rooted at control `0x758e`. The helper flips the dword and persists shell config through `0x00484910(1)`.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x004ff6f7,37,shell_settings_window_toggle_dialogs_page_flag_277,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for `Dialogs` page field `[0x006cec74+0x277]`, currently mirrored into the checkbox strip rooted at control `0x758f`. The helper flips the dword and persists shell config through `0x00484910(1)`.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x004ff727,37,shell_settings_window_toggle_dialogs_page_flag_27b,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for `Dialogs` page field `[0x006cec74+0x27b]`, currently mirrored into the checkbox strip rooted at control `0x7590`. The helper flips the dword and persists shell config through `0x00484910(1)`.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x004ff757,52,shell_settings_window_toggle_gameplay_page_display_runtime_dword_114742_and_refresh_building_detail_if_live,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,4,"Toggle branch for the `Gameplay` page display-runtime dword `[0x006d4024+0x114742]`, one of the fields mirrored by `shell_settings_window_refresh_gameplay_page` `0x004fda20`. The helper flips the dword, re-enters `0x004b2ae0` when the live `BuildingDetail.win` singleton at `0x006cfcbc` is present, and then persists shell config through `0x00484910(1)`. This is therefore the direct toggle owner for that gameplay-page display-runtime field plus its building-detail follow-on refresh.","objdump + local disassembly + settings-window page correlation + building-detail follow-on correlation + config-save correlation" +0x004ff796,37,shell_settings_window_toggle_gameplay_page_shell_flag_a8,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,3,"Toggle branch for the `Gameplay` page shell field `[0x006cec74+0x0a8]`, one of the values mirrored by `shell_settings_window_refresh_gameplay_page` `0x004fda20`. The helper flips the dword and persists shell config through `0x00484910(1)`.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x004ff7c6,113,shell_settings_window_toggle_gameplay_page_shell_flag_263_and_refresh_live_world_tool_sidecar,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,4,"Toggle branch for the `Gameplay` page shell field `[0x006cec74+0x263]`, mirrored by `shell_settings_window_refresh_gameplay_page` `0x004fda20`. The helper flips the dword and, when the live shell detail manager at `0x006d0818` is on page `0x0c`, updates one world-tool sidecar rooted at `0x0062c120+0x1689/0x168d` before persisting shell config through `0x00484910(1)`. This is therefore the direct owner for the `+0x263` gameplay toggle plus its narrow live-tool follow-on.","objdump + local disassembly + settings-window page correlation + live-tool follow-on correlation + config-save correlation" +0x004ff84e,109,shell_settings_window_toggle_gameplay_page_shell_flag_309_and_refresh_live_tool_counters,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,4,"Toggle branch for the `Gameplay` page shell field `[0x006cec74+0x309]`, mirrored by `shell_settings_window_refresh_gameplay_page` `0x004fda20`. The helper flips the dword and, when the live tool at `0x006d1a8c` plus world-side owner `0x006cfca8` are present, chooses between the small follow-on decrements `0x00491880` and `0x004932a0` before persisting shell config through `0x00484910(1)`. This is therefore the direct owner for the `+0x309` gameplay toggle plus its live-tool counter refresh side effect.","objdump + local disassembly + settings-window page correlation + live-tool follow-on correlation + config-save correlation" +0x004ffafb,102,shell_settings_window_service_graphics_backend_status_and_repaint_page,shell,cdecl,inferred,objdump + local disassembly + settings-window service correlation,4,"Timer-gated graphics-page service branch beneath `SettingsWindow.win`. The helper samples elapsed wall-clock time through `shell_get_elapsed_tick_count_since_bootstrap_seed` `0x0051d890` against the global deadline `0x006d136c`, rearms that deadline by `1000` ms, chooses between graphics-backend follow-on calls `0x0053f170` and `0x0053f2c0` from the composite predicate `shell_graphics_backend_query_primary_or_fallback_status_nonzero` `0x004fe140`, raises the shared shell refresh latch through `0x00484910(1)`, repaints the live graphics page through `shell_settings_window_refresh_graphics_page` `0x004fe770`, and then shortens the next service deadline to `60` ms. This is therefore the active graphics-backend service-and-repaint owner rather than just another generic timer callback.","objdump + local disassembly + settings-window service correlation + graphics-page refresh correlation" +0x004ffb64,96,shell_settings_window_service_graphics_backend_status_without_page_repaint,shell,cdecl,inferred,objdump + local disassembly + settings-window service correlation,4,"Sibling timer-gated graphics-backend service branch beneath `SettingsWindow.win`. The helper uses the same elapsed-tick gate at `0x006d136c`, rearms the `1000` ms coarse deadline through `shell_get_elapsed_tick_count_since_bootstrap_seed` `0x0051d890`, chooses between `0x0053f0f0` and `0x0053f210` from `graphics_backend_query_both_status_slots_clear` `0x0053ef70`, raises the shared shell refresh latch through `0x00484910(1)`, and then shortens the next service deadline to `60` ms without directly repainting the graphics page. Current local evidence keeps this as the no-page-repaint companion to `0x004ffafb` rather than a detached backend poller.","objdump + local disassembly + settings-window service correlation + backend-follow-on correlation" +0x004ffbc0,244,shell_settings_window_handle_custom_resolution_or_graphics_range_refresh,shell,cdecl,inferred,objdump + local disassembly + settings-window callback correlation + persistence correlation,3,"Settings-window callback branch that persists the display-runtime block through `0x0051eea0`, rebuilds the custom-resolution list through `0x004fe4c0`, and then republishes the graphics-range controls `0x7555` and `0x7578` depending on whether graphics mode byte `[0x006d4024+0x114226]` is nonzero. The branch is timer or service gated through `0x006d136c` and the surrounding settings dispatcher. This is still somewhat structural, but it is now clearly the graphics custom-resolution or range-refresh owner rather than an unrelated timer path.","objdump + local disassembly + settings-window callback correlation + persistence correlation + graphics-range-control correlation" +0x004ffd10,351,shell_settings_window_handle_graphics_range_custom_mode_toggle,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,4,"Settings-window callback branch for the graphics-range custom-mode affordance rooted at control `0x7555`. When the custom-mode flag from `shell_query_graphics_range_custom_mode_flag` `0x0051fd40` is already set it disables that flag through `shell_set_graphics_range_custom_mode_flag_and_reapply_if_needed` `0x00520fd0(0)` and persists the display-runtime block through `0x0051eea0`. Otherwise it first checks `shell_query_graphics_range_has_live_custom_payload` `0x0051fd00`; when no live custom payload exists it clears the control and presents one small localized notice through `0x005193f0(0x0e17) -> 0x004c98a0(mode=1)`. When a live payload does exist it uses shell byte `[0x006cec74+0x2d1]` as a one-shot warning gate, raises the shared shell refresh latch through `0x00484910(1)`, presents the confirmation dialog `0x005193f0(0x0e16) -> 0x004c98a0(mode=3)`, and only on the affirmative path re-enters `shell_set_graphics_range_custom_mode_flag_and_reapply_if_needed` `0x00520fd0(1)`, persists the display runtime, and republishes the same control. If the setter immediately clears the flag again it falls back to the localized notice path `0x005193f0(0x0e93) -> 0x004c98a0(mode=1)`. This is therefore the user-facing graphics-range custom-mode toggle owner rather than a generic dialog wrapper.","objdump + local disassembly + settings-window dispatcher correlation + graphics-range-control correlation + dialog-path correlation" +0x004ffe72,48,shell_settings_window_handle_graphics_range_scalar_zero_nonzero_toggle,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,4,"Small graphics-range scalar toggle beneath `SettingsWindow.win`. The helper reads the current scalar through `shell_query_graphics_range_scalar` `0x0051fd60`, collapses that to a zero-vs-nonzero boolean, inverts it, forwards the requested replacement through `shell_set_graphics_range_scalar_and_reapply_if_needed` `0x00521030`, and then persists the display-runtime block through `0x0051eea0`. Current grounded location is the same graphics-side callback strip as `0x004ffd10`, so this is the safest current read for the zero/nonzero graphics-range scalar toggle rather than a generic integer setter.","objdump + local disassembly + settings-window dispatcher correlation + graphics-range-scalar correlation" +0x004ffea4,91,shell_settings_window_toggle_display_runtime_preview_rect_notify_flag,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,3,"Toggle branch for display-runtime byte `[0x006d4024+0x1146eb]` beneath `SettingsWindow.win`. The helper flips the byte, and when the global world-root at `0x0062c120` is live and the new value becomes zero it emits one large world-space rect notification through `0x0044e940(0,0,0x270f,0x270f,0)` before persisting the display-runtime block through `0x0051eea0`. Current evidence safely bounds this as one preview-rect notify toggle in the graphics-side settings family rather than a fully named presentation option.","objdump + local disassembly + settings-window dispatcher correlation + world-rect-notify correlation" +0x004ffeff,46,shell_settings_window_toggle_display_runtime_dword_114697,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,3,"Toggle branch for display-runtime dword `[0x006d4024+0x114697]` beneath `SettingsWindow.win`. The helper flips the dword between `0` and `1` and immediately persists the display-runtime block through `0x0051eea0`. Current evidence keeps the field name conservative because no stronger user-facing semantic owner is grounded yet.","objdump + local disassembly + settings-window dispatcher correlation + persistence correlation" +0x004fff2d,37,shell_settings_window_toggle_display_runtime_byte_1146e9,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,3,"Toggle branch for display-runtime byte `[0x006d4024+0x1146e9]` beneath `SettingsWindow.win`. The helper flips the byte and immediately persists the display-runtime block through `0x0051eea0`. Current evidence keeps the label structural because the exact player-facing option name is still ungrounded.","objdump + local disassembly + settings-window dispatcher correlation + persistence correlation" +0x004fff59,41,shell_settings_window_toggle_display_runtime_byte_1146b8,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,3,"Toggle branch for display-runtime byte `[0x006d4024+0x1146b8]` beneath `SettingsWindow.win`. The helper flips the byte and persists the display-runtime block through `0x0051eea0`. Current adjacent disassembly keeps this on the graphics or model-detail side of the settings dispatcher, but the exact player-facing caption is still ungrounded.","objdump + local disassembly + settings-window dispatcher correlation + persistence correlation" +0x004fff85,86,shell_settings_window_toggle_display_runtime_scalar_1146af_between_0_and_0_5,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,4,"Small scalar toggle branch for display-runtime float `[0x006d4024+0x1146af]` beneath `SettingsWindow.win`. The helper compares the current scalar against `0.5`, stores `0.0` when the current value is already at or below that threshold, otherwise stores `0.5`, and then persists the display-runtime block through `0x0051eea0`. This is therefore the clearest current owner for a binary `0.0` vs `0.5` display scalar toggle inside the settings dispatcher.","objdump + local disassembly + settings-window dispatcher correlation + scalar-threshold correlation" +0x004fffde,46,shell_settings_window_toggle_display_runtime_byte_1146a8,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,3,"Toggle branch for display-runtime byte `[0x006d4024+0x1146a8]` beneath `SettingsWindow.win`. The helper flips the byte and persists the display-runtime block through `0x0051eea0`. Current evidence is still structural rather than caption-level.","objdump + local disassembly + settings-window dispatcher correlation + persistence correlation" +0x0050000a,46,shell_settings_window_toggle_display_runtime_byte_1146e3,shell,cdecl,inferred,objdump + local disassembly + settings-window dispatcher correlation,3,"Toggle branch for display-runtime byte `[0x006d4024+0x1146e3]` beneath `SettingsWindow.win`. The helper flips the byte and persists the display-runtime block through `0x0051eea0`. This is the direct byte-toggle owner mentioned more broadly in the settings dispatcher note, but its exact user-facing caption is still open.","objdump + local disassembly + settings-window dispatcher correlation + persistence correlation" +0x00500036,51,shell_settings_window_apply_graphics_misc_option_family12_from_checkbox_state,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,4,"Settings-window callback leaf for the first `Miscellaneous` graphics page option family derived through `0x00484af0(0x0c)`, currently mirrored into control `0x7586` by `shell_settings_window_refresh_graphics_misc_page` `0x004fdd70`. The helper reads the incoming checkbox-state bit from `[msg+0x2c]+0xcc`, forwards that boolean into `shell_set_graphics_option_with_fanout` `0x00485060(option_family=0x0c)`, and then persists the display-runtime block through `0x0051eea0`. This is therefore the direct apply leaf for that graphics-misc option family rather than another anonymous message stub.","objdump + local disassembly + settings-window page correlation + graphics-option-family correlation + persistence correlation" +0x0050006c,46,shell_settings_window_toggle_shared_setup_config_flag_247,shell,cdecl,inferred,objdump + local disassembly + settings-window and setup correlation,3,"Toggle branch for shared shell config flag `[0x006cec74+0x247]`. The helper flips the dword and persists shell config through `0x00484910(1)`. This is one of the same three persisted booleans later mirrored by `Setup.win` controls `0x0e88/0x0e89/0x0e8a`, so the safest current read is the shared setup-config toggle rather than a page-local-only setting.","objdump + local disassembly + settings-window and setup correlation + config-save correlation" +0x0050009c,46,shell_settings_window_toggle_shared_setup_config_flag_24b,shell,cdecl,inferred,objdump + local disassembly + settings-window and setup correlation,3,"Toggle branch for shared shell config flag `[0x006cec74+0x24b]`. The helper flips the dword and persists shell config through `0x00484910(1)`. This is one of the three persisted booleans also mirrored by `Setup.win` controls `0x0e88/0x0e89/0x0e8a`.","objdump + local disassembly + settings-window and setup correlation + config-save correlation" +0x005000cc,46,shell_settings_window_toggle_shared_setup_config_flag_243,shell,cdecl,inferred,objdump + local disassembly + settings-window and setup correlation,3,"Toggle branch for shared shell config flag `[0x006cec74+0x243]`. The helper flips the dword and persists shell config through `0x00484910(1)`. This is the third member of the persisted setup-config toggle trio also mirrored by `Setup.win` controls `0x0e88/0x0e89/0x0e8a`.","objdump + local disassembly + settings-window and setup correlation + config-save correlation" +0x005000fc,45,shell_settings_window_toggle_scrolling_page_boolean_companion_flag_120,shell,cdecl,inferred,objdump + local disassembly + settings-window page correlation,4,"Toggle branch for the `Scrolling` page boolean companion derived from shell field `[0x006cec74+0x120]`, mirrored into control `0x7585` by `shell_settings_window_refresh_scrolling_page` `0x004fdf20`. The helper maps the incoming control id to a zero-or-one dword, stores that at `[0x006cec74+0x120]`, and persists shell config through `0x00484910(1)`. This is therefore the direct owner for the scrolling-page boolean companion rather than a generic shell-field setter.","objdump + local disassembly + settings-window page correlation + config-save correlation" +0x00500410,528,shell_settings_window_refresh_selected_page_controls,shell,thiscall,inferred,objdump + local disassembly + settings-window correlation + RT3.lng page-label correlation,4,"Refreshes the visible category-strip state and the active page body for the shared `SettingsWindow.win` singleton. The helper raises the local in-refresh guard byte `0x006d135d`, normalizes caller page `0x0c` to `0x0b` and `0x0b` to `0x0d`, republishes the left category-strip control family `0x7533..0x753f` plus the trailing companion controls `0x7540` and `0x753f` through repeated `0x00540120` calls with mode `3` and style values `0x86/0xa6`, and then dispatches the selected page through the local table at `0x005005e0`. The category table rooted at `0x00622870` now grounds those page indices as `Gameplay`, `Sound`, `Graphics`, `Model Detail`, `Draw Distance`, `Textures`, `Miscellaneous`, `Hot Keys`, `Scrolling`, `Camera Controls`, `Dialogs`, `Miscellaneous`, and `Sandbox Options`; page `7` is directly confirmed as the hotkeys page because it dispatches into `shell_settings_window_rebuild_hotkeys_list_control_from_sorted_binding_report` `0x004fec60`. The currently grounded page-refresh callees are `0x004fda20`, `0x004fdb90`, `0x004fe770`, `0x004fe960`, `0x004feb20`, `0x004febd0`, `0x004fdd70`, `0x004fec60`, `0x004fdf20`, `0x004fdfd0`, `0x004fd940`, `0x004fd730`, and `0x004fd8d0`. The helper clears `0x006d135d` on every exit path, so the safest current read is the selected-page refresh owner rather than a generic settings redraw wrapper.","objdump + local disassembly + settings-window correlation + category-strip correlation + page-dispatch correlation + RT3.lng page-label correlation" +0x00500620,32,shell_refresh_settings_window_page_if_live_and_not_in_internal_refresh,shell,cdecl,inferred,objdump + local disassembly + settings-window correlation,4,"Small guarded wrapper above `shell_settings_window_refresh_selected_page_controls` `0x00500410`. The helper ignores page selector `-1`, ignores requests while the internal refresh guard byte `0x006d135d` is set, and otherwise re-enters the live settings singleton at `0x006d1350` when present. Current grounded callers are the surrounding settings-message and page-selection paths, where this acts as the nonreentrant page-refresh gate rather than a general shell-window service helper.","objdump + local disassembly + settings-window correlation + refresh-guard correlation" +0x00500640,487,shell_settings_window_construct,shell,thiscall,inferred,objdump + strings + RT3.lng page-label correlation,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 ordered page labels `Gameplay`, `Sound`, `Graphics`, `Model Detail`, `Draw Distance`, `Textures`, `Miscellaneous`, `Hot Keys`, `Scrolling`, `Camera Controls`, `Dialogs`, `Miscellaneous`, and `Sandbox Options` before the window is shown. The second dword in that table is now only bounded as one small subgroup or style flag; it is set on `Model Detail`, `Draw Distance`, `Textures`, and the first `Miscellaneous` entry and clear on the rest. This is therefore the safest current read for the shared settings-window constructor rather than a generic page-list allocator.","objdump + strings + RT3.lng page-label correlation + category-table correlation" 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 0x00501f20,270,shell_query_registry_open_command_for_http_or_rtf_target,shell,cdecl,inferred,objdump + literal inspection,3,"Queries one shell-open command string from the registry and formats it into the shared command buffer at `0x006d14d8`. Selector `0` uses the literal `http\\shell\\open` and validates the returned command against the substrings `netsc` and the quoted percent-one placeholder; selector `1` uses `rtffile\\shell\\open`, truncates at the percent-one placeholder, and appends the literal `readme.rtf` through the format `%s %s`. The helper returns `0x006d14d8` on success or `0` on failure. Current grounded callers are the early `Setup.win` dispatcher buttons at `0x00503585/0x0050359f/0x005035c7/0x005035ce`, which then forward the formatted command through import `0x005c8088` instead of re-entering the normal setup launch-mode family.","objdump + literal inspection + caller correlation" +0x00468b00,10,multiplayer_toggle_preview_dataset_service_gate,shell,cdecl,inferred,objdump + local disassembly + global-state inspection,2,Tiny helper that flips the preview-dataset frame-service gate at `0x006cd910` by XORing it with `1` and then returns `0`. Current evidence only grounds the store itself so this row stays structural for now.,objdump + local disassembly + global-state inspection +0x00468b10,58,multiplayer_preview_dataset_register_selector_callback_if_absent,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-callback registration helper over the keyed descriptor owner at `[this+0x04]`. It first probes the keyed store through `0x0053daa0(selector)` and, when no existing entry is present, inserts the caller-supplied callback pointer through `0x0053d960(selector, callback)` before returning success. Current grounded caller is the broader preview-dataset callback seeding pass `0x00473280`, which uses this helper to populate selector handlers `1..0x83`, so this is the clean local registration primitive beneath that callback-registry owner rather than a generic keyed insert.","objdump + local disassembly + registration-pass correlation + keyed-store correlation" +0x00468b50,7,multiplayer_preview_dataset_set_default_callback_root,shell,thiscall,inferred,objdump + local disassembly + caller inspection,2,Tiny setter that stores one caller-supplied callback root into `[this+0x08]`. Current grounded caller is the broader preview-dataset callback registration pass `0x00473280`, which seeds this slot with `0x0046f4a0` before populating the keyed selector table.,objdump + local disassembly + caller inspection + callback-root correlation 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 @@ -852,14 +1243,194 @@ 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 +0x00469690,52,multiplayer_intrusive_queue_append_node_and_maintain_head_tail_count,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Tiny intrusive queue append helper over the singly linked queue layout `[queue+0x00=head]`, `[queue+0x04=tail]`, and `[queue+0x08=count]`. When the caller supplies a predecessor node in the first stack argument it splices the new node after that predecessor and increments the queue count; otherwise it appends at the queue tail or seeds the head when the queue was empty. Current grounded callers include the `0x00469d30` sidecar-dispatch branch and later transport-side queue helpers at `0x00522c90` and `0x00523633`, so this is the common intrusive append primitive beneath the multiplayer preview-owner and session-event transport families rather than a one-off local list splice.","objdump + caller inspection + local disassembly + intrusive-queue-layout correlation" 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 +0x00469800,144,multiplayer_preview_dataset_acquire_pooled_block_or_heap_fallback,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Preview-dataset allocation helper beneath the request and sidecar-record families. For sizes up to `0x300` it spin-locks the small pool guard at `0x006cd940`, tries to pop one cached block from the dataset-local free-list owner at `[this+0x8f3c]`, and falls back to `0x0053b070(size)` when the pool is empty; larger requests always take the heap path. The companion release branch at `0x00469890` returns owned-span pointers back into the same pool when they fall inside `[this+0x8f40 .. this+0x8f40+0x48000)`. Current grounded callers include the broader transport submitter `0x00469d30`, the named callback-descriptor builders `0x00469930` and `0x00469a50`, and later preview-dataset helpers around `0x0046a31f`, `0x0046a60c`, and `0x0046ae24`, which makes this the local pooled-block owner for the Multiplayer preview dataset rather than a generic allocator.","objdump + caller inspection + local disassembly + pooled-span correlation + preview-dataset free-list correlation" +0x00469930,176,multiplayer_preview_dataset_append_named_callback_descriptor,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Builds one fixed-size named callback descriptor and appends it to the preview-dataset intrusive list at `[this+0x8f28]`. The helper acquires one `0xa4`-byte node from the local pool at `[this+0x8f20]`, zeroes the full record, stores the caller-supplied selector id at `[node+0x14]`, stores the two callback or payload dwords at `[node+0x04/+0x08]`, copies the caller string into `[node+0x18]`, and then appends the node through the standard intrusive-list head, tail, and count layout. The current grounded owner is the fixed registration block `0x00473a60`, which repeatedly seeds selector ids `1..0xa` from fixed name and callback pairs, so this is now best read as the preview-dataset named callback-descriptor append helper rather than an anonymous list insert.","objdump + caller inspection + local disassembly + registration-block correlation + intrusive-list correlation" +0x004699e0,48,multiplayer_preview_dataset_find_named_callback_payload_by_selector,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Small lookup helper over the named callback-descriptor list at `[this+0x8f28]`. It walks the intrusive list, matches the caller-supplied selector id against `[node+0x14]`, and returns the payload or callback dword at `[node+0x04]` or `0` when no match is present. Current grounded callers include the preview-dataset service lane at `0x0046b545`, so this is the paired selector lookup beneath the `0x00469930` descriptor-registration family rather than a generic keyed search.","objdump + caller inspection + local disassembly + descriptor-field correlation" +0x00469a50,160,multiplayer_preview_dataset_append_named_ui_request_record,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Builds one variable-size named UI-request record and appends it to the preview-dataset intrusive list at `[this+0x8f2c]`. The helper acquires `strlen(name)+0x21` bytes through `multiplayer_preview_dataset_acquire_pooled_block_or_heap_fallback` `0x00469800`, stores the caller-supplied request dwords at `[node+0x04/+0x08/+0x10/+0x14/+0x18]`, zeroes the transient field `[node+0x1c]`, copies the request label or text into `[node+0x20]`, and then appends the record to the dataset-local list. Current grounded callers package Multiplayer.win text and control updates such as the control-`0x69` mode publish path at `0x004ee4c0`, the selected-map and status branches around `0x0046f560..0x0046f837`, and several later preview-update branches, which keeps this bounded as the preview-dataset named UI-request append helper rather than a transport send.","objdump + caller inspection + local disassembly + UI-request-list correlation + Multiplayer.win control-update correlation" +0x00469d30,1268,multiplayer_preview_dataset_submit_transport_request,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,4,"Broad preview-owner request submitter used by the Multiplayer preview dataset at `0x006cd8d8` and several auxiliary shell-side async branches. The helper accepts an opcode or request id on the first stack slot, a 16-bit selector on the second, payload pointer and length on the next pair, flag dword on the fifth slot, and an optional auxiliary pointer on the sixth. On the selector-`1` fast path, when dataset state `[this+0x985c] == 1` and the live session gate `0x00521670` reports no active sessions, it bypasses the heavier transport packaging and forwards the supplied text directly through `multiplayer_send_session_event_text_selector0` `0x00469660`. Otherwise it spin-locks the global submit guard `0x006cd960`, optionally copies payload bytes into a local `0x1018` scratch block when flag bit `0x10` is set, optionally allocates one sidecar request object through `multiplayer_preview_dataset_acquire_pooled_block_or_heap_fallback` `0x00469800` when flag bit `0x04` is set, tags that sidecar with selector, size, flags, and payload bytes, and enqueues it through the callback queue rooted at `0x00521d40()->[+0x64]->[+0x04]` using `multiplayer_intrusive_queue_append_node_and_maintain_head_tail_count` `0x00469690`. The helper then updates the global payload counters `0x006cd930/0x006cd934` and dispatches either a direct small-payload request or the slower packed path through `0x00553000/0x00552ff0` into `0x00521dc0`, setting the extra high dispatch bit `0x80000000` on the packed branch. Current grounded callers include the `.gmt` save-side branch in `shell_map_file_world_bundle_coordinator` `0x00445de0`, `BuildingDetail.win` auxiliary sync at `0x004b9e10`, `Start New Company...` side-owner submission at `0x0047d120`, `CompanyDetail.win` async multiplayer actions, the multiplayer preview control publisher `0x004ee4c0`, and many preview-dataset-side update branches between `0x0046b431` and `0x00473bc9`, which makes this the shared preview-owner transport submitter rather than a window-local control helper.","objdump + caller xrefs + local disassembly + sidecar-dispatch correlation + transport-submit correlation + multiplayer-preview-owner correlation" +0x0046a030,224,multiplayer_preview_dataset_stage_profile_text_selected_path_and_sync_session_state,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Stages the local profile text and selected-path string into the preview dataset and then synchronizes that state into the session-side helper path when no live multiplayer session object is present at `0x006d40dc`. The helper clears or resolves the small arming latch at `[this+0x8f18]`, copies the caller profile text into `[this+0x8e10]`, copies the caller path into `[this+0x8f48]`, stores one boolean derived from the optional third pointer into global `0x006cd928`, and then forwards the staged strings plus the optional pointer into the lower session helper `0x005238e0`. When the session-event transport rooted at `0x006cd970` is live it also forces the paired status-pump and flush follow-ons through `0x0058d9d0` and `0x0058e1f0`. Current grounded caller is the action-`2` branch inside `multiplayer_dispatch_requested_action` `0x004ef960`, where it seeds the active preview dataset from the staged Multiplayer.win text buffers before the preview-mode refresh path.","objdump + caller inspection + local disassembly + staged-buffer correlation + action-2 correlation" +0x0046a110,131,multiplayer_preview_dataset_match_named_field_slot_copy_profile_text_and_probe_selection,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Action-`3` helper above the preview-dataset field-slot table. The function scans all `0x80` `0x11c`-byte rows rooted at `[this+0x10]`, comparing the caller-supplied key string against the per-row name field at `row+0x80`; on a match it copies the row's primary text field back into dataset buffer `[this+0x8e10]`. It then seeds dataset mode `[this+0x0c] = 1`, forwards the caller's strings into the lower session helper `0x00523af0`, and upgrades that mode to `2` when the helper reports a negative result. Current grounded caller is the action-`3` branch inside `multiplayer_dispatch_requested_action` `0x004ef960`, which uses this helper immediately after promoting the staged text buffers into the active preview dataset.","objdump + caller inspection + local disassembly + field-slot correlation + action-3 correlation" +0x0046a1a0,85,multiplayer_preview_dataset_ensure_field_slot_table_initialized,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Lazy initializer for the fixed `0x80 * 0x11c` field-slot table rooted at `[this+0x10]` inside the preview dataset. On first use it zeroes the full `0x2380`-byte table, clears `[this+0x8f10]`, marks `[this+0x8f18] = 1`, and then takes one of two follow-ons: when dataset state `[this+0x985c]` is zero it primes the session-side helper through `0x005223d0`; otherwise it re-enters `multiplayer_register_session_event_cache_fields` `0x00469520`. The helper always returns the base pointer `[this+0x10]`. Current grounded callers include the staged-text commit and roster-refresh paths at `0x004ee2b2` and `0x004ee765`, which then index `0x11c`-byte rows and copy the embedded strings at row offset `0x84`, so this is the clearest current owner for the preview-dataset field-slot table rather than another generic reset stub.","objdump + caller inspection + local disassembly + field-slot-table correlation + cache-field-registration correlation" +0x0046b6d0,163,multiplayer_preview_dataset_touch_current_session_year_bucket_and_return_staged_tuple,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Session-side helper over the staged tuple at `[this+0x9048]`. When the live world root `0x006cec78`, its companion pointer `[world+0x19]`, and the caller's stack flag are all present, the helper derives one key from the staged tuple through `0x0051d3c0`, resolves the current live session record through `0x005216c0/0x00521d60`, ensures one keyed bucket exists in that session record's hash owner at `[session+0x2580]` through `0x0053dae0` or the local create path `0x0046ab10`, increments that bucket, and then republishes the current-session selector through `0x005216d0`. On any failed precondition it skips the bucket touch and simply returns the staged tuple pointer `[this+0x9048]` or `0`. Current grounded callers include the broad selector-handler family registered by `0x00473280` and the launch-side branches around `0x0046f672/0x0046f7a0`, so this is the safest current structural read beneath the preview-dataset launch/service layer.","objdump + local disassembly + caller inspection + staged-tuple correlation + session-bucket correlation" +0x0046b910,219,multiplayer_preview_dataset_prune_session_buckets_below_current_year_key,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Threshold-prune helper over the keyed session bucket owner at `[arg+0x2580]`. It derives one current key either from the caller's optional second argument or from the active world tuple at `[0x006cec78+0x0d]` through `0x0051d3c0`, then repeatedly asks `0x0053db20` with comparator `0x00468ac0` for the next smaller keyed bucket, resolves that bucket through `0x0053d9e0`, drains every queued node in it, and frees those nodes through `multiplayer_preview_dataset_release_pooled_block_or_heap_span` `0x00469890`. The helper uses scratch global `0x006cd968` as the current selected key during the sweep. Current grounded callers are the broader current-session service body `0x0046b9f0` and the preview handlers around `0x0046f6b9/0x0046f708`, so this is the clearest current bucket-prune owner beneath the dataset launch/session maintenance family rather than a generic hash-table walk.","objdump + local disassembly + caller inspection + keyed-bucket-prune correlation" +0x0046b9f0,592,multiplayer_preview_dataset_service_current_session_buckets_and_publish_selector0x67,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Broader current-session service slice beneath the multiplayer preview dataset. It optionally timestamps its own service cost when `0x006cd900 == 1`, zeros the total-node counter `[this+0x9890]`, resolves the live session owner through `0x00521d40`, copies and normalizes the current world tuple into `[this+0x9048/+0x904c]` through `0x0051d5a0`, prunes older keyed buckets through `0x0046b910`, refreshes neighboring preview state through `0x0046a590` and `0x00473bf0`, and then looks up the current keyed bucket inside `[session+0x2580]`. For each queued node in that current bucket it increments `[this+0x9890]`, counts the subset not marked by byte `+0x09 == 0x67` and flag bit `+0x0b & 0x04`, routes the entry through `0x00522050` and `0x0046ac00`, and frees the node through `0x00469890`. After the loop it accumulates the unmarked subset into `[this+0x987c]`, restores the shared shell status/tool stack through `0x004423a0/0x004423d0`, and when the live session-event transport is active it packages one selector-`0x67` request through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` using the staged key at `[this+0x8f38]`. Current grounded callers include the simulation-side wrapper at `0x0040aa7a` and the broader launch/service family around `0x0046b780`, so this is the safest current owner for current-session bucket service rather than a generic preview refresh.","objdump + local disassembly + caller inspection + keyed-bucket correlation + selector-0x67 publish correlation" +0x0046bc40,563,multiplayer_preview_dataset_release_owned_lists_transients_and_session_side_state,shell,thiscall,inferred,objdump + local disassembly + caller inspection,4,"Primary release-side teardown body for the Multiplayer preview dataset rooted at `0x006cd8d8`. It first runs the narrower internal cleanup at `0x0046d240`, releases the dataset render target `[this+0x9884]` through `0x0053c000`, conditionally notifies the live session object through `0x005217b0/0x005216a0`, and re-enters the local transport-side sweep `0x0046b910` when the current session list is still live. After that it tears down the session-event transport-side helper path through `multiplayer_teardown_session_event_transport` `0x00469450` and `0x00523200`, walks and frees every node in the variable-size request list `[this+0x8f2c]`, releases the keyed callback owner `[this+0x8f20]`, request buffer `[this+0x8f24]`, semicolon-name owner `[this+0x9050]`, pooled free-list owner `[this+0x8f3c]`, backing pool span `[this+0x8f40]`, fixed descriptor list `[this+0x8f28]`, auxiliary keyed owner `[this+0x04]`, and finally the global helper at `0x006cd8e0`. It also clears the core dataset latches `[this+0x00]`, `[this+0x0c]`, `[this+0x8f18]`, `[this+0x8f30]`, and `[this+0x9054]`. Current grounded callers are the broader reset or constructor path `0x0046be80` and the full shutdown wrapper `0x0046c230`, which makes this the concrete dataset release body rather than a transport-only destructor.","objdump + local disassembly + caller inspection + teardown-correlation + owned-list-release correlation" +0x0046be80,938,multiplayer_preview_dataset_construct_reset_globals_and_seed_callback_owners,shell,thiscall,inferred,objdump + local disassembly + caller inspection,4,"Full constructor or reset owner for the Multiplayer preview dataset at `0x006cd8d8`. It begins by re-entering `multiplayer_preview_dataset_release_owned_lists_transients_and_session_side_state` `0x0046bc40`, then clears the surrounding launcher and preview globals (`0x006cd91c`, `0x006cd924..0x006cd92c`, `0x006cd8e4..0x006cd904`, `0x006ae4cc..0x006ae4d4`, and related `0x005f2b38/40` latches), allocates or reuses the small global helper at `0x00d973b4`, installs it into `[this+0x00]`, and requires the helper vtable state at `0x00557bc0 == 1` before proceeding. It then ensures the live session object at `0x006d40d0`, publishes one local version scalar through `0x00521910`, allocates the auxiliary keyed owner `[this+0x04]`, zeroes the fixed field-slot table `[this+0x10]`, allocates the variable request buffer `[this+0x8f24]`, the keyed callback owner `[this+0x8f20]`, the fixed descriptor list owner `[this+0x8f28]`, the UI-request list owner `[this+0x8f2c]`, the pooled backing span `[this+0x8f40]`, the pooled free-list owner `[this+0x8f3c]`, the semicolon-name helper `[this+0x9050]`, and the render target `[this+0x9884]`. Before returning it clears staged strings `[this+0x8f48]` and `[this+0x905c]`, seeds marker words `[this+0x9860]` and `[this+0x9864..+0x9870]` to `-1`, runs the callback seeding pass `0x00473280`, registers the fixed named descriptor block `0x00473a60`, and when the caller asks for the live branch it re-enters `multiplayer_register_session_event_callbacks` `0x0046a900`, storing the resulting mode in `[this+0x985c]`. Current grounded callers are the action-`2` and action-`3` reset branches inside `multiplayer_dispatch_requested_action` `0x004ef960`, so this is now the real preview-dataset constructor/reset owner above those action handlers rather than a loose helper cluster.","objdump + local disassembly + caller inspection + reset-global correlation + callback-owner correlation + action-dispatch correlation" 0x0046b780,368,multiplayer_preview_dataset_service_launch_state_and_warn_out_of_sync,shell,thiscall,inferred,objdump + caller xrefs + strings + callsite inspection,4,"Services one higher-level launch or preview transition slice on the Multiplayer preview dataset rooted at `0x006cd8d8`. At entry it checks global `0x006cd91c` and, when armed, formats localized id `3879` `Out of Sync` through `0x5193f0` and pushes it into the shell status presenter at `0x5386e0` with timeout `0xbb8`; this is the current grounded owner of that string and it is not part of the station-detail overlay. The same helper then gates on preview and launcher globals `0x006cd8dc`, `0x006ce9b8`, `0x006ce9c4`, and shell-state latches under `0x006cec78`, drives one modal shell branch through `0x482150`, timestamps `[this+0x9058]`, chains the internal dataset-side helpers at `0x46af70`, `0x46b0c0`, `0x46ad80`, `0x46aeb0`, `0x469b00`, and `0x46a590`, and now has a tighter launch-side tail: when `0x006ce9c4` is armed the inner branch at `0x0046b8bc` allocates or clears one active-mode object through `0x53b070/0x4336d0`, publishes it into `0x006cec78`, runs `shell_active_mode_run_profile_startup_and_load_dispatch` `0x00438890` with stack args `(0, 0)`, then clears `[0x006cec74+0x6c]` and only after that re-enters `shell_map_file_entry_coordinator` `0x00445ac0` through staged buffer `0x006ce630` plus flag dword `0x006ce9c0`. Current grounded callers include the multiplayer-side service loop around `0x004373c5` and `0x00437435`, plus later shell-side branches at `0x00483638`, `0x00483d79`, and `0x00484054`.","objdump + caller xrefs + strings + callsite inspection + multiplayer-preview correlation + launch-tail disassembly" 0x0046a6c0,307,multiplayer_session_event_publish_registration_field,shell,unknown,inferred,ghidra-headless + objdump,3,"Switch-driven session-event callback that publishes one Multiplayer.win registration or status field into the destination builder passed on the stack. Depending on selector `EDX` it now clearly includes the local executable version string through `runtime_query_cached_local_exe_version_string` `0x00482d80` on runtime root `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 + registration-field correlation" 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 +0x0046c230,80,multiplayer_shutdown_preview_dataset_session_object_and_global_helper,shell,thiscall,inferred,objdump + local disassembly + caller xrefs,4,"Final multiplayer-side shutdown wrapper above the preview dataset release body. It first re-enters `multiplayer_preview_dataset_release_owned_lists_transients_and_session_side_state` `0x0046bc40`, then releases the live session object at `0x006d40d0` through `0x00521590`, clears that global, releases the small shared helper at `0x00d973b4` through `0x00557b70`, and clears that global too. Current grounded callers include the broader shell shutdown and mode-transition branches at `0x004364e4`, `0x0048364d`, `0x00483d8e`, `0x00484073`, `0x004843dc`, `0x00484556`, `0x004dcc96`, `0x004edc50`, `0x004ef2b1`, `0x004ef31b`, `0x004ef823`, and `0x004f0a62`, which makes this the full multiplayer preview/session shutdown wrapper rather than just another dataset reset.","objdump + local disassembly + caller xrefs + global-helper shutdown correlation" 0x0046c360,32,multiplayer_route_chat_line,shell,cdecl,inferred,ghidra-headless,3,Routes one multiplayer chat line through the active transport object at `0x006cec78` when present or falls back to the local Multiplayer.win chat publisher otherwise. The transport path forwards the supplied text into 0x4554e0 with fixed mode arguments `5 1 0`; the local fallback tail-calls multiplayer_publish_wrapped_chat_message.,ghidra + rizin + llvm-objdump +0x0046c390,42,multiplayer_preview_dataset_publish_control_0x109_from_payload_dword,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Small selector-handler callback beneath the preview-dataset registration table. When the live shell profile at `0x006cec7c` exists, the helper packages the payload dword from `[msg+0x08]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` using fixed request kind `1`, fixed control id `0x0109`, and selector `2`. This is therefore the direct control-`0x109` publish leaf rather than another generic transport wrapper.","objdump + local disassembly + caller inspection + selector-handler correlation + control-0x109 correlation" +0x0046c3c0,96,multiplayer_preview_dataset_arm_launch_latches_publish_fixed_session_token_and_optionally_clear_profile_ready_bit,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback in the preview-dataset table that arms several launch-side latches at once. The helper calls `0x004c8670`, sets globals `0x006cd90c = 1` and `0x006cd8e8 = 1`, publishes the fixed session-event token through `multiplayer_publish_session_event_fixed_token` `0x004694c0`, clears `0x006cd96c`, and when preview-valid latch `0x006ce9bc` is nonzero it also clears profile byte `[0x006cec7c+0x97]` and sets global `0x006ce9c4 = 1`. This is the clearest current owner for the fixed-token plus launch-latch arm path beneath the selector-handler family.","objdump + local disassembly + caller inspection + launch-latch correlation + fixed-token correlation" +0x0046c420,827,multiplayer_apply_session_payload_slab_into_shell_root_and_refresh_dependents,shell,cdecl,inferred,objdump + local disassembly + caller inspection,4,"Large selector-handler callback that copies one incoming payload slab from `[msg+0x08]` into the live shell root at `0x006cec74`. The body performs a long fixed-offset copy into shell fields spanning startup, selection, and session-related lanes, then forces one shell-state refresh through `0x00484910(0)` and, when companion root `0x006ada8c` exists, re-enters `0x00464170` to refresh dependent world-side state. This is therefore the clearest current session-payload apply owner beneath the multiplayer callback table rather than a smaller field toggle.","objdump + local disassembly + caller inspection + slab-copy correlation + shell-refresh correlation" +0x0046c760,3,multiplayer_selector_handler_return_true_stub,shell,cdecl,inferred,objdump + local disassembly,1,"Literal selector-handler stub that returns `1` immediately with no side effects. It currently appears in the preview-dataset callback table seeded by `0x00473280`.","objdump + local disassembly + selector-handler correlation" +0x0046c770,65,multiplayer_preview_dataset_publish_session_field_0x48_with_selector7,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that resolves the live session object at `0x006d40d0`, reads field `[session+0x48]`, and packages that value together with payload pointer `[msg+0x08]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` using selector `7` and request kind `8`. This is the current grounded publish leaf for session field `0x48` beneath the callback table.","objdump + local disassembly + caller inspection + selector-handler correlation + session-field correlation" +0x0046c7c0,71,multiplayer_session_entry_update_elapsed_pair_and_republish,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that resolves one live session entry by key `[msg+0x04]`, rewrites the paired elapsed or timestamp dwords at `[entry+0x54/+0x58]` from the incoming payload, and then republishes the session list through `0x005216d0`. This is the clearest current owner for the per-entry elapsed-pair update beneath the callback table.","objdump + local disassembly + caller inspection + session-entry correlation + elapsed-pair correlation" +0x0046c810,33,multiplayer_forward_payload_dword_into_shell_owner_refresh_pair,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Small selector-handler callback that forwards the payload dword at `[msg+0x08]` into shell-owner helpers `0x0043a070` and `0x0043ca20` when shell root `0x0062be68` is live. Current evidence only grounds the forwarding behavior, so the label stays structural.","objdump + local disassembly + caller inspection + shell-owner correlation" +0x0046c840,53,multiplayer_session_entry_set_flag_0x08_and_republish,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that resolves one live session entry by key `[msg+0x04]`, sets bit `0x08` in entry flags `[entry+0x5c]`, and republishes the session list through `0x005216d0`. This is the current grounded owner for the flag-`0x08` session-entry latch beneath the callback table.","objdump + local disassembly + caller inspection + session-entry-flag correlation" +0x0046c870,71,multiplayer_session_entry_toggle_flag_0x01_from_payload_byte_and_republish,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that resolves one live session entry by key `[msg+0x04]`, reads the first byte of payload `[msg+0x08]`, sets or clears bit `0x01` in `[entry+0x5c]` accordingly, and republishes the session list through `0x005216d0`. This is the current grounded owner for the flag-`0x01` entry-toggle path beneath the callback table.","objdump + local disassembly + caller inspection + session-entry-flag correlation" +0x0046c8c0,201,multiplayer_apply_one_or_many_embedded_session_field_updates_and_republish,shell,cdecl,inferred,objdump + local disassembly + caller inspection,4,"Broader selector-handler callback over the live session-entry table. Guarded by globals `0x006cd8ec` and `0x006cd918`, the helper either treats payload `[msg+0x08]` as one single embedded field-update record or, when the first payload byte is `0xff`, as a small count-prefixed table of such records. It applies each embedded record through local updater `0x00468c10` and then republishes the session list through `0x005216d0`. This is the clearest current owner for batched embedded session-field updates beneath the selector-handler family.","objdump + local disassembly + caller inspection + embedded-record correlation + session-entry correlation" +0x0046c990,63,multiplayer_decrement_session_field_0x74_and_publish_selector0x0f,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that resolves the live session object at `0x006d40d0`, decrements field `[session+0x74]`, and packages the decremented value together with payload `[msg+0x08]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` using selector `0x0f` and request kind `4`. This is the current grounded decrement-and-publish owner for that session-side countdown lane.","objdump + local disassembly + caller inspection + session-field correlation + selector-0x0f correlation" +0x0046c9d0,7,multiplayer_publish_payload_dword0_through_0x518c70,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler leaf that loads dword `[msg+0x08]` and forwards it directly into `0x00518c70`. Current evidence only grounds the forwarding edge, so the label stays structural.","objdump + local disassembly + selector-handler correlation" +0x0046c9e0,3,multiplayer_selector_handler_return_true_stub_2,shell,cdecl,inferred,objdump + local disassembly,1,"Second literal selector-handler stub that returns `1` immediately with no side effects.","objdump + local disassembly + selector-handler correlation" +0x0046c9f0,18,multiplayer_forward_payload_ptr_into_0x50c150_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x0050c150` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046ca10,18,multiplayer_forward_payload_ptr_into_0x50c1f0_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x0050c1f0` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046ca30,18,multiplayer_forward_payload_ptr_into_0x4c66f0_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004c66f0` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046ca50,18,multiplayer_forward_payload_ptr_into_0x4c6760_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004c6760` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046ca70,18,multiplayer_forward_payload_ptr_into_0x4c67d0_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004c67d0` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046ca90,18,multiplayer_forward_payload_ptr_into_0x4c6840_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004c6840` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cab0,18,multiplayer_forward_payload_ptr_into_0x4c68a0_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004c68a0` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cad0,18,multiplayer_forward_payload_ptr_into_0x4c6910_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004c6910` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046caf0,18,multiplayer_forward_payload_ptr_into_0x4c6990_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004c6990` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cb10,18,multiplayer_forward_payload_ptr_into_0x4c6a00_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004c6a00` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cb30,18,multiplayer_forward_payload_ptr_into_0x4b8320_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004b8320` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cb50,18,multiplayer_forward_payload_ptr_into_0x4b8380_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004b8380` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cb70,18,multiplayer_forward_payload_ptr_into_0x4b83e0_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x004b83e0` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cb90,18,multiplayer_forward_payload_ptr_into_0x513050_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x00513050` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cbb0,18,multiplayer_forward_payload_ptr_into_0x511490_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x00511490` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cbd0,18,multiplayer_forward_payload_ptr_into_0x514620_when_length_positive,shell,cdecl,inferred,objdump + local disassembly,2,"Tiny selector-handler wrapper that forwards payload pointer `[msg+0x08]` into `0x00514620` only when payload length `[msg+0x0c]` is positive.","objdump + local disassembly + selector-handler correlation" +0x0046cbf0,101,multiplayer_hash_12byte_payload_queue_selector0x48_request_and_record_match_key,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that copies a 12-byte payload from `[msg+0x08]`, hashes it through `0x0053d870`, inserts the result into local store `0x00468ca0`, and then submits the same payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x48`. This is the clearest current owner for the 12-byte selector-`0x48` hashed request path beneath the callback table.","objdump + local disassembly + caller inspection + selector-0x48 correlation + hashed-payload correlation" +0x0046cc60,97,multiplayer_hash_10byte_payload_queue_selector0x4c_request_and_record_match_key,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback parallel to `0x0046cbf0`. It copies a 10-byte payload from `[msg+0x08]`, hashes it through `0x0053d870`, inserts the result into local store `0x00468ca0`, and submits the payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x4c`. This is the current grounded owner for the 10-byte selector-`0x4c` hashed request path.","objdump + local disassembly + caller inspection + selector-0x4c correlation + hashed-payload correlation" +0x0046ccd0,3,multiplayer_selector_handler_return_true_stub_3,shell,cdecl,inferred,objdump + local disassembly,1,"Third literal selector-handler stub that returns `1` immediately with no side effects.","objdump + local disassembly + selector-handler correlation" +0x0046cce0,46,multiplayer_reset_world_runtime_small_branch_set_launch_warning_latch_and_snapshot_tick,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that, when live world root `0x006cec78` exists, re-enters `0x00434680(0,0,0)`, sets global `0x006cd91c = 1`, and snapshots the current tick from `0x0051d890` into globals `0x006ce990` and `0x006cd8e4`. This is the current grounded owner for one small launch-warning latch and timestamp path beneath the callback table.","objdump + local disassembly + caller inspection + launch-latch correlation + tick-snapshot correlation" +0x0046cd10,28,multiplayer_store_payload_dword0_into_pending_action_value_and_set_state3,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Small selector-handler callback that stores payload dword `[msg+0x08]` into global `0x006d1284` and sets pending state `0x006d1280 = 3`. Current evidence grounds this as one direct pending-action seed beneath the callback table.","objdump + local disassembly + caller inspection + pending-state correlation" +0x0046cd30,218,multiplayer_store_current_session_string_and_scalars_and_publish_selector0x54,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that resolves the current live session entry, copies a NUL string from payload `[msg+0x08]` into entry field `[+0x258c]`, stores one current world-derived scalar into `[+0x268c]`, stores constant `0x006226d0` into `[+0x2690]`, builds one local `0x2c`-byte record, and submits that record through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x54`. This is the current grounded owner for the selector-`0x54` session-string publish path.","objdump + local disassembly + caller inspection + session-entry correlation + selector-0x54 correlation" +0x0046ce10,117,multiplayer_apply_string_and_three_scalars_into_current_session_entry_and_optionally_set_ready_flag,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that copies one payload string plus three following dwords into the current live session entry fields `[+0x258c/+0x268c/+0x2690/+0x2694]`, optionally sets bit `0x01` in entry flags `[+0x5c]`, and republishes the session list through `0x005216d0`. This is the current grounded current-session update companion to the selector-`0x54` submitter at `0x0046cd30`.","objdump + local disassembly + caller inspection + session-entry correlation + current-session correlation" +0x0046ce90,119,multiplayer_advance_pending_action_state_machine_from_payload_byte,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that advances pending-action globals `0x006d127c`, `0x006d1280`, and `0x006d128c` based on the first payload byte at `[msg+0x08]`. The grounded branches switch `0x006d1280` among values `8`, `0xd`, and `9`, which makes this a real pending-state owner beneath the callback table rather than another passive notifier.","objdump + local disassembly + caller inspection + pending-state correlation + state-machine correlation" +0x0046cf10,49,multiplayer_session_entry_set_flag_0x04,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that resolves one live session entry by key `[msg+0x04]` and sets bit `0x04` in entry flags `[entry+0x5c]`. This is the current grounded owner for the flag-`0x04` session-entry latch beneath the callback table.","objdump + local disassembly + caller inspection + session-entry-flag correlation" +0x0046cf40,44,multiplayer_copy_payload_bytes_into_world_runtime_block_0x66be,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that bulk-copies payload bytes from `[msg+0x08]` with count `[msg+0x0c]` into live world root `0x006cec78+0x66be`. Current evidence grounds the destination block but not its exact semantic owner, so the label stays structural.","objdump + local disassembly + caller inspection + world-runtime-block correlation" +0x0046cf70,56,multiplayer_clear_flag_0x01_on_all_live_session_entries,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that walks the live session list from `0x00521680`, clears bit `0x01` in each entry flags word `[entry+0x5c]`, and then republishes the full list through `0x005216a0`. This is the current grounded global clear path for the entry flag toggled by `0x0046c870` and `0x0046ce10`.","objdump + local disassembly + caller inspection + session-entry-flag correlation" +0x0046cfa0,3,multiplayer_selector_handler_return_true_stub_4,shell,cdecl,inferred,objdump + local disassembly,1,"Fourth literal selector-handler stub that returns `1` immediately with no side effects.","objdump + local disassembly + selector-handler correlation" +0x0046cfb0,37,multiplayer_toggle_selector0x67_batch_build_guard_and_call_0x444dd0,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Small selector-handler callback that sets global guard `0x006ce9b8 = 1`, calls `0x00444dd0` with payload fields `[msg+0x08]+8` and `[msg+0x08]+4`, and then clears that same guard. Current evidence only grounds the guard and dispatch shape, so the label stays structural.","objdump + local disassembly + caller inspection + guard-toggle correlation" +0x0046cfe0,163,multiplayer_allocate_transfer_progress_slot_copy_0x5c_record_and_optionally_format_label,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback over the fixed ten-slot transfer-progress table rooted at `0x006ce2e8` with `0x5c`-byte records. It scans for the first free slot, copies one full `0x5c` record from payload `[msg+0x08]` into that slot, and when payload dword `[+0x4c]` is nonzero it formats one auxiliary string through `0x004839e0` and `0x00518de0`, storing the resulting pointer in the slot side field. This is the current grounded allocate-and-seed owner for the local transfer-progress table.","objdump + local disassembly + caller inspection + transfer-progress-table correlation" +0x0046d090,318,multiplayer_append_transfer_progress_payload_update_and_publish_percent_text,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback over the same ten-slot transfer-progress table. When the incoming count word is nonzero it finds the matching `0x5c` slot record in `0x006ce2e8`, appends the payload body through `0x005a276f`, updates slot counters near `[slot+0x54]`, and, when shell status owner `0x006d401c` is live, computes one percentage string through localized id `0x10f6` and publishes it through `0x005387a0`. This is the current grounded progress-update owner for the local transfer table.","objdump + local disassembly + caller inspection + transfer-progress-table correlation + percent-text correlation" +0x0046d1d0,97,multiplayer_clear_transfer_progress_slot_and_release_optional_label,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler callback that finds the matching transfer-progress slot in the fixed ten-slot table rooted at `0x006ce290/0x006ce2e8`, frees the optional per-slot label string when present, and then zeroes the full `0x17`-dword slot record. This is the current grounded clear path for the local transfer-progress table.","objdump + local disassembly + caller inspection + transfer-progress-table correlation" +0x0046d230,10,multiplayer_set_global_transfer_completion_latch,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Tiny selector-handler callback that sets global latch `0x006ce9c8 = 1` and returns. Current evidence only grounds the latch store itself.","objdump + local disassembly + caller inspection + latch-store correlation" +0x0046d240,29,multiplayer_release_selector0x71_batch_staging_blob,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Small cleanup helper that releases the optional staging blob at `0x006ce994` through `0x005a1740` and clears that global. Current local evidence ties it to the same selector-`0x71` batch-record family rooted at `0x006cd990/0x006ce9a0`, so this is the safest current structural read.","objdump + local disassembly + caller inspection + selector-0x71-batch correlation" +0x0046d260,72,multiplayer_append_selector0x71_accumulated_record,shell,fastcall,inferred,objdump + local disassembly + caller inspection,3,"Appends one fixed-width accumulated record to the selector-`0x71` staging band rooted at `0x006cd990`, bounded by count `0x006ce9a0`. The helper rejects new records once the count reaches `0x80`; otherwise it writes a 16-bit leading key from `ECX`, then four caller-supplied dwords into the `0x12`-byte record body, and increments the live record count. This is the direct local append primitive later packaged by `multiplayer_preview_dataset_publish_accumulated_selector0x71_record_batch` `0x00473bf0`.","objdump + local disassembly + caller inspection + selector-0x71-batch correlation + fixed-record correlation" +0x0046d2b0,70,multiplayer_compare_input_scalar_against_rounded_session_build_threshold,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Small predicate that consults the multiplayer preview dataset at `0x006cd8d8`, queries one session-build-derived threshold through `0x0046a4b0`, rounds the caller float argument through the same `+0.0001 * 100 -> round` pattern, and returns `1` when the caller scalar does not exceed that rounded threshold or when no dataset is live. Current evidence grounds the comparison shape but not the exact gameplay meaning, so the label stays structural.","objdump + local disassembly + caller inspection + rounded-threshold correlation" +0x0046d780,111,multiplayer_apply_train_record_fields_into_live_train_entry_by_id,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Applies one small payload record into the live train collection `0x006cfcbc` when the leading id dword resolves and the target train exposes a valid metrics owner through `0x004a77b0`. The helper copies payload dword `[+0x08]` into owner field `[+0x35a]`, forwards payload pair `[+0x0c/+0x10]` into `0x0041c700`, triggers one local refresh through `0x0041ce80(-1,0,0,0)`, and stores payload dword `[+0x04]` into train field `[+0xcc]`. Current local caller is the selector callback wrapper at `0x00472dc0`, so this is the clearest current train-apply leaf beneath that branch.","objdump + local disassembly + caller inspection + live-train-collection correlation + train-apply correlation" +0x0046d980,89,multiplayer_find_collection_0x6ceb9c_entry_index_by_name_string,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Scans indexed collection `0x006ceb9c` and returns the first entry index whose inline string at `[entry+0x08]` matches the caller string through `0x005a57cf`; when no entry matches it returns `0xff`. Current grounded caller is the first fixed named-descriptor callback family beneath `0x0046f4a0`, where the helper supplies one small collection index from a staged name string.","objdump + local disassembly + caller inspection + indexed-collection correlation + string-match correlation" +0x0046d9e0,135,multiplayer_find_collection_0x6ceb9c_entry_index_matching_live_session_string,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Resolves one live session object from `0x006d40d0` through `0x00521d60`, scans indexed collection `0x006ceb9c` for the first entry whose inline string at `[entry+0x08]` matches the session-side string at `[session+0x08]`, returns that entry index or `0xff` when none match, and then releases the same session object through `0x005216d0`. This is the heavier live-session-backed companion to `0x0046d980` and the direct matcher used by `0x0046f8f0`.","objdump + local disassembly + caller inspection + live-session correlation + indexed-collection correlation + string-match correlation" +0x0046d300,560,multiplayer_service_transfer_progress_slots_and_publish_selector0x80_or_0x81,shell,thiscall,inferred,objdump + local disassembly + caller inspection,4,"Services the fixed ten-slot transfer-progress table rooted at `0x006ce290` with `0x5c`-byte records. For every live slot belonging to the current session owner it probes transport progress through `0x00522990`, repeatedly extracts chunk sizes up to `0xf00`, and, when no payload body has been staged yet, submits those chunks through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` using selector `0x80`; when the slot already carries staged body state it instead submits the four-byte follow-on request through selector `0x81`, frees the slot-owned payload buffer, and clears the full slot. In parallel it publishes localized progress text `0x10f5` through shell status owner `0x006d401c` and caches the active dataset pointer in `0x006ce9cc`. This is therefore the concrete service owner above the local transfer-progress table, not just another selector callback.","objdump + local disassembly + caller inspection + transfer-progress-table correlation + selector-0x80-correlation + selector-0x81-correlation" +0x0046d530,117,multiplayer_count_live_transfer_progress_slots,shell,cdecl,inferred,objdump + local disassembly + caller inspection,2,"Counts the currently occupied slots in the fixed transfer-progress pointer strip rooted at `0x006ce2d8..0x006ce614`. The helper returns the number of non-null slot pointers across that ten-entry band. Current evidence grounds this as a local occupancy counter for the same transfer-progress family serviced by `0x0046d300`.","objdump + local disassembly + caller inspection + transfer-progress-table correlation" +0x0046d610,38,multiplayer_preview_dataset_stage_optional_selected_token_from_source_ptr,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small staging helper that writes one optional derived token into `[this+0x8f38]`. When the caller passes a non-null source pointer, the helper transforms it through `0x0051d3c0` and stores the result; otherwise it clears `[this+0x8f38]` to zero. Current grounded callers are the launch-side branches around `0x0046f67e` and `0x0046f7ac`, which use this immediately after `0x0046b6d0` updates the staged tuple path.","objdump + local disassembly + caller inspection + staging-buffer correlation" +0x0046db10,58,multiplayer_fixed_named_callback_root_build_tag0x0a_world_year_tuple,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"First concrete root in the fixed named-callback block registered by `0x00473a60`. When live world roots `0x006cec78` and `0x0062c120` are present, the helper writes local tag byte `0x0a` plus zero payload into static block `0x006ce9dc`, derives one world-year key from `[world+0x0d]` through `0x0051d3c0`, stores that derived dword into the same block, and returns the block pointer. This is the safest current structural read for the first fixed named-callback root rather than a guessed descriptor caption.","objdump + local disassembly + registration-block correlation + world-year-key correlation" +0x0046db50,60,multiplayer_fixed_named_callback_root_build_tag0x09_from_global_6cd92c_and_world_year_tuple,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"Second concrete root in the fixed named-callback block beneath `0x00473a60`. When the live world roots are present it writes tag byte `0x09` into static block `0x006ce9e8`, copies global dword `0x006cd92c` into that block, derives the world-year key from `[0x006cec78+0x0d]` through `0x0051d3c0`, stores it, and returns the block pointer. Current evidence grounds the tuple shape but not the higher semantic field name.","objdump + local disassembly + registration-block correlation + world-year-key correlation" +0x0046db90,61,multiplayer_fixed_named_callback_root_build_tag0x07_from_0x46da70_and_world_year_tuple,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"Third concrete root in the fixed named-callback block beneath `0x00473a60`. When the live world roots are present it writes tag byte `0x07` into static block `0x006ce9f4`, derives one auxiliary dword through local helper `0x0046da70`, derives the world-year key from `[0x006cec78+0x0d]` through `0x0051d3c0`, stores both values into that block, and returns the block pointer.","objdump + local disassembly + registration-block correlation + world-year-key correlation" +0x0046dbd0,317,multiplayer_fixed_named_callback_root_build_tag0x06_from_collection_0x62be10,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"Concrete root in the fixed named-callback block that builds static record `0x006cea00`. The helper writes tag byte `0x06`, stores the current world-year key from `[0x006cec78+0x0d]`, then walks indexed collection `0x0062be10` and accumulates a weighted total from several per-entry scalar fields together with world-side mode-dependent bonus terms before storing the result and returning the block pointer. This is the current grounded collection-backed fixed named-callback root above the same registration block `0x00473a60`.","objdump + local disassembly + registration-block correlation + indexed-collection correlation" +0x0046dd10,294,multiplayer_fixed_named_callback_root_build_tag0x05_from_collection_0x6ceb9c,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"Concrete root in the fixed named-callback block that builds static record `0x006cea0c`. The helper writes tag byte `0x05`, stores the current world-year key from `[0x006cec78+0x0d]`, then walks indexed collection `0x006ceb9c`, hashes one inline string field through `0x0053d810`, adds several per-entry scalar fields and mode-dependent bonus terms, accumulates the total, and returns the finished record block. Current evidence keeps the field name structural, but the owner is now explicit.","objdump + local disassembly + registration-block correlation + indexed-collection correlation + hashed-string correlation" +0x0046de40,52,multiplayer_fixed_named_callback_root_build_tag0x04_and_cached_counter,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"Small fixed named-callback root that writes tag byte `0x04` into static block `0x006cea18`, stores the current world-year key from `[0x006cec78+0x0d]`, queries one cached counter through `0x00518c60`, stores that dword into the same block, and returns the block pointer. Current grounded owner is the first fixed named-descriptor block registered by `0x00473a60`.","objdump + local disassembly + registration-block correlation + cached-counter correlation" +0x0046de80,425,multiplayer_fixed_named_callback_root_build_tag0x01_from_collection_0x62b26c_and_local_overlay_samples,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"Broader fixed named-callback root that builds static record `0x006cea24`. After writing tag byte `0x01` and the current world-year key from `[0x006cec78+0x0d]`, the helper walks indexed collection `0x0062b26c`, filters entries through local predicate `0x0040c990`, accumulates several per-entry scalar bands including object fields `[+0x246/+0x29e/+0x3cc]`, queries one local bounds tuple through `0x0052e720`, projects that tuple through `0x004142e0`, samples the live world raster through `0x00448aa0`, and stores the final accumulated total into the static record before returning it. This is the clearest current collection-plus-overlay fixed named-callback root beneath `0x00473a60`, though the descriptor caption above it remains open.","objdump + local disassembly + registration-block correlation + indexed-collection correlation + world-raster-sample correlation" +0x0046e030,539,multiplayer_fixed_named_callback_root_build_tag0x02_from_route_entry_collection_and_overlay_geometry_samples,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"Broader fixed named-callback root that builds static record `0x006cea30`. The helper writes tag byte `0x02`, stores the current world-year key from `[0x006cec78+0x0d]`, and then walks the live route-entry collection `0x006cfca8`, keeping only entries whose byte `[entry+0x216]` equals `2`. For each surviving entry it accumulates multiple local scalar bands, projected bounds from `0x0048a170`, auxiliary values from `0x0048a020`, and one geometry-derived magnitude from `0x005394b0` before storing the final total in the static record and returning it. This is the current grounded route-entry-backed member of the fixed named-callback family beneath `0x00473a60`.","objdump + local disassembly + registration-block correlation + route-entry-collection correlation + geometry-sample correlation" +0x0046e250,868,multiplayer_fixed_named_callback_root_build_tag0x03_from_collection_0x6cfcbc_and_object_metric_bands,shell,cdecl,inferred,objdump + local disassembly + registration-block correlation,3,"Broader fixed named-callback root that builds static record `0x006cea3c`. The helper writes tag byte `0x03`, stores the current world-year key from `[0x006cec78+0x0d]`, then walks collection `0x006cfcbc` and accumulates several per-entry metric bands through `0x004a77b0`, `0x0052e720`, `0x004a6e60`, and `0x004a8880`, followed by a long run of inline scalar-field adjustments and a final city-database-derived handle or float term through `0x0041ab80`. The exact descriptor caption remains open, but this is clearly another concrete collection-backed static-record root in the fixed named-callback family registered under `0x00473a60`.","objdump + local disassembly + registration-block correlation + collection-correlation + metric-band correlation" +0x0046e5c0,1754,multiplayer_build_or_apply_dual_collection_metric_blob_by_mode,shell,thiscall,inferred,objdump + local disassembly + registration-block correlation,3,"Broader multiplayer-side blob owner directly adjacent to the fixed named-callback strip. In mode `1` it serializes a dual-collection metric blob through the caller out-pointer: first it walks collection `0x0062be10`, capturing one `0x24`-byte metric row per entry from repeated `0x0042a5d0` probes plus entry field `[+0x47]`; then it walks collection `0x006ceb9c`, capturing one `0x2c`-byte metric row per entry from fields `[+0x154..+0x181]`; it stores the two row counts into local header bytes `[this+0x0d/+0x0e]`, allocates one contiguous blob of size `0x10 + count0*0x24 + count1*0x2c`, copies the local header plus both metric bands into that blob, and returns it through the caller out-slot. The non-`1` branch begins the reverse apply path by validating the stored per-entry metric rows against the live collections and writing back mismatched values into the live entries. This is therefore a real dual-collection metric snapshot/apply owner, not another tiny selector leaf.","objdump + local disassembly + dual-collection correlation + metric-blob correlation + apply-path correlation" +0x0046f4a0,928,multiplayer_preview_dataset_default_selector_callback_dispatch_first_named_descriptor_block,shell,thiscall,inferred,objdump + local disassembly + registration-root correlation,4,"Default callback root seeded into `[0x006cd8d8+0x08]` by `multiplayer_preview_dataset_reset_global_callback_state_and_register_selector_handlers` `0x00473280`. The helper switches on selector id `[this+0x10]` and, for the first fixed named-descriptor family, dispatches a concrete mix of mode writes, staged-path synchronization, chat/status publication, session-identity comparison, tuple staging, selector-`0x58` submission, and keyed-bucket pruning. The simple arms map selector values `1..7` into dataset mode dword `[0x006cd8d8+0x0c]` plus one auxiliary store at `[+0x8f1c]`, while the heavier arms stage the current session path through `multiplayer_preview_dataset_stage_selected_path` `0x00469700`, publish localized status text through either `0x004554e0` or `multiplayer_preview_dataset_append_named_ui_request_record` `0x00469a50`, refresh the staged tuple through `0x0046b6d0` and token lane `0x0046d610`, submit selector `0x58` through `0x00469d30`, and prune old keyed buckets through `0x0046b910`. This is therefore the real default selector-dispatch root for the first named-descriptor block, not just a passive callback pointer.","objdump + local disassembly + registration-root correlation + selector-dispatch correlation + named-descriptor correlation" +0x0046f870,124,multiplayer_apply_rounded_float_delta_to_company_entry_metric_pair_by_index_byte,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Helper beneath the first fixed named-descriptor callback family that treats the caller payload as one float plus one collection byte index. It resolves the indexed company-style entry from `0x0062be10`, validates it through `0x00425b90`, rounds the input float through `0x005a10d0`, then writes the positive rounded value into metric id `0x0f` and the negated rounded value into metric id `0x0d` through `0x0042a040`. Current direct callers build the temporary two-field payload on the stack before calling this leaf, which keeps the helper bounded as a small rounded-delta apply path rather than a broader callback owner.","objdump + local disassembly + caller inspection + indexed-company-entry correlation + rounded-delta correlation" +0x0046f8f0,97,multiplayer_resolve_company_entry_by_index_if_live_session_profile_index_matches,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Resolves one indexed entry from `0x0062be10`, validates it through `0x00425b90`, derives the current live-session-backed name index through `multiplayer_find_collection_0x6ceb9c_entry_index_matching_live_session_string` `0x0046d9e0`, and returns the company entry only when its profile-index field `[entry+0x3b]` matches that derived `0x006ceb9c` index. Otherwise it returns null. Current callers use this as the stricter collection-match gate beneath several first-block fixed descriptor callbacks.","objdump + local disassembly + caller inspection + live-session correlation + indexed-company-entry correlation + profile-index correlation" 0x0046f960,2209,multiplayer_dispatch_chat_command,shell,cdecl,inferred,ghidra-headless,4,Parses and dispatches one slash-prefixed Multiplayer.win chat command line from `[eax+0x08]`. The parser normalizes `/` to `\\` and handles the grounded command family `\\kick` `\\clear` `\\whois` `\\me` `\\unban` `\\ban` `\\snore` `\\sneeze` `\\hurry` `\\trackisfree` `\\loadgame` and `\\sendgame`. The strongest branches are now clear: `\\kick` resolves a typed peer name through the active session tables and forwards the resulting peer object through multiplayer_request_peer_session_control when the target is neither null nor the local player; `\\clear` clears the local chat pane through multiplayer_publish_wrapped_chat_message(null); `\\whois` finds a named peer and emits multi-line `%s Ip = %s` `Cpu` `Game` and `Build Time` diagnostics through multiplayer_route_chat_line; `\\ban` and `\\unban` resolve either a dotted player name or the selected peer name then update the semicolon-delimited moderation list through multiplayer_update_semicolon_name_list with add/remove modes while `\\unban` can also forward a live peer object through multiplayer_request_peer_session_control; `\\snore` `\\sneeze` and `\\hurry` build transient presentation objects then broadcast text ids `0xb79` `0xb7a` and `0xb7b`; `\\loadgame` copies the requested filename into `0x006ce630` and arms flag `0x006ce9bc`; `\\trackisfree` arms flag `0x006ce9b4`; and `\\sendgame` allocates one 0x5c-byte transfer record under `0x006ce290` for the chosen player slot. The parser returns `1` only when a command branch handled the line and otherwise leaves the caller to treat it as ordinary chat text.,ghidra + rizin + llvm-objdump + strings +0x00470290,352,multiplayer_selector0x02_compare_staged_profile_text_sync_shell_profile_block_and_maybe_queue_selector0x53,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that compares the caller string at `[payload+0x11]` against the current shell profile string at `[0x006cec7c+0x11]` through `0x005a57cf`, optionally validates that staged profile text through `0x0046d7f0`, and then branches on requested action id `0x006d127c`. In the action-`3` lane it either advances the requested-action state fields `0x006d1280/0x006d1284` or queues selector `0x53` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30`. On the common success path it syncs the larger shell profile block rooted at `[0x006cec7c+0x44]` from the incoming payload, optionally overrides that block from `0x006ce670`, re-enters `0x004f13e0(1)`, refreshes `[0x006cec7c+0x83]` through `0x00518c70`, and stores one filename-presence flag into `0x006ce9bc` from `0x005c9cf8`. This is the clearest current structural read for the early selector-`0x02` branch beneath the preview-dataset callback table.","objdump + local disassembly + registration-pass correlation + selector-0x02 correlation + staged-profile correlation + requested-action correlation" +0x004703f0,224,multiplayer_selector0x0a_reset_world_session_owner_sync_profile_bytes_and_refresh_local_status,shell,cdecl,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that clears `[world+0x19]`, re-enters `0x0046a390(1)`, seeds world field `[world+0x66ae] = 1`, and refreshes local multiplayer state through `0x0053f000(1,0,1)`. It then walks the live session peer list from `0x006d40d0`, derives each peer's named-profile index through `0x0046d980`, and mirrors peer byte `[peer+0x2690]` into named-profile byte `[entry+0x15c]` for the corresponding `0x006ceb9c` entry. Before returning it refreshes `0x006ce98c` through `0x0051d890`, optionally publishes localized status `0x005c87a8` through `0x00538c70`, and when the session object `0x006d40dc` is live re-enters `0x00434680(3,1,0)`. This is the clearest current structural read for selector `0x0a` beneath the preview-dataset callback table.","objdump + local disassembly + registration-pass correlation + selector-0x0a correlation + world-session correlation + named-profile-byte correlation" +0x004704d0,96,multiplayer_selector0x0b_stage_current_token_and_publish_selector0x0c_when_session_guard_is_set,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that checks session-side guard dword `[EDX+0x50]` and, when that guard is nonzero, stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x0c`. This is the clean local selector-`0x0b` wrapper immediately above the heavier selector-`0x0c` branch.","objdump + local disassembly + registration-pass correlation + selector-0x0b correlation + selector-0x0c correlation + staged-token correlation" +0x00470530,96,multiplayer_selector0x0c_apply_signed_byte_pair_through_0x434680_and_adjust_dataset_counter,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, rejects work when dataset gate `0x006cd91c` is set, and otherwise forwards the signed byte pair at `[payload+0x00/+0x01]` into `0x00434680(leader, 0, follower)`. On success it then adjusts dataset counter `0x006cd8e8` based on whether `[world+0x19]` is currently nonzero and stores scalar `0x3c` into `0x005f2b38`. This is the clearest current structural read for selector `0x0c` above that signed-pair apply lane.","objdump + local disassembly + registration-pass correlation + selector-0x0c correlation + world-helper-0x434680 correlation + dataset-counter correlation" +0x00470590,96,multiplayer_selector0x0f_pop_head_session_queue_node_publish_record_and_release_it,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that resolves the current live-session object through `0x00521d40`, pops the head node from its queue owner at `[session+0x64]`, and when a node is present submits that node's fields through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` using dataset string root `[0x006cd8d8+0x8f48]`, selector id from the leading node word, and the node's stacked scalar fields `[+0x08/+0x0c/+0x10/+0x14]`. It then releases the consumed node through `0x00469890`. This is the clearest current structural read for selector `0x0f` beneath the preview-dataset callback table.","objdump + local disassembly + registration-pass correlation + selector-0x0f correlation + session-queue correlation + record-publish correlation" +0x004705f0,64,multiplayer_selector0x10_lookup_current_session_key_in_store0x60_and_forward_string_root,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that resolves the current live-session object through `0x00521d40`, looks up payload dword `[payload+0x00]` in the session-side keyed owner at `[session+0x60]` through `0x0053dae0`, and when a match exists forwards that resolved entry plus dataset string root `[0x006cd8d8+0x8f48]` into live-session helper `0x00521790`. This is the clearest current structural read for selector `0x10` beneath the preview-dataset callback table.","objdump + local disassembly + registration-pass correlation + selector-0x10 correlation + session-store correlation + string-root forward correlation" +0x004706b0,517,multiplayer_selector0x13_match_company_entry_try_place_payload_and_publish_selector0x6e_hash_fallback,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes a structured payload from `[this+0x08]`, resolves the matching company-style entry through `multiplayer_resolve_company_entry_by_index_if_live_session_profile_index_matches` `0x0046f8f0`, and on the active branch tries to validate and materialize the payload into the placed-structure world through `placed_structure_validate_projected_candidate_placement` `0x004197e0`, `0x0046eec0`, `placed_structure_collection_allocate_and_construct_entry` `0x004134d0`, `0x0040eba0`, and the nearby runtime-object refresh leaves `0x0052eb90` and `0x0040ef10`. When no compatible company entry is live but the multiplayer session object exists, it instead stages the current year-derived token into `[0x006cd8d8+0x8f38]`, hashes the first `0x1c` payload bytes through `0x0053d870`, and submits the compact fallback through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x6e`. Empty-input failure falls back to localized status id `0x0b7c`. This is the safest current structural read for the selector-`0x13` owner above that hashed selector-`0x6e` fallback lane.","objdump + local disassembly + caller inspection + selector-0x13 correlation + selector-0x6e correlation + placed-structure correlation" +0x00470630,126,multiplayer_selector0x12_validate_payload_and_publish_selector0x13_or_error,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes payload pointer `[this+0x08]`, validates that payload through `0x0046ef40(1)`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x13` and fixed payload length `0x1c`. When validation fails it instead forwards the paired error-style selector-`0x13` payload through the `0x21` branch using the caller fallback buffer from `EDX+0x08`. This is the clean local selector-`0x12` wrapper immediately above the heavier selector-`0x13` placement or hash-fallback body.","objdump + local disassembly + caller inspection + selector-0x12 correlation + selector-0x13 correlation + validation-gate correlation" +0x004708c0,141,multiplayer_selector0x14_validate_payload_and_publish_selector0x15_or_error,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes payload pointer `[this+0x08]`, validates that payload against the caller-side session or company context through `0x0046f0a0`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x15`. When the validation path fails it instead forwards the paired error-style selector-`0x15` payload through the `0x21` branch using the caller fallback buffer from `EDX+0x08`. This is the safest current read for the selector-`0x14` owner above the narrower selector-`0x15` delta-apply body rather than another direct local mutation helper.","objdump + local disassembly + caller inspection + selector-0x14 correlation + selector-0x15 correlation + validation-gate correlation" +0x00470950,431,multiplayer_selector0x15_match_company_entry_publish_selector0x6b_metric_delta_and_apply_locally,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes a 5-byte payload `(float delta, company-index byte)` from `[this+0x08]`, resolves the matching company-style entry through `multiplayer_resolve_company_entry_by_index_if_live_session_profile_index_matches` `0x0046f8f0`, temporarily masks world latch `[0x006cec78+0x4aab]` while validating the local session/company relation through `0x0046f0a0`, and on the active branch stages the current year-derived token into `[0x006cd8d8+0x8f38]`, submits the same compact update through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x6b`, updates local counters `[0x006cd8d8+0x987c/+0x9880]`, and immediately re-enters `multiplayer_apply_rounded_float_delta_to_company_entry_metric_pair_by_index_byte` `0x0046f870`. When the required entry match fails it falls back to localized status id `0x0b86`. This is the tightest current read for the selector-`0x15` owner above the smaller selector-`0x6b` apply leaf.","objdump + local disassembly + caller inspection + selector-0x15 correlation + selector-0x6b correlation + company-entry correlation" +0x00470b20,136,multiplayer_selector0x16_validate_payload_and_publish_selector0x17_or_error,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes payload pointer `[this+0x08]`, validates that payload through `0x0046edb0`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x17` and fixed request kind `0x19`. When validation fails it instead forwards the paired error-style selector-`0x17` payload through the `0x21` branch using the caller fallback buffer from `EDX+0x08`. This is the clean local selector-`0x16` wrapper immediately above the heavier selector-`0x17` live-world apply body.","objdump + local disassembly + caller inspection + selector-0x16 correlation + selector-0x17 correlation + validation-gate correlation" +0x00470bb0,428,multiplayer_selector0x17_match_company_entry_apply_0x33_stride_records_and_publish_selector0x6e_fallback,shell,thiscall,inferred,objdump + local disassembly + caller inspection,4,"Heavier selector-handler body that consumes a structured payload from `[this+0x08]`, resolves the matching company-style entry through `multiplayer_resolve_company_entry_by_index_if_live_session_profile_index_matches` `0x0046f8f0` using payload dwords `[+0x0c/+0x10]`, and on the active branch first folds the count-prefixed `0x33`-stride adjunct records from `[payload+0x14]` through local helpers `0x004b2ba0` and `0x004b3160`, then allocates or resolves one live train-side entry through `0x004b2140` against collection `0x006cfcbc`, applies optional subtype field `[payload+0x08]` through `0x004abd70`, resolves the train metrics owner through `0x004a77b0`, and finally re-enters `0x0052e720` plus the nearby refresh leaves under `0x0040eba0`, `0x0052eb90`, and `0x0040ef10`. When that apply path does not land a live entry but the multiplayer session object exists, it stages the current year-derived token into `[0x006cd8d8+0x8f38]`, hashes the first `0x14` payload bytes through `0x0053d870`, and submits the compact fallback through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x6e`. Empty-input failure falls back to localized status id `0x0b7e`. This is the safest current structural read for selector `0x17` above that hashed selector-`0x6e` fallback lane.","objdump + local disassembly + caller inspection + selector-0x17 correlation + selector-0x6e correlation + live-train correlation" +0x00470da0,139,multiplayer_selector0x19_validate_payload_and_publish_selector0x1a_or_error,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes payload pointer `[this+0x08]`, validates that payload through `0x0046ed30`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x1a` and fixed request kind `0x19`. When validation fails it instead forwards the paired error-style selector-`0x1a` payload through the `0x21` branch using the caller fallback buffer from `EDX+0x08`. This is the clean local selector-`0x19` wrapper immediately above the selector-`0x1a` status or apply branch.","objdump + local disassembly + caller inspection + selector-0x19 correlation + selector-0x1a correlation + validation-gate correlation" +0x00470e30,156,multiplayer_selector0x1a_query_or_publish_session_name_match_status,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes payload from `[this+0x08]` and branches on payload length `[this+0x0c]`. When the payload is not exactly four bytes, the helper first queries a local status code through `0x0046ed30`; on zero it forwards the payload into `0x0047d320`, while on nonzero it resolves the named `0x006ceb9c` entry from payload dword `[+0x00]`, compares that entry string against the current live session string, and uses the resulting status code to publish one localized status text `0x0b7f` or `0x0b80` through `0x00469a50` after refreshing `0x0053f000`. When the payload length is exactly four bytes it instead treats payload dword `[+0x00]` as the direct status code. This is the safest current structural read for selector `0x1a` above that session-name-match status branch rather than a broader world mutation owner.","objdump + local disassembly + caller inspection + selector-0x1a correlation + live-session-string correlation + status-text correlation" +0x00470ed0,208,multiplayer_reset_named_profile_activation_and_apply_positive_company_metric0x0d_preset,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Global reset or normalize pass over the two live multiplayer collections that first walks `0x006ceb9c` and, for every entry whose guard dword `[entry+0x1e1]` is nonzero, forwards constant `0x004c4b40` into `0x00476050`; it then walks the live company collection `0x0062be10` and, for every entry accepted by `0x00425b90`, writes preset scalar `0x4a989680` into metric id `0x0d` through `0x0042a040`. Current registration pressure places this helper immediately beside the selector-`0x1c` callback band inside the multiplayer preview-dataset callback table.","objdump + local disassembly + caller inspection + 0x6ceb9c-correlation + company-metric correlation + selector-band adjacency" +0x00470fa0,208,multiplayer_reset_named_profile_activation_and_apply_negative_company_metric0x0d_preset,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Companion global reset or normalize pass parallel to `0x00470ed0`. It walks the same guarded `0x006ceb9c` entry family and forwards constant `0xfffe7960` into `0x00476050`, then walks `0x0062be10` and, for every entry accepted by `0x00425b90`, writes preset scalar `0xc7c35000` into metric id `0x0d` through `0x0042a040`. Current selector-table adjacency keeps this bounded as the alternate preset sibling of `0x00470ed0` beneath the same multiplayer callback band.","objdump + local disassembly + caller inspection + 0x6ceb9c-correlation + company-metric correlation + selector-band adjacency" +0x00471070,96,multiplayer_selector0x1d_stage_current_token_and_publish_selector0x1e,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x1e` and fixed request kind `0x19`. This is the clean local selector-`0x1d` wrapper immediately above the registered selector-`0x1e` branch.","objdump + local disassembly + registration-pass correlation + selector-0x1d correlation + selector-0x1e correlation + staged-token correlation" +0x004710d0,96,multiplayer_selector0x1f_stage_current_token_and_publish_selector0x20,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x20` and fixed request kind `0x19`. This is the clean local selector-`0x1f` wrapper immediately above the registered selector-`0x20` branch.","objdump + local disassembly + registration-pass correlation + selector-0x1f correlation + selector-0x20 correlation + staged-token correlation" +0x00471130,96,multiplayer_selector0x21_stage_current_token_and_publish_selector0x22,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x22` and fixed request kind `0x19`. This is the clean local selector-`0x21` wrapper immediately above the registered selector-`0x22` branch.","objdump + local disassembly + registration-pass correlation + selector-0x21 correlation + selector-0x22 correlation + staged-token correlation" +0x00471190,96,multiplayer_selector0x23_stage_current_token_and_publish_selector0x24,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x24` and fixed request kind `0x19`. This is the clean local selector-`0x23` wrapper immediately above the registered selector-`0x24` branch.","objdump + local disassembly + registration-pass correlation + selector-0x23 correlation + selector-0x24 correlation + staged-token correlation" +0x004711f0,96,multiplayer_selector0x25_stage_current_token_and_publish_selector0x26,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x26` and fixed request kind `0x19`. This is the clean local selector-`0x25` wrapper immediately above the registered selector-`0x26` branch.","objdump + local disassembly + registration-pass correlation + selector-0x25 correlation + selector-0x26 correlation + staged-token correlation" +0x00471250,96,multiplayer_selector0x27_stage_current_token_and_publish_selector0x28,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x28` and fixed request kind `0x19`. This is the clean local selector-`0x27` wrapper immediately above the registered selector-`0x28` branch.","objdump + local disassembly + registration-pass correlation + selector-0x27 correlation + selector-0x28 correlation + staged-token correlation" +0x004712b0,96,multiplayer_selector0x29_stage_current_token_and_publish_selector0x2a,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x2a` and fixed request kind `0x19`. This is the clean local selector-`0x29` wrapper immediately above the registered selector-`0x2a` branch.","objdump + local disassembly + registration-pass correlation + selector-0x29 correlation + selector-0x2a correlation + staged-token correlation" +0x00471310,96,multiplayer_selector0x2b_stage_current_token_and_publish_selector0x2c,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x2c` and fixed request kind `0x19`. This is the clean local selector-`0x2b` wrapper immediately above the registered selector-`0x2c` branch.","objdump + local disassembly + registration-pass correlation + selector-0x2b correlation + selector-0x2c correlation + staged-token correlation" +0x00471370,96,multiplayer_selector0x2d_stage_current_token_and_publish_selector0x2e,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x2e` and fixed request kind `0x19`. This is the clean local selector-`0x2d` wrapper immediately above the registered selector-`0x2e` branch.","objdump + local disassembly + registration-pass correlation + selector-0x2d correlation + selector-0x2e correlation + staged-token correlation" +0x004713d0,96,multiplayer_selector0x2f_stage_current_token_and_publish_selector0x30,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x30` and fixed request kind `0x19`. This is the clean local selector-`0x2f` wrapper immediately above the registered selector-`0x30` branch.","objdump + local disassembly + registration-pass correlation + selector-0x2f correlation + selector-0x30 correlation + staged-token correlation" +0x00471430,96,multiplayer_selector0x31_stage_current_token_and_publish_selector0x32,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x32` and fixed request kind `0x19`. This is the clean local selector-`0x31` wrapper immediately above the registered selector-`0x32` branch.","objdump + local disassembly + registration-pass correlation + selector-0x31 correlation + selector-0x32 correlation + staged-token correlation" +0x00471490,96,multiplayer_selector0x33_stage_current_token_and_publish_selector0x34,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x34` and fixed request kind `0x19`. This is the clean local selector-`0x33` wrapper immediately above the registered selector-`0x34` branch.","objdump + local disassembly + registration-pass correlation + selector-0x33 correlation + selector-0x34 correlation + staged-token correlation" +0x004714f0,96,multiplayer_selector0x35_stage_current_token_and_publish_selector0x36,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x36` and fixed request kind `0x19`. This is the clean local selector-`0x35` wrapper immediately above the registered selector-`0x36` branch.","objdump + local disassembly + registration-pass correlation + selector-0x35 correlation + selector-0x36 correlation + staged-token correlation" +0x00471550,96,multiplayer_selector0x37_stage_current_token_and_publish_selector0x38,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x38` and fixed request kind `0x19`. This is the clean local selector-`0x37` wrapper immediately above the registered selector-`0x38` branch.","objdump + local disassembly + registration-pass correlation + selector-0x37 correlation + selector-0x38 correlation + staged-token correlation" +0x004715b0,96,multiplayer_selector0x39_stage_current_token_and_publish_selector0x3a,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x3a` and fixed request kind `0x19`. This is the clean local selector-`0x39` wrapper immediately above the registered selector-`0x3a` branch.","objdump + local disassembly + registration-pass correlation + selector-0x39 correlation + selector-0x3a correlation + staged-token correlation" +0x00471610,112,multiplayer_selector0x3b_resolve_live_train_id_and_publish_selector0x3c,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside live collection `0x006cfcbc`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x3c`. This is the clean local selector-`0x3b` wrapper immediately above the narrower selector-`0x3c` live-train apply branch.","objdump + local disassembly + registration-pass correlation + selector-0x3b correlation + selector-0x3c correlation + live-train correlation" +0x00471680,64,multiplayer_selector0x3c_resolve_live_train_and_dispatch_local_handler_0x4abd70,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside `0x006cfcbc`, and on success forwards the resolved train entry plus payload dword `[+0x08]` into local handler `0x004abd70`. This is the clearest current structural read for selector `0x3c` above that narrow live-train dispatch lane.","objdump + local disassembly + registration-pass correlation + selector-0x3c correlation + live-train correlation + local-handler correlation" +0x004716c0,112,multiplayer_selector0x3d_resolve_live_train_id_and_publish_selector0x3e,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside live collection `0x006cfcbc`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x3e`. This is the clean local selector-`0x3d` wrapper immediately above the narrower selector-`0x3e` live-train dispatch branch.","objdump + local disassembly + registration-pass correlation + selector-0x3d correlation + selector-0x3e correlation + live-train correlation" +0x00471730,80,multiplayer_selector0x3e_resolve_live_train_and_dispatch_local_handler_0x4b2f00,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside `0x006cfcbc`, and on success forwards the resolved train entry plus payload dword `[+0x08]` and flag `1` into local handler `0x004b2f00`. This is the clearest current structural read for selector `0x3e` above that narrow live-train dispatch lane.","objdump + local disassembly + registration-pass correlation + selector-0x3e correlation + live-train correlation + local-handler correlation" +0x00471780,112,multiplayer_selector0x3f_resolve_live_train_id_and_publish_selector0x40,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside live collection `0x006cfcbc`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x40`. This is the clean local selector-`0x3f` wrapper immediately above the narrower selector-`0x40` live-train dispatch branch.","objdump + local disassembly + registration-pass correlation + selector-0x3f correlation + selector-0x40 correlation + live-train correlation" +0x004717f0,64,multiplayer_selector0x40_resolve_live_train_and_dispatch_local_handler_0x4b3000,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside `0x006cfcbc`, and on success forwards the resolved train entry plus payload dword `[+0x08]` into local handler `0x004b3000`. This is the clearest current structural read for selector `0x40` above that narrow live-train dispatch lane.","objdump + local disassembly + registration-pass correlation + selector-0x40 correlation + live-train correlation + local-handler correlation" +0x00471830,112,multiplayer_selector0x41_resolve_live_train_id_and_publish_selector0x42,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside live collection `0x006cfcbc`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x42`. This is the clean local selector-`0x41` wrapper immediately above the heavier selector-`0x42` live-train interaction branch.","objdump + local disassembly + registration-pass correlation + selector-0x41 correlation + selector-0x42 correlation + live-train correlation" +0x004718a0,176,multiplayer_selector0x42_update_live_train_adjunct_and_dispatch_local_action_code,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside `0x006cfcbc`, and on success re-enters the train-side adjunct family `0x004b2b70`, `0x004b3160`, and `0x004b2c10` using the caller record band at `[payload+0x08]`. When the first `0x004b2c10(-1,0,0,-1)` gate fails it then branches on `0x004a9460`: the positive lane retries `0x004b2c10(-1,1,0,-1)` and dispatches local action code `0x13` through `0x004ab980`, while the fallback lane dispatches local action code `0x0a`. This is the safest current structural read for selector `0x42` above that train-side adjunct and action-code branch.","objdump + local disassembly + registration-pass correlation + selector-0x42 correlation + live-train correlation + local-train-adjunct correlation" +0x00471950,112,multiplayer_selector0x43_resolve_live_train_id_and_publish_selector0x44,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves train id `[payload+0x04]` inside live collection `0x006cfcbc`, and on success stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x44`. This is the clean local selector-`0x43` wrapper immediately above the registered selector-`0x44` branch.","objdump + local disassembly + registration-pass correlation + selector-0x43 correlation + selector-0x44 correlation + live-train correlation" +0x004719c0,112,multiplayer_complete_selector0x48_prompt_result_and_publish_selector0x49,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Prompt-result callback used by the selector-`0x48` request family. The helper treats `[this+0x1c]` as one `0x0c`-byte staged record, derives one bit position from the current live session through `0x00521d40` and `0x0046d980`, sets that bit in record dword `[record+0x08]`, forces the same bit again when the prompt result code in `EDX` equals `0x3f2`, then republishes the updated `0x0c`-byte record through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x49` and dataset string root `[0x006cd8d8+0x8f48]`.","objdump + local disassembly + caller inspection + selector-0x48 correlation + selector-0x49 correlation + prompt-result correlation" +0x00471a30,352,multiplayer_selector0x48_match_or_prompt_12byte_record_and_publish_selector0x49,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body for the 12-byte hashed request family seeded by `0x0046cbf0`. It treats `[this+0x08]` as one `0x0c`-byte record, derives the current live-session bit position through `0x00521d40` and `0x0046d980`, and when payload dword `[+0x00]` matches the current live session id simply sets that bit in record dword `[+0x08]` before publishing selector `0x49`. Otherwise it resolves the `0x006ceb9c` and `0x0062be10` entries selected by payload bytes `[+0x05]` and `[+0x04]`, and either marks the same bit directly or formats localized status `0x0b81` into `0x006ce700` and opens a prompt through `0x00469a50` with follow-on callback `0x004719c0`. In both branches the final publish uses `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x49`.","objdump + local disassembly + registration-pass correlation + selector-0x48 correlation + selector-0x49 correlation + hashed-request correlation + prompt correlation" +0x00471b90,256,multiplayer_selector0x49_build_company_activity_bitmaps_and_publish_selector0x47,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that consumes one 12-byte record from `[this+0x08]`, hashes that record through `0x0053d870`, resolves the current keyed object through `0x00468cb0`, and merges the record's existing bitset dword `[record+0x08]` into the resolved object. It then walks `0x006ceb9c` and, for every currently active named-profile entry whose bit is not already present in that merged mask, copies the live-activity bit into the local object. After that sweep it stages the current year-derived token into `[0x006cd8d8+0x8f38]`, republishes the object through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x47`, and releases the temporary record. This is the tightest current structural read for selector `0x49` above the follow-on selector-`0x47` bitmap branch.","objdump + local disassembly + registration-pass correlation + selector-0x49 correlation + selector-0x47 correlation + keyed-object correlation" +0x00471c90,320,multiplayer_selector0x47_build_profile_masks_and_trigger_merger_vote_resolution,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that consumes one 10-byte bitmap-style payload from `[this+0x08]`, builds two ten-slot byte arrays on the stack from payload bytes `[+0x04]`, `[+0x05]`, and payload bitmask dword `[+0x08]`, and then walks `0x006ceb9c` to mark currently active entries into the second array when their bit is present or when their guard fields are already clear. It then forwards the resulting arrays into `0x004eb230` and immediately re-enters `shell_resolve_merger_vote_and_commit_outcome` `0x004ebd10(0)`. This is the clearest current structural read for selector `0x47` beneath the paired selector-`0x49` bitmap-builder branch.","objdump + local disassembly + registration-pass correlation + selector-0x47 correlation + 0x006ceb9c-correlation + merger-vote correlation" +0x00471d50,112,multiplayer_complete_selector0x4c_prompt_result_and_publish_selector0x4d,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Prompt-result callback used by the selector-`0x4c` request family. The helper treats `[this+0x1c]` as one `0x0a`-byte staged record, derives one bit position from the current live session through `0x00521d40` and `0x0046d980`, sets that bit in record dword `[record+0x06]`, forces the same bit again when the prompt result code in `EDX` equals `0x3f2`, then republishes the updated `0x0a`-byte record through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x4d` and dataset string root `[0x006cd8d8+0x8f48]`.","objdump + local disassembly + caller inspection + selector-0x4c correlation + selector-0x4d correlation + prompt-result correlation" +0x00471dc0,272,multiplayer_selector0x4c_match_or_prompt_10byte_record_and_publish_selector0x4d,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body for the 10-byte hashed request family seeded by `0x0046cc60`. It treats `[this+0x08]` as one `0x0a`-byte record, derives the current live-session bit position through `0x00521d40` and `0x0046d980`, and when payload dword `[+0x00]` matches the current live session id simply sets that bit in record dword `[+0x06]` before publishing selector `0x4d`. Otherwise it resolves the `0x006ceb9c` and `0x0062be10` entries selected by payload bytes `[+0x05]` and `[+0x04]`, and either marks the same bit directly or formats localized status `0x0b82` into `0x006ce700` and opens a prompt through `0x00469a50` with follow-on callback `0x00471d50`. In both branches the final publish uses `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x4d`.","objdump + local disassembly + registration-pass correlation + selector-0x4c correlation + selector-0x4d correlation + hashed-request correlation + prompt correlation" +0x00471ed0,256,multiplayer_selector0x4d_build_company_activity_bitmaps_and_publish_selector0x4b,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that consumes one 10-byte record from `[this+0x08]`, hashes that record through `0x0053d870`, resolves the current keyed object through `0x00468cb0`, and merges the record's existing bitset dword `[record+0x06]` into the resolved object. It then walks `0x006ceb9c` and, for every currently active named-profile entry whose bit is not already present in that merged mask, copies the live-activity bit into the local object. After that sweep it stages the current year-derived token into `[0x006cd8d8+0x8f38]`, republishes the object through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x4b`, and releases the temporary record. This is the tightest current structural read for selector `0x4d` above the follow-on selector-`0x4b` bitmap branch.","objdump + local disassembly + registration-pass correlation + selector-0x4d correlation + selector-0x4b correlation + keyed-object correlation" +0x00471fd0,176,multiplayer_selector0x4b_build_profile_masks_and_refresh_two_bitmap_helpers,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that consumes one 10-byte bitmap-style payload from `[this+0x08]`, builds two ten-slot byte arrays on the stack from payload bytes `[+0x04]`, `[+0x05]`, and payload bitmask dword `[+0x06]`, and then walks `0x006ceb9c` to mark currently active entries into the second array when their bit is present or when their guard fields are already clear. It then forwards the resulting arrays into `0x0050c4e0` and `0x0050c940`. This is the clearest current structural read for selector `0x4b` beneath the paired selector-`0x4d` bitmap-builder branch.","objdump + local disassembly + registration-pass correlation + selector-0x4b correlation + 0x006ceb9c-correlation + bitmap-helper correlation" +0x00472080,48,multiplayer_selector0x4f_republish_selector0x6f_when_session_live_and_dataset_gate_clear,shell,cdecl,inferred,objdump + local disassembly + registration-pass correlation,2,"Small selector-handler body that checks for a live session object at `0x006d40dc` and a clear dataset gate at `0x006cd91c`, then resubmits a tiny empty request through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x6f`. This is the current grounded owner for selector `0x4f`.","objdump + local disassembly + registration-pass correlation + selector-0x4f correlation" +0x004720b0,32,multiplayer_selector0x50_copy_dataset_dword_0x9058_to_0x9054_when_session_live,shell,cdecl,inferred,objdump + local disassembly + registration-pass correlation,2,"Small selector-handler body that, when the live session object `0x006d40dc` is present, copies dataset dword `[0x006cd8d8+0x9058]` into `[0x006cd8d8+0x9054]`. This is the current grounded owner for selector `0x50`.","objdump + local disassembly + registration-pass correlation + selector-0x50 correlation + dataset-field correlation" +0x004720d0,208,multiplayer_selector0x51_derive_session_status_and_publish_selector0x52_or_control0x109_fallback,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that consumes one structured payload from `[this+0x08]`, checks for a live session object at `0x006d40dc`, and then derives one small status code from `0x00468ce0`, `0x0046c280`, and `0x004eda30`. When all three routes still return `0xff`, it republishes shell control `0x109` from root `0x006cec7c` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30`; otherwise it forwards the caller buffer at `EDX+0x08` plus the derived code through the same transport with selector `0x52`. This is the clearest current structural read for selector `0x51` above that selector-`0x52` status branch.","objdump + local disassembly + registration-pass correlation + selector-0x51 correlation + selector-0x52 correlation + session-status correlation" +0x004721a0,32,multiplayer_selector0x55_store_payload_dword_into_dataset_field_0x9860,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,2,"Tiny selector-handler body that stores payload dword `[ [this+0x08] + 0x00 ]` directly into dataset field `[0x006cd8d8+0x9860]`. This is the current grounded owner for selector `0x55`.","objdump + local disassembly + registration-pass correlation + selector-0x55 correlation + dataset-field correlation" +0x004721c0,64,multiplayer_selector0x56_copy_payload_string_into_named_profile_entry,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,2,"Selector-handler body that resolves one `0x006ceb9c` entry from payload dword `[+0x04]` and copies the caller string at `[payload+0x08]` into that entry's inline name band `[entry+0x08]` until the terminating NUL. This is the current grounded owner for selector `0x56`.","objdump + local disassembly + registration-pass correlation + selector-0x56 correlation + 0x6ceb9c-entry correlation + string-copy correlation" +0x00472200,48,multiplayer_selector0x57_store_payload_dword_into_named_profile_guard_0x1e1,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,2,"Selector-handler body that resolves one `0x006ceb9c` entry from payload dword `[+0x00]` and stores payload dword `[+0x04]` into that entry's guard field `[entry+0x1e1]`. This is the current grounded owner for selector `0x57`.","objdump + local disassembly + registration-pass correlation + selector-0x57 correlation + 0x6ceb9c-entry correlation + guard-field correlation" +0x00472230,96,multiplayer_selector0x58_flush_deferred_named_profile_reset_queue,shell,cdecl,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that walks the 16-slot dataset byte queue `[0x006cd8d8+0x9864..+0x9873]`. For every slot whose byte is not `0xff`, it resolves the corresponding `0x006ceb9c` entry, clears guard dword `[entry+0x1e1]`, sets byte `[entry+0x293] = 1`, and then resets the queue slot back to `0xff`. This is the current grounded owner for selector `0x58`.","objdump + local disassembly + registration-pass correlation + selector-0x58 correlation + deferred-queue correlation + 0x6ceb9c-entry correlation" +0x00472290,208,multiplayer_selector0x59_derive_roster_capacity_status_and_publish_selector0x5a,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that validates one payload through `0x0046d7f0`, formats a temporary object through `0x005a19c4`, `0x005a125d`, and `0x00442400`, clamps object field `[obj+0x3b6]` to at most `4`, compares that result against shell field `[0x006cec7c+0x79]`, and conditionally re-enters `0x004ecc50` before setting the final status dword. It then forwards that four-byte result through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x5a`. This is the clearest current structural read for selector `0x59` above that derived selector-`0x5a` status lane.","objdump + local disassembly + registration-pass correlation + selector-0x59 correlation + selector-0x5a correlation + derived-status correlation" +0x00472360,96,multiplayer_selector0x5b_stage_current_token_and_publish_selector0x5c,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x5c`. This is the clean local selector-`0x5b` wrapper immediately above the selector-`0x5c` branch.","objdump + local disassembly + registration-pass correlation + selector-0x5b correlation + selector-0x5c correlation + staged-token correlation" +0x004723c0,144,multiplayer_selector0x5c_gate_company_entry_dispatch_0x493960_and_optional_local_metric_apply,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, resolves company id `[payload+0x00]` inside `0x0062be10`, and then branches on a float comparison from `0x0046a4b0` against threshold `0x005c8c28`. In the direct lane it dispatches the resolved company id into `0x00493960(0x006cfca8, id, 0, 0, 0)`. In the alternate lane it first performs the same dispatch and then builds a one-byte stack payload from the company id and forwards that temporary record into `multiplayer_apply_rounded_float_delta_to_company_entry_metric_pair_by_index_byte` `0x0046f870`. This is the clearest current structural read for selector `0x5c` above that dispatch-or-local-apply split.","objdump + local disassembly + registration-pass correlation + selector-0x5c correlation + company-entry correlation + local-apply correlation" +0x00472450,144,multiplayer_selector0x5d_validate_payload_string_and_publish_selector0x5e,shell,thiscall,inferred,objdump + local disassembly + registration-pass correlation,3,"Selector-handler body that validates the caller string at `[payload+0x08]` through `0x0046a440` and, when that validation passes, stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x5e`. This is the clean local selector-`0x5d` wrapper immediately above the heavier selector-`0x5e` named-profile string-update branch.","objdump + local disassembly + registration-pass correlation + selector-0x5d correlation + selector-0x5e correlation + string-validation correlation" +0x004724e0,254,multiplayer_selector0x5e_update_named_profile_entry_string_and_live_session_label,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes one variable-length payload from `[this+0x08]` and requires a positive payload length from `[this+0x0c]`. On the active branch it uses payload dword `[+0x04]` to resolve one `0x006ceb9c` entry, copies the caller string at `[payload+0x08]` into that entry's inline name band `[entry+0x08]`, resolves the live session object at `0x006d40d0` from payload dword `[+0x00]`, mirrors the same string into `[session+0x08]`, and when `[session+0x50]` is nonzero hashes that string through `0x0053d810`, stores the result in `[session+0x48]`, and mirrors the string into dataset field `[0x006cd8d8+0x8f48]`. If the updated session id matches the current live session id it also decrements `0x006d10a0` and may re-enter `0x0053f000`. Empty-input failure falls back to localized status id `0x0b83`. This is the safest current structural read for selector `0x5e` beneath the preview-dataset callback table rather than a generic string setter.","objdump + local disassembly + caller inspection + selector-0x5e correlation + 0x6ceb9c-entry correlation + live-session-string correlation" +0x004725e0,91,multiplayer_selector0x5f_stage_current_token_and_publish_selector0x60,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x60`. This is the clean local selector-`0x5f` wrapper immediately above the narrower selector-`0x60` apply branch.","objdump + local disassembly + caller inspection + selector-0x5f correlation + selector-0x60 correlation + staged-token correlation" +0x00472640,159,multiplayer_selector0x60_apply_profile_entry_byte_0x15c_by_named_index_or_publish_error,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that either applies one small byte field into a `0x006ceb9c` entry or routes an error-style fallback. On the active payload branch it optionally marks whether payload dword `[+0x00]` matches the current live session id, resolves the target `0x006ceb9c` entry from payload dword `[+0x04]`, and when that entry's guard dword `[entry+0x1e1]` is nonzero writes payload byte `[+0x08]` into `[entry+0x15c]`. On the empty-input branch it instead resolves one live world-side owner through `0x004348c0`, copies global byte `0x00622090` into `[owner+0x15c]`, and falls back to localized status id `0x0b84`. In either branch, when the local-session match or fallback path is active it decrements `0x006d10a0` and may re-enter `0x0053f000`. This is the clearest current structural read for selector `0x60` above that one-byte profile-entry apply lane.","objdump + local disassembly + caller inspection + selector-0x60 correlation + 0x6ceb9c-entry correlation + live-world-owner correlation" +0x00472700,216,multiplayer_selector0x61_match_company_name_and_publish_selector0x62_or_error,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes one payload record from `[this+0x08]`, linearly scans indexed collection `0x0062be10` for the first entry whose inline name at `[entry+0x04]` matches the caller string at `[payload+0x08]`, and on a match stages the current year-derived token into `[0x006cd8d8+0x8f38]` before submitting selector `0x62` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with the original payload pointer and length from `[this+0x0c]`. When no matching company name resolves it instead submits the paired error-style selector-`0x62` payload through the `0x21` branch using the caller fallback buffer from `EDX+0x08`. This is the clearest current structural read for the selector-`0x61` owner above that selector-`0x62` submit split.","objdump + local disassembly + caller inspection + selector-0x61 correlation + selector-0x62 correlation + indexed-company-name correlation" +0x004727e0,144,multiplayer_selector0x62_copy_0x32_byte_company_entry_band_if_live_session_matches,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that requires a positive payload length from `[this+0x0c]`, checks whether payload dword `[+0x00]` matches the current live session id, resolves one company-style entry through `multiplayer_resolve_company_entry_by_index_if_live_session_profile_index_matches` `0x0046f8f0` using payload dword `[+0x04]`, and on success copies `0x32` bytes from payload band `[+0x08]` into the resolved entry at `[entry+0x04]` through `0x0051d8a0`. When the caller's session id matches the live session id but the entry apply fails, the helper falls back to localized status id `0x0b85`; the same local-session path then decrements `0x006d10a0` and may re-enter `0x0053f000`. This is the clearest current structural read for selector `0x62` above that fixed-width company-entry copy band.","objdump + local disassembly + caller inspection + selector-0x62 correlation + live-session correlation + company-entry copy correlation" +0x00472870,198,multiplayer_selector0x63_reject_duplicate_company_field_0x37_and_publish_selector0x64_or_error,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes one payload from `[this+0x08]`, linearly scans `0x0062be10` for an existing company-style entry whose dword field `[entry+0x37]` matches payload dword `[+0x08]`, and on the no-duplicate branch stages the current year-derived token into `[0x006cd8d8+0x8f38]` before resubmitting the original payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x64`. When a duplicate field-`0x37` value already exists it instead submits the paired error-style selector-`0x64` payload through the `0x21` branch using the caller fallback buffer from `EDX+0x08`. This is the safest current structural read for selector `0x63` above the narrower selector-`0x64` field-apply branch.","objdump + local disassembly + caller inspection + selector-0x63 correlation + selector-0x64 correlation + company-entry field-0x37 correlation" +0x00472940,176,multiplayer_selector0x64_apply_company_field_0x37_or_publish_error,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that either applies payload dword `[+0x08]` into company-entry field `[entry+0x37]` or publishes an error-style fallback. On the active payload branch it checks whether payload dword `[+0x00]` matches the current live session id, resolves the matching company-style entry through `multiplayer_resolve_company_entry_by_index_if_live_session_profile_index_matches` `0x0046f8f0` using payload dword `[+0x04]`, and on success stores payload dword `[+0x08]` into `[entry+0x37]`. On the failure path it resolves one live world-side owner through `0x00434870`, copies global dword `0x00622094` into that same field offset `[owner+0x37]`, and falls back to localized status id `0x0b86`. When the local-session path is active it then decrements `0x006d10a0` and may re-enter `0x0053f000`. This is the clearest current structural read for selector `0x64` above that one-field company-entry apply lane.","objdump + local disassembly + caller inspection + selector-0x64 correlation + company-entry field-0x37 correlation + live-world-owner correlation" +0x004729f0,57,multiplayer_selector0x73_stage_current_token_and_publish_selector0x74,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x74`. This is the clean local selector-`0x73` wrapper immediately above the narrower selector-`0x74` dispatch body.","objdump + local disassembly + caller inspection + selector-0x73 correlation + selector-0x74 correlation + staged-token correlation" +0x00472a50,75,multiplayer_selector0x74_resolve_company_entry_id_and_dispatch_collection_0x62b26c,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes payload dword `[this+0x08]`, checks whether that id resolves inside collection `0x0062b26c`, and on success first trips the small gate at `0x0046d2b0(1.02f)` to toggle global latch `0x006ce9a8` before calling the collection's vtable slot `+0x08` with that same id and then restoring the latch. This is the safest current structural read for selector `0x74` above that narrow collection-dispatch lane rather than a generic callback stub.","objdump + local disassembly + caller inspection + selector-0x74 correlation + 0x62b26c-collection correlation + latch-0x6ce9a8 correlation" +0x00472aa0,57,multiplayer_selector0x71_stage_current_token_and_publish_selector0x72,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x72`. This is the clean local selector-`0x71` wrapper immediately above the heavier selector-`0x72` counted-record apply body.","objdump + local disassembly + caller inspection + selector-0x71 correlation + selector-0x72 correlation + staged-token correlation" +0x00472b00,675,multiplayer_selector0x72_apply_counted_structure_records_into_live_collections,shell,thiscall,inferred,objdump + local disassembly + caller inspection,4,"Heavier selector-handler body that consumes a counted record set from `[this+0x08]` and applies it into the live world-side collections rooted at `0x0062b2fc`, `0x0062b26c`, and `0x0062bae0`. The handler first gates through `0x0046d2b0(1.02f)` and raises latch `0x006ce9a8`, then branches on the leading count word at `[payload+0x02]`. Its singleton fast path requires count `1` and a nonzero leading key word, seeds temporary sentinel fields under `0x0062b2fc`, bumps the scoped counter `[0x0062bae0+0x88]`, validates one record through `placed_structure_validate_projected_candidate_placement` `0x004197e0`, allocates or applies the live object through `placed_structure_collection_allocate_and_construct_entry` `0x004134d0`, and refreshes the region-side derived state through `world_region_refresh_cached_structure_class_mix_scalar_0x312_from_linked_chain` `0x00420560` when the keyed `0x0062bae0` entry exists. The general path walks `count` records of stride `0x12` from `[payload+0x04]`, applies the same `0x004197e0 -> 0x004134d0 -> 0x00420560` pattern per record, and finally restores the temporary `0x0062b2fc` sentinel fields and clears latch `0x006ce9a8`. This is the safest current structural read for selector `0x72` above that counted live-world apply family rather than a generic serializer inverse.","objdump + local disassembly + caller inspection + selector-0x72 correlation + counted-record correlation + live-world-collection correlation" +0x00472db0,8,multiplayer_selector_callback_apply_metric_delta_payload_into_company_entry,shell,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Tiny selector-facing wrapper that loads payload pointer `[this+0x08]`, forwards it into `multiplayer_apply_rounded_float_delta_to_company_entry_metric_pair_by_index_byte` `0x0046f870`, and then returns success. Registration-site xrefs place it under selector `0x6b` in the broader multiplayer callback table, so this is the local selector-`0x6b` apply leaf rather than the train-record branch.","objdump + local disassembly + caller inspection + selector-0x6b correlation + company-metric apply correlation" +0x00472dc0,8,multiplayer_selector_callback_apply_train_record_payload_into_live_train_entry,shell,thiscall,inferred,objdump + local disassembly + caller inspection,2,"Tiny selector-facing wrapper that loads payload pointer `[this+0x08]`, forwards it into `multiplayer_apply_train_record_fields_into_live_train_entry_by_id` `0x0046d780`, and then returns success. Registration-site xrefs place it under selector `0x6c` in the broader multiplayer selector-handler table rather than as a standalone service owner.","objdump + local disassembly + caller inspection + selector-0x6c correlation + train-apply correlation" +0x00472dd0,205,multiplayer_selector0x6d_publish_winner_status_text_into_world_buffer,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes one payload from `[this+0x08]`, checks for an active world root at `0x006cec78`, and when the leading winner id dword differs from the current world winner id from `0x004337b0` resolves the matching `0x006ceb9c` name entry and formats localized status id `0x0f4e` into a local buffer through `0x005193f0` and `0x00518de0`. It then copies that formatted string into the world-side outcome-text buffer `[world+0x4b47]`, or clears the first byte of that buffer when the name lookup fails, and finally sets world latch `[world+0x4a73] = 1`. This is the clearest current static owner for selector `0x6d` above the already-grounded live outcome-status text band.","objdump + local disassembly + caller inspection + selector-0x6d correlation + world-outcome-buffer correlation + 0x6ceb9c-name correlation" +0x00472ea0,102,multiplayer_selector0x6e_mark_matching_current_bucket_record_flag_0x08_by_payload_hash,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes a payload blob from `[this+0x08]`, resolves the current keyed bucket under `[EDX+0x2580]` using dataset key `[0x006cd8d8+0x9888]`, and then walks that bucket's linked node chain. For each node it hashes the current selector payload through `0x0053d870` when `[this+0x0c] > 0` and compares that hash against the payload's leading dword `[payload+0x00]`; on the first match it sets flag bit `0x08` in the companion object byte `[ [this+0x04] + 0x0b ]`. This is the cleanest current structural read for selector `0x6e` beneath the earlier selector-`0x13` hashed publish fallback.","objdump + local disassembly + caller inspection + selector-0x6e correlation + keyed-bucket correlation + payload-hash correlation" +0x00472f10,81,multiplayer_selector0x75_stage_current_token_and_publish_selector0x76,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x76`. This is the clean local selector-`0x75` wrapper immediately above the narrower selector-`0x76` company-entry dispatch body.","objdump + local disassembly + caller inspection + selector-0x75 correlation + selector-0x76 correlation + staged-token correlation" +0x00472f70,60,multiplayer_selector0x76_resolve_company_entry_and_dispatch_local_handler_0x409830,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes payload dword `[this+0x08]`, checks whether that id resolves inside collection `0x0062be10`, and on success resolves the matching company-style entry and forwards that entry into local handler `0x00409830`. This is the cleanest current structural read for selector `0x76` above that narrow company-entry dispatch lane rather than a generic callback stub.","objdump + local disassembly + caller inspection + selector-0x76 correlation + company-entry correlation + local-handler correlation" +0x00472fb0,81,multiplayer_selector0x77_stage_current_token_and_publish_selector0x78,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x78`. This is the clean local selector-`0x77` wrapper immediately above the heavier selector-`0x78` world-dispatch body.","objdump + local disassembly + caller inspection + selector-0x77 correlation + selector-0x78 correlation + staged-token correlation" +0x00473010,175,multiplayer_selector0x78_resolve_company_entry_and_dispatch_projection_request,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes one structured payload from `[this+0x08]`, checks whether payload dword `[+0x04]` resolves inside `0x0062be10`, and on success forwards payload tuple `[+0x04/+0x08/+0x0c]` plus local stack outputs into the broader world-side helper `0x0044b160` using scale `1.0f`. When that helper succeeds it also notifies owner `0x006d401c` through `0x00538e00(0xba, 0x808, 0, 0, 0)`. Separately, when payload dword `[+0x00]` matches the current live session id it clears field `[0x006d1a8c+0x83]`, re-enters `0x0053f000(1,0,0x15)`, and calls `0x0045ea20(0x39, 1.0f)`. This is the safest current structural read for selector `0x78` above that world-side projection or notify branch rather than a narrow leaf helper.","objdump + local disassembly + caller inspection + selector-0x78 correlation + world-helper-0x44b160 correlation + local-session correlation" +0x004730c0,81,multiplayer_selector0x79_stage_current_token_and_publish_selector0x7a,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x7a`. This is the clean local selector-`0x79` wrapper immediately above the narrower selector-`0x7a` company-entry dispatch body.","objdump + local disassembly + caller inspection + selector-0x79 correlation + selector-0x7a correlation + staged-token correlation" +0x00473120,90,multiplayer_selector0x7a_resolve_company_entry_and_dispatch_local_handler_0x427e20,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes one structured payload from `[this+0x08]`, checks whether payload dword `[+0x04]` resolves inside `0x0062be10`, and on success resolves the matching company-style entry and forwards that entry plus payload dword `[+0x08]` and zero flag into local handler `0x00427e20`. When payload dword `[+0x00]` matches the current live session id it also re-enters `0x0053f000(1,0,0)`. This is the cleanest current structural read for selector `0x7a` above that narrow company-entry dispatch lane.","objdump + local disassembly + caller inspection + selector-0x7a correlation + company-entry correlation + local-handler correlation" +0x00473180,81,multiplayer_selector0x7b_stage_current_token_and_publish_selector0x7c,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x7c`. This is the clean local selector-`0x7b` wrapper immediately above the narrower selector-`0x7c` company-entry dispatch body.","objdump + local disassembly + caller inspection + selector-0x7b correlation + selector-0x7c correlation + staged-token correlation" +0x004731e0,52,multiplayer_selector0x7c_resolve_company_entry_and_dispatch_local_handler_0x426d60,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Selector-handler body that consumes payload dword `[this+0x08]`, checks whether payload dword `[+0x04]` resolves inside `0x0062be10`, and on success resolves the matching company-style entry and forwards that entry into local handler `0x00426d60`. This is the cleanest current structural read for selector `0x7c` above that narrow company-entry dispatch lane rather than a generic callback stub.","objdump + local disassembly + caller inspection + selector-0x7c correlation + company-entry correlation + local-handler correlation" +0x00473220,81,multiplayer_selector0x7d_stage_current_token_and_publish_selector0x7e,shell,thiscall,inferred,objdump + local disassembly + caller inspection,3,"Small selector-forwarding body that stages the current year-derived token into `[0x006cd8d8+0x8f38]` through `0x0046b6d0` and `0x0051d3c0`, then resubmits the original payload pointer `[this+0x08]` and length `[this+0x0c]` through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x7e`. This is the clean local selector-`0x7d` wrapper immediately above the registered selector-`0x7e` branch.","objdump + local disassembly + caller inspection + selector-0x7d correlation + selector-0x7e correlation + staged-token correlation" +0x00473280,1502,multiplayer_preview_dataset_reset_global_callback_state_and_register_selector_handlers,shell,cdecl,inferred,objdump + local disassembly + caller inspection,4,"Broader callback-registry seeding pass beneath the Multiplayer preview dataset constructor. The helper zeroes the two large multiplayer-global scratch bands at `0x006ce808..0x006ce994` and `0x006ce290`, clears the staged launcher globals `0x006ce628`, `0x006ce630`, and `0x006ce9b4..0x006ce9c8`, seeds the dataset-local default callback root at `[0x006cd8d8+0x08]` with `0x0046f4a0` through `multiplayer_preview_dataset_set_default_callback_root` `0x00468b50`, and then registers the keyed selector-handler family by repeatedly calling `multiplayer_preview_dataset_register_selector_callback_if_absent` `0x00468b10` for selector ids `1..0x83` with the concrete callback roots spanning `0x0046c390..0x00473220`. Current grounded caller is the full dataset constructor/reset body `0x0046be80`, so this is the clearest current owner for the broad selector-handler registration phase above the smaller fixed-name descriptor block `0x00473a60` rather than another anonymous callback fan-out.","objdump + local disassembly + caller inspection + global-scratch reset correlation + selector-handler registration correlation" +0x00473a60,219,multiplayer_preview_dataset_register_fixed_named_callback_descriptors_1_to_10,shell,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Registers the first fixed selector-name callback block for the preview dataset at `0x006cd8d8`. The helper repeatedly calls `multiplayer_preview_dataset_append_named_callback_descriptor` `0x00469930` with selector ids `1..0xa`, fixed internal names from the `0x005ce3ac..0x005ce40c` string band, and the paired callback roots `0x0046db10..0x0046de80`. Current direct caller is the broader preview-dataset registration pass at `0x0046c1fb`, so this is the clearest current owner for the initial fixed descriptor block beneath `[0x006cd8d8+0x8f28]` rather than another anonymous callback fan-out.","objdump + caller inspection + local disassembly + fixed-descriptor-block correlation" +0x00473bf0,257,multiplayer_preview_dataset_publish_accumulated_selector0x71_record_batch,shell,cdecl,inferred,objdump + local disassembly + caller inspection,3,"Packages and publishes the accumulated fixed-width record band rooted at `0x006cd990` when the live count at `0x006ce9a0` is positive. The helper allocates one `0x14 * count + 0x4` payload block, prefixes it with two 16-bit header words `(0, count)`, copies each `0x12`-byte source record into the payload, submits that payload through `multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `0x71`, then resets `0x006ce9a0` and frees the temporary block. Current grounded caller is the broader current-session bucket service body `0x0046b9f0`, so this is the clearest current owner for the selector-`0x71` batch publish beneath that service path rather than another generic serializer.","objdump + local disassembly + caller inspection + selector-0x71 publish correlation" +0x00473cc0,3,multiplayer_preview_fixed_record_identity_helper,shell,thiscall,inferred,objdump + local disassembly,1,"Tiny identity helper that simply returns `ECX` unchanged. Current grounded caller is the fixed-record collection builder `0x00473f80`, where it initializes one stack-local temporary record before the later constructor and destructor callbacks.","objdump + local disassembly + fixed-record temp-helper correlation" +0x00473cd0,1,multiplayer_preview_fixed_record_noop_destructor_stub,shell,thiscall,inferred,objdump + local disassembly,1,"Literal no-op stub beside the `0x005ce418` fixed-record family. Current grounded caller is `0x00473f80`, where it serves as the paired release callback for the same stack-local temporary initialized by `0x00473cc0`.","objdump + local disassembly + fixed-record temp-helper correlation" +0x00473ce0,134,multiplayer_preview_fixed_record_construct_from_payload_strings_shell_profile_bytes_and_sequence,shell,thiscall,inferred,objdump + local disassembly + field-layout correlation,2,"Constructor for the `0x005ce418` fixed-record family rooted at size `0x187`. The helper stores the caller-supplied record id at `[this+0x00]`, copies one `0x78`-byte string into `[this+0x19]`, copies one `0xf0`-byte string into `[this+0x92]`, stores one caller dword at `[this+0x183]`, mirrors the current shell-profile-derived year tuple through `0x0051d3c0` into `[this+0x08]`, copies shell bytes `[0x006cec78+0x0d/+0x0f/+0x11]` into `[this+0x0c/+0x0e/+0x10]`, clears flag byte `[this+0x18]`, stores the caller-supplied owner dword at `[this+0x04]`, and assigns a monotonically increasing sequence at `[this+0x14]` from `0x006cea48`. Current grounded caller is the collection-side allocator `0x00473f80`, so this is the clearest current owner for the fixed record constructor rather than a generic string copier.","objdump + local disassembly + field-layout correlation + shell-profile correlation + sequence-counter correlation" +0x00473d70,42,multiplayer_preview_fixed_record_collection_construct,shell,thiscall,inferred,objdump + local disassembly + collection-layout correlation,2,"Constructor for the collection object rooted at vtable `0x005ce418`. The helper resets collection state through `0x00517ce0`, installs vtable `0x005ce418`, and initializes the collection through `0x00518570` with the fixed tuple `(1, 0x187, 0x0a, 0x05, 0, 0, 0)`. Current grounded callers are the fixed-record family paths beginning at `0x00473f80`, so this is the safest current read for the collection constructor rather than a record-local leaf.","objdump + local disassembly + collection-layout correlation + fixed-record-family correlation" +0x00473da0,18,multiplayer_preview_fixed_record_collection_release_and_free,shell,thiscall,inferred,objdump + local disassembly + collection-layout correlation,1,"Destructor-side wrapper for the same `0x005ce418` collection family. The helper reinstalls vtable `0x005ce418`, re-enters `0x00518600`, and then tails into `0x00518bd0`.","objdump + local disassembly + collection-layout correlation + fixed-record-family correlation" +0x00473dc0,87,multiplayer_preview_fixed_record_collection_query_max_sequence_entry,shell,thiscall,inferred,objdump + local disassembly + collection-iteration correlation,2,"Scans the live `0x005ce418` fixed-record collection and returns the record whose sequence dword `[entry+0x14]` is greatest. When no live record exists the helper returns `0`.","objdump + local disassembly + collection-iteration correlation + sequence-field correlation" +0x00473e20,73,multiplayer_preview_fixed_record_collection_query_any_inactive_record_with_owner,shell,thiscall,inferred,objdump + local disassembly + collection-iteration correlation,2,"Returns `1` when the live `0x005ce418` collection contains at least one record whose active flag byte `[entry+0x18]` is zero and whose owner dword `[entry+0x04]` is nonzero; otherwise returns `0`. This is the cleanest current structural read for the boolean scan beneath the same fixed-record family.","objdump + local disassembly + collection-iteration correlation + fixed-record-family correlation" +0x00473e70,106,multiplayer_preview_fixed_record_collection_query_min_sequence_entry_with_optional_active_filter,shell,thiscall,inferred,objdump + local disassembly + collection-iteration correlation,2,"Scans the live `0x005ce418` fixed-record collection and returns the record whose sequence dword `[entry+0x14]` is smallest. When the caller-supplied stack flag is zero it skips records whose active byte `[entry+0x18]` is nonzero; otherwise it accepts all live records. On no match it returns `0`.","objdump + local disassembly + collection-iteration correlation + sequence-field correlation + active-flag correlation" +0x00473ee0,68,multiplayer_preview_fixed_record_collection_find_entry_by_previous_sequence,shell,thiscall,inferred,objdump + local disassembly + collection-iteration correlation,2,"Searches the live `0x005ce418` fixed-record collection for the entry whose sequence dword `[entry+0x14]` equals `arg - 1`. On success it returns the resolved entry; otherwise `0`.","objdump + local disassembly + collection-iteration correlation + sequence-field correlation" +0x00473f30,68,multiplayer_preview_fixed_record_collection_find_entry_by_next_sequence,shell,thiscall,inferred,objdump + local disassembly + collection-iteration correlation,2,"Searches the live `0x005ce418` fixed-record collection for the entry whose sequence dword `[entry+0x14]` equals `arg + 1`. On success it returns the resolved entry; otherwise `0`.","objdump + local disassembly + collection-iteration correlation + sequence-field correlation" +0x00473f80,170,multiplayer_preview_fixed_record_collection_allocate_and_construct_entry,shell,thiscall,inferred,objdump + local disassembly + caller inspection + collection-layout correlation,2,"Shared allocator and constructor beneath the `0x005ce418` fixed-record family. When the live collection size exceeds `0x19`, the helper repeatedly resolves the minimum-sequence entry through `0x00473e70(1)` and removes it through collection virtual slot `+0x08` until the size drops to `0x19` or below. It then initializes one stack-local temporary through `0x00473cc0/0x00473cd0`, allocates a new live record through `0x00518900`, resolves that record through `0x00518140`, constructs it through `0x00473ce0` with the caller-supplied payload tuple, and finally tears down the temporary helper. This is the clearest current owner for fixed-record allocation plus constructor dispatch in the preview-side family.","objdump + local disassembly + caller inspection + collection-layout correlation + fixed-record-family correlation" 0x00470210,119,multiplayer_submit_chat_or_command_line,shell,cdecl,inferred,ghidra-headless,4,Submits one Multiplayer.win chat-entry line. The wrapper first calls multiplayer_dispatch_chat_command on the raw line buffer; when the parser returns zero it formats a normal `%s > %s` named chat line from the sender object at `[edi+0x08]` and the message payload; then either publishes it locally through multiplayer_publish_wrapped_chat_message or routes it through the active transport object at `0x006cec78`. When the parser returns nonzero the wrapper skips normal chat formatting because the slash-command branch already consumed the line.,ghidra + rizin + llvm-objdump + strings 0x004ecc90,52,multiplayer_set_pending_session_substate,shell,unknown,inferred,ghidra-headless,2,Small pending-session-substate setter used by the multiplayer session-event callback family. The grounded stores are request id `5` to substate `5` request id `6` to substate `6` and request id `8` to substate `8` at `0x006d1288`. Other current callback-family callers still pass ids `1` `2` `4` and `7` without a visible store in this helper so this row stays structural for now.,ghidra + rizin + llvm-objdump 0x004edce0,19,multiplayer_notify_window_owner,shell,unknown,inferred,ghidra-headless,3,Thin Multiplayer.win owner-notification wrapper. It loads the current window owner singleton from `0x006d1268` and when present forwards the supplied payload pointer into 0x004eccd0 for owner-side handling; current grounded callers are the session-event callback family around 0x004691a0 and the related registration path near 0x0046a8b3.,ghidra + rizin + llvm-objdump @@ -911,11 +1482,14 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x005033d0,1963,shell_setup_window_handle_message,shell,thiscall,inferred,objdump + local disassembly,3,"Primary message or command dispatcher for the `Setup.win` family rooted at `0x00504010`. The handler switches over many control ids in the `0x0c80..0x0f71` band, routes direct mode changes through `shell_setup_window_select_launch_mode_and_apply_shell_state` `0x00502c00`, refreshes the visible list families through `shell_setup_window_refresh_mode_dependent_lists` `0x00502910` and `shell_setup_window_refresh_selection_lists_and_summary_fields` `0x00502550`, republishes the selected labels and preview surface through `shell_setup_window_publish_selected_profile_labels_and_preview_surface` `0x00502220`, and writes startup-profile selector values into `[0x006cec7c+0x01]` before later shell request `0x00482150(0xcc, ...)` transitions continue. The control-id split is tighter now too: `0x0d4b/0x0de8/0x0e85` reuse the current row index from `[msg+0x08]` to republish one selected setup record through `0x00502220`; `0x0e88/0x0e89/0x0e8a` toggle the persisted shell-state booleans at `[0x006cec74+0x247/+0x243/+0x24b]` and immediately save config through `0x00484910(1)`; `0x0c1f` is the settings-window escape through `shell_has_settings_window` `0x004fe120` and `shell_open_settings_window` `0x00501e50`; `0x0c1e`, `0x0c20`, and `0x0c22` are direct shell-request branches entering `0x00482150` with request ids `0x0cc` or `0x0cd`; `0x0bc2`, `0x0bc5`, `0x0bc6`, and `0x0bc7` are the separate shell-open or help-content quartet above `shell_query_registry_open_command_for_http_or_rtf_target` `0x00501f20`; `0x0bc1` and `0x0bc8` both select submode `15`, which now safely reads as the `Extras` family because RT3.lng `3118..3129` and the surrounding shell-open quartet align with `Readme`, `Weblinks`, and the return-to-extras sibling; `0x0bc3` selects submode `16`, which now most safely reads as the remaining `High Scores` top-level root because `Credits` already lives in separate shell mode `6` `Credits.win`; `0x0bc4` selects submode `1`, the current strongest main landing-panel fit; `0x0c80` selects submode `13`, now the strongest residual fit for the `Multi Player` root; `0x0c1c` selects submode `17`, which now safely reads as the tutorial chooser because mode `17` is the only family that later exposes startup selectors `1` and `7` through controls `0x0f6f` and `0x0f70`; `0x0c1d` selects submode `2`, the current strongest `Single Player` root from RT3.lng `1991/1992`; and `0x0c24` selects submode `14`; `0x0c81`, `0x0c82`, `0x0c83`, and `0x0c84` select submodes `14`, `6`, `10`, and `12`; `0x0c85` conditionally selects submode `4` or `3` from the entry flag at `[msg+0x2c]+0x6a`; `0x0ce4` writes selector `4` and then selects submode `8`, now the strongest `New Map` chooser fit from RT3.lng `2022/2026/2028`; `0x0ce5` writes selector `3` and then selects submode `9`, now the strongest `Load Map` list sibling; `0x0de0` and `0x0dea` both select submode `7`, now the strongest `Editor` root fit from RT3.lng `1995/1996`; `0x0df4` and `0x0e80` are the high-side slider refresh pair; `0x0e83` selects submode `1`; and `0x0f71` selects submode `1` after writing selector `7`. `0x0ce6/0x0ce7` and `0x0d49/0x0d4a` are bounded decrement or increment controls over `[0x006cec7c+0x7b]` and `[0x006cec7c+0x77]`; `0x0ce9..0x0ced` plus `0x0f3d..0x0f3f` store compact option bytes into `[0x006cec7c+0x7d]`; and `0x0e82/0x0e83` are the wider clamp-to-`0x834/0x70d` slider pair that feeds `0x00502550`. The later launch-side branches are tighter in a corrective way too: the validated staged-profile launch lane no longer includes `0x0ce5` or `0x0dcb`. `0x0cf6` and `0x0e81` are the selector-`5` siblings in that validated lane; current local disassembly also shows the neighboring selector-`3` validated lane is at least shared by the later `0x0de9` and `0x0df3` controls before shell request `0x0cc` continues; and `0x0e81` is now tighter still because it is the only one of those validated controls that also sets runtime-profile byte `[0x006cec7c+0x82] = 1`, the strongest current sandbox-side anchor beneath the later `.gmx` file family. `0x0dca` is now tighter as the grayscale-map picker branch above `shell_open_grayscale_map_tga_picker_and_stage_selection` `0x004eb0b0`, then writes selector `4`; `0x0dcb` conditionally selects submode `5` or `3` from the same entry flag family used by the earlier `0x0c85` branch, which reinforces mode `5` as the sandbox-style companion rather than another launch control; `0x0ddf` is the separate windowed-mode-gated grayscale-heightmap generation branch that reopens the `TGA Files (*.tga)` / `.\Data\GrayscaleMaps` picker through `shell_open_file_dialog_copy_selected_path_and_restore_cwd` `0x0042a970`, validates the chosen image through `shell_query_tga_header_is_supported_truecolor_image` `0x005411c0`, and only then writes selector `2`; `0x0f6f` writes selector `1`; and `0x0f70` writes selector `7` before shell request `0x0cc` continues.","objdump + local disassembly + selector-writer correlation + caller-family reconstruction + control-cluster correlation + jump-table decode + literal-correlation + submode-mapping decode + grayscale-map-picker correlation + extras/tutorial correlation + grayscale-generation correlation + RT3.lng top-level correlation + setup-asset correlation + sandbox-launch-flag correlation + load-map correction" 0x0047bc80,457,shell_setup_payload_seed_unique_row_category_bytes_and_marker_slots,shell,thiscall,inferred,objdump + local disassembly,3,"Normalizes the live `Setup.win` payload row metadata before the shared non-file-backed panel consumes it. Outside editor-map mode `[0x006cec74+0x68] == 0`, the helper clears the static category-used table rooted at `0x005f2d28`, marks every already-nonzero payload category byte from `[payload+0x31a + row*9]`, counts the existing marker bytes across the four 10-byte local bands rooted at `[payload+0x2ca]`, and fills any remaining empty marker slots at `[payload+0x2c9 + n]` until the payload row count at `+0x3ae` is covered. On the multiplayer-preview side it also forces runtime profile dword `[0x006cec7c+0x83] = 7`. It then walks the row records again and, for any zero category byte at `[payload+0x31a + row*9]`, chooses the next unused category id using runtime profile dword `[0x006cec7c+0x83]`, the local marker-slot bytes at `[payload+0x2c9 + n]`, and a bounded retry loop before writing the chosen category back and marking the static-used table. Current grounded callers are the setup payload-copy helper at `0x0047be50` and the post-load chairman-profile builder at `0x00437220`, which makes this the shared category-byte and marker-slot normalizer beneath the setup payload panel rather than one world-only helper.","objdump + local disassembly + setup-payload correlation + category-table correlation + marker-slot correlation + caller split" 0x0047be50,69,shell_setup_profile_copy_payload_scroll_count_and_campaign_byte_and_seed_row_categories,shell,thiscall,inferred,objdump + local disassembly,3,"Copies the small shared-panel runtime fields out of one live `Setup.win` payload record into the staged runtime profile at `0x006cec7c`, then normalizes the payload row metadata. When the caller-supplied payload pointer is non-null and its first byte is nonzero, the helper copies payload word `+0x14` into profile `+0x77`, payload word `+0x3b2` into profile `+0x79`, payload word `+0x3ba` into profile `+0x7b`, and payload byte `+0x20` into profile `+0xc5`, except that the three word copies are skipped while the multiplayer-preview owner at `0x006cd8d8` is live. It then tail-calls `shell_setup_payload_seed_unique_row_category_bytes_and_marker_slots` `0x0047bc80` on the same payload. Current grounded caller is `shell_setup_window_publish_selected_profile_labels_and_preview_surface` `0x00502220`, which uses this helper immediately after the heavier payload-materialization lane at `0x00422400`.","objdump + local disassembly + setup-payload correlation + runtime-profile-field correlation + caller correlation" +0x0040cb00,13,placed_structure_set_linked_site_chain_next_id_field_0x2a2,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Tiny direct setter over linked-site word `[this+0x2a2]`. The helper stores the caller-supplied site id and returns. Current grounded callers are the world-cell linked-site chain helpers `0x0042c9a0` and `0x0042c9f0`, where this field acts as the next-site link for the cell-local linked-site chain rooted at `[cell+0xd6]`.","objdump + caller xrefs + local disassembly + linked-site-chain correlation" 0x0047d810,182,placed_structure_remove_route_entry_key_and_compact,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Removes one matching `u16` route-entry key from the six-byte route-entry list rooted at `[this+0x462]/[this+0x466]`. The helper scans the current list, copies surviving six-byte entries into a newly allocated compacted buffer, frees the old buffer, stores the replacement pointer back into `[this+0x466]`, and decrements the route-entry count at `[this+0x462]`. Current grounded caller is the linked-site refresh or teardown branch at `0x0040e102`, so this is the keyed remove-and-compact companion to the linked site's route-entry list rather than another generic free helper.","objdump + caller xrefs + callsite inspection + route-entry-list compaction correlation" 0x0047d8e0,346,placed_structure_load_dynamic_side_buffers_from_stream,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Deserializes the variable-size side buffers on one placed-structure record from the caller-supplied persistence stream. The helper reads tagged blocks through `0x00531360` and `0x00531150`, repopulates the six-byte route-entry list at `[this+0x462]/[this+0x466]`, the three five-byte-per-site arrays rooted at `[this+0x24]` from count `[this+0x30]`, the five eight-byte proximity-bucket arrays counted at `[this+0x590..0x5a0]` and rooted at `[this+0x5a4..0x5b4]`, and the trailing twelve-byte scratch band at `[this+0x34]/[this+0x38]`, then clears `[this+0x5bd]` and re-enters `0x00407780`. Current direct caller is the collection-level load pass at `0x00481464`. The real body begins at `0x0047d8e0` even though current recovered calls target the preceding padding slot `0x0047d8d0`.","objdump + caller xrefs + callsite inspection + stream-layout correlation" 0x0047dcd0,64,placed_structure_clear_proximity_bucket_lists,map,thiscall,inferred,objdump + caller xrefs + data-layout inspection,3,"Clears the five proximity-bucket arrays rooted at `[this+0x5a4..0x5b4]`, zeroes the corresponding per-bucket counts at `[this+0x590..0x5a0]`, and resets the total proximity-entry count at `[this+0x5b8]`. Current grounded callers are the linked-site teardown pass at `0x00480590` and the sibling route-anchor refresh family at `0x00480719`, so this now reads as the common clear step for the nearby-site bucket family rather than a generic free helper.","objdump + caller xrefs + data-layout inspection + proximity-bucket correlation" +0x0047d6f0,10,placed_structure_set_linked_cell_owner_next_site_id_field_0x3c,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Tiny direct setter over linked-site word `[this+0x3c]`. The helper stores the caller-supplied site id and returns. Current grounded callers are the world-cell owner-chain helpers `0x0042bbb0` and `0x0042bbf0`, where this field acts as the next-site link for the cell-local owner chain rooted at `[cell+0xd4]`.","objdump + caller xrefs + local disassembly + cell-owner-chain correlation" 0x0047dd10,130,placed_structure_remove_site_id_from_proximity_bucket_lists,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Removes one matching site id from every proximity bucket rooted at `[this+0x590..0x5b8]`. The helper scans all five bucket arrays, matches the supplied site id against the first dword of each eight-byte entry, compacts the surviving tail when needed, decrements the per-bucket count, and decrements the total count at `[this+0x5b8]`. Current direct caller is the collection sweep at `0x004814e9`, which makes this the remove-one-site companion to the nearby-site bucket append path rather than a broader route helper.","objdump + caller xrefs + callsite inspection + proximity-bucket correlation" 0x0047fdb0,317,placed_structure_append_nearby_transit_site_distance_bucket_entry,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Appends one nearby station-or-transit site into the current record's five proximity buckets. The helper first requires the caller-supplied peer record to pass `0x0047fd50`, then measures the current-to-peer distance through `0x00455800`, `0x00455810`, and `math_measure_float_xy_pair_distance` `0x0051db80`, rejects peers outside the fixed distance threshold at `0x005c8738`, classifies the surviving peer through `0x0040d350`, and finally appends one `(peer site id, distance)` pair into the corresponding eight-byte bucket array at `[this+bucket*4+0x5a4]` while incrementing both the per-bucket count and total count `[this+0x5b8]`. Current direct caller is the collection sweep at `0x004814a9`.","objdump + caller xrefs + callsite inspection + distance-threshold correlation + proximity-bucket correlation" +0x0047fef0,619,placed_structure_rebuild_nearby_transit_site_distance_buckets_from_neighbor_cells,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Rebuilds the current linked site's five nearby-transit proximity buckets from the neighboring world cells around its current position. After requiring the current record to pass `placed_structure_is_station_or_transit_site_class` `0x0047fd50`, the helper quantizes current world coordinates through `0x00455800`, `0x00455810`, and the world scale constant at `0x005c859c`, scans the surrounding live cell window through `[0x0062c120+0x2129]`, follows each cell's linked placed-structure chain through word field `[cell+0x0d6]` and next-id `[peer+0x2a2]`, keeps only peers whose resolved candidate subtype byte `[candidate+0x32]` equals `4`, and appends the survivors into the same `(peer site id, distance)` bucket arrays rooted at `[this+0x590..+0x5a4]` using the current world-distance threshold and bucket classifier. Current grounded caller is the linked-site runtime refresh owner `0x00480710`, so this is the safest current read for the proximity-bucket rebuild pass rather than another one-peer append helper.","objdump + caller xrefs + callsite inspection + neighbor-cell sweep correlation + proximity-bucket correlation" 0x00482d10,110,runtime_query_cached_local_exe_version_float,simulation,thiscall,inferred,objdump + local disassembly,3,"Returns one cached local executable version as a float-like `major + minor/100` value. On first use the helper queries the version-info resource of the literal stem `RT3.EXE` at `0x005cec18` through `0x0055d9c0`, splits the returned packed dword into low and high 16-bit words, converts them into one float as `hi + lo/100.0`, caches the result at `0x006cec5c`, and returns that cached value on later calls. The sibling formatter `0x00482d80` and the rounded hundredths query `0x00482e00` both consume the same source, which now makes this the clearest current owner for the local `1.03/1.04/1.05/1.06`-style version float rather than a gameplay progress value.","objdump + local disassembly + version-resource correlation" 0x00482d80,128,runtime_query_cached_local_exe_version_string,simulation,thiscall,inferred,objdump + local disassembly + string inspection,3,"Returns one cached local executable version string formatted from the same `RT3.EXE` version-info source used by `0x00482d10`. On first use the helper queries the packed local version dword through `0x0055d9c0`, formats it with the literal pattern `%d.%02d` at `0x005ced5c`, allocates one small shell string object at `0x006cec24`, and returns that cached string on later calls. Current grounded callers include `multiplayer_session_event_publish_registration_field` `0x0046a6c0` and the later shell text path at `0x00503254`, which makes this the clearest current local version-string owner.","objdump + local disassembly + string inspection + caller xrefs + version-resource correlation" 0x00482e00,70,runtime_query_hundredths_scaled_build_version,simulation,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Shared rounded hundredths-scaled build-version query used by route, company, train, and world-side logic. In the ordinary local path the helper consults the cached local executable version float from `runtime_query_cached_local_exe_version_float` `0x00482d10`, adds the fixed offset `0.0001`, multiplies by `100.0`, and rounds the result through the CRT helper at `0x005a10d0`, which makes the local outputs line up with integer build values such as `0x67/0x68/0x69/0x6a == 1.03/1.04/1.05/1.06`. When the multiplayer-side runtime rooted at `0x006cd8d8` is active, or when the local scenario-state gate at `0x004349a0` reports a later mode, it instead delegates to the multiplayer companion path at `0x0046a4b0`, which can reuse a cached network-side integer at `0x006cd96c` or scan live session-peer version fields before falling back to the same local executable-version path. Current grounded callers include the city-connection route builder `0x00402cb0`, the auxiliary tracker pair-metric dispatcher `0x004a65b0`, and numerous neighboring world-side maintenance branches. This is no longer best-read as a gameplay progress or era index: the recovered threshold pattern is a shared executable or session build-version gate.","objdump + caller xrefs + local disassembly + multiplayer-fallback correlation + version-resource correlation + threshold-correlation" @@ -934,12 +1508,29 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00420e00,453,world_region_rebuild_profile_collection_from_source_region_and_seed_default_weights,map,thiscall,inferred,objdump + caller xrefs + local disassembly + editor-copy-flow correlation,3,"Region-side subcollection rebuild helper over `[region+0x37f]`. The function first frees and recreates the current `0x88`-byte indexed collection at `[region+0x37f]`, then when the caller supplies one source region it walks that source region's live subcollection, copies each entry label into a local stack buffer, and replays the copied weight at `[entry+0x1e]` through `world_region_upsert_or_remove_structure_profile_weight_by_name` `0x004206b0`. When no source region is supplied it instead seeds one default profile set directly through repeated `0x004206b0` calls with fixed label literals and weight `0.2f`, splitting later by region live byte `[region+0x23e]`. Current grounded caller is the `Cities/Regions` editor copy-industry branch at `0x004ce72c`, so this is the safest current read for the region profile-collection rebuild plus copy-or-default seeding path rather than a generic collection allocator.","objdump + caller xrefs + local disassembly + editor-copy-flow correlation + profile-subcollection rebuild correlation" 0x00420ed0,803,world_region_rebuild_profile_collection_and_seed_class_split_default_weights,map,thiscall,inferred,objdump + caller xrefs + local disassembly + region-profile correlation,3,"Companion region-side subcollection rebuild helper over `[region+0x37f]` for the no-source default path. Like `world_region_rebuild_profile_collection_from_source_region_and_seed_default_weights` `0x00420e00`, the function first frees and recreates the current `0x88`-byte indexed collection at `[region+0x37f]`. It then immediately seeds one fixed profile-label set through repeated `world_region_upsert_or_remove_structure_profile_weight_by_name` `0x004206b0`, but the exact label set splits by region class dword `[region+0x23e]`: nonzero-class regions take one all-`0.2f` default set, while class-0 regions take a different default family that starts with one `0.3f` entry and then continues with repeated `0.2f` entries. Current grounded caller is the neighboring default-region initialization path at `0x0042141c`, so this is the safest current read for the shared class-split default profile seeding companion beneath the broader region-profile collection family rather than another editor-only copy helper.","objdump + caller xrefs + local disassembly + region-profile correlation + class-split default-set correlation" 0x00420410,167,world_region_refresh_profile_availability_summary_bytes_0x2f6_0x2fa_0x2fe,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Small derived-summary refresh over the current region subcollection `[region+0x37f]`. The helper clears the three dword summary lanes `[region+0x2f6/+0x2fa/+0x2fe]`, walks every live profile entry through `indexed_collection_slot_count` `0x00517cf0`, `indexed_collection_get_nth_live_entry_id` `0x00518380`, and `indexed_collection_resolve_live_entry_by_id` `0x00518140`, resolves the backing structure candidate by name through `0x00412b70`, and then inspects candidate bytes `[candidate+0xba]` and `[candidate+0xbb]`. When either byte is nonzero it sets `[region+0x2f6] = 1`; a nonzero `[candidate+0xba]` sets `[region+0x2fa] = 1`, while the complementary branch sets `[region+0x2fe] = 1`. Current grounded caller is the editor-side mutation helper `0x004206b0`, which runs this refresh after every profile add, remove, or weight update.","objdump + local disassembly + caller correlation + region-subcollection correlation + summary-byte correlation" +0x00421d20,246,world_region_collection_count_regions_with_profile_label_matching_candidate_name,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Counts the live regions in the current region collection whose profile subcollection `[region+0x37f]` contains one label equal to the candidate-name string for the caller-supplied candidate id. The helper resolves that candidate name from the global candidate pool `0x0062b268`, lowercases its first byte through `0x0051d660` as a cheap prefilter, skips region records whose class dword `[region+0x23e]` is nonzero and whose companion availability count `[region+0x242]` is nonpositive, then walks each surviving region's profile entries through `0x0041f6a0` and `0x0041fac0` until a casefolded label match through `0x005a57cf` is found. It increments the region count once per matching region and returns that total. Grounded callers include the editor-side summary builders at `0x004cdd56` and `0x004d150e`.","objdump + local disassembly + caller correlation + region-profile correlation + editor-summary correlation" +0x00421e30,275,world_region_collection_resolve_nth_region_with_profile_label_matching_candidate_name,map,thiscall,inferred,objdump + local disassembly + caller correlation,3,"Resolves the Nth live region in the current region collection whose profile subcollection `[region+0x37f]` contains one label equal to the candidate-name string for the caller-supplied candidate id. The helper uses the same first-byte lowercase prefilter and full casefolded compare as `0x00421d20`, skips nonzero-class regions whose `[region+0x242]` count is nonpositive, and increments one match counter once per region rather than once per profile row. When that counter reaches the caller-supplied 1-based ordinal, it returns the matching region record pointer; otherwise it returns null. Current grounded caller is the editor-side enumerator at `0x004cdeab`, which immediately formats the returned region name for display.","objdump + local disassembly + caller correlation + region-profile correlation + editor-summary correlation" +0x00422010,155,world_region_collection_resolve_nearest_class0_region_id_covering_normalized_rect,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Scans the live region collection for class-0 region records whose normalized primary and secondary coordinates fall inside the caller-supplied inclusive float bounds, refreshes a small region-local helper through `0x00455a70(0)` on each in-bounds candidate, and keeps the nearest matching region id `[region+0x23a]` by squared XY distance through `math_measure_float_xy_pair_distance` `0x0051db80`. The helper returns `0` when no class-0 region lies inside the supplied rectangle. Current grounded callers include the world-side selection branch at `0x00452658`, where integer world arguments are converted to floats before the query, and the small string wrapper `0x004220b0`.","objdump + local disassembly + caller correlation + region-distance correlation" +0x004220b0,73,world_region_collection_query_name_of_nearest_class0_region_covering_normalized_rect_or_default,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Small wrapper above `world_region_collection_resolve_nearest_class0_region_id_covering_normalized_rect` `0x00422010`. When the inner query returns a live region id, the helper resolves that region and returns name pointer `[region+0x356]`; otherwise it copies the fallback localized string `0x00d0` into global scratch buffer `0x0062ba90` and returns that buffer instead. Grounded callers include the early world-status formatter `0x00401815`, the later world-side branch `0x00411c41`, and the terrain-side formatter at `0x004f2b97`.","objdump + local disassembly + caller correlation + region-name correlation" +0x00422100,543,world_region_collection_pick_periodic_candidate_region_and_queue_scaled_event_record,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Periodic region-side selector reached from `simulation_service_periodic_boundary_work` `0x0040a590`. The helper first requires several live world-state gates to be clear, derives one year-sensitive random threshold from selected-year fields `[world+0x05/+0x0d/+0x0f]` plus live world width `[world+0x2155]`, and returns immediately unless one bounded random test passes. On the active path it scans the live region collection twice. The first pass counts eligible class-0 regions whose transient dwords `[region+0x276]` and `[region+0x302]` are clear and which fail the city-connection peer probe `0x00420030(1,1,0,0)`. The second pass picks one random eligible region, derives one small severity bucket from cached scalar `[region+0x25e]`, stores the resulting scaled amount into `[region+0x276]`, and appends one 0x20-byte queued record through `0x004337c0` with literal kind `7`, the chosen region id `[region+0x23a]`, the scaled amount, sentinel dwords `-1/-1`, and fixed payload `0x005c87a8`. The exact gameplay label for that queued record is still open, so the current name stays structural around the periodic class-0 region pick plus queued scaled event record.","objdump + local disassembly + caller correlation + periodic-maintenance correlation + queued-record correlation" +0x00421f50,181,world_region_collection_refresh_position_triplet_for_class0_regions_inside_normalized_rect,map,thiscall,inferred,objdump + local disassembly + caller correlation,2,"Scans the current live region collection for class-0 records whose normalized primary and secondary coordinates fall inside the caller-supplied inclusive float rectangle, then refreshes each qualifying region's current-position triplet through `runtime_object_publish_current_position_triplet_with_height_bias` `0x00455a70(0)`. The helper performs no further aggregation and simply walks the surviving records through the live region collection interfaces `0x00517cf0/0x00518380/0x00518140`. Current grounded caller is the rectangle-side height-support owner `0x0044d410`, where this acts as one dependent region refresh across the updated work window rather than a broader collection rebuild.","objdump + local disassembly + caller correlation + region-rectangle correlation" 0x00421700,32,runtime_object_collection_remove_entry_by_id_release_record_and_erase_id,map,thiscall,inferred,objdump + local disassembly + collection-layout correlation,2,"Small collection-side removal helper for the sibling runtime-object family tied to table `0x005c9a60`. The function resolves the caller-supplied entry id through `0x00518140`, releases the resulting record through `0x00420670`, and then removes that id from the current collection through `0x00518a30`. Current evidence grounds this as the collection-owned remove-and-release wrapper rather than a wider rebuild pass.","objdump + local disassembly + collection-layout correlation + sibling-table correlation" 0x00421730,560,world_region_collection_clear_cell_region_word_and_assign_nearest_region_ids,map,thiscall,inferred,objdump + local disassembly + caller inspection + region-correlation,3,"Region-side world-grid finalizer beneath the default region seeding path. The helper first clears the per-cell region word at `[world+0x212d] + cell*4 + 1` across the full live world raster using dimensions `[world+0x214d/+0x2151]`. It then seeds each live region entry with default bounds and helper fields `[region+0x242/+0x24e/+0x252] = 0` and `[region+0x246/+0x24a] = 0x270f`, and for every class-0 region computes one square neighborhood around the region center from `[region+0x256]`, `0x00455800`, and `0x00455810`. Within that bounded cell rectangle it evaluates one distance-like score through `0x0051dbb0` and writes the current region id `[region+0x23a]` into the per-cell word when the slot is empty or when the current region beats the previously assigned region on the same score. Current grounded callers are `world_region_collection_seed_default_regions` `0x00421b60` and the broader world-build path around `0x004476ec`, so this is the safest current read for clearing and repopulating the world-cell region-id raster rather than a generic collection sweep.","objdump + local disassembly + caller inspection + region-correlation + raster-assignment correlation" +0x0042b190,144,route_entry_list_append_six_byte_record,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Appends one six-byte `(u16 key, u32 payload)` record onto the compact route-entry list rooted at `[this+0xeb]/[this+0xef]`. The helper allocates a replacement buffer sized for one extra record, copies the existing six-byte rows, writes the caller-supplied key and payload into the new tail, frees the old buffer, stores the replacement pointer, and increments the count. Current grounded callers include the sampled-cell rebuild owner `0x0047f320` and the world-cell chain sweep `0x0042c530`, so this is the safest current read for the plain append companion beneath the broader route-entry list families.","objdump + caller xrefs + local disassembly + six-byte-record correlation" +0x0042b230,158,route_entry_list_remove_six_byte_record_by_key,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Removes one six-byte route-entry row from the compact list rooted at `[this+0xeb]/[this+0xef]` by matching the leading `u16` key. When the current count is greater than one the helper allocates a replacement buffer for `count-1` rows, copies every nonmatching six-byte row forward, frees the old buffer, stores the replacement pointer, and decrements the count; small or empty lists fall through to the same free-and-decrement tail. Current grounded caller is the sampled-cell rebuild owner `0x0047f320`, which uses it while maintaining the per-cell route-entry side list, so this is the safest current read for the keyed remove companion to `0x0042b190`.","objdump + caller xrefs + local disassembly + six-byte-record correlation" +0x0042b2d0,52,route_entry_list_contains_key,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Boolean membership test over the compact six-byte route-entry list rooted at `[this+0xeb]/[this+0xef]`. The helper linearly scans the current rows and returns true when any leading `u16` key matches the caller-supplied id; otherwise it returns false. Current grounded callers include the linked-site support strip at `0x0040d27f`, the region or profile-side query family at `0x0041f6e7`, `0x0042007c`, `0x0042011a`, `0x0042020c`, `0x004202ba`, `0x004208b6`, and the later placed-structure branch at `0x004adecf`, so this is the safest current read for the shared contains-key helper beneath the same six-byte route-entry list family.","objdump + caller xrefs + local disassembly + six-byte-record correlation" +0x0042bbb0,51,world_cell_prepend_site_id_into_owner_chain_field_0xd4,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Prepends one placed-structure site id into the world-cell owner chain rooted at word `[cell+0xd4]`. The helper resolves the caller-supplied site id through the live placed-structure collection `0x006cec20`, writes the previous head id from `[cell+0xd4]` into that site's next-site field `[site+0x3c]` through `placed_structure_set_linked_cell_owner_next_site_id_field_0x3c` `0x0047d6f0`, and then stores the new site id back into `[cell+0xd4]`. Current grounded callers are the linked-site runtime refresh strip at `0x004807d7` and the earlier world-coordinate mutation path at `0x00480673`, so this is the safest current read for the cell-owner-chain prepend helper rather than a generic word setter.","objdump + caller xrefs + local disassembly + cell-owner-chain correlation" +0x0042bbf0,124,world_cell_remove_site_id_from_owner_chain_field_0xd4,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Removes one placed-structure site id from the world-cell owner chain rooted at word `[cell+0xd4]`. The helper walks the current head id and the linked next-site field `[site+0x3c]` through the live placed-structure collection `0x006cec20` until it finds the requested site id; when the requested site is the head it replaces `[cell+0xd4]` with that site's successor, otherwise it patches the predecessor's `[site+0x3c]` through `placed_structure_set_linked_cell_owner_next_site_id_field_0x3c` `0x0047d6f0`. Current grounded callers are the linked-site teardown and refresh strip at `0x00480673` and `0x00480769`, so this is the safest current read for the cell-owner-chain remove helper rather than a broader collection sweep.","objdump + caller xrefs + local disassembly + cell-owner-chain correlation" 0x0042a970,188,shell_open_file_dialog_copy_selected_path_and_restore_cwd,shell,thiscall,inferred,objdump + literal correlation,3,"Small shell-side file-open dialog wrapper. The helper clears the caller output buffer, snapshots the current working directory through one import pair, builds a `0x4c`-byte open-file dialog record on the stack, calls the file-open import, restores the previous working directory, and returns true only when the caller buffer is left non-empty. Current grounded caller is the `Setup.win` branch at `0x005039cd`, which passes the `TGA Files (*.tga)` filter at `0x005d1674` and root `.\Data\GrayscaleMaps` at `0x005d1690`, so this is now the generic picker beneath the grayscale-heightmap generation lane rather than another multiplayer helper.","objdump + literal correlation + setup-branch reconstruction" 0x005411c0,79,shell_query_tga_header_is_supported_truecolor_image,shell,cdecl,inferred,objdump + error-string correlation,3,"Small image-header validator used by the `Setup.win` grayscale-heightmap lane. The helper opens the caller path, reads `0x12` bytes into a local buffer, closes the handle, and returns true only when the read succeeds, the error byte remains clear, and the header's image-type byte equals `2`. Current grounded caller is the `0x005039fe` branch beneath `0x005033d0`, where failure raises localized error `0x0e13` (`The selected image is not useable by the game... true-color ... Targa image.`).","objdump + caller correlation + error-string correlation + TGA-header inspection" 0x004801a0,105,placed_structure_is_linked_transit_site_reachable_from_company_route_anchor,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Boolean gate between one linked transit site and one company-side route anchor. The helper first requires the current placed structure to pass the station-or-transit gate `0x0047fd50`, then requires its linked-instance class test through `0x0040c990 == 1`. It resolves the caller-supplied company id through the live company collection `0x0062be10`, asks that company for one cached route-anchor entry id through `company_query_cached_linked_transit_route_anchor_entry_id` `0x00401860`, resolves the site's own route-entry anchor through collection `0x006cfca8`, and finally re-enters `0x0048e3c0` to test whether the two route-entry anchors lie in the same reachable route-side family. Current grounded caller is `company_rebuild_linked_transit_site_peer_cache` `0x004093d0`, where this helper gates whether a foreign linked transit site can still participate in the current company's peer cache.","objdump + caller xrefs + callsite inspection + linked-transit reachability correlation" +0x0042c530,74,world_cell_append_linked_site_chain_route_entries_into_route_list,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Walks the placed-structure linked-site chain for one world cell and appends each site's route-entry payload into the caller-owned six-byte list. The helper starts from word `[cell+0xd6]`, follows the linked-site chain through `[site+0x2a2]` in the live placed-structure collection `0x0062b26c`, and re-enters `route_entry_list_append_six_byte_record` `0x0042b190` with each visited site id plus the caller-supplied payload dword. Current grounded caller is the sampled-cell rebuild owner `0x0047f320`, so this is the safest current read for the cell-linked-site route-entry gather helper rather than a generic list walk.","objdump + caller xrefs + local disassembly + linked-site-chain correlation + route-entry-list correlation" +0x0042c580,265,world_cell_accumulate_directional_word_fan_toward_grid_target,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Accumulates one directional word fan from the current world-cell record toward a caller-supplied grid target. The helper reads the cell-local anchor pair `[cell+0xe7]` and `[cell+0xe9]`, derives the dominant-axis distance to the target, chooses one of eight direction slots from the sign pattern of the X/Y deltas, and then walks outward one step at a time through the live world-grid table rooted at `[0x0062c120+0x2129]` using the fixed offset tables at `0x00624b28` and `0x00624b48`. At each step it adds the selected directional word from `[cell+0xf3 + dir*2]` into the running float total and returns that accumulated value. Current grounded caller is the sampled-cell rebuild owner `0x0047f320`, where this helper supplies the floating score stored in each temporary `(grid x, grid y, sampled score)` row.","objdump + caller xrefs + local disassembly + directional-word-fan correlation + sampled-score correlation" +0x0042c9a0,65,world_cell_prepend_site_id_into_linked_site_chain_field_0xd6,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Prepends one placed-structure site id into the world-cell linked-site chain rooted at word `[cell+0xd6]`. The helper resolves the caller-supplied site id through the live placed-structure collection `0x0062b26c`, writes the previous head id from `[cell+0xd6]` into that site's next-site field `[site+0x2a2]` through `placed_structure_set_linked_site_chain_next_id_field_0x2a2` `0x0040cb00`, stores the new site id back into `[cell+0xd6]`, and then re-enters `0x0042c690` plus `0x0042c8f0` to refresh the same cell-local linked-site derived state. Current grounded callers are the linked-site add or reposition paths `0x0040ec58` and `0x0040f84a`, so this is the safest current read for the cell-linked-site-chain prepend helper rather than a generic word setter.","objdump + caller xrefs + local disassembly + linked-site-chain correlation" +0x0042c9f0,179,world_cell_remove_site_id_from_linked_site_chain_field_0xd6,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Removes one placed-structure site id from the world-cell linked-site chain rooted at word `[cell+0xd6]`. The helper walks the current head id and the linked next-site field `[site+0x2a2]` through the live placed-structure collection `0x0062b26c` until it finds the requested site id; when the requested site is the head it replaces `[cell+0xd6]` with that site's successor, otherwise it patches the predecessor's `[site+0x2a2]` through `placed_structure_set_linked_site_chain_next_id_field_0x2a2` `0x0040cb00`. It then re-enters `0x0042c690` and `0x0042c8f0` to rebuild the same cell-local linked-site derived state. Current grounded callers are the linked-site removal or reposition paths `0x0040e331` and `0x0040ebfe`, so this is the safest current read for the cell-linked-site-chain remove helper rather than a broader collection sweep.","objdump + caller xrefs + local disassembly + linked-site-chain correlation" +0x0042c960,51,placed_structure_query_issue_opinion_scaled_word_lane,map,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Queries one rounded integer metric by multiplying the current word lane `[this+index*2] << 4` against the issue-opinion scale returned by `0x00437d20(index)`. The helper forwards the caller index into the scenario-side issue-opinion scaler, converts the selected word lane into a float, multiplies the two factors, and rounds the result through `0x005a10d0`. Current grounded callers include the setup-side candidate local-metrics rebuild `0x0041e2b0`, the route-style helper `0x0042cab0`, the linked-site runtime refresh strip `0x0047e240/0x0047faff`, several later placed-structure and world-side callers around `0x0040faf5`, `0x00410d7a`, `0x0044a093`, `0x0045020d`, `0x00452a1c`, and shell-side branches at `0x004ba156` and `0x004def77`, so this is the safest current read for the shared issue-opinion-scaled word-lane query rather than a raw table fetch.","objdump + caller xrefs + local disassembly + issue-opinion scaling correlation" 0x00480590,371,placed_structure_teardown_linked_site_runtime_state_before_removal,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Tears down the mutable runtime side of one linked placed-structure record before collection removal. The helper clears the route-style scratch lane through `0x004077e0`, clears the proximity buckets through `placed_structure_clear_proximity_bucket_lists` `0x0047dcd0`, frees the trailing scratch buffer at `[this+0x34]`, clears the route-link list through `0x0047f320`, detaches or invalidates the current route-entry anchor at `[this+0x08]` through the route-entry collection `0x006cfca8`, recomputes the current grid-keyed owner lane through `0x0042bbf0`, frees the three per-site byte arrays at `[this+0x24..0x2c]`, clears this record's indexed byte in the corresponding arrays of every later placed-structure record in `0x006cec20`, and finally re-enters the scenario-side follow-on at `0x00436040` with the current site id. Current direct caller is `placed_structure_collection_remove_linked_site_record` `0x004813d0`, so this is the linked-site teardown pass rather than another route-anchor refresh helper.","objdump + caller xrefs + callsite inspection + linked-site teardown correlation" +0x00480710,1170,placed_structure_refresh_linked_site_runtime_side_buffers_and_route_entry_anchor,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Primary linked-site runtime-side refresh owner above the sampled-cell list and nearby-transit bucket helpers. The function first clears the current proximity buckets through `placed_structure_clear_proximity_bucket_lists` `0x0047dcd0`, runs `placed_structure_rebuild_local_service_sampled_cell_list_and_reset_route_link_scratch` `0x0047f320(1,arg1)` against the pre-update state, republishes the current site position into the world-grid owner mapping through `0x0042bbf0/0x0042bbb0`, reruns `0x0047f320(0,-1)` to materialize the current sampled-cell list, and then rebuilds the nearby-transit bucket arrays through `placed_structure_rebuild_nearby_transit_site_distance_buckets_from_neighbor_cells` `0x0047fef0`. After that it either reuses a still-valid route-entry anchor through `0x00417b40` and `placed_structure_rebind_route_entry_anchor_to_site_id` `0x0048abc0`, or synthesizes a replacement through `0x00493cf0` before rebinding it the same way; when an old anchor survives but now points at a different owner, the helper clears the prior `[entry+0x222]` back to `-1`. Current grounded callers are the world-coordinate mutation path `placed_structure_set_world_coords_and_refresh_local_runtime_side_state` `0x0040eba0` and the constructor or rebuild strip around `0x0040f6d0`, so this is the safest current read for the broader linked-site runtime-side refresh plus route-entry-anchor rebind owner rather than another narrow route selector.","objdump + caller xrefs + callsite inspection + linked-site-runtime correlation + route-entry-anchor rebind correlation + proximity-bucket correlation" 0x00480bb0,1535,placed_structure_refresh_linked_site_display_name_and_route_anchor,map,thiscall,inferred,objdump + caller xrefs + callsite inspection + RT3.lng strings,3,"Single-site post-create or post-edit refresh helper reached from `placed_structure_finalize_creation_or_rebuild_local_runtime_state` `0x0040ef10` when the current placed structure keeps one linked site id at `[this+0x2a8]`. The helper operates on that linked placed-structure record, optionally rebuilds one route-entry anchor at `[this+0x08]` through `route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0` with both optional endpoint-entry ids unset and literal policy byte `2`, then binds the chosen route entry back to the site through `0x0048abc0` and re-enters `aux_route_entry_tracker_collection_refresh_route_entry_group_membership` `0x004a45f0` so the auxiliary tracker family at `0x006cfcb4` can regroup around the refreshed anchor. Current caller correlation makes that byte the strongest current match for the broader linked-site route-anchor rebuild lane, as opposed to the narrower direct endpoint-anchor creation or replacement lane that neighboring repair branches drive through literal byte `1` into `0x00493cf0`. It also rebuilds the display-name buffer at `[this+0x46b]`: when the current site coordinates resolve a city or region entry through `0x0044a830` it copies that entry name from `[entry+0x356]`, optionally appends one civic suffix from RT3.lng ids `585..588` `Township`, `New`, `Modern`, and `Renaissance`, and on special linked-instance class branches appends `589` `Service Tower` or `590` `Maintenance Facility` with per-city counters instead. When no city entry resolves it falls back to `591` `Anytown`. The ordinary non-special branch also rotates through RT3.lng ids `578..584` `Junction`, `Crossing`, `Depot`, `Corners`, `Exchange`, `Point`, and `Center` via the static table at `0x005f2cf8`. After trimming trailing spaces it conditionally re-enters `placed_structure_route_link_collection_recompute_all_endpoint_pair_state` `0x004682c0` when the narrower station-or-transit gate `0x0047fd50` passes, clears or seeds adjacent city-side cached state through `0x004358d0` and `0x00420650`, and returns. Current direct caller is `0x0040f626`, so this now looks like the linked-site display-name and route-anchor refresh beneath placed-structure finalization rather than another city-connection owner.","objdump + caller xrefs + callsite inspection + RT3.lng strings + route-anchor correlation + linked-site refresh correlation + linked-site policy-byte split correlation + tracker-regrouping correlation" 0x00481390,55,placed_structure_collection_allocate_and_construct_linked_site_record,map,thiscall,inferred,objdump + caller xrefs + constructor inspection,3,"Small allocator wrapper over the live placed-structure collection at `0x006cec20`. The helper allocates one fresh collection entry id through `0x00518900`, resolves the new record through `0x00518140`, and then hands the new id plus the caller-supplied anchor site id and coordinate pair into `placed_structure_construct_linked_site_record_from_anchor_and_coords` `0x00480210`. Current direct caller is `placed_structure_construct_entry_from_candidate_and_world_args` `0x0040f6d0`, where the returned id is published into `[site+0x2a8]` when the backing candidate subtype byte `[candidate+0x32]` is `1`. This is the allocator wrapper for the linked-site records used by the later policy-`1` and policy-`2` route-anchor refresh families rather than another anonymous collection helper.","objdump + caller xrefs + constructor inspection + linked-site correlation" 0x004813d0,91,placed_structure_collection_remove_linked_site_record,map,thiscall,inferred,objdump + caller xrefs + callsite inspection,3,"Removes one linked-site record from the live placed-structure collection. The helper resolves the supplied site id through `0x006cec20`, derives one station-or-transit or linked-instance-class latch through `0x0047de00 -> 0x0040c990`, runs `placed_structure_teardown_linked_site_runtime_state_before_removal` `0x00480590`, and then removes the collection entry through `0x00518a30`. When scenario field `[0x006cec78+0x4c93]` is clear and the removed record passed the narrower latch, it also re-enters the company-wide follow-on at `0x00429c10`. Current direct caller is the subtype-`1` destruction path around `0x0040f626`.","objdump + caller xrefs + callsite inspection + linked-site removal correlation" @@ -957,16 +1548,98 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x005a3117,36,crt_fast_error_exit,startup,cdecl,inferred,ghidra-headless,4,Startup error path that optionally emits the CRT banner then formats the failure and terminates through ___crtExitProcess.,ghidra + rizin 0x005a313b,423,crt_startup_entrypoint,startup,cdecl,inferred,ghidra-headless,4,PE entrypoint for patch 1.06; performs CRT and environment setup then validates early state before handing off to application bootstrap.,sha256:01b0d2496cddefd80e7e8678930e00b13eb8607dd4960096f527564f02af36d4 + ghidra + rizin + llvm-objdump 0x0053b020,70,bootstrap_reset_locale_state,bootstrap,unknown,inferred,ghidra-headless,2,Calls the locale helper at 0x0053ae70 then frees and clears related global pointers before later shell setup continues.,ghidra + rizin +0x0053afd0,26,shared_release_owned_heap_ptr_field_0_and_clear_root,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny shared release wrapper over dword root `[this+0x00]`. When that root is non-null, the helper frees it through `0x005a1145` and clears `[this+0x00]` back to null. Current callers span the slot-table service family `0x00530a00`, the shell status and control owner `0x00538640/0x00538b60`, several world and bootstrap support strips, and multiple placed-structure or runtime-object payload owners, so this is the safest current read for a generic free-and-clear wrapper rather than a family-specific destructor.","objdump + caller inspection + local disassembly + shared-wrapper correlation" +0x0053aff0,26,shared_release_owned_heap_ptr_field_0_and_clear_root_sibling,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Sibling tiny free-and-clear wrapper over dword root `[this+0x00]`. Like `0x0053afd0`, the helper frees one non-null owned heap pointer through `0x005a1145` and clears the root back to null. Current grounded callers are narrower specialization and payload-owner families such as `0x00455d65`, `0x0045607b`, `0x0045b1f9`, `0x0045c280`, and `0x0045e516`, so this is the safest current read for a shared sibling wrapper rather than a unique subtype-specific release body.","objdump + caller inspection + local disassembly + shared-wrapper correlation" +0x0053b090,757,global_banked_13_byte_record_family_load_stream_bank_and_rebuild_bucket_tables,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Loader for one bank in the neighboring global support family rooted at `[this+0x204ac]` with active-bank count `[this+0x427b8]`. The helper acquires one stream or slot handle from the caller through `0x005a4c57(…,0x8000)`, validates two tagged `4`-byte reads through `0x005a48c5`, allocates one contiguous `13 * count` byte record slab, and then populates that slab either by copying raw `13`-byte records or by slicing the same stream into fixed `13`-byte rows. It records the active row count at `[this+bank*4+0x417ec]`, zeroes and fills one `32`-bucket histogram at `[this+bank*0x80+0x223ec]`, allocates per-bucket storage for each nonempty bucket, copies each row into the matching bucket-selected slab, frees the temporary contiguous slab, and finally increments active-bank count `[this+0x427b8]`. Current grounded caller is the static-table-driven load loop at `0x0053ce09`, so this is the safest current read for the banked fixed-record loader plus bucket-table rebuild owner rather than a generic file reader.","objdump + caller inspection + local disassembly + fixed-record correlation + bucket-table correlation" +0x0053b390,561,global_banked_13_byte_record_family_lookup_by_key_with_recent_query_cache,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Lookup core for the same banked `13`-byte-record support family. Given a caller-supplied key dword, the helper first searches a `10`-entry recent-query cache rooted at `[this+0x4290c]`, then scans the active per-bank bucket slabs selected by `key & 0x1f`, and on a hit returns the resolved bank index, bucket-local row index, and row offset to three caller output pointers. On a miss it optionally formats one diagnostic buffer from `[this+0x427c0]` and returns `0`; on a direct hit in the first bank scan it also rotates the recent-query cache fields `[this+0x4290c/+0x42934/+0x4295c/+0x42984/+0x429ac]`. Current grounded callers are the thin wrapper `0x0053b590` and a larger family of support-side query branches under `0x0053babd..0x0053ce09`, so this is the safest current read for the keyed bank-and-bucket lookup core rather than a generic map search.","objdump + caller inspection + local disassembly + keyed-lookup correlation + recent-cache correlation" +0x0053b590,35,global_banked_13_byte_record_lookup_wrapper_with_stack_locals,bootstrap,cdecl,inferred,objdump + caller inspection + local disassembly,1,"Thin cdecl wrapper above `global_banked_13_byte_record_family_lookup_by_key_with_recent_query_cache` `0x0053b390`. The helper builds three stack-local output slots, forwards the caller key and output pointers into `0x0053b390`, and returns that same status code. This is the safest current read for the trivial lookup wrapper rather than a second independent search owner.","objdump + caller inspection + local disassembly + lookup-wrapper correlation" +0x0053b5c0,98,global_hash_string_and_copy_into_0x427c0_scratch,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small string helper in the same banked-record support family. The helper copies the caller-supplied NUL-terminated string into scratch buffer `[this+0x427c0]`, measures its length, then folds each byte through `0x0051d660` and one multiply-add recurrence seeded from `7`, returning the final signed hash-like accumulator. This is the safest current read for the support-family string-hash helper rather than a user-facing formatter.","objdump + caller inspection + local disassembly + string-hash correlation" +0x0053b630,94,global_banked_13_byte_record_family_resolve_nth_live_entry_and_cache_current,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Ordinal resolver over the same banked support family. Given one zero-based ordinal, the helper walks the `32` bucket-chain roots at `[this+0x203a4]`, advances through each linked list by link field `+0x14`, and returns the matching live entry root when found. On success it also caches the current ordinal at `[this+0x427b0]` and the current entry root at `[this+0x20424]`. This is the safest current read for the nth-live-entry resolver rather than a generic list walk.","objdump + caller inspection + local disassembly + ordinal-resolution correlation" +0x0053b690,82,global_banked_13_byte_record_family_close_current_stream_handle_if_open,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small close helper over the current entry selected through `[this+0x427bc]`. The helper resolves that current entry through `global_banked_13_byte_record_family_resolve_nth_live_entry_and_cache_current` `0x0053b630`, and when the selected entry carries a live stream or slot handle at `[entry+0x04]` it closes either the auxiliary object `[entry+0x08]` through `0x005a1740` or the raw handle itself through `0x005a440d`, then resets `[entry+0x04]` to `-1` and `[entry+0x08]` to `0`. This is the safest current read for the current-stream close helper rather than a generic free path.","objdump + caller inspection + local disassembly + current-stream correlation" +0x0053b6f0,199,global_banked_13_byte_record_family_open_current_entry_stream_from_path,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Open helper for the current selected support-family entry. The helper resolves the current entry through `0x0053b630`, copies the path string at `[entry+0x10]` into one stack buffer, opens a new stream or slot handle through `0x005a4c57(…,0x8000)`, stores that handle at `[entry+0x04]`, clears `[entry+0x08]`, and emits one diagnostics path when the open fails. This is the safest current read for opening the current entry's stream from its stored path rather than a generic file open wrapper.","objdump + caller inspection + local disassembly + current-stream correlation" +0x0053b7c0,105,global_banked_13_byte_record_family_read_bytes_from_selected_or_current_stream_and_accumulate_counters,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Shared read helper over the support family's active stream handle. When `[this+0x427bc] < 0` it resolves the current entry through `0x0053b630` and uses that entry's handle `[entry+0x04]`; otherwise it uses the active-bank handle from `[this+0x204ac + [this+0x427bc]*4]`. It then reads the caller-requested byte count through `0x005a48c5`, accumulates the total bytes-read and read-call counters into `[this+0x428ec/+0x428f0]`, and emits one diagnostics path when the short read does not match the requested size. Current grounded callers include `0x0053b830` and many support-side consumers under `0x0053cb1d..0x00566e7e`, so this is the safest current read for the family's shared byte-read helper.","objdump + caller inspection + local disassembly + stream-read correlation + counter-accumulation correlation" +0x0053b830,17,global_banked_13_byte_record_family_read_u32_wrapper,bootstrap,cdecl,inferred,objdump + caller inspection + local disassembly,1,"Tiny wrapper above `global_banked_13_byte_record_family_read_bytes_from_selected_or_current_stream_and_accumulate_counters` `0x0053b7c0`. The helper requests exactly `4` bytes into one stack-local dword and returns that same dword to the caller. This is the safest current read for the fixed-width read wrapper rather than a second stream owner.","objdump + caller inspection + local disassembly + fixed-read-wrapper correlation" +0x0053b850,125,global_banked_13_byte_record_staging_table_grow_by_100_rows,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Growth helper over the local `13`-byte staging table rooted at `[this+0x1f400]` with current row capacity `[this+0x427b4]`. The helper allocates a new slab large enough for the current rows plus `100` more, zero-fills the extension, copies any existing rows into the new slab, frees the old slab, then stores the new root back into `[this+0x1f400]` and increments capacity `[this+0x427b4]` by `100`. This is the safest current read for the staging-table growth helper rather than a generic realloc wrapper.","objdump + caller inspection + local disassembly + staging-table correlation" +0x0053b8d0,66,global_banked_13_byte_record_staging_table_service_type7_payloads_through_0x5512f0,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Linear service pass over the same `13`-byte staging table. The helper walks all live rows in `[this+0x1f400]`, and for each row whose leading count dword is positive and whose type byte at `+0x08` equals `7`, it forwards payload dword `[row+0x09]` into `0x005512f0`. Current grounded callers include `0x0051ffba`, `0x0052b9e7`, and `0x00565164`, so this is the safest current read for one type-7 staging-table service pass rather than a broader table rebuild.","objdump + caller inspection + local disassembly + staging-table correlation + type7-service correlation" +0x0053b920,66,global_banked_13_byte_record_staging_table_service_type7_payloads_through_0x550420,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Sibling linear service pass over the same `13`-byte staging table. Like `0x0053b8d0`, the helper walks all live rows and filters on positive count plus type byte `7`, but it forwards payload dword `[row+0x09]` into `0x00550420` instead. Current grounded callers include `0x0051ffba`, `0x0052040a`, `0x0052b9c1`, and `0x0056513e`, so this is the safest current read for the second type-7 service pass rather than another generic table walk.","objdump + caller inspection + local disassembly + staging-table correlation + type7-service correlation" +0x0053b970,98,global_banked_13_byte_record_family_clear_bucket_chains_and_reset_current_selection,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Reset helper over the same banked-record support family. The helper first closes the current selected entry through `0x0053b690` when `[this+0x427bc]` is negative, then walks all `32` bucket-chain roots at `[this+0x203a4]`, frees each chained node's payload `[node+0x10]` and the node itself through `0x0053b080`, and finally clears current-entry cache `[this+0x20424]` and resets current ordinal `[this+0x427b0]` back to `-1`. Current grounded caller is the broader staging-table owner `0x0053b9f2`, so this is the safest current read for the bucket-chain reset helper rather than a full family destructor.","objdump + caller inspection + local disassembly + bucket-chain-reset correlation" +0x0053b9e0,848,global_banked_13_byte_record_family_emit_pack_system_leak_report_reset_owned_report_slots_and_close_all_bank_streams,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Broader report-and-reset owner over the same banked `13`-byte-record support family. The helper begins by calling `0x0053b970`, then releases four owned report-slot roots at `[this+0x429b0..+0x429bc]` plus sibling global root `0x00ccba50` through `0x0053ba46`. It next walks the local staging rows at `[this+0x1f400]`, repeatedly resolves keyed bank entries through `0x0053b390`, formats several numeric row fields through `0x0051b700`, packages the resulting line data through `0x00518de0/0x0051d680`, and publishes those lines through callback slot `0x005c8078`; the final footer uses static format string `Pack System Leak Count : %1`. After the report pass it frees the staging slab, clears active-bank count `[this+0x427b8]`, releases one `32`-entry owned-report strip through `0x0053afd0`, and closes every per-bank handle or auxiliary object rooted at `[this+0x204ac/+0x2144c]`. This is the safest current read for the pack-system leak-report and full support-family reset owner rather than a generic destructor.","objdump + caller inspection + local disassembly + leak-report-string correlation + bank-reset correlation" +0x0053ba1b,43,global_construct_0x88_pack_report_slot_through_0x518b90,bootstrap,stdcall,inferred,objdump + local disassembly,1,"Tiny owned-object constructor used in the same support-side report family. The helper allocates `0x88` bytes through `0x0053b070`, and on success forwards the new root plus caller payload into `0x00518b90(…,1,arg,10,5,0,0,0)`. This is the safest current read for a narrow `0x88`-byte report-slot constructor rather than a generic allocator wrapper.","objdump + local disassembly + ctor-shape correlation" +0x0053ba46,33,global_release_and_clear_owned_pack_report_slot_root,bootstrap,stdcall,inferred,objdump + caller inspection + local disassembly,1,"Tiny release helper over one caller-supplied dword root pointer. When the root is non-null, the helper clears it, releases the owned object through `0x00519bd0`, then frees the wrapper through `0x0053b080`. Current grounded callers are the broader report owner `0x0053b9e0` and nearby support-side cleanup strips, so this is the safest current read for a narrow owned-report-slot release helper rather than a family-wide destructor.","objdump + caller inspection + local disassembly + release-shape correlation" +0x0053bd40,197,global_banked_13_byte_record_family_seek_selected_or_current_payload_stream_by_key_and_return_handle,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Keyed stream-position helper over the same banked support family. The helper resolves the caller key through `0x0053b390`; when the lookup lands in one active bank, it increments query counter `[this+0x428f4]`, computes the bank-local byte offset from the row-size base `[this+0x1f404 + bank*4]`, row count `[this+0x417ec + bank*4]`, bucket row root, and row offset, then seeks the live bank handle `[this+0x204ac + bank*4]` through `0x005ac18d(…,offset+8,0)` and returns that handle. When the lookup resolves as a negative current-entry ordinal instead, it opens the selected entry stream through `0x0053b6f0`, optionally seeks that entry handle by the caller offset, and returns the same handle. Current grounded callers allocate one output buffer from the paired length helper `0x0053c9c0` and immediately feed the returned handle into `0x0053b7c0`, so this is the safest current read for the keyed seek-and-return-stream helper rather than a raw file-open wrapper.","objdump + caller inspection + local disassembly + stream-seek correlation + keyed-lookup correlation" +0x0053be10,325,global_banked_13_byte_record_family_resolve_or_lazy_open_typed_aux_object_by_key,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Keyed typed-object resolver over the same support family. The helper resolves the caller key through `0x0053b390`; on a positive bank hit it seeks the matching bank handle to the row payload through the same offset computation used by `0x0053bd40`, then returns the cached per-bank auxiliary object at `[this+0x2144c + bank*4]` or lazily creates it through `0x005c7905` with one of two static descriptors, including one rooted at `data\\\\Other\\\\AirplaneTypes.txt`. On a negative current-entry ordinal it opens the current entry stream through `0x0053b6f0` and returns the lazily-created current-entry auxiliary object at `[entry+0x08]`. A global gate from `0x005a3f5b` can suppress one branch when the caller's flag byte is clear. Current grounded callers immediately pass the returned object into higher typed readers, so this is the safest current read for the keyed auxiliary-object resolver rather than another raw stream helper.","objdump + caller inspection + local disassembly + typed-object correlation + descriptor-string correlation" +0x0053bf60,125,global_banked_13_byte_record_staging_table_release_row_payload_by_type_and_clear_row,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Typed release helper over one local `13`-byte staging-table row selected by ordinal. The helper reads the row type byte at `+0x08` and payload root at `+0x09`, dispatches non-null payloads through type-specific release or service helpers including `0x00567520`, `0x00542c90`, `0x0053ee60`, and `0x005512a0`, then frees the payload root through `0x0053b080` when that branch returns and clears the entire row back to zero. Current grounded caller is the refcount-drop helper `0x0053c000`, so this is the safest current read for the typed row-payload release owner rather than a generic table reset.","objdump + caller inspection + local disassembly + staging-row correlation + type-dispatch correlation" +0x0053c000,98,global_banked_13_byte_record_staging_table_drop_refcount_by_payload_id_and_release_row_when_last_user,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Reference-drop helper over the same local `13`-byte staging table. Given one caller payload id, the helper scans row field `[row+0x09]` for a match, decrements that row's lead refcount dword, and returns immediately while the count stays positive. When the count reaches zero it checks one per-type persistent slot strip at `[this+0x4278c + type*4]`; if that strip is null, it tail-calls `0x0053bf60` to release the row payload and clear the row. This is the safest current read for a refcount-drop helper over staging payload instances rather than a second generic free path.","objdump + caller inspection + local disassembly + refcount correlation + staging-row correlation" +0x0053c070,333,global_banked_13_byte_record_staging_table_acquire_or_create_refcounted_row_for_payload_and_type,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Typed acquire-or-create helper over the same local `13`-byte staging table. The helper first searches existing rows for matching field `[row+0x04] == caller_payload_id`; on a hit it increments the lead refcount dword and returns the existing payload root `[row+0x09]`. On a miss it scans backward for one empty row, grows the table through `0x0053b850` when needed, seeds a new row with refcount `1`, caller payload id at `+0x04`, caller type byte at `+0x08`, and then lazily constructs the typed payload root at `+0x09` for selected types including `1 -> 0x00567500`, `6 -> 0x0053ee70`, and `7 -> 0x00551970`. This is the safest current read for the refcounted staging-row acquire-or-create owner rather than a plain append helper.","objdump + caller inspection + local disassembly + refcount correlation + typed-payload correlation" +0x0053c900,35,global_banked_13_byte_record_family_reset_bucket_stream_and_recent_query_state,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Compact reset helper above the same support family. The helper clears bucket chains through `0x0053b970`, re-enters neighboring cleanup `0x0053c820`, and then fills the `10`-entry recent-query cache rooted at `[this+0x4290c]` with `-1`. This is the safest current read for the family's compact cache-and-stream reset owner rather than a full constructor.","objdump + caller inspection + local disassembly + recent-cache correlation" +0x0053c930,140,global_banked_13_byte_record_family_lookup_composite_string_key,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Composite-string lookup wrapper over the same banked support family. The helper copies one caller primary string into a local stack buffer, optionally appends a second caller suffix string, hashes the resulting composite key through `0x0053b5c0`, and then forwards that key plus caller output slots and mode flag into `0x0053b390`. Current grounded callers use this as the main string-keyed probe across many shell and bootstrap paths, so this is the safest current read for the composite-key lookup wrapper rather than a user-facing formatter.","objdump + caller inspection + local disassembly + string-key correlation + keyed-lookup correlation" +0x0053c9c0,93,global_banked_13_byte_record_family_lookup_key_and_return_payload_byte_len,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small size resolver over the same banked support family. The helper resolves the caller key through `0x0053b390`; on a positive bank hit it returns row field `[bucket_row + row_index*0x0d + 0x04]`, while on a negative current-entry ordinal it resolves that entry through `0x0053b630` and returns `[entry+0x0c]` instead. Current grounded callers immediately pair this byte length with `0x0053bd40` and `0x0053b7c0` to allocate and read one keyed payload, so this is the safest current read for the keyed payload-length resolver rather than a generic field getter.","objdump + caller inspection + local disassembly + payload-length correlation + keyed-lookup correlation" +0x0053ca20,100,global_banked_13_byte_record_family_push_current_stream_selection_frame,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Push helper over the same banked support family's current stream-selection state. The helper allocates one `0x0c`-byte frame, snapshots either the current-entry handle `[entry+0x04]` or the active-bank handle `[this+0x204ac + [this+0x427bc]*4]` through `0x005c7820`, stores the current selection lane `[this+0x427bc]`, chains the previous frame root from `[this+0x20428]` into `[frame+0x08]`, and then publishes the new frame root back to `[this+0x20428]` while incrementing push counter `[this+0x428f8]`. Current grounded callers pair it with `0x0053ca90`, so this is the safest current read for the current-selection push helper rather than a generic alloc wrapper.","objdump + caller inspection + local disassembly + selection-frame correlation" +0x0053ca90,127,global_banked_13_byte_record_family_pop_current_stream_selection_frame_and_restore_seek,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Pop-and-restore helper over the same current stream-selection frame stack rooted at `[this+0x20428]`. When one frame is live, the helper increments `[this+0x428f8]`, closes the current entry stream through `0x0053b690` when needed, restores selection lane `[this+0x427bc]` from `[frame+0x04]`, reopens the selected current-entry stream through `0x0053b6f0` when the restored lane is negative, otherwise resolves the live bank handle from `[this+0x204ac]`, seeks that handle back to saved cursor `[frame+0x00]` through `0x005ac18d`, pops the frame chain from `[frame+0x08]`, and frees the frame root. Current grounded callers bracket typed support-side reads and object-acquisition flows, so this is the safest current read for the current-selection restore helper rather than a generic stack pop.","objdump + caller inspection + local disassembly + selection-frame correlation + stream-seek correlation" +0x0053cb10,73,global_banked_13_byte_record_family_read_two_u32_header_and_optional_heap_blob,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small read helper over the same active stream. The helper reads two `u32` values through `0x0053b7c0`; when the second value is nonzero, it allocates a heap buffer of that length through `0x005a125d`, stores the new pointer to one caller output slot, and reads that many payload bytes into the buffer through `0x0053b7c0`. Current grounded callers sit in support-family object loaders under `0x0053fb88`, `0x005403c7`, `0x0055b9a4`, and `0x00563c8f`, so this is the safest current read for a small two-dword-plus-optional-blob reader rather than a generic stream wrapper.","objdump + caller inspection + local disassembly + header-read correlation + heap-blob correlation" +0x0053cb60,1408,global_banked_13_byte_record_family_construct_reset_load_static_root_table_and_seed_report_slots,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Broader constructor and bootstrap-load owner for the same banked `13`-byte-record support family. The helper zeroes the per-type persistent slot strip `[this+0x4278c]`, clears the bucket-chain roots and active bank roots under `[this+0x203a4/+0x20424/+0x204ac]`, resets all counters and recent-query cache fields `[this+0x427b0..+0x429ac]`, seeds four owned report-slot roots `[this+0x429b0..+0x429bc]` through `0x0053ba1b`, grows the local staging slab through `0x0053b850`, and then walks the static pointer table rooted at `0x00624e14` through `0x00624e48`. For each table entry it formats one `%%1*.pk4`-style probe, loads one bank through `0x0053b090`, and later re-enters the keyed lookup and typed-object strip `0x0053c930/0x0053be10` to route selected records into the owned report slots with category probes such as `companyLogo`, `portrait`, and `trainSkin`. This is the safest current read for the family's constructor-plus-static-root-table bootstrap loader rather than a narrow per-bank helper.","objdump + caller inspection + local disassembly + static-root-table correlation + support-family bootstrap correlation" +0x0053d0f0,24,global_banked_13_byte_record_staging_table_acquire_type1_payload_by_string_key,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny string-keyed wrapper above the same staging-table acquire path. The helper hashes the caller string through `0x0053b5c0`, then acquires or creates a staging-row payload of type `1` through `0x0053c070`. Current grounded callers sit in shared runtime-object and support-family bootstrap flows, so this is the safest current read for the type-`1` string-keyed staging wrapper rather than a generic hash helper.","objdump + caller inspection + local disassembly + string-key correlation + type1-wrapper correlation" +0x0053d110,25,global_banked_13_byte_record_staging_table_acquire_type6_payload_by_string_key,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Sibling tiny string-keyed wrapper above `0x0053c070`. Like `0x0053d0f0`, the helper hashes one caller string through `0x0053b5c0`, but it acquires or creates a staging-row payload of type `6` instead. Current grounded callers span runtime-object, shell, and support-family flows, which makes this the safest current read for the type-`6` string-keyed staging wrapper rather than a raw field setter.","objdump + caller inspection + local disassembly + string-key correlation + type6-wrapper correlation" +0x0053d130,143,global_banked_type7_record_refresh_from_openable_path_basename_and_stem,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly + string-template correlation,2,"Path-normalizing helper beside the string-keyed staging wrappers. The function scans one caller path for the final backslash, copies the basename into a local buffer, derives a second local stem through `0x0051d8a0`, probes the original path through `support_query_path_is_openable_for_read` `0x0051e430`, and only on success forwards the basename plus stem into `0x0053c710` with the refresh flag set before resetting owner dword `[this+0x427b0] = -1`. The current grounded caller is the selector-`2` setup branch inside `shell_active_mode_run_profile_startup_and_load_dispatch` `0x00438890`, where it refreshes one support-family record from setup path buffer `0x006d1370` before the common world-init work continues, so this is the safest current read for the openable-path basename or stem refresh helper rather than a generic file parser.","objdump + caller inspection + local disassembly + string-template correlation + selector2-setup-path correlation" +0x0053d1d0,103,scored_heap_sift_up_node_by_field_0x04_and_refresh_slot_backpointers,support,thiscall,inferred,objdump + local disassembly,1,"Binary-heap sift-up helper over one owner whose array root is `[this+0x08]`. Starting from one caller index, the helper compares node score field `[node+0x04]` against the parent score, bubbles the higher-scoring node upward, and refreshes each moved node's backpointer at `[node+0x00]` to the new array slot address. This is the safest current read for a max-heap sift-up helper rather than a support-family-specific payload routine.","objdump + local disassembly + heap-shape correlation" +0x0053d240,143,scored_heap_sift_down_node_by_field_0x04_and_refresh_slot_backpointers,support,thiscall,inferred,objdump + local disassembly,1,"Binary-heap sift-down helper over the same owner. Given one caller index, the helper chooses the larger-scoring child by comparing child score field `[node+0x04]`, bubbles that child upward while its score stays above the current node's score, then writes the final node root back into the settled slot and refreshes its backpointer at `[node+0x00]`. This is the safest current read for the paired max-heap sift-down helper rather than a queue-family destructor.","objdump + local disassembly + heap-shape correlation" +0x0053d2e0,19,scored_heap_peek_top_score_field_0x04_or_zero,support,thiscall,inferred,objdump + local disassembly,1,"Tiny query helper over the same scored heap owner. When `[this+0x0c] > 0`, the helper returns score field `[heap[0]+0x04]`; otherwise it returns `0`. This is the safest current read for a top-score peek helper rather than a broader queue query.","objdump + local disassembly + heap-shape correlation" +0x0053d300,24,scored_heap_decrement_node_score_field_0x04_and_sift_down,support,thiscall,inferred,objdump + local disassembly,1,"Small heap-adjust helper over one caller node root. The helper decrements the node's score field `[node+0x04]`, derives the current array index from backpointer `[node+0x00]`, and tail-calls `0x0053d240` to restore heap order from that slot. This is the safest current read for a decrement-and-reheapify helper rather than a generic arithmetic wrapper.","objdump + local disassembly + heap-shape correlation" +0x0053d320,107,scored_node_queue_acquire_node_from_freelist_or_alloc_and_push,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small scored-node queue helper over one owner with queue root `[this+0x08]` and node-pool descriptor `[this+0x04]`. The helper first pops one reusable node from the pool freelist when available, otherwise allocates a fresh node of size `[pool+0x10]` through `0x0053b070`; it then pushes the node into the live queue rooted at `[this+0x08]`, increments that queue count, and seeds caller values into `[node+0x04]` and `[node+0x08]`. Current grounded callers pair it with `0x0053d390` and `0x0053d440`, so this is the safest current read for a scored-node queue acquire-and-push helper rather than a plain list append.","objdump + caller inspection + local disassembly + queue-shape correlation" +0x0053d390,176,scored_node_queue_pop_highest_score_payload_and_recycle_or_free_node,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Removal helper over the same scored-node queue. The helper scans the live queue rooted at `[this+0x08]` for the node with the highest score field `[node+0x04]`, unlinks that node, decrements the queue count, captures payload field `[node+0x08]`, and then either returns the node to the pool freelist described by `[this+0x04]` when it lies inside the managed pool span or frees it through `0x0053b080` otherwise. This is the safest current read for a pop-highest-score helper rather than a generic free path.","objdump + caller inspection + local disassembly + queue-shape correlation" +0x0053d440,36,scored_node_queue_contains_payload_value,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Linear membership query over the same scored-node queue. The helper walks the live queue rooted at `[this+0x08]` and returns `1` when any node carries caller payload value `[node+0x08] == arg`, or `0` on miss. Current grounded callers sit beside `0x0053d320/0x0053d390`, so this is the safest current read for a queue-membership predicate rather than a key hash helper.","objdump + caller inspection + local disassembly + queue-shape correlation" +0x0053d470,76,scored_node_queue_release_pool_and_owned_roots,support,thiscall,inferred,objdump + local disassembly,1,"Release helper over the same scored-node queue owner. The helper frees optional root `[this+0x08]` through `0x005a1145`, releases optional pool descriptor `[this+0x04]` through `0x0053dcb0` and `0x0053b080`, frees optional root `[this+0x00]`, and clears queue count `[this+0x0c]` back to zero. This is the safest current read for the queue-owner release helper rather than a family-wide support destructor.","objdump + local disassembly + queue-shape correlation" +0x0053d4c0,120,scored_heap_acquire_node_from_pool_or_alloc_insert_and_sift_up,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Pooled insert helper over the scored heap owner whose node-pool descriptor lives at `[this+0x04]`, slot array at `[this+0x08]`, and live count at `[this+0x0c]`. The helper first pops a reusable node from the pool freelist or allocates one fresh node of pool stride `[pool+0x10]`, then increments the live count, stores the new node into the next heap slot, seeds caller values into `[node+0x04]` and `[node+0x08]`, and finally re-enters `0x0053d1d0` to restore max-heap order. Current grounded callers pair it with `0x0053d540`, so this is the safest current read for the heap insert helper rather than a queue append.","objdump + caller inspection + local disassembly + heap-shape correlation" +0x0053d540,136,scored_heap_pop_top_payload_and_recycle_or_free_node,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Pop helper over the same scored heap owner. When the heap is non-empty, the helper captures the payload field `[top+0x08]`, recycles or frees the root node through the pool descriptor at `[this+0x04]`, replaces the top slot from the last live slot when more than one node remains, decrements live count `[this+0x0c]`, and re-enters `0x0053d240` to restore heap order from slot `1`. This is the safest current read for a pop-top-payload helper over the scored heap rather than a queue scan.","objdump + caller inspection + local disassembly + heap-shape correlation" +0x0053d5d0,81,scored_heap_release_pool_array_and_owned_roots,support,thiscall,inferred,objdump + local disassembly,1,"Release helper over the same scored heap owner. The helper frees optional slot-array root `[this+0x08]` through `0x0053b080`, releases optional pool descriptor `[this+0x04]` through `0x0053dcb0` and `0x0053b080`, and frees optional backing root `[this+0x00]` through `0x005a1145`. This is the safest current read for the heap-owner release helper rather than a broader family destructor.","objdump + local disassembly + heap-shape correlation" +0x0053d630,179,scored_heap_construct_with_capacity_and_pool_stride_0x0c,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Constructor for the same scored heap owner. Given one caller capacity, the helper first releases any existing owner through `0x0053d5d0`, allocates one zeroed backing slab of `capacity * 0x0c` bytes into `[this+0x00]`, allocates a `0x1c` pool descriptor into `[this+0x04]`, initializes that descriptor through `0x0053dcf0` with stride `0x0c`, and then allocates one zeroed `0x0c` slot-array header into `[this+0x08]`. Current grounded callers are the nearby owner paths at `0x00416aa4` and `0x0053d740`, so this is the safest current read for the scored-heap constructor rather than a generic vector alloc.","objdump + caller inspection + local disassembly + heap-shape correlation" +0x0053d6f0,76,extended_scored_heap_release_pool_array_and_owned_roots,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Release helper over the adjacent extended scored-heap owner. The helper frees optional slot-array root `[this+0x08]` through `0x005a1145`, releases optional pool descriptor `[this+0x04]` through `0x0053dcb0` and `0x0053b080`, frees optional backing slab `[this+0x00]`, and clears live count `[this+0x0c]` back to zero. Current grounded callers are the hotkey-report iterator teardown at `0x0045f343` and the sibling owner teardown at `0x00522f54`, so this is the safest current read for the extended heap-owner release helper rather than a generic destructor.","objdump + caller inspection + local disassembly + heap-shape correlation" +0x0053d740,178,extended_scored_heap_construct_with_capacity_and_sentinel_header,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Constructor for the adjacent extended scored-heap owner. Given one caller capacity, the helper first releases any existing owner through `0x0053d470`, allocates one zeroed backing slab of `capacity * 0x0c` bytes into `[this+0x00]`, allocates a `0x1c` pool descriptor into `[this+0x04]`, initializes that descriptor through `0x0053dcf0` with stride `0x0c`, allocates one zeroed pointer-slot array of `(capacity * 4) + 4` bytes into `[this+0x08]`, seeds sentinel header `[this+0x10]`, default best-score lane `[this+0x14] = 0x7fffffff`, and counter `[this+0x18] = 0`, and stores the sentinel header as the first slot-array entry. Current grounded callers are the temporary hotkey-report owner at `0x0045f292` and the sibling shell/runtime owner at `0x00522c67`, so this is the safest current read for the extended heap constructor rather than a second plain vector alloc.","objdump + caller inspection + local disassembly + heap-shape correlation + sentinel-header correlation" +0x0053d810,95,hash_cstring_crc32_like_with_optional_ascii_uppercase,support,cdecl,inferred,objdump + caller inspection + local disassembly,1,"Small hashing helper over one NUL-terminated byte string. The helper folds each byte through the table rooted at `0x00624e48`, optionally uppercases ASCII letters first when mode arg1 equals `1`, and returns the final CRC32-like accumulator. Current grounded caller is `shell_input_binding_registry_resolve_entry_by_action_stem` `0x0045ede0`, which uses the uppercase-enabled path while resolving normalized action stems, so this is the safest current read for the support-side NUL-terminated hash helper rather than a generic checksum wrapper.","objdump + caller inspection + local disassembly + crc-table correlation" +0x0053d870,46,hash_fixed_length_byte_span_crc32_like,support,cdecl,inferred,objdump + caller inspection + local disassembly,1,"Sibling hashing helper over one fixed-length byte span. The helper folds exactly `len` bytes from the caller pointer through the same table rooted at `0x00624e48` and returns the final CRC32-like accumulator. Current grounded callers hash fixed `0x0a`- and `0x1c`-byte record headers at `0x0046cc97` and `0x0047085a`, so this is the safest current read for the fixed-length support-side hash helper rather than a string normalizer.","objdump + caller inspection + local disassembly + crc-table correlation" +0x0053d8a0,186,u32_to_ptr_hash_table_release_optional_pooled_nodes_and_bucket_array,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Release helper over one intrusive `u32 -> ptr` hash-table owner. The helper walks every bucket-chain root in bucket array `[this+0x00]`, and for each node either returns that node to the optional pooled-node descriptor at `[this+0x08]` when the descriptor span and in-pool checks match, or frees it through `0x0053b080` otherwise; it then releases the optional pool descriptor, frees the optional node-backing root `[this+0x04]`, frees the bucket array root `[this+0x00]`, and clears live-node count `[this+0x0c]` plus bucket count `[this+0x10]`. Current grounded callers are the connected-component and local-bucket map owners around `0x00416170` and `0x00522ed1`, so this is the safest current read for the pooled hash-table release helper rather than a generic map clear.","objdump + caller inspection + local disassembly + intrusive-hash-table correlation" +0x0053d960,124,u32_to_ptr_hash_table_insert_or_replace_value_by_key,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Insert helper over the same intrusive `u32 -> ptr` hash-table owner. The helper acquires one pooled node from free list `[table+0x08]` or allocates a fresh node when needed, hashes the caller key through `(key ^ (key >> 15)) % [table+0x10]`, seeds node fields `[node+0x00] = key` and `[node+0x04] = value`, links the node to the head of the selected bucket chain, and leaves duplicate-key replacement to the caller's preceding remove path. Current grounded callers include the connected-component map writers at `0x00416170` and `0x00416298`, so this is the safest current read for hash-table insert-by-key rather than a generic queue push.","objdump + caller inspection + local disassembly + intrusive-hash-table correlation" +0x0053d9e0,185,u32_to_ptr_hash_table_remove_key_and_return_value,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Removal helper over the same intrusive `u32 -> ptr` hash-table owner. The helper hashes the caller key through `(key ^ (key >> 15)) % [table+0x10]`, walks the selected bucket chain, unlinks the matching node when found, returns stored value `[node+0x04]`, and then either recycles the node into the optional pool descriptor at `[table+0x08]` or frees it through `0x0053b080`. Current grounded callers are the connected-component and local-bucket refresh paths at `0x00416170`, `0x0041626c`, and `0x0041643e`, so this is the safest current read for remove-and-return-value rather than another membership predicate.","objdump + caller inspection + local disassembly + intrusive-hash-table correlation" +0x0053daa0,58,u32_to_ptr_hash_table_contains_key,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Membership predicate over the same intrusive `u32 -> ptr` hash-table owner. The helper hashes the caller key through `(key ^ (key >> 15)) % [table+0x10]`, walks the selected bucket chain by link field `+0x08`, and returns `1` on the first matching key or `0` on miss. Current grounded callers sit beside the sibling lookup and remove helpers, so this is the safest current read for a hash-table contains-key predicate rather than a value fetch.","objdump + caller inspection + local disassembly + intrusive-hash-table correlation" +0x0053dae0,54,u32_to_ptr_hash_table_lookup_value_by_key,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Lookup helper over the same intrusive `u32 -> ptr` hash-table owner. The helper hashes the caller key through `(key ^ (key >> 15)) % [table+0x10]`, walks the selected bucket chain, and returns stored value `[node+0x04]` on the first matching key or `0` on miss. Current grounded callers include `placed_structure_collection_refresh_local_runtime_side_state_in_rect_from_cell_bucket_map` `0x00419110`, the connected-component rectangle pass `0x00416170`, and `global_owner_family_lookup_key_in_selected_hash_root` `0x00531ef0`, so this is the safest current read for hash-table lookup-by-key rather than a membership-only helper.","objdump + caller inspection + local disassembly + intrusive-hash-table correlation" +0x0053db20,177,u32_to_ptr_hash_table_iterate_entries_with_optional_exact_key_filter_and_callback,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Callback iterator over the same intrusive `u32 -> ptr` hash-table owner. When key arg0 is zero, the helper walks every bucket chain in bucket array `[table+0x00]`; otherwise it hashes that key through `(key ^ (key >> 15)) % [table+0x10]` and only walks the selected bucket. For each visited node it calls the caller-supplied callback with `ecx = node`, `edx = user_arg`, and stops early on the first nonzero callback result, returning that value. Current grounded callers are the cleanup and release passes at `0x00522e85` and `0x00522ec0`, so this is the safest current read for the optional-key callback iterator rather than a value lookup helper.","objdump + caller inspection + local disassembly + intrusive-hash-table correlation + callback-iterator correlation" +0x0053dbe0,5,u32_to_ptr_hash_table_release_thunk,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tail-call thunk into `u32_to_ptr_hash_table_release_optional_pooled_nodes_and_bucket_array` `0x0053d8a0`. Current grounded callers use it as the direct release entry for hash-table owners at `0x00522e93` and `0x00522ed1`, so the safest current read is a narrow release thunk rather than an independent owner.","objdump + caller inspection + local disassembly + release-thunk correlation" +0x0053dbf0,185,u32_to_ptr_hash_table_construct_with_bucket_count_and_pooled_node_capacity,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Constructor for the same intrusive `u32 -> ptr` hash-table owner. Given caller bucket count and pooled-node capacity, the helper first releases any existing owner through `0x0053d8a0`, allocates one zeroed pooled-node backing slab of `capacity * 0x10` bytes into `[this+0x04]`, allocates a `0x1c` pool descriptor into `[this+0x08]`, initializes that descriptor through `0x0053dcf0` with stride `0x10`, allocates one zeroed bucket array of `bucket_count * 4` bytes into `[this+0x00]`, and stores pooled-node capacity `[this+0x0c]` plus bucket count `[this+0x10]`. Current grounded callers are the map-side owners under `0x00416170` and the sibling runtime owner at `0x00522e7e`, so this is the safest current read for the pooled hash-table constructor rather than a generic alloc wrapper.","objdump + caller inspection + local disassembly + intrusive-hash-table correlation" +0x0053dcb0,55,fixed_stride_pool_descriptor_release_optional_owned_block,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Release helper over one fixed-stride pool descriptor. The helper frees optional freelist or root pointer `[this+0x00]`, and when ownership flag `[this+0x18] == 1` it also frees optional owned backing block `[this+0x04]`, then leaves the descriptor itself for the caller to release. Current grounded callers are the scored-heap and hash-table owner destructors `0x0053d470`, `0x0053d5d0`, `0x0053d6f0`, and `0x0053d8a0`, so this is the safest current read for the pool-descriptor release helper rather than a family-wide destructor.","objdump + caller inspection + local disassembly + pool-descriptor correlation" +0x0053dcf0,216,fixed_stride_pool_descriptor_reset_with_optional_owned_block_and_freelist_seed,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Reset or constructor helper over one fixed-stride pool descriptor. The helper stores caller stride at `[this+0x14]`, releases prior freelist root `[this+0x00]` and any owned backing block `[this+0x04]` when ownership flag `[this+0x18]` was set, then either adopts one caller-supplied backing block and count directly or allocates an owned block of `count * stride` bytes, seeds freelist header `[this+0x00]`, block start `[this+0x04]`, block end `[this+0x08]`, count `[this+0x0c]`, stride `[this+0x10]`, and ownership flag `[this+0x18]`, and links every fixed-stride node into the freelist. Current grounded callers initialize scored-heap and hash-table pool descriptors from `0x0053d630`, `0x0053d740`, and `0x0053dbf0`, so this is the safest current read for the fixed-stride pool-descriptor reset helper rather than one pool-family-specific constructor.","objdump + caller inspection + local disassembly + pool-descriptor correlation + freelist-seed correlation" +0x0053dde0,8,world_anchor_scale_primary_extent_by_local_factor,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny world-anchor scaling helper. The function multiplies caller float arg0 by local factor `[this+0x2e]` and returns the resulting floating-point extent. Current grounded caller is `shell_queue_world_anchor_marker` `0x00552560`, which pairs it with `0x0053ddf0` while building screen-space marker extents, so this is the safest current read for the primary extent scaler rather than a generic multiply wrapper.","objdump + caller inspection + local disassembly + world-anchor correlation" +0x0053ddf0,8,world_anchor_scale_secondary_extent_by_local_factor,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Sibling world-anchor scaling helper. The function multiplies caller float arg0 by local factor `[this+0x32]` and returns the resulting floating-point extent. Current grounded caller is `shell_queue_world_anchor_marker` `0x00552560`, which uses it for the second screen-space marker extent lane, so this is the safest current read for the secondary extent scaler rather than a generic multiply wrapper.","objdump + caller inspection + local disassembly + world-anchor correlation" +0x0053de00,83,indexed_string_table_lookup_ptr_or_format_out_of_range_warning,support,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Indexed string-table getter over one owner with optional family label `[this+0x20]`, table root `[this+0x24]`, and entry count word `[this+0x28]`. When index arg0 is in range, the helper returns table entry pointer `[table + index*4]`; on overflow it formats one warning through the template at `0x005dd658` using the owner label or fallback `0x005c87a8`, then returns the first table entry. Current grounded callers are the setup payload-category row draw callback `0x00502030` and the selected-train route-and-state panel renderer `0x0050fc00`, so this is the safest current read for the indexed string-table lookup helper rather than a route-specific formatter.","objdump + caller inspection + local disassembly + indexed-string-table correlation" +0x0053de60,1137,shell_image_marker_payload_refresh_variant_table_from_screen_metrics_and_vram_policy,shell,thiscall,inferred,objdump + caller inspection + local disassembly + rdata string decode,2,"Heavy refresh pass over the typed type-`6` image-marker payload constructed by `0x0053ee70/0x0053e370`. The helper derives current screen-space scale from shell display state `[0x006d4024+0x11421e/+0x34/+0x11422f/+0x114243/+0x114247/+0x11424f/+0x1146dd]`, clears and rebuilds the local variant table rooted at `[this+0x24]`, resolves one selected TGA or DDS resource through `0x0053c1c0`, and then parses the payload's per-variant descriptors into one live table of `0x25`-byte marker variants via `0x005520a0`. The parsed keyword set is now grounded from `.rdata`: `Image`, `ImageWH`, `ImageWHForceScale`, `ImageWHWithRef`, `ImageScaled`, `ImageWHScaled`, `MaxPercentOfInterfaceVRAM`, `MaxPercentOfInterfaceVRAMToUse`, `Scaleable`, `TGATargetScreenHeight`, `TGATargetScreenWidth`, `TGAHeight`, `TGAWidth`, `TGAName`, `HorizontalScaleModifier`, and `VerticalScaleModifier`. Current direct callers are the constructor tail `0x0053ee15` and the rebuild wrapper `0x0053e2d0`, while downstream consumers include `shell_queue_world_anchor_marker` `0x00552560`, so this is the safest current read for the payload's variant-table refresh owner rather than a generic image loader.","objdump + caller inspection + local disassembly + rdata string decode + typed-payload correlation" +0x0053e2b0,32,shell_image_marker_payload_release_variant_resources_then_refresh,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small rebuild wrapper over the same type-`6` image-marker payload. The helper releases any current variant table entries rooted at `[this+0x24]`, releases optional loaded image handle `[this+0x2a]` through `0x0053c000`, clears that handle, and then tail-jumps back into `shell_image_marker_payload_refresh_variant_table_from_screen_metrics_and_vram_policy` `0x0053de60`. Current grounded caller is the shell helper-collection refresh sweep `0x00538ec0`, so this is the safest current read for the payload rebuild wrapper after shell selection or display changes rather than a pure destructor.","objdump + caller inspection + local disassembly + typed-payload correlation" +0x0053e2e0,144,shell_image_marker_payload_release_variant_table_image_handle_and_label,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Release helper over the same type-`6` image-marker payload. The helper walks every live variant pointer in `[this+0x24]`, releases each variant through `0x00552130` and `0x0053b080`, frees the variant-pointer array, releases optional loaded image handle `[this+0x2a]` through `0x0053c000`, frees optional label string `[this+0x20]`, and then notifies the shell helper collection rooted at `[0x006d401c+0xc69]` with token `[this+0x36]`. Current direct callers are the rebuild wrapper thunk `0x0053ee60` and the support-side row release paths that destroy typed type-`6` payloads, so this is the safest current read for the image-marker payload destructor rather than a generic array free.","objdump + caller inspection + local disassembly + typed-payload correlation" +0x0053e370,2744,shell_image_marker_payload_construct_from_banked_record_key,shell,thiscall,inferred,objdump + caller inspection + local disassembly + rdata string decode,2,"Constructor for the same typed type-`6` image-marker payload used by the banked-record staging family. The helper seeds default dimension and scaling fields, opens one selected support-family record stream through `0x0053bd40/0x0053c9c0/0x0053b7c0`, tokenizes the record text through `0x0051d9d0`, parses the grounded keyword set (`Image`, `ImageWH`, `ImageWHForceScale`, `ImageWHWithRef`, `ImageScaled`, `ImageWHScaled`, `MaxPercentOfInterfaceVRAM`, `MaxPercentOfInterfaceVRAMToUse`, `Scaleable`, `TGATargetScreenHeight`, `TGATargetScreenWidth`, `TGAHeight`, `TGAWidth`, `TGAName`, `HorizontalScaleModifier`, `VerticalScaleModifier`), registers one shell helper token through `[0x006d401c+0xc69]`, derives local extent ratios `[this+0x2e/+0x32]`, and finally enters `0x0053de60` to build the live variant table. Current grounded constructor wrapper is `0x0053ee70`, and the typed acquire-or-create owner `0x0053c070` already binds payload type `6` to that wrapper, so this is the safest current read for the type-`6` banked-record payload constructor rather than a generic text parser.","objdump + caller inspection + local disassembly + rdata string decode + typed-payload correlation" +0x0053ee60,5,shell_image_marker_payload_release_thunk,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tail-call thunk into `shell_image_marker_payload_release_variant_table_image_handle_and_label` `0x0053e2e0`. Current grounded caller is the typed-row release family beneath `0x0053c000/0x0053c070`, so the safest current read is a narrow type-`6` payload release thunk rather than an independent owner.","objdump + caller inspection + local disassembly + typed-payload correlation" +0x0053ee70,17,shell_image_marker_payload_construct_wrapper,shell,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Thin wrapper above `shell_image_marker_payload_construct_from_banked_record_key` `0x0053e370`. The helper forwards the caller record key into the heavier constructor and then returns `this` unchanged. Current grounded callers are the typed type-`6` staging-row acquire path at `0x0053c070` and the broader banked-record family, so this is the safest current read for the type-`6` payload constructor wrapper rather than another parser owner.","objdump + caller inspection + local disassembly + typed-payload correlation" +0x0053ee90,104,shell_load_named_or_fallback_ui_image_handle_into_global_slot_table_ccba60,shell,cdecl,inferred,objdump + local disassembly + import-shape correlation,1,"Small shell image-handle loader over the global slot table rooted at `0x00ccba60`. The helper formats one resource name from the string table rooted at `0x00625258` plus a caller-selected index and one of two templates at `0x005dd7f0/0x005dd80c`, forwards that string into the USER32 image-load import at `0x005c829c`, and on failure falls back to the stock-image import at `0x005c82a0` with id `0x7f00`. The resolved handle is then stored into slot `0x00ccba60 + (arg0*0x17 + arg1)*4`. Current evidence is strong enough for a named-or-fallback UI image-handle loader, but not yet for the exact player-facing slot family.","objdump + local disassembly + import-shape correlation + global-slot-table correlation" 0x0053b010,11,bootstrap_mark_runtime_started,bootstrap,cdecl,inferred,ghidra-headless,2,Single-purpose bootstrap helper that flips a process-global started flag to one before branding and shell setup continue.,ghidra + rizin 0x0054e6d0,42,bootstrap_capture_keyboard_state,bootstrap,cdecl,inferred,ghidra-headless,4,Single-purpose bootstrap probe that snapshots the host keyboard state through GetKeyboardState.,ghidra + rizin 0x00540a47,75,shell_control_refresh_matching_dynamic_text_payload,shell,unknown,inferred,objdump + caller inspection,3,"Small shell-control helper used on one matching control descriptor during refresh or replacement. When the incoming control id matches `[control+0x4]`, the helper frees any prior heap-backed text payload at `[control+0xce]`, clears that field, optionally copies a replacement payload from the caller descriptor through `0x0051d820`, and then returns `0` when the incoming control type is `0x6f` or `1` otherwise. Current grounded importance is the `CompanyDetail.win` section-0 overview widget `0x947f`: together with the sibling helper at `0x005639d2`, this makes type `0x6f` look like a special heap-backed dynamic-text control rather than an ordinary callback widget.","objdump + caller inspection + type-0x6f control correlation" 0x005639d2,22,shell_control_release_dynamic_text_payload,shell,unknown,inferred,objdump + caller inspection,3,"Tiny shell-control release helper that clears one control's attached payload through `0x0051d820` and then returns `0` when the control type at `[this+0x0]` is `0x6f` or `1` otherwise. Current grounded importance is the same CompanyDetail section-0 overview lane around control `0x947f`, where this reinforces that type `0x6f` is treated as a special dynamic-text family with its own release path instead of a normal callback-style widget.","objdump + caller inspection + type-0x6f control correlation" 0x0055da40,424,bootstrap_probe_system_profile,bootstrap,cdecl,inferred,ghidra-headless,4,Collects GlobalMemoryStatus and CPUID feature bits then stores coarse machine capability flags used by later bootstrap decisions.,ghidra + rizin +0x00507980,59,station_place_selection_id_is_special_negative_tool_item,shell,cdecl,inferred,objdump + caller xrefs + local disassembly,2,"Tiny StationPlace selection-id predicate. The helper returns `1` only for the negative sentinel ids `-11..-17` and `-20..-22`, and `0` for every other id. Current grounded callers are the later StationPlace preview and selection branches at `0x00508c24`, `0x00508e07`, and `0x005094a1`, where it distinguishes special tool-local pseudo-items from ordinary live placement ids before helper-handle or preview follow-ons run.","objdump + caller xrefs + local disassembly + StationPlace sentinel-id correlation" +0x005079c0,138,station_place_window_release_cached_selection_handles_and_world_followons,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Small StationPlace.win cleanup helper over the live tool object at `0x006d1720`. The helper first re-enters `0x00453510` on the live world root `0x0062c120` and `0x00413620` on the placed-structure owner `0x0062b26c`, then releases up to four cached selection or helper handles stored at `[this+0x7c]`, `[+0x80]`, `[+0x88]`, and `[+0x84]` through the matching global owners `0x0062b26c`, `0x006ada80`, `0x006cea50`, and `0x0062bae0`, writing `-1` back into each slot after release. Current grounded callers are the thin wrapper `0x00507a50` plus direct StationPlace branches at `0x00507b59` and `0x00509289`, so this is the safest current read for the cached selection-handle release helper beneath the StationPlace tool family rather than a generic shell window destroy stub.","objdump + caller xrefs + local disassembly + handle-release correlation" +0x00507a50,5,station_place_window_release_cached_selection_handles_and_world_followons_thunk,shell,thiscall,inferred,objdump + caller xrefs + wrapper inspection,2,"Tiny tail-jump wrapper over `station_place_window_release_cached_selection_handles_and_world_followons` `0x005079c0`. Current grounded callers are the higher save-load wrapper `0x004423a0` and the direct StationPlace cleanup branch at `0x00444e4a`, which makes this the light entry used when the broader StationPlace family only needs the cached-handle release path.","objdump + caller xrefs + wrapper inspection + StationPlace-family correlation" +0x00507a90,187,station_place_rotation_circle_callback_publish_current_heading_widget,shell,cdecl,inferred,objdump + caller xrefs + local disassembly,3,"StationPlace callback for the dedicated rotation-circle control `0x6987`. The helper reads the current StationPlace angle at `0x006d172c`, subtracts the active world-view angle from `[0x0062be68+0x10]`, normalizes the result through `0x005a1390`, pushes one formatted heading value plus the fixed circle-widget tuning constants into the helper object at `0x006d1724`, and then dispatches through `0x00552900`. Current grounded caller is the StationPlace constructor branch at `0x00509df6`, where this callback is wired directly onto control `0x6987`, so this is the safest current read for the rotation-circle publish path rather than a generic angle formatter.","objdump + caller xrefs + local disassembly + StationPlace control-0x6987 correlation" +0x00507b50,49,station_place_window_destruct_release_helpers_and_clear_singleton,shell,thiscall,inferred,objdump + vtable scan + local disassembly,2,"Primary StationPlace.win destructor. The helper restores vtable `0x005d17c0`, re-enters `station_place_window_release_cached_selection_handles_and_world_followons` `0x005079c0`, releases the helper handle at `0x006d1724` through the shared owner `0x006d4020 -> 0x0053c000`, clears singleton `0x006d1720`, and then tail-jumps into the common shell-window teardown at `0x0053f7d0`. Current evidence comes from the StationPlace vtable and constructor pair, so this is the safest current read for the concrete window destructor rather than another cleanup wrapper.","objdump + vtable scan + local disassembly + StationPlace destructor correlation" 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 +0x00507cf0,135,station_place_set_rotation_and_refresh_live_selected_site_pose,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Shared StationPlace rotation setter over the live tool object. The helper writes the requested heading float into global `0x006d172c`, optionally mirrors that same heading into the auto-orientation seed `0x006d1730`, and then, when the current selected placed structure at `[this+0x7c]` is live, resolves its normalized anchor pair through `0x00455800/0x00455810`, applies the new heading through `0x00455750`, and republishes the refreshed pose through `placed_structure_set_world_coords_and_refresh_local_runtime_side_state` `0x0040eba0` plus the shared runtime-object cleanup tail `0x0052eb90`. Current grounded callers are the cursor-drag rotation helper `0x00507d80`, the discrete step helper `0x005086c0`, and the preview or commit follow-ons at `0x00508fff` and `0x00509050`, so this is the safest current owner for StationPlace heading writes plus live selected-site pose refresh.","objdump + caller xrefs + local disassembly + StationPlace rotation correlation + live-site refresh correlation" +0x00507d80,255,station_place_window_drag_rotate_selected_site_toward_world_cursor,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"StationPlace live drag-rotation helper for the current selected site. The function reads the current cursor or screen-derived pair from `0x006d4018+0xa94/+0xa98`, normalizes that pair through the local scale and wrap helpers `0x005a1270` and `0x005a1390`, derives one wrapped heading delta against the current world-view angle at `[0x0062be68+0x10]`, and then re-enters `station_place_set_rotation_and_refresh_live_selected_site_pose` `0x00507cf0` with mirror flag `1`. Current grounded callers are the direct StationPlace dispatcher branches at `0x005092f3` and `0x00509aa1`, which keeps this on the live station-rotation circle or drag-update side rather than a generic view-angle helper.","objdump + caller xrefs + local disassembly + StationPlace drag-rotation correlation" +0x00507e80,432,station_place_validate_current_selection_at_world_coords_and_optionally_format_status,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Shared StationPlace go-or-no-go validator beneath both preview and commit paths. The helper first rejects the empty-selection case `[this+0x7c] == -1`, then resolves the current placed structure and its candidate stem through `0x0040cec0`, collects the linked-site latch through vtable slot `+0x70` and `0x0040d1f0`, computes one projected placement record through `0x00455730` and `indexed_collection_resolve_live_entry_id_by_stem_string` `0x00416e20`, and validates that projected record at the caller-supplied world coordinates through `placed_structure_validate_projected_candidate_placement` `0x004197e0`. On failure it publishes red status through `0x0040cb10`; on partial or blocked follow-on conditions it can publish yellow status plus localized short strings `0x29b/0x29c`; and on success it publishes green status after checking linked-site or territory gating through `0x0040d360` and `0x00481500`. Current grounded callers are the StationPlace preview branch `0x0050906d` and the commit branch `0x00509648`, so this is the safest current read for the shared StationPlace validation-and-status gate rather than another placed-structure-private helper.","objdump + caller xrefs + local disassembly + StationPlace validation correlation + status-color correlation" +0x00508040,1116,station_place_window_try_auto_orient_candidate_to_covering_route_entry_and_validate_placement,shell,thiscall,inferred,objdump + caller xrefs + local disassembly + StationPlace control correlation,3,"Searches for one auto-oriented StationPlace placement pose when the strict-rotation policy is off. The helper seeds the caller heading output from global angle `0x006d1730`, snapshots the staged world-space point, derives one candidate-class latch from the current selection record at `[this+0x8c]`, and then iterates up to three orientation-search modes. On each trial it computes one candidate heading and footprint-offset pose, re-enters `route_entry_collection_try_reuse_covering_entry_for_site_coords_and_heading` `0x00417b40` to see whether an already-covered route entry can support the staged point, and then validates the accepted candidate pose through `placed_structure_validate_projected_candidate_placement` `0x004197e0` before committing it to the caller outputs. The subtype-`1` station branch also probes the route-entry collection directly through `0x00494cb0`, while the later retry loop relaxes the angle and distance thresholds through the local trig and distance helpers before trying the next orientation mode. Current grounded callers are the StationPlace preview path `0x00508f81` and the commit path `0x00509635`, and the surrounding control semantics already tie those callers to the non-strict station-rotation options at controls `0x6985/0x6986`, so this is the safest current read for the StationPlace auto-orientation search owner rather than a generic route-entry chooser.","objdump + caller xrefs + local disassembly + StationPlace control correlation + route-entry reuse correlation + placement-validation correlation" +0x005084a0,174,station_place_quantize_preview_metric_scalar_by_profile_rule,shell,thiscall,inferred,objdump + caller xrefs + local disassembly + caller correlation,2,"Small StationPlace preview-metric quantizer beneath control `0x6983`. The helper first checks the current build version through `0x00482e00`; when that version is below `0x67`, or when the linked profile dword `[profile+0x78c]` is zero, it returns literal `1.0`. Otherwise it scales the caller-supplied float, applies one of two piecewise rounded bands through `0x005a10d0`, and returns the quantized float in steps of either `0x186a0` or `0xc350` depending on the input range. Current grounded callers are `station_place_refresh_preview_metric_control_0x6983` `0x00508550` and the StationPlace commit-side preview or feedback branch `0x0050970c`, so this is the safest current read for the shared preview-metric quantizer rather than a generic math helper.","objdump + caller xrefs + local disassembly + caller correlation + StationPlace control-0x6983 correlation" +0x00508550,363,station_place_refresh_preview_metric_control_0x6983,shell,cdecl,inferred,objdump + strings + local disassembly + caller inspection,4,"Refreshes the remaining StationPlace preview metric field at control `0x6983` for the current selection. The helper validates `[this+0x8c]`, resolves the staged world-cell category through `world_query_float_coords_within_live_grid_bounds` `0x00414bd0` and `0x0044ad60`, reads the linked profile scalar at `[profile+0x22]` through `0x0062b268`, branches on candidate subtype byte `[candidate+0x32]` to choose issue slot `0x3b` or `0x3c`, folds the raw scalar through `scenario_state_compute_issue_opinion_multiplier` `0x00436590`, passes the scaled result through the version-gated quantizer `0x005084a0`, formats the localized metric string `0x29d`, and publishes the final text through `0x00540120` into control `0x6983`. Current grounded caller is the broader preview-panel owner `0x00508730`, so this is the safest current read for the StationPlace preview metric publisher rather than the selected-site summary formatter.","objdump + strings + local disassembly + caller inspection + StationPlace control-0x6983 correlation + issue-slot correlation" +0x005086c0,58,station_place_step_rotation_by_integer_notches,shell,cdecl,inferred,objdump + caller xrefs + local disassembly,2,"Small StationPlace rotation-step helper. The function converts the caller-supplied integer notch count into a heading delta through the fixed scalar at `0x005d1810`, adds that delta to the current StationPlace angle at `0x006d172c`, and then re-enters `station_place_set_rotation_and_refresh_live_selected_site_pose` `0x00507cf0` with mirror flag `1`. Current grounded callers are the two neighboring shell-side StationPlace rotation-step branches at `0x00440c9f` and `0x00440d5f`, which keeps this on the discrete bracket-key or rotation-control side rather than a generic angle-scaling helper.","objdump + caller xrefs + local disassembly + StationPlace discrete-rotation correlation" +0x00508700,34,station_place_query_selected_site_linked_route_entry_id_or_minus1,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,2,"Tiny StationPlace helper that resolves the current selected placed structure at `[this+0x7c]` and returns its linked route-entry id from `[site+0x2a8]`, or `-1` when no live selected site exists or no linked route entry is attached. Current grounded caller is the later StationPlace post-create notification branch at `0x0050991e`, where that linked route-entry id is forwarded into the shared world-side notifier path.","objdump + caller xrefs + local disassembly + linked-route-entry correlation" +0x00508730,292,station_place_format_preview_panel,shell,cdecl,inferred,objdump + strings + local disassembly + caller inspection,4,"Refreshes the main StationPlace preview panel for the current selection id passed in `arg_4`. The helper stores that selection into `[this+0x8c]`, publishes one preview asset into control `0x6982`, refreshes the metric field at `0x6983` through `station_place_refresh_preview_metric_control_0x6983` `0x00508550`, and then publishes the paired description block into control `0x6984`. For negative synthetic selection ids it chooses one fallback preview asset and description token from the local `0x005d1818..0x005d1848` table; for live ids it resolves the placement record through `0x0062b2fc`, formats the asset name from the linked profile block at `0x0062b268+0x4f` through `0x005a19c4`, and formats the description through `0x00413bc0`. Current grounded callers are the category refresh owner `0x00508880` and the small singleton wrapper `0x00508860`, so this is the safest current owner for the StationPlace preview-art, metric, and description refresh strip.","objdump + strings + local disassembly + caller inspection + StationPlace preview-panel correlation" +0x00508860,21,station_place_format_preview_panel_if_live_singleton_and_valid_selection,shell,cdecl,inferred,objdump + caller xrefs + local disassembly,2,"Tiny StationPlace singleton wrapper around `station_place_format_preview_panel` `0x00508730`. The helper ignores selection id `-1`, then checks singleton `0x006d1720` and forwards the caller-supplied selection id only when the StationPlace tool window is live. Current grounded callers are the two neighboring selection-refresh branches at `0x0050a44b` and `0x0050a462`, so this is the safest current read for the guarded preview-panel refresh entry rather than a standalone formatter.","objdump + caller xrefs + local disassembly + StationPlace singleton-wrapper correlation" 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 +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/0x006d173c`, refreshes the remaining preview metric field through `station_place_refresh_preview_metric_control_0x6983` `0x00508550`, and updates the live placement selection globals at `0x00622af0`, `0x00622aec`, and `0x006d1740` plus helper objects rooted at `[this+0x80]`, `[+0x84]`, and `[+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 + StationPlace control-0x6983 correlation" 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 0x004b81d0,336,shell_building_detail_window_construct_and_bind_core_rows,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `BuildingDetail.win` family rooted at singleton `0x006cfd04`. The constructor installs vtable `0x005d00dc`, binds the helper asset `StationIcons.imb` plus `BuildingDetail.win` through `0x0053d110` and `0x0053fa50`, seeds three shell presenter handles at `0x006cfcf8..0x006cfd00`, clears local bytes `0x006cfd08/0x006cfd09`, wires the paired core action controls `0xbd17` and `0xbd18`, binds the smaller summary callbacks `0xbd13` and `0xbd14`, conditionally binds the extra row trio `0xbd19..0xbd1b` when `[0x006d3c84] == 1`, and then refreshes the visible selection band through `0x004b71b0`. Current grounded caller is the detail-panel manager branch at `0x004dde67`, which keeps this on the shell building-detail side rather than the later standalone opener rooted at `0x004bc100`.","objdump + strings + detail-manager correlation + control-wiring correlation + singleton correlation" @@ -974,17 +1647,39 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x004b84f0,560,shell_bulldoze_window_handle_message,shell,thiscall,inferred,objdump + constructor correlation + caller inspection,4,"Primary message dispatcher for the shell-side `Bulldoze.win` tool window. Under message `0xc8`, control ids `0xbf69..0xbf6f` update the current ordinal at `[this+0x78]` and global `0x00621cc4` through the local setter `0x004b8470`, then re-enter `shell_bulldoze_window_refresh_ordinal_strip` `0x004b84b0`. Control `0x07d6` arms or clears the world-surface latch `[this+0x7c]` after the standard hit-test gate `0x00448ac0`. While that latch is live, the helper re-samples world coordinates, tracks the last accepted pair in globals `0x00621ce4/0x00621ce8`, queries one local world score through `0x0044b160`, and then publishes one status line through `0x00538c70` on shell runtime `0x006d401c`. Current grounded callers or owners are the constructor `0x004b8720` and the live shell message loop, which keeps this on the bulldoze tool-window side of the shared `0x07d6` world-surface family rather than on a generic shell-detail row path.","objdump + constructor correlation + caller inspection + world-surface latch correlation + local-score query correlation" 0x004b8720,128,shell_bulldoze_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `Bulldoze.win` tool window. The constructor installs vtable `0x005d02b4`, seeds the current ordinal from `0x00621cc4`, formats the visible scalar caption from `0x00621cc8` through `0x0051f070` and `0x00527de0`, binds `Bulldoze.win` through `0x0053fa50`, clears local field `[this+0x7c]`, refreshes the visible selection rows through `0x004b84b0`, and then re-enters `0x00523e10` on the shell presenter. Current grounded caller is the detail-panel manager branch at `0x004ddef0`, which keeps this on the shell tool-window side above the broader world-side bulldoze chooser `0x0044b160`.","objdump + strings + detail-manager correlation + scalar-caption correlation + singleton correlation" 0x004bcb50,160,shell_change_height_window_construct,shell,thiscall,inferred,objdump + strings + detail-manager correlation,4,"Constructs the shell-side `ChangeHeight.win` tool window. The constructor installs vtable `0x005d0690`, seeds the current ordinal from `0x00621e20`, formats the visible scalar caption from `0x00621e24`, binds `ChangeHeight.win` through `0x0053fa50`, stores live singleton `0x006cfe18`, refreshes the visible selection and mode rows through `0x004bc290`, and then triggers one world-side follow-on through `0x00452ca0` with mode id `6`. Current grounded caller is the detail-panel manager branch at `0x004ddf13`, which keeps this on the shell terrain-edit tool side rather than the generic world-surface brush owner itself.","objdump + strings + detail-manager correlation + singleton correlation + control-refresh correlation" -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 +0x0050a530,64,station_place_window_service_frame,shell,thiscall,inferred,objdump + caller xrefs + callsite inspection,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 `station_place_world_surface_sync_and_dispatch` `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 are the higher restore wrapper `0x004423d0` plus the direct save-load tails at `0x00444eda` and `0x00445a64`, which keeps this on the recurring StationPlace tool-service side rather than a one-off constructor epilogue.","objdump + caller xrefs + callsite inspection + world-surface correlation" +0x0050dab0,84,track_lay_window_refresh_active_route_entry_linked_peer_and_publish_runtime_followon,shell,cdecl,inferred,objdump + caller xrefs + local disassembly,3,"Small TrackLay-side helper under the active route-owner path. When global route latch `[0x006cfca8+0x118]` is nonzero and route id `[+0x125]` still resolves, the helper resolves that live route entry through `0x00518140`, re-enters `0x0049afe0` on the route owner with the resolved entry, re-enters `0x0048b660` on the same entry, and then tail-jumps into `0x0049b070` on the route owner. Current grounded callers are the broader TrackLay helpers `0x0050dc80`, `0x0050dce0`, and `0x0050e070` plus several later TrackLay message branches, so this is the safest current read for the small active-route refresh and publish companion rather than a generic route-entry accessor.","objdump + caller xrefs + local disassembly + route-entry correlation + TrackLay-family correlation" +0x0050d1e0,237,track_lay_window_release_invalid_route_entries_reset_cached_selection_and_refresh_presenter,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Shared TrackLay.win cleanup tail over the live tool object at `0x006d1a8c`. The helper first re-enters `0x0049ad90` and `0x00495540` on the global route owner `0x006cfca8`, then branches on route latch `[route+0x118]`. When that latch is clear it validates the cached tool route id `[this+0x78]` through `0x00518140` and candidate byte `[entry+0x216]`, releasing the cached id from the route owner when the entry is no longer admitted. When the latch is set it instead walks every live route entry, removing entries whose byte `[entry+0x216]` is clear through `0x0049bbb0`. In either case it resets `[this+0x78]` to `-1`, refreshes the active shell presenter through `0x0051f070`, and conditionally tail-jumps into `0x00523e20` on presenter slot `[presenter+0x3741]`. Current grounded callers are the TrackLay entry-side helper `0x0050e070` plus direct TrackLay branches at `0x0050db19` and `0x0050ebab`, so this is the safest current read for the shared invalid-route cleanup and presenter-refresh tail rather than a generic route-store sweep.","objdump + caller xrefs + local disassembly + route-cleanup correlation + presenter-refresh correlation" 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 +0x0050dc00,113,track_lay_window_refresh_version_gated_action_rows_then_reenter_main_refresh,shell,thiscall,inferred,objdump + caller xrefs + local disassembly + strings,3,"Small TrackLay.win control helper over the live tool object at `0x006d1a8c`. The helper first uses the local executable-version gate from `[0x006cec78+0x0d]` to restyle the three action rows `0x986a..0x986c` through `0x00540120`, then applies the same version-gated style split to control `0x9872`, and finally tail-jumps back into `track_lay_window_refresh_controls` `0x0050d2d0`. Current grounded caller is the TrackLay constructor `0x0050e528`, so this is the safest current read for the small version-gated action-row refresh helper rather than another generic shell row styler.","objdump + caller xrefs + local disassembly + version-gate correlation + control-row correlation" +0x0050dc80,87,track_lay_window_refresh_or_clear_active_route_latch,shell,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Small TrackLay.win route-latch helper beneath the broader message owner. The helper checks whether the live route owner `0x006cfca8` still has active latch `[route+0x118]`. When that latch is set it refreshes tool-local state through `0x0050dab0`; if local byte `[this+0x82]` is clear it tail-jumps into `0x004a00b0`, otherwise it clears `[this+0x82]`, resets `[route+0x118]` to zero, and posts the fixed shell payload through `0x0053ef90`. Current grounded callers are the TrackLay message owner `0x0050e5c0` and one neighboring helper at `0x0050f4c4`, so this is the safest current read for the active route-latch refresh or clear branch rather than a generic route-entry query.","objdump + caller xrefs + local disassembly + route-latch correlation" +0x0050dce0,912,track_lay_window_sync_world_surface_hit_or_active_route_selection_into_route_owner,shell,thiscall,inferred,objdump + caller xrefs + local disassembly + callsite-arg inspection,3,"Broad TrackLay.win world-surface and route-selection sync owner. The helper first validates the current world or route context through `0x004337a0` plus collection `0x0062be10`, releases any prior cached tool route id `[this+0x78]`, and then branches on the two caller-supplied flags. On the world-hit-test path it re-enters `0x00448ac0` to resolve current world coordinates, seeds or updates a route entry in the global route owner `0x006cfca8` through `0x00493600`, `0x0049ace0`, and several route-classification helpers, mirrors the chosen entry id back into `[this+0x78]` and class byte `[entry+0x216]` into `[this+0x7c]`, updates route-owner byte `[route+0x11c]`, and publishes the chosen entry through `0x0049b180`. On the active-route branch it can refresh or recreate route-owner field `[route+0x125]` through `0x004955b0` and `0x00493cf0`, then re-enter the later route-update helper `0x004a04c0`. On the cleanup side it posts the fixed shell payload through `0x0053ef90`, can clear route latch `[route+0x118]`, can delete route ids `[route+0x125]` and `[route+0x129]` through `0x0049bbb0`, and can set local byte `[this+0x82]` for a later clear pass. Current grounded callers are the recurring TrackLay service-frame path `0x0050e3ed` and the TrackLay message owner branch `0x0050e8a2`, so this is the safest current read for the shared TrackLay world-surface or active-route synchronization owner rather than a narrow hit-test helper.","objdump + caller xrefs + local disassembly + callsite-arg inspection + route-owner correlation + world-surface correlation" +0x0050e070,358,track_lay_window_push_reentry_guard_snapshot_world_route_state_and_refresh_tool_state,shell,thiscall,inferred,objdump + caller xrefs + local disassembly + strings,3,"Entry-side TrackLay.win helper over the live tool object at `0x006d1a8c`. The helper increments the local nested-service guard at `[this+0x87]` and only runs the heavier body on the outermost entry. In bulldoze mode `0x40` it immediately tail-jumps into `0x004361d0`; otherwise it snapshots several live route-entry fields from the global route owner `0x006cfca8` into tool slots `[this+0x9b..+0xaf]`, clears or advances the matching world-side route-anchor fields at `[route+0x88/+0x90/+0x94/+0x98]`, re-enters `0x0050dab0` to refresh the tool-local state, mirrors later route fields `[route+0x118/+0x125/+0x11d/+0x121]` into `[this+0x8b..+0x97]`, and then tail-jumps into `0x0050d1e0`. Current grounded callers are the save-load wrapper `0x004423a0` and the direct save path at `0x00444e3b`, so this is the safest current read for the TrackLay entry-side nested-service snapshot and route-state handoff rather than the recurring per-frame service pass.","objdump + caller xrefs + local disassembly + route-owner correlation + nested-service correlation" +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 are the higher restore wrapper `0x004423d0` plus the direct save-load tails at `0x00444ee9` and `0x00445a73`; the paired entry-side helper is `track_lay_window_push_reentry_guard_snapshot_world_route_state_and_refresh_tool_state` `0x0050e070`.","objdump + caller xrefs + strings + callsite inspection + nested-service correlation" +0x0050db10,236,track_lay_window_destroy_release_routes_reset_singleton_and_tail_shell_teardown,shell,thiscall,inferred,objdump + caller xrefs + local disassembly + teardown correlation,3,"Destructor-side TrackLay.win teardown helper. The function restores vtable `0x005d191c`, re-enters `track_lay_window_release_invalid_route_entries_reset_cached_selection_and_refresh_presenter` `0x0050d1e0`, runs the route-owner post-change sweep `0x004a3db0`, clears the global singleton `0x006d1a8c`, posts the fixed shell payload rooted at `0x005c87a8` through `0x0053ef90`, conditionally mirrors one world scalar from `[world+0x1689]` into `[world+0x168d]` when `[0x006cec74+0x263]` is set and `0x006d1a94` is still clear, replays `0x00453510` on live world mode `0x15` when the `0x006cec74+0x2cc` gate and `0x00450150` allow it, tail-jumps into `0x004361d0` on the startup object, clears `[this+0x83]`, conditionally re-enters `0x00491880` on the route owner, optionally posts shell status id `0xba` through `0x00538e00`, and finally tail-jumps into `0x0053f7d0`. Current grounded caller is the shell detail-panel transition manager `0x004ddbd0`, so this is the safest current read for the TrackLay.win destroy path rather than another internal route-store helper.","objdump + caller xrefs + local disassembly + teardown correlation + route-owner correlation + shell-status correlation" 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 +0x0051ea80,304,shell_controller_reset_core_state_fields_and_seed_small_defaults,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Small shell-controller reset helper beneath global-controller install. The function clears the early controller pointer and scalar band at `[this+0x00..+0x1c]`, seeds several small mode and flag fields such as `[this+0x11421a] = 1`, `[this+0x11420e] = 0x5c`, `[this+0x114228] = 2`, `[this+0x114232] = 1`, `[this+0x114254] = 1`, and `[this+0x114227] = 0x11`, and resets a broader set of small controller bytes and dwords under `[this+0x11422c..+0x11427e]` plus `[this+0x1136a9/+0x1136ad]`. Current grounded caller is `shell_install_global_controller` `0x0051ff90`, so this is the safest current read for the controller's core small-field reset-plus-default seeding path rather than the larger display-runtime reset owner at `0x0051ebc0`.","objdump + caller inspection + local disassembly + field-reset correlation" 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 0x0051eea0,128,shell_save_display_runtime_config,shell,cdecl,inferred,ghidra-headless,4,Writes the larger display-runtime blob to data\\configuration\\engine.cfg. It stores version key 0x41b serializes the 0x1e4-byte runtime block rooted at [this+0x11468a] and writes an additional 0x1ec-byte companion block before closing the file.,ghidra + rizin + llvm-objdump + strings 0x0051ef20,194,shell_load_display_runtime_config_or_init_defaults,shell,cdecl,inferred,ghidra-headless,4,Loads the larger display-runtime blob from data\\configuration\\engine.cfg. When the file is missing invalid or already superseded by mode state at 0x006d4028 it falls back to 0x0051ebc0 and 0x0051eea0; otherwise it validates key 0x41b restores the 0x1e4-byte and 0x1ec-byte blocks and clears one shell display flag when [this+0x11474a] is set.,ghidra + rizin + llvm-objdump + strings +0x0051eff0,8,shell_controller_store_pointer_field_0x0c,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Trivial field setter that stores the caller pointer argument into controller dword `[this+0x0c]` unchanged. Current grounded callers are the neighboring window-family branches at `0x0054bdf8` and `0x0054be8c`, which use it while installing or clearing one live controller-owned pointer during the `World` window setup path.","objdump + caller inspection + local disassembly + field-store correlation" +0x0051f000,101,shell_register_world_window_class_from_static_wndproc,shell,thiscall,inferred,objdump + local disassembly + string correlation + import-shape correlation,3,"Small shell-side window-class registration helper. The function builds one local `WNDCLASS`-style descriptor with style `3`, class name `World`, static window procedure `0x0054e3a0`, and one stock brush handle derived from argument `0x7f00`, then forwards the descriptor into the USER32 class-registration import and returns the resulting class atom as a zero-extended `u16`. The grounded class-name string `World` and the static wndproc make this the safest current read for the shared world-window class registration helper rather than a generic USER32 wrapper.","objdump + local disassembly + string correlation + import-shape correlation + wndproc correlation" +0x0051f070,4,shell_controller_get_primary_presentation_owner,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Returns controller dword `[this+0x18]` unchanged. Current grounded callers include `world_set_selected_year_and_refresh_calendar_presentation_state` `0x00409e80`, several shell caption-formatting branches, and broader presentation helpers, so the safest current read is the controller's primary presentation-owner accessor rather than a raw anonymous field load.","objdump + caller inspection + local disassembly + presentation-owner correlation" +0x0051f080,8,shell_controller_set_primary_presentation_owner,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Stores one caller pointer into controller dword `[this+0x18]` unchanged. Current grounded caller is the shell-side initialization path at `0x0055e3c9`, which seeds the same presentation-owner lane later queried by `0x0051f070`.","objdump + caller inspection + local disassembly + presentation-owner correlation" +0x0051f090,4,shell_controller_get_world_basis_owner,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Returns controller dword `[this+0x1c]` unchanged. Current grounded callers immediately feed the result into world-basis or view-space helpers such as `0x00534490`, `0x00534c50`, `0x00534910`, and `0x00534930`, so the safest current read is the controller's world-basis owner accessor rather than a raw anonymous field load.","objdump + caller inspection + local disassembly + world-basis correlation" +0x0051f0a0,8,shell_controller_set_world_basis_owner,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Stores one caller pointer into controller dword `[this+0x1c]` unchanged. Current grounded callers include the world-view setup branches around `0x00537e56` and `0x00537eda`, which seed or clear the same owner later queried through `0x0051f090`.","objdump + caller inspection + local disassembly + world-basis correlation" +0x0051f0b0,4,shell_controller_get_cursor_service_active_flag,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Returns controller dword `[this+0x20]` unchanged. Current grounded caller is `shell_mouse_cursor_adjust_showcursor_refcount_and_sync_screen_position_if_live` `0x0051e810`, which uses this value as the gate for the live cursor-position sync branch.","objdump + caller inspection + local disassembly + mouse-cursor correlation" +0x0051f0c0,8,shell_controller_mark_input_subobject_index_present,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small shell-input helper that resolves controller subobject `[this+0x24]` and forwards one caller byte index into the byte-table writer at `0x00564180`, which stores value `1` at `[subobject + index]`. Current grounded caller is the main shell window-message dispatcher `0x0054e3a0` on the `WM_KEYDOWN` branch.","objdump + caller inspection + local disassembly + window-message correlation" +0x0051f0d0,8,shell_controller_mark_input_subobject_index_absent,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small shell-input helper that resolves controller subobject `[this+0x24]` and forwards one caller byte index into the byte-table writer at `0x00564190`, which stores value `0` at `[subobject + index]`. Current grounded caller is the main shell window-message dispatcher `0x0054e3a0` on the `WM_KEYUP` branch.","objdump + caller inspection + local disassembly + window-message correlation" +0x0051f0e0,8,shell_controller_query_input_subobject_index_flag,shell,thiscall,inferred,objdump + local disassembly + helper correlation,2,"Small shell-input helper that resolves controller subobject `[this+0x24]` and forwards one caller byte index into the byte-table reader at `0x005641a0`, returning the current byte flag at `[subobject + index]`. This is the query-side sibling of `0x0051f0c0` and `0x0051f0d0`.","objdump + local disassembly + helper correlation + byte-table correlation" 0x0051f0f0,3,shell_controller_get_window_handle,shell,thiscall,inferred,objdump + import-table,4,Returns the native shell window handle stored at [this+0x00]. Callers forward the returned handle into USER32 imports such as SetFocus SetMenu and SetCapture during shell startup and presentation interaction.,objdump + USER32 import table + callsite xrefs +0x0051f100,143,shell_controller_copy_active_display_mode_tuple,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Copies the active display-mode tuple from the controller mode table rooted at `[this+0x34]` using live selector `[this+0x11421e]`. The helper always writes the first two dwords from offsets `+0x00` and `+0x04`, optionally copies dword `+0x08`, conditionally returns either `0` or dword `+0x0c` depending on graphics-range scalar `[this+0x11470e]`, and optionally copies trailing byte `+0x14` as a zero-extended dword. Current grounded callers include the graphics-range predicates `0x0051fd00/0x00520fd0`, the mouse-cursor sync helper `0x0051e810`, and the window-class or view-side coordinate helpers, so this is the safest current read for the active display-mode tuple materializer rather than another opaque table accessor.","objdump + caller inspection + local disassembly + display-mode-table correlation + graphics-range correlation" +0x0051f1a0,7,shell_controller_get_graphics_mode_byte,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Returns graphics-mode byte `[this+0x114226]` as a zero-extended integer. Current grounded callers include the graphics settings page, the mouse-cursor family, the shell input window-message family, and several world-presentation gates, so this is the safest current read for the controller's current graphics-mode-byte accessor.","objdump + caller inspection + local disassembly + graphics-mode correlation" +0x0051f1b0,7,shell_controller_get_display_runtime_dword_1146f6,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Returns display-runtime dword `[this+0x1146f6]` unchanged. Current grounded caller is the shell-side initialization path at `0x0055e3ed`, which snapshots the field into a local runtime record.","objdump + caller inspection + local disassembly + field-correlation" +0x0051f1c0,8,shell_controller_set_display_runtime_dword_1146f6,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Stores one caller dword into display-runtime field `[this+0x1146f6]` unchanged. Current grounded callers include `0x00527cb4` and `0x0052c136`, which write new values back through the controller rather than touching the field directly.","objdump + caller inspection + local disassembly + field-correlation" 0x0051f1d0,90,shell_signal_deferred_work_item_shutdown,shell,thiscall,inferred,ghidra-headless,3,Walks the shell deferred-work item queue at [this+0x1136a5] and inspects each queued payload object's nested message queue at [item+0xe4]. When intrusive_queue_peek_tail_payload finds a nonnull tail payload it clears the outer queued-handle slot at [item+0xe8] and appends a null sentinel into the nested queue through intrusive_queue_push_back before continuing iteration.,ghidra + rizin + llvm-objdump 0x0051f230,128,shell_enqueue_deferred_work_message,shell,thiscall,inferred,ghidra-headless,4,Routes one deferred-work message through the shell queue system. When the global routing gate at 0x006d4034 and shell flag [this+0x11369c] are both set it feeds the special queue at [this+0x11369d]; otherwise a nonnull payload object is queued once in [this+0x1136a5] with the returned queue-node handle cached at [item+0xe8] and the message is appended to the payload-owned nested queue at [item+0xe4] while a null payload appends directly into the fallback queue at [this+0x1136a1].,ghidra + rizin + llvm-objdump 0x0051f2b0,104,shell_post_deferred_message_type5,shell,thiscall,inferred,ghidra-headless,4,Allocates one 0x5e-byte deferred-message record from the shell-owned slab rooted at [this+0x5c] using count [this+0x58] tags it as type 0x05 stores four caller dwords at offsets +0x01 +0x05 +0x09 and +0x0d and then posts the record directly into the shell deferred queue roots through [this+0x11369d] or [this+0x1136a1].,ghidra + rizin + llvm-objdump @@ -992,9 +1687,15 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0051f370,229,shell_enqueue_deferred_message_type4,shell,thiscall,inferred,ghidra-headless,4,Allocates one 0x5e-byte deferred-message record from the shell-local slab at [this+0x5c] populates the larger multi-field payload tags it as type 0x04 mixes the shell byte [this+0x114227] into record byte +0x5d and routes the finished record through shell_enqueue_deferred_work_message.,ghidra + rizin + llvm-objdump 0x0051f460,173,shell_enqueue_deferred_message_type1,shell,thiscall,inferred,ghidra-headless,4,Allocates one 0x5e-byte deferred-message record from the same shell-local slab fills the smaller type-0x01 payload subset mixes the shell byte [this+0x114227] into record byte +0x5d and routes the finished record through shell_enqueue_deferred_work_message.,ghidra + rizin + llvm-objdump 0x0051f510,48,shell_set_gamma_ramp_scalar,shell,thiscall,inferred,ghidra-headless,4,Applies one shell gamma-ramp scalar to the active display runtime state. When the presentation service pointer at [this+0x0c] is live it forwards the scalar into 0x00547f20 for an immediate hardware upload; otherwise it only caches the requested value at [this+0x1146b9] until the service is ready.,ghidra + rizin + llvm-objdump +0x0051d890,13,shell_get_elapsed_tick_count_since_bootstrap_seed,shell,cdecl,inferred,objdump + timer-caller correlation,4,"Returns the current wall-clock tick count minus the bootstrap seed stored at `0x006d3d14`. The helper is a one-line elapsed-time primitive over the same USER32 tick import used by `bootstrap_seed_tick_count` `0x0051d870`. Current grounded callers include the timer-gated `SettingsWindow.win` graphics service strip around `0x004ffafb/0x004ffb64`, the world-view keyboard pan helper, and the frame-time history family.","objdump + timer-caller correlation + bootstrap-seed correlation" +0x0051fd00,64,shell_query_graphics_range_has_live_custom_payload,shell,thiscall,inferred,objdump + settings-window caller correlation,4,"Reports whether the graphics-range family currently has a live custom payload worth reapplying. The helper first rejects graphics mode byte `[this+0x114226] == 0`, then calls `0x0051f100` to materialize the current range tuple into five stack outputs and returns true only when the first returned dword is nonzero. Current grounded caller is `shell_settings_window_handle_graphics_range_custom_mode_toggle` `0x004ffd10`, which uses this predicate to decide whether the custom-mode toggle can proceed directly or must fall back to the warning path.","objdump + settings-window caller correlation + stack-output correlation" +0x0051fd40,29,shell_query_graphics_range_custom_mode_flag,shell,thiscall,inferred,objdump + settings-window caller correlation,4,"Returns one small custom-range mode flag for the graphics settings family. The helper reports true only when byte `[this+0x1146ae]` is set and dword `[this+0x11427a]` is still zero; otherwise it returns false. Current grounded caller is `shell_settings_window_refresh_graphics_page` `0x004fe770`, which uses this flag together with `shell_query_graphics_range_scalar` `0x0051fd60` to decide how controls `0x7555` and `0x7578` should be republished.","objdump + settings-window caller correlation + field-gate correlation" +0x0051fd60,7,shell_query_graphics_range_scalar,shell,thiscall,inferred,objdump + settings-window caller correlation,4,"Returns graphics-range scalar dword `[this+0x11470e]` unchanged. Current grounded caller is the graphics settings page refresh `0x004fe770`, which pairs this with `shell_query_graphics_range_custom_mode_flag` `0x0051fd40` when formatting controls `0x7555` and `0x7578`.","objdump + settings-window caller correlation" 0x0051fd70,516,shell_update_frame_time_history,shell,thiscall,inferred,ghidra-headless,4,Updates a 256-sample frame-time history from successive GetTickCount deltas. The helper advances the ring index in 0x006d403c stores each delta under [this+0x11428a] and derives a smoothed frame scalar at [this+0x114282] for later shell frame consumers such as 0x0051ff80 and the presentation-frame path.,ghidra + rizin + llvm-objdump 0x0051ff80,7,shell_get_smoothed_frame_scalar,shell,thiscall,inferred,objdump,4,Returns the smoothed frame scalar cached at [this+0x114282]. shell_update_frame_time_history refreshes that field each frame and shell_refresh_presentation_frame consumes it during the main presentation refresh path.,objdump + callsite xrefs 0x0051ff90,24,shell_install_global_controller,shell,thiscall,inferred,objdump + analysis-context,4,Installs one shell controller as the process-global singleton at 0x006d4024 clears controller flag [this+0x114201] reruns the local state reset helper at 0x0051ea80 and returns the same controller pointer. bootstrap_init_shell_window_services calls it immediately after allocating the 0x11486e-byte controller object.,objdump + analysis-context + startup xrefs +0x00520fd0,87,shell_set_graphics_range_custom_mode_flag_and_reapply_if_needed,shell,thiscall,inferred,objdump + settings-window caller correlation,4,"Applies a requested custom-mode flag for the graphics-range family. The helper compares the incoming boolean against `shell_query_graphics_range_custom_mode_flag` semantics over `[this+0x1146ae]` and `[this+0x11427a]`, stores the new byte at `[this+0x1146ae]` only when it changed, rejects the enabling path when `shell_query_graphics_range_has_live_custom_payload` `0x0051fd00` is false, and when reapplication is allowed forwards the current graphics mode byte `[this+0x114226]` plus the live selector dword `[this+0x11421e]` into `0x00520400`. Current grounded caller is `shell_settings_window_handle_graphics_range_custom_mode_toggle` `0x004ffd10`.","objdump + settings-window caller correlation + graphics-range-reapply correlation" +0x00521030,45,shell_set_graphics_range_scalar_and_reapply_if_needed,shell,thiscall,inferred,objdump + settings-window caller correlation,4,"Stores one replacement graphics-range scalar dword at `[this+0x11470e]` and, when graphics mode byte `[this+0x114226]` is nonzero, immediately re-enters `0x00520400` with the live selector dword `[this+0x11421e]` plus the current mode. Current grounded caller is `shell_settings_window_handle_graphics_range_scalar_zero_nonzero_toggle` `0x004ffe72`, which uses this helper to flip the scalar between zero and nonzero states.","objdump + settings-window caller correlation + graphics-range-reapply correlation" 0x00521d10,38,multiplayer_request_peer_session_control,shell,cdecl,inferred,ghidra-headless,3,Requests one direct session-control action for a resolved multiplayer peer object. When the live session transport at `0x006d40dc` is present it follows the transport-owned interface at `[ecx+0x18e]->+0x08` and invokes vtable slot `+0x68` with the target peer object and three zero trailing arguments; the current grounded callers are the `\\kick` branch and the online-peer `\\unban` follow-up path.,ghidra + rizin + llvm-objdump 0x0051fa00,56,shell_get_memory_budget_ceiling_bytes,shell,thiscall,inferred,ghidra-headless,3,Returns the current upper memory-budget bucket in bytes for the shell display runtime. When override field [this+0x1146ca] is set it maps that tier through the shared table at 0x00624c34 containing 0 1MB 2MB and 4MB entries; otherwise it starts from baseline field [this+0x1136ad] and adjusts it by the active lower-tier delta derived from [this+0x1146c6] and [this+0x1136a9] before clamping negative results to zero.,ghidra + rizin + llvm-objdump 0x0051fa40,25,shell_get_memory_budget_floor_bytes,shell,thiscall,inferred,ghidra-headless,3,Returns the current lower memory-budget bucket in bytes for the shell display runtime. When field [this+0x1146c6] is nonzero it maps that tier through the shared 0 1MB 2MB 4MB table at 0x00624c34; otherwise it falls back to baseline field [this+0x1136a9].,ghidra + rizin + llvm-objdump @@ -1007,6 +1708,7 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x00523e40,51,shell_invalidate_layout_state,bootstrap,thiscall,inferred,ghidra-headless,4,Marks the shell controller's layout-state path dirty by setting flags [this+0x3747] [this+0x3748] and [this+0x3749] then forwarding two state parameters into the subordinate object at [this+0x2d].,ghidra + rizin 0x005270d0,8,shell_mark_layout_dirty,bootstrap,thiscall,inferred,ghidra-headless,2,Marks the shell layout child dirty by setting byte flag [this+0x3749] before later code forces a commit pass.,ghidra + rizin 0x00527650,1476,shell_publish_texture_budget_report,shell,thiscall,inferred,ghidra-headless,4,Builds and publishes a shell-side texture budget report through the current layout state at [this+0x2d]. The routine formats the current memory-budget floor and ceiling buckets from 0x0051fa40 and 0x0051fa00 converts them to kilobytes adds the current texture-change counter through 0x0055d390 appends labels like Texture changes per frame Texture SRAM and Texture VRAM and forwards the assembled text into 0x00566980.,ghidra + rizin + llvm-objdump + strings +0x00527de0,46,shell_presenter_publish_scaled_scalar_caption_and_store_aux_weight,bootstrap,thiscall,inferred,objdump + caller correlation + local disassembly,3,"Shared shell-presenter scalar-caption helper. The routine scales the caller float argument by `0x005dd158`, forwards that value through `0x0052ea90` on nested presenter field `[this+0x364d]`, scales a second incoming float by `0x005c8568`, and stores the result into `[this+0x3728]` as an auxiliary weight or caption-side scalar. Current grounded callers are several shell tool-window constructors and setters including `Bulldoze.win` `0x004b8720`, `ChangeTrees.win` `0x004bcdd0/0x004bcc20`, the world-surface brush ordinal setter `0x004bc210`, `PaintRegion.win` `0x004f5080`, `PaintSound.win` `0x004f55b0/0x004f5670`, `PaintTerrain.win` `0x004f5cf0`, `PaintTerritory.win` `0x004fcaf0`, and the ungrouped caller strips at `0x0050a430` and `0x0050d5d0`, so this is the current safest read for the shared shell scalar-caption publisher rather than a window-specific caption formatter.","objdump + caller correlation + local disassembly + shell-presenter correlation" 0x00527e10,868,shell_update_layout_tracking_sample,bootstrap,thiscall,inferred,ghidra-headless,4,Samples a tracked shell target from the object argument computes distance heading and orientation deltas against cached values at [this+0x36b8..0x36cc] consults the dirty flags and index helper at 0x00526590 and returns whether the controller should drive a fresh layout-state apply; on success it updates the cached sample fields and the global tick at 0x00cc3b4c.,ghidra + rizin 0x0052b990,4993,shell_refresh_presentation_frame,shell,thiscall,inferred,ghidra-headless,3,Main shell frame-style refresh pass for the active controller and layout-state path. It handles mode-sensitive layout-state rebuilds and dirties updates tracked shell samples through 0x00527e10 runs the nearby geographic-label static-cell animated-quad ranked-overlay and ranked-billboard sweeps applies presentation-node properties and cached vertex spans optionally publishes the texture budget report through 0x00527650 may request a deeper rebuild through 0x00565110 and can recurse once for a follow-up presentation pass before downstream timing or present helpers run.,ghidra + rizin + llvm-objdump 0x0052da00,102,vehicle_visual_register_attachment_object,bootstrap,thiscall,inferred,ghidra-headless,3,Registers one prebuilt attachment object on the owning vehicle visual. The helper lazily allocates a small attachment list at [this+0x81] pushes the object through 0x00556e10 copies the owner tint triple from [this+0x1e2] [this+0x1e6] and [this+0x1ea] into the object through 0x005545d0 and links the owner back through 0x005540a0.,ghidra + rizin + llvm-objdump @@ -1018,25 +1720,126 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0052a2f0,736,shell_build_ranked_overlay_vertex24_sweep,bootstrap,thiscall,inferred,ghidra-headless,3,Builds a ranked secondary vertex24 overlay pass over the cell grid returned by 0x00533e50 and two object collections at [this+0x85] and [this+0x81]. It computes a per-frame packed tint from the current shell brightness gathers and sorts candidate items by priority field [item+0x1d9] binds the layout-state vertex24 table and emits accepted items through 0x00524780 and 0x00554e70 before committing the span.,ghidra + rizin + llvm-objdump 0x0052a5d0,1784,shell_build_ranked_object_billboard_sweep,bootstrap,thiscall,inferred,ghidra-headless,3,Builds the sibling ranked object-overlay pass gated by config byte [this+0x29+0x5e]. It merges candidates from the object collections at [this+0x85] and [this+0x81] sorts them by priority field [item+0x1d9] prepares billboard basis state through 0x00566670 and emits accepted entries through 0x00554e70 before committing the vertex24 span.,ghidra + rizin + llvm-objdump 0x0052dd00,864,shell_expand_segment_record_triplets,bootstrap,thiscall,inferred,ghidra-headless,4,Expands one active presentation-batch record into three transformed 0x20-byte segment records inside the caller-provided buffer; each output record is two vec3 blocks at +0x00 and +0x0c plus scalar slots at +0x18 and +0x1c. The selected batch record supplies a source-array pointer at +0x04 a source-count at +0x0c and 0x4c-byte packed source entries that carry four point sources plus three scalar pairs for the emitted triplet.,ghidra + rizin +0x0053f000,238,mouse_cursor_select_shape_id_load_handle_and_refresh_shell_presentation,shell,thiscall,inferred,objdump + caller inspection + local disassembly + source-string correlation,3,"Core `MouseCursor.cpp` selector over one requested cursor-shape id. The helper normalizes negative ids to zero, optionally short-circuits when the requested id already matches `[this+0x04]`, refreshes the local elapsed-tick latch `[this+0x24]` through `0x0051d890`, toggles cursor visibility through `0x0051e810` on the special `0 -> nonzero` and `nonzero -> 0` transitions, lazily loads the corresponding native cursor handle into table `0x00ccba60` through `0x0053ee90`, publishes that handle through the USER32 cursor-set import, resolves one shell presentation payload through `0x0053d110` when the requested id is nonzero, releases the previous payload through `0x0053c000`, and then stores the new payload at `[this+0x00]` plus the selected id at `[this+0x04]`. Current grounded callers include shell modal setup `0x004c98a0`, several detail-panel mode publishers, and the rest of the mouse-cursor owner family, so this is the safest current read for the live cursor-shape selector plus presentation refresh owner.","objdump + caller inspection + local disassembly + source-string correlation + cursor-handle-table correlation" +0x0053f0f0,115,mouse_cursor_enter_hidden_or_captured_mode_and_clear_selection,shell,thiscall,inferred,objdump + caller inspection + local disassembly + source-string correlation,3,"Mode-transition branch in the `MouseCursor.cpp` owner family. When local state `[this+0x18]` is still clear, the helper first pings shell work owner `[0x006d4024+0x28]` through vtable slot `+0x1c`, then calls one zero-argument USER32 import, marks `[this+0x18] = 1`, clears `[this+0x14]`, seeds `[this+0x08] = 1`, mirrors shell latch `[0x006d4024+0x11473e] = 1`, and, when a non-`-1` cursor id is active, forces cursor visibility down through `0x0051e810(0)` before re-entering `0x0053f000(-1, 0, 0)`. Current grounded callers are the graphics-backend service branches `0x004ffb64`, the coarse mouse-cursor service `0x0053f400`, and the local constructor sync at `0x0053f330`, so the safest current read is a hidden-or-captured mode entry branch rather than a generic state toggle.","objdump + caller inspection + local disassembly + source-string correlation + shell-latch correlation" +0x0053f170,159,mouse_cursor_begin_pending_release_from_hidden_mode,shell,thiscall,inferred,objdump + caller inspection + local disassembly + source-string correlation,3,"Release-side mode-transition branch in the `MouseCursor.cpp` owner family. When `[this+0x14]` is still clear, the helper conditionally forwards the shell window handle through one one-argument USER32 import when graphics mode byte `[0x006d4024+0x114226]` is active, pings shell work owner `[0x006d4024+0x28]` through vtable slot `+0x1c`, re-enters `0x0053f000(0, 0, 0)` to clear the live cursor selection, clears `[this+0x18]`, sets `[this+0x14] = 1`, zeroes shell latches `[0x006d4024+0x11473a/+0x11473e]`, and, when local byte-flag dword `[this+0x08]` is nonzero, raises cursor visibility back through `0x0051e810(1)`. Current grounded callers are the graphics-backend service-and-repaint branch `0x004ffafb`, the coarse mouse-cursor service `0x0053f400`, and the local inside-view watcher `0x0053f450`, so this is the safest current read for the begin-release transition out of the hidden mode.","objdump + caller inspection + local disassembly + source-string correlation + shell-latch correlation" +0x0053f210,166,mouse_cursor_complete_release_and_raise_shell_visible_latch,shell,thiscall,inferred,objdump + caller inspection + local disassembly + source-string correlation,3,"Second release-side mode-transition branch in the same `MouseCursor.cpp` family. When either `[this+0x14]` or `[this+0x18]` is still set, the helper reruns the same shell-window and shell-work-owner follow-ons as `0x0053f170`, clears the live cursor selection through `0x0053f000(0, 0, 0)`, clears both `[this+0x18]` and `[this+0x14]`, writes shell latch `[0x006d4024+0x11473a] = 1` while keeping `[+0x11473e] = 0`, restores the saved selected id into `[this+0x04]`, and when `[this+0x08]` is nonzero raises cursor visibility through `0x0051e810(1)`. Current grounded callers are the graphics-backend no-repaint service branch `0x004ffb64` and the local chooser `0x0053f2c0`, so this is the safest current read for the completed release-to-visible transition rather than another generic toggle.","objdump + caller inspection + local disassembly + source-string correlation + shell-latch correlation" +0x0053f2c0,32,mouse_cursor_service_pending_mode_choice_from_shell_latch,shell,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small chooser over the two release-transition branches in the `MouseCursor.cpp` family. When local pending flag `[this+0x14]` is nonzero, it dispatches either to `0x0053f0f0` or `0x0053f210` according to shell latch `[0x006d4024+0x11473e]`; otherwise it returns immediately. Current grounded caller is the timer-gated graphics-page service branch `0x004ffafb`.","objdump + caller inspection + local disassembly + shell-latch correlation" +0x0053f2f0,32,mouse_cursor_push_selection_hold_and_optionally_switch_to_id6,shell,thiscall,inferred,objdump + local disassembly + family correlation,2,"Small hold-counter increment helper in the `MouseCursor.cpp` family. On the first nested hold when `[this+0x0c]` is still zero, it snapshots the current selected id from `[this+0x04]` into `[this+0x10]`, switches the live cursor through `0x0053f000(6, 0, 0)`, and then increments the hold count at `[this+0x0c]`.","objdump + local disassembly + family correlation + hold-counter correlation" +0x0053f310,28,mouse_cursor_pop_selection_hold_and_restore_saved_or_default_id,shell,thiscall,inferred,objdump + local disassembly + family correlation,2,"Hold-counter decrement helper paired with `0x0053f2f0`. The helper decrements `[this+0x0c]`, and when the count reaches zero it restores the saved id from `[this+0x10]` or fallback id `1` through `0x0053f000(saved_or_default, 0, 0)`.","objdump + local disassembly + family correlation + hold-counter correlation" +0x0053f330,146,mouse_cursor_reset_controller_state_and_sync_shell_mode_latches,shell,thiscall,inferred,objdump + caller inspection + local disassembly + source-string correlation,3,"Constructor-side reset for the global `MouseCursor.cpp` controller at `0x00ccbb20`. The helper clears the local state band `[this+0x00..+0x28]`, seeds `[this+0x08] = 1`, `[this+0x10] = 1`, and `[this+0x04/+0x20] = -1`, re-enters `0x0053f000(0, 0, 0)`, frees any auxiliary handle at `[this+0x1c]`, and then syncs the local hidden or visible mode latches from shell dwords `[0x006d4024+0x11473e/+0x11473a]` by optionally entering `0x0053f0f0` or setting `[this+0x14]` directly. The tail also clears the shared cursor-handle table `0x00ccba60`. Current grounded caller is `shell_install_global_controller` follow-on startup beneath the mouse-cursor owner family.","objdump + caller inspection + local disassembly + source-string correlation + startup correlation" +0x0053f3d0,39,mouse_cursor_release_current_selection_and_aux_handle,shell,thiscall,inferred,objdump + local disassembly + family correlation,2,"Small cleanup helper in the `MouseCursor.cpp` family. The helper clears the current selection through `0x0053f000(0, 0, 0)`, frees the auxiliary handle at `[this+0x1c]` when present, and zeroes that slot. This is the direct release-side sibling of the constructor reset at `0x0053f330`.","objdump + local disassembly + family correlation + cleanup correlation" +0x0053f400,80,mouse_cursor_service_coarse_global_mode_latches,shell,cdecl,inferred,objdump + caller inspection + local disassembly + family correlation,3,"Coarse service branch over the global `MouseCursor.cpp` mode latches `0x00ccbb18/0x00ccbb1c/0x00ccbb24/0x00ccba58/0x00ccba5c`. The helper decrements countdown `0x00ccbb24`, and when that reaches zero it dispatches either into `0x0053f0f0` or `0x0053f170` from the pending global owners, then mirrors the surviving globals back into shell latches `[0x006d4024+0x11473e/+0x11473a]`. Current grounded caller is the frame updater `0x0053f4e0`.","objdump + caller inspection + local disassembly + family correlation + shell-latch correlation" +0x0053f450,134,mouse_cursor_refresh_inside_active_view_and_toggle_visibility_hint,shell,thiscall,inferred,objdump + caller inspection + local disassembly + source-string correlation,3,"Small view-sensitive refresh in the `MouseCursor.cpp` family. The helper samples the current `cursor inside active view` predicate through `shell_input_cursor_inside_active_view` `0x0054f540`, compares that boolean against local state `[this+0x08]`, and on changes updates the same state plus toggles cursor visibility through `0x0051e810(0/1)` when hidden mode `[this+0x18]` is active. On the fallback path it also consults the global shell-side cursor owner at `0x00ccbb20` and, when the global `ShowCursor` refcount is positive, refreshes the coarse elapsed-tick latch `[this+0x24]` or re-enters `0x0053f000(1, 1, 0)`. Current grounded callers are `mouse_cursor_update_frame_state` `0x0053f4e0` and the shell camera action helper `0x004e0780`, so this is the safest current read for the inside-view watcher plus visibility hint owner.","objdump + caller inspection + local disassembly + source-string correlation + inside-view correlation" 0x0053f4e0,739,mouse_cursor_update_frame_state,shell,thiscall,inferred,ghidra-headless,4,Per-frame MouseCursor.cpp updater for the global cursor controller at 0x00ccbb20. It refreshes elapsed tick state through 0x0051d890 re-arms the active cursor selection through 0x0053f450 and 0x0053f000 when the 150 ms and 15 s idle thresholds trip resets per-frame cursor globals through 0x0054f6c0 and 0x0054f6d0 samples cursor placement and world-relative state through world_anchor_measure_projected_half_width world_anchor_measure_projected_half_height and shell_queue_world_anchor_marker and publishes the resulting cursor presentation state through shell_publish_text_callout_presentation before finalizing through 0x0054f6e0.,ghidra + rizin + llvm-objdump + strings 0x0052e060,537,shell_expand_vertex24_triplets,bootstrap,thiscall,inferred,ghidra-headless,4,Sibling emitter for the same active presentation-batch record family; expands each 0x4c-byte packed source entry into three 0x18-byte vertex24 records in the caller-provided buffer. Each emitted record stores a vec3 at +0x00 a style dword from [this+0x43] at +0x0c and scalar slots at +0x10 and +0x14 while the output-count accumulator advances by count*3.,ghidra + rizin 0x0052eb20,51,shell_read_optional_presentation_extents4,bootstrap,thiscall,inferred,ghidra-headless,4,Reads an optional four-float extent block from the active presentation-batch record when byte flag [this+0x25] is set; copies dwords at +0x26 +0x2a +0x2e and +0x32 into caller outparams for the presentation-extents helper at 0x547d10.,ghidra + rizin 0x0052eb60,6,runtime_object_constant_0x46_stub_vtable_5cfd00_slot0,map,thiscall,inferred,objdump + vtable scan + local disassembly,1,"Tiny constant-return virtual slot in the sibling `Infrastructure`-side table `0x005cfd00`. The helper returns literal `0x46` in `EAX` and exits immediately. Current evidence does not justify a stronger semantic name beyond that fixed return value.","objdump + vtable scan + local disassembly" 0x0052eb70,6,runtime_object_constant_0x46_stub_vtable_5cfd00_slot1,map,thiscall,inferred,objdump + vtable scan + local disassembly,1,"Second tiny constant-return virtual slot in the sibling `Infrastructure`-side table `0x005cfd00`. The helper also returns literal `0x46` in `EAX` and exits immediately. Current evidence does not justify a stronger semantic name beyond that fixed return value.","objdump + vtable scan + local disassembly" 0x0052eb80,7,runtime_object_constant_float_1_25_stub_vtable_5cfd00_slot,map,thiscall,inferred,objdump + vtable scan + local disassembly + rdata inspection,1,"Tiny float-return virtual slot in the sibling `Infrastructure`-side table `0x005cfd00`. The helper loads and returns the constant float at `0x005dd1e8`, which is `1.25f`. Current evidence grounds it only as a fixed float-return slot.","objdump + vtable scan + local disassembly + rdata inspection" -0x0052eca0,43,shell_get_next_presentation_batch_record,bootstrap,thiscall,inferred,ghidra-headless,4,Returns the next 0x45-byte presentation-batch record for the active item family rooted at [this+0x14] if current index [this+0x21] plus one is still below the family count at [+0x14]; otherwise returns null.,ghidra + rizin +0x0052eb90,53,runtime_object_release_all_entries_in_list_field_0x79_via_0x554d50,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared cleanup helper over the broader `0x23a` runtime-object family. When list root `[this+0x79]` is nonnull, the helper walks that collection through `0x00556ef0/0x00556f00` and releases every entry through `0x00554d50` until no child remains. Current grounded callers include placed-structure rebuild or mutation branches `0x0046f055`, `0x004707e1`, `0x00507d70`, and `0x00509057`, where it acts as the release-side companion after local-runtime state mutations.","objdump + caller inspection + local disassembly + shared-runtime-object correlation" +0x0052ebd0,122,runtime_object_load_two_flag_bits_into_byte_0x20_and_optionally_refresh_handle_0x0c,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared stream-load helper beneath the broader `0x23a` runtime-object family. The function reads two one-byte flag lanes from the caller-supplied stream through `0x00531150`, folds those values into bits `0x20` and `0x40` of state byte `[this+0x20]`, and when the refreshed `0x40` bit ends up enabled with owner pointer `[this+0x04]` already live it clears that bit again, rebuilds one dependent handle through `0x00533bc0`, and stores the result into `[this+0x0c]`. Current grounded caller is the tagged payload loader `0x004560c0`, so the safest read is a two-bit load helper with an optional dependent-handle refresh rather than a generic byte reader.","objdump + caller inspection + local disassembly + stream-load correlation" +0x0052ec50,68,runtime_object_serialize_two_flag_bits_from_byte_0x20,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared stream-save companion to `0x0052ebd0` beneath the broader `0x23a` runtime-object family. The helper extracts bits `0x20` and `0x40` from state byte `[this+0x20]` as two one-byte values and writes both bytes into the caller-supplied stream through `0x00531030`. Current grounded caller is the shared tagged serializer `0x00455a22`, so this is the safest current read for the two-bit save helper rather than a broader payload writer.","objdump + caller inspection + local disassembly + stream-save correlation" +0x0052eca0,46,runtime_object_query_next_grouped_0x45_byte_subrecord_from_table_0x14,map,thiscall,inferred,objdump + local disassembly + field inspection,2,"Shared fixed-record cursor helper over the broader `0x23a` runtime-object family. When grouped table root `[this+0x14]` is live and current subrecord index `[this+0x21] + 1` remains below the current group count taken from the `0x45`-byte group header selected by `[this+0x3a]`, the helper returns the next subrecord pointer from that group's payload base `[group+0x0c]`; otherwise it returns null. Current evidence is strong enough for the grouped-table cursor shape but not yet for a stronger user-facing semantic name for the `0x45`-byte records.","objdump + local disassembly + field inspection + grouped-subrecord correlation" +0x0052ecd0,272,runtime_object_reset_local_state_and_seed_default_scalar_flag_bands,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared low-level reset helper beneath the broader `0x23a` runtime-object family. The function clears the local list and handle roots at `[this+0x04/+0x08/+0x0c/+0x10/+0x14/+0x1c/+0x75..+0x81]`, resets string or scalar side bands around `[this+0x4b..+0x65]`, clears cached words at `[this+0x8d]`, `[this+0x1be..+0x1da]`, and related spans, preserves only selected low bits of state byte `[this+0x20]` before forcing default mask `0x62`, writes `-1` sentinels into `[this+0x3e]`, `[this+0x1ee]`, and `[this+0x1fa]`, and seeds the recurring default `1.0f` lanes at `[this+0x36]`, `[this+0x18e]`, `[this+0x1a2]`, `[this+0x1b6]`, `[this+0x1ca]`, and `[this+0x1da]`. Current grounded callers are the shared payload loaders `0x00455b70`, `0x00455fc0`, and the deeper init branch `0x0052edf0`, so this is the safest current read for the common local-state reset and default seeding owner.","objdump + caller inspection + local disassembly + shared-runtime-object correlation" +0x0052edf0,178,runtime_object_seed_owner_handle_anchor_triplet_and_default_color,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared post-reset initializer beneath the broader `0x23a` runtime-object family. After re-entering `0x0052ecd0`, the helper stores one caller-supplied owner or parent pointer into `[this+0x04]`, optionally resolves a primary handle from the second caller argument through owner `0x006d4020` into `[this+0x10]`, optionally resolves a secondary handle from the third argument into `[this+0x1c]`, copies the first triplet from the resolved primary handle into `[this+0x1e2/+0x1e6/+0x1ea]`, sets bit `0x08` in state byte `[this+0x20]`, and seeds packed color lane `[this+0x43]` to `0x007f7f7f`. When the primary handle argument is null, it zeros `[this+0x10/+0x14/+0x18]` and the copied triplet instead. Current grounded callers are the shared initializers `0x00455b70`, `0x00485819`, and `0x0053065a`, so this is the safest current read for seeding the owner-handle and anchor-triplet band rather than a subtype-specific constructor.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + anchor-triplet correlation" +0x0052eeb0,93,runtime_object_release_owned_entry_list_field_0x79_and_clear_root,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared release helper over owned list root `[this+0x79]` in the broader `0x23a` runtime-object family. The function walks the current list through `0x00556ef0/0x00556f00`, releases each live entry through `0x00556460`, frees those entries through `0x0053b080`, then destroys and frees the root list object itself through `0x005571d0` plus `0x0053b080`, and finally clears `[this+0x79]` back to null. Current grounded callers are the deeper release body `0x0052ef70` and the specialization-side cleanup `0x0045b734`, so this is the safest current read for the owned-list `[this+0x79]` release path.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + owned-list-release correlation" +0x0052ef10,93,runtime_object_release_owned_entry_list_field_0x7d_and_clear_root,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Sibling release helper over owned list root `[this+0x7d]` in the broader `0x23a` runtime-object family. The function walks the current list through `0x00556ef0/0x00556f00`, releases each live entry through `0x00553a00`, frees those entries through `0x0053b080`, then destroys and frees the root list object itself through `0x005571d0` plus `0x0053b080`, and finally clears `[this+0x7d]` back to null. Current grounded callers are the deeper release body `0x0052ef70` and specialization-side cleanup `0x0045b701`, so this is the safest current read for the owned-list `[this+0x7d]` release path.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + owned-list-release correlation" +0x0052ef70,424,runtime_object_release_owned_lists_detach_world_binding_and_free_handles,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Broader release body over the shared `0x23a` runtime-object family. The helper first clears the live shell-side preview or helper owner through `0x0052d160` when the active presentation owner still references `this`, releases the dependent handle at `[this+0x0c]` through `0x00533bd0`, then re-enters the owned-list cleanup helpers for `[this+0x79]` and `[this+0x7d]`. It also recursively releases the nested object list at `[this+0x75]` by rebasing each entry to vtable `0x005dd1f0`, calling `0x0052ef70` on that child, and then freeing both each child and the root list, while the sibling list at `[this+0x81]` is walked through `0x005540b0` plus the same free-root pattern. After those releases it clears one shell-side owner slot at `[presentation+0x366e]` when it still points at `this`, detaches the world binding through `0x00533c20` when owner `[this+0x04]` and handle `[this+0x08]` are live, and finally frees the optional handles at `[this+0x10]` and `[this+0x1c]` through owner `0x006d4020`. Current grounded callers are the shared cleanup wrapper `0x00455d47` and the recursive child-release path inside this same helper, so this is the safest current read for the common owned-list, binding, and handle teardown body.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + recursive-release correlation + world-binding-teardown correlation" +0x0052f120,192,runtime_object_refresh_cached_4x4_transform_block_when_dirty_bit_0x02,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared dirty-bit refresh helper over the broader `0x23a` runtime-object family. When state byte `[this+0x20]` still has bit `0x02` set, the helper clears that bit, sets bit `0x04`, zeroes the cached 16-dword transform block at `[this+0x14e]`, seeds its scale and anchor lanes from `[this+0x36]` and `[this+0x1e2/+0x1e6/+0x1ea]`, writes default scalar `1.0f` at `[this+0x18a]`, and then rebuilds the remaining matrix-style contents through `0x0056d3cd`. When the sign bit of `[this+0x20]` is clear it first derives one temporary basis from local vector lanes `[this+0x4b/+0x4f/+0x53]` through `0x0056e1a8`; otherwise it uses the stored fallback block at `[this+0x18e]` directly. Current grounded callers include constructors or refresh paths `0x004aa9be`, `0x00524470`, `0x005287ee`, `0x0052893e`, `0x005289d4`, `0x00528b63`, `0x005306b7`, and `0x0055613a`, so this is the safest current read for cached transform-block refresh rather than a generic math helper.","objdump + caller inspection + local disassembly + dirty-bit correlation + transform-block correlation" +0x0052f1e0,391,geometry_query_five_vec3_separating_volume_overlap_predicate,map,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Pure boolean geometry helper that consumes five 3-float vector blocks and returns `1` only when a sequence of signed-volume or separating-plane style tests all pass. The routine builds local difference vectors from two of the input vec3s, forms intermediate cross-style terms against a third input vec3, rejects when the first signed volume is nonpositive, repeats the same pattern against a fourth input vec3, and then performs a final doubled-threshold comparison before returning. Current grounded callers are `0x0052f737` and `0x00530241`, where it acts as a geometric overlap or side-test predicate rather than as a stateful runtime-object helper. The exact higher-level shape semantics remain open, so this note stays structural.","objdump + caller inspection + local disassembly + geometric-predicate correlation" +0x0052f370,385,runtime_object_quantize_world_position_sample_group_metric_and_select_subrecord,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared quantized-selection helper over the broader `0x23a` runtime-object family. The function rounds the caller-supplied world coordinates, folds them through the quantized lookup table at `0x006d9098`, derives one odd metric seed from the final table index, queries a scaled scalar through owner handle `[this+0x04]` and `0x00533120`, applies one or two global scale adjustments from shell state, updates flag bit `0x02` in byte `[this+0x5c]` against threshold `0x005c8628`, and then chooses the active grouped `0x45`-byte subrecord by scanning the current group at `[this+0x14]` until the stored threshold field exceeds that sampled metric. The helper stores the selected subrecord index in `[this+0x21]` and the corresponding subrecord pointer in `[this+0x18]`. Current grounded caller is `0x00528f5b`, so this is the safest current read for a quantized metric-driven subrecord selector rather than a generic coordinate utility.","objdump + caller inspection + local disassembly + quantized-lookup correlation + grouped-subrecord correlation" +0x0052f500,1134,runtime_object_emit_selected_grouped_subrecords_into_global_packet_ring,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared packet-emission owner over the broader `0x23a` runtime-object family. The helper begins from the currently selected grouped subrecord at `[this+0x18]`, snapshots the active global packet write pointer and remaining count at `0x00cc3b64/0x00cc3b5c`, and rejects early when the selected group has no entries. When state bit `0x01` is active it also consumes caller-supplied world vectors, lazily refreshes the cached transform block when bit `0x04` is still set, transforms those vectors through the cached basis lanes `[this+0x8e..+0xb6]`, and runs the resulting geometry through `geometry_query_five_vec3_separating_volume_overlap_predicate` `0x0052f1e0` to decide whether one alternate emission branch should be used. In either branch it emits one run of `0x20`-byte output packets built from the current global packet source span and the selected grouped `0x45`-byte records, advancing the global packet pointer by `0x4c` per source packet while decrementing the shared remaining count. Current grounded callers are the world-side emission paths `0x005290d8`, `0x0052917f`, `0x0055dc3e`, `0x0055dc78`, `0x0055dcb4`, and `0x0055dd2a`, so this is the safest current read for grouped subrecord emission into the global packet ring rather than a local math helper.","objdump + caller inspection + local disassembly + packet-ring correlation + grouped-subrecord correlation + transform-refresh correlation" +0x0052fb70,480,runtime_object_set_packed_color_lane_and_optionally_propagate_child_brightness,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared packed-color helper over the broader `0x23a` runtime-object family. The function takes one caller-supplied byte and, when the shell-side gate at `[0x006d4024+0x114742]` is live, derives visible packed color `[this+0x43]` from stored high-byte lane `[this+0x47]` plus either dim RGB literal `0x003c3c3c` or full-bright literal `0x00ffffff` depending on whether the byte is below `0xff`. It also pushes the same dim-or-bright RGB triplet into every nested child reachable through list root `[this+0x75]` via `0x0052e680`, and when the recursive flag argument is nonzero it reapplies the same packed-color update to each child by re-entering itself. When the shell gate is absent, the helper instead stores the raw byte into high-byte lane `[this+0x47]` and only recurses that byte state to children. Current grounded callers are the specialization-side refresh and UI branches `0x004871b3`, `0x004a8277`, `0x004ad0a6`, `0x004af6b6`, `0x004b0e36`, and the local recursive calls inside this helper, so this is the safest current read for packed color or brightness propagation rather than a more specific UI event sink.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + child-color-propagation correlation" +0x0052fd60,93,runtime_object_publish_anchor_triplet_to_attached_entry_list_field_0x81,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared anchor-triplet publish helper over attached list root `[this+0x81]` in the broader `0x23a` runtime-object family. When that list exists and its root carries a nonnull payload at `[root+0x0c]`, the helper walks the entries through `0x00556ef0/0x00556f00` and forwards the current anchor triplet `[this+0x1e2/+0x1e6/+0x1ea]` into each live entry through `0x005545d0`. Current grounded callers are the relocation or republish paths `0x004acf51`, `0x0052fdc0`, `0x005307dc`, and `0x00530808`, so this is the safest current read for publishing the current anchor triplet to attached entries rather than a broader list-service helper.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + attached-entry-publish correlation" +0x0052fdc0,496,runtime_object_translate_anchor_triplet_rebind_world_cell_handle_and_refresh_attached_entries,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared relocation helper over the broader `0x23a` runtime-object family. The function first marks state byte `[this+0x20]` dirty with bit `0x02`, then adds the caller-supplied triplet delta to current anchor `[this+0x1e2/+0x1e6/+0x1ea]`. When owner `[this+0x04]` is live, it quantizes the old and new X/Z anchor lanes through `0x005a10d0` and the same world-scale constant used by `0x00530720`, checks the resulting cell indices against world-grid bounds from `0x00533970/0x00533980`, and if the quantized cell changed rebinds world handle `[this+0x08]` by detaching the old slot through `0x00533c20` and attaching the new slot through `0x00533bf0`. On success it republishes the current anchor triplet through `0x0052fd60`; on out-of-bounds failure it restores the prior anchor and returns `0`. Current grounded callers are the movement or placement-side branches `0x0045647b`, `0x00457d48`, `0x00458ec1`, and `0x00459945`, so this is the safest current read for anchor-triplet translation plus optional world-cell rebinding rather than a generic vector-add helper.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + world-binding-rebind correlation" +0x0052ffb0,115,runtime_object_scale_current_axis_angle_rotation_and_rebuild_orientation_block,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared rotation-scale helper over the broader `0x23a` runtime-object family. The function converts current local 4-dword orientation block `[this+0x1ce..+0x1da]` into one temporary axis-angle style representation through `0x0056e556`, scales the recovered angle by the caller-supplied float, rescales the axis lanes by constant `0x005c9b08`, and then rebuilds the stored orientation block by re-entering `0x0052e9f0`. Current grounded callers are the same specialization-side geometry and animation branches `0x00458b86`, `0x00458da5`, `0x00458e7f`, and `0x0045967c`, so this is the safest current read for scaling the current axis-angle rotation and rebuilding the cached orientation block rather than a generic scalar setter.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + axis-angle correlation" 0x00524780,1252,shell_emit_ranked_overlay_cell_items,bootstrap,thiscall,inferred,ghidra-headless,3,Processes one ranked-overlay cell list for 0x0052a2f0. It samples shell range thresholds through 0x00533180 and 0x00533160 filters cell items by distance and intensity derives an alpha-biased packed color from the caller input and emits accepted items into the current vertex24 span through layout helper 0x005468c0.,ghidra + rizin + llvm-objdump +0x00530030,591,runtime_object_query_selected_grouped_packet_overlap_against_input_segment,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared overlap-style query over the broader `0x23a` runtime-object family. The helper starts from the currently selected grouped `0x45`-byte subrecord and snapshots the same global packet source span used by `0x0052f500`, lazily refreshes the cached basis block at `[this+0x8e..+0xce]` when bit `0x04` is still set, transforms one caller-supplied input triplet through that basis, and then walks the remaining packet span at `0x00cc3b64/0x00cc3b5c`. For each candidate packet it assembles three packet-side vec3 triplets plus the transformed caller triplet and re-enters `geometry_query_five_vec3_separating_volume_overlap_predicate` `0x0052f1e0`, returning `1` on the first passing packet and `0` when the whole span fails. Current grounded caller is the world-side branch `0x005291ea`, so this is the safest current read for a selected-grouped-packet overlap query against one caller-provided segment or vector pair rather than a broad renderer.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + packet-overlap-query correlation" +0x005305c0,118,runtime_object_set_bit0_in_owned_entry_field_0xb0_across_list_0x79,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small list-bit propagation helper over owned entry list `[this+0x79]` in the broader `0x23a` runtime-object family. The function walks the list through `0x00556ef0/0x00556f00` and either sets or clears bit `0` in each live entry's dword `[entry+0xb0]` according to the caller's boolean. Current grounded callers are the specialization-side rebuild branches `0x0045cce7`, `0x0045cf90`, and one later sibling call at `0x00530857`, so this is the safest current read for propagating one mode bit across the owned-entry list rather than a generic iterator.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + owned-entry-flag propagation correlation" +0x00530640,35,runtime_object_construct_vtable_5dd1f0_and_seed_owner_handle_anchor,map,thiscall,inferred,objdump + caller inspection + local disassembly + rdata scan,2,"Tiny constructor wrapper for the sibling runtime-object table `0x005dd1f0`. The function installs vtable `0x005dd1f0`, forwards the caller's three setup arguments into `0x0052edf0`, and returns `this`. Current grounded callers are repeated descriptor or child-allocation branches including `0x0041ded0`, `0x0042ab05`, `0x00455148`, `0x00456e49`, `0x0045b95d`, `0x00474e61`, and `0x0055e71a`, so this is the safest current read for the shared seeded constructor wrapper rather than a subtype-specific allocator.","objdump + caller inspection + local disassembly + rdata scan + sibling-vtable correlation" +0x00530670,11,runtime_object_init_vtable_5dd1f0_and_reset_local_state,map,thiscall,inferred,objdump + caller inspection + local disassembly + rdata scan,1,"Tiny init wrapper for the sibling runtime-object table `0x005dd1f0`. The helper installs vtable `0x005dd1f0`, re-enters `0x0052ecd0`, and returns `this`. Current grounded callers are the local constructors `0x00455b24`, `0x00456104`, and `0x0048576c`, so the safest read is a minimal vtable-install plus shared-reset helper.","objdump + caller inspection + local disassembly + rdata scan + sibling-vtable correlation" +0x00530680,11,runtime_object_rebind_vtable_5dd1f0_and_tail_release_shared_lists,map,thiscall,inferred,objdump + caller inspection + local disassembly + rdata scan,1,"Tiny release-side wrapper for the sibling runtime-object table `0x005dd1f0`. The helper installs vtable `0x005dd1f0` and immediately tail-jumps into shared release body `0x0052ef70`. Current grounded callers are repeated cleanup paths including `0x0041df19`, `0x0045738b`, `0x0045c3fe`, `0x0045d729`, `0x004874f0`, and `0x0055e098`, so this is the safest current read for the sibling-table release thunk rather than a standalone destructor body.","objdump + caller inspection + local disassembly + rdata scan + sibling-vtable correlation" +0x00530690,133,runtime_object_copy_cached_blocks_from_source_object_and_recurse_children,map,thiscall,inferred,objdump + caller inspection + local disassembly + rdata scan,2,"Shared copy or refresh helper for the sibling runtime-object table `0x005dd1f0`. The function queries one 16-dword block from the caller-supplied source object through vtable slot `+0x44` and copies it into `[this+0x10e]`, triggers source slot `+0x10`, rebuilds local cached transform block `[this+0x14e]` through `0x0052f120` and source slot `+0x20`, copies the second 16-dword block from source slot `+0x44` into `[this+0xce]`, and then recursively applies the same copy to every child in list `[this+0x75]` before finally calling source slot `+0x0c`. Current grounded callers are the world-side branch `0x00528f18` and the local recursive descent inside this helper, so this is the safest current read for copying cached blocks from one source object into this object tree rather than a generic serializer.","objdump + caller inspection + local disassembly + rdata scan + sibling-vtable correlation + recursive-copy correlation" +0x00530720,242,runtime_object_publish_anchor_triplet_and_optionally_rebind_world_cell_handle,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared anchor-triplet publish helper over the broader `0x23a` runtime-object family. The function marks state byte `[this+0x20]` dirty with bit `0x02`, stores one caller-supplied absolute triplet into `[this+0x1e2/+0x1e6/+0x1ea]`, and when owner `[this+0x04]` is live quantizes the old and new X/Z anchor lanes through `0x005a10d0`, checks whether the world-cell binding changed, optionally detaches old handle `[this+0x08]` through `0x00533c20`, attaches the new slot through `0x00533bf0`, and then republishes the current anchor triplet through `0x0052fd60`. When owner `[this+0x04]` is null or the quantized cell does not change, it still writes the absolute triplet and republishes attached entries. Current grounded callers include `0x0040b4c7`, `0x004558ff`, `0x004871b3`, `0x0048dd50`, and the stream-load companion `0x00455870`, so this is the safest current read for publishing an absolute anchor triplet with optional world-cell rebinding rather than a generic vec3 setter.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + anchor-triplet correlation + world-binding correlation" +0x00530820,425,runtime_object_format_status_label_from_group_selection_and_shell_mode,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared fallback formatter beneath `0x00455860` over the broader `0x23a` runtime-object family. The helper only runs when shell gate `[0x006d4024+0x1146be]` is live, state bit `0x10` is clear, vtable slot `+0x14` returns zero, and the owned-entry bit propagator `0x005305c0` reports a live path. It then formats one caller-owned text buffer through `0x0051d8a0` using one of three structural branches: when grouped table `[this+0x14]` is null it emits a fixed fallback block via `0x5193f0/0x518de0`; when shell mode `[0x006d4024+0x1146be] == 1` it emits either literal `X` or the current grouped index `[this+0x21]`; otherwise it combines the current grouped float lane `[subrecord+0x10]`, the grouped index `[this+0x21]`, and one shell-mode-dependent wrapper block built through repeated `0x0051b700` calls before copying the final text. Current grounded callers are the shared thunk `0x00455860`, the placed-structure UI query wrapper `0x0040e9d0`, and the city-site status formatter `0x004207d0`, so this is the safest current read for a shared group-selection status-label formatter rather than a subtype-specific UI routine.","objdump + caller inspection + local disassembly + shared-runtime-object correlation + fallback-formatter correlation" +0x005309d0,35,global_indexed_slot_table_initialize_once_0xccb880,map,cdecl,inferred,objdump + caller inspection + local disassembly,1,"One-shot initializer for the indexed global slot table rooted at `0x00ccb880`. When guard dword `0x00ccb9ec` is still zero, the helper clears `0x5a` dwords starting at `0x00ccb880`, then sets the guard to `1`; otherwise it returns immediately. Current grounded callers are the setup and shell branches `0x004820d3` and `0x00521084`, so this is the safest current read for lazy table initialization rather than a broader mode reset.","objdump + caller inspection + local disassembly + global-slot-table correlation" +0x00530a00,364,global_indexed_slot_table_service_or_release_one_slot_state,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Indexed service or release helper over the global slot table rooted at `0x00ccb880`. The function switches on slot state dword `[slot+0x00]`, using the per-slot handle, buffer, capacity, and length lanes at `[+0x08/+0x18/+0x14/+0x1c/+0x20/+0x24]`. The observed branches cover: releasing the primary handle when the state is `0/1`; a state-`2` growth path that reallocates and copies the payload buffer when `[slot+0x0c] < [slot+0x14]`; state `4` forwarding one handle plus a size pair through `0x005a4c57/0x005a464d`; state `5/6` releasing one or two payload buffers through `0x0053afd0` and `0x005a440d`; and a final cleanup step that clears active flag `[slot+0x01]` and drops the auxiliary buffer when needed. Current grounded callers include the live-world serializer paths `0x004424ee`, `0x00443cab`, `0x00445916`, the shell-side branches `0x0048496f`, `0x00489920`, `0x004e180a`, and the late global cleanup loop `0x00530bb1`, so this is the safest current read for servicing or releasing one indexed slot-table state rather than a file-family-specific bundle helper.","objdump + caller inspection + local disassembly + global-slot-table correlation + state-machine correlation" +0x00530b70,20,global_indexed_slot_table_query_slot_primary_handle_metric,map,cdecl,inferred,objdump + caller inspection + local disassembly,1,"Tiny indexed query over the global slot table rooted at `0x00ccb880`. The helper resolves per-slot primary handle `[slot+0x08]` and forwards it into `0x005c7820`, returning the resulting metric unchanged. Current grounded callers are the serializer-side branch `0x00442676`, where the returned value is treated as a byte-count or size-like metric, so this is the safest current read for a primary-handle metric query rather than a direct pointer accessor.","objdump + caller inspection + local disassembly + global-slot-table correlation" +0x00530b90,11,global_indexed_slot_table_query_slot_primary_handle,map,cdecl,inferred,objdump + local disassembly,1,"Tiny pointer query over the global slot table rooted at `0x00ccb880`. The helper returns per-slot dword `[slot+0x08]` unchanged. Current evidence only grounds it as a direct primary-handle accessor.","objdump + local disassembly + global-slot-table correlation" +0x00530ba0,98,global_indexed_slot_table_release_slot_buffers_and_service_if_active,map,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Release-side companion over the global slot table rooted at `0x00ccb880`. When active flag `[slot+0x00]` is nonzero it first re-enters `0x00530a00`; when slot-owned payload flag `[slot+0x01]` is nonzero it frees the auxiliary payload and staging buffers at `[slot+0x18]` and `[slot+0x14]` through `0x005a1145`, then clears those pointers and the flag. Current grounded caller is the late cleanup path `0x00530bb1`, so this is the safest current read for releasing one slot's owned buffers and forcing a final service step when needed.","objdump + caller inspection + local disassembly + global-slot-table correlation + cleanup correlation" +0x00530c10,11,global_indexed_slot_table_query_slot_payload_length,map,cdecl,inferred,objdump + local disassembly,1,"Tiny indexed accessor over the global slot table rooted at `0x00ccb880`. The helper returns per-slot dword `[slot+0x14]` unchanged. Current evidence only grounds it as a payload-length or used-size accessor.","objdump + local disassembly + global-slot-table correlation" +0x00530c80,943,global_indexed_slot_table_open_or_reuse_named_stream_slot,map,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Primary open-or-reuse entry over the indexed slot table rooted at `0x00ccb880`. The helper first lazily initializes the table when needed, then for requested slot types `2` and `3` scans active entries whose type dword `[slot+0x0c]` is also `2/3`, comparing the caller-supplied name against stored pointer `[slot+0x20]` through `0x005a57cf`; type `2` also forces `0x00530ba0` cleanup before reusing the slot. Otherwise it locates a free slot, marks `[slot+0x00]` and `[slot+0x04]` active, stores the requested type into `[slot+0x0c]`, allocates and copies the caller name into `[slot+0x20]`, clears the size and cursor lanes, and then stages the backing resource according to type. Type `0` opens one direct handle through `0x005a4c57` with `(0x8301,0x80)`. Types `5` and `6` open through the same path with `(0x8000,0x100)` and then either stage the whole payload into owned buffer `[slot+0x1c]` or cap the staging window at `0x30d40`, sometimes collapsing type `6` back into type `5` when the payload is small. The recursive type-`3` branch allocates one scratch slot of length `0x30d40` plus one caller-sized owned buffer. Current callers span setup, shell, world, and serializer-loader paths including `0x00433260`, `0x00442463`, `0x00443a50`, `0x00444e83`, `0x00484939`, `0x0051c230`, and `0x0051eebe`, so this is the safest current read for opening or reusing one named bundle or stream slot rather than a file-family-specific loader.","objdump + caller inspection + local disassembly + global-slot-table correlation + bundle-slot correlation" +0x00531030,271,global_indexed_slot_table_write_bytes_into_slot,map,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Write-side byte pump over one indexed slot in the global table rooted at `0x00ccb880`. When slot type `[slot+0x0c]` is `0`, the helper forwards the caller buffer and requested length directly to handle `[slot+0x08]` through `0x005a464d`. When the type is `2` or `4`, it appends into owned buffer `[slot+0x1c]` at cursor `[slot+0x18]`, grows capacity `[slot+0x10]` in bounded chunks up to `0x186a0` through `0x005a125d/0x005a1145`, copies the caller bytes in place, advances the cursor, and raises used size `[slot+0x14]` when needed. Current callers are spread across the save and bundle serializer paths, including `0x004416af`, `0x0042ba7b`, `0x004462fa`, `0x004e1803`, `0x00517da4`, and the local tagged-header wrapper `0x00531340`, so this is the safest current read for the shared slot-table write primitive rather than a narrower world-only serializer.","objdump + caller inspection + local disassembly + global-slot-table correlation + shared-serializer correlation" +0x00531150,559,global_indexed_slot_table_read_bytes_from_slot,map,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Read-side byte pump over one indexed slot in the global table rooted at `0x00ccb880`. When slot type `[slot+0x0c]` is `1`, the helper reads directly from handle `[slot+0x08]` through `0x005a48c5`. When the type is `6`, it serves the caller from a rolling `0x30d40` staging buffer rooted at `[slot+0x1c]`, refilling that buffer from the same handle through `0x005a48c5` whenever cursor `[slot+0x18]` reaches the staged byte count and advancing the cursor after each copy. All remaining in-memory slot types read from owned buffer `[slot+0x1c]`, bounded by available count `[slot+0x14] - [slot+0x18]`, and then advance the cursor. Current callers are pervasive across setup, world, save, and runtime-object load paths, including `0x00412134`, `0x00413fa4`, `0x00443c39`, `0x00446ddb`, `0x00455888`, `0x00481a53`, `0x005186a6`, and the tagged-header and varlen readers `0x00531360/0x00531380`, so this is the safest current read for the shared slot-table read primitive rather than a file-family-specific chunk decoder.","objdump + caller inspection + local disassembly + global-slot-table correlation + shared-loader correlation" +0x00531340,20,global_indexed_slot_table_write_one_tagged_u32_header,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny write-side tagged-header wrapper over the same global slot table. The helper forwards the caller-supplied header dword in `EDX` into `0x00531030` with fixed length `4` and no auxiliary counter bump, using the current slot index in `ECX`. Current grounded callers are the many serializer-side tag brackets in world, scenario, and runtime-object save paths, including `0x0040b6b0`, `0x00413f3f`, `0x00441f40`, `0x00444f8a`, `0x004459df`, `0x0045b576`, and `0x005537f2`, so this is the safest current read for writing one tagged four-byte block header rather than a broader open-or-close primitive.","objdump + caller inspection + local disassembly + tagged-block correlation" +0x00531360,32,global_indexed_slot_table_read_one_tagged_u32_header_and_optionally_bump_counter,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Tiny read-side tagged-header wrapper over the same global slot table. When the caller-supplied stack flag is nonzero it increments global dword `0x00ccb9e8`, then reads one four-byte header from the current slot through `0x00531150` into the caller-supplied `u32` destination. Current grounded callers are the many loader-side tag brackets in world, scenario, setup, and runtime-object paths, including `0x0040b5ee`, `0x00413f3f`, `0x0041e8f4`, `0x0042dbf9`, `0x00443c56`, `0x0045600c`, `0x0046fd87`, and `0x00553258`, so this is the safest current read for reading one tagged four-byte block header with an optional global counter bump rather than a broader chunk-open helper.","objdump + caller inspection + local disassembly + tagged-block correlation" +0x00531380,144,global_indexed_slot_table_read_varlen_heap_string,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared variable-length string reader built on top of `0x00531150`. The helper first frees the caller-owned destination pointer when nonnull, then reads a one-byte prefix. Prefix `0` leaves the destination null. Prefixes `1..0x7f` are treated as the byte length directly. Prefixes with bit `0x80` set read one extra byte and combine the low seven high bits with that second byte into a `u15` length. The helper then allocates that many bytes through `0x005a125d`, stores the new heap pointer to the caller slot, and reads the payload bytes through `0x00531150`. Current grounded callers include `runtime_object_load_tagged_string_triplet_and_reseed_scalar_bands` `0x00455fc0`, `placed_structure_specialization_load_payload_and_rebuild_transients` `0x0045c150`, and the later payload loader at `0x0045e594`, so this is the safest current read for the shared variable-length heap-string import helper rather than a narrower subtype loader.","objdump + caller inspection + local disassembly + varlen-string correlation" +0x00531410,128,global_indexed_slot_table_write_varlen_heap_string,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared variable-length string writer built on top of `0x00531030`. Null pointers emit a single zero byte. Nonnull pointers are measured as a NUL-terminated byte string plus terminator; lengths up to `0x7f` emit one prefix byte, while longer lengths emit two prefix bytes with the high seven bits flagged by `0x80`. The helper then writes the string payload bytes through `0x00531030`. Current grounded callers include `runtime_object_serialize_tagged_string_triplet_and_dispatch_slot_0x4c` `0x004559d0`, `placed_structure_specialization_serialize_payload_via_0x45b560` `0x0045b560`, and the city-entry-family serializer `0x0045c6f0`, so this is the safest current read for the shared variable-length heap-string save helper rather than a generic raw buffer writer.","objdump + caller inspection + local disassembly + varlen-string correlation" +0x00531490,27,global_indexed_slot_table_write_nul_terminated_string_without_length_prefix,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny raw string writer over the same slot-table byte pump. The helper computes the caller-supplied NUL-terminated string length plus terminator from `EDX` and forwards those bytes directly into `0x00531030` without any explicit prefix layer. Current grounded callers are the neighboring shell-side branches `0x00489396` and `0x004894ec`, so the safest current read is a direct NUL-terminated string write helper rather than a broader tagged serializer.","objdump + caller inspection + local disassembly + raw-string-write correlation" +0x005314b0,79,global_callback_0x5c8454_query_first_nonzero_result_up_to_index,map,cdecl,inferred,objdump + caller inspection + local disassembly,1,"Small callback-driven selector over global dword `0x00ccba08`. The helper clears that global, then iterates indices `0..arg0`, repeatedly calling function pointer `0x005c8454` with one stack-local index slot plus the address of `0x00ccba08`, and stops when the callback returns zero; otherwise it increments the index and continues. On success it returns the value written to `0x00ccba08`, else `0`. Current grounded callers include `0x004fdb9b`, `0x0053166b`, `0x005321b4`, and `0x00532248`. The owning resource behind `0x005c8454` is still open, so the safest name stays structural.","objdump + caller inspection + local disassembly + callback-selector correlation" +0x00531500,25,global_query_requires_mode1_owner_and_nonnull_0xccb9f4,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny global gate. The helper returns `1` only when dword `[this+0x04]` equals `1` and global dword `0x00ccb9f4` is nonnull; otherwise it returns `0`. Current grounded callers include the neighboring UI or status-object branches `0x0046fd87`, `0x004b8f71`, `0x004c8243`, the setup-side branch `0x004e1a05`, and the runtime-object helper `0x00557e5c`. The exact owner of `0x00ccb9f4` remains open, so the safest read is still this structural gate rather than a named feature flag.","objdump + caller inspection + local disassembly + global-gate correlation" +0x00531520,59,global_mode1_gate_dispatch_0x557c90_0x557cb0_then_0x557cd0,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small mode-gated forwarding helper over global owner `0x00ccba00`. The helper only runs when `[this+0x04] == 1` and global `0x00ccb9f4` is still null. Under that gate it first queries `0x00557c90` on `0x00ccba00`; when that does not return `1` it queries `0x00557cb0`; and when either query returns `1` it tail-dispatches the same owner through `0x00557cd0`. Current grounded caller is the neighboring branch `0x004b8ea8`, so the safest current read is a small mode-1 gate plus two-stage dispatch wrapper rather than a fully named subsystem call.","objdump + caller inspection + local disassembly + mode-gated-forwarder correlation" +0x00531560,79,global_mode1_gate_dispatch_arg_selected_0x557d90_or_0x56a8e0_0x569ae0,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Mode-gated argument-selected forwarding helper spanning globals `0x00ccba00`, `0x00ccb9f8`, and `0x00ccb9fc`. The same gate applies: it only runs when `[this+0x04] == 1` and `0x00ccb9f4` is null. When selector arg1 is `0`, it forwards arg0 into owner `0x00ccba00` through `0x00557d90`. When selector arg1 is `2`, it forwards arg0 into `0x0056a8e0(0x00ccb9f8)` and then into `0x00569ae0(0x00ccb9fc)`. Current grounded callers span several shell and world-adjacent branches including `0x0043643b`, `0x00464b3b`, `0x004833c4`, `0x004feea4`, `0x00517a04`, and `0x005212ae`, so the safest current read is a small selector wrapper over three global owners rather than a named feature toggle.","objdump + caller inspection + local disassembly + mode-gated-forwarder correlation" +0x005315c0,91,affine_transform_three_float_outputs_by_matrix_3x4,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared affine transform helper over a 3x4 float matrix rooted at `ECX`. The helper reads three caller-supplied float slots from the output pointers at stack args `+0x04/+0x08/+0x0c`, multiplies them against matrix coefficients `[this+0x08..+0x30]`, adds translation lanes `[this+0x38/+0x3c/+0x40]`, and writes the transformed X, Y, and Z values back in place. Current grounded callers include `0x00569628`, `0x0056a1e2`, and `0x0056a5e5`, so this is the safest current read for the shared 3x4 affine point-transform helper rather than another mode gate.","objdump + caller inspection + local disassembly + affine-transform correlation" +0x00531620,32,global_mode1_gate_query_0x569720_or_return_fallback_0xccba0c,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small mode-gated query wrapper. When `[this+0x04] == 1` and global `0x00ccb9f4` is null, the helper dispatches owner `0x00ccb9fc` through `0x00569720`; otherwise it returns literal pointer `0x00ccba0c`. Current grounded caller is `0x004638f1`, so the safest current read is a gated query with one fixed fallback pointer rather than a named resource resolver.","objdump + caller inspection + local disassembly + mode-gated-query correlation" +0x00531640,129,global_mode1_gate_resolve_callback_string_match_index,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Mode-gated string-match index resolver built on top of `0x005314b0`. Under the same `[this+0x04] == 1 && 0x00ccb9f4 == 0` gate, the helper first queries one current string pointer from owner `0x00ccb9fc` through `0x00569720`, then enumerates callback-selected strings through `0x005314b0(index,1)` and compares them byte-for-byte until it finds an exact match. It returns the zero-based index of the first matching callback string, or the number of earlier nonmatching entries when the callback list is exhausted. Current grounded callers include `0x00464c80`, `0x004fdc10`, `0x004fe1db`, `0x004ff990`, and `0x00521276`, so the safest current read is a gated callback-string index resolver rather than a higher-level selector UI helper.","objdump + caller inspection + local disassembly + callback-selector correlation + string-match correlation" +0x005316d0,48,global_mode1_gate_forward_callback_selected_entry_to_0x569730,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Mode-gated forwarding helper above `0x005314b0`. Under the same `[this+0x04] == 1 && 0x00ccb9f4 == 0` gate, the helper resolves one callback-selected entry pointer through `0x005314b0(arg0,1)`, writes that pointer back to the stack-local argument slot, and then dispatches owner `0x00ccb9fc` through `0x00569730`. Current grounded callers include `0x004fdc38`, `0x004fe21c`, and `0x004ff99c`, so the safest current read is a small callback-entry forwarder rather than a standalone owner method.","objdump + caller inspection + local disassembly + callback-selector correlation + mode-gated-forwarder correlation" +0x00531710,26,global_mode1_gate_forward_three_arg_call_to_0x569660,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny mode-gated forwarding wrapper. When `[this+0x04] == 1` and `0x00ccb9f4` is null, it dispatches global owner `0x00ccb9fc` through `0x00569660`; otherwise it returns immediately. Current grounded callers are `0x0040b8e1` and `0x00464c21`. The current evidence only supports this structural gate-plus-forward description.","objdump + caller inspection + local disassembly + mode-gated-forwarder correlation" +0x00531730,26,global_mode1_gate_forward_six_arg_call_to_0x5696b0,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny mode-gated forwarding wrapper. When `[this+0x04] == 1` and `0x00ccb9f4` is null, it dispatches global owner `0x00ccb9fc` through `0x005696b0`; otherwise it returns immediately. Current grounded callers are `0x0040b8d0` and `0x0043ac4b`. The current evidence only supports this structural gate-plus-forward description.","objdump + caller inspection + local disassembly + mode-gated-forwarder correlation" +0x00531750,26,global_mode1_gate_forward_two_arg_call_to_0x569540,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny mode-gated forwarding wrapper. When `[this+0x04] == 1` and `0x00ccb9f4` is null, it dispatches global owner `0x00ccb9fc` through `0x00569540`; otherwise it returns immediately. Current grounded callers are `0x00464c21`, `0x0048434c`, `0x004fd1a5`, and `0x0055edee`. The current evidence only supports this structural gate-plus-forward description.","objdump + caller inspection + local disassembly + mode-gated-forwarder correlation" +0x00531770,32,global_mode1_gate_query_0x5695d0,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny mode-gated query wrapper. When `[this+0x04] == 1` and `0x00ccb9f4` is null, it dispatches global owner `0x00ccb9fc` through `0x005695d0` and returns that result; otherwise it returns `0`. Current grounded callers are `0x0046388e` and `0x004fdcb5`, so the safest current read is a small gated query rather than a named subsystem predicate.","objdump + caller inspection + local disassembly + mode-gated-query correlation" +0x00531790,27,global_mode1_gate_dispatch_0x56acd0_or_0x56ac50,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny mode-gated selector wrapper spanning global owner `0x00ccb9f8`. When `[this+0x04] == 1` and `0x00ccb9f4` is null, selector arg1 `0` dispatches `0x0056acd0(0x00ccb9f8)`, while selector arg1 `1` forwards arg0 into `0x0056ac50(0x00ccb9f8,arg0)`. Current grounded callers include `0x0043a342` and `0x0055412c`, so the safest current read is a two-way gated dispatch wrapper rather than a named settings setter.","objdump + caller inspection + local disassembly + mode-gated-forwarder correlation" +0x005317b0,63,global_mode1_gate_dispatch_0x569c40_or_0x56ac50,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny mode-gated selector wrapper spanning globals `0x00ccb9fc` and `0x00ccb9f8`. When `[this+0x04] == 1` and `0x00ccb9f4` is null, selector arg1 `0` forces stack arg0 to zero and dispatches owner `0x00ccb9fc` through `0x00569c40`; selector arg1 `1` forwards the original arg0 into `0x0056ac50(0x00ccb9f8,arg0)`. Current grounded callers are broad enough to prove reuse across shell and later world-adjacent paths, including `0x0040b7fc`, `0x0040c889`, `0x0043a50c`, `0x0045e3c2`, `0x004b87fc`, and `0x00554767`, so the safest current read is a gated two-way dispatch wrapper rather than a fully named subsystem method.","objdump + caller inspection + local disassembly + mode-gated-forwarder correlation" +0x00531800,52,global_null_0xccb9f4_guarded_call_0x56ae80_with_reentrancy_counter,map,cdecl,inferred,objdump + caller inspection + local disassembly,1,"Tiny global-owner wrapper over `0x00ccb9f8`. When global `0x00ccb9f4` is null, the helper increments reentrancy counter `0x00ccb9f0`, forwards arg0 into `0x0056ae80(0x00ccb9f8,arg0)`, then decrements the same counter before returning. Current direct caller is `0x00531f69`, so the safest current read is a null-guarded call wrapper with a scoped reentrancy counter rather than a named subsystem service.","objdump + caller inspection + local disassembly + guarded-call correlation" +0x00531840,52,global_null_0xccb9f4_guarded_call_0x569cf0_with_reentrancy_counter,map,cdecl,inferred,objdump + local disassembly,1,"Tiny global-owner wrapper over `0x00ccb9fc`. When global `0x00ccb9f4` is null, the helper increments reentrancy counter `0x00ccb9f0`, forwards arg0 into `0x00569cf0(0x00ccb9fc,arg0)`, then decrements the same counter before returning. Current evidence grounds it structurally as the `0x00ccb9fc` sibling of `0x00531800`.","objdump + local disassembly + guarded-call correlation" +0x00531880,46,global_release_optional_handle_field_0x4c_when_0x624d58_is_1,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small release helper over one optional handle field at `[this+0x4c]`. When that field is not `-1` and global dword `0x00624d58` equals `1`, the helper first dispatches the handle through function pointer `0x005c83b8`, then through `0x005c8450`, and finally resets `[this+0x4c]` to `-1`. Current grounded callers are the local owner-family constructors or service branches `0x00531f69` and `0x00532294`, so the safest current read is an optional-handle release helper rather than a broader object teardown.","objdump + caller inspection + local disassembly + optional-handle correlation" +0x005318b0,10,spin_wait_until_global_reentrancy_counter_0xccb9f0_reaches_zero,map,cdecl,inferred,objdump + caller inspection + local disassembly,1,"Tiny busy-wait helper over global reentrancy counter `0x00ccb9f0`. The function loops until that dword reaches zero, then returns. Current grounded callers are the neighboring owner-family methods in the `0x569a..0x56ae..` strip, so this is the safest current read for a spin-wait on the shared counter rather than a named scheduler primitive.","objdump + caller inspection + local disassembly + reentrancy-counter correlation" +0x005318c0,35,global_dispatch_0x56a970_or_0x569f30_based_on_0xccba04,map,cdecl,inferred,objdump + local disassembly,1,"Tiny global dispatch selector. When global dword `0x00ccba04` is zero, it dispatches owner `0x00ccb9f8` through `0x0056a970`; otherwise it dispatches owner `0x00ccb9fc` through `0x00569f30`. The current evidence grounds it only as a small owner-family selector between the two globals.","objdump + local disassembly + global-owner-selector correlation" +0x005318f0,280,global_owner_family_construct_0xccb9f8_0xccb9fc_and_0xccba00_then_arm_mode1_flag,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Primary constructor or bootstrap path for the neighboring global-owner family. The helper first registers fixed literal `0x005dd240` through the `0x005c847c/0x0056c840/0x005c83b4` strip, allocates `0x30` bytes and constructs owner `0x00ccb9f8` through `0x0056aee0`, then allocates `0x64` bytes and constructs owner `0x00ccb9fc` through `0x0056a6e0`, forwarding the caller-supplied arg0 into `0x005698a0`. It then allocates one `0x108`-byte object into global `0x00ccba00`, zeroes its leading dword, seeds `[obj+0x104] = 1.0f`, and when all three globals are live it sets mode flag `[this+0x04] = 1`. Failure paths release partially constructed owners through `0x0056a740/0x0056af20` and free the backing allocations through `0x0053b080`. Current grounded callers are the neighboring owner-family wrappers `0x00531c3d` and `0x005321be`, so the safest current read is a shared global-owner constructor plus mode-flag arming path rather than a file-specific loader.","objdump + caller inspection + local disassembly + global-owner-family correlation" +0x00531a10,496,global_owner_family_shutdown_with_optional_scalar_fade_and_full_teardown,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Primary shutdown or teardown owner for the same global-owner family. The helper first raises global override gate `0x00ccb9f4`, then, when mode flag `[this+0x04]` is live and caller arg0 is zero, runs a short fade loop over scalar lanes `[0x00ccba00+0x104]` and `[0x00ccb9fc+0x58]` by repeatedly re-entering `0x00557d90(0x00ccba00,...)`, `0x00569ae0(0x00ccb9fc,...)`, and `0x00569ca0(0x00ccb9fc)` with one `0x10`-tick sleep through function pointer `0x005c81f0`. It then spin-waits on `0x005318b0`, dispatches the three global owners through `0x00557cd0`, `0x0056a880`, `0x00569a80`, `0x00569d90`, and `0x0056aeb0`, releases optional handle `[this+0x4c]` through `0x00531880`, tears the globals down through `0x0053b080`, clears mode flag `[this+0x04]`, and finally drops override gate `0x00ccb9f4` back to `0`. Current grounded callers are the local rebuild and destructor side at `0x00531c26`, `0x00532213`, and `0x0053224b`, so this is the safest current read for the full owner-family shutdown with optional scalar fade rather than a one-shot stop helper.","objdump + caller inspection + local disassembly + global-owner-family correlation + fade-loop correlation" +0x00531c00,304,global_owner_family_rebuild_from_string_and_seed_default_scalars,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Shared rebuild owner for the same global-owner family. The helper first force-shuts the current family through `0x00531a10(this,1)`, copies the caller string into a local stack buffer, reconstructs the three global owners through `0x005318f0`, and when mode flag `[this+0x04]` is live seeds the default active state through `0x005696b0(0x00ccb9fc,...)`, `0x00569660(0x00ccb9fc,...)`, `0x00557d90(0x00ccba00, shell_scalar*0x005c9c80)`, `0x0056a8e0(0x00ccb9f8, shell_scalar)`, and `0x00569ae0(0x00ccb9fc, shell_scalar)`. Current grounded callers are controller-side rebuild helpers `0x0053224b`, `0x0053225b`, and the settings-window branch `0x004ffc80`, so this is the safest current read for the shared rebuild-from-string plus default-scalar seed path rather than another small wrapper.","objdump + caller inspection + local disassembly + global-owner-family correlation + rebuild correlation" +0x00531d30,144,global_owner_family_refresh_primary_scalar_and_dispatch_0x557e50,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Active-mode service wrapper over the same owner family. When mode flag `[this+0x04]` is live and override gate `0x00ccb9f4` is clear, the helper refreshes the primary scalar on owner `0x00ccba00` from one shell-side scalar, optionally toggles the neighboring `0x00557c90/0x00557cb0/0x00557cd0` branch when `[0x00ccba00+0x104]` stays positive, and then dispatches `0x00557e50(0x00ccba00,arg0,[0x00ccb9f8+0x2c])`. Current grounded caller is the local callback service strip under `0x00531fd0`, so the safest current read is a primary-scalar refresh plus dispatch wrapper rather than a named backend command.","objdump + caller inspection + local disassembly + scalar-refresh correlation" +0x00531dc0,80,global_owner_family_query_primary_scalars_idle_or_nonpositive,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small active-mode predicate over the same owner family. When mode flag `[this+0x04]` is live and override gate `0x00ccb9f4` is clear, the helper checks readiness-style scalar lanes `[0x00ccb9f8+0x20]` and `[0x00ccb9fc+0x58]` against the local zeroish threshold at `0x005c8598` and returns `1` only on the idle or nonpositive side of that split; otherwise it returns `0`. Current grounded caller is the local settings or service strip at `0x004ffcf0`, so the safest current read is a shared dual-scalar idle predicate rather than a named backend-health query.","objdump + caller inspection + local disassembly + scalar-idle correlation" +0x00531e50,64,shell_audio_service_dispatch_named_string_event_if_ready,shell,thiscall,inferred,objdump + caller correlation + local disassembly,3,"String-driven sibling of `shell_audio_service_apply_indexed_feedback_event_if_ready` `0x00531e10`. The helper only dispatches when service mode dword `[this+0x04]` equals `1`, override gate `0x00ccb9f4` is clear, the secondary readiness scalar at `[0x00ccb9fc+0x58]` passes the local positive check, and the caller string is nonempty; on the ready path it tail-jumps into `0x0056a520`. Current grounded caller is `placed_structure_specialization_service_timed_anim_light_and_random_sound_variants` `0x0045baf0`, which uses this as the final named-event sink for the `rnd_%1_%2.wav` and anim or light family.","objdump + caller correlation + local disassembly + readiness-gate correlation + named-event correlation" +0x00531e90,64,global_owner_family_stage_16_dword_payload_block_and_mark_ccb9fc_mode2,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Active-mode staging helper over the same owner family. When mode flag `[this+0x04]` is live and override gate `0x00ccb9f4` is clear, the helper marks byte `[this+0x48] = 1`, copies one caller-supplied 16-dword block into local storage `[this+0x08..+0x44]`, and then forces mode dword `[0x00ccb9fc+0x60] = 2`. Current grounded caller is the local controller-side path around `0x005322c0`, so the safest current read is a staged payload-block copy plus mode-2 mark rather than a named decode routine.","objdump + caller inspection + local disassembly + staged-payload correlation" +0x00531ed0,32,global_owner_family_query_ccb9f8_field_0x2c_when_active,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Tiny active-mode query wrapper. When mode flag `[this+0x04]` is live and override gate `0x00ccb9f4` is clear, the helper returns dword `[0x00ccb9f8+0x2c]`; otherwise it returns `0`. Current grounded caller is the neighboring controller family at `0x005322b2`, so the safest current read is the shared `0x00ccb9f8+0x2c` query wrapper rather than a named selector.","objdump + caller inspection + local disassembly + shared-field-query correlation" +0x00531ef0,80,global_owner_family_lookup_key_in_selected_hash_root,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Active-mode selected-hash lookup helper over the same owner family. When mode flag `[this+0x04]` is live and override gate `0x00ccb9f4` is clear, selector arg1 `0` probes key arg0 through `0x0053dae0` against hash root `[0x00ccb9f8+0x0c]`, while selector arg1 `1` probes the sibling hash root `[0x00ccb9fc+0x14]`. Current grounded callers include settings-window and neighboring shell branches at `0x004ffcdc`, `0x004ffe51`, and `0x004ffecb`, so the safest current read is a selected hash-root key lookup rather than a fully named registry query.","objdump + caller inspection + local disassembly + hash-root correlation" +0x00531f40,80,global_owner_family_service_ccb9f8_ccb9fc_and_clear_staged_flag,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Active-mode service helper over the same owner family. The helper optionally releases handle `[this+0x4c]` through `0x00531880`, dispatches owner `0x00ccb9f8` through `0x0056ae30`, dispatches owner `0x00ccb9fc` through `0x00569ca0`, and finally clears staged flag byte `[this+0x48]`. Current grounded caller is the timed transition path `0x005322ed`, so the safest current read is a small paired-owner service pass plus staged-flag clear rather than another constructor or query.","objdump + caller inspection + local disassembly + paired-owner-service correlation" +0x00531f90,64,global_owner_family_register_selected_guarded_callback_0x531800_or_0x531840,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small callback-registration selector over the same owner family. When mode flag `[this+0x04]` is live and override gate `0x00ccb9f4` is clear, selector arg1 `0` installs callback target `0x00531800` through function pointer `0x005c83a8`, while selector arg1 `1` installs sibling callback target `0x00531840` through `0x005c83a4`. Current grounded caller is the controller-side bind path `0x005322d8`, so the safest current read is a selected guarded-callback registration helper rather than a broader scheduler primitive.","objdump + caller inspection + local disassembly + callback-registration correlation" +0x00531fd0,384,global_owner_family_timed_primary_scalar_transition_service,map,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Timed transition service over the same owner family. When override gate `0x00ccb9f4` is clear, the helper increments reentrancy counter `0x00ccb9f0`, branches on selector arg0, and then updates the primary scalar owner `0x00ccba00` from shell-derived values through `0x00557d90`, `0x00557c90`, `0x00557cb0`, and `0x00557cd0`, coordinating the transition with globals `0x00624d58` and `0x00624d60`. One branch seeds `0x00624d60` from the current owner scalar and another forces `0x00624d58 = 1` plus `0x00624d60 = -1.0f` before returning. All exits decrement the same reentrancy counter. Current grounded caller is the controller-side bind helper `0x005322d8`, so the safest current read is a timed primary-scalar transition service rather than a narrow audio-only callback.","objdump + caller inspection + local disassembly + scalar-transition correlation + reentrancy-counter correlation" +0x00532150,176,global_owner_family_controller_construct_and_optionally_bootstrap_selected_entry,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Constructor for the local controller object that fronts the same global-owner family. The helper zeroes the controller block, seeds multiple default float lanes to `1.0f`, clears or presets local flags and handles, and when caller arg0 is not `-1` resolves one callback-selected entry through `0x005314b0` before forwarding it into `0x005318f0`. On successful bootstrap it also allocates one `0x44`-byte local payload into `[this+0x00]` and initializes that payload through `0x00564570`. Current grounded caller is the broader controller allocation path `0x00521254`, so the safest current read is a local controller constructor plus optional selected-entry bootstrap rather than the global owner constructor itself.","objdump + caller inspection + local disassembly + controller-constructor correlation" +0x00532200,48,global_owner_family_controller_shutdown_and_release_payload,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Destructor-side companion to `global_owner_family_controller_construct_and_optionally_bootstrap_selected_entry` `0x00532150`. When controller mode flag `[this+0x04]` is live, the helper first shuts the shared owner family down through `0x00531a10(this,0)`, then releases optional local payload `[this+0x00]` through `0x00564560` and `0x0053b080`. Current grounded caller is the local lifetime strip under `0x005212a6`, so the safest current read is controller shutdown plus payload release rather than a global-owner reset.","objdump + caller inspection + local disassembly + controller-destructor correlation" +0x00532230,48,global_owner_family_controller_rebuild_from_selected_callback_entry,map,thiscall,inferred,objdump + caller inspection + local disassembly,1,"Small controller-side rebuild wrapper over the same owner family. When global owner `0x00ccb9fc` exists, the helper resolves one callback-selected entry through `0x005314b0` and forwards that string into `0x00531c00(this,...)`. Current grounded callers are settings-window backend-selection branches at `0x004fefb0` and the neighboring controller strip, so the safest current read is a rebuild-from-selected-entry helper rather than another query.","objdump + caller inspection + local disassembly + controller-rebuild correlation" +0x00532260,176,global_owner_family_controller_rebind_primary_handle_and_register_transition_callback,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Controller-side bind or rebinding owner for the same global-owner family. When controller mode flag `[this+0x04]` is live and override gate `0x00ccb9f4` is clear, the helper optionally releases existing handle `[this+0x4c]` through `0x00531880`, registers transition callback `0x00531fd0` through function pointer `0x005c83f4`, stores the returned handle in `[this+0x4c]`, seeds selector `[this+0x50]`, resets global float `0x00624d60 = -1.0f`, and then drives one branch-specific initialization strip through `0x00557d90` plus function pointers `0x005c8400`, `0x005c83c8`, and `0x005c83a0` with mode selectors `1`, `2`, or `3`. Current grounded callers include shell-side branches at `0x0048314c`, `0x00483ffc`, `0x0048431f`, and `0x00517444`, so the safest current read is a primary-handle rebind plus transition-callback registration owner rather than a one-shot play command.","objdump + caller inspection + local disassembly + controller-bind correlation + transition-callback correlation" 0x00533ba0,39,shell_grid_get_nearby_presentation_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the nearby-presentation layer rooted at [this+0x1671]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1671].,ghidra + rizin + llvm-objdump +0x00533bc0,11,shell_nearby_presentation_queue_push_back_payload,bootstrap,thiscall,inferred,objdump + local disassembly + intrusive-queue correlation,2,"Tiny queue append helper over the shell nearby-presentation queue root `[this+0x166d]`. The helper forwards the caller payload into `intrusive_queue_push_back` `0x00556e10`.","objdump + local disassembly + intrusive-queue correlation" +0x00533bd0,11,shell_nearby_presentation_queue_remove_payload,bootstrap,thiscall,inferred,objdump + local disassembly + intrusive-queue correlation,2,"Tiny queue removal helper over the shell nearby-presentation queue root `[this+0x166d]`. The helper forwards the caller payload into `0x00556e80` on the same intrusive queue root.","objdump + local disassembly + intrusive-queue correlation" +0x00533be0,7,shell_query_nearby_presentation_queue_root,bootstrap,thiscall,inferred,objdump + local disassembly + field correlation,2,"Tiny getter for the shell nearby-presentation intrusive queue root `[this+0x166d]`.","objdump + local disassembly + field correlation" +0x00533bf0,37,shell_nearby_presentation_cell_queue_push_back_payload,bootstrap,thiscall,inferred,objdump + local disassembly + intrusive-queue correlation,2,"Cell-addressed append helper over the nearby-presentation cell table `[this+0x1671]`. The helper resolves one 16x16 tile cell from caller coordinates using width `[this+0x15d9]` and then pushes the payload into that cell's intrusive queue through `intrusive_queue_push_back` `0x00556e10`. Current grounded callers include the shared runtime-object world-binding paths `0x0052fdc0` and `0x00530720`.","objdump + local disassembly + intrusive-queue correlation + cell-table correlation" +0x00533c20,37,shell_nearby_presentation_cell_queue_remove_payload,bootstrap,thiscall,inferred,objdump + local disassembly + intrusive-queue correlation,2,"Cell-addressed removal helper over the nearby-presentation cell table `[this+0x1671]`. The helper resolves one 16x16 tile cell from caller coordinates using width `[this+0x15d9]` and removes the payload from that cell's intrusive queue through `0x00556e80`. Current grounded callers include the shared runtime-object world-binding paths `0x0052ef70`, `0x0052fdc0`, and `0x00530720`.","objdump + local disassembly + intrusive-queue correlation + cell-table correlation" +0x00533c50,30,world_region_border_overlay_get_chunk_queue_by_cell,bootstrap,thiscall,inferred,objdump + local disassembly + field correlation,2,"Tiny cell-addressed getter over the region-border overlay chunk table `[this+0x1679]`. The helper resolves one 16x16 chunk slot from caller coordinates using width `[this+0x15d9]` and returns that slot pointer.","objdump + local disassembly + field correlation + coarse-chunk correlation" +0x00533c70,37,world_region_border_overlay_chunk_queue_push_back_payload,bootstrap,thiscall,inferred,objdump + local disassembly + intrusive-queue correlation,2,"Cell-addressed append helper over the region-border overlay chunk table `[this+0x1679]`. The helper resolves one 16x16 chunk slot and forwards the caller payload into `intrusive_queue_push_back` `0x00556e10`.","objdump + local disassembly + intrusive-queue correlation + coarse-chunk correlation" +0x00533ca0,37,world_region_border_overlay_chunk_queue_remove_payload,bootstrap,thiscall,inferred,objdump + local disassembly + intrusive-queue correlation,2,"Cell-addressed removal helper over the region-border overlay chunk table `[this+0x1679]`. The helper resolves one 16x16 chunk slot and forwards the caller payload into `0x00556e80`.","objdump + local disassembly + intrusive-queue correlation + coarse-chunk correlation" 0x00533cd0,39,shell_grid_get_static_vertex24_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the fixed-geometry vertex24 layer rooted at [this+0x167d]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x167d].,ghidra + rizin + llvm-objdump 0x00533db0,30,shell_grid_get_geographic_label_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the geographic-label layer rooted at [this+0x1675]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1675].,ghidra + rizin + llvm-objdump +0x00533dd0,37,shell_geographic_label_cell_queue_push_back_payload,bootstrap,thiscall,inferred,objdump + local disassembly + intrusive-queue correlation,2,"Cell-addressed append helper over the geographic-label cell table `[this+0x1675]`. The helper resolves one 16x16 tile cell from caller coordinates and forwards the payload into `intrusive_queue_push_back` `0x00556e10`.","objdump + local disassembly + intrusive-queue correlation + cell-table correlation" +0x00533e00,37,shell_geographic_label_cell_queue_remove_payload,bootstrap,thiscall,inferred,objdump + local disassembly + intrusive-queue correlation,2,"Cell-addressed removal helper over the geographic-label cell table `[this+0x1675]`. The helper resolves one 16x16 tile cell from caller coordinates and forwards the payload into `0x00556e80`.","objdump + local disassembly + intrusive-queue correlation + cell-table correlation" 0x00533e30,32,shell_grid_get_animated_quad_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the animated-quad presentation layer rooted at [this+0x1681]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1681].,ghidra + rizin + llvm-objdump 0x00533e50,32,shell_grid_get_ranked_overlay_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the ranked secondary overlay layer rooted at [this+0x1685]. The helper uses the same 16x16 tile addressing and grid width field at [this+0x15d9] as the other shell cell-grid accessors and currently feeds 0x0052a2f0.,ghidra + rizin + llvm-objdump 0x00533e70,168,world_secondary_overlay_release_coarse_chunks_in_rect,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Rectangle-wide coarse-chunk release helper over the secondary overlay table rooted at `[this+0x1685]`. The helper clamps the caller-supplied world-grid rectangle to the live bundle dimensions `[this+0x15d9/+0x15d5]`, converts the surviving bounds to 16x16 chunk coordinates, walks every chunk slot in that coarse range, and when a chunk pointer is present releases or clears it through `0x0056b770(this)`. Current grounded callers include the late world-entry tail at `0x00444b48`, the secondary-grid overlay-cache service `world_service_secondary_grid_marked_cell_overlay_cache` `0x0044c670`, one neighboring world-side refresh branch at `0x0044d469`, and the shell-side world-mode branch at `0x00484f51`, so this is the safest current read for the shared coarse secondary-overlay rectangle reset helper rather than a one-shot startup scrub.","objdump + caller inspection + field correlation + coarse-chunk correlation + secondary-overlay correlation" 0x00533fe0,89,world_secondary_overlay_write_local_chunk_cell_value,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Small write-side companion to the secondary overlay coarse-chunk family rooted at `[this+0x1685]`. The helper resolves the caller-supplied world-grid cell into one 16x16 chunk slot using width field `[this+0x15d9]`, keeps only the low local cell offsets inside that chunk, and when the chunk object exists delegates the local write or clear through `0x0056b000(chunk, world, x_local, y_local, arg2)`. Current grounded callers include the post-load `319` cleanup sweep through `world_run_post_load_generation_pipeline` `0x004384d0`, neighboring placed-structure or world-overlay branches at `0x00414f33`, `0x004158a6`, `0x0041ff3c`, and `0x00454ede`, and one later world-entry-side caller at `0x00444712`, so this is the safest current read for the shared local secondary-overlay chunk-cell write helper rather than a broad chunk reset or allocator.","objdump + caller inspection + field correlation + coarse-chunk correlation + write-side companion correlation" 0x00534160,259,world_secondary_overlay_ensure_coarse_chunk_and_seed_local_marks,map,thiscall,inferred,objdump + caller inspection + field correlation,3,"Shared coarse-chunk helper beneath the secondary overlay family rooted at `[this+0x1685]`. The helper converts the caller-supplied world-grid coordinates into one 16x16 chunk index using width field `[this+0x15d9]`, lazily allocates one `0x54`-byte chunk object into `[this+0x1685]` through `0x0053b070` when that slot is empty, initializes the new chunk from chunk-space coordinates through `0x0056af70`, and then re-enters `0x0056b580` up to the caller-supplied step count capped at `6` using the low-bit local offsets plus two extra caller parameters. Current grounded callers include the late secondary-grid overlay service `world_service_secondary_grid_marked_cell_overlay_cache` `0x0044c670`, the neighboring startup-side branch at `0x00447faf`, one earlier placed-structure overlay builder at `0x004157d2`, and one world-side surface branch at `0x004545b2`, so this is the safest current read for the shared coarse secondary-overlay chunk ensure-and-seed helper rather than a one-shot startup allocator.","objdump + caller inspection + field correlation + coarse-chunk correlation + secondary-overlay correlation" +0x005339a0,144,math_build_plane_from_three_xyz_points_store_abc_and_negd,bootstrap,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Reusable three-point plane-construction helper. The routine treats the first nine float arguments as three XYZ points, computes the cross product of the two edge vectors rooted at the first point, stores the resulting plane coefficients `A`, `B`, and `C` through the caller pointers in `ECX`, `EDX`, and the fourth stack pointer, and then stores `-(A*x0 + B*y0 + C*z0)` through the final out-pointer. Current grounded callers are the neighboring world-presentation geometry owners at `0x005346b8` and `0x005346ff`, which immediately package the four outputs as one local plane record, so the safest current read is a shared plane-equation builder rather than a presentation-only scoring helper.","objdump + caller inspection + local disassembly + plane-equation correlation" +0x00533a30,176,math_solve_plane_y_from_three_xyz_points_and_xz,bootstrap,cdecl,inferred,objdump + caller inspection + local disassembly,3,"Reusable plane-sampling helper over the same three-point XYZ input family as `0x005339a0`. The routine rebuilds the plane coefficients from the first three points, derives the plane constant, substitutes the caller-supplied query `x` and `z` arguments, divides by coefficient `B`, and returns the solved height on the x87 stack. Current grounded callers are the neighboring world-presentation geometry owners at `0x0053458b` and `0x005345af`, which use it as the direct height interpolation step over one local three-sample patch, so the safest current read is a shared plane-height solver rather than a broader world-score helper.","objdump + caller inspection + local disassembly + plane-height correlation" +0x00534910,8,shell_world_presentation_query_staging_flag,bootstrap,thiscall,inferred,objdump + caller inspection + field correlation,2,"Tiny flag getter over the shared shell-side world-presentation bundle. The helper returns staging byte `[this+0x1588]` unchanged. Current grounded caller is the broad derived-surface rebuild owner `world_rebuild_secondary_raster_derived_surface_and_companion_planes_in_rect` `0x0044e940`, which uses it only as the fast staging-presence test before sampling the live staging buffer or rebuilding the rectangle.","objdump + caller inspection + field correlation + staged-surface correlation" +0x00534920,8,shell_world_presentation_query_staging_buffer_root,bootstrap,thiscall,inferred,objdump + caller inspection + field correlation,2,"Tiny pointer getter over the shared shell-side world-presentation bundle. The helper returns the live staging dword buffer root `[this+0x1584]` unchanged. Current grounded caller is `world_rebuild_secondary_raster_derived_surface_and_companion_planes_in_rect` `0x0044e940`, which samples that root only after the neighboring staging-flag getter `0x00534910` succeeds.","objdump + caller inspection + field correlation + staged-surface correlation" +0x00534930,448,shell_world_presentation_stage_overlay_rect_from_normalized_bounds,bootstrap,thiscall,inferred,objdump + caller inspection + local disassembly + field correlation,3,"Shared rect-staging owner over the shell-side world-presentation bundle. When staging flag `[this+0x1588]` is clear, the helper quantizes the caller-supplied normalized bounds into scaled surface coordinates using width or height fields `[this+0x157c/+0x1580]`, stores the surviving rectangle into `[this+0x1589..+0x1595]`, allocates one dword staging buffer at `[this+0x1584]`, marks staging byte `[this+0x1588] = 1`, and copies the current per-strip surface rows through lazily materialized strip objects from `[this+0x08..]` into that buffer. It optionally returns the staged rect origin through two out-pointers. Current grounded callers include earlier overlay builders at `0x00418032`, startup or world-entry siblings at `0x0044664c` and `0x00447428`, the late secondary-grid overlay path at `0x0044c9e6`, the broad derived-surface rebuild owner at `0x0044ea0a`, the transport or pricing preview builder at `0x0044f861`, the shell-side world branch at `0x0047a184`, and one terrain-preview caller at `0x004f7ee4`, so this is the safest current read for the shared staged-overlay rect capture helper rather than a generic allocator or the later publish step.","objdump + caller inspection + local disassembly + field correlation + staged-surface correlation + normalized-bounds quantization" 0x00534af0,350,shell_world_presentation_publish_staged_overlay_surfaces_and_release_buffer,bootstrap,thiscall,inferred,objdump + caller inspection + field correlation,3,"Shared publish-or-teardown helper over the shell-side world-presentation bundle. The helper first requires staging flag byte `[this+0x1588]`. In normal publish mode `arg0=0` it walks the staged dword buffer at `[this+0x1584]` across the rectangle `[this+0x1589..+0x1591] x [this+0x158d..+0x1595]`, lazily materializes up to `0xff` temporary strip or surface objects through `0x00541970` using the per-slot roots at `[this+0x08..]`, copies staged row dwords into those objects, and then finalizes each populated slot through `0x005438d0`. In teardown-only mode `arg0!=0` it skips the publish sweep and goes straight to cleanup. Both paths then clear `[this+0x1588]`, free the staging buffer at `[this+0x1584]`, and null that pointer. Current grounded callers include the late secondary-grid overlay path at `0x0044cdff`, startup-side and neighboring world branches at `0x00446691`, `0x00447754`, `0x0044f63b`, and `0x0044fada`, earlier overlay builders at `0x004180a8`, `0x004184bf`, and `0x00418584`, plus shell-side callers at `0x0047b061` and `0x004f5f74`, so this is the safest current read for the shared staged-overlay surface publish-and-release helper rather than a world-only renderer or a pure destructor.","objdump + caller inspection + field correlation + staged-surface correlation + publish-vs-teardown correlation" 0x00534c50,32,shell_world_presentation_query_scaled_surface_dimensions,bootstrap,thiscall,inferred,objdump + caller inspection + field correlation,3,"Tiny dimension query over the shared shell-side world-presentation bundle. The helper reads dwords `[this+0x157c]` and `[this+0x1580]`, shifts both left by two, and writes the results to the caller-supplied out-pointers as one scaled width-height pair. Current grounded callers first resolve the live presentation object through the shell owner at `0x006d4024` or the neighboring bundle resolver and then use these scaled dimensions in overlay, bounds, or allocation setup, including the late secondary-grid overlay path at `0x0044ca3e`, neighboring world-side branches at `0x0044ea34` and `0x0044f876`, earlier placed-structure overlay builders at `0x0041538a` and `0x00417fad`, and one shell-side allocator at `0x004f7f0a`, so this is the safest current read for the shared scaled surface-dimension query rather than a world-only or startup-only helper.","objdump + caller inspection + field correlation + shell-world-bundle correlation" 0x00534e10,64,world_secondary_raster_query_cell_class_in_set_1_3_4_5,map,thiscall,inferred,objdump + caller inspection + raster-cell correlation,3,"Tiny reusable predicate over one 3-byte cell record in the secondary raster family rooted at `[this+0x165d]` with row stride `[this+0x15dd]`. The helper resolves the requested cell from caller-supplied world-grid coordinates, masks the low three class bits from the first byte, and returns `1` when that class is `1`, `3`, `4`, or `5`, else `0`. Current grounded callers span many world-side placement, overlay, and scan branches including `placed_structure_validate_projected_candidate_placement` `0x004197e0`, `placed_structure_build_projected_runtime_scratch_from_candidate_and_coords` `0x00416ec0`, the late world-entry tail around `0x004481a6`, and one secondary-grid sibling under `0x0044c450`, so this is the safest current read for the shared secondary-raster class-set predicate rather than a startup-only helper.","objdump + caller inspection + raster-cell correlation + late-world-tail correlation" +0x00534f60,28,world_presentation_base_init_and_clear_surface_owner_field_0x154c,map,thiscall,inferred,objdump + caller inspection + local disassembly,2,"Small base initializer for the world-presentation owner family. The helper installs vtable `0x005dd25c`, clears dword `[this+0x154c]`, and then re-enters the lower shared initializer `0x00532590` before returning `this`. Current grounded callers are `world_construct_root_and_load_bundle_payload_thunk` `0x0044e910` and the neighboring load-side branch at `0x0044cf73`, so this is the safest current read for the immediate presentation-owner base init rather than a broader world-root constructor.","objdump + caller inspection + local disassembly + world-presentation-family correlation" +0x00534f80,50,world_presentation_release_transient_surface_handle_0x478_and_clear_flag_0x159b,map,thiscall,inferred,objdump + caller inspection + field correlation,2,"Small release helper over one transient surface-handle field in the world-presentation owner family. When pointer `[this+0x478]` is non-null the helper finalizes it through `0x00542c90`, frees it through `0x0053b080`, clears `[this+0x478]`, and then clears byte `[this+0x159b]`. Current grounded callers include the world-side status or action strip around `0x00452fa5`, `0x0045339d`, `0x004535f8`, and `0x00453617`, plus one neighboring world branch at `0x0045074f`, so the safest current read is a focused transient-surface release helper rather than a full presentation teardown.","objdump + caller inspection + field correlation + transient-surface correlation" 0x00534e50,50,world_secondary_raster_query_cell_class_in_set_1_4,map,thiscall,inferred,objdump + caller inspection + raster-cell correlation,3,"Tiny reusable companion predicate over the same 3-byte secondary-raster cell family rooted at `[this+0x165d]` with row stride `[this+0x15dd]`. The helper resolves one caller-selected world-grid cell, masks the low three class bits from the first byte, and returns `1` only when that class is `1` or `4`, else `0`. Current grounded callers include the transportation or pricing grid pass `world_compute_transport_and_pricing_grid` `0x0044fb70`, the live-world `.smp` serializer `world_runtime_serialize_smp_bundle` `0x00446240`, and several neighboring world-side scan or presentation branches at `0x00448c2f`, `0x00449d46`, `0x0044ec29`, `0x00451016`, and `0x0047a551`, which makes this the safest current read for the shared secondary-raster class-subset predicate rather than a transport-only helper.","objdump + caller inspection + raster-cell correlation + transport-grid correlation + serializer correlation" 0x00534e90,48,world_secondary_raster_query_cell_marked_bit,map,thiscall,inferred,objdump + caller inspection + raster-cell correlation,3,"Tiny reusable bit query over the same 3-byte secondary-raster cell family rooted at `[this+0x165d]` with row stride `[this+0x15dd]`. The helper resolves one cell from caller-supplied world-grid coordinates, reads the 16-bit companion word from that cell record, and returns bit `9` as a boolean marked-state flag. Current grounded callers include the secondary-grid overlay-cache service `world_service_secondary_grid_marked_cell_overlay_cache` `0x0044c670`, neighboring world scan or mutation branches at `0x004499a6`, `0x00449bdf`, and `0x00450f69`, plus one shell-side or editor-adjacent caller at `0x004a0e72`, which makes this the safest current name for the shared secondary-raster marked-bit predicate.","objdump + caller inspection + raster-cell correlation + secondary-grid overlay correlation" 0x00534ec0,56,world_secondary_raster_query_cell_class_in_set_2_4_5,map,thiscall,inferred,objdump + caller inspection + raster-cell correlation,3,"Tiny reusable class-subset predicate over the same 3-byte secondary-raster family rooted at `[this+0x165d]` with row stride `[this+0x15dd]`. The helper resolves one caller-selected world-grid cell, masks the low three class bits from the first byte, and returns `1` only when that class is `2`, `4`, or `5`, else `0`. Current grounded callers include neighboring world-side setup, scan, and presentation branches around `0x00446418`, `0x00449c88`, `0x0044bdfc`, `0x0044dd78`, `0x0044ec51`, `0x0044f30e`, `0x0044f445`, `0x00450f7a`, and `0x004fa86c`, plus serializer-adjacent paths under `0x00446240`, so this is the safest current read for the shared secondary-raster class-subset predicate rather than a more player-facing terrain label.","objdump + caller inspection + raster-cell correlation + serializer correlation" @@ -1047,6 +1850,11 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0053a960,723,shell_emit_geographic_label_text_span,bootstrap,thiscall,inferred,ghidra-headless,4,Builds and emits one geographic-label text span for the current cell item. The helper calls the item vtable at +0x10 to materialize a null-terminated display string up to 0x12c bytes computes placement from item float fields and shell service state checks visibility through the shell bundle and forwards the resolved text payload into the presentation path through 0x005519f0. The item family aligns with gpdLabelDB and 2DLabel.imb rather than the parallel city assets.,ghidra + rizin + llvm-objdump 0x00543f10,853,layout_state_bind_presentation_asset_bundle,bootstrap,thiscall,inferred,ghidra-headless,4,Initial bind-time asset loader for the layout state's presentation node at [this+0x25df]; pulls a fixed presentation bundle through the node vtable at +0x5c and +0x60 including standalone assets stored around 0x2643 0x2647 0x264b 0x264f 0x2653 0x265b 0x265f and 0x2663 plus a 64-entry asset bank at 0x31ab while advancing an internal asset-offset cursor at [this+0x2543].,ghidra + rizin 0x00554830,142,attachment_object_init_named_asset,bootstrap,thiscall,inferred,ghidra-headless,3,Initializes one named attachment object from a caller-supplied asset string and placement parameters. The helper copies the asset name into the local object buffer at [this+0x10] stores attachment selectors at [this+0x130] and [this+0x138] optionally derives a cached scale pair at [this+0x120] and [this+0x124] and then finalizes object state through 0x005545d0.,ghidra + rizin + llvm-objdump +0x00531640,129,shell_audio_service_query_selected_backend_index_by_name,shell,thiscall,inferred,objdump + settings-window caller correlation,4,"Queries the currently selected audio backend index from the shell audio service. When service mode dword `[this+0x04]` is `1` and the override gate at `0x00ccb9f4` is clear, the helper pulls the current backend-name stem through `0x569720` on service object `0x00ccb9fc`, iterates candidate names through `0x005314b0`, and returns the first matching backend index. Otherwise it falls back to `0`. Current grounded callers are the `Sound` page refresh and callback paths, which use it to mirror the live backend selector into control `0x7551`.","objdump + settings-window caller correlation + backend-name-match correlation" +0x005316d0,47,shell_audio_service_query_backend_available_flag_by_index,shell,thiscall,inferred,objdump + settings-window caller correlation,4,"Returns one availability flag for the requested audio backend index. When service mode dword `[this+0x04]` is `1` and the override gate at `0x00ccb9f4` is clear, the helper resolves the backend-name pointer through `0x005314b0(index)` and forwards it into `0x569730` on service object `0x00ccb9fc`; otherwise it returns `0`. Current grounded callers are the `Sound` page refresh and callback paths, which use the returned flag to republish control `0x7550`.","objdump + settings-window caller correlation + backend-availability correlation" +0x00531e10,48,shell_audio_service_apply_indexed_feedback_event_if_ready,shell,thiscall,inferred,objdump + caller correlation + local disassembly,4,"Small shell-audio-service sink beneath the indexed feedback-nudge helper `0x0045ea20`. The helper only dispatches when service mode dword `[this+0x04]` equals `1`, override gate `0x00ccb9f4` is clear, and the service-side readiness scalar at `[0x00ccb9f8+0x20]` passes the local positive check; on the ready path it tail-jumps into `0x0056ad20` with the caller's table-driven event pair and scalar, otherwise it returns `0`. Current grounded direct caller is `shell_emit_indexed_audio_feedback_nudge_if_live` `0x0045ea20`, which keeps this safely on the shell-audio feedback side rather than the broader backend-selection family.","objdump + caller correlation + local disassembly + readiness-gate correlation" +0x0053ef60,4,graphics_backend_query_primary_status_dword_18,shell,thiscall,inferred,objdump + settings-window caller correlation,3,"Returns graphics-backend dword `[this+0x18]` unchanged. Current grounded callers are the `Graphics` page refresh and graphics-selector callback strip, which pair this value with `graphics_backend_query_both_status_slots_clear` `0x0053ef70` when deciding how controls `0x757c` and `0x759a` should be republished.","objdump + settings-window caller correlation" +0x0053ef70,23,graphics_backend_query_both_status_slots_clear,shell,thiscall,inferred,objdump + settings-window caller correlation,4,"Returns `1` only when both graphics-backend dword `[this+0x18]` and dword `[this+0x14]` are zero; otherwise returns `0`. Current grounded callers are the `Graphics` page refresh and the graphics-selector callback strip, which use this test as the fallback branch when republishing controls `0x757c` and `0x759a`.","objdump + settings-window caller correlation + status-slot correlation" 0x005455e0,224,layout_state_set_slot_triplet_lo,bootstrap,thiscall,inferred,ghidra-headless,4,Updates the first three cached per-slot presentation scalars in the 24-byte slot table at [this+0x2597+slot*24]. In notify mode it compares against the cached values and forwards only changed fields into the bound presentation node through vtable slot +0xfc with subproperty ids 1 through 3.,ghidra + rizin + llvm-objdump 0x005456d0,240,layout_state_set_slot_triplet_hi,bootstrap,thiscall,inferred,ghidra-headless,4,Updates the second three cached per-slot presentation scalars in the same 24-byte slot table at [this+0x2597+slot*24]. In notify mode it compares against the cached values and forwards only changed fields into the bound presentation node through vtable slot +0xfc with subproperty ids 4 through 6.,ghidra + rizin + llvm-objdump 0x005458f0,169,layout_state_read_segment_record_window,bootstrap,thiscall,inferred,ghidra-headless,4,Gates the 32-byte segment-record table at [this+0x2643]; queries record bounds then copies a start-to-end or wrapped window into scratch storage at [this+0x2657] through vtable slot +0x2c while toggling byte flag [this+0x254e]. The downstream shell path treats each 0x20-byte record as two vec3 blocks plus two trailing scalars.,ghidra + rizin @@ -1068,10 +1876,21 @@ 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 +0x0054e880,305,shell_input_service_pointer_proximity_event_record_and_queue_followon,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Processes one queued 12-dword shell-input event record from the ring rooted at `[this+0x128]` as a pointer-proximity or timeout update. The helper classifies input record types `6`, `8`, and `10` into one of three local slot bands under `[this+0x104]`, `[this+0x110]`, and `[this+0x11c]`, measures the absolute pointer delta against the controller-selected view size from `[0x006d4024+0x34 + selector*0x15]`, compares that against the shared radius threshold, and either snapshots the current pointer coordinates plus deadline tick into the chosen slot or clones the record into a follow-on event with rewritten type `0x1e`, `0x20`, or `0x22` before requeueing it through `0x0054e9c0`. Current grounded callers are the queue wrappers `0x0054e9c0`, `0x0054f5b0`, and `0x0054eb10`, so this is the safest current read for the pointer-proximity event service owner rather than another generic ring-buffer helper.","objdump + caller inspection + local disassembly + event-ring correlation + pointer-proximity correlation" +0x0054e9c0,79,shell_input_enqueue_event_record_and_run_pointer_followon,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Small queue wrapper over the shell-input event ring at `[this+0x128]`. The helper appends one caller-supplied 12-dword record into the ring, rewrites ring index `[this+0xa88]` from `0x32` back to `0x31` when needed, increments that index, and immediately tails into `0x0054e880` on the same record. Current grounded callers are `shell_input_apply_window_key_transition` `0x0054f290`, `shell_input_enqueue_window_event_record_and_signal_dispatch` `0x0054f5b0`, and `shell_input_handle_window_command_and_toggle_messages` `0x0054eb10`.","objdump + caller inspection + local disassembly + event-ring correlation" +0x0054ea20,229,shell_input_pop_next_event_record_with_type2_coalescing,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Dequeues the next 12-dword shell-input event record from the same ring at `[this+0x128]` into one caller output buffer. When more than one event is pending and nested dispatch latch `[this+0xa90]` is clear, the helper compacts the ring forward, decrements the event count, and performs one special coalescing pass for adjacent type-`2` records when no key-state byte at `[this+0x100]` is active. Current grounded caller is `shell_input_snapshot_dispatch_state` `0x0054f4d0`, which uses this helper to pull one filtered dispatch record at a time.","objdump + caller inspection + local disassembly + event-ring correlation + coalescing correlation" +0x0054eb10,376,shell_input_handle_window_command_and_toggle_messages,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Processes one shell window-command or toggle-style input message into the shell-input ring. The helper tracks the last packed command or coordinate tuple under `[this+0xa94/+0xa98/+0xa9c]`, iterates eight local branch families, toggles selected state bits in `[this+0xa8c]`, synthesizes 12-dword records with types such as `1`, `2`, `5`, `6`, `7`, `8`, `9`, `10`, and `11`, and enqueues those records through `0x0054e880`. Current grounded caller is the `WM_COMMAND` branch in `shell_controller_window_message_dispatch` `0x0054e3a0`, so this is the safest current read for the shell-input command or toggle message owner rather than a generic control callback.","objdump + caller inspection + local disassembly + event-ring correlation + command-message correlation" +0x0054ee50,544,shell_input_handle_window_mouse_message_and_enqueue_events,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Primary shell mouse-message handler for the `0x0200..0x0208` window-message family. The helper first deduplicates repeated `WM_MOUSEMOVE` coordinates against globals `0x0062545c/0x00625460`, then routes the live message through the shared shell-input command or toggle worker `0x0054eb10` and the surrounding pointer-state branches. Current evidence grounds this as the mouse-message ingress owner beneath `shell_controller_window_message_dispatch` `0x0054e3a0`, with local state updates flowing into the event-ring helpers `0x0054e880`, `0x0054e9c0`, and `0x0054ea20`.","objdump + caller inspection + local disassembly + mouse-message correlation + event-ring correlation" 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 +0x0054f5b0,140,shell_input_enqueue_window_event_record_and_signal_dispatch,shell,thiscall,inferred,objdump + caller inspection + local disassembly,3,"Queues one 12-dword shell-input event record into the rotating ring rooted at `[this+0x128]`. The helper copies six caller-supplied dwords into one local 12-dword scratch record, rewrites ring index `[this+0xa88]` from `0x32` back to `0x31` when needed, writes the record into slot `[this+0x128 + index*0x30]`, increments the ring index, and then signals the downstream dispatch path through `0x0054e880`. Current grounded caller is the shell window-message dispatcher `0x0054e3a0` on the low-message branch that synthesizes event id `0xcd`, so this is the safest current read for the shell-input event enqueue-plus-signal helper rather than another keyboard-state primitive.","objdump + caller inspection + local disassembly + ring-buffer correlation" 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 +0x0054f6a0,11,shell_set_global_presentation_phase_scalar_constant_0x3b30f27c,shell,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Tiny fixed-value setter for the shared presentation-phase scalar at `0x00d93850`. The helper stores literal float bit-pattern `0x3b30f27c` and returns immediately. Current grounded caller is shell-side branch `0x00538b72`, so this is the safest current read as one alternate fixed phase seed in the same strip as `0x0054f640` and `0x0054f700`.","objdump + caller inspection + local disassembly + presentation-phase correlation" +0x0054f6b0,11,shell_set_global_presentation_phase_scalar_constant_0x3baa64c3,shell,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Second tiny fixed-value setter for the shared presentation-phase scalar at `0x00d93850`. The helper stores literal float bit-pattern `0x3baa64c3` and returns immediately. Current grounded callers are shell-side branches `0x0052819d` and `0x0052b9f8`, so this is the safest current read as another alternate fixed phase seed beside `0x0054f6a0`, `0x0054f6c0`, and `0x0054f700`.","objdump + caller inspection + local disassembly + presentation-phase correlation" +0x0054f6c0,11,mouse_cursor_set_primary_motion_scalar_default,shell,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Tiny `MouseCursor.cpp` helper that seeds global float `0x00d93850` with the fixed default scalar `0x3951b717`. Current grounded caller is the per-frame mouse-cursor updater `0x0053f4e0`, which uses this as one of its reset-side scalar leaves before the later cursor-presentation pass.","objdump + caller inspection + local disassembly + mouse-cursor correlation" +0x0054f6d0,11,mouse_cursor_snapshot_primary_motion_scalar_into_saved_slot,shell,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Tiny `MouseCursor.cpp` helper that copies the current primary motion scalar from `0x00d93850` into saved slot `0x00625464`. Current grounded caller is the per-frame mouse-cursor updater `0x0053f4e0`.","objdump + caller inspection + local disassembly + mouse-cursor correlation" +0x0054f6e0,21,mouse_cursor_restore_primary_motion_scalar_from_saved_slot_and_clear_saved_slot,shell,cdecl,inferred,objdump + caller inspection + local disassembly,2,"Tiny `MouseCursor.cpp` helper that restores global motion scalar `0x00d93850` from saved slot `0x00625464` and then clears the saved slot back to `-1.0f`. Current grounded caller is the per-frame mouse-cursor updater `0x0053f4e0`, where it acts as the tail-side restore companion to `0x0054f6d0`.","objdump + caller inspection + local disassembly + mouse-cursor correlation" 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 0x0054f9f0,281,shell_queue_callout_frame_segments,shell,cdecl,inferred,ghidra-headless,4,Builds a four-segment callout frame around one projected extent box. The helper samples the same shell zoom and reciprocal scale tables under 0x006d4024 computes the four box legs from the caller extent inputs and emits each side through shell_queue_callout_segment_marker.,ghidra + rizin + llvm-objdump @@ -1094,6 +1913,16 @@ address,size,name,subsystem,calling_convention,prototype_status,source_tool,conf 0x0051df50,55,support_query_or_round_down_to_power_of_two,support,fastcall,inferred,objdump + caller xrefs + local disassembly,3,"Small power-of-two helper. Given one positive integer in `ECX`, it first finds the least power of two greater than or equal to that value. If the input is already an exact power of two it returns the input unchanged; if it is not exact and caller flag `EDX` is zero, it returns the next lower power of two; otherwise it returns `0`. Current grounded caller is the resource-side sizing branch at `0x005327eb/0x005327fa`, which passes `EDX = 0` to clamp two dimensions down to usable power-of-two texture sizes before later minimum-size enforcement. This now reads as a generic exact-or-round-down power-of-two helper rather than a texture-only magic-constant block.","objdump + caller xrefs + local disassembly + power-of-two correlation + resource-sizing correlation" 0x0051df90,39,support_strip_extension_in_place_from_last_dot,support,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Small in-place extension stripper. The helper walks to the end of the caller-owned NUL-terminated string, scans backward for the last literal `'.'`, and when found overwrites that dot with NUL; strings without any dot are left unchanged. Current grounded callers include `shell_setup_build_file_list_records_from_current_root_and_pattern` `0x004333f0` and several save/load or scenario-text formatting branches around `0x004427df`, `0x00445d53`, `0x00461847`, `0x004f0b78`, and `0x00553784`, where it is used to normalize display labels from extension-bearing resource names. This now reads as the shared strip-extension-in-place helper rather than another file-family-specific normalizer.","objdump + caller xrefs + local disassembly + extension-strip correlation" 0x0051dfc0,522,support_remap_clamped_unit_scalar_into_piecewise_packed_preview_color,support,cdecl,inferred,objdump + caller xrefs + local disassembly + color-ramp correlation,3,"Piecewise scalar-to-color helper over one caller float. The function first clamps the input into the unit interval `[0,1]`, then derives one remapped scalar and its complement through a piecewise curve with explicit breakpoints around `0.25`, `0.5`, and `0.75`. It finally packs those remapped values into one `0xcf`-alpha 32-bit preview color, with a small mode switch keyed by `[0x006d4024+0x11474e]` deciding whether the packed result duplicates one grayscale lane or preserves a two-lane split. Current grounded callers include world-side preview and overlay branches around `0x0045092e`, `0x00450b0f`, `0x00450cc9`, and `0x00450ddd`, plus several route-style and runtime-object presentation branches at `0x0048a860`, `0x0048e033`, `0x00493048`, `0x004b2a24`, and `0x004bd379`, so the safest current read is a shared clamped scalar-to-packed-preview-color ramp rather than a single-family palette helper.","objdump + caller xrefs + local disassembly + color-ramp correlation + preview-color correlation" +0x0051e1d0,591,support_remap_clamped_unit_scalar_into_alternate_piecewise_preview_color_when_mode0,support,cdecl,inferred,objdump + caller xrefs + local disassembly + color-ramp correlation,3,"Alternate sibling of `0x0051dfc0` over one caller float. When display-runtime mode dword `[0x006d4024+0x11474e]` is nonzero the helper jumps back into the ordinary packed preview-color ramp at `0x0051dfc0`; otherwise it applies a different piecewise remap with extra breakpoints around `0.2`, `0.4`, `0.6`, and `0.8`, then packs one `0xcf`-alpha preview color with several grayscale or two-lane output modes. Current grounded caller is the presentation branch at `0x0048dc3f`, so the safest current read is a mode-`0` alternate scalar-to-preview-color ramp rather than a generic palette helper.","objdump + caller xrefs + local disassembly + color-ramp correlation + preview-color correlation" +0x0051e430,79,support_query_path_is_openable_for_read,support,thiscall,inferred,objdump + caller xrefs + local disassembly + import correlation,3,"Small file-openability probe over one caller path string. The helper copies the incoming path into a stack buffer, opens it through the local file-open wrapper `0x005a4c57`, and when that succeeds immediately closes the handle through `CloseHandle` before returning `1`; failures return `0`. Current grounded callers include branches at `0x00446064`, `0x004b8af1`, `0x004dd305`, `0x004dd33a`, and `0x0053d18b`, so this is the safest current read for the shared `can this path be opened for read` probe rather than another family-specific file test.","objdump + caller xrefs + local disassembly + import correlation + file-open correlation" +0x0051e480,95,support_query_file_size_by_path_or_zero,support,thiscall,inferred,objdump + caller xrefs + local disassembly + import correlation,3,"Small file-size probe over one caller path string. The helper copies the incoming path into a stack buffer, opens it through the same local file-open wrapper used by `0x0051e430`, seeks to end through `SetFilePointer(handle, 0, 0, FILE_END)`, closes the handle, and returns the resulting size; open failures return `0`. Current grounded caller is the resource-side branch at `0x0053c758`, where it supplies a missing file-size value when the incoming cached size is `-1`.","objdump + caller xrefs + local disassembly + import correlation + file-size correlation" +0x0051e4e0,113,support_publish_ascii_text_to_clipboard_if_available,support,cdecl,inferred,objdump + caller xrefs + local disassembly + import correlation,3,"Shared ASCII clipboard-export helper. The function opens the clipboard, empties it, allocates a movable global block, copies the caller text into that block through `lstrcpyA`, unlocks it, and publishes the handle through `SetClipboardData(CF_TEXT)` before closing the clipboard. Current grounded callers are neighboring text-edit or widget branches at `0x0055c2b0` and `0x0055c772`, so this is the safest current read for the bounded clipboard publish helper.","objdump + caller xrefs + local disassembly + import correlation + clipboard correlation" +0x0051e560,98,support_copy_clipboard_text_into_buffer_bounded,support,cdecl,inferred,objdump + caller xrefs + local disassembly + import correlation,3,"Shared ASCII clipboard-import helper. The function opens the clipboard, queries `CF_TEXT` through `GetClipboardData`, locks the returned handle, bounded-copies the clipboard contents into the caller buffer through `lstrcpynA`, forces a trailing NUL, unlocks the block, and closes the clipboard. Current grounded caller is the neighboring text-edit branch at `0x0055be56`, so this is the safest current read for the bounded clipboard pull helper.","objdump + caller xrefs + local disassembly + import correlation + clipboard correlation" +0x0051e6e0,62,support_query_string_is_nonempty_ascii_digits_only,support,thiscall,inferred,objdump + caller xrefs + local disassembly,3,"Small string predicate over one caller-owned NUL-terminated buffer. The helper rejects null pointers and empty strings, then scans every byte and succeeds only when each character is ASCII `'0'..'9'`. Current grounded callers are text-entry validation branches at `0x004acd01` and `0x004ae817`, so this is the safest current read for the nonempty digits-only predicate rather than a broader parser.","objdump + caller xrefs + local disassembly + text-validation correlation" +0x0051e720,29,support_set_active_debug_log_filename_and_clear_init_flags,support,thiscall,inferred,objdump + caller xrefs + local disassembly + string correlation,3,"Small debug-log filename setter over one caller string. The helper copies up to `0x64` bytes into global buffer `0x006d3ca8`, clears byte `0x006d3d0c`, and clears dword `0x006d3d10`. Current grounded callers are the neighboring bootstrap leaves at `0x0051cff5` and `0x0051d02b`, which seed the default names `rt3_debug.txt` and `language_debug.txt`, so this is the safest current read for the active debug-log filename setter plus init-flag clear.","objdump + caller xrefs + local disassembly + string correlation + debug-log correlation" +0x0051e740,197,support_open_or_create_active_debug_log_and_append_separator_once,support,cdecl,inferred,objdump + caller xrefs + local disassembly + string correlation,3,"Debug-log bootstrap helper over the active global filename at `0x006d3ca8`. The function gates on byte `0x006d3ca0`, uses dword `0x006d3d10` as an in-progress latch, seeds the default filename when needed, formats the path `.\\data\\log\\%s`, opens or creates the target stream through the local file wrapper, appends the fixed separator line `------------------\\n`, closes the stream, and clears the in-progress latch. Current grounded callers are `0x0051cffa` and `0x00521089`, so this is the safest current read for the active debug-log open-or-create plus one-time separator writer.","objdump + caller xrefs + local disassembly + string correlation + debug-log correlation" +0x0051e810,363,shell_mouse_cursor_adjust_showcursor_refcount_and_sync_screen_position_if_live,shell,thiscall,inferred,objdump + caller xrefs + local disassembly + import correlation + source-string correlation,3,"Shared mouse-cursor visibility and position helper beneath the live shell family. The function adjusts global refcount `0x00624b20` up or down from one caller boolean, repeatedly calls `ShowCursor` until the OS cursor visibility count crosses the desired state, and when the live shell bundle exists plus `0x0051f0b0` says the cursor service is active, it derives current screen coordinates from the display tuple via `0x0051f100` and `0x00543c10` and may call `SetCursorPos` when `0x0051f1a0` passes. The grounded source string `\\RT3\\exe\\Src\\Engine\\MouseCursor.cpp` and callers around `0x0053f075`, `0x0053f146`, `0x0053f208`, `0x0053f2af`, `0x0053f480`, `0x0053f492`, and `0x0051e9b7` make this the safest current read for the mouse-cursor ShowCursor-refcount and live-position sync helper.","objdump + caller xrefs + local disassembly + import correlation + source-string correlation + mouse-cursor correlation" +0x0051e980,246,shell_publish_warning_modal_once_and_force_cursor_visible,shell,cdecl,inferred,objdump + caller xrefs + local disassembly + import correlation + string correlation,3,"Guarded warning-modal publisher. The helper uses dword `0x006d3d18` as a reentrancy latch, flips shell byte `[0x006d4024+0x57]` when the live shell bundle exists, forces cursor visibility through `0x0051e810(1, \"\\\\RT3\\\\exe\\\\Src\\\\Engine\\\\Misc.cpp\", 0x110)`, formats the warning body through `0x0051d680`, and shows the shared `MessageBoxA` warning box with localized text and caption ids `0x44/0x45`. Current grounded callers include `0x0040cd70` and many neighboring shell, runtime-object, and setup-warning branches, so this is the safest current read for the shared guarded warning-modal publisher rather than a one-off formatter.","objdump + caller xrefs + local disassembly + import correlation + string correlation + warning-modal correlation" 0x0044bd10,152,world_query_region_category_byte_at_world_coords,map,thiscall,inferred,objdump + caller xrefs + local disassembly + region-raster correlation,3,"Small world-grid lookup helper over the per-cell region word family rooted at `[world+0x212d]`. The function converts caller float coordinates into rounded cell indices through the world-cell scale at `0x005c8568`, clamps those indices to live dimensions `[world+0x214d/+0x2151]`, resolves the current cell record from `[world+0x212d] + cell*4`, and treats the record as a mixed byte-or-word id: when the trailing `u16` lane at `+1` is nonzero it uses that wider id, otherwise it falls back to the first byte. It then resolves the resulting region or city entry through collection `0x0062bae0` and returns entry dword `[entry+0x272]`, with fixed fallback `5` when no entry resolves. Current grounded callers include the structure-side formatter at `0x00403ba7` and the StationPlace world-surface branches at `0x00508b80`, `0x00508d59`, and `0x0050a4e6`, where this helper feeds the current selected-site category latch `0x00622af0`.","objdump + caller xrefs + local disassembly + region-raster correlation + StationPlace category correlation" 0x0044b160,936,world_try_bulldoze_near_coords_and_format_failure_message,map,thiscall,inferred,objdump + caller xrefs + local disassembly + RT3.lng strings,3,"Shared bulldoze-side chooser and commit helper beneath the TrackLay and sibling world-surface bulldoze lanes. The function first clears the caller-owned failure-text buffer and one output slot, validates the supplied company id through the live company collection `0x0062be10`, and on the ordinary non-editor path formats RT3.lng `419` `You can't bulldoze without a company.` when no valid company is available. It then performs two grounded passes over nearby runtime collections around the caller's world coordinates and radius: the early pass estimates or selects the best current bulldoze target while tracking the strongest nearby route-entry distance split, and the later pass performs the actual delete-or-commit branches. The target-family split is now real too. It scans the live route-entry collection `0x006cfca8`, the city-or-region collection `0x0062bae0`, the broader structure collection `0x006cea50`, linked placed structures in `0x0062b26c`, the route-side blocker collection `0x0062ba84`, and the live placed-structure collection `0x006cec20`, repeatedly sampling coordinates through `0x00455800/0x00455810`, `0x0048a1a0/0x0048a1c0`, `0x0047ded0/0x0047df00`, and the radial helper `0x0051db80`. The rejection ladder is now grounded by string ids: mismatched building ownership formats `421` `You can't bulldoze this building - it's owned by another railroad!`, mismatched track ownership formats `422`, nearby rolling-stock blockage formats `423`, and the placed-structure blocker lane localizes the two colliding structure stems through `0x0051c920` before formatting `424` `You can't bulldoze that track - it's too close to a %1. Try bulldozing the %2 first.`. The cost gate is grounded too: on the ordinary company path it reads the company treasury through `company_read_year_or_control_transfer_metric_value` `0x0042a5d0` on stat family `0x2329` mode `0x0d`, formats `420` when the chosen bulldoze cost exceeds available cash, and otherwise commits the cost through `company_apply_bulldoze_or_local_action_cost_scalar` `0x0042a080`. On success the helper dispatches the actual bulldoze branch through the selected owner family: route-entry and route-anchor targets commit through `0x004937f0`, `0x004941a0`, and `0x0048abf0`, while building or linked-site targets commit through the surrounding placed-structure virtual slot `+0x58` and neighboring collection erases. Current grounded direct callers are the TrackLay bulldoze branches at `0x0050d83e` and `0x0050d8fc` plus the neighboring world-surface branches at `0x00473050` and `0x004b8685`, so this is the safest current read for the shared bulldoze chooser-plus-failure-message helper rather than a generic proximity scan.","objdump + caller xrefs + local disassembly + RT3.lng strings + TrackLay bulldoze correlation + rejection-ladder correlation" 0x0044bdb0,107,world_count_neighbor_cells_in_secondary_raster_class_set_2_4_5,map,thiscall,inferred,objdump + caller xrefs + local disassembly + secondary-raster correlation,3,"Eight-neighbor count helper over the secondary-raster class subset owned by `world_secondary_raster_query_cell_class_in_set_2_4_5` `0x00534ec0`. Starting from one caller cell coordinate pair, the helper walks the shared `0x00624b28/0x00624b48` offset tables across the eight immediate neighbors, bounds-checks each neighbor against world dimensions `[world+0x2155/+0x2159]`, and increments the result only when `0x00534ec0` reports that the neighbor cell belongs to class set `2/4/5`. Current grounded callers are the neighboring secondary-raster service branches at `0x0044bf9d`, `0x0044bfc8`, `0x0044c0d5`, `0x0044c348`, and `0x0044c37b`, so this is the safest current read for the local class-subset neighbor counter rather than another generic lattice scan.","objdump + caller xrefs + local disassembly + secondary-raster correlation + 8-neighbor offset-table correlation" diff --git a/artifacts/tmp/BuildingDetail.win.bin b/artifacts/tmp/BuildingDetail.win.bin new file mode 100644 index 0000000..6157db7 Binary files /dev/null and b/artifacts/tmp/BuildingDetail.win.bin differ diff --git a/artifacts/tmp/CompanyDetail.win.bin b/artifacts/tmp/CompanyDetail.win.bin new file mode 100644 index 0000000..031909a Binary files /dev/null and b/artifacts/tmp/CompanyDetail.win.bin differ diff --git a/artifacts/tmp/analysis/analysis-context-functions.csv b/artifacts/tmp/analysis/analysis-context-functions.csv new file mode 100644 index 0000000..5bbf8b4 --- /dev/null +++ b/artifacts/tmp/analysis/analysis-context-functions.csv @@ -0,0 +1,2 @@ +query_address,function_address,name,size,calling_convention,signature,caller_count,callers,callee_count,callees,data_ref_count,data_refs,entry_excerpt +0x004ba3d0,0x004ba3d0,fcn.004ba3d0,2380,cdecl,fcn.004ba3d0();,5,0x004baedd@0x004bad20:fcn.004bad20; 0x004bb8dc@0x004baef0:fcn.004baef0; 0x004bbc89; 0x004bbd6a; 0x004bc02b,67,0x004ba53d->0x00517d40:fcn.00517d40; 0x004ba556->0x00518140:fcn.00518140; 0x004ba5b6->0x00518de0:fcn.00518de0; 0x004ba606->0x005193f0:fcn.005193f0; 0x004ba489->0x0051d820:fcn.0051d820; 0x004ba5e6->0x0051d820:fcn.0051d820; 0x004ba611->0x0051d820:fcn.0051d820; 0x004ba78a->0x0051d820:fcn.0051d820; 0x004ba830->0x0051d820:fcn.0051d820; 0x004ba8cb->0x0051d820:fcn.0051d820; 0x004ba997->0x0051d820:fcn.0051d820; 0x004bac73->0x0051d820:fcn.0051d820; 0x004ba493->0x0053b070:fcn.0053b070; 0x004ba61b->0x0053b070:fcn.0053b070; 0x004ba6d9->0x0053b070:fcn.0053b070; 0x004ba794->0x0053b070:fcn.0053b070; 0x004ba83a->0x0053b070:fcn.0053b070; 0x004ba8d5->0x0053b070:fcn.0053b070; 0x004ba9a1->0x0053b070:fcn.0053b070; 0x004baa6d->0x0053b070:fcn.0053b070; 0x004bab24->0x0053b070:fcn.0053b070; 0x004bac8f->0x0053b070:fcn.0053b070; 0x004ba5cd->0x0053c930:fcn.0053c930; 0x004ba40b->0x0053f830:fcn.0053f830; 0x004ba4c9->0x0053f830:fcn.0053f830; 0x004ba661->0x0053f830:fcn.0053f830; 0x004ba9f4->0x0053f830:fcn.0053f830; 0x004baaab->0x0053f830:fcn.0053f830; 0x004bab53->0x0053f830:fcn.0053f830; 0x004ba4b4->0x0053f9c0:fcn.0053f9c0; 0x004ba63c->0x0053f9c0:fcn.0053f9c0; 0x004ba6fd->0x0053f9c0:fcn.0053f9c0; 0x004ba7b6->0x0053f9c0:fcn.0053f9c0; 0x004ba85a->0x0053f9c0:fcn.0053f9c0; 0x004ba8f5->0x0053f9c0:fcn.0053f9c0; 0x004ba9c1->0x0053f9c0:fcn.0053f9c0; 0x004baa90->0x0053f9c0:fcn.0053f9c0; 0x004bab47->0x0053f9c0:fcn.0053f9c0; 0x004bacb2->0x0053f9c0:fcn.0053f9c0; 0x004ba421->0x0053fe00:fcn.0053fe00; 0x004ba4dc->0x0053fe00:fcn.0053fe00; 0x004ba674->0x0053fe00:fcn.0053fe00; 0x004baa0a->0x0053fe00:fcn.0053fe00; 0x004baac1->0x0053fe00:fcn.0053fe00; 0x004bab69->0x0053fe00:fcn.0053fe00; 0x004bacda->0x00540120:fcn.00540120; 0x004bacf4->0x00540120:fcn.00540120; 0x004bad0f->0x00540120:fcn.00540120; 0x004ba4a6->0x0055a040:fcn.0055a040; 0x004ba62e->0x0055a040:fcn.0055a040; 0x004ba7a9->0x0055a040:fcn.0055a040; 0x004ba84d->0x0055a040:fcn.0055a040; 0x004ba8e8->0x0055a040:fcn.0055a040; 0x004ba9b4->0x0055a040:fcn.0055a040; 0x004baca5->0x0055ab50:fcn.0055ab50; 0x004ba6ef->0x00563210:fcn.00563210; 0x004baa83->0x00563210:fcn.00563210; 0x004bab3a->0x00563210:fcn.00563210; 0x004ba4be->0x005a1145:fcn.005a1145; 0x004ba646->0x005a1145:fcn.005a1145; 0x004ba650->0x005a1145:fcn.005a1145; 0x004ba7c0->0x005a1145:fcn.005a1145; 0x004ba864->0x005a1145:fcn.005a1145; 0x004ba8ff->0x005a1145:fcn.005a1145; 0x004ba9cb->0x005a1145:fcn.005a1145; 0x004bacbf->0x005a1145:fcn.005a1145; 0x004ba56c->0x005a19c4:fcn.005a19c4,28,"0x004bacc9->0x004ba270; 0x004ba5e1->0x005d0194; 0x004ba952->0x005d0608; 0x004ba889->0x005d0614:""Caboose.imb""; 0x004ba59a->0x005d0620:""PassMail.imb""; 0x004ba593->0x005d0630:""AnyFreight.imb""; 0x004ba587->0x005d0640:""AnyCargo.imb""; 0x004ba566->0x005d0650:""%s.imb""; 0x004ba44e->0x005d0658:""Cargo.imb""; 0x004ba74e->0x005d0658:""Cargo.imb""; 0x004ba7f4->0x005d0658:""Cargo.imb""; 0x004bac25->0x005d0658:""Cargo.imb""; 0x004ba536->0x0062ba8c; 0x004ba54f->0x0062ba8c; 0x004ba3e2->0x006cfe04; 0x004ba4fa->0x006cfe04; 0x004ba546->0x006cfe04; 0x004ba576->0x006cfe04; 0x004ba711->0x006cfe04; 0x004ba7c5->0x006cfe04; 0x004ba869->0x006cfe04; 0x004ba904->0x006cfe04; 0x004ba9d0->0x006cfe04; 0x004baa95->0x006cfe04; 0x004bab81->0x006cfe04; 0x004bacdf->0x006cfe04; 0x004bacf9->0x006cfe04; 0x004ba5bb->0x006d4020"," 4ba3b0: jl 0x4ba355 <.text+0xb9355> | 4ba3b2: decl %ebx | 4ba3b3: addb %ah, 0x4ba3(%ebp) | 4ba3b9: addl %eax, (%ebx) | 4ba3bb: addl (%ebx), %eax | 4ba3bd: addl (%ebx), %eax | 4ba3bf: addb (%ebx), %al | 4ba3c1: addl (%eax), %eax | 4ba3c3: addl %eax, (%eax) | 4ba3c5: addl %edx, -0x6f6f6f70(%eax) | 4ba3cb: nop | 4ba3cc: nop | 4ba3cd: nop | 4ba3ce: nop | 4ba3cf: nop | 4ba3d0: pushl %ebp | 4ba3d1: movl %esp, %ebp | 4ba3d3: andl $-0x8, %esp | 4ba3d6: subl $0x318, %esp # imm = 0x318 | 4ba3dc: pushl %ebx | 4ba3dd: pushl %ebp | 4ba3de: pushl %esi | 4ba3df: pushl %edi | 4ba3e0: movl %ecx, %ebp | 4ba3e2: movl 0x6cfe04, %eax | 4ba3e7: cmpb $0x0, (%eax) | 4ba3ea: jbe 0x4ba72f <.text+0xb972f>" diff --git a/artifacts/tmp/analysis/analysis-context.md b/artifacts/tmp/analysis/analysis-context.md new file mode 100644 index 0000000..b1e6f6d --- /dev/null +++ b/artifacts/tmp/analysis/analysis-context.md @@ -0,0 +1,292 @@ +# Analysis Context + +- Target binary: `/home/jan/projects/rrt/rt3_wineprefix/drive_c/rt3/RT3.exe` +- Function names prefer the curated ledger when a committed mapping exists. + +## Function Targets + +### `0x004ba3d0` -> `0x004ba3d0` `fcn.004ba3d0` + +- Size: `2380` +- Calling convention: `cdecl` +- Signature: `fcn.004ba3d0();` + +Entry excerpt: + +```asm + 4ba3b0: jl 0x4ba355 <.text+0xb9355> + 4ba3b2: decl %ebx + 4ba3b3: addb %ah, 0x4ba3(%ebp) + 4ba3b9: addl %eax, (%ebx) + 4ba3bb: addl (%ebx), %eax + 4ba3bd: addl (%ebx), %eax + 4ba3bf: addb (%ebx), %al + 4ba3c1: addl (%eax), %eax + 4ba3c3: addl %eax, (%eax) + 4ba3c5: addl %edx, -0x6f6f6f70(%eax) + 4ba3cb: nop + 4ba3cc: nop + 4ba3cd: nop + 4ba3ce: nop + 4ba3cf: nop + 4ba3d0: pushl %ebp + 4ba3d1: movl %esp, %ebp + 4ba3d3: andl $-0x8, %esp + 4ba3d6: subl $0x318, %esp # imm = 0x318 + 4ba3dc: pushl %ebx + 4ba3dd: pushl %ebp + 4ba3de: pushl %esi + 4ba3df: pushl %edi + 4ba3e0: movl %ecx, %ebp + 4ba3e2: movl 0x6cfe04, %eax + 4ba3e7: cmpb $0x0, (%eax) + 4ba3ea: jbe 0x4ba72f <.text+0xb972f> +``` + +Callers: +- `0x004baedd` in `0x004bad20` `fcn.004bad20` +- `0x004bb8dc` in `0x004baef0` `fcn.004baef0` +- `0x004bbc89` +- `0x004bbd6a` +- `0x004bc02b` + +Caller xref excerpts: + +#### `0x004baedd` + +```asm + 4baebd: addb %cl, 0x6cfe0415(%ebx) + 4baec3: addb %cl, (%edi) + 4baec5: movb $0x42, %dh + 4baec7: andl %ebp, (%edx) + 4baeca: pushl $0x0 + 4baecc: pushl %eax + 4baecd: pushl $0x7d0e # imm = 0x7D0E + 4baed2: pushl $0x66 + 4baed4: movl %esi, %ecx + 4baed6: calll 0x540120 <.text+0x13f120> + 4baedb: movl %esi, %ecx + 4baedd: calll 0x4ba3d0 <.text+0xb93d0> + 4baee2: popl %edi + 4baee3: popl %esi + 4baee4: popl %ebx + 4baee5: retl $0x4 + 4baee8: nop + 4baee9: nop + 4baeea: nop + 4baeeb: nop + 4baeec: nop + 4baeed: nop + 4baeee: nop + 4baeef: nop + 4baef0: pushl %ebp + 4baef1: movl %esp, %ebp + 4baef3: andl $-0x8, %esp + 4baef6: subl $0x270, %esp # imm = 0x270 + 4baefc: movl 0x6cfe04, %eax +``` + +#### `0x004bb8dc` + +```asm + 4bb8bc: incl %ebx + 4bb8bd: movl %ebx, 0x2c(%esp) + 4bb8c1: incl %ebp + 4bb8c2: movl 0x62ba8c, %ecx + 4bb8c8: incl %edi + 4bb8c9: movl %edi, 0x18(%esp) + 4bb8cd: calll 0x517cf0 <.text+0x116cf0> + 4bb8d2: cmpl %eax, %edi + 4bb8d4: jl 0x4bb490 <.text+0xba490> + 4bb8da: movl %esi, %ecx + 4bb8dc: calll 0x4ba3d0 <.text+0xb93d0> + 4bb8e1: movl %esi, %ecx + 4bb8e3: calll 0x4b9a20 <.text+0xb8a20> + 4bb8e8: pushl $0x7d0b # imm = 0x7D0B + 4bb8ed: movl %esi, %ecx + 4bb8ef: calll 0x53f830 <.text+0x13e830> + 4bb8f4: movl 0x6cec20, %ecx + 4bb8fa: movl %eax, %edi +``` + +#### `0x004bbc89` + +```asm + 4bbc69: pushl $0x7d96 # imm = 0x7D96 + 4bbc6e: movl %ebp, %ecx + 4bbc70: calll 0x53fe00 <.text+0x13ee00> + 4bbc75: pushl %edi + 4bbc76: pushl $0x8051 # imm = 0x8051 + 4bbc7b: pushl $0x8020 # imm = 0x8020 + 4bbc80: movl %ebp, %ecx + 4bbc82: calll 0x53fe00 <.text+0x13ee00> + 4bbc87: movl %ebp, %ecx + 4bbc89: calll 0x4ba3d0 <.text+0xb93d0> + 4bbc8e: movl 0x6cfe08, %edx + 4bbc94: movb 0xc(%edx), %al + 4bbc97: testb %al, %al + 4bbc99: je 0x4bbca2 <.text+0xbaca2> + 4bbc9b: movl %ebp, %ecx + 4bbc9d: calll 0x4b9ec0 <.text+0xb8ec0> + 4bbca2: popl %edi + 4bbca3: popl %ebx + 4bbca4: popl %esi + 4bbca5: xorl %eax, %eax + 4bbca7: popl %ebp + 4bbca8: retl $0x4 +``` + +#### `0x004bbd6a` + +```asm + 4bbd4a: movzbl (%eax), %ecx + 4bbd4d: movl %edx, -0x3(%eax,%ecx,4) + 4bbd51: jmp 0x4bbd68 <.text+0xbad68> + 4bbd53: leal -0x3(%eax), %ecx + 4bbd56: calll 0x4b99c0 <.text+0xb89c0> + 4bbd5b: movl 0x6cfe04, %ecx + 4bbd61: movzbl (%ecx), %edx + 4bbd64: movl %eax, -0x3(%ecx,%edx,4) + 4bbd68: movl %ebp, %ecx + 4bbd6a: calll 0x4ba3d0 <.text+0xb93d0> + 4bbd6f: movl 0x6cfe08, %eax + 4bbd74: movb 0xc(%eax), %cl + 4bbd77: testb %cl, %cl + 4bbd79: je 0x4bbca2 <.text+0xbaca2> + 4bbd7f: movl %ebp, %ecx + 4bbd81: calll 0x4b9ec0 <.text+0xb8ec0> + 4bbd86: popl %edi + 4bbd87: popl %ebx + 4bbd88: popl %esi + 4bbd89: xorl %eax, %eax +``` + +#### `0x004bc02b` + +```asm + 4bc00b: addb %dl, 0x68(%edi) + 4bc00e: pushl %ecx + 4bc00f: addb $0x0, (%eax) + 4bc012: pushl $0x8020 # imm = 0x8020 + 4bc017: movl %ebp, %ecx + 4bc019: calll 0x53fe00 <.text+0x13ee00> + 4bc01e: movl 0x6cfe04, %eax + 4bc023: testb $0x40, 0x28(%eax) + 4bc027: movl %ebp, %ecx + 4bc029: je 0x4bc039 <.text+0xbb039> + 4bc02b: calll 0x4ba3d0 <.text+0xb93d0> + 4bc030: popl %edi + 4bc031: popl %ebx + 4bc032: popl %esi + 4bc033: xorl %eax, %eax + 4bc035: popl %ebp + 4bc036: retl $0x4 + 4bc039: calll 0x4b9a20 <.text+0xb8a20> + 4bc03e: popl %edi + 4bc03f: popl %ebx + 4bc040: popl %esi + 4bc041: xorl %eax, %eax + 4bc043: popl %ebp + 4bc044: retl $0x4 + 4bc047: cmpl %edi, 0x6cfe10 +``` + +Direct internal callees: +- `0x004ba53d` -> `0x00517d40` `fcn.00517d40` +- `0x004ba556` -> `0x00518140` `fcn.00518140` +- `0x004ba5b6` -> `0x00518de0` `fcn.00518de0` +- `0x004ba606` -> `0x005193f0` `fcn.005193f0` +- `0x004ba489` -> `0x0051d820` `fcn.0051d820` +- `0x004ba5e6` -> `0x0051d820` `fcn.0051d820` +- `0x004ba611` -> `0x0051d820` `fcn.0051d820` +- `0x004ba78a` -> `0x0051d820` `fcn.0051d820` +- `0x004ba830` -> `0x0051d820` `fcn.0051d820` +- `0x004ba8cb` -> `0x0051d820` `fcn.0051d820` +- `0x004ba997` -> `0x0051d820` `fcn.0051d820` +- `0x004bac73` -> `0x0051d820` `fcn.0051d820` +- `0x004ba493` -> `0x0053b070` `fcn.0053b070` +- `0x004ba61b` -> `0x0053b070` `fcn.0053b070` +- `0x004ba6d9` -> `0x0053b070` `fcn.0053b070` +- `0x004ba794` -> `0x0053b070` `fcn.0053b070` +- `0x004ba83a` -> `0x0053b070` `fcn.0053b070` +- `0x004ba8d5` -> `0x0053b070` `fcn.0053b070` +- `0x004ba9a1` -> `0x0053b070` `fcn.0053b070` +- `0x004baa6d` -> `0x0053b070` `fcn.0053b070` +- `0x004bab24` -> `0x0053b070` `fcn.0053b070` +- `0x004bac8f` -> `0x0053b070` `fcn.0053b070` +- `0x004ba5cd` -> `0x0053c930` `fcn.0053c930` +- `0x004ba40b` -> `0x0053f830` `fcn.0053f830` +- `0x004ba4c9` -> `0x0053f830` `fcn.0053f830` +- `0x004ba661` -> `0x0053f830` `fcn.0053f830` +- `0x004ba9f4` -> `0x0053f830` `fcn.0053f830` +- `0x004baaab` -> `0x0053f830` `fcn.0053f830` +- `0x004bab53` -> `0x0053f830` `fcn.0053f830` +- `0x004ba4b4` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004ba63c` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004ba6fd` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004ba7b6` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004ba85a` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004ba8f5` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004ba9c1` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004baa90` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004bab47` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004bacb2` -> `0x0053f9c0` `fcn.0053f9c0` +- `0x004ba421` -> `0x0053fe00` `fcn.0053fe00` +- `0x004ba4dc` -> `0x0053fe00` `fcn.0053fe00` +- `0x004ba674` -> `0x0053fe00` `fcn.0053fe00` +- `0x004baa0a` -> `0x0053fe00` `fcn.0053fe00` +- `0x004baac1` -> `0x0053fe00` `fcn.0053fe00` +- `0x004bab69` -> `0x0053fe00` `fcn.0053fe00` +- `0x004bacda` -> `0x00540120` `fcn.00540120` +- `0x004bacf4` -> `0x00540120` `fcn.00540120` +- `0x004bad0f` -> `0x00540120` `fcn.00540120` +- `0x004ba4a6` -> `0x0055a040` `fcn.0055a040` +- `0x004ba62e` -> `0x0055a040` `fcn.0055a040` +- `0x004ba7a9` -> `0x0055a040` `fcn.0055a040` +- `0x004ba84d` -> `0x0055a040` `fcn.0055a040` +- `0x004ba8e8` -> `0x0055a040` `fcn.0055a040` +- `0x004ba9b4` -> `0x0055a040` `fcn.0055a040` +- `0x004baca5` -> `0x0055ab50` `fcn.0055ab50` +- `0x004ba6ef` -> `0x00563210` `fcn.00563210` +- `0x004baa83` -> `0x00563210` `fcn.00563210` +- `0x004bab3a` -> `0x00563210` `fcn.00563210` +- `0x004ba4be` -> `0x005a1145` `fcn.005a1145` +- `0x004ba646` -> `0x005a1145` `fcn.005a1145` +- `0x004ba650` -> `0x005a1145` `fcn.005a1145` +- `0x004ba7c0` -> `0x005a1145` `fcn.005a1145` +- `0x004ba864` -> `0x005a1145` `fcn.005a1145` +- `0x004ba8ff` -> `0x005a1145` `fcn.005a1145` +- `0x004ba9cb` -> `0x005a1145` `fcn.005a1145` +- `0x004bacbf` -> `0x005a1145` `fcn.005a1145` +- `0x004ba56c` -> `0x005a19c4` `fcn.005a19c4` + +Data refs: +- `0x004bacc9` -> `0x004ba270` +- `0x004ba5e1` -> `0x005d0194` +- `0x004ba952` -> `0x005d0608` +- `0x004ba889` -> `0x005d0614` "Caboose.imb" +- `0x004ba59a` -> `0x005d0620` "PassMail.imb" +- `0x004ba593` -> `0x005d0630` "AnyFreight.imb" +- `0x004ba587` -> `0x005d0640` "AnyCargo.imb" +- `0x004ba566` -> `0x005d0650` "%s.imb" +- `0x004ba44e` -> `0x005d0658` "Cargo.imb" +- `0x004ba74e` -> `0x005d0658` "Cargo.imb" +- `0x004ba7f4` -> `0x005d0658` "Cargo.imb" +- `0x004bac25` -> `0x005d0658` "Cargo.imb" +- `0x004ba536` -> `0x0062ba8c` +- `0x004ba54f` -> `0x0062ba8c` +- `0x004ba3e2` -> `0x006cfe04` +- `0x004ba4fa` -> `0x006cfe04` +- `0x004ba546` -> `0x006cfe04` +- `0x004ba576` -> `0x006cfe04` +- `0x004ba711` -> `0x006cfe04` +- `0x004ba7c5` -> `0x006cfe04` +- `0x004ba869` -> `0x006cfe04` +- `0x004ba904` -> `0x006cfe04` +- `0x004ba9d0` -> `0x006cfe04` +- `0x004baa95` -> `0x006cfe04` +- `0x004bab81` -> `0x006cfe04` +- `0x004bacdf` -> `0x006cfe04` +- `0x004bacf9` -> `0x006cfe04` +- `0x004ba5bb` -> `0x006d4020` + diff --git a/crates/rrt-cli/src/main.rs b/crates/rrt-cli/src/main.rs index 4cce1b7..95a472b 100644 --- a/crates/rrt-cli/src/main.rs +++ b/crates/rrt-cli/src/main.rs @@ -15,15 +15,65 @@ use rrt_runtime::{ CAMPAIGN_SCENARIO_COUNT, CampaignExeInspectionReport, OBSERVED_CAMPAIGN_SCENARIO_NAMES, Pk4ExtractionReport, Pk4InspectionReport, RuntimeSnapshotDocument, RuntimeSnapshotSource, RuntimeSummary, SNAPSHOT_FORMAT_VERSION, SmpClassicPackedProfileBlock, SmpInspectionReport, - SmpRt3105PackedProfileBlock, WinInspectionReport, execute_step_command, extract_pk4_entry_file, - inspect_campaign_exe_file, inspect_pk4_file, inspect_smp_file, inspect_win_file, - load_runtime_snapshot_document, load_runtime_state_import, save_runtime_snapshot_document, - validate_runtime_snapshot_document, + SmpLoadedSaveSlice, SmpRt3105PackedProfileBlock, SmpSaveLoadSummary, WinInspectionReport, + execute_step_command, extract_pk4_entry_file, inspect_campaign_exe_file, inspect_pk4_file, + inspect_smp_file, inspect_win_file, load_runtime_snapshot_document, load_runtime_state_import, + load_save_slice_file, project_save_slice_to_runtime_state_import, + save_runtime_snapshot_document, validate_runtime_snapshot_document, }; use serde::Serialize; use serde_json::Value; use sha2::{Digest, Sha256}; +const SPECIAL_CONDITIONS_OFFSET: usize = 0x0d64; +const SPECIAL_CONDITION_COUNT: usize = 36; +const SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT: usize = 35; +const SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT: usize = 50; +const SMP_ALIGNED_RUNTIME_RULE_KNOWN_EDITOR_RULE_COUNT: usize = 49; +const SMP_ALIGNED_RUNTIME_RULE_END_OFFSET: usize = + SPECIAL_CONDITIONS_OFFSET + SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT * 4; +const POST_SPECIAL_CONDITIONS_SCALAR_OFFSET: usize = 0x0df4; +const POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET: usize = 0x0f30; +const POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET: usize = SMP_ALIGNED_RUNTIME_RULE_END_OFFSET; +const SPECIAL_CONDITION_LABELS: [&str; SPECIAL_CONDITION_COUNT] = [ + "Disable Stock Buying and Selling", + "Disable Margin Buying/Short Selling Stock", + "Disable Company Issue/Buy Back Stock", + "Disable Issuing/Repaying Bonds", + "Disable Declaring Bankruptcy", + "Disable Changing the Dividend Rate", + "Disable Replacing a Locomotive", + "Disable Retiring a Train", + "Disable Changing Cargo Consist On Train", + "Disable Buying a Train", + "Disable All Track Building", + "Disable Unconnected Track Building", + "Limited Track Building Amount", + "Disable Building Stations", + "Disable Building Hotel/Restaurant/Tavern/Post Office", + "Disable Building Customs House", + "Disable Building Industry Buildings", + "Disable Buying Existing Industry Buildings", + "Disable Being Fired As Chairman", + "Disable Resigning as Chairman", + "Disable Chairmanship Takeover", + "Disable Starting Any Companies", + "Disable Starting Multiple Companies", + "Disable Merging Companies", + "Disable Bulldozing", + "Show Visited Track", + "Show Visited Stations", + "Use Slow Date", + "Completely Disable Money-Related Things", + "Use Bio-Accelerator Cars", + "Disable Cargo Economy", + "Use Wartime Cargos", + "Disable Train Crashes", + "Disable Train Crashes AND Breakdowns", + "AI Ignore Territories At Startup", + "Hidden sentinel", +]; + enum Command { Validate { repo_root: PathBuf, @@ -55,6 +105,16 @@ enum Command { RuntimeInspectSmp { smp_path: PathBuf, }, + RuntimeSummarizeSaveLoad { + smp_path: PathBuf, + }, + RuntimeLoadSaveSlice { + smp_path: PathBuf, + }, + RuntimeImportSaveState { + smp_path: PathBuf, + output_path: PathBuf, + }, RuntimeInspectPk4 { pk4_path: PathBuf, }, @@ -78,15 +138,36 @@ enum Command { RuntimeCompareCandidateTable { smp_paths: Vec, }, + RuntimeCompareRecipeBookLines { + smp_paths: Vec, + }, RuntimeCompareSetupPayloadCore { smp_paths: Vec, }, RuntimeCompareSetupLaunchPayload { smp_paths: Vec, }, + RuntimeComparePostSpecialConditionsScalars { + smp_paths: Vec, + }, RuntimeScanCandidateTableHeaders { root_path: PathBuf, }, + RuntimeScanSpecialConditions { + root_path: PathBuf, + }, + RuntimeScanAlignedRuntimeRuleBand { + root_path: PathBuf, + }, + RuntimeScanPostSpecialConditionsScalars { + root_path: PathBuf, + }, + RuntimeScanPostSpecialConditionsTail { + root_path: PathBuf, + }, + RuntimeScanRecipeBookLines { + root_path: PathBuf, + }, RuntimeExportProfileBlock { smp_path: PathBuf, output_path: PathBuf, @@ -128,6 +209,18 @@ struct RuntimeSmpInspectionOutput { inspection: SmpInspectionReport, } +#[derive(Debug, Serialize)] +struct RuntimeSaveLoadSummaryOutput { + path: String, + summary: SmpSaveLoadSummary, +} + +#[derive(Debug, Serialize)] +struct RuntimeLoadedSaveSliceOutput { + path: String, + save_slice: SmpLoadedSaveSlice, +} + #[derive(Debug, Serialize)] struct RuntimePk4InspectionOutput { path: String, @@ -235,6 +328,85 @@ struct RuntimeCandidateTableComparisonReport { differences: Vec, } +#[derive(Debug, Clone, Serialize)] +struct RuntimeRecipeBookLineSample { + path: String, + profile_family: String, + source_kind: String, + book_count: usize, + book_stride_hex: String, + line_count: usize, + line_stride_hex: String, + book_head_kind_by_index: BTreeMap, + book_line_area_kind_by_index: BTreeMap, + max_annual_production_word_hex_by_book: BTreeMap, + line_kind_by_path: BTreeMap, + mode_word_hex_by_path: BTreeMap, + annual_amount_word_hex_by_path: BTreeMap, + supplied_cargo_token_word_hex_by_path: BTreeMap, + demanded_cargo_token_word_hex_by_path: BTreeMap, +} + +#[derive(Debug, Serialize)] +struct RuntimeRecipeBookLineComparisonReport { + file_count: usize, + matches: bool, + content_matches: bool, + common_profile_family: Option, + samples: Vec, + difference_count: usize, + differences: Vec, + content_difference_count: usize, + content_differences: Vec, +} + +#[derive(Debug, Clone)] +struct RuntimeRecipeBookLineScanSample { + path: String, + profile_family: String, + source_kind: String, + nonzero_mode_paths: BTreeMap, + nonzero_supplied_token_paths: BTreeMap, + nonzero_demanded_token_paths: BTreeMap, +} + +#[derive(Debug, Serialize)] +struct RuntimeRecipeBookLineFieldSummary { + line_path: String, + file_count_present: usize, + distinct_value_count: usize, + sample_value_hexes: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimeRecipeBookLineFamilySummary { + profile_family: String, + source_kinds: Vec, + file_count: usize, + files_with_any_nonzero_modes_count: usize, + files_with_any_nonzero_supplied_tokens_count: usize, + files_with_any_nonzero_demanded_tokens_count: usize, + stable_nonzero_mode_paths: Vec, + stable_nonzero_supplied_token_paths: Vec, + stable_nonzero_demanded_token_paths: Vec, + mode_summaries: Vec, + supplied_token_summaries: Vec, + demanded_token_summaries: Vec, + sample_paths: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimeRecipeBookLineScanReport { + root_path: String, + file_count: usize, + files_with_probe_count: usize, + files_with_any_nonzero_modes_count: usize, + files_with_any_nonzero_supplied_tokens_count: usize, + files_with_any_nonzero_demanded_tokens_count: usize, + skipped_file_count: usize, + family_summaries: Vec, +} + #[derive(Debug, Serialize)] struct RuntimeSetupPayloadCoreSample { path: String, @@ -296,6 +468,25 @@ struct RuntimeSetupLaunchPayloadComparisonReport { differences: Vec, } +#[derive(Debug, Serialize)] +struct RuntimePostSpecialConditionsScalarSample { + path: String, + profile_family: String, + source_kind: String, + nonzero_relative_offset_hexes: Vec, + values_by_relative_offset_hex: BTreeMap, +} + +#[derive(Debug, Serialize)] +struct RuntimePostSpecialConditionsScalarComparisonReport { + file_count: usize, + matches: bool, + common_profile_family: Option, + samples: Vec, + difference_count: usize, + differences: Vec, +} + #[derive(Debug, Serialize)] struct RuntimeCandidateTableHeaderCluster { header_word_0_hex: String, @@ -330,6 +521,157 @@ struct RuntimeCandidateTableHeaderScanSample { zero_trailer_entry_names: Vec, } +#[derive(Debug, Clone, Serialize)] +struct RuntimeSpecialConditionsScanSample { + path: String, + profile_family: String, + source_kind: String, + enabled_visible_count: usize, + enabled_visible_labels: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimeSpecialConditionsSlotSummary { + slot_index: u8, + label: String, + file_count_enabled: usize, + sample_paths: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimeSpecialConditionsScanReport { + root_path: String, + file_count: usize, + files_with_probe_count: usize, + files_with_any_enabled_count: usize, + skipped_file_count: usize, + enabled_slot_summaries: Vec, + sample_files_with_any_enabled: Vec, +} + +#[derive(Debug, Clone)] +struct RuntimePostSpecialConditionsScalarScanSample { + path: String, + profile_family: String, + source_kind: String, + nonzero_relative_offsets: Vec, + values_by_relative_offset_hex: BTreeMap, +} + +#[derive(Debug, Serialize)] +struct RuntimePostSpecialConditionsScalarOffsetSummary { + relative_offset_hex: String, + file_count_present: usize, + distinct_value_count: usize, + sample_value_hexes: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimePostSpecialConditionsScalarFamilySummary { + profile_family: String, + source_kinds: Vec, + file_count: usize, + files_with_any_nonzero_count: usize, + distinct_nonzero_offset_set_count: usize, + stable_nonzero_relative_offset_hexes: Vec, + union_nonzero_relative_offset_hexes: Vec, + offset_summaries: Vec, + sample_paths: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimePostSpecialConditionsScalarScanReport { + root_path: String, + file_count: usize, + files_with_probe_count: usize, + files_with_any_nonzero_count: usize, + skipped_file_count: usize, + family_summaries: Vec, +} + +#[derive(Debug, Clone)] +struct RuntimePostSpecialConditionsTailScanSample { + path: String, + profile_family: String, + source_kind: String, + nonzero_relative_offsets: Vec, + values_by_relative_offset_hex: BTreeMap, +} + +#[derive(Debug, Serialize)] +struct RuntimePostSpecialConditionsTailOffsetSummary { + relative_offset_hex: String, + file_count_present: usize, + distinct_value_count: usize, + sample_value_hexes: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimePostSpecialConditionsTailFamilySummary { + profile_family: String, + source_kinds: Vec, + file_count: usize, + files_with_any_nonzero_count: usize, + distinct_nonzero_offset_set_count: usize, + stable_nonzero_relative_offset_hexes: Vec, + union_nonzero_relative_offset_hexes: Vec, + offset_summaries: Vec, + sample_paths: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimePostSpecialConditionsTailScanReport { + root_path: String, + file_count: usize, + files_with_probe_count: usize, + files_with_any_nonzero_count: usize, + skipped_file_count: usize, + family_summaries: Vec, +} + +#[derive(Debug, Clone)] +struct RuntimeAlignedRuntimeRuleBandScanSample { + path: String, + profile_family: String, + source_kind: String, + nonzero_band_indices: Vec, + values_by_band_index: BTreeMap, +} + +#[derive(Debug, Serialize)] +struct RuntimeAlignedRuntimeRuleBandOffsetSummary { + band_index: usize, + relative_offset_hex: String, + lane_kind: String, + known_label: Option, + file_count_present: usize, + distinct_value_count: usize, + sample_value_hexes: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimeAlignedRuntimeRuleBandFamilySummary { + profile_family: String, + source_kinds: Vec, + file_count: usize, + files_with_any_nonzero_count: usize, + distinct_nonzero_index_set_count: usize, + stable_nonzero_band_indices: Vec, + union_nonzero_band_indices: Vec, + offset_summaries: Vec, + sample_paths: Vec, +} + +#[derive(Debug, Serialize)] +struct RuntimeAlignedRuntimeRuleBandScanReport { + root_path: String, + file_count: usize, + files_with_probe_count: usize, + files_with_any_nonzero_count: usize, + skipped_file_count: usize, + family_summaries: Vec, +} + #[derive(Debug, Serialize)] struct RuntimeProfileBlockExportDocument { source_path: String, @@ -394,6 +736,18 @@ fn real_main() -> Result<(), Box> { Command::RuntimeInspectSmp { smp_path } => { run_runtime_inspect_smp(&smp_path)?; } + Command::RuntimeSummarizeSaveLoad { smp_path } => { + run_runtime_summarize_save_load(&smp_path)?; + } + Command::RuntimeLoadSaveSlice { smp_path } => { + run_runtime_load_save_slice(&smp_path)?; + } + Command::RuntimeImportSaveState { + smp_path, + output_path, + } => { + run_runtime_import_save_state(&smp_path, &output_path)?; + } Command::RuntimeInspectPk4 { pk4_path } => { run_runtime_inspect_pk4(&pk4_path)?; } @@ -419,15 +773,36 @@ fn real_main() -> Result<(), Box> { Command::RuntimeCompareCandidateTable { smp_paths } => { run_runtime_compare_candidate_table(&smp_paths)?; } + Command::RuntimeCompareRecipeBookLines { smp_paths } => { + run_runtime_compare_recipe_book_lines(&smp_paths)?; + } Command::RuntimeCompareSetupPayloadCore { smp_paths } => { run_runtime_compare_setup_payload_core(&smp_paths)?; } Command::RuntimeCompareSetupLaunchPayload { smp_paths } => { run_runtime_compare_setup_launch_payload(&smp_paths)?; } + Command::RuntimeComparePostSpecialConditionsScalars { smp_paths } => { + run_runtime_compare_post_special_conditions_scalars(&smp_paths)?; + } Command::RuntimeScanCandidateTableHeaders { root_path } => { run_runtime_scan_candidate_table_headers(&root_path)?; } + Command::RuntimeScanSpecialConditions { root_path } => { + run_runtime_scan_special_conditions(&root_path)?; + } + Command::RuntimeScanAlignedRuntimeRuleBand { root_path } => { + run_runtime_scan_aligned_runtime_rule_band(&root_path)?; + } + Command::RuntimeScanPostSpecialConditionsScalars { root_path } => { + run_runtime_scan_post_special_conditions_scalars(&root_path)?; + } + Command::RuntimeScanPostSpecialConditionsTail { root_path } => { + run_runtime_scan_post_special_conditions_tail(&root_path)?; + } + Command::RuntimeScanRecipeBookLines { root_path } => { + run_runtime_scan_recipe_book_lines(&root_path)?; + } Command::RuntimeExportProfileBlock { smp_path, output_path, @@ -502,6 +877,28 @@ fn parse_command() -> Result> { smp_path: PathBuf::from(path), }) } + [command, subcommand, path] + if command == "runtime" && subcommand == "summarize-save-load" => + { + Ok(Command::RuntimeSummarizeSaveLoad { + smp_path: PathBuf::from(path), + }) + } + [command, subcommand, path] + if command == "runtime" && subcommand == "load-save-slice" => + { + Ok(Command::RuntimeLoadSaveSlice { + smp_path: PathBuf::from(path), + }) + } + [command, subcommand, smp_path, output_path] + if command == "runtime" && subcommand == "import-save-state" => + { + Ok(Command::RuntimeImportSaveState { + smp_path: PathBuf::from(smp_path), + output_path: PathBuf::from(output_path), + }) + } [command, subcommand, path] if command == "runtime" && subcommand == "inspect-pk4" => { Ok(Command::RuntimeInspectPk4 { pk4_path: PathBuf::from(path), @@ -555,6 +952,15 @@ fn parse_command() -> Result> { smp_paths: smp_paths.iter().map(PathBuf::from).collect(), }) } + [command, subcommand, smp_paths @ ..] + if command == "runtime" + && subcommand == "compare-recipe-book-lines" + && smp_paths.len() >= 2 => + { + Ok(Command::RuntimeCompareRecipeBookLines { + smp_paths: smp_paths.iter().map(PathBuf::from).collect(), + }) + } [command, subcommand, smp_paths @ ..] if command == "runtime" && subcommand == "compare-setup-payload-core" @@ -573,6 +979,15 @@ fn parse_command() -> Result> { smp_paths: smp_paths.iter().map(PathBuf::from).collect(), }) } + [command, subcommand, smp_paths @ ..] + if command == "runtime" + && subcommand == "compare-post-special-conditions-scalars" + && smp_paths.len() >= 2 => + { + Ok(Command::RuntimeComparePostSpecialConditionsScalars { + smp_paths: smp_paths.iter().map(PathBuf::from).collect(), + }) + } [command, subcommand, root_path] if command == "runtime" && subcommand == "scan-candidate-table-headers" => { @@ -580,6 +995,41 @@ fn parse_command() -> Result> { root_path: PathBuf::from(root_path), }) } + [command, subcommand, root_path] + if command == "runtime" && subcommand == "scan-special-conditions" => + { + Ok(Command::RuntimeScanSpecialConditions { + root_path: PathBuf::from(root_path), + }) + } + [command, subcommand, root_path] + if command == "runtime" && subcommand == "scan-aligned-runtime-rule-band" => + { + Ok(Command::RuntimeScanAlignedRuntimeRuleBand { + root_path: PathBuf::from(root_path), + }) + } + [command, subcommand, root_path] + if command == "runtime" && subcommand == "scan-post-special-conditions-scalars" => + { + Ok(Command::RuntimeScanPostSpecialConditionsScalars { + root_path: PathBuf::from(root_path), + }) + } + [command, subcommand, root_path] + if command == "runtime" && subcommand == "scan-post-special-conditions-tail" => + { + Ok(Command::RuntimeScanPostSpecialConditionsTail { + root_path: PathBuf::from(root_path), + }) + } + [command, subcommand, root_path] + if command == "runtime" && subcommand == "scan-recipe-book-lines" => + { + Ok(Command::RuntimeScanRecipeBookLines { + root_path: PathBuf::from(root_path), + }) + } [command, subcommand, smp_path, output_path] if command == "runtime" && subcommand == "export-profile-block" => { @@ -589,7 +1039,7 @@ fn parse_command() -> Result> { }) } _ => Err( - "usage: rrt-cli [validate [repo-root] | finance eval | finance diff | runtime validate-fixture | runtime summarize-fixture | runtime export-fixture-state | runtime summarize-state | runtime import-state | runtime inspect-smp | runtime inspect-pk4 | runtime inspect-win | runtime extract-pk4-entry | runtime inspect-campaign-exe | runtime compare-classic-profile [saveN.gms...] | runtime compare-105-profile [saveN.gms...] | runtime compare-candidate-table [fileN...] | runtime compare-setup-payload-core [fileN...] | runtime compare-setup-launch-payload [fileN...] | runtime scan-candidate-table-headers | runtime export-profile-block ]" + "usage: rrt-cli [validate [repo-root] | finance eval | finance diff | runtime validate-fixture | runtime summarize-fixture | runtime export-fixture-state | runtime summarize-state | runtime import-state | runtime inspect-smp | runtime summarize-save-load | runtime load-save-slice | runtime import-save-state | runtime inspect-pk4 | runtime inspect-win | runtime extract-pk4-entry | runtime inspect-campaign-exe | runtime compare-classic-profile [saveN.gms...] | runtime compare-105-profile [saveN.gms...] | runtime compare-candidate-table [fileN...] | runtime compare-recipe-book-lines [fileN...] | runtime compare-setup-payload-core [fileN...] | runtime compare-setup-launch-payload [fileN...] | runtime compare-post-special-conditions-scalars [fileN...] | runtime scan-candidate-table-headers | runtime scan-special-conditions | runtime scan-aligned-runtime-rule-band | runtime scan-post-special-conditions-scalars | runtime scan-post-special-conditions-tail | runtime scan-recipe-book-lines | runtime export-profile-block ]" .into(), ), } @@ -748,6 +1198,66 @@ fn run_runtime_inspect_smp(smp_path: &Path) -> Result<(), Box Result<(), Box> { + let inspection = inspect_smp_file(smp_path)?; + let summary = inspection.save_load_summary.ok_or_else(|| { + format!( + "{} did not expose a recognizable save-load summary", + smp_path.display() + ) + })?; + let report = RuntimeSaveLoadSummaryOutput { + path: smp_path.display().to_string(), + summary, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + +fn run_runtime_load_save_slice(smp_path: &Path) -> Result<(), Box> { + let report = RuntimeLoadedSaveSliceOutput { + path: smp_path.display().to_string(), + save_slice: load_save_slice_file(smp_path)?, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + +fn run_runtime_import_save_state( + smp_path: &Path, + output_path: &Path, +) -> Result<(), Box> { + let save_slice = load_save_slice_file(smp_path)?; + let import = project_save_slice_to_runtime_state_import( + &save_slice, + smp_path + .file_stem() + .and_then(|stem| stem.to_str()) + .unwrap_or("save-state"), + Some(format!( + "Projected partial runtime state from save {}", + smp_path.display() + )), + ) + .map_err(|err| format!("failed to project save slice: {err}"))?; + let snapshot = RuntimeSnapshotDocument { + format_version: SNAPSHOT_FORMAT_VERSION, + snapshot_id: format!("{}-snapshot", import.import_id), + source: RuntimeSnapshotSource { + source_fixture_id: None, + description: import.description, + }, + state: import.state, + }; + save_runtime_snapshot_document(output_path, &snapshot)?; + let report = RuntimeStateSummaryReport { + snapshot_id: snapshot.snapshot_id.clone(), + summary: snapshot.summary(), + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + fn run_runtime_inspect_pk4(pk4_path: &Path) -> Result<(), Box> { let report = RuntimePk4InspectionOutput { path: pk4_path.display().to_string(), @@ -882,6 +1392,38 @@ fn run_runtime_compare_candidate_table( Ok(()) } +fn run_runtime_compare_recipe_book_lines( + smp_paths: &[PathBuf], +) -> Result<(), Box> { + let samples = smp_paths + .iter() + .map(|path| load_recipe_book_line_sample(path)) + .collect::, _>>()?; + let common_profile_family = samples + .first() + .map(|sample| sample.profile_family.clone()) + .filter(|family| { + samples + .iter() + .all(|sample| sample.profile_family == *family) + }); + let differences = diff_recipe_book_line_samples(&samples)?; + let content_differences = diff_recipe_book_line_content_samples(&samples)?; + let report = RuntimeRecipeBookLineComparisonReport { + file_count: samples.len(), + matches: differences.is_empty(), + content_matches: content_differences.is_empty(), + common_profile_family, + difference_count: differences.len(), + differences, + content_difference_count: content_differences.len(), + content_differences, + samples, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + fn run_runtime_compare_setup_payload_core( smp_paths: &[PathBuf], ) -> Result<(), Box> { @@ -920,6 +1462,34 @@ fn run_runtime_compare_setup_launch_payload( Ok(()) } +fn run_runtime_compare_post_special_conditions_scalars( + smp_paths: &[PathBuf], +) -> Result<(), Box> { + let samples = smp_paths + .iter() + .map(|path| load_post_special_conditions_scalar_sample(path)) + .collect::, _>>()?; + let common_profile_family = samples + .first() + .map(|sample| sample.profile_family.clone()) + .filter(|family| { + samples + .iter() + .all(|sample| sample.profile_family == *family) + }); + let differences = diff_post_special_conditions_scalar_samples(&samples)?; + let report = RuntimePostSpecialConditionsScalarComparisonReport { + file_count: samples.len(), + matches: differences.is_empty(), + common_profile_family, + difference_count: differences.len(), + differences, + samples, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + fn run_runtime_scan_candidate_table_headers( root_path: &Path, ) -> Result<(), Box> { @@ -1019,6 +1589,589 @@ fn run_runtime_scan_candidate_table_headers( Ok(()) } +fn run_runtime_scan_special_conditions(root_path: &Path) -> Result<(), Box> { + let mut candidate_paths = Vec::new(); + collect_special_conditions_input_paths(root_path, &mut candidate_paths)?; + + let file_count = candidate_paths.len(); + let mut samples = Vec::new(); + let mut skipped_file_count = 0usize; + for path in candidate_paths { + match load_special_conditions_scan_sample(&path) { + Ok(sample) => samples.push(sample), + Err(_) => skipped_file_count += 1, + } + } + + let files_with_probe_count = samples.len(); + let sample_files_with_any_enabled = samples + .iter() + .filter(|sample| sample.enabled_visible_count != 0) + .cloned() + .collect::>(); + let files_with_any_enabled_count = sample_files_with_any_enabled.len(); + + let mut grouped = BTreeMap::<(u8, String), Vec>::new(); + for sample in &samples { + for label in &sample.enabled_visible_labels { + if let Some(slot_index) = parse_special_condition_slot_index(label) { + grouped + .entry((slot_index, label.clone())) + .or_default() + .push(sample.path.clone()); + } + } + } + + let enabled_slot_summaries = grouped + .into_iter() + .map( + |((slot_index, label), paths)| RuntimeSpecialConditionsSlotSummary { + slot_index, + label, + file_count_enabled: paths.len(), + sample_paths: paths.into_iter().take(12).collect(), + }, + ) + .collect::>(); + + let report = RuntimeSpecialConditionsScanReport { + root_path: root_path.display().to_string(), + file_count, + files_with_probe_count, + files_with_any_enabled_count, + skipped_file_count, + enabled_slot_summaries, + sample_files_with_any_enabled, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + +fn run_runtime_scan_aligned_runtime_rule_band( + root_path: &Path, +) -> Result<(), Box> { + let mut candidate_paths = Vec::new(); + collect_special_conditions_input_paths(root_path, &mut candidate_paths)?; + + let file_count = candidate_paths.len(); + let mut samples = Vec::new(); + let mut skipped_file_count = 0usize; + for path in candidate_paths { + match load_aligned_runtime_rule_band_scan_sample(&path) { + Ok(sample) => samples.push(sample), + Err(_) => skipped_file_count += 1, + } + } + + let files_with_probe_count = samples.len(); + let files_with_any_nonzero_count = samples + .iter() + .filter(|sample| !sample.nonzero_band_indices.is_empty()) + .count(); + + let mut grouped = BTreeMap::>::new(); + for sample in samples { + grouped + .entry(sample.profile_family.clone()) + .or_default() + .push(sample); + } + + let family_summaries = grouped + .into_iter() + .map(|(profile_family, samples)| { + let file_count = samples.len(); + let files_with_any_nonzero_count = samples + .iter() + .filter(|sample| !sample.nonzero_band_indices.is_empty()) + .count(); + let source_kinds = samples + .iter() + .map(|sample| sample.source_kind.clone()) + .collect::>() + .into_iter() + .collect::>(); + let distinct_nonzero_index_set_count = samples + .iter() + .map(|sample| sample.nonzero_band_indices.clone()) + .collect::>() + .len(); + + let stable_band_indices = if samples.is_empty() { + BTreeSet::new() + } else { + let mut stable = samples[0] + .nonzero_band_indices + .iter() + .copied() + .collect::>(); + for sample in samples.iter().skip(1) { + let current = sample + .nonzero_band_indices + .iter() + .copied() + .collect::>(); + stable = stable.intersection(¤t).copied().collect(); + } + stable + }; + + let mut band_values = BTreeMap::>::new(); + let mut band_counts = BTreeMap::::new(); + for sample in &samples { + for band_index in &sample.nonzero_band_indices { + *band_counts.entry(*band_index).or_default() += 1; + } + for (band_index, value_hex) in &sample.values_by_band_index { + band_values + .entry(*band_index) + .or_default() + .insert(value_hex.clone()); + } + } + + let offset_summaries = band_counts + .into_iter() + .map( + |(band_index, count)| RuntimeAlignedRuntimeRuleBandOffsetSummary { + band_index, + relative_offset_hex: format!("0x{:x}", band_index * 4), + lane_kind: aligned_runtime_rule_lane_kind(band_index).to_string(), + known_label: aligned_runtime_rule_known_label(band_index) + .map(str::to_string), + file_count_present: count, + distinct_value_count: band_values + .get(&band_index) + .map(BTreeSet::len) + .unwrap_or(0), + sample_value_hexes: band_values + .get(&band_index) + .map(|values| values.iter().take(8).cloned().collect()) + .unwrap_or_default(), + }, + ) + .collect::>(); + + RuntimeAlignedRuntimeRuleBandFamilySummary { + profile_family, + source_kinds, + file_count, + files_with_any_nonzero_count, + distinct_nonzero_index_set_count, + stable_nonzero_band_indices: stable_band_indices.into_iter().collect(), + union_nonzero_band_indices: band_values.keys().copied().collect(), + offset_summaries, + sample_paths: samples + .iter() + .take(12) + .map(|sample| sample.path.clone()) + .collect(), + } + }) + .collect::>(); + + let report = RuntimeAlignedRuntimeRuleBandScanReport { + root_path: root_path.display().to_string(), + file_count, + files_with_probe_count, + files_with_any_nonzero_count, + skipped_file_count, + family_summaries, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + +fn run_runtime_scan_post_special_conditions_scalars( + root_path: &Path, +) -> Result<(), Box> { + let mut candidate_paths = Vec::new(); + collect_special_conditions_input_paths(root_path, &mut candidate_paths)?; + + let file_count = candidate_paths.len(); + let mut samples = Vec::new(); + let mut skipped_file_count = 0usize; + for path in candidate_paths { + match load_post_special_conditions_scalar_scan_sample(&path) { + Ok(sample) => samples.push(sample), + Err(_) => skipped_file_count += 1, + } + } + + let files_with_probe_count = samples.len(); + let files_with_any_nonzero_count = samples + .iter() + .filter(|sample| !sample.nonzero_relative_offsets.is_empty()) + .count(); + + let mut grouped = BTreeMap::>::new(); + for sample in samples { + grouped + .entry(sample.profile_family.clone()) + .or_default() + .push(sample); + } + + let family_summaries = grouped + .into_iter() + .map(|(profile_family, samples)| { + let file_count = samples.len(); + let files_with_any_nonzero_count = samples + .iter() + .filter(|sample| !sample.nonzero_relative_offsets.is_empty()) + .count(); + let source_kinds = samples + .iter() + .map(|sample| sample.source_kind.clone()) + .collect::>() + .into_iter() + .collect::>(); + let distinct_nonzero_offset_set_count = samples + .iter() + .map(|sample| sample.nonzero_relative_offsets.clone()) + .collect::>() + .len(); + + let stable_offsets = if samples.is_empty() { + BTreeSet::new() + } else { + let mut stable = samples[0] + .nonzero_relative_offsets + .iter() + .copied() + .collect::>(); + for sample in samples.iter().skip(1) { + let current = sample + .nonzero_relative_offsets + .iter() + .copied() + .collect::>(); + stable = stable.intersection(¤t).copied().collect(); + } + stable + }; + + let mut offset_values = BTreeMap::>::new(); + let mut offset_counts = BTreeMap::::new(); + for sample in &samples { + for offset in &sample.nonzero_relative_offsets { + *offset_counts.entry(*offset).or_default() += 1; + } + for (offset_hex, value_hex) in &sample.values_by_relative_offset_hex { + if let Some(offset) = parse_hex_offset(offset_hex) { + offset_values + .entry(offset) + .or_default() + .insert(value_hex.clone()); + } + } + } + + let offset_summaries = offset_counts + .into_iter() + .map( + |(offset, count)| RuntimePostSpecialConditionsScalarOffsetSummary { + relative_offset_hex: format!("0x{offset:x}"), + file_count_present: count, + distinct_value_count: offset_values + .get(&offset) + .map(BTreeSet::len) + .unwrap_or(0), + sample_value_hexes: offset_values + .get(&offset) + .map(|values| values.iter().take(8).cloned().collect()) + .unwrap_or_default(), + }, + ) + .collect::>(); + + RuntimePostSpecialConditionsScalarFamilySummary { + profile_family, + source_kinds, + file_count, + files_with_any_nonzero_count, + distinct_nonzero_offset_set_count, + stable_nonzero_relative_offset_hexes: stable_offsets + .into_iter() + .map(|offset| format!("0x{offset:x}")) + .collect(), + union_nonzero_relative_offset_hexes: offset_values + .keys() + .copied() + .map(|offset| format!("0x{offset:x}")) + .collect(), + offset_summaries, + sample_paths: samples + .iter() + .take(12) + .map(|sample| sample.path.clone()) + .collect(), + } + }) + .collect::>(); + + let report = RuntimePostSpecialConditionsScalarScanReport { + root_path: root_path.display().to_string(), + file_count, + files_with_probe_count, + files_with_any_nonzero_count, + skipped_file_count, + family_summaries, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + +fn run_runtime_scan_post_special_conditions_tail( + root_path: &Path, +) -> Result<(), Box> { + let mut candidate_paths = Vec::new(); + collect_special_conditions_input_paths(root_path, &mut candidate_paths)?; + + let file_count = candidate_paths.len(); + let mut samples = Vec::new(); + let mut skipped_file_count = 0usize; + for path in candidate_paths { + match load_post_special_conditions_tail_scan_sample(&path) { + Ok(sample) => samples.push(sample), + Err(_) => skipped_file_count += 1, + } + } + + let files_with_probe_count = samples.len(); + let files_with_any_nonzero_count = samples + .iter() + .filter(|sample| !sample.nonzero_relative_offsets.is_empty()) + .count(); + + let mut grouped = BTreeMap::>::new(); + for sample in samples { + grouped + .entry(sample.profile_family.clone()) + .or_default() + .push(sample); + } + + let family_summaries = grouped + .into_iter() + .map(|(profile_family, samples)| { + let file_count = samples.len(); + let files_with_any_nonzero_count = samples + .iter() + .filter(|sample| !sample.nonzero_relative_offsets.is_empty()) + .count(); + let source_kinds = samples + .iter() + .map(|sample| sample.source_kind.clone()) + .collect::>() + .into_iter() + .collect::>(); + let distinct_nonzero_offset_set_count = samples + .iter() + .map(|sample| sample.nonzero_relative_offsets.clone()) + .collect::>() + .len(); + + let stable_offsets = if samples.is_empty() { + BTreeSet::new() + } else { + let mut stable = samples[0] + .nonzero_relative_offsets + .iter() + .copied() + .collect::>(); + for sample in samples.iter().skip(1) { + let current = sample + .nonzero_relative_offsets + .iter() + .copied() + .collect::>(); + stable = stable.intersection(¤t).copied().collect(); + } + stable + }; + + let mut offset_values = BTreeMap::>::new(); + let mut offset_counts = BTreeMap::::new(); + for sample in &samples { + for offset in &sample.nonzero_relative_offsets { + *offset_counts.entry(*offset).or_default() += 1; + } + for (offset_hex, value_hex) in &sample.values_by_relative_offset_hex { + if let Some(offset) = parse_hex_offset(offset_hex) { + offset_values + .entry(offset) + .or_default() + .insert(value_hex.clone()); + } + } + } + + let offset_summaries = offset_counts + .into_iter() + .map( + |(offset, count)| RuntimePostSpecialConditionsTailOffsetSummary { + relative_offset_hex: format!("0x{offset:x}"), + file_count_present: count, + distinct_value_count: offset_values + .get(&offset) + .map(BTreeSet::len) + .unwrap_or(0), + sample_value_hexes: offset_values + .get(&offset) + .map(|values| values.iter().take(8).cloned().collect()) + .unwrap_or_default(), + }, + ) + .collect::>(); + + RuntimePostSpecialConditionsTailFamilySummary { + profile_family, + source_kinds, + file_count, + files_with_any_nonzero_count, + distinct_nonzero_offset_set_count, + stable_nonzero_relative_offset_hexes: stable_offsets + .into_iter() + .map(|offset| format!("0x{offset:x}")) + .collect(), + union_nonzero_relative_offset_hexes: offset_values + .keys() + .copied() + .map(|offset| format!("0x{offset:x}")) + .collect(), + offset_summaries, + sample_paths: samples + .iter() + .take(12) + .map(|sample| sample.path.clone()) + .collect(), + } + }) + .collect::>(); + + let report = RuntimePostSpecialConditionsTailScanReport { + root_path: root_path.display().to_string(), + file_count, + files_with_probe_count, + files_with_any_nonzero_count, + skipped_file_count, + family_summaries, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + +fn run_runtime_scan_recipe_book_lines(root_path: &Path) -> Result<(), Box> { + let mut candidate_paths = Vec::new(); + collect_special_conditions_input_paths(root_path, &mut candidate_paths)?; + + let file_count = candidate_paths.len(); + let mut samples = Vec::new(); + let mut skipped_file_count = 0usize; + for path in candidate_paths { + match load_recipe_book_line_scan_sample(&path) { + Ok(sample) => samples.push(sample), + Err(_) => skipped_file_count += 1, + } + } + + let files_with_probe_count = samples.len(); + let files_with_any_nonzero_modes_count = samples + .iter() + .filter(|sample| !sample.nonzero_mode_paths.is_empty()) + .count(); + let files_with_any_nonzero_supplied_tokens_count = samples + .iter() + .filter(|sample| !sample.nonzero_supplied_token_paths.is_empty()) + .count(); + let files_with_any_nonzero_demanded_tokens_count = samples + .iter() + .filter(|sample| !sample.nonzero_demanded_token_paths.is_empty()) + .count(); + + let mut grouped = BTreeMap::>::new(); + for sample in samples { + grouped + .entry(sample.profile_family.clone()) + .or_default() + .push(sample); + } + + let family_summaries = grouped + .into_iter() + .map( + |(profile_family, samples)| RuntimeRecipeBookLineFamilySummary { + profile_family, + source_kinds: samples + .iter() + .map(|sample| sample.source_kind.clone()) + .collect::>() + .into_iter() + .collect(), + file_count: samples.len(), + files_with_any_nonzero_modes_count: samples + .iter() + .filter(|sample| !sample.nonzero_mode_paths.is_empty()) + .count(), + files_with_any_nonzero_supplied_tokens_count: samples + .iter() + .filter(|sample| !sample.nonzero_supplied_token_paths.is_empty()) + .count(), + files_with_any_nonzero_demanded_tokens_count: samples + .iter() + .filter(|sample| !sample.nonzero_demanded_token_paths.is_empty()) + .count(), + stable_nonzero_mode_paths: intersect_nonzero_recipe_line_paths( + samples.iter().map(|sample| &sample.nonzero_mode_paths), + ), + stable_nonzero_supplied_token_paths: intersect_nonzero_recipe_line_paths( + samples + .iter() + .map(|sample| &sample.nonzero_supplied_token_paths), + ), + stable_nonzero_demanded_token_paths: intersect_nonzero_recipe_line_paths( + samples + .iter() + .map(|sample| &sample.nonzero_demanded_token_paths), + ), + mode_summaries: build_recipe_line_field_summaries( + samples.iter().map(|sample| &sample.nonzero_mode_paths), + ), + supplied_token_summaries: build_recipe_line_field_summaries( + samples + .iter() + .map(|sample| &sample.nonzero_supplied_token_paths), + ), + demanded_token_summaries: build_recipe_line_field_summaries( + samples + .iter() + .map(|sample| &sample.nonzero_demanded_token_paths), + ), + sample_paths: samples + .iter() + .take(12) + .map(|sample| sample.path.clone()) + .collect(), + }, + ) + .collect::>(); + + let report = RuntimeRecipeBookLineScanReport { + root_path: root_path.display().to_string(), + file_count, + files_with_probe_count, + files_with_any_nonzero_modes_count, + files_with_any_nonzero_supplied_tokens_count, + files_with_any_nonzero_demanded_tokens_count, + skipped_file_count, + family_summaries, + }; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} + fn run_runtime_export_profile_block( smp_path: &Path, output_path: &Path, @@ -1112,6 +2265,92 @@ fn load_candidate_table_sample( }) } +fn load_recipe_book_line_sample( + smp_path: &Path, +) -> Result> { + let inspection = inspect_smp_file(smp_path)?; + let probe = inspection.recipe_book_summary_probe.ok_or_else(|| { + format!( + "{} did not expose a grounded recipe-book summary block", + smp_path.display() + ) + })?; + + let mut book_head_kind_by_index = BTreeMap::new(); + let mut book_line_area_kind_by_index = BTreeMap::new(); + let mut max_annual_production_word_hex_by_book = BTreeMap::new(); + let mut line_kind_by_path = BTreeMap::new(); + let mut mode_word_hex_by_path = BTreeMap::new(); + let mut annual_amount_word_hex_by_path = BTreeMap::new(); + let mut supplied_cargo_token_word_hex_by_path = BTreeMap::new(); + let mut demanded_cargo_token_word_hex_by_path = BTreeMap::new(); + + for book in &probe.books { + let book_key = format!("book{:02}", book.book_index); + book_head_kind_by_index.insert(book_key.clone(), book.head_kind.clone()); + book_line_area_kind_by_index.insert(book_key.clone(), book.line_area_kind.clone()); + max_annual_production_word_hex_by_book.insert( + book_key.clone(), + book.max_annual_production_word_hex.clone(), + ); + for line in &book.lines { + let line_key = format!("{book_key}.line{:02}", line.line_index); + line_kind_by_path.insert(line_key.clone(), line.line_kind.clone()); + mode_word_hex_by_path.insert(line_key.clone(), line.mode_word_hex.clone()); + annual_amount_word_hex_by_path + .insert(line_key.clone(), line.annual_amount_word_hex.clone()); + supplied_cargo_token_word_hex_by_path + .insert(line_key.clone(), line.supplied_cargo_token_word_hex.clone()); + demanded_cargo_token_word_hex_by_path + .insert(line_key.clone(), line.demanded_cargo_token_word_hex.clone()); + } + } + + Ok(RuntimeRecipeBookLineSample { + path: smp_path.display().to_string(), + profile_family: probe.profile_family, + source_kind: probe.source_kind, + book_count: probe.book_count, + book_stride_hex: probe.book_stride_hex, + line_count: probe.line_count, + line_stride_hex: probe.line_stride_hex, + book_head_kind_by_index, + book_line_area_kind_by_index, + max_annual_production_word_hex_by_book, + line_kind_by_path, + mode_word_hex_by_path, + annual_amount_word_hex_by_path, + supplied_cargo_token_word_hex_by_path, + demanded_cargo_token_word_hex_by_path, + }) +} + +fn load_recipe_book_line_scan_sample( + smp_path: &Path, +) -> Result> { + let sample = load_recipe_book_line_sample(smp_path)?; + Ok(RuntimeRecipeBookLineScanSample { + path: sample.path, + profile_family: sample.profile_family, + source_kind: sample.source_kind, + nonzero_mode_paths: sample + .mode_word_hex_by_path + .into_iter() + .filter(|(_, value)| value != "0x00000000") + .collect(), + nonzero_supplied_token_paths: sample + .supplied_cargo_token_word_hex_by_path + .into_iter() + .filter(|(_, value)| value != "0x00000000") + .collect(), + nonzero_demanded_token_paths: sample + .demanded_cargo_token_word_hex_by_path + .into_iter() + .filter(|(_, value)| value != "0x00000000") + .collect(), + }) +} + fn load_setup_payload_core_sample( smp_path: &Path, ) -> Result> { @@ -1279,6 +2518,23 @@ fn load_setup_launch_payload_sample( }) } +fn load_post_special_conditions_scalar_sample( + smp_path: &Path, +) -> Result> { + let sample = load_post_special_conditions_scalar_scan_sample(smp_path)?; + Ok(RuntimePostSpecialConditionsScalarSample { + path: sample.path, + profile_family: sample.profile_family, + source_kind: sample.source_kind, + nonzero_relative_offset_hexes: sample + .nonzero_relative_offsets + .into_iter() + .map(|offset| format!("0x{offset:x}")) + .collect(), + values_by_relative_offset_hex: sample.values_by_relative_offset_hex, + }) +} + fn load_candidate_table_header_scan_sample( smp_path: &Path, ) -> Result> { @@ -1392,6 +2648,300 @@ fn load_candidate_table_header_scan_sample( }) } +fn load_special_conditions_scan_sample( + smp_path: &Path, +) -> Result> { + let bytes = fs::read(smp_path)?; + let table_len = SPECIAL_CONDITION_COUNT * 4; + let table_end = SPECIAL_CONDITIONS_OFFSET + .checked_add(table_len) + .ok_or("special-conditions table overflow")?; + if bytes.len() < table_end { + return Err(format!( + "{} is too small for the fixed special-conditions table", + smp_path.display() + ) + .into()); + } + + let hidden_sentinel = read_u32_le( + &bytes, + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4, + ) + .ok_or_else(|| { + format!( + "{} is missing the hidden special-condition sentinel", + smp_path.display() + ) + })?; + if hidden_sentinel != 1 { + return Err(format!( + "{} does not match the fixed special-conditions table sentinel", + smp_path.display() + ) + .into()); + } + + let enabled_visible_labels = (0..SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT) + .filter_map(|slot_index| { + let value = read_u32_le(&bytes, SPECIAL_CONDITIONS_OFFSET + slot_index * 4)?; + (value != 0).then(|| { + format!( + "slot {}: {}", + slot_index, SPECIAL_CONDITION_LABELS[slot_index] + ) + }) + }) + .collect::>(); + + let extension = smp_path + .extension() + .and_then(|ext| ext.to_str()) + .map(|ext| ext.to_ascii_lowercase()) + .unwrap_or_default(); + let profile_family = classify_candidate_table_header_profile(Some(extension.clone()), &bytes); + let source_kind = match extension.as_str() { + "gmp" => "map-fixed-special-conditions-range", + "gms" => "save-fixed-special-conditions-range", + "gmx" => "sandbox-fixed-special-conditions-range", + _ => "fixed-special-conditions-range", + } + .to_string(); + + Ok(RuntimeSpecialConditionsScanSample { + path: smp_path.display().to_string(), + profile_family, + source_kind, + enabled_visible_count: enabled_visible_labels.len(), + enabled_visible_labels, + }) +} + +fn load_post_special_conditions_scalar_scan_sample( + smp_path: &Path, +) -> Result> { + let bytes = fs::read(smp_path)?; + let table_len = SPECIAL_CONDITION_COUNT * 4; + let table_end = SPECIAL_CONDITIONS_OFFSET + .checked_add(table_len) + .ok_or("special-conditions table overflow")?; + if bytes.len() < POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET || bytes.len() < table_end { + return Err(format!( + "{} is too small for the fixed post-special-conditions scalar window", + smp_path.display() + ) + .into()); + } + + let hidden_sentinel = read_u32_le( + &bytes, + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4, + ) + .ok_or_else(|| { + format!( + "{} is missing the hidden special-condition sentinel", + smp_path.display() + ) + })?; + if hidden_sentinel != 1 { + return Err(format!( + "{} does not match the fixed special-conditions table sentinel", + smp_path.display() + ) + .into()); + } + + let extension = smp_path + .extension() + .and_then(|ext| ext.to_str()) + .map(|ext| ext.to_ascii_lowercase()) + .unwrap_or_default(); + let profile_family = classify_candidate_table_header_profile(Some(extension.clone()), &bytes); + let source_kind = match extension.as_str() { + "gmp" => "map-post-special-conditions-window", + "gms" => "save-post-special-conditions-window", + "gmx" => "sandbox-post-special-conditions-window", + _ => "post-special-conditions-window", + } + .to_string(); + + let mut nonzero_relative_offsets = Vec::new(); + let mut values_by_relative_offset_hex = BTreeMap::new(); + for offset in (POST_SPECIAL_CONDITIONS_SCALAR_OFFSET..POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET) + .step_by(4) + { + let value = read_u32_le(&bytes, offset).ok_or_else(|| { + format!( + "{} is truncated inside the fixed post-special-conditions scalar window", + smp_path.display() + ) + })?; + if value == 0 { + continue; + } + let relative_offset = offset - POST_SPECIAL_CONDITIONS_SCALAR_OFFSET; + nonzero_relative_offsets.push(relative_offset); + values_by_relative_offset_hex + .insert(format!("0x{relative_offset:x}"), format!("0x{value:08x}")); + } + + Ok(RuntimePostSpecialConditionsScalarScanSample { + path: smp_path.display().to_string(), + profile_family, + source_kind, + nonzero_relative_offsets, + values_by_relative_offset_hex, + }) +} + +fn load_post_special_conditions_tail_scan_sample( + smp_path: &Path, +) -> Result> { + let bytes = fs::read(smp_path)?; + let table_len = SPECIAL_CONDITION_COUNT * 4; + let table_end = SPECIAL_CONDITIONS_OFFSET + .checked_add(table_len) + .ok_or("special-conditions table overflow")?; + if bytes.len() < POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET || bytes.len() < table_end { + return Err(format!( + "{} is too small for the fixed post-special-conditions tail window", + smp_path.display() + ) + .into()); + } + + let hidden_sentinel = read_u32_le( + &bytes, + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4, + ) + .ok_or_else(|| { + format!( + "{} is missing the hidden special-condition sentinel", + smp_path.display() + ) + })?; + if hidden_sentinel != 1 { + return Err(format!( + "{} does not match the fixed special-conditions table sentinel", + smp_path.display() + ) + .into()); + } + + let extension = smp_path + .extension() + .and_then(|ext| ext.to_str()) + .map(|ext| ext.to_ascii_lowercase()) + .unwrap_or_default(); + let profile_family = classify_candidate_table_header_profile(Some(extension.clone()), &bytes); + let source_kind = match extension.as_str() { + "gmp" => "map-post-special-conditions-tail", + "gms" => "save-post-special-conditions-tail", + "gmx" => "sandbox-post-special-conditions-tail", + _ => "post-special-conditions-tail", + } + .to_string(); + + let mut nonzero_relative_offsets = Vec::new(); + let mut values_by_relative_offset_hex = BTreeMap::new(); + for offset in (POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET + ..POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET) + .step_by(4) + { + let value = read_u32_le(&bytes, offset).ok_or_else(|| { + format!( + "{} is truncated inside the fixed post-special-conditions tail window", + smp_path.display() + ) + })?; + if value == 0 { + continue; + } + let relative_offset = offset - POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET; + nonzero_relative_offsets.push(relative_offset); + values_by_relative_offset_hex + .insert(format!("0x{relative_offset:x}"), format!("0x{value:08x}")); + } + + Ok(RuntimePostSpecialConditionsTailScanSample { + path: smp_path.display().to_string(), + profile_family, + source_kind, + nonzero_relative_offsets, + values_by_relative_offset_hex, + }) +} + +fn load_aligned_runtime_rule_band_scan_sample( + smp_path: &Path, +) -> Result> { + let bytes = fs::read(smp_path)?; + if bytes.len() < SMP_ALIGNED_RUNTIME_RULE_END_OFFSET { + return Err(format!( + "{} is too small for the fixed aligned runtime-rule band", + smp_path.display() + ) + .into()); + } + + let hidden_sentinel = read_u32_le( + &bytes, + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4, + ) + .ok_or_else(|| { + format!( + "{} is missing the hidden special-condition sentinel", + smp_path.display() + ) + })?; + if hidden_sentinel != 1 { + return Err(format!( + "{} does not match the fixed special-conditions table sentinel", + smp_path.display() + ) + .into()); + } + + let extension = smp_path + .extension() + .and_then(|ext| ext.to_str()) + .map(|ext| ext.to_ascii_lowercase()) + .unwrap_or_default(); + let profile_family = classify_candidate_table_header_profile(Some(extension.clone()), &bytes); + let source_kind = match extension.as_str() { + "gmp" => "map-smp-aligned-runtime-rule-band", + "gms" => "save-smp-aligned-runtime-rule-band", + "gmx" => "sandbox-smp-aligned-runtime-rule-band", + _ => "smp-aligned-runtime-rule-band", + } + .to_string(); + + let mut nonzero_band_indices = Vec::new(); + let mut values_by_band_index = BTreeMap::new(); + for band_index in 0..SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT { + let offset = SPECIAL_CONDITIONS_OFFSET + band_index * 4; + let value = read_u32_le(&bytes, offset).ok_or_else(|| { + format!( + "{} is truncated inside the fixed aligned runtime-rule band", + smp_path.display() + ) + })?; + if value == 0 { + continue; + } + nonzero_band_indices.push(band_index); + values_by_band_index.insert(band_index, format!("0x{value:08x}")); + } + + Ok(RuntimeAlignedRuntimeRuleBandScanSample { + path: smp_path.display().to_string(), + profile_family, + source_kind, + nonzero_band_indices, + values_by_band_index, + }) +} + fn collect_candidate_table_input_paths( root_path: &Path, out: &mut Vec, @@ -1441,6 +2991,84 @@ fn collect_candidate_table_input_paths( Ok(()) } +fn collect_special_conditions_input_paths( + root_path: &Path, + out: &mut Vec, +) -> Result<(), Box> { + let metadata = match fs::symlink_metadata(root_path) { + Ok(metadata) => metadata, + Err(err) if err.kind() == std::io::ErrorKind::PermissionDenied => return Ok(()), + Err(err) => return Err(err.into()), + }; + if metadata.file_type().is_symlink() { + return Ok(()); + } + + if root_path.is_file() { + if root_path + .extension() + .and_then(|ext| ext.to_str()) + .is_some_and(|ext| matches!(ext.to_ascii_lowercase().as_str(), "gmp" | "gms" | "gmx")) + { + out.push(root_path.to_path_buf()); + } + return Ok(()); + } + + let entries = match fs::read_dir(root_path) { + Ok(entries) => entries, + Err(err) if err.kind() == std::io::ErrorKind::PermissionDenied => return Ok(()), + Err(err) => return Err(err.into()), + }; + + for entry in entries { + let entry = entry?; + let path = entry.path(); + if path.is_dir() { + collect_special_conditions_input_paths(&path, out)?; + continue; + } + if path + .extension() + .and_then(|ext| ext.to_str()) + .is_some_and(|ext| matches!(ext.to_ascii_lowercase().as_str(), "gmp" | "gms" | "gmx")) + { + out.push(path); + } + } + + Ok(()) +} + +fn parse_special_condition_slot_index(label: &str) -> Option { + let suffix = label.strip_prefix("slot ")?; + let (slot_index, _) = suffix.split_once(':')?; + slot_index.parse().ok() +} + +fn parse_hex_offset(text: &str) -> Option { + text.strip_prefix("0x") + .and_then(|digits| usize::from_str_radix(digits, 16).ok()) +} + +fn aligned_runtime_rule_lane_kind(band_index: usize) -> &'static str { + if band_index < SPECIAL_CONDITION_COUNT { + "known-special-condition-dword" + } else if band_index < SMP_ALIGNED_RUNTIME_RULE_KNOWN_EDITOR_RULE_COUNT { + "unlabeled-editor-rule-dword" + } else { + "trailing-runtime-scalar" + } +} + +fn aligned_runtime_rule_known_label(band_index: usize) -> Option<&'static str> { + if band_index < SPECIAL_CONDITION_LABELS.len() { + Some(SPECIAL_CONDITION_LABELS[band_index]) + } else { + None + } +} + fn matches_candidate_table_header_bytes(bytes: &[u8], header_offset: usize) -> bool { matches!( ( @@ -1594,6 +3222,118 @@ fn diff_candidate_table_samples( Ok(differences) } +fn diff_recipe_book_line_samples( + samples: &[RuntimeRecipeBookLineSample], +) -> Result, Box> { + let labeled_values = samples + .iter() + .map(|sample| { + ( + sample.path.clone(), + serde_json::json!({ + "profile_family": sample.profile_family, + "source_kind": sample.source_kind, + "book_count": sample.book_count, + "book_stride_hex": sample.book_stride_hex, + "line_count": sample.line_count, + "line_stride_hex": sample.line_stride_hex, + "book_head_kind_by_index": sample.book_head_kind_by_index, + "book_line_area_kind_by_index": sample.book_line_area_kind_by_index, + "max_annual_production_word_hex_by_book": sample.max_annual_production_word_hex_by_book, + "line_kind_by_path": sample.line_kind_by_path, + "mode_word_hex_by_path": sample.mode_word_hex_by_path, + "annual_amount_word_hex_by_path": sample.annual_amount_word_hex_by_path, + "supplied_cargo_token_word_hex_by_path": sample.supplied_cargo_token_word_hex_by_path, + "demanded_cargo_token_word_hex_by_path": sample.demanded_cargo_token_word_hex_by_path, + }), + ) + }) + .collect::>(); + let mut differences = Vec::new(); + collect_json_multi_differences("$", &labeled_values, &mut differences); + Ok(differences) +} + +fn diff_recipe_book_line_content_samples( + samples: &[RuntimeRecipeBookLineSample], +) -> Result, Box> { + let labeled_values = samples + .iter() + .map(|sample| { + ( + sample.path.clone(), + serde_json::json!({ + "book_count": sample.book_count, + "book_stride_hex": sample.book_stride_hex, + "line_count": sample.line_count, + "line_stride_hex": sample.line_stride_hex, + "book_head_kind_by_index": sample.book_head_kind_by_index, + "book_line_area_kind_by_index": sample.book_line_area_kind_by_index, + "max_annual_production_word_hex_by_book": sample.max_annual_production_word_hex_by_book, + "line_kind_by_path": sample.line_kind_by_path, + "mode_word_hex_by_path": sample.mode_word_hex_by_path, + "annual_amount_word_hex_by_path": sample.annual_amount_word_hex_by_path, + "supplied_cargo_token_word_hex_by_path": sample.supplied_cargo_token_word_hex_by_path, + "demanded_cargo_token_word_hex_by_path": sample.demanded_cargo_token_word_hex_by_path, + }), + ) + }) + .collect::>(); + let mut differences = Vec::new(); + collect_json_multi_differences("$", &labeled_values, &mut differences); + Ok(differences) +} + +fn intersect_nonzero_recipe_line_paths<'a>( + maps: impl Iterator>, +) -> Vec { + let mut maps = maps.peekable(); + if maps.peek().is_none() { + return Vec::new(); + } + + let mut stable = maps + .next() + .map(|map| map.keys().cloned().collect::>()) + .unwrap_or_default(); + for map in maps { + let current = map.keys().cloned().collect::>(); + stable = stable.intersection(¤t).cloned().collect(); + } + stable.into_iter().collect() +} + +fn build_recipe_line_field_summaries<'a>( + maps: impl Iterator>, +) -> Vec { + let mut value_sets = BTreeMap::>::new(); + let mut counts = BTreeMap::::new(); + for map in maps { + for (line_path, value_hex) in map { + *counts.entry(line_path.clone()).or_default() += 1; + value_sets + .entry(line_path.clone()) + .or_default() + .insert(value_hex.clone()); + } + } + + counts + .into_iter() + .map( + |(line_path, file_count_present)| RuntimeRecipeBookLineFieldSummary { + line_path: line_path.clone(), + file_count_present, + distinct_value_count: value_sets.get(&line_path).map(BTreeSet::len).unwrap_or(0), + sample_value_hexes: value_sets + .get(&line_path) + .map(|values| values.iter().take(8).cloned().collect()) + .unwrap_or_default(), + }, + ) + .collect() +} + fn diff_setup_payload_core_samples( samples: &[RuntimeSetupPayloadCoreSample], ) -> Result, Box> { @@ -1663,6 +3403,28 @@ fn diff_setup_launch_payload_samples( Ok(differences) } +fn diff_post_special_conditions_scalar_samples( + samples: &[RuntimePostSpecialConditionsScalarSample], +) -> Result, Box> { + let labeled_values = samples + .iter() + .map(|sample| { + ( + sample.path.clone(), + serde_json::json!({ + "profile_family": sample.profile_family, + "source_kind": sample.source_kind, + "nonzero_relative_offset_hexes": sample.nonzero_relative_offset_hexes, + "values_by_relative_offset_hex": sample.values_by_relative_offset_hex, + }), + ) + }) + .collect::>(); + let mut differences = Vec::new(); + collect_json_multi_differences("$", &labeled_values, &mut differences); + Ok(differences) +} + fn build_profile_block_export_document( smp_path: &Path, inspection: &SmpInspectionReport, @@ -2376,6 +4138,157 @@ mod tests { ); } + #[test] + fn diffs_recipe_book_line_samples_across_multiple_files() { + let sample_a = RuntimeRecipeBookLineSample { + path: "a.gmp".to_string(), + profile_family: "rt3-105-map-container-v1".to_string(), + source_kind: "recipe-book-summary".to_string(), + book_count: 12, + book_stride_hex: "0x4e1".to_string(), + line_count: 5, + line_stride_hex: "0x30".to_string(), + book_head_kind_by_index: BTreeMap::from([("book00".to_string(), "mixed".to_string())]), + book_line_area_kind_by_index: BTreeMap::from([( + "book00".to_string(), + "mixed".to_string(), + )]), + max_annual_production_word_hex_by_book: BTreeMap::from([( + "book00".to_string(), + "0x41200000".to_string(), + )]), + line_kind_by_path: BTreeMap::from([("book00.line00".to_string(), "mixed".to_string())]), + mode_word_hex_by_path: BTreeMap::from([( + "book00.line00".to_string(), + "0x00000003".to_string(), + )]), + annual_amount_word_hex_by_path: BTreeMap::from([( + "book00.line00".to_string(), + "0x41a00000".to_string(), + )]), + supplied_cargo_token_word_hex_by_path: BTreeMap::from([( + "book00.line00".to_string(), + "0x00000017".to_string(), + )]), + demanded_cargo_token_word_hex_by_path: BTreeMap::from([( + "book00.line00".to_string(), + "0x0000002a".to_string(), + )]), + }; + let sample_b = RuntimeRecipeBookLineSample { + path: "b.gms".to_string(), + profile_family: "rt3-105-alt-save-container-v1".to_string(), + source_kind: "recipe-book-summary".to_string(), + book_count: 12, + book_stride_hex: "0x4e1".to_string(), + line_count: 5, + line_stride_hex: "0x30".to_string(), + book_head_kind_by_index: BTreeMap::from([("book00".to_string(), "mixed".to_string())]), + book_line_area_kind_by_index: BTreeMap::from([( + "book00".to_string(), + "mixed".to_string(), + )]), + max_annual_production_word_hex_by_book: BTreeMap::from([( + "book00".to_string(), + "0x41200000".to_string(), + )]), + line_kind_by_path: BTreeMap::from([("book00.line00".to_string(), "zero".to_string())]), + mode_word_hex_by_path: BTreeMap::from([( + "book00.line00".to_string(), + "0x00000000".to_string(), + )]), + annual_amount_word_hex_by_path: BTreeMap::from([( + "book00.line00".to_string(), + "0x00000000".to_string(), + )]), + supplied_cargo_token_word_hex_by_path: BTreeMap::from([( + "book00.line00".to_string(), + "0x00000000".to_string(), + )]), + demanded_cargo_token_word_hex_by_path: BTreeMap::from([( + "book00.line00".to_string(), + "0x00000000".to_string(), + )]), + }; + + let differences = diff_recipe_book_line_samples(&[sample_a, sample_b]) + .expect("recipe-book diff should succeed"); + + assert!( + differences + .iter() + .any(|entry| entry.field_path == "$.profile_family") + ); + assert!( + differences + .iter() + .any(|entry| entry.field_path == "$.line_kind_by_path.book00.line00") + ); + assert!( + differences + .iter() + .any(|entry| entry.field_path == "$.mode_word_hex_by_path.book00.line00") + ); + assert!(differences.iter().any( + |entry| entry.field_path == "$.supplied_cargo_token_word_hex_by_path.book00.line00" + )); + } + + #[test] + fn recipe_book_content_diff_ignores_wrapper_metadata() { + let sample_a = RuntimeRecipeBookLineSample { + path: "a.gmp".to_string(), + profile_family: "rt3-105-map-container-v1".to_string(), + source_kind: "recipe-book-summary".to_string(), + book_count: 12, + book_stride_hex: "0x4e1".to_string(), + line_count: 5, + line_stride_hex: "0x30".to_string(), + book_head_kind_by_index: BTreeMap::from([("book00".to_string(), "mixed".to_string())]), + book_line_area_kind_by_index: BTreeMap::from([( + "book00".to_string(), + "mixed".to_string(), + )]), + max_annual_production_word_hex_by_book: BTreeMap::from([( + "book00".to_string(), + "0x00000000".to_string(), + )]), + line_kind_by_path: BTreeMap::from([("book00.line02".to_string(), "mixed".to_string())]), + mode_word_hex_by_path: BTreeMap::from([( + "book00.line02".to_string(), + "0x00110000".to_string(), + )]), + annual_amount_word_hex_by_path: BTreeMap::from([( + "book00.line02".to_string(), + "0x00000000".to_string(), + )]), + supplied_cargo_token_word_hex_by_path: BTreeMap::from([( + "book00.line02".to_string(), + "0x000040a0".to_string(), + )]), + demanded_cargo_token_word_hex_by_path: BTreeMap::from([( + "book00.line01".to_string(), + "0x72470000".to_string(), + )]), + }; + let mut sample_b = sample_a.clone(); + sample_b.path = "b.gms".to_string(); + sample_b.profile_family = "rt3-105-save-container-v1".to_string(); + sample_b.source_kind = "recipe-book-summary".to_string(); + + let differences = diff_recipe_book_line_samples(&[sample_a.clone(), sample_b.clone()]) + .expect("wrapper-aware diff should succeed"); + let content_differences = diff_recipe_book_line_content_samples(&[sample_a, sample_b]) + .expect("content diff should succeed"); + + assert!( + differences + .iter() + .any(|entry| entry.field_path == "$.profile_family") + ); + assert!(content_differences.is_empty()); + } + #[test] fn diffs_setup_payload_core_samples_across_multiple_files() { let sample_a = RuntimeSetupPayloadCoreSample { diff --git a/crates/rrt-fixtures/src/load.rs b/crates/rrt-fixtures/src/load.rs index ffc7903..98af2a4 100644 --- a/crates/rrt-fixtures/src/load.rs +++ b/crates/rrt-fixtures/src/load.rs @@ -81,8 +81,9 @@ mod tests { use super::*; use crate::FixtureStateOrigin; use rrt_runtime::{ - CalendarPoint, RuntimeServiceState, RuntimeSnapshotDocument, RuntimeSnapshotSource, - RuntimeState, SNAPSHOT_FORMAT_VERSION, save_runtime_snapshot_document, + CalendarPoint, RuntimeSaveProfileState, RuntimeServiceState, RuntimeSnapshotDocument, + RuntimeSnapshotSource, RuntimeState, RuntimeWorldRestoreState, SNAPSHOT_FORMAT_VERSION, + save_runtime_snapshot_document, }; use std::collections::BTreeMap; @@ -111,8 +112,13 @@ mod tests { tick_slot: 5, }, world_flags: BTreeMap::new(), + save_profile: RuntimeSaveProfileState::default(), + world_restore: RuntimeWorldRestoreState::default(), + metadata: BTreeMap::new(), companies: Vec::new(), event_runtime_records: Vec::new(), + candidate_availability: BTreeMap::new(), + special_conditions: BTreeMap::new(), service_state: RuntimeServiceState::default(), }, }; diff --git a/crates/rrt-fixtures/src/schema.rs b/crates/rrt-fixtures/src/schema.rs index 67567ba..fec1da5 100644 --- a/crates/rrt-fixtures/src/schema.rs +++ b/crates/rrt-fixtures/src/schema.rs @@ -16,12 +16,77 @@ pub struct ExpectedRuntimeSummary { #[serde(default)] pub calendar: Option, #[serde(default)] + pub calendar_projection_source: Option, + #[serde(default)] + pub calendar_projection_is_placeholder: Option, + #[serde(default)] pub world_flag_count: Option, #[serde(default)] + pub world_restore_selected_year_profile_lane: Option, + #[serde(default)] + pub world_restore_campaign_scenario_enabled: Option, + #[serde(default)] + pub world_restore_sandbox_enabled: Option, + #[serde(default)] + pub world_restore_seed_tuple_written_from_raw_lane: Option, + #[serde(default)] + pub world_restore_absolute_counter_requires_shell_context: Option, + #[serde(default)] + pub world_restore_absolute_counter_reconstructible_from_save: Option, + #[serde(default)] + pub world_restore_disable_cargo_economy_special_condition_slot: Option, + #[serde(default)] + pub world_restore_disable_cargo_economy_special_condition_reconstructible_from_save: + Option, + #[serde(default)] + pub world_restore_disable_cargo_economy_special_condition_write_side_grounded: Option, + #[serde(default)] + pub world_restore_disable_cargo_economy_special_condition_enabled: Option, + #[serde(default)] + pub world_restore_use_bio_accelerator_cars_enabled: Option, + #[serde(default)] + pub world_restore_use_wartime_cargos_enabled: Option, + #[serde(default)] + pub world_restore_disable_train_crashes_enabled: Option, + #[serde(default)] + pub world_restore_disable_train_crashes_and_breakdowns_enabled: Option, + #[serde(default)] + pub world_restore_ai_ignore_territories_at_startup_enabled: Option, + #[serde(default)] + pub world_restore_absolute_counter_restore_kind: Option, + #[serde(default)] + pub world_restore_absolute_counter_adjustment_context: Option, + #[serde(default)] + pub metadata_count: Option, + #[serde(default)] pub company_count: Option, #[serde(default)] pub event_runtime_record_count: Option, #[serde(default)] + pub candidate_availability_count: Option, + #[serde(default)] + pub zero_candidate_availability_count: Option, + #[serde(default)] + pub special_condition_count: Option, + #[serde(default)] + pub enabled_special_condition_count: Option, + #[serde(default)] + pub save_profile_kind: Option, + #[serde(default)] + pub save_profile_family: Option, + #[serde(default)] + pub save_profile_map_path: Option, + #[serde(default)] + pub save_profile_display_name: Option, + #[serde(default)] + pub save_profile_selected_year_profile_lane: Option, + #[serde(default)] + pub save_profile_sandbox_enabled: Option, + #[serde(default)] + pub save_profile_campaign_scenario_enabled: Option, + #[serde(default)] + pub save_profile_staged_profile_copy_on_restore: Option, + #[serde(default)] pub total_event_record_service_count: Option, #[serde(default)] pub periodic_boundary_call_count: Option, @@ -45,6 +110,22 @@ impl ExpectedRuntimeSummary { )); } } + if let Some(source) = &self.calendar_projection_source { + if actual.calendar_projection_source.as_ref() != Some(source) { + mismatches.push(format!( + "calendar_projection_source mismatch: expected {source:?}, got {:?}", + actual.calendar_projection_source + )); + } + } + if let Some(is_placeholder) = self.calendar_projection_is_placeholder { + if actual.calendar_projection_is_placeholder != is_placeholder { + mismatches.push(format!( + "calendar_projection_is_placeholder mismatch: expected {is_placeholder}, got {}", + actual.calendar_projection_is_placeholder + )); + } + } if let Some(count) = self.world_flag_count { if actual.world_flag_count != count { mismatches.push(format!( @@ -53,6 +134,164 @@ impl ExpectedRuntimeSummary { )); } } + if let Some(lane) = self.world_restore_selected_year_profile_lane { + if actual.world_restore_selected_year_profile_lane != Some(lane) { + mismatches.push(format!( + "world_restore_selected_year_profile_lane mismatch: expected {lane}, got {:?}", + actual.world_restore_selected_year_profile_lane + )); + } + } + if let Some(enabled) = self.world_restore_campaign_scenario_enabled { + if actual.world_restore_campaign_scenario_enabled != Some(enabled) { + mismatches.push(format!( + "world_restore_campaign_scenario_enabled mismatch: expected {enabled}, got {:?}", + actual.world_restore_campaign_scenario_enabled + )); + } + } + if let Some(enabled) = self.world_restore_sandbox_enabled { + if actual.world_restore_sandbox_enabled != Some(enabled) { + mismatches.push(format!( + "world_restore_sandbox_enabled mismatch: expected {enabled}, got {:?}", + actual.world_restore_sandbox_enabled + )); + } + } + if let Some(enabled) = self.world_restore_seed_tuple_written_from_raw_lane { + if actual.world_restore_seed_tuple_written_from_raw_lane != Some(enabled) { + mismatches.push(format!( + "world_restore_seed_tuple_written_from_raw_lane mismatch: expected {enabled}, got {:?}", + actual.world_restore_seed_tuple_written_from_raw_lane + )); + } + } + if let Some(enabled) = self.world_restore_absolute_counter_requires_shell_context { + if actual.world_restore_absolute_counter_requires_shell_context != Some(enabled) { + mismatches.push(format!( + "world_restore_absolute_counter_requires_shell_context mismatch: expected {enabled}, got {:?}", + actual.world_restore_absolute_counter_requires_shell_context + )); + } + } + if let Some(enabled) = self.world_restore_absolute_counter_reconstructible_from_save { + if actual.world_restore_absolute_counter_reconstructible_from_save != Some(enabled) { + mismatches.push(format!( + "world_restore_absolute_counter_reconstructible_from_save mismatch: expected {enabled}, got {:?}", + actual.world_restore_absolute_counter_reconstructible_from_save + )); + } + } + if let Some(slot) = self.world_restore_disable_cargo_economy_special_condition_slot { + if actual.world_restore_disable_cargo_economy_special_condition_slot != Some(slot) { + mismatches.push(format!( + "world_restore_disable_cargo_economy_special_condition_slot mismatch: expected {slot}, got {:?}", + actual.world_restore_disable_cargo_economy_special_condition_slot + )); + } + } + if let Some(enabled) = + self.world_restore_disable_cargo_economy_special_condition_reconstructible_from_save + { + if actual + .world_restore_disable_cargo_economy_special_condition_reconstructible_from_save + != Some(enabled) + { + mismatches.push(format!( + "world_restore_disable_cargo_economy_special_condition_reconstructible_from_save mismatch: expected {enabled}, got {:?}", + actual.world_restore_disable_cargo_economy_special_condition_reconstructible_from_save + )); + } + } + if let Some(enabled) = + self.world_restore_disable_cargo_economy_special_condition_write_side_grounded + { + if actual.world_restore_disable_cargo_economy_special_condition_write_side_grounded + != Some(enabled) + { + mismatches.push(format!( + "world_restore_disable_cargo_economy_special_condition_write_side_grounded mismatch: expected {enabled}, got {:?}", + actual.world_restore_disable_cargo_economy_special_condition_write_side_grounded + )); + } + } + if let Some(enabled) = self.world_restore_disable_cargo_economy_special_condition_enabled { + if actual.world_restore_disable_cargo_economy_special_condition_enabled != Some(enabled) + { + mismatches.push(format!( + "world_restore_disable_cargo_economy_special_condition_enabled mismatch: expected {enabled}, got {:?}", + actual.world_restore_disable_cargo_economy_special_condition_enabled + )); + } + } + if let Some(enabled) = self.world_restore_use_bio_accelerator_cars_enabled { + if actual.world_restore_use_bio_accelerator_cars_enabled != Some(enabled) { + mismatches.push(format!( + "world_restore_use_bio_accelerator_cars_enabled mismatch: expected {enabled}, got {:?}", + actual.world_restore_use_bio_accelerator_cars_enabled + )); + } + } + if let Some(enabled) = self.world_restore_use_wartime_cargos_enabled { + if actual.world_restore_use_wartime_cargos_enabled != Some(enabled) { + mismatches.push(format!( + "world_restore_use_wartime_cargos_enabled mismatch: expected {enabled}, got {:?}", + actual.world_restore_use_wartime_cargos_enabled + )); + } + } + if let Some(enabled) = self.world_restore_disable_train_crashes_enabled { + if actual.world_restore_disable_train_crashes_enabled != Some(enabled) { + mismatches.push(format!( + "world_restore_disable_train_crashes_enabled mismatch: expected {enabled}, got {:?}", + actual.world_restore_disable_train_crashes_enabled + )); + } + } + if let Some(enabled) = self.world_restore_disable_train_crashes_and_breakdowns_enabled { + if actual.world_restore_disable_train_crashes_and_breakdowns_enabled != Some(enabled) { + mismatches.push(format!( + "world_restore_disable_train_crashes_and_breakdowns_enabled mismatch: expected {enabled}, got {:?}", + actual.world_restore_disable_train_crashes_and_breakdowns_enabled + )); + } + } + if let Some(enabled) = self.world_restore_ai_ignore_territories_at_startup_enabled { + if actual.world_restore_ai_ignore_territories_at_startup_enabled != Some(enabled) { + mismatches.push(format!( + "world_restore_ai_ignore_territories_at_startup_enabled mismatch: expected {enabled}, got {:?}", + actual.world_restore_ai_ignore_territories_at_startup_enabled + )); + } + } + if let Some(kind) = &self.world_restore_absolute_counter_restore_kind { + if actual.world_restore_absolute_counter_restore_kind.as_ref() != Some(kind) { + mismatches.push(format!( + "world_restore_absolute_counter_restore_kind mismatch: expected {kind:?}, got {:?}", + actual.world_restore_absolute_counter_restore_kind + )); + } + } + if let Some(context) = &self.world_restore_absolute_counter_adjustment_context { + if actual + .world_restore_absolute_counter_adjustment_context + .as_ref() + != Some(context) + { + mismatches.push(format!( + "world_restore_absolute_counter_adjustment_context mismatch: expected {context:?}, got {:?}", + actual.world_restore_absolute_counter_adjustment_context + )); + } + } + if let Some(count) = self.metadata_count { + if actual.metadata_count != count { + mismatches.push(format!( + "metadata_count mismatch: expected {count}, got {}", + actual.metadata_count + )); + } + } if let Some(count) = self.company_count { if actual.company_count != count { mismatches.push(format!( @@ -69,6 +308,102 @@ impl ExpectedRuntimeSummary { )); } } + if let Some(count) = self.candidate_availability_count { + if actual.candidate_availability_count != count { + mismatches.push(format!( + "candidate_availability_count mismatch: expected {count}, got {}", + actual.candidate_availability_count + )); + } + } + if let Some(count) = self.zero_candidate_availability_count { + if actual.zero_candidate_availability_count != count { + mismatches.push(format!( + "zero_candidate_availability_count mismatch: expected {count}, got {}", + actual.zero_candidate_availability_count + )); + } + } + if let Some(count) = self.special_condition_count { + if actual.special_condition_count != count { + mismatches.push(format!( + "special_condition_count mismatch: expected {count}, got {}", + actual.special_condition_count + )); + } + } + if let Some(count) = self.enabled_special_condition_count { + if actual.enabled_special_condition_count != count { + mismatches.push(format!( + "enabled_special_condition_count mismatch: expected {count}, got {}", + actual.enabled_special_condition_count + )); + } + } + if let Some(kind) = &self.save_profile_kind { + if actual.save_profile_kind.as_ref() != Some(kind) { + mismatches.push(format!( + "save_profile_kind mismatch: expected {kind:?}, got {:?}", + actual.save_profile_kind + )); + } + } + if let Some(family) = &self.save_profile_family { + if actual.save_profile_family.as_ref() != Some(family) { + mismatches.push(format!( + "save_profile_family mismatch: expected {family:?}, got {:?}", + actual.save_profile_family + )); + } + } + if let Some(map_path) = &self.save_profile_map_path { + if actual.save_profile_map_path.as_ref() != Some(map_path) { + mismatches.push(format!( + "save_profile_map_path mismatch: expected {map_path:?}, got {:?}", + actual.save_profile_map_path + )); + } + } + if let Some(display_name) = &self.save_profile_display_name { + if actual.save_profile_display_name.as_ref() != Some(display_name) { + mismatches.push(format!( + "save_profile_display_name mismatch: expected {display_name:?}, got {:?}", + actual.save_profile_display_name + )); + } + } + if let Some(lane) = self.save_profile_selected_year_profile_lane { + if actual.save_profile_selected_year_profile_lane != Some(lane) { + mismatches.push(format!( + "save_profile_selected_year_profile_lane mismatch: expected {lane}, got {:?}", + actual.save_profile_selected_year_profile_lane + )); + } + } + if let Some(enabled) = self.save_profile_sandbox_enabled { + if actual.save_profile_sandbox_enabled != Some(enabled) { + mismatches.push(format!( + "save_profile_sandbox_enabled mismatch: expected {enabled}, got {:?}", + actual.save_profile_sandbox_enabled + )); + } + } + if let Some(enabled) = self.save_profile_campaign_scenario_enabled { + if actual.save_profile_campaign_scenario_enabled != Some(enabled) { + mismatches.push(format!( + "save_profile_campaign_scenario_enabled mismatch: expected {enabled}, got {:?}", + actual.save_profile_campaign_scenario_enabled + )); + } + } + if let Some(enabled) = self.save_profile_staged_profile_copy_on_restore { + if actual.save_profile_staged_profile_copy_on_restore != Some(enabled) { + mismatches.push(format!( + "save_profile_staged_profile_copy_on_restore mismatch: expected {enabled}, got {:?}", + actual.save_profile_staged_profile_copy_on_restore + )); + } + } if let Some(count) = self.total_event_record_service_count { if actual.total_event_record_service_count != count { mismatches.push(format!( diff --git a/crates/rrt-runtime/src/import.rs b/crates/rrt-runtime/src/import.rs index 4b5b506..01ba454 100644 --- a/crates/rrt-runtime/src/import.rs +++ b/crates/rrt-runtime/src/import.rs @@ -1,8 +1,12 @@ +use std::collections::BTreeMap; use std::path::Path; use serde::{Deserialize, Serialize}; -use crate::RuntimeState; +use crate::{ + CalendarPoint, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState, + RuntimeWorldRestoreState, SmpLoadedSaveSlice, +}; pub const STATE_DUMP_FORMAT_VERSION: u32 = 1; @@ -30,6 +34,282 @@ pub struct RuntimeStateImport { pub state: RuntimeState, } +pub fn project_save_slice_to_runtime_state_import( + save_slice: &SmpLoadedSaveSlice, + import_id: &str, + description: Option, +) -> Result { + if import_id.trim().is_empty() { + return Err("import_id must not be empty".to_string()); + } + + let mut world_flags = BTreeMap::new(); + world_flags.insert( + "save_slice.profile_present".to_string(), + save_slice.profile.is_some(), + ); + world_flags.insert( + "save_slice.candidate_availability_present".to_string(), + save_slice.candidate_availability_table.is_some(), + ); + world_flags.insert( + "save_slice.special_conditions_present".to_string(), + save_slice.special_conditions_table.is_some(), + ); + world_flags.insert( + "save_slice.mechanism_confidence_grounded".to_string(), + save_slice.mechanism_confidence == "grounded", + ); + if let Some(profile) = &save_slice.profile { + world_flags.insert( + "save_slice.profile_byte_0x82_nonzero".to_string(), + profile.profile_byte_0x82 != 0, + ); + world_flags.insert( + "save_slice.profile_byte_0x97_nonzero".to_string(), + profile.profile_byte_0x97 != 0, + ); + world_flags.insert( + "save_slice.profile_byte_0xc5_nonzero".to_string(), + profile.profile_byte_0xc5 != 0, + ); + } + + let mut metadata = BTreeMap::new(); + metadata.insert( + "save_slice.import_projection".to_string(), + "partial-runtime-restore-v1".to_string(), + ); + metadata.insert( + "save_slice.calendar_source".to_string(), + "default-1830-placeholder".to_string(), + ); + metadata.insert( + "save_slice.selected_year_seed_tuple_source".to_string(), + "raw-lane-via-0x51d3f0".to_string(), + ); + metadata.insert( + "save_slice.selected_year_absolute_counter_source".to_string(), + "mode-adjusted-lane-via-0x51d390-0x409e80".to_string(), + ); + metadata.insert( + "save_slice.selected_year_absolute_counter_reconstructible_from_save".to_string(), + "false".to_string(), + ); + metadata.insert( + "save_slice.disable_cargo_economy_special_condition_slot".to_string(), + "30".to_string(), + ); + metadata.insert( + "save_slice.disable_cargo_economy_special_condition_reconstructible_from_save".to_string(), + "true".to_string(), + ); + metadata.insert( + "save_slice.disable_cargo_economy_special_condition_write_side_grounded".to_string(), + "true".to_string(), + ); + metadata.insert( + "save_slice.selected_year_absolute_counter_adjustment_context".to_string(), + "editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30" + .to_string(), + ); + metadata.insert( + "save_slice.mechanism_family".to_string(), + save_slice.mechanism_family.clone(), + ); + metadata.insert( + "save_slice.mechanism_confidence".to_string(), + save_slice.mechanism_confidence.clone(), + ); + if let Some(family) = &save_slice.container_profile_family { + metadata.insert( + "save_slice.container_profile_family".to_string(), + family.clone(), + ); + } + if let Some(family) = &save_slice.trailer_family { + metadata.insert("save_slice.trailer_family".to_string(), family.clone()); + } + if let Some(family) = &save_slice.bridge_family { + metadata.insert("save_slice.bridge_family".to_string(), family.clone()); + } + let save_profile = if let Some(profile) = &save_slice.profile { + metadata.insert( + "save_slice.profile_kind".to_string(), + profile.profile_kind.clone(), + ); + metadata.insert( + "save_slice.profile_family".to_string(), + profile.profile_family.clone(), + ); + metadata.insert( + "save_slice.packed_profile_offset".to_string(), + profile.packed_profile_offset.to_string(), + ); + metadata.insert( + "save_slice.packed_profile_len".to_string(), + profile.packed_profile_len.to_string(), + ); + metadata.insert( + "save_slice.leading_word_0_hex".to_string(), + profile.leading_word_0_hex.clone(), + ); + metadata.insert( + "save_slice.profile_byte_0x77_hex".to_string(), + profile.profile_byte_0x77_hex.clone(), + ); + metadata.insert( + "save_slice.profile_byte_0x82_hex".to_string(), + profile.profile_byte_0x82_hex.clone(), + ); + metadata.insert( + "save_slice.profile_byte_0x97_hex".to_string(), + profile.profile_byte_0x97_hex.clone(), + ); + metadata.insert( + "save_slice.profile_byte_0xc5_hex".to_string(), + profile.profile_byte_0xc5_hex.clone(), + ); + if let Some(header_flag_word_3_hex) = &profile.header_flag_word_3_hex { + metadata.insert( + "save_slice.header_flag_word_3_hex".to_string(), + header_flag_word_3_hex.clone(), + ); + } + if let Some(map_path) = &profile.map_path { + metadata.insert("save_slice.map_path".to_string(), map_path.clone()); + } + if let Some(display_name) = &profile.display_name { + metadata.insert("save_slice.display_name".to_string(), display_name.clone()); + } + RuntimeSaveProfileState { + profile_kind: Some(profile.profile_kind.clone()), + profile_family: Some(profile.profile_family.clone()), + map_path: profile.map_path.clone(), + display_name: profile.display_name.clone(), + selected_year_profile_lane: Some(profile.profile_byte_0x77), + sandbox_enabled: Some(profile.profile_byte_0x82 != 0), + campaign_scenario_enabled: Some(profile.profile_byte_0xc5 != 0), + staged_profile_copy_on_restore: Some(profile.profile_byte_0x97 != 0), + } + } else { + RuntimeSaveProfileState::default() + }; + + let special_condition_enabled = |slot_index: u8| { + save_slice.special_conditions_table.as_ref().map(|table| { + table + .entries + .iter() + .find(|entry| entry.slot_index == slot_index) + .map(|entry| entry.value != 0) + .unwrap_or(false) + }) + }; + + let world_restore = if let Some(profile) = &save_slice.profile { + let disable_cargo_economy_special_condition_enabled = special_condition_enabled(30); + RuntimeWorldRestoreState { + selected_year_profile_lane: Some(profile.profile_byte_0x77), + campaign_scenario_enabled: Some(profile.profile_byte_0xc5 != 0), + sandbox_enabled: Some(profile.profile_byte_0x82 != 0), + seed_tuple_written_from_raw_lane: Some(true), + absolute_counter_requires_shell_context: Some(true), + absolute_counter_reconstructible_from_save: Some(false), + disable_cargo_economy_special_condition_slot: Some(30), + disable_cargo_economy_special_condition_reconstructible_from_save: Some(true), + disable_cargo_economy_special_condition_write_side_grounded: Some(true), + disable_cargo_economy_special_condition_enabled, + use_bio_accelerator_cars_enabled: special_condition_enabled(29), + use_wartime_cargos_enabled: special_condition_enabled(31), + disable_train_crashes_enabled: special_condition_enabled(32), + disable_train_crashes_and_breakdowns_enabled: special_condition_enabled(33), + ai_ignore_territories_at_startup_enabled: special_condition_enabled(34), + absolute_counter_restore_kind: Some( + "mode-adjusted-selected-year-lane".to_string(), + ), + absolute_counter_adjustment_context: Some( + "editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30" + .to_string(), + ), + } + } else { + RuntimeWorldRestoreState::default() + }; + + let mut candidate_availability = BTreeMap::new(); + if let Some(table) = &save_slice.candidate_availability_table { + metadata.insert( + "save_slice.candidate_table_source_kind".to_string(), + table.source_kind.clone(), + ); + metadata.insert( + "save_slice.candidate_table_semantic_family".to_string(), + table.semantic_family.clone(), + ); + metadata.insert( + "save_slice.candidate_table_entry_count".to_string(), + table.observed_entry_count.to_string(), + ); + metadata.insert( + "save_slice.candidate_table_zero_count".to_string(), + table.zero_availability_count.to_string(), + ); + for entry in &table.entries { + candidate_availability.insert(entry.text.clone(), entry.availability_dword); + } + } + let mut special_conditions = BTreeMap::new(); + if let Some(table) = &save_slice.special_conditions_table { + metadata.insert( + "save_slice.special_conditions_source_kind".to_string(), + table.source_kind.clone(), + ); + metadata.insert( + "save_slice.special_conditions_table_offset".to_string(), + table.table_offset.to_string(), + ); + metadata.insert( + "save_slice.special_conditions_enabled_visible_count".to_string(), + table.enabled_visible_count.to_string(), + ); + for entry in &table.entries { + if !entry.hidden { + special_conditions.insert(entry.label.clone(), entry.value); + } + } + } + + for (index, note) in save_slice.notes.iter().enumerate() { + metadata.insert(format!("save_slice.note.{index}"), note.clone()); + } + + let state = RuntimeState { + calendar: CalendarPoint { + year: 1830, + month_slot: 0, + phase_slot: 0, + tick_slot: 0, + }, + world_flags, + save_profile, + world_restore, + metadata, + companies: Vec::new(), + event_runtime_records: Vec::new(), + candidate_availability, + special_conditions, + service_state: RuntimeServiceState::default(), + }; + state.validate()?; + + Ok(RuntimeStateImport { + import_id: import_id.to_string(), + description, + state, + }) +} + pub fn validate_runtime_state_dump_document( document: &RuntimeStateDumpDocument, ) -> Result<(), String> { @@ -85,8 +365,6 @@ pub fn load_runtime_state_import_from_str( #[cfg(test)] mod tests { use super::*; - use crate::{CalendarPoint, RuntimeServiceState}; - use std::collections::BTreeMap; fn state() -> RuntimeState { RuntimeState { @@ -97,8 +375,13 @@ mod tests { tick_slot: 0, }, world_flags: BTreeMap::new(), + save_profile: RuntimeSaveProfileState::default(), + world_restore: RuntimeWorldRestoreState::default(), + metadata: BTreeMap::new(), companies: Vec::new(), event_runtime_records: Vec::new(), + candidate_availability: BTreeMap::new(), + special_conditions: BTreeMap::new(), service_state: RuntimeServiceState::default(), } } @@ -130,4 +413,236 @@ mod tests { assert_eq!(import.import_id, "fallback"); assert!(import.description.is_none()); } + + #[test] + fn projects_save_slice_into_runtime_state_import() { + let save_slice = SmpLoadedSaveSlice { + file_extension_hint: Some("gms".to_string()), + container_profile_family: Some("rt3-105-save-container-v1".to_string()), + mechanism_family: "rt3-105-save-post-span-bridge-v1".to_string(), + mechanism_confidence: "mixed".to_string(), + trailer_family: Some("rt3-105-save-trailer-v1".to_string()), + bridge_family: Some("rt3-105-save-post-span-bridge-v1".to_string()), + profile: Some(crate::SmpLoadedProfile { + profile_kind: "rt3-105-packed-profile".to_string(), + profile_family: "rt3-105-save-container-v1".to_string(), + packed_profile_offset: 0x73c0, + packed_profile_len: 0x108, + packed_profile_len_hex: "0x108".to_string(), + leading_word_0: 3, + leading_word_0_hex: "0x00000003".to_string(), + header_flag_word_3: Some(0x01000000), + header_flag_word_3_hex: Some("0x01000000".to_string()), + map_path: Some("Alternate USA.gmp".to_string()), + display_name: Some("Alternate USA".to_string()), + profile_byte_0x77: 0x07, + profile_byte_0x77_hex: "0x07".to_string(), + profile_byte_0x82: 0x4d, + profile_byte_0x82_hex: "0x4d".to_string(), + profile_byte_0x97: 0x00, + profile_byte_0x97_hex: "0x00".to_string(), + profile_byte_0xc5: 0x00, + profile_byte_0xc5_hex: "0x00".to_string(), + }), + candidate_availability_table: Some(crate::SmpLoadedCandidateAvailabilityTable { + source_kind: "save-bridge-secondary-block".to_string(), + semantic_family: "scenario-named-candidate-availability-table".to_string(), + header_offset: 0x6a70, + entries_offset: 0x6ad1, + entries_end_offset: 0x73b7, + observed_entry_count: 2, + zero_availability_count: 1, + zero_availability_names: vec!["Uranium Mine".to_string()], + footer_progress_hex_words: vec!["0x000032dc".to_string(), "0x00003714".to_string()], + entries: vec![ + crate::SmpRt3105SaveNameTableEntry { + index: 0, + offset: 0x6ad1, + text: "AutoPlant".to_string(), + availability_dword: 1, + availability_dword_hex: "0x00000001".to_string(), + trailer_word: 1, + trailer_word_hex: "0x00000001".to_string(), + }, + crate::SmpRt3105SaveNameTableEntry { + index: 1, + offset: 0x6af3, + text: "Uranium Mine".to_string(), + availability_dword: 0, + availability_dword_hex: "0x00000000".to_string(), + trailer_word: 0, + trailer_word_hex: "0x00000000".to_string(), + }, + ], + }), + special_conditions_table: Some(crate::SmpLoadedSpecialConditionsTable { + source_kind: "save-fixed-special-conditions-range".to_string(), + table_offset: 0x0d64, + table_len: 36 * 4, + enabled_visible_count: 0, + enabled_visible_labels: vec![], + entries: vec![ + crate::SmpSpecialConditionEntry { + slot_index: 30, + hidden: false, + label_id: 3722, + help_id: 3723, + label: "Disable Cargo Economy".to_string(), + value: 0, + value_hex: "0x00000000".to_string(), + }, + crate::SmpSpecialConditionEntry { + slot_index: 35, + hidden: true, + label_id: 3, + help_id: 3, + label: "Hidden sentinel".to_string(), + value: 1, + value_hex: "0x00000001".to_string(), + }, + ], + }), + notes: vec!["packed profile recovered".to_string()], + }; + + let import = project_save_slice_to_runtime_state_import( + &save_slice, + "save-import-smoke", + Some("test save import".to_string()), + ) + .expect("save slice should project"); + + assert_eq!(import.import_id, "save-import-smoke"); + assert_eq!( + import + .state + .metadata + .get("save_slice.map_path") + .map(String::as_str), + Some("Alternate USA.gmp") + ); + assert_eq!( + import.state.save_profile.selected_year_profile_lane, + Some(0x07) + ); + assert_eq!(import.state.save_profile.sandbox_enabled, Some(true)); + assert_eq!( + import.state.world_restore.selected_year_profile_lane, + Some(0x07) + ); + assert_eq!(import.state.world_restore.sandbox_enabled, Some(true)); + assert_eq!( + import.state.world_restore.campaign_scenario_enabled, + Some(false) + ); + assert_eq!( + import.state.world_restore.seed_tuple_written_from_raw_lane, + Some(true) + ); + assert_eq!( + import + .state + .world_restore + .absolute_counter_requires_shell_context, + Some(true) + ); + assert_eq!( + import + .state + .world_restore + .absolute_counter_reconstructible_from_save, + Some(false) + ); + assert_eq!( + import + .state + .world_restore + .disable_cargo_economy_special_condition_slot, + Some(30) + ); + assert_eq!( + import + .state + .world_restore + .disable_cargo_economy_special_condition_reconstructible_from_save, + Some(true) + ); + assert_eq!( + import + .state + .world_restore + .disable_cargo_economy_special_condition_write_side_grounded, + Some(true) + ); + assert_eq!( + import + .state + .world_restore + .disable_cargo_economy_special_condition_enabled, + Some(false) + ); + assert_eq!( + import.state.world_restore.use_bio_accelerator_cars_enabled, + Some(false) + ); + assert_eq!( + import.state.world_restore.use_wartime_cargos_enabled, + Some(false) + ); + assert_eq!( + import.state.world_restore.disable_train_crashes_enabled, + Some(false) + ); + assert_eq!( + import + .state + .world_restore + .disable_train_crashes_and_breakdowns_enabled, + Some(false) + ); + assert_eq!( + import + .state + .world_restore + .ai_ignore_territories_at_startup_enabled, + Some(false) + ); + assert_eq!( + import + .state + .world_restore + .absolute_counter_restore_kind + .as_deref(), + Some("mode-adjusted-selected-year-lane") + ); + assert_eq!( + import + .state + .world_restore + .absolute_counter_adjustment_context + .as_deref(), + Some( + "editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30" + ) + ); + assert_eq!( + import.state.save_profile.map_path.as_deref(), + Some("Alternate USA.gmp") + ); + assert_eq!( + import.state.candidate_availability.get("Uranium Mine"), + Some(&0) + ); + assert_eq!( + import.state.special_conditions.get("Disable Cargo Economy"), + Some(&0) + ); + assert_eq!( + import + .state + .world_flags + .get("save_slice.profile_byte_0x82_nonzero"), + Some(&true) + ); + } } diff --git a/crates/rrt-runtime/src/lib.rs b/crates/rrt-runtime/src/lib.rs index dac6e60..6990902 100644 --- a/crates/rrt-runtime/src/lib.rs +++ b/crates/rrt-runtime/src/lib.rs @@ -16,7 +16,8 @@ pub use campaign_exe::{ }; pub use import::{ RuntimeStateDumpDocument, RuntimeStateDumpSource, RuntimeStateImport, - STATE_DUMP_FORMAT_VERSION, load_runtime_state_import, validate_runtime_state_dump_document, + STATE_DUMP_FORMAT_VERSION, load_runtime_state_import, + project_save_slice_to_runtime_state_import, validate_runtime_state_dump_document, }; pub use persistence::{ RuntimeSnapshotDocument, RuntimeSnapshotSource, SNAPSHOT_FORMAT_VERSION, @@ -27,16 +28,30 @@ pub use pk4::{ PK4_DIRECTORY_ENTRY_STRIDE, PK4_MAGIC, Pk4Entry, Pk4ExtractionReport, Pk4InspectionReport, extract_pk4_entry_bytes, extract_pk4_entry_file, inspect_pk4_bytes, inspect_pk4_file, }; -pub use runtime::{RuntimeCompany, RuntimeEventRecord, RuntimeServiceState, RuntimeState}; +pub use runtime::{ + RuntimeCompany, RuntimeEventRecord, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState, + RuntimeWorldRestoreState, +}; pub use smp::{ - SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAsciiPreview, SmpClassicPackedProfileBlock, + SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane, + SmpAlignedRuntimeRuleBandProbe, SmpAsciiPreview, SmpClassicPackedProfileBlock, SmpClassicRehydrateProfileProbe, SmpContainerProfile, SmpEarlyContentProbe, - SmpHeaderVariantProbe, SmpInspectionReport, SmpKnownTagHit, SmpPackedProfileWordLane, - SmpPreamble, SmpPreambleWord, SmpRt3105PackedProfileBlock, SmpRt3105PackedProfileProbe, - SmpRt3105PostSpanBridgeProbe, SmpRt3105SaveBridgePayloadProbe, SmpRt3105SaveNameTableEntry, - SmpRt3105SaveNameTableProbe, SmpRuntimeAnchorCycleBlock, SmpRuntimePostSpanHeaderCandidate, - SmpRuntimePostSpanProbe, SmpRuntimeTrailerBlock, SmpSaveAnchorRunBlock, SmpSaveBootstrapBlock, - SmpSecondaryVariantProbe, SmpSharedHeader, inspect_smp_bytes, inspect_smp_file, + SmpHeaderVariantProbe, SmpInspectionReport, SmpKnownTagHit, + SmpLoadedCandidateAvailabilityTable, SmpLoadedProfile, SmpLoadedSaveSlice, + SmpLoadedSpecialConditionsTable, SmpLocomotivePolicyFieldObservation, + SmpLocomotivePolicyFloatAlignmentCandidate, SmpLocomotivePolicyNeighborhoodProbe, + SmpPackedProfileWordLane, SmpPostSpecialConditionsScalarLane, + SmpPostSpecialConditionsScalarProbe, SmpPostTextFieldNeighborhoodProbe, + SmpPostTextFloatAlignmentCandidate, SmpPostTextGroundedFieldObservation, + SmpPreRecipeScalarPlateauLane, SmpPreRecipeScalarPlateauProbe, SmpPreamble, SmpPreambleWord, + SmpRecipeBookLineSummary, SmpRecipeBookSummaryBook, SmpRecipeBookSummaryProbe, + SmpRt3105PackedProfileBlock, SmpRt3105PackedProfileProbe, SmpRt3105PostSpanBridgeProbe, + SmpRt3105SaveBridgePayloadProbe, SmpRt3105SaveNameTableEntry, SmpRt3105SaveNameTableProbe, + SmpRuntimeAnchorCycleBlock, SmpRuntimePostSpanHeaderCandidate, SmpRuntimePostSpanProbe, + SmpRuntimeTrailerBlock, SmpSaveAnchorRunBlock, SmpSaveBootstrapBlock, + SmpSaveLoadCandidateTableSummary, SmpSaveLoadSummary, SmpSecondaryVariantProbe, + SmpSharedHeader, SmpSpecialConditionEntry, SmpSpecialConditionsProbe, inspect_smp_bytes, + inspect_smp_file, load_save_slice_file, load_save_slice_from_report, }; pub use step::{BoundaryEvent, ServiceEvent, StepCommand, StepResult, execute_step_command}; pub use summary::RuntimeSummary; diff --git a/crates/rrt-runtime/src/persistence.rs b/crates/rrt-runtime/src/persistence.rs index eea01fe..8760784 100644 --- a/crates/rrt-runtime/src/persistence.rs +++ b/crates/rrt-runtime/src/persistence.rs @@ -68,7 +68,9 @@ pub fn save_runtime_snapshot_document( #[cfg(test)] mod tests { use super::*; - use crate::{CalendarPoint, RuntimeServiceState}; + use crate::{ + CalendarPoint, RuntimeSaveProfileState, RuntimeServiceState, RuntimeWorldRestoreState, + }; use std::collections::BTreeMap; fn snapshot() -> RuntimeSnapshotDocument { @@ -87,8 +89,13 @@ mod tests { tick_slot: 0, }, world_flags: BTreeMap::new(), + save_profile: RuntimeSaveProfileState::default(), + world_restore: RuntimeWorldRestoreState::default(), + metadata: BTreeMap::new(), companies: Vec::new(), event_runtime_records: Vec::new(), + candidate_availability: BTreeMap::new(), + special_conditions: BTreeMap::new(), service_state: RuntimeServiceState::default(), }, } diff --git a/crates/rrt-runtime/src/runtime.rs b/crates/rrt-runtime/src/runtime.rs index ea5ef1d..cee6d79 100644 --- a/crates/rrt-runtime/src/runtime.rs +++ b/crates/rrt-runtime/src/runtime.rs @@ -34,16 +34,84 @@ pub struct RuntimeServiceState { pub dirty_rerun_count: u64, } +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] +pub struct RuntimeSaveProfileState { + #[serde(default)] + pub profile_kind: Option, + #[serde(default)] + pub profile_family: Option, + #[serde(default)] + pub map_path: Option, + #[serde(default)] + pub display_name: Option, + #[serde(default)] + pub selected_year_profile_lane: Option, + #[serde(default)] + pub sandbox_enabled: Option, + #[serde(default)] + pub campaign_scenario_enabled: Option, + #[serde(default)] + pub staged_profile_copy_on_restore: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] +pub struct RuntimeWorldRestoreState { + #[serde(default)] + pub selected_year_profile_lane: Option, + #[serde(default)] + pub campaign_scenario_enabled: Option, + #[serde(default)] + pub sandbox_enabled: Option, + #[serde(default)] + pub seed_tuple_written_from_raw_lane: Option, + #[serde(default)] + pub absolute_counter_requires_shell_context: Option, + #[serde(default)] + pub absolute_counter_reconstructible_from_save: Option, + #[serde(default)] + pub disable_cargo_economy_special_condition_slot: Option, + #[serde(default)] + pub disable_cargo_economy_special_condition_reconstructible_from_save: Option, + #[serde(default)] + pub disable_cargo_economy_special_condition_write_side_grounded: Option, + #[serde(default)] + pub disable_cargo_economy_special_condition_enabled: Option, + #[serde(default)] + pub use_bio_accelerator_cars_enabled: Option, + #[serde(default)] + pub use_wartime_cargos_enabled: Option, + #[serde(default)] + pub disable_train_crashes_enabled: Option, + #[serde(default)] + pub disable_train_crashes_and_breakdowns_enabled: Option, + #[serde(default)] + pub ai_ignore_territories_at_startup_enabled: Option, + #[serde(default)] + pub absolute_counter_restore_kind: Option, + #[serde(default)] + pub absolute_counter_adjustment_context: Option, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct RuntimeState { pub calendar: CalendarPoint, #[serde(default)] pub world_flags: BTreeMap, #[serde(default)] + pub save_profile: RuntimeSaveProfileState, + #[serde(default)] + pub world_restore: RuntimeWorldRestoreState, + #[serde(default)] + pub metadata: BTreeMap, + #[serde(default)] pub companies: Vec, #[serde(default)] pub event_runtime_records: Vec, #[serde(default)] + pub candidate_availability: BTreeMap, + #[serde(default)] + pub special_conditions: BTreeMap, + #[serde(default)] pub service_state: RuntimeServiceState, } @@ -71,6 +139,79 @@ impl RuntimeState { } } + for (label, value) in [ + ( + "save_profile.profile_kind", + self.save_profile.profile_kind.as_deref(), + ), + ( + "save_profile.profile_family", + self.save_profile.profile_family.as_deref(), + ), + ( + "save_profile.map_path", + self.save_profile.map_path.as_deref(), + ), + ( + "save_profile.display_name", + self.save_profile.display_name.as_deref(), + ), + ] { + if value.is_some_and(|text| text.trim().is_empty()) { + return Err(format!("{label} must not be empty")); + } + } + + if self.world_restore.selected_year_profile_lane.is_none() + && (self.world_restore.campaign_scenario_enabled.is_some() + || self.world_restore.sandbox_enabled.is_some()) + { + return Err( + "world_restore.selected_year_profile_lane must be present when world restore flags are populated" + .to_string(), + ); + } + + if self + .world_restore + .absolute_counter_restore_kind + .as_deref() + .is_some_and(|text| text.trim().is_empty()) + { + return Err( + "world_restore.absolute_counter_restore_kind must not be empty".to_string(), + ); + } + if self + .world_restore + .absolute_counter_adjustment_context + .as_deref() + .is_some_and(|text| text.trim().is_empty()) + { + return Err( + "world_restore.absolute_counter_adjustment_context must not be empty".to_string(), + ); + } + for (key, value) in &self.metadata { + if key.trim().is_empty() { + return Err("metadata contains an empty key".to_string()); + } + if value.trim().is_empty() { + return Err(format!("metadata[{key}] must not be empty")); + } + } + + for key in self.candidate_availability.keys() { + if key.trim().is_empty() { + return Err("candidate_availability contains an empty key".to_string()); + } + } + for key in self.special_conditions.keys() { + if key.trim().is_empty() { + return Err("special_conditions contains an empty key".to_string()); + } + } + Ok(()) } } @@ -89,6 +230,9 @@ mod tests { tick_slot: 0, }, world_flags: BTreeMap::new(), + save_profile: RuntimeSaveProfileState::default(), + world_restore: RuntimeWorldRestoreState::default(), + metadata: BTreeMap::new(), companies: vec![ RuntimeCompany { company_id: 1, @@ -102,6 +246,53 @@ mod tests { }, ], event_runtime_records: Vec::new(), + candidate_availability: BTreeMap::new(), + special_conditions: BTreeMap::new(), + service_state: RuntimeServiceState::default(), + }; + + assert!(state.validate().is_err()); + } + + #[test] + fn rejects_partial_world_restore_without_year_lane() { + let state = RuntimeState { + calendar: CalendarPoint { + year: 1830, + month_slot: 0, + phase_slot: 0, + tick_slot: 0, + }, + world_flags: BTreeMap::new(), + save_profile: RuntimeSaveProfileState::default(), + world_restore: RuntimeWorldRestoreState { + selected_year_profile_lane: None, + campaign_scenario_enabled: Some(false), + sandbox_enabled: Some(true), + seed_tuple_written_from_raw_lane: Some(true), + absolute_counter_requires_shell_context: Some(true), + absolute_counter_reconstructible_from_save: Some(false), + disable_cargo_economy_special_condition_slot: Some(30), + disable_cargo_economy_special_condition_reconstructible_from_save: Some(true), + disable_cargo_economy_special_condition_write_side_grounded: Some(true), + disable_cargo_economy_special_condition_enabled: Some(false), + use_bio_accelerator_cars_enabled: Some(false), + use_wartime_cargos_enabled: Some(false), + disable_train_crashes_enabled: Some(false), + disable_train_crashes_and_breakdowns_enabled: Some(false), + ai_ignore_territories_at_startup_enabled: Some(false), + absolute_counter_restore_kind: Some( + "mode-adjusted-selected-year-lane".to_string(), + ), + absolute_counter_adjustment_context: Some( + "editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30".to_string(), + ), + }, + metadata: BTreeMap::new(), + companies: Vec::new(), + event_runtime_records: Vec::new(), + candidate_availability: BTreeMap::new(), + special_conditions: BTreeMap::new(), service_state: RuntimeServiceState::default(), }; diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index b92d736..42bff84 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -12,10 +12,346 @@ const TAG_OFFSET_SAMPLE_LIMIT: usize = 8; const EARLY_ZERO_RUN_THRESHOLD: usize = 16; const EARLY_PREVIEW_BYTE_LIMIT: usize = 32; const EARLY_ALIGNED_WORD_WINDOW_COUNT: usize = 8; +const SPECIAL_CONDITIONS_OFFSET: usize = 0x0d64; +const SPECIAL_CONDITION_COUNT: usize = 36; +const SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT: usize = 35; +const SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT: usize = 50; +const SMP_ALIGNED_RUNTIME_RULE_KNOWN_EDITOR_RULE_COUNT: usize = 49; +const SMP_ALIGNED_RUNTIME_RULE_RUNTIME_OBJECT_OFFSET: usize = 0x4a7f; +const SMP_ALIGNED_RUNTIME_RULE_END_OFFSET: usize = + SPECIAL_CONDITIONS_OFFSET + SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT * 4; +const POST_SPECIAL_CONDITIONS_SCALAR_OFFSET: usize = 0x0df4; +const POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET: usize = 0x0f30; +const POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET: usize = 0x0f58; +const POST_SPECIAL_CONDITIONS_SCALAR_OVERLAP_END_OFFSET: usize = + SMP_ALIGNED_RUNTIME_RULE_END_OFFSET; +const POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET: usize = SMP_ALIGNED_RUNTIME_RULE_END_OFFSET; +const POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_OFFSET: usize = + SMP_ALIGNED_RUNTIME_RULE_RUNTIME_OBJECT_OFFSET + + (POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET - SPECIAL_CONDITIONS_OFFSET); +const POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_END_OFFSET: usize = + SMP_ALIGNED_RUNTIME_RULE_RUNTIME_OBJECT_OFFSET + + (POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET - SPECIAL_CONDITIONS_OFFSET); +const POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_OFFSET: usize = 0x4b47; +const POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_LEN: usize = 0x12c; +const POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_END_OFFSET: usize = + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_OFFSET + + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_LEN; +const POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET: usize = 0x0f59; +const POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET: usize = 0x0f75; +const POST_TEXT_FIELD_0_RUNTIME_OBJECT_OFFSET: usize = 0x4c74; +const POST_TEXT_FIELD_1_RUNTIME_OBJECT_OFFSET: usize = 0x4c78; +const POST_TEXT_FIELD_2_RUNTIME_OBJECT_OFFSET: usize = 0x4c7c; +const POST_TEXT_FIELD_3_RUNTIME_OBJECT_OFFSET: usize = 0x4c80; +const POST_TEXT_FIELD_4_RUNTIME_OBJECT_OFFSET: usize = 0x4c88; +const POST_TEXT_FIELD_5_RUNTIME_OBJECT_OFFSET: usize = 0x4c8c; +const POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_OFFSET: usize = 0x4c80; +const POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_OFFSET: usize = 0x4c8c; +const POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_FILE_OFFSET: usize = + SPECIAL_CONDITIONS_OFFSET + + (POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_OFFSET + - SMP_ALIGNED_RUNTIME_RULE_RUNTIME_OBJECT_OFFSET); +const POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_FILE_OFFSET: usize = + SPECIAL_CONDITIONS_OFFSET + + (POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_OFFSET + - SMP_ALIGNED_RUNTIME_RULE_RUNTIME_OBJECT_OFFSET); +const LOCOMOTIVE_POLICY_NEIGHBORHOOD_OFFSET: usize = 0x0f78; +const LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET: usize = 0x0fa7; +const LOCOMOTIVE_POLICY_FIELD_NEG3_RUNTIME_OBJECT_OFFSET: usize = 0x4ca2; +const LOCOMOTIVE_POLICY_FIELD_NEG2_RUNTIME_OBJECT_OFFSET: usize = 0x4cae; +const LOCOMOTIVE_POLICY_FIELD_NEG1_RUNTIME_OBJECT_OFFSET: usize = 0x4cb2; +const LOCOMOTIVE_POLICY_FIELD_0_RUNTIME_OBJECT_OFFSET: usize = 0x4c93; +const LOCOMOTIVE_POLICY_FIELD_1_RUNTIME_OBJECT_OFFSET: usize = 0x4c97; +const LOCOMOTIVE_POLICY_FIELD_2_RUNTIME_OBJECT_OFFSET: usize = 0x4c98; +const LOCOMOTIVE_POLICY_FIELD_3_RUNTIME_OBJECT_OFFSET: usize = 0x4c99; +const LOCOMOTIVE_POLICY_FIELD_4_RUNTIME_OBJECT_OFFSET: usize = 0x4cba; +const LOCOMOTIVE_POLICY_FIELD_5_RUNTIME_OBJECT_OFFSET: usize = 0x4cbe; +const PRE_RECIPE_SCALAR_PLATEAU_OFFSET: usize = 0x0fa7; +const PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET: usize = 0x0fe7; +const RECIPE_BOOK_ROOT_OFFSET: usize = 0x0fe7; +const RECIPE_BOOK_COUNT: usize = 12; +const RECIPE_BOOK_STRIDE: usize = 0x4e1; +const RECIPE_BOOK_HEAD_SAMPLE_LEN: usize = 16; +const RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET: usize = 0x3ed; +const RECIPE_BOOK_LINE_AREA_OFFSET: usize = 0x3f1; +const RECIPE_BOOK_LINE_COUNT: usize = 5; +const RECIPE_BOOK_LINE_STRIDE: usize = 0x30; +const RECIPE_BOOK_LINE_AREA_LEN: usize = RECIPE_BOOK_LINE_COUNT * RECIPE_BOOK_LINE_STRIDE; +const RECIPE_BOOK_SUMMARY_END_OFFSET: usize = + RECIPE_BOOK_ROOT_OFFSET + RECIPE_BOOK_COUNT * RECIPE_BOOK_STRIDE; +const SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX: usize = + (POST_SPECIAL_CONDITIONS_SCALAR_OFFSET - SPECIAL_CONDITIONS_OFFSET) / 4; +const SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT: usize = + (SMP_ALIGNED_RUNTIME_RULE_END_OFFSET - POST_SPECIAL_CONDITIONS_SCALAR_OFFSET) / 4; const SHARED_SIGNATURE_WORDS_1_TO_7: [u32; 7] = [ 0x00002ee0, 0x00040001, 0x00028000, 0x00010000, 0x00000771, 0x00000771, 0x00000771, ]; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +struct KnownSpecialConditionDefinition { + slot_index: u8, + hidden: bool, + label_id: u32, + help_id: u32, + label: &'static str, +} + +const KNOWN_SPECIAL_CONDITION_DEFINITIONS: [KnownSpecialConditionDefinition; + SPECIAL_CONDITION_COUNT] = [ + KnownSpecialConditionDefinition { + slot_index: 0, + hidden: false, + label_id: 2535, + help_id: 2564, + label: "Disable Stock Buying and Selling", + }, + KnownSpecialConditionDefinition { + slot_index: 1, + hidden: false, + label_id: 2536, + help_id: 2565, + label: "Disable Margin Buying/Short Selling Stock", + }, + KnownSpecialConditionDefinition { + slot_index: 2, + hidden: false, + label_id: 2537, + help_id: 2566, + label: "Disable Company Issue/Buy Back Stock", + }, + KnownSpecialConditionDefinition { + slot_index: 3, + hidden: false, + label_id: 2538, + help_id: 2567, + label: "Disable Issuing/Repaying Bonds", + }, + KnownSpecialConditionDefinition { + slot_index: 4, + hidden: false, + label_id: 2539, + help_id: 2568, + label: "Disable Declaring Bankruptcy", + }, + KnownSpecialConditionDefinition { + slot_index: 5, + hidden: false, + label_id: 2540, + help_id: 2569, + label: "Disable Changing the Dividend Rate", + }, + KnownSpecialConditionDefinition { + slot_index: 6, + hidden: false, + label_id: 2541, + help_id: 2570, + label: "Disable Replacing a Locomotive", + }, + KnownSpecialConditionDefinition { + slot_index: 7, + hidden: false, + label_id: 2542, + help_id: 2571, + label: "Disable Retiring a Train", + }, + KnownSpecialConditionDefinition { + slot_index: 8, + hidden: false, + label_id: 2543, + help_id: 2572, + label: "Disable Changing Cargo Consist On Train", + }, + KnownSpecialConditionDefinition { + slot_index: 9, + hidden: false, + label_id: 2544, + help_id: 2573, + label: "Disable Buying a Train", + }, + KnownSpecialConditionDefinition { + slot_index: 10, + hidden: false, + label_id: 2545, + help_id: 2574, + label: "Disable All Track Building", + }, + KnownSpecialConditionDefinition { + slot_index: 11, + hidden: false, + label_id: 2546, + help_id: 2575, + label: "Disable Unconnected Track Building", + }, + KnownSpecialConditionDefinition { + slot_index: 12, + hidden: false, + label_id: 2547, + help_id: 2576, + label: "Limited Track Building Amount", + }, + KnownSpecialConditionDefinition { + slot_index: 13, + hidden: false, + label_id: 2548, + help_id: 2577, + label: "Disable Building Stations", + }, + KnownSpecialConditionDefinition { + slot_index: 14, + hidden: false, + label_id: 2549, + help_id: 2578, + label: "Disable Building Hotel/Restaurant/Tavern/Post Office", + }, + KnownSpecialConditionDefinition { + slot_index: 15, + hidden: false, + label_id: 2550, + help_id: 2579, + label: "Disable Building Customs House", + }, + KnownSpecialConditionDefinition { + slot_index: 16, + hidden: false, + label_id: 2551, + help_id: 2580, + label: "Disable Building Industry Buildings", + }, + KnownSpecialConditionDefinition { + slot_index: 17, + hidden: false, + label_id: 2552, + help_id: 2581, + label: "Disable Buying Existing Industry Buildings", + }, + KnownSpecialConditionDefinition { + slot_index: 18, + hidden: false, + label_id: 2553, + help_id: 2582, + label: "Disable Being Fired As Chairman", + }, + KnownSpecialConditionDefinition { + slot_index: 19, + hidden: false, + label_id: 2554, + help_id: 2583, + label: "Disable Resigning as Chairman", + }, + KnownSpecialConditionDefinition { + slot_index: 20, + hidden: false, + label_id: 2555, + help_id: 2584, + label: "Disable Chairmanship Takeover", + }, + KnownSpecialConditionDefinition { + slot_index: 21, + hidden: false, + label_id: 2556, + help_id: 2585, + label: "Disable Starting Any Companies", + }, + KnownSpecialConditionDefinition { + slot_index: 22, + hidden: false, + label_id: 2557, + help_id: 2586, + label: "Disable Starting Multiple Companies", + }, + KnownSpecialConditionDefinition { + slot_index: 23, + hidden: false, + label_id: 2558, + help_id: 2587, + label: "Disable Merging Companies", + }, + KnownSpecialConditionDefinition { + slot_index: 24, + hidden: false, + label_id: 2559, + help_id: 2588, + label: "Disable Bulldozing", + }, + KnownSpecialConditionDefinition { + slot_index: 25, + hidden: false, + label_id: 2560, + help_id: 2589, + label: "Show Visited Track", + }, + KnownSpecialConditionDefinition { + slot_index: 26, + hidden: false, + label_id: 2561, + help_id: 2590, + label: "Show Visited Stations", + }, + KnownSpecialConditionDefinition { + slot_index: 27, + hidden: false, + label_id: 2562, + help_id: 2591, + label: "Use Slow Date", + }, + KnownSpecialConditionDefinition { + slot_index: 28, + hidden: false, + label_id: 2563, + help_id: 2592, + label: "Completely Disable Money-Related Things", + }, + KnownSpecialConditionDefinition { + slot_index: 29, + hidden: false, + label_id: 2874, + help_id: 2875, + label: "Use Bio-Accelerator Cars", + }, + KnownSpecialConditionDefinition { + slot_index: 30, + hidden: false, + label_id: 3722, + help_id: 3723, + label: "Disable Cargo Economy", + }, + KnownSpecialConditionDefinition { + slot_index: 31, + hidden: false, + label_id: 3835, + help_id: 3836, + label: "Use Wartime Cargos", + }, + KnownSpecialConditionDefinition { + slot_index: 32, + hidden: false, + label_id: 3850, + help_id: 3851, + label: "Disable Train Crashes", + }, + KnownSpecialConditionDefinition { + slot_index: 33, + hidden: false, + label_id: 3852, + help_id: 3853, + label: "Disable Train Crashes AND Breakdowns", + }, + KnownSpecialConditionDefinition { + slot_index: 34, + hidden: false, + label_id: 3920, + help_id: 3921, + label: "AI Ignore Territories At Startup", + }, + KnownSpecialConditionDefinition { + slot_index: 35, + hidden: true, + label_id: 3, + help_id: 3, + label: "Hidden sentinel", + }, +]; + #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct KnownTagDefinition { tag_id: u16, @@ -335,6 +671,350 @@ pub struct SmpRt3105SaveNameTableEntry { pub trailer_word_hex: String, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSpecialConditionEntry { + pub slot_index: u8, + pub hidden: bool, + pub label_id: u32, + pub help_id: u32, + pub label: String, + pub value: u32, + pub value_hex: String, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSpecialConditionsProbe { + pub profile_family: String, + pub source_kind: String, + pub table_offset: usize, + pub table_len: usize, + pub enabled_visible_count: usize, + pub enabled_visible_labels: Vec, + pub hidden_sentinel_slot_index: u8, + pub hidden_sentinel_value: u32, + pub hidden_sentinel_value_hex: String, + pub entries: Vec, + pub evidence: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpAlignedRuntimeRuleBandLane { + pub band_index: usize, + pub absolute_offset: usize, + pub relative_offset: usize, + pub absolute_offset_hex: String, + pub relative_offset_hex: String, + pub lane_kind: String, + pub known_label: Option, + pub value: u32, + pub value_hex: String, + pub probable_f32_le: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpAlignedRuntimeRuleBandProbe { + pub profile_family: String, + pub source_kind: String, + pub band_offset: usize, + pub band_end_offset: usize, + pub band_len: usize, + pub band_len_hex: String, + pub dword_count: usize, + pub known_editor_rule_dword_count: usize, + pub trailing_scalar_index: usize, + pub trailing_scalar_offset: usize, + pub trailing_scalar_offset_hex: String, + pub post_window_overlap_start_index: usize, + pub post_window_overlap_dword_count: usize, + pub post_window_overlap_end_index: usize, + pub post_window_overlap_post_relative_offset_start_hex: String, + pub post_window_overlap_post_relative_offset_end_hex: String, + pub nonzero_post_window_overlap_band_indices: Vec, + pub nonzero_post_window_overlap_post_relative_offset_hexes: Vec, + pub nonzero_lane_count: usize, + pub nonzero_band_indices: Vec, + pub nonzero_relative_offset_hexes: Vec, + pub nonzero_lanes: Vec, + pub evidence: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpPostSpecialConditionsScalarLane { + pub absolute_offset: usize, + pub relative_offset: usize, + pub absolute_offset_hex: String, + pub relative_offset_hex: String, + pub value: u32, + pub value_hex: String, + pub probable_f32_le: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpPostTextGroundedFieldObservation { + pub field_name: String, + pub runtime_object_offset: usize, + pub runtime_object_offset_hex: String, + pub file_offset: usize, + pub file_offset_hex: String, + pub field_width_bytes: usize, + pub field_width_bytes_hex: String, + pub raw_hex: String, + pub value_u8: Option, + pub value_u8_hex: Option, + pub value_u32: Option, + pub value_u32_hex: Option, + pub probable_f32_le: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpPostTextFloatAlignmentCandidate { + pub grounded_field_name: String, + pub grounded_field_runtime_object_offset: usize, + pub grounded_field_runtime_object_offset_hex: String, + pub grounded_field_file_offset: usize, + pub grounded_field_file_offset_hex: String, + pub candidate_offset: usize, + pub candidate_offset_hex: String, + pub candidate_value: u32, + pub candidate_value_hex: String, + pub probable_f32_le: String, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpPostTextFieldNeighborhoodProbe { + pub profile_family: String, + pub source_kind: String, + pub window_offset: usize, + pub window_end_offset: usize, + pub window_len: usize, + pub window_len_hex: String, + pub grounded_field_observations: Vec, + pub one_byte_early_float_candidates: Vec, + pub evidence: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLocomotivePolicyFieldObservation { + pub field_name: String, + pub runtime_object_offset: usize, + pub runtime_object_offset_hex: String, + pub file_offset: usize, + pub file_offset_hex: String, + pub field_width_bytes: usize, + pub field_width_bytes_hex: String, + pub raw_hex: String, + pub value_u8: Option, + pub value_u8_hex: Option, + pub value_u32: Option, + pub value_u32_hex: Option, + pub probable_f32_le: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLocomotivePolicyFloatAlignmentCandidate { + pub grounded_field_name: String, + pub grounded_field_runtime_object_offset: usize, + pub grounded_field_runtime_object_offset_hex: String, + pub grounded_field_file_offset: usize, + pub grounded_field_file_offset_hex: String, + pub candidate_offset: usize, + pub candidate_offset_hex: String, + pub candidate_value: u32, + pub candidate_value_hex: String, + pub probable_f32_le: String, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLocomotivePolicyNeighborhoodProbe { + pub profile_family: String, + pub source_kind: String, + pub window_offset: usize, + pub window_end_offset: usize, + pub window_len: usize, + pub window_len_hex: String, + pub grounded_field_observations: Vec, + pub three_byte_early_float_candidates: Vec, + pub evidence: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpPreRecipeScalarPlateauLane { + pub absolute_offset: usize, + pub relative_offset: usize, + pub absolute_offset_hex: String, + pub relative_offset_hex: String, + pub value: u32, + pub value_hex: String, + pub probable_f32_le: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpPreRecipeScalarPlateauProbe { + pub profile_family: String, + pub source_kind: String, + pub window_offset: usize, + pub window_end_offset: usize, + pub window_len: usize, + pub window_len_hex: String, + pub aligned_dword_count: usize, + pub family_signature: String, + pub nonzero_lanes: Vec, + pub evidence: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpRecipeBookSummaryBook { + pub book_index: usize, + pub book_offset: usize, + pub book_offset_hex: String, + pub head_kind: String, + pub head_nonzero_byte_count: usize, + pub head_cdcd_byte_count: usize, + pub head_first_16_hex: String, + pub max_annual_production_offset: usize, + pub max_annual_production_offset_hex: String, + pub max_annual_production_word: u32, + pub max_annual_production_word_hex: String, + pub max_annual_production_probable_f32_le: Option, + pub line_area_offset: usize, + pub line_area_offset_hex: String, + pub line_area_len: usize, + pub line_area_len_hex: String, + pub line_area_kind: String, + pub line_area_nonzero_byte_count: usize, + pub line_area_cdcd_byte_count: usize, + pub line_area_first_16_hex: String, + pub lines: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpRecipeBookLineSummary { + pub line_index: usize, + pub line_offset: usize, + pub line_offset_hex: String, + pub line_kind: String, + pub line_signature_kind: String, + pub imports_to_runtime_descriptor: bool, + pub runtime_import_branch_kind: String, + pub line_nonzero_byte_count: usize, + pub line_cdcd_byte_count: usize, + pub line_first_16_hex: String, + pub mode_word_offset: usize, + pub mode_word_offset_hex: String, + pub mode_word: u32, + pub mode_word_hex: String, + pub annual_amount_offset: usize, + pub annual_amount_offset_hex: String, + pub annual_amount_word: u32, + pub annual_amount_word_hex: String, + pub annual_amount_probable_f32_le: Option, + pub supplied_cargo_token_offset: usize, + pub supplied_cargo_token_offset_hex: String, + pub supplied_cargo_token_word: u32, + pub supplied_cargo_token_word_hex: String, + pub supplied_cargo_token_layout_kind: String, + pub supplied_cargo_token_window_hex: String, + pub supplied_cargo_token_window_ascii: String, + pub supplied_cargo_token_active_in_runtime_import: bool, + pub supplied_cargo_token_probable_high16_ascii_stem: Option, + pub demanded_cargo_token_offset: usize, + pub demanded_cargo_token_offset_hex: String, + pub demanded_cargo_token_word: u32, + pub demanded_cargo_token_word_hex: String, + pub demanded_cargo_token_layout_kind: String, + pub demanded_cargo_token_window_hex: String, + pub demanded_cargo_token_window_ascii: String, + pub demanded_cargo_token_active_in_runtime_import: bool, + pub demanded_cargo_token_probable_high16_ascii_stem: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpRecipeBookSummaryProbe { + pub profile_family: String, + pub source_kind: String, + pub root_offset: usize, + pub root_offset_hex: String, + pub runtime_object_root_offset: usize, + pub runtime_object_root_offset_hex: String, + pub book_count: usize, + pub book_stride: usize, + pub book_stride_hex: String, + pub max_annual_production_relative_offset: usize, + pub max_annual_production_relative_offset_hex: String, + pub line_area_relative_offset: usize, + pub line_area_relative_offset_hex: String, + pub line_count: usize, + pub line_stride: usize, + pub line_stride_hex: String, + pub books: Vec, + pub evidence: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpPostSpecialConditionsScalarProbe { + pub profile_family: String, + pub source_kind: String, + pub window_offset: usize, + pub window_end_offset: usize, + pub window_len: usize, + pub window_len_hex: String, + pub dword_count: usize, + pub overlap_end_offset: usize, + pub overlap_end_offset_hex: String, + pub overlap_dword_count: usize, + pub overlap_nonzero_dword_count: usize, + pub overlap_nonzero_relative_offset_hexes: Vec, + pub tail_offset: usize, + pub tail_offset_hex: String, + pub tail_len: usize, + pub tail_len_hex: String, + pub tail_dword_count: usize, + pub tail_runtime_object_offset: usize, + pub tail_runtime_object_offset_hex: String, + pub tail_runtime_object_end_offset: usize, + pub tail_runtime_object_end_offset_hex: String, + pub tail_runtime_object_validated_byte_mirror: bool, + pub tail_grounded_live_field_offset: usize, + pub tail_grounded_live_field_offset_hex: String, + pub tail_grounded_live_field_name: String, + pub tail_grounded_live_field_copy_len: usize, + pub tail_grounded_live_field_copy_len_hex: String, + pub tail_grounded_live_field_copy_end_offset: usize, + pub tail_grounded_live_field_copy_end_offset_hex: String, + pub tail_window_cuts_through_grounded_live_field: bool, + pub tail_grounded_live_field_remaining_file_window_offset: usize, + pub tail_grounded_live_field_remaining_file_window_offset_hex: String, + pub tail_grounded_live_field_remaining_file_window_len: usize, + pub tail_grounded_live_field_remaining_file_window_len_hex: String, + pub tail_grounded_live_field_remaining_file_window_nonzero_byte_count: usize, + pub tail_grounded_live_field_remaining_file_window_first_nonzero_offset: Option, + pub tail_grounded_live_field_remaining_file_window_first_nonzero_offset_hex: Option, + pub tail_grounded_live_field_remaining_file_window_last_nonzero_offset: Option, + pub tail_grounded_live_field_remaining_file_window_last_nonzero_offset_hex: Option, + pub tail_next_grounded_dword_field_offset: usize, + pub tail_next_grounded_dword_field_offset_hex: String, + pub tail_next_grounded_dword_field_file_offset: usize, + pub tail_next_grounded_dword_field_file_offset_hex: String, + pub tail_second_grounded_dword_field_offset: usize, + pub tail_second_grounded_dword_field_offset_hex: String, + pub tail_second_grounded_dword_field_file_offset: usize, + pub tail_second_grounded_dword_field_file_offset_hex: String, + pub post_text_field_file_alignment_matches_grounded_dword_fields: bool, + pub tail_nonzero_dword_count: usize, + pub tail_first_nonzero_offset: Option, + pub tail_first_nonzero_offset_hex: Option, + pub tail_last_nonzero_offset: Option, + pub tail_last_nonzero_offset_hex: Option, + pub tail_nonzero_relative_offset_hexes: Vec, + pub nonzero_dword_count: usize, + pub first_nonzero_offset: Option, + pub first_nonzero_offset_hex: Option, + pub last_nonzero_offset: Option, + pub last_nonzero_offset_hex: Option, + pub nonzero_lanes: Vec, + pub evidence: Vec, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SmpClassicRehydrateProfileProbe { pub profile_family: String, @@ -404,6 +1084,103 @@ pub struct SmpRt3105PackedProfileBlock { pub stable_nonzero_words: Vec, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSaveLoadCandidateTableSummary { + pub source_kind: String, + pub semantic_family: String, + pub observed_entry_count: usize, + pub zero_availability_count: usize, + pub zero_availability_names: Vec, + pub footer_progress_hex_words: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSaveLoadSummary { + pub file_extension_hint: Option, + pub container_profile_family: Option, + pub mechanism_family: String, + pub mechanism_confidence: String, + pub packed_profile_kind: Option, + pub packed_profile_family: Option, + pub packed_profile_offset: Option, + pub packed_profile_len: Option, + pub map_path: Option, + pub display_name: Option, + pub profile_byte_0x77: Option, + pub profile_byte_0x77_hex: Option, + pub profile_byte_0x82: Option, + pub profile_byte_0x82_hex: Option, + pub profile_byte_0x97: Option, + pub profile_byte_0x97_hex: Option, + pub profile_byte_0xc5: Option, + pub profile_byte_0xc5_hex: Option, + pub trailer_family: Option, + pub bridge_family: Option, + pub candidate_table: Option, + pub notes: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLoadedProfile { + pub profile_kind: String, + pub profile_family: String, + pub packed_profile_offset: usize, + pub packed_profile_len: usize, + pub packed_profile_len_hex: String, + pub leading_word_0: u32, + pub leading_word_0_hex: String, + pub header_flag_word_3: Option, + pub header_flag_word_3_hex: Option, + pub map_path: Option, + pub display_name: Option, + pub profile_byte_0x77: u8, + pub profile_byte_0x77_hex: String, + pub profile_byte_0x82: u8, + pub profile_byte_0x82_hex: String, + pub profile_byte_0x97: u8, + pub profile_byte_0x97_hex: String, + pub profile_byte_0xc5: u8, + pub profile_byte_0xc5_hex: String, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLoadedCandidateAvailabilityTable { + pub source_kind: String, + pub semantic_family: String, + pub header_offset: usize, + pub entries_offset: usize, + pub entries_end_offset: usize, + pub observed_entry_count: usize, + pub zero_availability_count: usize, + pub zero_availability_names: Vec, + pub footer_progress_hex_words: Vec, + pub entries: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLoadedSpecialConditionsTable { + pub source_kind: String, + pub table_offset: usize, + pub table_len: usize, + pub enabled_visible_count: usize, + pub enabled_visible_labels: Vec, + pub entries: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLoadedSaveSlice { + pub file_extension_hint: Option, + pub container_profile_family: Option, + pub mechanism_family: String, + pub mechanism_confidence: String, + pub trailer_family: Option, + pub bridge_family: Option, + pub profile: Option, + pub candidate_availability_table: Option, + pub special_conditions_table: Option, + pub notes: Vec, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SmpPackedProfileWordLane { pub relative_offset: usize, @@ -433,8 +1210,16 @@ pub struct SmpInspectionReport { pub rt3_105_post_span_bridge_probe: Option, pub rt3_105_save_bridge_payload_probe: Option, pub rt3_105_save_name_table_probe: Option, + pub special_conditions_probe: Option, + pub smp_aligned_runtime_rule_band_probe: Option, + pub post_special_conditions_scalar_probe: Option, + pub post_text_field_neighborhood_probe: Option, + pub locomotive_policy_neighborhood_probe: Option, + pub pre_recipe_scalar_plateau_probe: Option, + pub recipe_book_summary_probe: Option, pub classic_rehydrate_profile_probe: Option, pub rt3_105_packed_profile_probe: Option, + pub save_load_summary: Option, pub contains_grounded_runtime_tags: bool, pub known_tag_hits: Vec, pub notes: Vec, @@ -455,6 +1240,113 @@ pub fn inspect_smp_bytes(bytes: &[u8]) -> SmpInspectionReport { inspect_bundle_bytes(bytes, None) } +pub fn load_save_slice_file(path: &Path) -> Result> { + let inspection = inspect_smp_file(path)?; + load_save_slice_from_report(&inspection) + .map_err(|err| -> Box { err.into() }) +} + +pub fn load_save_slice_from_report( + report: &SmpInspectionReport, +) -> Result { + let summary = report + .save_load_summary + .as_ref() + .ok_or_else(|| "inspection did not expose a recognizable save-load summary".to_string())?; + let profile = if let Some(probe) = &report.classic_rehydrate_profile_probe { + Some(SmpLoadedProfile { + profile_kind: "classic-rehydrate-profile".to_string(), + profile_family: probe.profile_family.clone(), + packed_profile_offset: probe.packed_profile_offset, + packed_profile_len: probe.packed_profile_len, + packed_profile_len_hex: probe.packed_profile_len_hex.clone(), + leading_word_0: probe.packed_profile_block.leading_word_0, + leading_word_0_hex: probe.packed_profile_block.leading_word_0_hex.clone(), + header_flag_word_3: None, + header_flag_word_3_hex: None, + map_path: probe.packed_profile_block.map_path.clone(), + display_name: probe.packed_profile_block.display_name.clone(), + profile_byte_0x77: probe.packed_profile_block.profile_byte_0x77, + profile_byte_0x77_hex: probe.packed_profile_block.profile_byte_0x77_hex.clone(), + profile_byte_0x82: probe.packed_profile_block.profile_byte_0x82, + profile_byte_0x82_hex: probe.packed_profile_block.profile_byte_0x82_hex.clone(), + profile_byte_0x97: probe.packed_profile_block.profile_byte_0x97, + profile_byte_0x97_hex: probe.packed_profile_block.profile_byte_0x97_hex.clone(), + profile_byte_0xc5: probe.packed_profile_block.profile_byte_0xc5, + profile_byte_0xc5_hex: probe.packed_profile_block.profile_byte_0xc5_hex.clone(), + }) + } else { + report + .rt3_105_packed_profile_probe + .as_ref() + .map(|probe| SmpLoadedProfile { + profile_kind: "rt3-105-packed-profile".to_string(), + profile_family: probe.profile_family.clone(), + packed_profile_offset: probe.packed_profile_offset, + packed_profile_len: probe.packed_profile_len, + packed_profile_len_hex: probe.packed_profile_len_hex.clone(), + leading_word_0: probe.packed_profile_block.leading_word_0, + leading_word_0_hex: probe.packed_profile_block.leading_word_0_hex.clone(), + header_flag_word_3: Some(probe.packed_profile_block.header_flag_word_3), + header_flag_word_3_hex: Some( + probe.packed_profile_block.header_flag_word_3_hex.clone(), + ), + map_path: probe.packed_profile_block.map_path.clone(), + display_name: probe.packed_profile_block.display_name.clone(), + profile_byte_0x77: probe.packed_profile_block.profile_byte_0x77, + profile_byte_0x77_hex: probe.packed_profile_block.profile_byte_0x77_hex.clone(), + profile_byte_0x82: probe.packed_profile_block.profile_byte_0x82, + profile_byte_0x82_hex: probe.packed_profile_block.profile_byte_0x82_hex.clone(), + profile_byte_0x97: probe.packed_profile_block.profile_byte_0x97, + profile_byte_0x97_hex: probe.packed_profile_block.profile_byte_0x97_hex.clone(), + profile_byte_0xc5: probe.packed_profile_block.profile_byte_0xc5, + profile_byte_0xc5_hex: probe.packed_profile_block.profile_byte_0xc5_hex.clone(), + }) + }; + let candidate_availability_table = report.rt3_105_save_name_table_probe.as_ref().map(|probe| { + SmpLoadedCandidateAvailabilityTable { + source_kind: probe.source_kind.clone(), + semantic_family: probe.semantic_family.clone(), + header_offset: probe.header_offset, + entries_offset: probe.entries_offset, + entries_end_offset: probe.entries_end_offset, + observed_entry_count: probe.observed_entry_count, + zero_availability_count: probe.zero_trailer_entry_count, + zero_availability_names: probe.zero_trailer_entry_names.clone(), + footer_progress_hex_words: vec![ + probe.footer_progress_word_0_hex.clone(), + probe.footer_progress_word_1_hex.clone(), + ], + entries: probe.entries.clone(), + } + }); + let special_conditions_table = + report + .special_conditions_probe + .as_ref() + .map(|probe| SmpLoadedSpecialConditionsTable { + source_kind: probe.source_kind.clone(), + table_offset: probe.table_offset, + table_len: probe.table_len, + enabled_visible_count: probe.enabled_visible_count, + enabled_visible_labels: probe.enabled_visible_labels.clone(), + entries: probe.entries.clone(), + }); + + Ok(SmpLoadedSaveSlice { + file_extension_hint: summary.file_extension_hint.clone(), + container_profile_family: summary.container_profile_family.clone(), + mechanism_family: summary.mechanism_family.clone(), + mechanism_confidence: summary.mechanism_confidence.clone(), + trailer_family: summary.trailer_family.clone(), + bridge_family: summary.bridge_family.clone(), + profile, + candidate_availability_table, + special_conditions_table, + notes: summary.notes.clone(), + }) +} + fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option) -> SmpInspectionReport { let known_tag_hits = KNOWN_TAG_DEFINITIONS .iter() @@ -531,8 +1423,58 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option) -> Sm container_profile.as_ref(), rt3_105_save_bridge_payload_probe.as_ref(), ); + let special_conditions_probe = parse_special_conditions_probe( + bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + ); + let smp_aligned_runtime_rule_band_probe = parse_smp_aligned_runtime_rule_band_probe( + bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + special_conditions_probe.as_ref(), + ); + let post_special_conditions_scalar_probe = parse_post_special_conditions_scalar_probe( + bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + special_conditions_probe.as_ref(), + ); + let post_text_field_neighborhood_probe = parse_post_text_field_neighborhood_probe( + bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + special_conditions_probe.as_ref(), + ); + let locomotive_policy_neighborhood_probe = parse_locomotive_policy_neighborhood_probe( + bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + special_conditions_probe.as_ref(), + ); + let pre_recipe_scalar_plateau_probe = parse_pre_recipe_scalar_plateau_probe( + bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + special_conditions_probe.as_ref(), + ); + let recipe_book_summary_probe = parse_recipe_book_summary_probe( + bytes, + file_extension_hint.as_deref(), + container_profile.as_ref(), + special_conditions_probe.as_ref(), + ); let classic_rehydrate_profile_probe = parse_classic_rehydrate_profile_probe(bytes, runtime_post_span_probe.as_ref()); + let save_load_summary = build_save_load_summary( + file_extension_hint.as_deref(), + container_profile.as_ref(), + runtime_trailer_block.as_ref(), + rt3_105_post_span_bridge_probe.as_ref(), + classic_rehydrate_profile_probe.as_ref(), + rt3_105_packed_profile_probe.as_ref(), + rt3_105_save_name_table_probe.as_ref(), + ); let mut warnings = Vec::new(); if bytes.is_empty() { warnings @@ -610,8 +1552,16 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option) -> Sm rt3_105_post_span_bridge_probe, rt3_105_save_bridge_payload_probe, rt3_105_save_name_table_probe, + special_conditions_probe, + smp_aligned_runtime_rule_band_probe, + post_special_conditions_scalar_probe, + post_text_field_neighborhood_probe, + locomotive_policy_neighborhood_probe, + pre_recipe_scalar_plateau_probe, + recipe_book_summary_probe, classic_rehydrate_profile_probe, rt3_105_packed_profile_probe, + save_load_summary, contains_grounded_runtime_tags: !known_tag_hits.is_empty(), known_tag_hits, notes: vec![ @@ -624,6 +1574,10 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option) -> Sm .to_string(), "The secondary-variant probe classifies that aligned word window into one of the currently observed file-family patterns." .to_string(), + "The recipe-book summary probe reports per-book structural signatures at the grounded recipe-book root [world+0x0fe7] without attempting a full cargo-line decode." + .to_string(), + "Where a recipe cargo-token word looks like two printable letters in its high 16 bits, the probe exposes that as one probable ASCII stem while still treating the wider token semantics as inferred." + .to_string(), "The container-profile layer combines extension hint, header family, and second-window family into one observed container classification." .to_string(), "The save-bootstrap reader currently parses one conservative 8-word descriptor only for known save-container profiles." @@ -642,6 +1596,8 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option) -> Sm .to_string(), "The RT3 1.05 candidate-availability table probe decodes the fixed-width trailing name table from either the common-save bridge payload or the fixed 0x6a70..0x73c0 source range when that header validates." .to_string(), + "The post-special-conditions scalar probe captures the fixed 0x0df4..0x0f30 dword window immediately after the hidden sentinel slot, splits it into the aligned-band overlap prefix and the later tail, and records the live-object offset alignment of that tail without claiming a byte-for-byte mirror." + .to_string(), "The classic rehydrate-profile probe recognizes the grounded 0x32dc -> 0x3714 -> 0x3715 progress-id sequence and captures the exact 0x108-byte block between the latter two ids when that pattern appears." .to_string(), "The classic packed-profile block reader exposes the stable map-path, display-name, atlas-tracked latch bytes, and the small set of nonzero word lanes observed inside that 0x108-byte block." @@ -657,6 +1613,180 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option) -> Sm } } +fn build_save_load_summary( + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, + runtime_trailer_block: Option<&SmpRuntimeTrailerBlock>, + rt3_105_post_span_bridge_probe: Option<&SmpRt3105PostSpanBridgeProbe>, + classic_rehydrate_profile_probe: Option<&SmpClassicRehydrateProfileProbe>, + rt3_105_packed_profile_probe: Option<&SmpRt3105PackedProfileProbe>, + rt3_105_save_name_table_probe: Option<&SmpRt3105SaveNameTableProbe>, +) -> Option { + let file_extension_hint = file_extension_hint.map(str::to_string); + let container_profile_family = container_profile.map(|profile| profile.profile_family.clone()); + let trailer_family = runtime_trailer_block.map(|trailer| trailer.trailer_family.clone()); + let bridge_family = rt3_105_post_span_bridge_probe.map(|bridge| bridge.bridge_family.clone()); + let candidate_table = + rt3_105_save_name_table_probe.map(|probe| SmpSaveLoadCandidateTableSummary { + source_kind: probe.source_kind.clone(), + semantic_family: probe.semantic_family.clone(), + observed_entry_count: probe.observed_entry_count, + zero_availability_count: probe.zero_trailer_entry_count, + zero_availability_names: probe.zero_trailer_entry_names.clone(), + footer_progress_hex_words: vec![ + probe.footer_progress_word_0_hex.clone(), + probe.footer_progress_word_1_hex.clone(), + ], + }); + + if let Some(probe) = classic_rehydrate_profile_probe { + let block = &probe.packed_profile_block; + let mut notes = vec![ + "Classic save load reaches the grounded late rehydrate band 0x32dc -> 0x3714 -> 0x3715." + .to_string(), + "The file exposes one exact 0x108 packed-profile block between progress ids 0x3714 and 0x3715." + .to_string(), + ]; + if let Some(map_path) = &block.map_path { + notes.push(format!("Packed profile map path: {map_path}")); + } + if let Some(display_name) = &block.display_name { + notes.push(format!("Packed profile display name: {display_name}")); + } + + return Some(SmpSaveLoadSummary { + file_extension_hint, + container_profile_family, + mechanism_family: "classic-save-rehydrate-v1".to_string(), + mechanism_confidence: "grounded".to_string(), + packed_profile_kind: Some("classic-rehydrate-profile".to_string()), + packed_profile_family: Some(probe.profile_family.clone()), + packed_profile_offset: Some(probe.packed_profile_offset), + packed_profile_len: Some(probe.packed_profile_len), + map_path: block.map_path.clone(), + display_name: block.display_name.clone(), + profile_byte_0x77: Some(block.profile_byte_0x77), + profile_byte_0x77_hex: Some(block.profile_byte_0x77_hex.clone()), + profile_byte_0x82: Some(block.profile_byte_0x82), + profile_byte_0x82_hex: Some(block.profile_byte_0x82_hex.clone()), + profile_byte_0x97: Some(block.profile_byte_0x97), + profile_byte_0x97_hex: Some(block.profile_byte_0x97_hex.clone()), + profile_byte_0xc5: Some(block.profile_byte_0xc5), + profile_byte_0xc5_hex: Some(block.profile_byte_0xc5_hex.clone()), + trailer_family, + bridge_family: None, + candidate_table, + notes, + }); + } + + if let Some(probe) = rt3_105_packed_profile_probe { + let block = &probe.packed_profile_block; + let mechanism_family = rt3_105_post_span_bridge_probe + .map(|bridge| bridge.bridge_family.clone()) + .unwrap_or_else(|| match probe.profile_family.as_str() { + "rt3-105-scenario-save-container-v1" => { + "rt3-105-scenario-save-profile-analog-v1".to_string() + } + "rt3-105-alt-save-container-v1" => "rt3-105-alt-save-profile-analog-v1".to_string(), + _ => "rt3-105-save-profile-analog-v1".to_string(), + }); + let mechanism_confidence = if rt3_105_post_span_bridge_probe.is_some() { + "mixed" + } else { + "inferred" + } + .to_string(); + let mut notes = Vec::new(); + if let Some(bridge) = rt3_105_post_span_bridge_probe { + notes.push(format!( + "RT3 1.05 save branch uses {} with selector/descriptor {} -> {}.", + bridge.bridge_family, bridge.selector_high_hex, bridge.descriptor_high_hex + )); + } else { + notes.push( + "RT3 1.05 save exposes a packed-profile analogue, but the upstream load bridge is not resolved for this branch." + .to_string(), + ); + } + if let Some(map_path) = &block.map_path { + notes.push(format!("Packed profile map path: {map_path}")); + } + if let Some(display_name) = &block.display_name { + notes.push(format!("Packed profile display name: {display_name}")); + } + if let Some(table) = &candidate_table { + notes.push(format!( + "Candidate table source {} carries {} entries with {} zero-availability overrides.", + table.source_kind, table.observed_entry_count, table.zero_availability_count + )); + } + + return Some(SmpSaveLoadSummary { + file_extension_hint, + container_profile_family, + mechanism_family, + mechanism_confidence, + packed_profile_kind: Some("rt3-105-packed-profile".to_string()), + packed_profile_family: Some(probe.profile_family.clone()), + packed_profile_offset: Some(probe.packed_profile_offset), + packed_profile_len: Some(probe.packed_profile_len), + map_path: block.map_path.clone(), + display_name: block.display_name.clone(), + profile_byte_0x77: Some(block.profile_byte_0x77), + profile_byte_0x77_hex: Some(block.profile_byte_0x77_hex.clone()), + profile_byte_0x82: Some(block.profile_byte_0x82), + profile_byte_0x82_hex: Some(block.profile_byte_0x82_hex.clone()), + profile_byte_0x97: Some(block.profile_byte_0x97), + profile_byte_0x97_hex: Some(block.profile_byte_0x97_hex.clone()), + profile_byte_0xc5: Some(block.profile_byte_0xc5), + profile_byte_0xc5_hex: Some(block.profile_byte_0xc5_hex.clone()), + trailer_family, + bridge_family, + candidate_table, + notes, + }); + } + + if let Some(table) = candidate_table { + return Some(SmpSaveLoadSummary { + file_extension_hint, + container_profile_family, + mechanism_family: "rt3-105-candidate-catalog-source-v1".to_string(), + mechanism_confidence: "mixed".to_string(), + packed_profile_kind: None, + packed_profile_family: None, + packed_profile_offset: None, + packed_profile_len: None, + map_path: None, + display_name: None, + profile_byte_0x77: None, + profile_byte_0x77_hex: None, + profile_byte_0x82: None, + profile_byte_0x82_hex: None, + profile_byte_0x97: None, + profile_byte_0x97_hex: None, + profile_byte_0xc5: None, + profile_byte_0xc5_hex: None, + trailer_family, + bridge_family, + notes: vec![ + format!( + "The file carries the shared 1.05 candidate table source block through {}.", + table.source_kind + ), + format!( + "The table exposes {} named entries with {} zero-availability overrides.", + table.observed_entry_count, table.zero_availability_count + ), + ], + candidate_table: Some(table), + }); + } + + None +} + fn parse_preamble(bytes: &[u8]) -> SmpPreamble { let byte_len = bytes.len().min(PREAMBLE_U32_WORD_COUNT * 4); let words = bytes[..byte_len] @@ -2010,6 +3140,1168 @@ fn parse_rt3_105_save_name_table_probe( }) } +fn parse_special_conditions_probe( + bytes: &[u8], + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, +) -> Option { + let table_len = SPECIAL_CONDITION_COUNT.checked_mul(4)?; + let table_end = SPECIAL_CONDITIONS_OFFSET.checked_add(table_len)?; + if table_end > bytes.len() { + return None; + } + + let mut entries = Vec::with_capacity(SPECIAL_CONDITION_COUNT); + for definition in KNOWN_SPECIAL_CONDITION_DEFINITIONS { + let value = read_u32_at( + bytes, + SPECIAL_CONDITIONS_OFFSET + (definition.slot_index as usize) * 4, + )?; + if value > 1 { + return None; + } + entries.push(SmpSpecialConditionEntry { + slot_index: definition.slot_index, + hidden: definition.hidden, + label_id: definition.label_id, + help_id: definition.help_id, + label: definition.label.to_string(), + value, + value_hex: format!("0x{value:08x}"), + }); + } + + let hidden_sentinel = entries + .iter() + .find(|entry| entry.slot_index == SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT as u8)?; + if hidden_sentinel.value != 1 { + return None; + } + + let enabled_visible_labels = entries + .iter() + .filter(|entry| !entry.hidden && entry.value != 0) + .map(|entry| entry.label.clone()) + .collect::>(); + let source_kind = match file_extension_hint.unwrap_or("") { + "gmp" => "map-fixed-special-conditions-range", + "gms" => "save-fixed-special-conditions-range", + "gmx" => "sandbox-fixed-special-conditions-range", + _ => "fixed-special-conditions-range", + } + .to_string(); + let profile_family = container_profile + .map(|profile| profile.profile_family.clone()) + .unwrap_or_else(|| "unknown".to_string()); + let mut evidence = vec![ + format!("fixed 36-dword range at 0x{SPECIAL_CONDITIONS_OFFSET:04x}"), + "all observed lanes are boolean dwords".to_string(), + "hidden slot 35 carries the expected sentinel value 1".to_string(), + "slot metadata matches the grounded editor special-conditions table at 0x005f3ab0" + .to_string(), + ]; + if enabled_visible_labels.is_empty() { + evidence.push("no visible special conditions enabled in this file".to_string()); + } else { + evidence.push(format!( + "enabled visible conditions: {}", + enabled_visible_labels.join(", ") + )); + } + + Some(SmpSpecialConditionsProbe { + profile_family, + source_kind, + table_offset: SPECIAL_CONDITIONS_OFFSET, + table_len, + enabled_visible_count: enabled_visible_labels.len(), + enabled_visible_labels, + hidden_sentinel_slot_index: SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT as u8, + hidden_sentinel_value: hidden_sentinel.value, + hidden_sentinel_value_hex: hidden_sentinel.value_hex.clone(), + entries, + evidence, + }) +} + +fn parse_post_special_conditions_scalar_probe( + bytes: &[u8], + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, + special_conditions_probe: Option<&SmpSpecialConditionsProbe>, +) -> Option { + special_conditions_probe?; + if POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET > bytes.len() { + return None; + } + + let dword_count = + (POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET - POST_SPECIAL_CONDITIONS_SCALAR_OFFSET) / 4; + let mut nonzero_lanes = Vec::new(); + for index in 0..dword_count { + let absolute_offset = POST_SPECIAL_CONDITIONS_SCALAR_OFFSET + index * 4; + let value = read_u32_at(bytes, absolute_offset)?; + if value == 0 { + continue; + } + nonzero_lanes.push(SmpPostSpecialConditionsScalarLane { + absolute_offset, + relative_offset: absolute_offset - POST_SPECIAL_CONDITIONS_SCALAR_OFFSET, + absolute_offset_hex: format!("0x{absolute_offset:04x}"), + relative_offset_hex: format!( + "0x{:x}", + absolute_offset - POST_SPECIAL_CONDITIONS_SCALAR_OFFSET + ), + value, + value_hex: format!("0x{value:08x}"), + probable_f32_le: probable_normal_f32_string(value), + }); + } + + let source_kind = match file_extension_hint.unwrap_or("") { + "gmp" => "map-post-special-conditions-window", + "gms" => "save-post-special-conditions-window", + "gmx" => "sandbox-post-special-conditions-window", + _ => "post-special-conditions-window", + } + .to_string(); + let profile_family = container_profile + .map(|profile| profile.profile_family.clone()) + .unwrap_or_else(|| "unknown".to_string()); + let first_nonzero_offset = nonzero_lanes.first().map(|lane| lane.absolute_offset); + let last_nonzero_offset = nonzero_lanes.last().map(|lane| lane.absolute_offset); + let overlap_nonzero_relative_offset_hexes = nonzero_lanes + .iter() + .filter(|lane| lane.absolute_offset < POST_SPECIAL_CONDITIONS_SCALAR_OVERLAP_END_OFFSET) + .map(|lane| lane.relative_offset_hex.clone()) + .collect::>(); + let tail_nonzero_lanes = nonzero_lanes + .iter() + .filter(|lane| lane.absolute_offset >= POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET) + .cloned() + .collect::>(); + let tail_first_nonzero_offset = tail_nonzero_lanes.first().map(|lane| lane.absolute_offset); + let tail_last_nonzero_offset = tail_nonzero_lanes.last().map(|lane| lane.absolute_offset); + let tail_nonzero_relative_offset_hexes = tail_nonzero_lanes + .iter() + .map(|lane| lane.relative_offset_hex.clone()) + .collect::>(); + let grounded_text_field_remaining_file_window = &bytes[POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET + ..POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET]; + let mut grounded_text_field_remaining_nonzero_offsets = Vec::new(); + for (index, byte) in grounded_text_field_remaining_file_window.iter().enumerate() { + if *byte != 0 { + grounded_text_field_remaining_nonzero_offsets + .push(POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET + index); + } + } + let grounded_text_field_remaining_first_nonzero_offset = + grounded_text_field_remaining_nonzero_offsets + .first() + .copied(); + let grounded_text_field_remaining_last_nonzero_offset = + grounded_text_field_remaining_nonzero_offsets + .last() + .copied(); + let mut evidence = vec![ + format!( + "fixed post-sentinel dword window at 0x{POST_SPECIAL_CONDITIONS_SCALAR_OFFSET:04x}..0x{POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET:04x}" + ), + "window starts immediately after the hidden special-conditions sentinel slot at 0x0df0" + .to_string(), + format!( + "leading overlap prefix 0x{POST_SPECIAL_CONDITIONS_SCALAR_OFFSET:04x}..0x{POST_SPECIAL_CONDITIONS_SCALAR_OVERLAP_END_OFFSET:04x} aliases aligned runtime-rule band indices {}..{}", + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX, + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX + + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT + - 1 + ), + format!("save-only tail begins at 0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET:04x}"), + format!( + "that tail is offset-aligned with live runtime object bytes [world+0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_OFFSET:04x}..+0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_END_OFFSET:04x}]" + ), + format!( + "the tail start lands on the grounded live field [world+0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_OFFSET:04x}], a 0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_LEN:x}-byte status-text buffer written by win/lose and winner-announcement helpers" + ), + format!( + "current dword scan stops at 0x{POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET:04x}, leaving one byte-aligned continuation window 0x{POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET:04x}..0x{POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET:04x} before the next clean live-field edge at [world+0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_END_OFFSET:04x}]" + ), + format!( + "the next exact grounded fields after that edge begin at [world+0x{POST_TEXT_FIELD_0_RUNTIME_OBJECT_OFFSET:04x}], [world+0x{POST_TEXT_FIELD_1_RUNTIME_OBJECT_OFFSET:04x}], [world+0x{POST_TEXT_FIELD_2_RUNTIME_OBJECT_OFFSET:04x}], [world+0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_OFFSET:04x}], and [world+0x{POST_TEXT_FIELD_4_RUNTIME_OBJECT_OFFSET:04x}], which map to file offsets 0x{POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET:04x}, 0x0f5d, 0x0f61, 0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_FILE_OFFSET:04x}, and 0x0f6d" + ), + format!( + "the first grounded dword-sized fields after that edge are [world+0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_OFFSET:04x}] and [world+0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_OFFSET:04x}], which would land at file offsets 0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_FILE_OFFSET:04x} and 0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_FILE_OFFSET:04x}" + ), + ]; + if nonzero_lanes.is_empty() { + evidence.push( + "all observed dwords in this post-sentinel window are zero for this file".to_string(), + ); + } else { + evidence.push(format!( + "observed {} nonzero dword lanes between {} and {}", + nonzero_lanes.len(), + nonzero_lanes + .first() + .map(|lane| lane.absolute_offset_hex.as_str()) + .unwrap_or("n/a"), + nonzero_lanes + .last() + .map(|lane| lane.absolute_offset_hex.as_str()) + .unwrap_or("n/a") + )); + if nonzero_lanes + .iter() + .all(|lane| lane.probable_f32_le.is_some()) + { + evidence.push( + "every nonzero lane in this window also decodes as a normal finite little-endian f32" + .to_string(), + ); + } + evidence.push(format!( + "{} nonzero lanes fall inside the aligned-band overlap prefix and {} fall inside the later tail", + overlap_nonzero_relative_offset_hexes.len(), + tail_nonzero_lanes.len() + )); + } + evidence.push( + "checked file bytes in the later tail are not yet validated as a byte-for-byte mirror of the live object, because the region aligned to [world+0x4b47] does not currently decode as preserved text in the checked saves" + .to_string(), + ); + if grounded_text_field_remaining_nonzero_offsets.is_empty() { + evidence.push( + "the remaining file window through the grounded text-field edge is all zero in this file" + .to_string(), + ); + } else { + evidence.push(format!( + "the remaining file window through the grounded text-field edge still has {} nonzero bytes between 0x{:04x} and 0x{:04x}", + grounded_text_field_remaining_nonzero_offsets.len(), + grounded_text_field_remaining_first_nonzero_offset.unwrap_or(0), + grounded_text_field_remaining_last_nonzero_offset.unwrap_or(0) + )); + } + + Some(SmpPostSpecialConditionsScalarProbe { + profile_family, + source_kind, + window_offset: POST_SPECIAL_CONDITIONS_SCALAR_OFFSET, + window_end_offset: POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET, + window_len: POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET + - POST_SPECIAL_CONDITIONS_SCALAR_OFFSET, + window_len_hex: format!( + "0x{:x}", + POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET - POST_SPECIAL_CONDITIONS_SCALAR_OFFSET + ), + dword_count, + overlap_end_offset: POST_SPECIAL_CONDITIONS_SCALAR_OVERLAP_END_OFFSET, + overlap_end_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_SCALAR_OVERLAP_END_OFFSET:04x}" + ), + overlap_dword_count: (POST_SPECIAL_CONDITIONS_SCALAR_OVERLAP_END_OFFSET + - POST_SPECIAL_CONDITIONS_SCALAR_OFFSET) + / 4, + overlap_nonzero_dword_count: overlap_nonzero_relative_offset_hexes.len(), + overlap_nonzero_relative_offset_hexes, + tail_offset: POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET, + tail_offset_hex: format!("0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET:04x}"), + tail_len: POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET + - POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET, + tail_len_hex: format!( + "0x{:x}", + POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET - POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET + ), + tail_dword_count: (POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET + - POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET) + / 4, + tail_runtime_object_offset: POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_OFFSET, + tail_runtime_object_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_OFFSET:04x}" + ), + tail_runtime_object_end_offset: + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_END_OFFSET, + tail_runtime_object_end_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_END_OFFSET:04x}" + ), + tail_runtime_object_validated_byte_mirror: false, + tail_grounded_live_field_offset: + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_OFFSET, + tail_grounded_live_field_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_OFFSET:04x}" + ), + tail_grounded_live_field_name: "victory-or-outcome status text buffer".to_string(), + tail_grounded_live_field_copy_len: + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_LEN, + tail_grounded_live_field_copy_len_hex: format!( + "0x{:x}", + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_LEN + ), + tail_grounded_live_field_copy_end_offset: + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_END_OFFSET, + tail_grounded_live_field_copy_end_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_END_OFFSET:04x}" + ), + tail_window_cuts_through_grounded_live_field: + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_END_OFFSET + < POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_END_OFFSET, + tail_grounded_live_field_remaining_file_window_offset: + POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET, + tail_grounded_live_field_remaining_file_window_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET:04x}" + ), + tail_grounded_live_field_remaining_file_window_len: + POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET + - POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET, + tail_grounded_live_field_remaining_file_window_len_hex: format!( + "0x{:x}", + POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET + - POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET + ), + tail_grounded_live_field_remaining_file_window_nonzero_byte_count: + grounded_text_field_remaining_nonzero_offsets.len(), + tail_grounded_live_field_remaining_file_window_first_nonzero_offset: + grounded_text_field_remaining_first_nonzero_offset, + tail_grounded_live_field_remaining_file_window_first_nonzero_offset_hex: + grounded_text_field_remaining_first_nonzero_offset + .map(|offset| format!("0x{offset:04x}")), + tail_grounded_live_field_remaining_file_window_last_nonzero_offset: + grounded_text_field_remaining_last_nonzero_offset, + tail_grounded_live_field_remaining_file_window_last_nonzero_offset_hex: + grounded_text_field_remaining_last_nonzero_offset + .map(|offset| format!("0x{offset:04x}")), + tail_next_grounded_dword_field_offset: + POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_OFFSET, + tail_next_grounded_dword_field_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_OFFSET:04x}" + ), + tail_next_grounded_dword_field_file_offset: + POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_FILE_OFFSET, + tail_next_grounded_dword_field_file_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_FILE_OFFSET:04x}" + ), + tail_second_grounded_dword_field_offset: + POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_OFFSET, + tail_second_grounded_dword_field_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_OFFSET:04x}" + ), + tail_second_grounded_dword_field_file_offset: + POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_FILE_OFFSET, + tail_second_grounded_dword_field_file_offset_hex: format!( + "0x{POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_FILE_OFFSET:04x}" + ), + post_text_field_file_alignment_matches_grounded_dword_fields: false, + tail_nonzero_dword_count: tail_nonzero_lanes.len(), + tail_first_nonzero_offset, + tail_first_nonzero_offset_hex: tail_first_nonzero_offset + .map(|offset| format!("0x{offset:04x}")), + tail_last_nonzero_offset, + tail_last_nonzero_offset_hex: tail_last_nonzero_offset + .map(|offset| format!("0x{offset:04x}")), + tail_nonzero_relative_offset_hexes, + nonzero_dword_count: nonzero_lanes.len(), + first_nonzero_offset, + first_nonzero_offset_hex: first_nonzero_offset.map(|offset| format!("0x{offset:04x}")), + last_nonzero_offset, + last_nonzero_offset_hex: last_nonzero_offset.map(|offset| format!("0x{offset:04x}")), + nonzero_lanes, + evidence, + }) +} + +fn parse_post_text_field_neighborhood_probe( + bytes: &[u8], + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, + special_conditions_probe: Option<&SmpSpecialConditionsProbe>, +) -> Option { + special_conditions_probe?; + if POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET > bytes.len() { + return None; + } + + let profile_family = container_profile + .map(|profile| profile.profile_family.clone()) + .unwrap_or_else(|| "unknown".to_string()); + let source_kind = match file_extension_hint.unwrap_or("") { + "gmp" => "post-text-grounded-field-neighborhood", + "gms" => "post-text-grounded-field-neighborhood", + "gmx" => "post-text-grounded-field-neighborhood", + _ => "post-text-grounded-field-neighborhood", + } + .to_string(); + + let exact_fields = [ + ( + "Auto-Show Grade During Track Lay", + POST_TEXT_FIELD_0_RUNTIME_OBJECT_OFFSET, + POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET, + 1usize, + ), + ( + "Starting Building Density Level", + POST_TEXT_FIELD_1_RUNTIME_OBJECT_OFFSET, + 0x0f5dusize, + 1usize, + ), + ( + "Building Density Growth", + POST_TEXT_FIELD_2_RUNTIME_OBJECT_OFFSET, + 0x0f61usize, + 1usize, + ), + ( + "leftover simulation time accumulator", + POST_TEXT_FIELD_3_RUNTIME_OBJECT_OFFSET, + 0x0f65usize, + 4usize, + ), + ( + "selected-year lane snapshot", + POST_TEXT_FIELD_4_RUNTIME_OBJECT_OFFSET, + 0x0f6dusize, + 1usize, + ), + ( + "late locomotive policy gate dword", + POST_TEXT_FIELD_5_RUNTIME_OBJECT_OFFSET, + 0x0f71usize, + 4usize, + ), + ]; + + let grounded_field_observations = exact_fields + .iter() + .map( + |(field_name, runtime_object_offset, file_offset, field_width_bytes)| { + let raw = &bytes[*file_offset..*file_offset + *field_width_bytes]; + let raw_hex = hex_encode(raw); + let (value_u8, value_u8_hex, value_u32, value_u32_hex, probable_f32_le) = + if *field_width_bytes == 1 { + let value = raw[0]; + ( + Some(value), + Some(format!("0x{value:02x}")), + None, + None, + None, + ) + } else { + let value = u32::from_le_bytes([raw[0], raw[1], raw[2], raw[3]]); + ( + None, + None, + Some(value), + Some(format!("0x{value:08x}")), + probable_normal_f32_string(value), + ) + }; + SmpPostTextGroundedFieldObservation { + field_name: (*field_name).to_string(), + runtime_object_offset: *runtime_object_offset, + runtime_object_offset_hex: format!("0x{runtime_object_offset:04x}"), + file_offset: *file_offset, + file_offset_hex: format!("0x{file_offset:04x}"), + field_width_bytes: *field_width_bytes, + field_width_bytes_hex: format!("0x{field_width_bytes:x}"), + raw_hex, + value_u8, + value_u8_hex, + value_u32, + value_u32_hex, + probable_f32_le, + } + }, + ) + .collect::>(); + + let one_byte_early_float_candidates = exact_fields + .iter() + .filter(|(_, _, file_offset, _)| *file_offset > 0) + .filter_map(|(field_name, runtime_object_offset, file_offset, _)| { + let candidate_offset = file_offset - 1; + let value = read_u32_at(bytes, candidate_offset)?; + let probable_f32_le = probable_normal_f32_string(value)?; + Some(SmpPostTextFloatAlignmentCandidate { + grounded_field_name: (*field_name).to_string(), + grounded_field_runtime_object_offset: *runtime_object_offset, + grounded_field_runtime_object_offset_hex: format!("0x{runtime_object_offset:04x}"), + grounded_field_file_offset: *file_offset, + grounded_field_file_offset_hex: format!("0x{file_offset:04x}"), + candidate_offset, + candidate_offset_hex: format!("0x{candidate_offset:04x}"), + candidate_value: value, + candidate_value_hex: format!("0x{value:08x}"), + probable_f32_le, + }) + }) + .collect::>(); + + let mut evidence = vec![ + format!( + "post-text grounded-field neighborhood spans file offsets 0x{POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET:04x}..0x{POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET:04x}" + ), + "this neighborhood starts at the first grounded post-text field [world+0x4c74] and extends through the later dword at [world+0x4c8c]".to_string(), + "the exact grounded field offsets here are byte-oriented at 0x0f59, 0x0f5d, 0x0f61, and 0x0f6d, with dword-sized fields only at 0x0f65 and 0x0f71".to_string(), + ]; + if one_byte_early_float_candidates.is_empty() { + evidence.push( + "no one-byte-early little-endian float-looking starts were observed ahead of the grounded fields in this file".to_string(), + ); + } else { + evidence.push(format!( + "observed {} float-looking 4-byte starts exactly one byte before grounded field offsets in this file", + one_byte_early_float_candidates.len() + )); + } + + Some(SmpPostTextFieldNeighborhoodProbe { + profile_family, + source_kind, + window_offset: POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET, + window_end_offset: POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET, + window_len: POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET - POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET, + window_len_hex: format!( + "0x{:x}", + POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET - POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET + ), + grounded_field_observations, + one_byte_early_float_candidates, + evidence, + }) +} + +fn parse_locomotive_policy_neighborhood_probe( + bytes: &[u8], + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, + special_conditions_probe: Option<&SmpSpecialConditionsProbe>, +) -> Option { + special_conditions_probe?; + if LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET > bytes.len() { + return None; + } + + let profile_family = container_profile + .map(|profile| profile.profile_family.clone()) + .unwrap_or_else(|| "unknown".to_string()); + let source_kind = match file_extension_hint.unwrap_or("") { + "gmp" => "locomotive-policy-neighborhood", + "gms" => "locomotive-policy-neighborhood", + "gmx" => "locomotive-policy-neighborhood", + _ => "locomotive-policy-neighborhood", + } + .to_string(); + + let exact_fields = [ + ( + "selected-year bucket companion scalar", + LOCOMOTIVE_POLICY_FIELD_NEG3_RUNTIME_OBJECT_OFFSET, + 0x0f87usize, + 4usize, + ), + ( + "startup-dispatch reset-owned band at +0x4cae", + LOCOMOTIVE_POLICY_FIELD_NEG2_RUNTIME_OBJECT_OFFSET, + 0x0f93usize, + 4usize, + ), + ( + "startup-dispatch reset-owned band at +0x4cb2", + LOCOMOTIVE_POLICY_FIELD_NEG1_RUNTIME_OBJECT_OFFSET, + 0x0f97usize, + 4usize, + ), + ( + "linked-site removal follow-on gate", + LOCOMOTIVE_POLICY_FIELD_0_RUNTIME_OBJECT_OFFSET, + 0x0f78usize, + 1usize, + ), + ( + "All Steam Locos Avail.", + LOCOMOTIVE_POLICY_FIELD_1_RUNTIME_OBJECT_OFFSET, + 0x0f7cusize, + 1usize, + ), + ( + "All Diesel Locos Avail.", + LOCOMOTIVE_POLICY_FIELD_2_RUNTIME_OBJECT_OFFSET, + 0x0f7dusize, + 1usize, + ), + ( + "All Electric Locos Avail.", + LOCOMOTIVE_POLICY_FIELD_3_RUNTIME_OBJECT_OFFSET, + 0x0f7eusize, + 1usize, + ), + ( + "station-list selected station id", + LOCOMOTIVE_POLICY_FIELD_4_RUNTIME_OBJECT_OFFSET, + 0x0f9fusize, + 4usize, + ), + ( + "cached available-locomotive rating", + LOCOMOTIVE_POLICY_FIELD_5_RUNTIME_OBJECT_OFFSET, + 0x0fa3usize, + 4usize, + ), + ]; + + let grounded_field_observations = exact_fields + .iter() + .map( + |(field_name, runtime_object_offset, file_offset, field_width_bytes)| { + let raw = &bytes[*file_offset..*file_offset + *field_width_bytes]; + let raw_hex = hex_encode(raw); + let (value_u8, value_u8_hex, value_u32, value_u32_hex, probable_f32_le) = + if *field_width_bytes == 1 { + let value = raw[0]; + ( + Some(value), + Some(format!("0x{value:02x}")), + None, + None, + None, + ) + } else { + let value = u32::from_le_bytes([raw[0], raw[1], raw[2], raw[3]]); + ( + None, + None, + Some(value), + Some(format!("0x{value:08x}")), + probable_normal_f32_string(value), + ) + }; + SmpLocomotivePolicyFieldObservation { + field_name: (*field_name).to_string(), + runtime_object_offset: *runtime_object_offset, + runtime_object_offset_hex: format!("0x{runtime_object_offset:04x}"), + file_offset: *file_offset, + file_offset_hex: format!("0x{file_offset:04x}"), + field_width_bytes: *field_width_bytes, + field_width_bytes_hex: format!("0x{field_width_bytes:x}"), + raw_hex, + value_u8, + value_u8_hex, + value_u32, + value_u32_hex, + probable_f32_le, + } + }, + ) + .collect::>(); + + let three_byte_early_float_candidates = exact_fields + .iter() + .filter(|(_, _, _, width)| *width == 4usize) + .filter_map(|(field_name, runtime_object_offset, file_offset, _)| { + let candidate_offset = file_offset.saturating_sub(3); + let value = read_u32_at(bytes, candidate_offset)?; + let probable_f32_le = probable_normal_f32_string(value)?; + Some(SmpLocomotivePolicyFloatAlignmentCandidate { + grounded_field_name: (*field_name).to_string(), + grounded_field_runtime_object_offset: *runtime_object_offset, + grounded_field_runtime_object_offset_hex: format!("0x{runtime_object_offset:04x}"), + grounded_field_file_offset: *file_offset, + grounded_field_file_offset_hex: format!("0x{file_offset:04x}"), + candidate_offset, + candidate_offset_hex: format!("0x{candidate_offset:04x}"), + candidate_value: value, + candidate_value_hex: format!("0x{value:08x}"), + probable_f32_le, + }) + }) + .collect::>(); + + let mut evidence = vec![ + format!( + "locomotive-policy neighborhood spans file offsets 0x{LOCOMOTIVE_POLICY_NEIGHBORHOOD_OFFSET:04x}..0x{LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET:04x}" + ), + "this neighborhood covers the selected-year bucket companion scalar, two startup-reset-owned bands, the linked-site removal gate, the three locomotive-availability policy bytes, the station-list selected-station mirror, and the cached available-locomotive rating".to_string(), + "the exact byte policy lanes live at 0x0f78 and 0x0f7c..0x0f7e, while the earlier grounded dword starts map to 0x0f87, 0x0f93, and 0x0f97 and the later grounded dword starts map to 0x0f9f and 0x0fa3".to_string(), + ]; + if three_byte_early_float_candidates.is_empty() { + evidence.push( + "no three-byte-early little-endian float-looking starts were observed ahead of the grounded dword fields in this file".to_string(), + ); + } else { + evidence.push(format!( + "observed {} float-looking 4-byte starts exactly three bytes before grounded dword fields in this file", + three_byte_early_float_candidates.len() + )); + } + + Some(SmpLocomotivePolicyNeighborhoodProbe { + profile_family, + source_kind, + window_offset: LOCOMOTIVE_POLICY_NEIGHBORHOOD_OFFSET, + window_end_offset: LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET, + window_len: LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET + - LOCOMOTIVE_POLICY_NEIGHBORHOOD_OFFSET, + window_len_hex: format!( + "0x{:x}", + LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET - LOCOMOTIVE_POLICY_NEIGHBORHOOD_OFFSET + ), + grounded_field_observations, + three_byte_early_float_candidates, + evidence, + }) +} + +fn parse_pre_recipe_scalar_plateau_probe( + bytes: &[u8], + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, + special_conditions_probe: Option<&SmpSpecialConditionsProbe>, +) -> Option { + special_conditions_probe?; + if PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET > bytes.len() { + return None; + } + + let profile_family = container_profile + .map(|profile| profile.profile_family.clone()) + .unwrap_or_else(|| "unknown".to_string()); + let source_kind = match file_extension_hint.unwrap_or("") { + "gmp" => "pre-recipe-scalar-plateau", + "gms" => "pre-recipe-scalar-plateau", + "gmx" => "pre-recipe-scalar-plateau", + _ => "pre-recipe-scalar-plateau", + } + .to_string(); + + let aligned_dword_count = + (PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET - PRE_RECIPE_SCALAR_PLATEAU_OFFSET) / 4; + let mut nonzero_lanes = Vec::new(); + for index in 0..aligned_dword_count { + let absolute_offset = PRE_RECIPE_SCALAR_PLATEAU_OFFSET + index * 4; + let value = read_u32_at(bytes, absolute_offset)?; + if value == 0 { + continue; + } + nonzero_lanes.push(SmpPreRecipeScalarPlateauLane { + absolute_offset, + relative_offset: absolute_offset - PRE_RECIPE_SCALAR_PLATEAU_OFFSET, + absolute_offset_hex: format!("0x{absolute_offset:04x}"), + relative_offset_hex: format!( + "0x{:x}", + absolute_offset - PRE_RECIPE_SCALAR_PLATEAU_OFFSET + ), + value, + value_hex: format!("0x{value:08x}"), + probable_f32_le: probable_normal_f32_string(value), + }); + } + + let family_signature = match ( + read_u32_at(bytes, 0x0faf), + read_u32_at(bytes, 0x0fb3), + read_u32_at(bytes, 0x0fcb), + ) { + (Some(0x4000003f), Some(0xe560423f), Some(0x00000000)) => { + "rt3-105-scenario-pre-recipe-plateau-v1" + } + (Some(0x8000003f), Some(0x75c28f3f), Some(0x00300000)) => { + "rt3-105-base-pre-recipe-plateau-v1" + } + (Some(0x8000003f), Some(0x75c28f3f), Some(0xcdcdcd00)) => { + "rt3-105-alt-pre-recipe-plateau-v1" + } + _ => "unknown", + } + .to_string(); + + let mut evidence = vec![ + format!( + "aligned scalar plateau spans file offsets 0x{PRE_RECIPE_SCALAR_PLATEAU_OFFSET:04x}..0x{PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET:04x}" + ), + "this plateau ends immediately before the grounded recipe-book root at [world+0x0fe7]".to_string(), + "current grounding inside this span is still structural rather than semantic, so the probe only records aligned dword lanes and observed family signatures".to_string(), + ]; + if !nonzero_lanes.is_empty() { + evidence.push(format!( + "observed {} nonzero aligned dword lanes in the pre-recipe plateau", + nonzero_lanes.len() + )); + } + if family_signature != "unknown" { + evidence.push(format!( + "matched observed family signature {family_signature}" + )); + } + + Some(SmpPreRecipeScalarPlateauProbe { + profile_family, + source_kind, + window_offset: PRE_RECIPE_SCALAR_PLATEAU_OFFSET, + window_end_offset: PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET, + window_len: PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET - PRE_RECIPE_SCALAR_PLATEAU_OFFSET, + window_len_hex: format!( + "0x{:x}", + PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET - PRE_RECIPE_SCALAR_PLATEAU_OFFSET + ), + aligned_dword_count, + family_signature, + nonzero_lanes, + evidence, + }) +} + +fn parse_recipe_book_summary_probe( + bytes: &[u8], + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, + special_conditions_probe: Option<&SmpSpecialConditionsProbe>, +) -> Option { + special_conditions_probe?; + if RECIPE_BOOK_SUMMARY_END_OFFSET > bytes.len() { + return None; + } + + let profile_family = container_profile + .map(|profile| profile.profile_family.clone()) + .unwrap_or_else(|| "unknown".to_string()); + let source_kind = match file_extension_hint.unwrap_or("") { + "gmp" => "recipe-book-summary", + "gms" => "recipe-book-summary", + "gmx" => "recipe-book-summary", + _ => "recipe-book-summary", + } + .to_string(); + + let mut books = Vec::with_capacity(RECIPE_BOOK_COUNT); + let mut mixed_head_count = 0usize; + let mut mixed_line_area_count = 0usize; + let mut cdcd_line_area_count = 0usize; + let mut zero_line_area_count = 0usize; + + for book_index in 0..RECIPE_BOOK_COUNT { + let book_offset = RECIPE_BOOK_ROOT_OFFSET + book_index * RECIPE_BOOK_STRIDE; + let head = &bytes[book_offset..book_offset + RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET]; + let line_area_offset = book_offset + RECIPE_BOOK_LINE_AREA_OFFSET; + let line_area = &bytes[line_area_offset..line_area_offset + RECIPE_BOOK_LINE_AREA_LEN]; + let max_annual_production_offset = book_offset + RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET; + let max_annual_production_word = read_u32_at(bytes, max_annual_production_offset)?; + let mut lines = Vec::with_capacity(RECIPE_BOOK_LINE_COUNT); + for line_index in 0..RECIPE_BOOK_LINE_COUNT { + let line_offset = line_area_offset + line_index * RECIPE_BOOK_LINE_STRIDE; + let line = &bytes[line_offset..line_offset + RECIPE_BOOK_LINE_STRIDE]; + let supplied_cargo_token_window = &line[0x08..0x20]; + let demanded_cargo_token_window = &line[0x1c..0x30]; + let mode_word = read_u32_at(bytes, line_offset)?; + let annual_amount_word = read_u32_at(bytes, line_offset + 0x04)?; + let supplied_cargo_token_word = read_u32_at(bytes, line_offset + 0x08)?; + let demanded_cargo_token_word = read_u32_at(bytes, line_offset + 0x1c)?; + lines.push(SmpRecipeBookLineSummary { + line_index, + line_offset, + line_offset_hex: format!("0x{line_offset:04x}"), + line_kind: classify_recipe_book_region_kind(line).to_string(), + line_signature_kind: classify_recipe_line_signature( + mode_word, + supplied_cargo_token_word, + demanded_cargo_token_word, + ) + .to_string(), + imports_to_runtime_descriptor: mode_word != 0, + runtime_import_branch_kind: classify_recipe_runtime_import_branch(mode_word) + .to_string(), + line_nonzero_byte_count: line.iter().filter(|byte| **byte != 0).count(), + line_cdcd_byte_count: line.iter().filter(|byte| **byte == 0xcd).count(), + line_first_16_hex: hex_encode(&line[..RECIPE_BOOK_HEAD_SAMPLE_LEN.min(line.len())]), + mode_word_offset: line_offset, + mode_word_offset_hex: format!("0x{line_offset:04x}"), + mode_word, + mode_word_hex: format!("0x{mode_word:08x}"), + annual_amount_offset: line_offset + 0x04, + annual_amount_offset_hex: format!("0x{:04x}", line_offset + 0x04), + annual_amount_word, + annual_amount_word_hex: format!("0x{annual_amount_word:08x}"), + annual_amount_probable_f32_le: probable_normal_f32_string(annual_amount_word), + supplied_cargo_token_offset: line_offset + 0x08, + supplied_cargo_token_offset_hex: format!("0x{:04x}", line_offset + 0x08), + supplied_cargo_token_word, + supplied_cargo_token_word_hex: format!("0x{supplied_cargo_token_word:08x}"), + supplied_cargo_token_layout_kind: classify_recipe_token_layout( + supplied_cargo_token_word, + ) + .to_string(), + supplied_cargo_token_window_hex: hex_encode(supplied_cargo_token_window), + supplied_cargo_token_window_ascii: ascii_preview(supplied_cargo_token_window), + supplied_cargo_token_active_in_runtime_import: mode_word != 0 && mode_word != 1, + supplied_cargo_token_probable_high16_ascii_stem: + probable_recipe_token_high16_ascii_stem(supplied_cargo_token_word), + demanded_cargo_token_offset: line_offset + 0x1c, + demanded_cargo_token_offset_hex: format!("0x{:04x}", line_offset + 0x1c), + demanded_cargo_token_word, + demanded_cargo_token_word_hex: format!("0x{demanded_cargo_token_word:08x}"), + demanded_cargo_token_layout_kind: classify_recipe_token_layout( + demanded_cargo_token_word, + ) + .to_string(), + demanded_cargo_token_window_hex: hex_encode(demanded_cargo_token_window), + demanded_cargo_token_window_ascii: ascii_preview(demanded_cargo_token_window), + demanded_cargo_token_active_in_runtime_import: mode_word == 1 || mode_word == 3, + demanded_cargo_token_probable_high16_ascii_stem: + probable_recipe_token_high16_ascii_stem(demanded_cargo_token_word), + }); + } + + let head_kind = classify_recipe_book_region_kind(head).to_string(); + let line_area_kind = classify_recipe_book_region_kind(line_area).to_string(); + if head_kind == "mixed" { + mixed_head_count += 1; + } + match line_area_kind.as_str() { + "zero" => zero_line_area_count += 1, + "cdcd" => cdcd_line_area_count += 1, + _ => mixed_line_area_count += 1, + } + + books.push(SmpRecipeBookSummaryBook { + book_index, + book_offset, + book_offset_hex: format!("0x{book_offset:04x}"), + head_kind, + head_nonzero_byte_count: head.iter().filter(|byte| **byte != 0).count(), + head_cdcd_byte_count: head.iter().filter(|byte| **byte == 0xcd).count(), + head_first_16_hex: hex_encode(&head[..RECIPE_BOOK_HEAD_SAMPLE_LEN.min(head.len())]), + max_annual_production_offset, + max_annual_production_offset_hex: format!("0x{max_annual_production_offset:04x}"), + max_annual_production_word, + max_annual_production_word_hex: format!("0x{max_annual_production_word:08x}"), + max_annual_production_probable_f32_le: probable_normal_f32_string( + max_annual_production_word, + ), + line_area_offset, + line_area_offset_hex: format!("0x{line_area_offset:04x}"), + line_area_len: RECIPE_BOOK_LINE_AREA_LEN, + line_area_len_hex: format!("0x{:x}", RECIPE_BOOK_LINE_AREA_LEN), + line_area_kind, + line_area_nonzero_byte_count: line_area.iter().filter(|byte| **byte != 0).count(), + line_area_cdcd_byte_count: line_area.iter().filter(|byte| **byte == 0xcd).count(), + line_area_first_16_hex: hex_encode( + &line_area[..RECIPE_BOOK_HEAD_SAMPLE_LEN.min(line_area.len())], + ), + lines, + }); + } + + let mut evidence = vec![ + format!( + "grounded recipe-book root begins at file offset 0x{RECIPE_BOOK_ROOT_OFFSET:04x} and runtime offset [world+0x{RECIPE_BOOK_ROOT_OFFSET:04x}]" + ), + format!( + "parsed {RECIPE_BOOK_COUNT} fixed books with stride 0x{RECIPE_BOOK_STRIDE:x}, shared cap lane at +0x{RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET:x}, and five line slots at +0x{RECIPE_BOOK_LINE_AREA_OFFSET:x} with stride 0x{RECIPE_BOOK_LINE_STRIDE:x}" + ), + "this probe is structural only: it summarizes per-book heads plus five raw line records without decoding the mode or cargo-token semantics beyond the grounded offsets".to_string(), + ]; + evidence.push(format!( + "{mixed_head_count} books have mixed pre-line heads; line areas split into {zero_line_area_count} zero, {cdcd_line_area_count} cdcd, and {mixed_line_area_count} mixed books" + )); + + Some(SmpRecipeBookSummaryProbe { + profile_family, + source_kind, + root_offset: RECIPE_BOOK_ROOT_OFFSET, + root_offset_hex: format!("0x{RECIPE_BOOK_ROOT_OFFSET:04x}"), + runtime_object_root_offset: RECIPE_BOOK_ROOT_OFFSET, + runtime_object_root_offset_hex: format!("0x{RECIPE_BOOK_ROOT_OFFSET:04x}"), + book_count: RECIPE_BOOK_COUNT, + book_stride: RECIPE_BOOK_STRIDE, + book_stride_hex: format!("0x{:x}", RECIPE_BOOK_STRIDE), + max_annual_production_relative_offset: RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET, + max_annual_production_relative_offset_hex: format!( + "0x{:x}", + RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET + ), + line_area_relative_offset: RECIPE_BOOK_LINE_AREA_OFFSET, + line_area_relative_offset_hex: format!("0x{:x}", RECIPE_BOOK_LINE_AREA_OFFSET), + line_count: RECIPE_BOOK_LINE_COUNT, + line_stride: RECIPE_BOOK_LINE_STRIDE, + line_stride_hex: format!("0x{:x}", RECIPE_BOOK_LINE_STRIDE), + books, + evidence, + }) +} + +fn parse_smp_aligned_runtime_rule_band_probe( + bytes: &[u8], + file_extension_hint: Option<&str>, + container_profile: Option<&SmpContainerProfile>, + special_conditions_probe: Option<&SmpSpecialConditionsProbe>, +) -> Option { + special_conditions_probe?; + if SMP_ALIGNED_RUNTIME_RULE_END_OFFSET > bytes.len() { + return None; + } + + let source_kind = match file_extension_hint.unwrap_or("") { + "gmp" => "map-smp-aligned-runtime-rule-band", + "gms" => "save-smp-aligned-runtime-rule-band", + "gmx" => "sandbox-smp-aligned-runtime-rule-band", + _ => "smp-aligned-runtime-rule-band", + } + .to_string(); + let profile_family = container_profile + .map(|profile| profile.profile_family.clone()) + .unwrap_or_else(|| "unknown".to_string()); + + let mut nonzero_lanes = Vec::new(); + for band_index in 0..SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT { + let absolute_offset = SPECIAL_CONDITIONS_OFFSET + band_index * 4; + let value = read_u32_at(bytes, absolute_offset)?; + if value == 0 { + continue; + } + let lane_kind = if band_index < SPECIAL_CONDITION_COUNT { + "known-special-condition-dword" + } else if band_index < SMP_ALIGNED_RUNTIME_RULE_KNOWN_EDITOR_RULE_COUNT { + "unlabeled-editor-rule-dword" + } else { + "trailing-runtime-scalar" + } + .to_string(); + let known_label = if band_index < SPECIAL_CONDITION_COUNT { + Some( + KNOWN_SPECIAL_CONDITION_DEFINITIONS[band_index] + .label + .to_string(), + ) + } else { + None + }; + nonzero_lanes.push(SmpAlignedRuntimeRuleBandLane { + band_index, + absolute_offset, + relative_offset: absolute_offset - SPECIAL_CONDITIONS_OFFSET, + absolute_offset_hex: format!("0x{absolute_offset:04x}"), + relative_offset_hex: format!("0x{:x}", absolute_offset - SPECIAL_CONDITIONS_OFFSET), + lane_kind, + known_label, + value, + value_hex: format!("0x{value:08x}"), + probable_f32_le: probable_normal_f32_string(value), + }); + } + + let nonzero_band_indices = nonzero_lanes + .iter() + .map(|lane| lane.band_index) + .collect::>(); + let nonzero_post_window_overlap_band_indices = nonzero_lanes + .iter() + .filter(|lane| { + lane.band_index >= SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX + && lane.band_index + < SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX + + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT + }) + .map(|lane| lane.band_index) + .collect::>(); + let nonzero_post_window_overlap_post_relative_offset_hexes = nonzero_lanes + .iter() + .filter(|lane| { + lane.band_index >= SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX + && lane.band_index + < SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX + + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT + }) + .map(|lane| { + format!( + "0x{:x}", + (lane.band_index - SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX) * 4 + ) + }) + .collect::>(); + let nonzero_relative_offset_hexes = nonzero_lanes + .iter() + .map(|lane| lane.relative_offset_hex.clone()) + .collect::>(); + let mut evidence = vec![ + format!( + "fixed `.smp`-aligned runtime-rule band at 0x{SPECIAL_CONDITIONS_OFFSET:04x}..0x{SMP_ALIGNED_RUNTIME_RULE_END_OFFSET:04x}" + ), + format!( + "band spans {} known editor rule dwords plus one trailing scalar", + SMP_ALIGNED_RUNTIME_RULE_KNOWN_EDITOR_RULE_COUNT + ), + "first 36 dwords overlap the older fixed matrix probe rooted at 0x0d64".to_string(), + format!( + "trailing band indices {}..{} alias the leading post-sentinel window offsets {}..{}", + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX, + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX + + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT + - 1, + "0x00", + format!( + "0x{:x}", + (SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT - 1) * 4 + ) + ), + "band matches the grounded `.smp` save/load copy into `[world+0x4a7f..+0x4b43]`" + .to_string(), + ]; + if nonzero_lanes.is_empty() { + evidence + .push("all dwords in the aligned runtime-rule band are zero for this file".to_string()); + } else { + evidence.push(format!( + "observed {} nonzero lanes at band indices {:?}", + nonzero_lanes.len(), + nonzero_band_indices + )); + if !nonzero_post_window_overlap_band_indices.is_empty() { + evidence.push(format!( + "nonzero overlap lanes mirror post-window offsets {:?}", + nonzero_post_window_overlap_post_relative_offset_hexes + )); + } + } + + Some(SmpAlignedRuntimeRuleBandProbe { + profile_family, + source_kind, + band_offset: SPECIAL_CONDITIONS_OFFSET, + band_end_offset: SMP_ALIGNED_RUNTIME_RULE_END_OFFSET, + band_len: SMP_ALIGNED_RUNTIME_RULE_END_OFFSET - SPECIAL_CONDITIONS_OFFSET, + band_len_hex: format!( + "0x{:x}", + SMP_ALIGNED_RUNTIME_RULE_END_OFFSET - SPECIAL_CONDITIONS_OFFSET + ), + dword_count: SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT, + known_editor_rule_dword_count: SMP_ALIGNED_RUNTIME_RULE_KNOWN_EDITOR_RULE_COUNT, + trailing_scalar_index: SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT - 1, + trailing_scalar_offset: SPECIAL_CONDITIONS_OFFSET + + (SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT - 1) * 4, + trailing_scalar_offset_hex: format!( + "0x{:04x}", + SPECIAL_CONDITIONS_OFFSET + (SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT - 1) * 4 + ), + post_window_overlap_start_index: SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX, + post_window_overlap_dword_count: SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT, + post_window_overlap_end_index: SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX + + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT + - 1, + post_window_overlap_post_relative_offset_start_hex: "0x0".to_string(), + post_window_overlap_post_relative_offset_end_hex: format!( + "0x{:x}", + (SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT - 1) * 4 + ), + nonzero_post_window_overlap_band_indices, + nonzero_post_window_overlap_post_relative_offset_hexes, + nonzero_lane_count: nonzero_lanes.len(), + nonzero_band_indices, + nonzero_relative_offset_hexes, + nonzero_lanes, + evidence, + }) +} + fn matches_candidate_availability_table_header(bytes: &[u8], header_offset: usize) -> bool { matches!( ( @@ -2409,10 +4701,112 @@ fn read_u32_at(bytes: &[u8], offset: usize) -> Option { Some(u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]])) } +fn probable_normal_f32_string(value: u32) -> Option { + let exponent = (value >> 23) & 0xff; + if exponent == 0 || exponent == 0xff { + return None; + } + let scalar = f32::from_bits(value); + if !scalar.is_finite() { + return None; + } + Some(format!("{scalar:.6}")) +} + +fn probable_recipe_token_high16_ascii_stem(value: u32) -> Option { + if value & 0xffff != 0 { + return None; + } + let high = ((value >> 16) & 0xffff) as u16; + if high == 0 { + return None; + } + let low_byte = (high & 0x00ff) as u8; + let high_byte = (high >> 8) as u8; + if !low_byte.is_ascii_alphabetic() || !high_byte.is_ascii_alphabetic() { + return None; + } + Some(format!("{}{}", low_byte as char, high_byte as char)) +} + +fn classify_recipe_token_layout(value: u32) -> &'static str { + if value == 0 { + return "zero"; + } + if probable_recipe_token_high16_ascii_stem(value).is_some() { + return "high16-ascii-stem"; + } + if value & 0xffff == 0 { + return "high16-numeric"; + } + if value >> 16 == 0 { + return "low16-marker"; + } + "mixed" +} + +fn classify_recipe_line_signature( + mode_word: u32, + supplied_cargo_token_word: u32, + demanded_cargo_token_word: u32, +) -> &'static str { + let supplied_layout = classify_recipe_token_layout(supplied_cargo_token_word); + let demanded_layout = classify_recipe_token_layout(demanded_cargo_token_word); + if mode_word == 0 && supplied_cargo_token_word == 0 && demanded_layout == "high16-numeric" { + return "demand-numeric-entry"; + } + if mode_word == 0 && supplied_cargo_token_word == 0 && demanded_layout == "high16-ascii-stem" { + return "demand-stem-entry"; + } + if mode_word == 0 && demanded_cargo_token_word == 0 && supplied_layout == "high16-numeric" { + return "supply-numeric-entry"; + } + if mode_word != 0 && demanded_cargo_token_word == 0 && supplied_layout == "low16-marker" { + return "supply-marker-entry"; + } + if mode_word == 0 && supplied_cargo_token_word == 0 && demanded_cargo_token_word == 0 { + return "zero"; + } + "mixed" +} + +fn classify_recipe_runtime_import_branch(mode_word: u32) -> &'static str { + if mode_word == 0 { + return "zero-mode-skipped"; + } + if mode_word == 1 { + return "mode1-demand-branch"; + } + if mode_word == 3 { + return "mode3-dual-branch"; + } + "nonzero-supply-branch" +} + +fn classify_recipe_book_region_kind(bytes: &[u8]) -> &'static str { + if bytes.iter().all(|byte| *byte == 0) { + "zero" + } else if bytes.iter().all(|byte| *byte == 0xcd) { + "cdcd" + } else { + "mixed" + } +} + fn hex_encode(bytes: &[u8]) -> String { bytes.iter().map(|byte| format!("{byte:02x}")).collect() } +fn ascii_preview(bytes: &[u8]) -> String { + bytes + .iter() + .map(|byte| match byte { + 0x20..=0x7e => char::from(*byte), + _ => '.', + }) + .collect() +} + fn sha256_hex(bytes: &[u8]) -> String { let digest = Sha256::digest(bytes); format!("{digest:x}") @@ -2542,6 +4936,615 @@ mod tests { ); } + #[test] + fn parses_zeroed_post_special_conditions_scalar_window() { + let mut bytes = vec![0u8; POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET]; + let sentinel_offset = + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4; + bytes[sentinel_offset..sentinel_offset + 4].copy_from_slice(&1u32.to_le_bytes()); + + let special_conditions_probe = parse_special_conditions_probe(&bytes, Some("gmp"), None) + .expect("special-conditions probe should parse"); + let probe = parse_post_special_conditions_scalar_probe( + &bytes, + Some("gmp"), + Some(&SmpContainerProfile { + profile_family: "rt3-map-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&special_conditions_probe), + ) + .expect("post-special-conditions probe should parse"); + + assert_eq!(probe.window_offset, POST_SPECIAL_CONDITIONS_SCALAR_OFFSET); + assert_eq!( + probe.window_end_offset, + POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET + ); + assert_eq!(probe.dword_count, 79); + assert_eq!( + probe.overlap_end_offset, + POST_SPECIAL_CONDITIONS_SCALAR_OVERLAP_END_OFFSET + ); + assert_eq!(probe.overlap_dword_count, 14); + assert_eq!(probe.overlap_nonzero_dword_count, 0); + assert!(probe.overlap_nonzero_relative_offset_hexes.is_empty()); + assert_eq!( + probe.tail_offset, + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET + ); + assert_eq!(probe.tail_dword_count, 65); + assert_eq!( + probe.tail_runtime_object_offset, + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_OFFSET + ); + assert_eq!( + probe.tail_runtime_object_end_offset, + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_END_OFFSET + ); + assert!(!probe.tail_runtime_object_validated_byte_mirror); + assert_eq!( + probe.tail_grounded_live_field_offset, + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_OFFSET + ); + assert_eq!( + probe.tail_grounded_live_field_copy_len, + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_LEN + ); + assert_eq!( + probe.tail_grounded_live_field_copy_end_offset, + POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_END_OFFSET + ); + assert!(probe.tail_window_cuts_through_grounded_live_field); + assert_eq!( + probe.tail_grounded_live_field_remaining_file_window_offset, + POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET + ); + assert_eq!( + probe.tail_grounded_live_field_remaining_file_window_len, + 0x28 + ); + assert_eq!( + probe.tail_grounded_live_field_remaining_file_window_nonzero_byte_count, + 0 + ); + assert_eq!(probe.tail_next_grounded_dword_field_offset_hex, "0x4c80"); + assert_eq!( + probe.tail_next_grounded_dword_field_file_offset_hex, + "0x0f65" + ); + assert_eq!(probe.tail_second_grounded_dword_field_offset_hex, "0x4c8c"); + assert_eq!( + probe.tail_second_grounded_dword_field_file_offset_hex, + "0x0f71" + ); + assert!(!probe.post_text_field_file_alignment_matches_grounded_dword_fields); + assert!( + probe + .tail_grounded_live_field_remaining_file_window_first_nonzero_offset + .is_none() + ); + assert!( + probe + .tail_grounded_live_field_remaining_file_window_last_nonzero_offset + .is_none() + ); + assert_eq!(probe.tail_nonzero_dword_count, 0); + assert!(probe.tail_first_nonzero_offset.is_none()); + assert!(probe.tail_last_nonzero_offset.is_none()); + assert!(probe.tail_nonzero_relative_offset_hexes.is_empty()); + assert_eq!(probe.nonzero_dword_count, 0); + assert!(probe.first_nonzero_offset.is_none()); + assert!(probe.last_nonzero_offset.is_none()); + assert!(probe.nonzero_lanes.is_empty()); + } + + #[test] + fn parses_zeroed_smp_aligned_runtime_rule_band() { + let mut bytes = vec![0u8; POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET]; + let sentinel_offset = + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4; + bytes[sentinel_offset..sentinel_offset + 4].copy_from_slice(&1u32.to_le_bytes()); + + let special_conditions_probe = parse_special_conditions_probe(&bytes, Some("gmp"), None) + .expect("special-conditions probe should parse"); + let probe = parse_smp_aligned_runtime_rule_band_probe( + &bytes, + Some("gmp"), + Some(&SmpContainerProfile { + profile_family: "rt3-map-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&special_conditions_probe), + ) + .expect("aligned runtime-rule band probe should parse"); + + assert_eq!(probe.band_offset, SPECIAL_CONDITIONS_OFFSET); + assert_eq!(probe.band_end_offset, SMP_ALIGNED_RUNTIME_RULE_END_OFFSET); + assert_eq!(probe.dword_count, SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT); + assert_eq!( + probe.known_editor_rule_dword_count, + SMP_ALIGNED_RUNTIME_RULE_KNOWN_EDITOR_RULE_COUNT + ); + assert_eq!( + probe.post_window_overlap_start_index, + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX + ); + assert_eq!( + probe.post_window_overlap_dword_count, + SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT + ); + assert_eq!(probe.nonzero_lane_count, 1); + assert_eq!(probe.nonzero_band_indices, vec![35]); + assert!(probe.nonzero_post_window_overlap_band_indices.is_empty()); + assert!( + probe + .nonzero_post_window_overlap_post_relative_offset_hexes + .is_empty() + ); + assert_eq!( + probe.nonzero_lanes[0].lane_kind, + "known-special-condition-dword" + ); + assert_eq!( + probe.nonzero_lanes[0].known_label.as_deref(), + Some("Hidden sentinel") + ); + } + + #[test] + fn parses_nonzero_post_special_conditions_scalar_window() { + let mut bytes = vec![0u8; POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET]; + let sentinel_offset = + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4; + bytes[sentinel_offset..sentinel_offset + 4].copy_from_slice(&1u32.to_le_bytes()); + bytes[0x0df8..0x0dfc].copy_from_slice(&0x413d298cu32.to_le_bytes()); + bytes[0x0e00..0x0e04].copy_from_slice(&0x40e6b756u32.to_le_bytes()); + bytes[0x0f0c..0x0f10].copy_from_slice(&0x42574909u32.to_le_bytes()); + bytes[0x0f34] = 0xaa; + bytes[0x0f4e] = 0xbb; + + let special_conditions_probe = parse_special_conditions_probe(&bytes, Some("gms"), None) + .expect("special-conditions probe should parse"); + let probe = parse_post_special_conditions_scalar_probe( + &bytes, + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&special_conditions_probe), + ) + .expect("post-special-conditions probe should parse"); + + assert_eq!(probe.nonzero_dword_count, 3); + assert_eq!(probe.first_nonzero_offset, Some(0x0df8)); + assert_eq!(probe.last_nonzero_offset, Some(0x0f0c)); + assert_eq!(probe.overlap_nonzero_dword_count, 2); + assert_eq!( + probe.overlap_nonzero_relative_offset_hexes, + vec!["0x4".to_string(), "0xc".to_string()] + ); + assert_eq!(probe.tail_nonzero_dword_count, 1); + assert_eq!(probe.tail_first_nonzero_offset, Some(0x0f0c)); + assert_eq!(probe.tail_last_nonzero_offset, Some(0x0f0c)); + assert_eq!( + probe.tail_nonzero_relative_offset_hexes, + vec!["0x118".to_string()] + ); + assert_eq!(probe.tail_runtime_object_offset_hex, "0x4b47"); + assert_eq!(probe.tail_runtime_object_end_offset_hex, "0x4c4b"); + assert_eq!( + probe.tail_grounded_live_field_copy_end_offset_hex, + "0x4c73".to_string() + ); + assert_eq!( + probe.tail_grounded_live_field_name, + "victory-or-outcome status text buffer" + ); + assert!(probe.tail_window_cuts_through_grounded_live_field); + assert_eq!( + probe.tail_grounded_live_field_remaining_file_window_len_hex, + "0x28" + ); + assert_eq!( + probe.tail_grounded_live_field_remaining_file_window_nonzero_byte_count, + 2 + ); + assert_eq!( + probe.tail_grounded_live_field_remaining_file_window_first_nonzero_offset, + Some(0x0f34) + ); + assert_eq!( + probe.tail_grounded_live_field_remaining_file_window_last_nonzero_offset, + Some(0x0f4e) + ); + assert_eq!(probe.tail_next_grounded_dword_field_file_offset, 0x0f65); + assert_eq!(probe.tail_second_grounded_dword_field_file_offset, 0x0f71); + assert!(!probe.post_text_field_file_alignment_matches_grounded_dword_fields); + assert_eq!(probe.nonzero_lanes[0].relative_offset, 0x04); + assert_eq!(probe.nonzero_lanes[1].relative_offset, 0x0c); + assert_eq!(probe.nonzero_lanes[2].relative_offset, 0x118); + assert!( + probe + .nonzero_lanes + .iter() + .all(|lane| lane.probable_f32_le.is_some()) + ); + } + + #[test] + fn parses_post_text_field_neighborhood_probe() { + let mut bytes = vec![0u8; POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET]; + let sentinel_offset = + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4; + bytes[sentinel_offset..sentinel_offset + 4].copy_from_slice(&1u32.to_le_bytes()); + bytes[0x0f59] = 0x01; + bytes[0x0f5d] = 0x02; + bytes[0x0f61] = 0x03; + bytes[0x0f6d] = 0x04; + bytes[0x0f5c..0x0f60].copy_from_slice(&0x40f33333u32.to_le_bytes()); + bytes[0x0f6c..0x0f70].copy_from_slice(&0x40c08cfbu32.to_le_bytes()); + + let special_conditions_probe = parse_special_conditions_probe(&bytes, Some("gms"), None) + .expect("special-conditions probe should parse"); + let probe = parse_post_text_field_neighborhood_probe( + &bytes, + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-scenario-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&special_conditions_probe), + ) + .expect("post-text field neighborhood probe should parse"); + + assert_eq!(probe.window_offset, POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET); + assert_eq!( + probe.window_end_offset, + POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET + ); + assert_eq!(probe.grounded_field_observations.len(), 6); + assert_eq!( + probe.grounded_field_observations[0].field_name, + "Auto-Show Grade During Track Lay" + ); + assert_eq!(probe.grounded_field_observations[0].value_u8, Some(0x01)); + assert_eq!( + probe.grounded_field_observations[3].field_name, + "leftover simulation time accumulator" + ); + assert_eq!(probe.one_byte_early_float_candidates.len(), 2); + assert_eq!( + probe.one_byte_early_float_candidates[0].grounded_field_name, + "Starting Building Density Level" + ); + assert_eq!( + probe.one_byte_early_float_candidates[0].candidate_offset_hex, + "0x0f5c" + ); + assert_eq!( + probe.one_byte_early_float_candidates[1].grounded_field_name, + "selected-year lane snapshot" + ); + assert_eq!( + probe.one_byte_early_float_candidates[1].candidate_offset_hex, + "0x0f6c" + ); + } + + #[test] + fn parses_locomotive_policy_neighborhood_probe() { + let mut bytes = vec![0u8; LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET]; + let sentinel_offset = + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4; + bytes[sentinel_offset..sentinel_offset + 4].copy_from_slice(&1u32.to_le_bytes()); + bytes[0x0f78] = 0x01; + bytes[0x0f7c] = 0x02; + bytes[0x0f7d] = 0x03; + bytes[0x0f7e] = 0x04; + bytes[0x0f9c..0x0fa0].copy_from_slice(&0x42c1c036u32.to_le_bytes()); + bytes[0x0fa0..0x0fa4].copy_from_slice(&0x433a7abeu32.to_le_bytes()); + + let special_conditions_probe = parse_special_conditions_probe(&bytes, Some("gms"), None) + .expect("special-conditions probe should parse"); + let probe = parse_locomotive_policy_neighborhood_probe( + &bytes, + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-scenario-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&special_conditions_probe), + ) + .expect("locomotive policy neighborhood probe should parse"); + + assert_eq!(probe.window_offset, LOCOMOTIVE_POLICY_NEIGHBORHOOD_OFFSET); + assert_eq!( + probe.window_end_offset, + LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET + ); + assert_eq!(probe.grounded_field_observations.len(), 9); + assert_eq!( + probe.grounded_field_observations[0].field_name, + "selected-year bucket companion scalar" + ); + assert_eq!( + probe.grounded_field_observations[4].field_name, + "All Steam Locos Avail." + ); + assert_eq!(probe.grounded_field_observations[4].value_u8, Some(0x02)); + assert_eq!( + probe.grounded_field_observations[8].field_name, + "cached available-locomotive rating" + ); + assert_eq!(probe.three_byte_early_float_candidates.len(), 2); + assert_eq!( + probe.three_byte_early_float_candidates[0].grounded_field_name, + "station-list selected station id" + ); + assert_eq!( + probe.three_byte_early_float_candidates[0].candidate_offset_hex, + "0x0f9c" + ); + assert_eq!( + probe.three_byte_early_float_candidates[1].grounded_field_name, + "cached available-locomotive rating" + ); + assert_eq!( + probe.three_byte_early_float_candidates[1].candidate_offset_hex, + "0x0fa0" + ); + } + + #[test] + fn parses_pre_recipe_scalar_plateau_probe() { + let mut bytes = vec![0u8; PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET]; + let sentinel_offset = + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4; + bytes[sentinel_offset..sentinel_offset + 4].copy_from_slice(&1u32.to_le_bytes()); + bytes[0x0fa7..0x0fab].copy_from_slice(&0x82839300u32.to_le_bytes()); + bytes[0x0fab..0x0faf].copy_from_slice(&0x948c9949u32.to_le_bytes()); + bytes[0x0faf..0x0fb3].copy_from_slice(&0x8000003fu32.to_le_bytes()); + bytes[0x0fb3..0x0fb7].copy_from_slice(&0x75c28f3fu32.to_le_bytes()); + bytes[0x0fcb..0x0fcf].copy_from_slice(&0x00300000u32.to_le_bytes()); + bytes[0x0fdb..0x0fdf].copy_from_slice(&0x00ffea22u32.to_le_bytes()); + + let special_conditions_probe = parse_special_conditions_probe(&bytes, Some("gms"), None) + .expect("special-conditions probe should parse"); + let probe = parse_pre_recipe_scalar_plateau_probe( + &bytes, + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&special_conditions_probe), + ) + .expect("pre-recipe scalar plateau probe should parse"); + + assert_eq!(probe.window_offset, PRE_RECIPE_SCALAR_PLATEAU_OFFSET); + assert_eq!( + probe.window_end_offset, + PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET + ); + assert_eq!(probe.family_signature, "rt3-105-base-pre-recipe-plateau-v1"); + assert_eq!(probe.nonzero_lanes[0].absolute_offset_hex, "0x0fa7"); + assert_eq!(probe.nonzero_lanes[2].absolute_offset_hex, "0x0faf"); + assert_eq!(probe.nonzero_lanes[2].value_hex, "0x8000003f"); + } + + #[test] + fn parses_recipe_book_summary_probe() { + let mut bytes = vec![0u8; RECIPE_BOOK_SUMMARY_END_OFFSET]; + let sentinel_offset = + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4; + bytes[sentinel_offset..sentinel_offset + 4].copy_from_slice(&1u32.to_le_bytes()); + + let book0 = RECIPE_BOOK_ROOT_OFFSET; + bytes[book0..book0 + 16].copy_from_slice(&[ + 0x11, 0x22, 0x33, 0x44, 0xaa, 0xbb, 0xcc, 0xdd, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, + 0x70, 0x80, + ]); + bytes[book0 + RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET + ..book0 + RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET + 4] + .copy_from_slice(&0x41200000u32.to_le_bytes()); + bytes[book0 + RECIPE_BOOK_LINE_AREA_OFFSET + ..book0 + RECIPE_BOOK_LINE_AREA_OFFSET + RECIPE_BOOK_LINE_AREA_LEN] + .fill(0xcd); + bytes[book0 + RECIPE_BOOK_LINE_AREA_OFFSET..book0 + RECIPE_BOOK_LINE_AREA_OFFSET + 4] + .copy_from_slice(&0x00000003u32.to_le_bytes()); + bytes[book0 + RECIPE_BOOK_LINE_AREA_OFFSET + 4..book0 + RECIPE_BOOK_LINE_AREA_OFFSET + 8] + .copy_from_slice(&0x41a00000u32.to_le_bytes()); + bytes[book0 + RECIPE_BOOK_LINE_AREA_OFFSET + 8..book0 + RECIPE_BOOK_LINE_AREA_OFFSET + 12] + .copy_from_slice(&0x00000017u32.to_le_bytes()); + bytes[book0 + RECIPE_BOOK_LINE_AREA_OFFSET + 0x1c + ..book0 + RECIPE_BOOK_LINE_AREA_OFFSET + 0x20] + .copy_from_slice(&0x0000002au32.to_le_bytes()); + + let book1 = RECIPE_BOOK_ROOT_OFFSET + RECIPE_BOOK_STRIDE; + bytes[book1 + RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET + ..book1 + RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET + 4] + .copy_from_slice(&0x00000000u32.to_le_bytes()); + + let special_conditions_probe = parse_special_conditions_probe(&bytes, Some("gmp"), None) + .expect("special-conditions probe should parse"); + let probe = parse_recipe_book_summary_probe( + &bytes, + Some("gmp"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-map-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&special_conditions_probe), + ) + .expect("recipe-book summary probe should parse"); + + assert_eq!(probe.root_offset, RECIPE_BOOK_ROOT_OFFSET); + assert_eq!(probe.book_count, RECIPE_BOOK_COUNT); + assert_eq!(probe.book_stride, RECIPE_BOOK_STRIDE); + assert_eq!( + probe.max_annual_production_relative_offset, + RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET + ); + assert_eq!(probe.books[0].head_kind, "mixed"); + assert_eq!(probe.books[0].line_area_kind, "mixed"); + assert_eq!(probe.books[0].max_annual_production_word_hex, "0x41200000"); + assert_eq!( + probe.books[0] + .max_annual_production_probable_f32_le + .as_deref(), + Some("10.000000") + ); + assert_eq!(probe.books[0].lines.len(), RECIPE_BOOK_LINE_COUNT); + assert_eq!(probe.books[0].lines[0].line_kind, "mixed"); + assert_eq!(probe.books[0].lines[0].mode_word_hex, "0x00000003"); + assert_eq!(probe.books[0].lines[0].annual_amount_word_hex, "0x41a00000"); + assert_eq!( + probe.books[0].lines[0] + .annual_amount_probable_f32_le + .as_deref(), + Some("20.000000") + ); + assert_eq!( + probe.books[0].lines[0].supplied_cargo_token_word_hex, + "0x00000017" + ); + assert_eq!( + probe.books[0].lines[0].supplied_cargo_token_window_hex, + "17000000cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd2a000000" + ); + assert_eq!( + probe.books[0].lines[0].supplied_cargo_token_window_ascii, + "....................*..." + ); + assert!(probe.books[0].lines[0].supplied_cargo_token_active_in_runtime_import); + assert_eq!( + probe.books[0].lines[0].demanded_cargo_token_word_hex, + "0x0000002a" + ); + assert_eq!( + probe.books[0].lines[0].demanded_cargo_token_window_hex, + "2a000000cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + ); + assert_eq!( + probe.books[0].lines[0].demanded_cargo_token_window_ascii, + "*..................." + ); + assert!(probe.books[0].lines[0].demanded_cargo_token_active_in_runtime_import); + assert_eq!(probe.books[1].head_kind, "zero"); + assert_eq!(probe.books[1].line_area_kind, "zero"); + assert_eq!(probe.books[1].lines[0].line_kind, "zero"); + } + + #[test] + fn decodes_probable_recipe_token_high16_ascii_stem() { + assert_eq!( + probable_recipe_token_high16_ascii_stem(0x72470000).as_deref(), + Some("Gr") + ); + assert_eq!( + probable_recipe_token_high16_ascii_stem(0x68430000).as_deref(), + Some("Ch") + ); + assert_eq!(probable_recipe_token_high16_ascii_stem(0x000040a0), None); + assert_eq!(probable_recipe_token_high16_ascii_stem(0x00170000), None); + } + + #[test] + fn classifies_recipe_token_layouts() { + assert_eq!(classify_recipe_token_layout(0x00000000), "zero"); + assert_eq!(classify_recipe_token_layout(0x72470000), "high16-ascii-stem"); + assert_eq!(classify_recipe_token_layout(0x00170000), "high16-numeric"); + assert_eq!(classify_recipe_token_layout(0x000040a0), "low16-marker"); + } + + #[test] + fn classifies_recipe_line_signatures() { + assert_eq!( + classify_recipe_line_signature(0x00000000, 0x00000000, 0x00010000), + "demand-numeric-entry" + ); + assert_eq!( + classify_recipe_line_signature(0x00000000, 0x00000000, 0x72470000), + "demand-stem-entry" + ); + assert_eq!( + classify_recipe_line_signature(0x00000000, 0x00170000, 0x00000000), + "supply-numeric-entry" + ); + assert_eq!( + classify_recipe_line_signature(0x00110000, 0x000040a0, 0x00000000), + "supply-marker-entry" + ); + } + + #[test] + fn classifies_recipe_runtime_import_branches() { + assert_eq!(classify_recipe_runtime_import_branch(0), "zero-mode-skipped"); + assert_eq!(classify_recipe_runtime_import_branch(1), "mode1-demand-branch"); + assert_eq!(classify_recipe_runtime_import_branch(3), "mode3-dual-branch"); + assert_eq!( + classify_recipe_runtime_import_branch(0x00110000), + "nonzero-supply-branch" + ); + } + + #[test] + fn parses_nonzero_smp_aligned_runtime_rule_band() { + let mut bytes = vec![0u8; POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET]; + let sentinel_offset = + SPECIAL_CONDITIONS_OFFSET + SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT * 4; + bytes[sentinel_offset..sentinel_offset + 4].copy_from_slice(&1u32.to_le_bytes()); + bytes[0x0df8..0x0dfc].copy_from_slice(&0x413d298cu32.to_le_bytes()); + bytes[0x0e00..0x0e04].copy_from_slice(&0x40e6b756u32.to_le_bytes()); + bytes[0x0e18..0x0e1c].copy_from_slice(&0x41d4ccceu32.to_le_bytes()); + bytes[0x0e24..0x0e28].copy_from_slice(&0x3fd2b549u32.to_le_bytes()); + + let special_conditions_probe = parse_special_conditions_probe(&bytes, Some("gms"), None) + .expect("special-conditions probe should parse"); + let probe = parse_smp_aligned_runtime_rule_band_probe( + &bytes, + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-scenario-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + Some(&special_conditions_probe), + ) + .expect("aligned runtime-rule band probe should parse"); + + assert_eq!(probe.nonzero_band_indices, vec![35, 37, 39, 45, 48]); + assert_eq!( + probe.nonzero_post_window_overlap_band_indices, + vec![37, 39, 45, 48] + ); + assert_eq!( + probe.nonzero_post_window_overlap_post_relative_offset_hexes, + vec![ + "0x4".to_string(), + "0xc".to_string(), + "0x24".to_string(), + "0x30".to_string() + ] + ); + assert_eq!(probe.nonzero_lanes[1].relative_offset, 0x94); + assert_eq!( + probe.nonzero_lanes[1].lane_kind, + "unlabeled-editor-rule-dword" + ); + assert!(probe.nonzero_lanes[1].probable_f32_le.is_some()); + assert_eq!(probe.nonzero_lanes.last().unwrap().band_index, 48); + } + #[test] fn parses_save_anchor_cycle_and_trailer() { let cycle_words: [u32; 9] = [ @@ -2795,6 +5798,372 @@ mod tests { assert_eq!(probe.packed_profile_block.profile_byte_0xc5, 0x00); } + #[test] + fn builds_classic_save_load_summary() { + let summary = build_save_load_summary( + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-classic-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + None, + None, + Some(&SmpClassicRehydrateProfileProbe { + profile_family: "rt3-classic-save-container-v1".to_string(), + progress_32dc_offset: 0x76e8, + progress_3714_offset: 0x76ec, + progress_3715_offset: 0x77f8, + packed_profile_offset: 0x76f0, + packed_profile_len: 0x108, + packed_profile_len_hex: "0x108".to_string(), + packed_profile_block: SmpClassicPackedProfileBlock { + relative_len: 0x108, + relative_len_hex: "0x108".to_string(), + leading_word_0: 3, + leading_word_0_hex: "0x00000003".to_string(), + trailing_zero_word_count_after_leading_word: 3, + map_path_offset: 0x13, + map_path: Some("British Isles.gmp".to_string()), + display_name_offset: 0x46, + display_name: Some("British Isles".to_string()), + profile_byte_0x77: 0, + profile_byte_0x77_hex: "0x00".to_string(), + profile_byte_0x82: 0, + profile_byte_0x82_hex: "0x00".to_string(), + profile_byte_0x97: 0, + profile_byte_0x97_hex: "0x00".to_string(), + profile_byte_0xc5: 0, + profile_byte_0xc5_hex: "0x00".to_string(), + stable_nonzero_words: vec![], + }, + ascii_runs: vec![], + }), + None, + None, + ) + .expect("classic summary"); + + assert_eq!(summary.mechanism_family, "classic-save-rehydrate-v1"); + assert_eq!(summary.mechanism_confidence, "grounded"); + assert_eq!(summary.map_path.as_deref(), Some("British Isles.gmp")); + assert_eq!(summary.packed_profile_len, Some(0x108)); + } + + #[test] + fn builds_rt3_105_save_load_summary_with_candidate_table() { + let summary = build_save_load_summary( + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + None, + Some(&SmpRt3105PostSpanBridgeProbe { + profile_family: "rt3-105-save-container-v1".to_string(), + bridge_family: "rt3-105-save-post-span-bridge-v1".to_string(), + bridge_evidence: vec![], + span_target_offset: 0x3678, + next_candidate_offset: Some(0x4f14), + next_candidate_delta_from_span_target: Some(0x189c), + packed_profile_offset: 0x73c0, + packed_profile_delta_from_span_target: 0x3d48, + next_candidate_delta_from_packed_profile: Some(-0x24ac), + selector_high_u16: 0x7110, + selector_high_hex: "0x7110".to_string(), + descriptor_high_u16: 0x7801, + descriptor_high_hex: "0x7801".to_string(), + next_candidate_high_u16_words: vec![0x6200, 0x0000, 0xfff7, 0x5515], + next_candidate_high_hex_words: vec![], + }), + None, + Some(&SmpRt3105PackedProfileProbe { + profile_family: "rt3-105-save-container-v1".to_string(), + packed_profile_offset: 0x73c0, + packed_profile_len: 0x108, + packed_profile_len_hex: "0x108".to_string(), + packed_profile_block: SmpRt3105PackedProfileBlock { + relative_len: 0x108, + relative_len_hex: "0x108".to_string(), + leading_word_0: 3, + leading_word_0_hex: "0x00000003".to_string(), + trailing_zero_word_count_after_leading_word: 2, + header_flag_word_3: 1, + header_flag_word_3_hex: "0x00000001".to_string(), + map_path_offset: 0x10, + map_path: Some("Alternate USA.gmp".to_string()), + display_name_offset: 0x43, + display_name: Some("Alternate USA".to_string()), + profile_byte_0x77: 0x07, + profile_byte_0x77_hex: "0x07".to_string(), + profile_byte_0x82: 0x4d, + profile_byte_0x82_hex: "0x4d".to_string(), + profile_byte_0x97: 0, + profile_byte_0x97_hex: "0x00".to_string(), + profile_byte_0xc5: 0, + profile_byte_0xc5_hex: "0x00".to_string(), + stable_nonzero_words: vec![], + }, + ascii_runs: vec![], + }), + Some(&SmpRt3105SaveNameTableProbe { + profile_family: "rt3-105-save-container-v1".to_string(), + source_kind: "save-bridge-secondary-block".to_string(), + semantic_family: "scenario-named-candidate-availability-table".to_string(), + semantic_alignment: vec![], + header_offset: 0x6a70, + header_word_0: 0, + header_word_0_hex: "0x00000000".to_string(), + header_word_1: 0, + header_word_1_hex: "0x00000000".to_string(), + header_word_2: 0x332e, + header_word_2_hex: "0x0000332e".to_string(), + entry_stride: 0x22, + entry_stride_hex: "0x22".to_string(), + header_prefix_word_count: 11, + observed_entry_capacity: 0x44, + observed_entry_count: 67, + zero_trailer_entry_count: 3, + nonzero_trailer_entry_count: 64, + distinct_trailer_words: vec![0, 1], + distinct_trailer_hex_words: vec![ + "0x00000000".to_string(), + "0x00000001".to_string(), + ], + zero_trailer_entry_names: vec![ + "Nuclear Power Plant".to_string(), + "Recycling Plant".to_string(), + "Uranium Mine".to_string(), + ], + entries_offset: 0x6ad1, + entries_end_offset: 0x73b7, + trailing_footer_hex: "dc3200001437000000".to_string(), + footer_progress_word_0: 0x32dc, + footer_progress_word_0_hex: "0x000032dc".to_string(), + footer_progress_word_1: 0x3714, + footer_progress_word_1_hex: "0x00003714".to_string(), + footer_trailing_byte: 0, + footer_trailing_byte_hex: "0x00".to_string(), + footer_grounded_alignments: vec![], + entries: vec![], + evidence: vec![], + }), + ) + .expect("1.05 summary"); + + assert_eq!(summary.mechanism_family, "rt3-105-save-post-span-bridge-v1"); + assert_eq!(summary.mechanism_confidence, "mixed"); + assert_eq!(summary.map_path.as_deref(), Some("Alternate USA.gmp")); + assert_eq!( + summary + .candidate_table + .as_ref() + .expect("candidate table") + .zero_availability_count, + 3 + ); + } + + #[test] + fn loads_classic_save_slice_from_report() { + let mut report = inspect_smp_bytes(&[]); + let classic_probe = SmpClassicRehydrateProfileProbe { + profile_family: "rt3-classic-save-container-v1".to_string(), + progress_32dc_offset: 0x76e8, + progress_3714_offset: 0x76ec, + progress_3715_offset: 0x77f8, + packed_profile_offset: 0x76f0, + packed_profile_len: 0x108, + packed_profile_len_hex: "0x108".to_string(), + packed_profile_block: SmpClassicPackedProfileBlock { + relative_len: 0x108, + relative_len_hex: "0x108".to_string(), + leading_word_0: 3, + leading_word_0_hex: "0x00000003".to_string(), + trailing_zero_word_count_after_leading_word: 3, + map_path_offset: 0x13, + map_path: Some("British Isles.gmp".to_string()), + display_name_offset: 0x46, + display_name: Some("British Isles".to_string()), + profile_byte_0x77: 0, + profile_byte_0x77_hex: "0x00".to_string(), + profile_byte_0x82: 0, + profile_byte_0x82_hex: "0x00".to_string(), + profile_byte_0x97: 0, + profile_byte_0x97_hex: "0x00".to_string(), + profile_byte_0xc5: 0, + profile_byte_0xc5_hex: "0x00".to_string(), + stable_nonzero_words: vec![], + }, + ascii_runs: vec![], + }; + report.classic_rehydrate_profile_probe = Some(classic_probe.clone()); + report.save_load_summary = build_save_load_summary( + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-classic-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + None, + None, + Some(&classic_probe), + None, + None, + ); + + let slice = load_save_slice_from_report(&report).expect("classic save slice"); + assert_eq!(slice.mechanism_family, "classic-save-rehydrate-v1"); + assert_eq!( + slice + .profile + .as_ref() + .and_then(|profile| profile.map_path.as_deref()), + Some("British Isles.gmp") + ); + assert!(slice.candidate_availability_table.is_none()); + } + + #[test] + fn loads_rt3_105_save_slice_from_report() { + let mut report = inspect_smp_bytes(&[]); + let packed_profile = SmpRt3105PackedProfileProbe { + profile_family: "rt3-105-save-container-v1".to_string(), + packed_profile_offset: 0x73c0, + packed_profile_len: 0x108, + packed_profile_len_hex: "0x108".to_string(), + packed_profile_block: SmpRt3105PackedProfileBlock { + relative_len: 0x108, + relative_len_hex: "0x108".to_string(), + leading_word_0: 3, + leading_word_0_hex: "0x00000003".to_string(), + trailing_zero_word_count_after_leading_word: 2, + header_flag_word_3: 1, + header_flag_word_3_hex: "0x00000001".to_string(), + map_path_offset: 0x10, + map_path: Some("Alternate USA.gmp".to_string()), + display_name_offset: 0x43, + display_name: Some("Alternate USA".to_string()), + profile_byte_0x77: 0x07, + profile_byte_0x77_hex: "0x07".to_string(), + profile_byte_0x82: 0x4d, + profile_byte_0x82_hex: "0x4d".to_string(), + profile_byte_0x97: 0, + profile_byte_0x97_hex: "0x00".to_string(), + profile_byte_0xc5: 0, + profile_byte_0xc5_hex: "0x00".to_string(), + stable_nonzero_words: vec![], + }, + ascii_runs: vec![], + }; + let name_table = SmpRt3105SaveNameTableProbe { + profile_family: "rt3-105-save-container-v1".to_string(), + source_kind: "save-bridge-secondary-block".to_string(), + semantic_family: "scenario-named-candidate-availability-table".to_string(), + semantic_alignment: vec![], + header_offset: 0x6a70, + header_word_0: 0, + header_word_0_hex: "0x00000000".to_string(), + header_word_1: 0, + header_word_1_hex: "0x00000000".to_string(), + header_word_2: 0x332e, + header_word_2_hex: "0x0000332e".to_string(), + entry_stride: 0x22, + entry_stride_hex: "0x22".to_string(), + header_prefix_word_count: 11, + observed_entry_capacity: 0x44, + observed_entry_count: 2, + zero_trailer_entry_count: 1, + nonzero_trailer_entry_count: 1, + distinct_trailer_words: vec![0, 1], + distinct_trailer_hex_words: vec!["0x00000000".to_string(), "0x00000001".to_string()], + zero_trailer_entry_names: vec!["Uranium Mine".to_string()], + entries_offset: 0x6ad1, + entries_end_offset: 0x6b15, + trailing_footer_hex: "dc3200001437000000".to_string(), + footer_progress_word_0: 0x32dc, + footer_progress_word_0_hex: "0x000032dc".to_string(), + footer_progress_word_1: 0x3714, + footer_progress_word_1_hex: "0x00003714".to_string(), + footer_trailing_byte: 0, + footer_trailing_byte_hex: "0x00".to_string(), + footer_grounded_alignments: vec![], + entries: vec![ + SmpRt3105SaveNameTableEntry { + index: 0, + offset: 0x6ad1, + text: "AutoPlant".to_string(), + availability_dword: 1, + availability_dword_hex: "0x00000001".to_string(), + trailer_word: 1, + trailer_word_hex: "0x00000001".to_string(), + }, + SmpRt3105SaveNameTableEntry { + index: 1, + offset: 0x6af3, + text: "Uranium Mine".to_string(), + availability_dword: 0, + availability_dword_hex: "0x00000000".to_string(), + trailer_word: 0, + trailer_word_hex: "0x00000000".to_string(), + }, + ], + evidence: vec![], + }; + let bridge = SmpRt3105PostSpanBridgeProbe { + profile_family: "rt3-105-save-container-v1".to_string(), + bridge_family: "rt3-105-save-post-span-bridge-v1".to_string(), + bridge_evidence: vec![], + span_target_offset: 0x3678, + next_candidate_offset: Some(0x4f14), + next_candidate_delta_from_span_target: Some(0x189c), + packed_profile_offset: 0x73c0, + packed_profile_delta_from_span_target: 0x3d48, + next_candidate_delta_from_packed_profile: Some(-0x24ac), + selector_high_u16: 0x7110, + selector_high_hex: "0x7110".to_string(), + descriptor_high_u16: 0x7801, + descriptor_high_hex: "0x7801".to_string(), + next_candidate_high_u16_words: vec![0x6200, 0x0000, 0xfff7, 0x5515], + next_candidate_high_hex_words: vec![], + }; + report.rt3_105_packed_profile_probe = Some(packed_profile.clone()); + report.rt3_105_save_name_table_probe = Some(name_table.clone()); + report.save_load_summary = build_save_load_summary( + Some("gms"), + Some(&SmpContainerProfile { + profile_family: "rt3-105-save-container-v1".to_string(), + profile_evidence: vec![], + is_known_profile: true, + }), + None, + Some(&bridge), + None, + Some(&packed_profile), + Some(&name_table), + ); + + let slice = load_save_slice_from_report(&report).expect("1.05 save slice"); + assert_eq!(slice.mechanism_family, "rt3-105-save-post-span-bridge-v1"); + assert_eq!( + slice + .profile + .as_ref() + .and_then(|profile| profile.map_path.as_deref()), + Some("Alternate USA.gmp") + ); + assert_eq!( + slice + .candidate_availability_table + .as_ref() + .expect("candidate table") + .entries[1] + .text, + "Uranium Mine" + ); + } + #[test] fn classifies_rt3_105_post_span_bridge_variants() { let base_trailer = SmpRuntimeTrailerBlock { diff --git a/crates/rrt-runtime/src/step.rs b/crates/rrt-runtime/src/step.rs index 0055c77..ab9548c 100644 --- a/crates/rrt-runtime/src/step.rs +++ b/crates/rrt-runtime/src/step.rs @@ -188,7 +188,10 @@ mod tests { use std::collections::BTreeMap; use super::*; - use crate::{CalendarPoint, RuntimeCompany, RuntimeEventRecord, RuntimeServiceState}; + use crate::{ + CalendarPoint, RuntimeCompany, RuntimeEventRecord, RuntimeSaveProfileState, + RuntimeServiceState, RuntimeWorldRestoreState, + }; fn state() -> RuntimeState { RuntimeState { @@ -199,12 +202,17 @@ mod tests { tick_slot: 0, }, world_flags: BTreeMap::new(), + save_profile: RuntimeSaveProfileState::default(), + world_restore: RuntimeWorldRestoreState::default(), + metadata: BTreeMap::new(), companies: vec![RuntimeCompany { company_id: 1, current_cash: 10, debt: 0, }], event_runtime_records: Vec::new(), + candidate_availability: BTreeMap::new(), + special_conditions: BTreeMap::new(), service_state: RuntimeServiceState::default(), } } diff --git a/crates/rrt-runtime/src/summary.rs b/crates/rrt-runtime/src/summary.rs index ea3ef29..fdcdbf3 100644 --- a/crates/rrt-runtime/src/summary.rs +++ b/crates/rrt-runtime/src/summary.rs @@ -5,9 +5,42 @@ use crate::{CalendarPoint, RuntimeState}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct RuntimeSummary { pub calendar: CalendarPoint, + pub calendar_projection_source: Option, + pub calendar_projection_is_placeholder: bool, pub world_flag_count: usize, + pub world_restore_selected_year_profile_lane: Option, + pub world_restore_campaign_scenario_enabled: Option, + pub world_restore_sandbox_enabled: Option, + pub world_restore_seed_tuple_written_from_raw_lane: Option, + pub world_restore_absolute_counter_requires_shell_context: Option, + pub world_restore_absolute_counter_reconstructible_from_save: Option, + pub world_restore_disable_cargo_economy_special_condition_slot: Option, + pub world_restore_disable_cargo_economy_special_condition_reconstructible_from_save: + Option, + pub world_restore_disable_cargo_economy_special_condition_write_side_grounded: Option, + pub world_restore_disable_cargo_economy_special_condition_enabled: Option, + pub world_restore_use_bio_accelerator_cars_enabled: Option, + pub world_restore_use_wartime_cargos_enabled: Option, + pub world_restore_disable_train_crashes_enabled: Option, + pub world_restore_disable_train_crashes_and_breakdowns_enabled: Option, + pub world_restore_ai_ignore_territories_at_startup_enabled: Option, + pub world_restore_absolute_counter_restore_kind: Option, + pub world_restore_absolute_counter_adjustment_context: Option, + pub metadata_count: usize, pub company_count: usize, pub event_runtime_record_count: usize, + pub candidate_availability_count: usize, + pub zero_candidate_availability_count: usize, + pub special_condition_count: usize, + pub enabled_special_condition_count: usize, + pub save_profile_kind: Option, + pub save_profile_family: Option, + pub save_profile_map_path: Option, + pub save_profile_display_name: Option, + pub save_profile_selected_year_profile_lane: Option, + pub save_profile_sandbox_enabled: Option, + pub save_profile_campaign_scenario_enabled: Option, + pub save_profile_staged_profile_copy_on_restore: Option, pub total_event_record_service_count: u64, pub periodic_boundary_call_count: u64, pub total_trigger_dispatch_count: u64, @@ -19,9 +52,86 @@ impl RuntimeSummary { pub fn from_state(state: &RuntimeState) -> Self { Self { calendar: state.calendar, + calendar_projection_source: state.metadata.get("save_slice.calendar_source").cloned(), + calendar_projection_is_placeholder: state + .metadata + .get("save_slice.calendar_source") + .is_some_and(|value| value == "default-1830-placeholder"), world_flag_count: state.world_flags.len(), + world_restore_selected_year_profile_lane: state + .world_restore + .selected_year_profile_lane, + world_restore_campaign_scenario_enabled: state.world_restore.campaign_scenario_enabled, + world_restore_sandbox_enabled: state.world_restore.sandbox_enabled, + world_restore_seed_tuple_written_from_raw_lane: state + .world_restore + .seed_tuple_written_from_raw_lane, + world_restore_absolute_counter_requires_shell_context: state + .world_restore + .absolute_counter_requires_shell_context, + world_restore_absolute_counter_reconstructible_from_save: state + .world_restore + .absolute_counter_reconstructible_from_save, + world_restore_disable_cargo_economy_special_condition_slot: state + .world_restore + .disable_cargo_economy_special_condition_slot, + world_restore_disable_cargo_economy_special_condition_reconstructible_from_save: state + .world_restore + .disable_cargo_economy_special_condition_reconstructible_from_save, + world_restore_disable_cargo_economy_special_condition_write_side_grounded: state + .world_restore + .disable_cargo_economy_special_condition_write_side_grounded, + world_restore_disable_cargo_economy_special_condition_enabled: state + .world_restore + .disable_cargo_economy_special_condition_enabled, + world_restore_use_bio_accelerator_cars_enabled: state + .world_restore + .use_bio_accelerator_cars_enabled, + world_restore_use_wartime_cargos_enabled: state + .world_restore + .use_wartime_cargos_enabled, + world_restore_disable_train_crashes_enabled: state + .world_restore + .disable_train_crashes_enabled, + world_restore_disable_train_crashes_and_breakdowns_enabled: state + .world_restore + .disable_train_crashes_and_breakdowns_enabled, + world_restore_ai_ignore_territories_at_startup_enabled: state + .world_restore + .ai_ignore_territories_at_startup_enabled, + world_restore_absolute_counter_restore_kind: state + .world_restore + .absolute_counter_restore_kind + .clone(), + world_restore_absolute_counter_adjustment_context: state + .world_restore + .absolute_counter_adjustment_context + .clone(), + metadata_count: state.metadata.len(), company_count: state.companies.len(), event_runtime_record_count: state.event_runtime_records.len(), + candidate_availability_count: state.candidate_availability.len(), + zero_candidate_availability_count: state + .candidate_availability + .values() + .filter(|value| **value == 0) + .count(), + special_condition_count: state.special_conditions.len(), + enabled_special_condition_count: state + .special_conditions + .values() + .filter(|value| **value != 0) + .count(), + save_profile_kind: state.save_profile.profile_kind.clone(), + save_profile_family: state.save_profile.profile_family.clone(), + save_profile_map_path: state.save_profile.map_path.clone(), + save_profile_display_name: state.save_profile.display_name.clone(), + save_profile_selected_year_profile_lane: state.save_profile.selected_year_profile_lane, + save_profile_sandbox_enabled: state.save_profile.sandbox_enabled, + save_profile_campaign_scenario_enabled: state.save_profile.campaign_scenario_enabled, + save_profile_staged_profile_copy_on_restore: state + .save_profile + .staged_profile_copy_on_restore, total_event_record_service_count: state.service_state.total_event_record_services, periodic_boundary_call_count: state.service_state.periodic_boundary_calls, total_trigger_dispatch_count: state diff --git a/crates/rrt-runtime/src/win.rs b/crates/rrt-runtime/src/win.rs index b7bf405..54ac3c0 100644 --- a/crates/rrt-runtime/src/win.rs +++ b/crates/rrt-runtime/src/win.rs @@ -382,20 +382,24 @@ fn collect_anonymous_selector_records( let mut records = Vec::new(); let mut start = 0usize; - while let Some(relative) = bytes - .get(start..) - .and_then(|slice| slice.windows(PRELUDE.len()).position(|window| window == PRELUDE)) - { + while let Some(relative) = bytes.get(start..).and_then(|slice| { + slice + .windows(PRELUDE.len()) + .position(|window| window == PRELUDE) + }) { let record_offset = start + relative; let name_len = read_u32_le(bytes, record_offset + PRELUDE.len()).unwrap_or(0); if name_len == 0 { let selector_word_0 = read_u32_le(bytes, record_offset + 0x10).unwrap_or(0); let selector_word_0_low_u16 = (selector_word_0 & 0xffff) as u16; if (0xc352..=0xc39b).contains(&selector_word_0_low_u16) { - let preceding_named_record = - references.iter().rev().find(|reference| reference.offset < record_offset); - let following_named_record = - references.iter().find(|reference| reference.offset > record_offset); + let preceding_named_record = references + .iter() + .rev() + .find(|reference| reference.offset < record_offset); + let following_named_record = references + .iter() + .find(|reference| reference.offset > record_offset); let selector_word_1 = read_u32_le(bytes, record_offset + 0x14).unwrap_or(0); let selector_word_0_high_u16 = ((selector_word_0 >> 16) & 0xffff) as u16; let selector_word_1_middle_u16 = ((selector_word_1 >> 8) & 0xffff) as u16; diff --git a/rt3_auto_load_winedbg.log b/rt3_auto_load_winedbg.log new file mode 100644 index 0000000..7ed8bd6 --- /dev/null +++ b/rt3_auto_load_winedbg.log @@ -0,0 +1,87 @@ +Script started on 2026-04-08 18:28:14-07:00 [COMMAND="/opt/wine-stable/bin/winedbg --file /home/jan/projects/rrt/tools/winedbg_auto_load_compare.cmd RT3.exe" TERM="xterm-256color" TTY="/dev/pts/4" COLUMNS="116" LINES="70"] +]0;Wine Debugger[?25lWineDbg starting on pid 00f0 +[?25h00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module +00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module +[?25lprocess_breakpoint () at /usr/src/packages/BUILD/dlls/ntdll/signal_i386.c:557 +[?25h[?25l0x0000007bd237b6 process_breakpoint+0x36 [/usr/src/packages/BUILD/dlls/ntdll/signal_i386.c:557] in ntdll: movl -0x58 +(%ebp), %eax +[?25h[?25lUnable to access file '/usr/src/packages/BUILD/dlls/ntdll/signal_i386.c' +[?25h[?25lBreakpoint 1 at 0x00000000438890 rt3+0x38890 +[?25h[?25lBreakpoint 2 at 0x000000004390cb rt3+0x390cb +[?25h[?25lBreakpoint 3 at 0x00000000445ac0 rt3+0x45ac0 +[?25h00f4:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +00f4:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 19.1.7, 256 bits)"). +00f4:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 19.1.7, 256 bits)"). +[?25lThread ID=0160 not in our list of threads -> can't rename +[?25h[?25lThread ID=0184 not in our list of threads -> can't rename +[?25h0140:fixme:d3d:state_linepattern_w Setting line patterns is not supported in OpenGL core contexts. +X Error of failed request: XF86VidModeClientNotLocal + Major opcode of failed request: 150 (XFree86-VidModeExtension) + Minor opcode of failed request: 15 (XF86VidModeSetGamma) + Serial number of failed request: 3081 + Current serial number in output stream: 3098 +[?25lInvalid address (0x00000000438890 rt3+0x38890) for breakpoint 1, disabling it +[?25h[?25lInvalid address (0x000000004390cb rt3+0x390cb) for breakpoint 2, disabling it +[?25h[?25lInvalid address (0x00000000445ac0 rt3+0x45ac0) for breakpoint 3, disabling it +[?25h[?25lProcess of pid=00f0 has terminated +[?25h +[?25lException c0000005 +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+4)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+8)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+12)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec74' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec7c' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec78' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9b8' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9bc' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c0' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c4' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1270' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1274' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1278' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d127c' +[?25h[?25lYou must be attached to a process to run this command. +[?25h[?25lNo process loaded, cannot execute 'cont' +[?25h[?25lNo process loaded, cannot execute 'cont' +[?25h +[?25lException c0000005 +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+4)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+8)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+12)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec74' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec7c' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec78' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9b8' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9bc' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c0' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c4' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1270' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1274' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1278' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d127c' +[?25h[?25lYou must be attached to a process to run this command. +[?25h[?25lNo process loaded, cannot execute 'cont' +[?25h +[?25lException c0000005 +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+4)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+8)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+12)' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec74' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec7c' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec78' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9b8' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9bc' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c0' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c4' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1270' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1274' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1278' +[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d127c' +[?25h[?25lYou must be attached to a process to run this command. +[?25h +Script done on 2026-04-08 18:33:15-07:00 [COMMAND_EXIT_CODE="0"] diff --git a/rt3_manual_load_winedbg.log b/rt3_manual_load_winedbg.log new file mode 100644 index 0000000..1cd8251 --- /dev/null +++ b/rt3_manual_load_winedbg.log @@ -0,0 +1,44 @@ +Script started on 2026-04-07 18:35:01-07:00 [COMMAND="/opt/wine-stable/bin/winedbg --file /home/jan/projects/rrt/tools/winedbg_manual_load_445ac0.cmd RT3.exe" TERM="xterm-256color" TTY="/dev/pts/4" COLUMNS="116" LINES="30"] +]0;Wine Debugger[?25lWineDbg starting on pid 00f0 +[?25h00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module +00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module +[?25lprocess_breakpoint () at /usr/src/packages/BUILD/dlls/ntdll/signal_i386.c:557 +[?25h[?25l0x0000007bd237b6 process_breakpoint+0x36 [/usr/src/packages/BUILD/dlls/ntdll/signal_i386.c:557] in ntdll: movl -0x58 +(%ebp), %eax +[?25h[?25lUnable to access file '/usr/src/packages/BUILD/dlls/ntdll/signal_i386.c' +[?25h[?25lBreakpoint 1 at 0x000000004390cb rt3+0x390cb +[?25h[?25lBreakpoint 2 at 0x00000000445ac0 rt3+0x45ac0 +[?25h00f4:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION +libEGL warning: DRI3 error: Could not get DRI3 device +libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering +00f4:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 19.1.7, 256 bits)"). +00f4:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 19.1.7, 256 bits)"). +[?25lThread ID=0164 not in our list of threads -> can't rename +[?25h[?25lThread ID=0188 not in our list of threads -> can't rename +[?25h0144:fixme:d3d:state_linepattern_w Setting line patterns is not supported in OpenGL core contexts. +00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module +[?25lStopped on breakpoint 1 at 0x000000004390cb rt3+0x390cb +[?25h[?25lRegister dump: +[?25h[?25l CS:0023 SS:002b DS:002b ES:002b FS:0000 GS:002b + EIP:004390cb ESP:0022fb30 EBP:02af5840 EFLAGS:00000206( - -- I - -P- ) +[?25h[?25l EAX:00000002 EBX:00000000 ECX:02af5840 EDX:01db4739 +[?25h[?25l ESI:00000000 EDI:00000001 +[?25h[?25l0x1db4739 +[?25h[?25l0x4 +[?25h[?25l0x22fb50 +[?25h[?25l0x26d7b88 +[?25h[?25l0x1d81230 +[?25h[?25l0x2af5840 +[?25h[?25l0 +[?25h[?25l0 +[?25h[?25l0 +[?25h[?25l0 +[?25h[?25l0 +[?25h[?25l0 +[?25h[?25l0 +[?25h[?25l0 +[?25h[?25lBacktrace: +[?25h[?25l=>0 0x000000004390cb in rt3 (+0x390cb) (0x00000002af5840) +[?25h[?25l 1 0x00000001072558 (0000000000000000) +[?25h +Script done on 2026-04-07 18:35:28-07:00 [COMMAND_EXIT_CODE="0"]