Extend atlas seam annotations across subsystems

This commit is contained in:
Jan Petykiewicz 2026-04-13 14:12:18 -07:00
commit 97295d4060
8 changed files with 2837 additions and 234 deletions

View file

@ -9,9 +9,67 @@
- State Anchors: CRT heap and file-handle tables; process environment and argv storage.
- Subsystem Handoffs: exits the generic CRT path at `app_bootstrap_main`, which becomes the first
RT3-owned coordinator.
- Local CRT side seams are tighter now too: `0x005a2c30/0x005a2cb0/0x005a2cd8/0x005a2d10` own the
global on-exit callback table at `0x00dbb8dc/0x00dbb8d8`, `0x005a2d22` is the optional
`mscoree.dll!CorExitProcess` bridge before the normal process-exit tail,
`0x005a2dc9/0x005a2e9c/0x005a2ead/0x005a2ebe/0x005a2ecd` are the shared exit-cleanup owner plus
its four terminate-vs-return and cleanup-vs-skip variants, and `0x005a2d64` is now bounded as
the higher init owner that walks fixed callback tables `0x005ed018..0x005ed034` and
`0x005ed000..0x005ed014` before registering callback `0x005acaa1` into that dynamic on-exit
table. The same startup-owned table path is now tighter internally too: `0x005acaa1` is the
fixed callback-table walker over `0x005eab28..`, `0x005ac9e7` is the capacity query helper that
prefers the local CRT heap fast path over `KERNEL32!HeapSize`, and `0x005a6649` is the
region-descriptor probe under that fast path. The surrounding early-init side is tighter now
too: `__heap_init` `0x005a644d` is the real `HeapCreate + heap-mode + small-block-heap` owner,
and `startup_run_init_callback_table` `0x005aca5d` is the fixed startup callback walker over the
currently empty `0x005eab20..` band.
- the adjacent CRT runtime-report seam is explicit now too: `0x005acdb0` is the shared
runtime-error or math-error message emitter by code, selecting texts like `R6002`, `R6024`,
`DOMAIN error`, `SING error`, and `TLOSS error` from `0x0062aac0`, then emitting them through
the GUI report path or the console `WriteFile` path. `0x005acf27` is the smaller banner-pair
wrapper around that emitter, and `0x005acf60` is the registered floating-point exception
dispatcher that translates Windows exception codes into the local runtime math codes before
falling back to `UnhandledExceptionFilter`. The nearby unhandled-exception bridge is grounded now
too: `0x005b1ddd` is the top-level filter callback that first recognizes the VC++ exception
signature before tailing into the previously installed filter, and `0x005b1e23/0x005b1e36` are
its install and restore wrappers over `SetUnhandledExceptionFilter`. The neighboring fatal
security-report owner `0x005b1c31` is now explicit too: it formats either the buffer-overrun or
unknown-security-failure message, appends the current program path, emits that body through the
same GUI runtime-report path, and then forces CRT termination. The nearby startup helper
`0x005ad0c4` is the common command-line program-name-tail extractor used by the CRT argument
path. The adjacent locale-startup strip is grounded now too: `0x005ad524/0x005ad88b/0x005ada1b`
build, release, and publish the primary `0xb8` locale text record, while `0x005adad9` and
`0x005add7f` rebuild the narrower active locale-text bands rooted at `0x0062acd4`; those
owners all materialize their individual fields through `0x005b1a42`. The startup-side locale
option path is tighter now too: it resolves the older locale selector through `0x005ae9d5`,
which chooses one LCID pair plus codepage from the incoming locale strings, validates them, and
writes the resulting triple into `0x00dba060`.
- the adjacent startup argument and environment seam is explicit now too: `0x005ad1f4` is the
shared two-pass command-line parser that counts and optionally copies argv pointers plus bytes
while honoring quotes, backslashes, and the multibyte lead-byte table at `0x00dba541`.
`startup_build_argv` `0x005ad360` is the owner above it: it chooses either raw command line
`0x00dbb8d0` or the cached module-path fallback in `0x00dba1e8`, runs that parser once to size
the allocation and once to materialize the final table, then stores `argc-1` in `0x00dba024`
and the argv root in `0x00dba028`. On the environment side, `___crtGetEnvironmentStringsA`
`0x005ad402` materializes one CRT-owned multibyte copy of the Windows environment block using
`GetEnvironmentStringsW + WideCharToMultiByte` when available and `GetEnvironmentStringsA`
otherwise, and `__setenvp` `0x005ad12d` then filters that block into the final envp table by
skipping leading-`=` entries and cloning the admitted `name=value` strings into `0x00dba030`.
- the broader startup owners above those helpers are tighter now too: `startup_init_tls_state`
`0x005abd49` is the real `TlsAlloc + TlsSetValue + per-thread-block` bootstrap. Beneath it,
`startup_init_multithread_lock_table` `0x005a649e` seeds the fixed CRT lock table from the
static lock-storage band at `0x00dba078`, `startup_release_tls_slot_and_multithread_lock_table`
`0x005abcba` is the shared failure cleanup owner, and the adjacent `0x005a653c/0x005a6551/0x005a65d0`
strip now reads cleanly as the generic unlock, lazy-init, and lock-acquire helpers for those CRT
multithread slots. The neighboring `crt_get_or_create_current_thread_data_preserving_last_error`
`0x005abcd8` is also grounded now as the older CRT per-thread data getter that allocates a zeroed
`0x88`-byte record on first use while preserving `GetLastError`. `startup_init_file_handle_table`
`0x005abf1b` is the concrete CRT handle-table owner that seeds
the `0x00dba780` descriptor pages, imports inherited handles from `STARTUPINFO`, grows the table
in `0x20`-entry chunks, and finally backfills the three standard streams from `GetStdHandle`
plus `GetFileType`.
- Evidence: `artifacts/exports/rt3-1.06/startup-call-chain.md`,
`artifacts/exports/rt3-1.06/function-map.csv`.
- Open Questions: exact ownership boundary between compiler CRT shims and the first game-owned
bootstrap helper; whether any nontrivial startup callbacks seed game globals before
`app_bootstrap_main`.

View file

@ -71,9 +71,43 @@ The broader map-editor page owner is now bounded through
lines into one repeated array of identical `0xbc`-byte runtime descriptors with no row-index
special casing, and the candidate-side rebuild pass at
`structure_candidate_collection_rebuild_runtime_records_from_scenario_state` `0x00412d70` then
projects those descriptors into the live structure collection at `0x0062ba8c` before
`structure_candidate_rebuild_cargo_membership_and_scaled_rate_tables` `0x00411ee0` rebuilds the
per-cargo runtime summary tables. The current local file-side result is now tighter too: the
projects those descriptors into the live structure collection at `0x0062b268` in two
availability-bank passes. The current local disassembly now shows that this bridge reuses live
candidate slots by prior ordinal field `[candidate+0x794]` when possible, otherwise allocates one
fresh candidate, clones from the current bank's template source candidate, and only then copies in
the imported recipe-line count, shared production-cap float, and packed `0xbc` descriptor strip
from scenario state. Each rebuilt candidate then feeds
`structure_candidate_rebuild_cargo_membership_and_scaled_rate_tables` `0x00411ee0`, which rebuilds
the per-cargo runtime summary tables. That helper now reads more concretely too: it clears both
emitted cargo-id tables at `[candidate+0x79c]` and `[candidate+0x7a0]`, rebuilds one local
`0x35`-cargo mark band from the descriptor strip, accumulates the scaled per-cargo runtime rates
into `[candidate+0xa1..+0xb8]`, and then allocates the two final compact membership tables from
the `mark>=1` and `mark>=2` sets with counts stored at `[candidate+0x7a4]` and `[candidate+0x7a8]`.
The same scan also makes the production-mode split explicit on the runtime side: descriptor mode
`0` uses the shared production cap at `[candidate+0x2a]` divided by the descriptor amount, while
nonzero mode bypasses that scaling path. The immediate sibling
`structure_candidate_refresh_recipe_runtime_mode_flags_0x78c_0x790` `0x00411ce0`, which for
subtype byte `[candidate+0x32] == 2` scans the imported descriptor strip and derives two compact
post-import flags from mode `0` presence and subordinate-row presence. The stream-load side is
tighter in the same way: the constructor-side load owner
`structure_candidate_collection_construct_and_stream_load_runtime_records` `0x004131f0`
seeds global pool `0x0062b268` and immediately re-enters the broader collection importer
`structure_candidate_collection_stream_load_rebuild_runtime_summaries_and_refresh_named_availability`
`0x00412fb0`. That owner streams each packed candidate body back through
`structure_candidate_stream_load_runtime_record_and_rebuild_cargo_state` `0x004120b0`, then
reruns the same scenario-side recipe projection at `0x00412d70`, the same stem-policy sweep at
`0x00412ab0`, the collection aggregate subtotal pass over `[pool+0x8c..+0x9c]`, rebuilds the
fixed name catalog at `0x0061dbc2/0x0061dc09` for non-subtype-`1` zero-availability candidates
with live ids `<= 0x6e` via localized string `0x0b53`, and only then re-enters the same
named-availability refresh at `0x00412c10` before returning. The neighboring placed-structure
side is bounded too: global pool `0x0062b26c` comes from
`placed_structure_collection_construct_empty_runtime_pool` `0x00413230`, while the paired tagged
collection owners `0x00413280` and `0x00413440` now own the broader placed-structure stream
load/save path around tags `0x36b1/0x36b2/0x36b3` and the per-entry virtual load/save slots
`+0x40/+0x44`. The adjacent collection pass `0x00412ab0` is tighter in
the same way: it now reads as a pure stem-policy sweep that refreshes candidate dword `[+0xbc]`
from defaults `0x1869f/3/4` plus the fixed override table at `0x005edca8..0x005edd20`. The
current local file-side result is now tighter too: the
grounded recipe-book root at `0x0fe7` is preserved byte-for-byte across the checked map/save
scenario pairs, so the loader can safely treat the twelve `0x4e1`-byte books as preserved
scenario payload rather than a drifting save-only band. A conservative summary probe now only
@ -148,24 +182,29 @@ The broader map-editor page owner is now bounded through
The raw token windows beneath those branch labels are tighter now too. The checked mode-zero
demand rows preserve string-bearing windows at `line+0x1c`, and the current probe shows those
conservatively as prefixed ASCII previews such as `..Grain`, `..Corn`, `..Livestock`, and
`..Milk`; local `objdump` over `0x0041e9f0` then shows the importer feeding the corresponding
token buffer into an exact cargo-name matcher built over the live cargo collection at
`0x0062ba8c`. By contrast, the imported `supply-marker-entry` rows feed nonprintable windows such
as `.@...` from `line+0x08` through that same matcher, and the resolver path currently shows no
special-case decoding for those marker forms. So the strongest static read is now: the stem-like
demand rows preserve cargo-name text but are skipped because their mode is zero, while the
nonzero imported marker rows are the live descriptor inputs yet likely fail exact cargo-name
resolution unless another upstream transform exists.
`..Milk`; local `objdump` now grounds `0x0041e9f0` itself as
`cargo_collection_find_entry_by_exact_name`, a direct exact-string walk over the live cargo
collection at `0x0062ba8c`. The importer at `0x00435630` feeds both token lanes through that same
matcher after one conservative in-place cleanup pass: empty strings are replaced with the first
live cargo name, and mode `3` loops until the supplied and demanded token strings no longer
compare equal. By contrast, the imported `supply-marker-entry` rows still feed nonprintable
windows such as `.@...` from `line+0x08` through that same exact matcher, and the resolver path
currently shows no special-case decoding for those marker forms. So the strongest static read is
now: the stem-like demand rows preserve cargo-name text but are skipped because their mode is
zero, while the nonzero imported marker rows are the live descriptor inputs yet likely fail exact
cargo-name resolution unless another upstream transform exists.
The wrapper layer above that query no longer looks like a hiding place for special treatment
either. Local `objdump` now shows `0x00412960` simply summing the two supply-side floats returned
by `0x00412650`, while `0x004129a0` returns the single scaled production-output lane directly;
neither wrapper checks for cargo id `0` after the query returns. The broader world-side
accumulator at `0x0041e7be` is tighter in the same way: it calls `0x00412650`, requires all four
returned channels to be positive before continuing, and only then scales those four channel
values by one linked-instance count from `0x00413940` into caller-owned accumulators. So the
current strongest read remains structural rather than semantic: unresolved marker rows can still
propagate through the first bank bucket, but the first place that meaning matters is a normal
positivity-gated cargo-channel consumer, not a dedicated null-cargo branch.
returned channels to be positive before continuing, queries one linked-instance count through
`0x00413940`, scales each of the four channel values by that count, and then writes the finished
quartet into candidate dwords `[candidate+0x8e/+0x92/+0x96/+0x9a]` while stamping
`[candidate+0x8a]` from current world field `[0x006cec78+0x15]`. So the current strongest read
remains structural rather than semantic: unresolved marker rows can still propagate through the
first bank bucket, but the first place that meaning matters is a normal positivity-gated
cargo-channel consumer, not a dedicated null-cargo branch.
The caller side is narrower than before too. The steady-state site bitset owner
`placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` starts its inner cargo
loop at id `1` and only walks upward through the current live cargo count, so it never
@ -199,9 +238,13 @@ The broader map-editor page owner is now bounded through
`0x0048a090(1)` reports that all three anchor-slot dwords `[entry+0x206]`, `[entry+0x20a]`, and
`[entry+0x20e]` are still `-1`. So the strongest current read is no longer just "linked-site
capable" in the abstract: this latch consistently fronts the local linked-peer class gate
`0x0047fd50`, the paired `[site+0x42]` route-entry state toggles, and the later linked-peer
collection sweep `0x004138b0`, which keeps the `cargo id 0` bypass path firmly on the
linked-site route-anchor or classification side rather than on an ordinary cargo lane.
`0x0047fd50`, the paired `[site+0x42]` route-entry state toggles, the route-link cleanup sweep
`0x004138b0`, and the later linked-peer collection families `0x004139a0`, `0x00413a00`,
`0x00413aa0`, and `0x00413b40`, which count linked peers that pass the station-or-transit gate,
narrow that same subset to candidate class `3/4`, or stay on the subtype-`4` side and only
inspect raw linked-instance candidate byte `0xb9`.
That keeps the `cargo id 0` bypass path firmly on the linked-site route-anchor or classification
side rather than on an ordinary cargo lane.
One smaller ownership boundary is tighter too: byte `[site+0x42]` is not private scratch owned
only by that pair. Local `objdump` shows tiny direct setters at `0x0040cbc0` and `0x0040cbd0`
plus a raw getter at `0x0040cbf0`, so the `0x0040dba0/0x0040dbf0` pair is writing one shared
@ -313,13 +356,18 @@ The broader map-editor page owner is now bounded through
`shell_station_detail_present_selected_station_not_controlled_notice` `0x005043f0` is the
localized not-controlled popup beneath the same action family,
`shell_station_detail_present_scenario_station_connection_triplet_popup` `0x00504590` is the
scenario-latched station-to-station triplet popup that formats three per-destination scalar lanes
with `%5.2f` or `N/C`, and
scenario-latched station-to-station triplet popup that walks the current station's
`0x24`-byte per-destination table, skips invalid or self ids, and formats three five-byte-stepped
per-destination scalar lanes as `%5.2f` after dividing by `100.0`, or `N/C` when the lane is
absent, and
`shell_station_detail_refresh_class_3_or_4_train_service_matrix` `0x00504ec0` is the alternate
class-`3/4` branch that rebuilds the `Trains Serviced` / `Trains Maintained` matrix before
reusing the shared haul-popup callback wiring,
`shell_station_detail_refresh_class_gated_action_controls_0xb3bb_to_0xb3bf` `0x005044b0`
refreshes the lower class-gated action strip rather than the older guessed `0xb3f8` lane. The
`shell_station_detail_refresh_class_partitioned_action_controls_0xb3bb_to_0xb3bf` `0x005044b0`
is tighter now too: it does not just gate one vague lower strip. It partitions the lower action
row into two class-sensitive families, leaving `0xb3bb/0xb3bd/0xb3be` active only when the linked
candidate class is `0`, while `0xb3bc/0xb3bf` stay active only when that class is exactly `1`.
The
adjacent lifecycle and navigation side is tighter now too:
`shell_station_detail_window_destruct_release_preview_helpers_and_clear_singleton` `0x00505bf0`
is the real `StationDetail.win` destructor, and
@ -877,7 +925,22 @@ The broader map-editor page owner is now bounded through
`0x00441980`, `0x004419c0`, and `0x00441a00` are the five repeated `Overview.win` page toggles
over detail-manager mode `9`, each closing the current page through
`shell_detail_panel_transition_manager` `0x004ddbd0(-1, 0)` when that exact page is already
active and otherwise requesting mode `9` with page ordinals `0..4`.
active and otherwise requesting mode `9` with page ordinals `0..4`. One nearby idle-shell gate
is tighter now too: `0x004414d0` only forwards into the queued-record prompt owner `0x00438840`
when the live world object exists and the active shell presentation stack depth
`[0x006d401c+0xc64]` is not positive. The neighboring shell-command leaves are now explicit too:
`shell_command_open_overview_for_previous_or_latest_fixed_preview_record` `0x00441490` walks the
fixed preview-record sequence family at `0x005ce418`, preferring the predecessor of the current
inactive minimum-sequence record and otherwise falling back to the max-sequence record before
opening `Overview.win` through `0x004f3a10`; `shell_command_prompt_for_class0_region_name_and_focus_matching_world_region`
`0x00441500` opens prompt `0x16a`, scans the live class-`0` region records in `0x0062bae0` by
name `[region+0x356]`, and on a match centers the live world view through
`shell_world_view_center_on_object_with_mode_specific_zoom_policy` `0x00433900`, while misses
fall back to prompt `0x16b`; and
`shell_command_prompt_for_text_and_submit_selector1_multiplayer_transport_request_when_auxiliary_preview_ready`
`0x00441690` requires the auxiliary-preview owner gate `0x00434050` plus one live queued-preview
record at `[world+0x66ae]`, opens prompt `0x0b6d`, and submits the entered text through
`multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `1`.
`shell_station_list_format_freight_and_express_availability_summary` `0x00506e50` feeds the
station-list summary `%1 has %2 freight loads and %3 express loads available for hauling...`, and
the paired modifier helper `shell_station_list_handle_center_or_rename_action` `0x00506d50` owns
@ -887,6 +950,28 @@ The broader map-editor page owner is now bounded through
`0x61aa`, wiring the visible summary and modifier callbacks, mirroring the shared selected-station
latch at `[0x006cec78+0x4cba]` when it still belongs to the current company, and updating the two
status labels `0x61af` and `0x61b0`. The row-side callout lane is tighter too:
one adjacent active-window follow-on strip is explicit now too. The no-arg helper
`shell_refresh_active_window_followons_without_subject_gate` `0x00436070` refreshes the live
company-detail, stock-buy, and `Overview.win` branches for modes `7`, `0x0b`, and `9`.
The helper
`shell_refresh_active_window_followons_for_subject_and_optional_company_match` `0x004360d0`
refreshes the live company-detail branch in mode `7`, the stock-buy branch in mode `0x0b`, the
mode-`8` timed overlay only when the current subject id matches the caller dword, and the
`Overview.win` side in mode `9`. Its wrapper
`shell_refresh_active_window_followons_and_adjacent_station_or_company_lists` `0x00436170`
forwards through that helper and then adds the station-list refresh through
`shell_station_list_window_refresh_rows_selection_and_status` `0x00506f30` when mode `4` is
active plus the company-list refresh through `0x005158f0(-1)` when mode `1` is active. The
shared world-side follow-on beneath those shell branches is explicit now too:
`world_refresh_collection_side_effects_after_broad_state_change` `0x004361d0` sweeps the live
region, placed-structure, and three adjacent world collections, re-entering their per-record
refresh owners after broader state changes. Current grounded callers include the larger
world/status owner at `0x44b160` and the TrackLay teardown path at `0x50dba7`. The
nearby train-detail lower-action special case
`shell_handle_train_detail_lower_action_0x3f9_follow_current_route_object` `0x00435ac0` is now
bounded too: it validates the current train, resolves its linked route object, recenters the
world view on that route object, and then re-enters the shell detail manager with mode `2`.
The row-side callout lane is tighter too:
`shell_station_list_row_callback_publish_station_callout_card` `0x00506ac0` is the actual
row callback beneath both list controls, resolving the selected station, deriving one category
header through `0x0053de00` and `0x00552560`, and then publishing the station-name plus freight

View file

@ -44,7 +44,14 @@
load-screen call shape is `(4, 0)`, not a one-arg mode switch. The second stack argument is now
tighter too: current local evidence reads it as an old-active-mode teardown flag, because the
`0x482fc6..0x482fff` branch only runs when it is nonzero and then releases the prior active-mode
world through `0x434300`, `0x433730`, and the common free path before clearing `0x006cec78`.
world through `0x434300`, falls through the neighboring no-op placeholder `0x433730`, and then
reaches the common free path before clearing `0x006cec78`. The teardown owner itself is tighter
now too: `0x434300` first destroys the two indexed world collections at `[world+0x66b2]` and
`[world+0x66b6]`, then releases the typed global roots `0x0062b244`, `0x006cfcbc`,
`0x0062be10`, `0x006ceb9c`, `0x0062c120`, `0x0062ba8c`, `0x006ada84`, `0x0062ba88`,
`0x0062b2fc`, `0x0062b268`, `0x006cea4c`, and `0x006acd34` in that order before it drains the
shell-helper handle band `[world+0x46a80..+0x46aa0]`, the variable owner band `[world+0x46aa4]`,
and the linked chains at `[world+0x66a6]` and `[world+0x66aa]`.
The later world-entry reactivation branch correspondingly uses `(1, esi)` rather than `(1, 0)`.
The current live hook probes now push the remaining auto-load gap much later too: on the
hook-driven path `shell_transition_mode(4, 0)` returns cleanly, and the full old-mode teardown
@ -447,4 +454,3 @@
whether `0x00443a50` is world entry. It is where the long-lived simulation cadence takes over
after this bring-up and whether that cadence still rendezvous with the shell-owned frame path or
escapes into a separate gameplay loop.

View file

@ -32,6 +32,24 @@
`[entry+0x94]`, total-success count at `[entry+0x98]`, pending-template list at
`[transport+0x550]`, dispatch store at `[worker+0x54c]`, and text-stream buffers rooted under
`[worker+0x1c]`.
- The worker-owned text-stream seam is tighter now too: `0x59c670` constructs the two growable
text buffers, `0x59c6c0` resolves the remote host and opens one keepalive TCP socket into
`[worker+0x1c]`, `0x59cbd0` formats transient command lines through the shared static builder at
`0x00db8dd0`, `0x59caf0` appends those lines plus CRLF, and `0x59cad0` services the resulting
send/recv socket state. The current worker bring-up at `0x58f110` now reads cleanly through that
strip: after store construction it opens the text stream, connects it to the caller host/port,
and then emits either `CRYPT des 1 %s` or the fallback `USRIP` command into the send buffer. The
mode-`3` transport-text pair setter is tighter now too: `0x59ae20` takes the two payload strings
under `[msg+0x20]`, XORs each of them in place against the fixed repeating key band
`[transport+0x564]` through `0x5a1050`, seeds the paired RC4-style `0x102`-byte stream-cipher
states at `[transport+0x242]` and `[transport+0x140]` through `0x5a0d00`, marks `[transport+0x13c]`
active, and then refreshes the status line through `0x59caf0`. The
receive side is tighter now too: `0x59d210` peels one complete CRLF-delimited line out of the
receive buffer, `0x59cec0` decodes that isolated line into the transient field band rooted at
`[worker+0x328..+0x344]`, `0x59cc30` splits any `nick!user@host`-style prefix into owned
subfields, `0x59cdf0` tokenizes the later fields into the transient vector at
`[worker+0x348..+0x34c]`, and `0x59d400` returns the transient band only when one full line was
successfully decoded.
- Subsystem Handoffs: the Multiplayer.win initializer seeds the backing block at `0x006d1270`, later
reset paths construct the separate preview dataset at `0x006cd8d8`, and the shell-owned
active-mode frame services that dataset every frame through
@ -58,7 +76,14 @@
request-id, selector, payload pointer and length, flag word, and optional auxiliary pointer,
optionally allocates one sidecar object, and then either sends the request directly through the
session-event transport or takes the slower packed branch through `0x00553000/0x00552ff0` into
`0x00521dc0`. The constructor and teardown side are tighter now too.
`0x00521dc0`. One shell-side prompt owner above that submitter is now explicit too:
`shell_command_prompt_for_text_and_submit_selector1_multiplayer_transport_request_when_auxiliary_preview_ready`
`0x00441690` requires active scenario state, the auxiliary-preview-owner gate
`shell_has_auxiliary_preview_owner` `0x00434050`, and one live queued-preview record at
`[world+0x66ae]`, then opens prompt `0x0b6d` and forwards the returned text through
`0x00469d30` with selector `1`, request id `0`, flag `1`, and a null auxiliary payload while the
shell-global modal latch `0x0062be80` is held around the prompt. The constructor and teardown
side are tighter now too.
`multiplayer_preview_dataset_construct_reset_globals_and_seed_callback_owners` `0x0046be80`
is the real reset owner above the action-`2/3` branches in
`multiplayer_dispatch_requested_action`: it re-enters the paired release body
@ -253,6 +278,141 @@
`multiplayer_transport_service_status_and_live_routes`, and then descends one layer farther into
the shared GameSpy route helper `multiplayer_gamespy_route_service_frame` at `0x58d040`. The
transport also owns a separate selector-view sidecar beneath that route cadence.
The reset and teardown side of that same outer transport is tighter now too. The bounded local
callback-table attach validator `0x58d7e0` first clears selector registrations through
`multiplayer_transport_reset_selector_tables`, then ensures the keyed selector-view store, and
only then rebuilds the surrounding selector-view runtime through the auxiliary sidecar ensure
owner `0x593fe0` before returning success. That sidecar seam is now explicit too:
`0x593db0` hashes the ordered status-string pair `(entry, entry+0x40)` modulo the caller
divisor, `0x593e40` compares that same ordered pair for keyed equality, `0x593ef0` is a real
no-op release callback, and `0x593fb0` is the worker callback that resolves one selector-view
entry through `0x594b40` and commits probe success through `0x593f00`. One layer lower,
`0x58d810` is the common
runtime-reset strip that clears selector slots, releases the
keyed selector-view store, clears the auxiliary selector-view sidecar rooted at `[transport+0xac8]`,
and forwards into the remaining route-mode-sensitive selector cleanup. That lower strip is no
longer opaque either: `0x5955a0` is the bulk three-slot selector reset plus shared probe-marker
clear, `0x594080` is the auxiliary selector-view sidecar release when the keyed store is unbound,
and `0x595820` is the forced route-mode-`0` cleanup that preserves selector slot `2` ownership
across the reset. The next owner above that strip is now explicit too: `0x58de50` either latches
deferred reset at `[transport+0x1edc]`
while outstanding work remains or, once the transport is quiescent, clears `[transport+0xab0]`,
releases the live worker/runtime band through `0x58d860`, and immediately pumps one more service
step through `0x58d8d0(-1)`. The final destroy tail `0x58d8a0` then tears down queued work,
active opcode records, the Winsock guard, and the remaining owned runtime strings before freeing
the transport body. The constructor-side and shutdown-side owners are explicit now too.
`0x58dc50` enters the Winsock `1.1` guard, allocates and zeroes the full `0x1ee4`-byte transport
body, seeds local IPv4 `[transport+0x58]`, constructs the transient work-record collection,
copies one caller-supplied `0x70`-byte callback-vector/state seed block into
`[transport+0x178c..+0x17f8]`, then constructs the active opcode-record collection at
`[transport+0x17fc]` through `0x592750` and the shared plus slot-local selector callback-name stores at `[transport+0x18a8]`,
`[transport+0x1890..+0x1898]`, `[transport+0x189c..+0x18a4]`, and `[transport+0x18ac..+0x18b4]`
through `0x5966f0` before the object is considered live. The later callback-slot wrappers rooted
at `[transport+0x178c]`, `[transport+0x17c0]`, `[transport+0x17c4]`, and the sibling callback
contexts near `[transport+0x17f8]` now make that copied band read as the constructor-side
callback vector and companion state, not as a generic label blob. The paired runtime release strip
`0x58d860` tears the worker down, clears the configured transport latches, releases the transient
work-record side, reruns the selector/callback reset block, and clears `[transport+0x180c]`,
byte `[transport+0x1810]`, and deferred-reset latch `[transport+0x1edc]`. Above that, `0x58de90`
is the actual shutdown owner: it preserves the leading callback-vector dword at
`[transport+0x178c]` across `0x58de50`, disconnects the live route state, and then either marks
deferred-close flag `[transport+0x1ee0]` while work remains or falls straight into final destroy
owner `0x58d8a0`, which also releases the selector callback-name store family through `0x5967f0`.
The adjacent route-mode text side is tighter too. `0x58db70` is the small selector-text helper
that formats one caller mode string through the shared stack builder and sends it through
selector slot `3` or `4`, while the broader owner `0x58dfb0` sits above it and derives the live
route-mode status from transport latches, refreshes the mode-string band
`[transport+0xad0/+0xadc]`, stores companion state at `[transport+0xb34/+0xb40/+0xb44/+0xb54]`,
and then either submits the richer selector-text route request through `0x593c40` or falls back
to the probe/enqueue path `0x592a70`. That same owner also participates in the current
callback-table attach validation through `0x58d7e0`, with disconnect fallback `0x58d830`, and
reuses the same immediate-drain context-id wait loop as `0x58df20`.
The selector-status side underneath those owners is tighter now too. `0x5951f0` is not just a
generic transport pump: it builds up to three transient selector-mode strings from selector
presence lanes `[transport+0x384..+0x398]` and status latches `[transport+0xb40/+0xb44/+0xb54]`
plus `[transport+0x180c]`, appending the letters `s`, `r`, `h`, `g`, and `a` into three local
string bands and then hashing those bands through `0x594c40`. It only emits the matching
`SETCHANKEY`/`SETCKEY` lines through `0x58ece0` when the hashed mode state changed versus cached
masks `[transport+0x99c/+0x9a0/+0x9a4]`. The adjacent cleanup sibling `0x5965d0` is concrete
too: it optionally releases the status route through `0x597350`, clears the `h/g/r` latch band
`[transport+0xb40/+0xb44/+0xb54]`, and then reruns `0x5951f0` so the emitted selector-mode text
stays consistent with the cleared route state.
The adjacent selector and callback-table owners are tighter now too. `0x58e100` is the fixed
selector-`2` status publisher: it only runs when transport latches `[+0x60]`, `[+0x48]`,
`[+0x398]`, and `[+0xb40]` are all live, falls back to `0x005c87a8` when the caller token is
null, formats one line from the caller token plus `[transport+0x282]` and the current route IPv4
at `[transport+0x54]`, sends that line through selector `2`, sets `[transport+0xb44] = 1`, and
then either nudges route-mode helper `0x595650(5)` or falls into the auxiliary `0x597350 /
0x597370` branch. The adjacent dispatcher `0x596fd0` is now explicit too: it only exposes its
built-in status-field strip when `[transport+0x398]` is live and the `[transport+0xb44]` or
`[transport+0xb38]` gate allows it, then appends internal text `[transport+0x79c]`, decimal
state from `[transport+0xac0]`, `[transport+0xb48]`, and `[transport+0xb3c]`, one static
fallback token, or the boolean form of `[transport+0xb4c]`; outside those built-in ids it
dispatches into the local status-route callback-vector lanes or falls back to the owner callback
at `[transport+0x17dc]` with context `[transport+0x17f8]`. One level earlier, `0x58dce0` is now the setup-side sibling:
it copies the local name into `[transport+0x60]`, seeds the two status-text bands at
`[transport+0xad0/+0xadc]`, preserves those descriptor triplets only when selector-view result
slot `[transport+0xab0]` is already live, copies the route-label buffers at
`[transport+0xb58/+0xb78]`, clears route-label state bytes `[transport+0xb77/+0xb97]`, stores
callback-table metadata at `[transport+0xb98/+0xb9c]`, rebuilds the route callback-table family
through `0x596090`, and on success refreshes the current status text at `[transport+0xaf4]`
before rerunning `0x5965d0(1)`. The same local pass also makes the negative boundary tighter:
setup still touches the surrounding callback-table and replay-band fields without ever seeding a
nonzero value into `[transport+0x1778]`, so that sidecar remains an upstream producer gap.
Beside it, `0x58e200` is the broader callback-table attach or refresh owner:
it seeds one immediate-drain context id, conditionally copies the local name into `[transport+0x04]`,
clears `[transport]`, `[transport+0x48]`, and `[transport+0x1edc]`, stores follow-on callback
fields `[+0x4c/+0x5c]`, sets `[transport+0x44] = 1`, attaches the descriptor block through
`0x593650`, whose worker-side callback pair is now explicit too: `0x593610` republishes the
staged work-record triplet through opcode-`5` binding enqueue helper `0x592c40`, while
`0x593630` stores the incoming route scalar at `[transport+0x54]` and then forwards the caller
text/buffer plus `[transport+0x5c]` into `0x597780`, the fixed-template encoded route-scalar
formatter beneath that attach path. On attach failure the outer owner falls through `0x58d860`,
dispatches the resolved binding through `0x592a40`, and optionally reuses the same
immediate-drain wait loop as the neighboring transport submit owners.
The direct selector-text seam under those owners is explicit now too. `0x58e630` is just the
current-local-name helper: it returns `[transport+0x36c]` while the worker root is live and
otherwise falls back to `0x005c87a8`. Above that, `0x58e7e0` is the real direct selector-text
variant publisher under `0x58d9e0`: it formats one line through `[transport+0x1c]` as
`PRIVMSG %s :%s`, action-prefixed `PRIVMSG`, `NOTICE %s :%s`, `UTM %s :%s`, or `ATM %s :%s`
depending on caller mode `0..4`, then probes the matching registered-name entry through
`0x59d7d0` and emits opcode `4` through `0x59b790` when that entry exists. The plain sibling
branch is explicit now too: `0x58ea60` formats the same five selector-text variants through
`[transport+0x1c]` but stops after appending the text line, without probing `0x59d7d0` or
emitting opcode `4`. The registered-name fastpath side is tighter at the same time:
`0x58eb10` is just the null-worker guard above
`multiplayer_transport_find_registered_name_entry_and_optionally_return_bucket` `0x59df60`,
which walks the worker-owned registered-name store at `[worker+0x548]` and can return both the
matched entry and its owning bucket pointer. One level earlier, `0x58e510` is the broader
fastpath owner under `0x593d60`: when the caller text is null, empty, too long, or
casefold-equal to current local name `[transport+0x36c]`, it takes the immediate callback-style
opcode-`0x1b` path through `0x598060 -> 0x59b790`; otherwise it formats one local-name command
through `[transport+0x1c]` using format `0x005e1c64`, packages that request through `0x598280`,
and on either branch reuses the same `0x58e3f0 / Sleep(10) / 0x58e370` immediate-drain loop when
requested.
The route-request side beneath those owners is explicit too. `0x58e720` is the common submit root
under `0x593bb0` and `0x593c40`: it formats one local route line through `[transport+0x1c]`,
packages the caller route payload and callback triplet into a type-`1` transient request through
`0x5981b0`, refreshes the registered-name side through `0x59d5b0`, and when requested loops
through `0x58e3f0`, `Sleep(10)`, and `0x58e370` until the request completes. That registered-name
refresh path is tighter too: `0x59d5b0` builds one zeroed `0x1e0`-byte stub from the caller
string and appends it into the flat registered-name vector `[transport+0x54c]` through the
shared `generic_vector_push_back` helper `0x59e4d0`, while the smaller sibling `0x58e7a0` sits
under `0x5954b0` and formats one selector-slot line before removing the corresponding
registered-name entry through `0x59d760`. The selector callback-name side under the same reset
tail is explicit now too: `0x596900` first walks the shared selector callback-name store at
`[transport+0x18a8]` through the hashed-table reverse walk `0x58fa40` and callback `0x596840`,
pruning names that no longer correspond to any live selector-view entry or any of the three
slot-specific callback stores rooted at `[transport+0x1890/+0x1894/+0x1898]`. It then services
the slot-local callback collections at `[transport+0x18ac/+0x18b0/+0x18b4]`, clearing inactive
slots through the hashed-table clear helper `0x58fac0` and otherwise using `0x58fa40` plus
callback `0x5968b0` to prune any shared names whose current selector-view entry no longer owns
the current slot.
The drain side itself is tighter too. `0x58e3f0` no longer just “notifies a small observer
table”: its local child `0x58e310` walks the global `(command-name, callback)` table at
`0x00629d58/0x00629d5c`, compares the decoded command token at `[line+0x14]` through the shared
casefolded compare `0x5a57cf`, and on a match invokes the paired callback with the current
decoded-line band in `EDX` and the transport pointer in `ECX`.
`multiplayer_transport_ensure_selector_view_store` allocates the keyed selector-view store at
`[transport+0xab4]`, `multiplayer_transport_find_selector_view_entry_by_name` resolves entries
from that store, `multiplayer_transport_upsert_selector_name_entry` marks per-slot activity and
@ -285,7 +445,26 @@
selector mode-letter field, and `(END)` as a real sentinel that publishes a zeroed slot-`22`
payload instead of a marker pair. The same helper also hashes the selector-name, key-name, and
resolved value text back into the caller table, so the profile-key bundle now looks like a real
bounded handoff rather than an anonymous callback cloud. The deferred callback shim
bounded handoff rather than an anonymous callback cloud. The owner above it is tighter too:
`0x596da0` is now the real per-slot bundle submitter, not just a vague wrapper. For one active
selector slot it first collects the slot-local key list from `[transport+0x1890+slot*4]` and
issues the synchronous `GETKEY` query through `0x58ec50`, using either the caller override or
the slot name at `[transport+0x80+slot*0x101]`. When no override is supplied it then collects a
second list from `[transport+0x189c+slot*4]`, conditionally adds built-in `username` and
`b_flags`, and sends the larger channel-key pair list through `0x58ef20` with callback
`0x596ce0`. That second-stage callback is now explicit too: the default-slot branch resolves the
returned selector name back into one slot and then walks one selector-name pair array through
`0x596b90` using the shared fallback text at `0x00629d54`, while the selector-name-override
branch uses the explicit override name and walks one parallel pair array through the same lower
helper with publication enabled. The thin wrappers above the owner are now grounded accordingly:
`0x596fa0` forwards one selector-name override, while `0x596fc0` forces the slot's fixed name.
The adjacent rename helper `0x596c10` now also makes the selector callback-name
maintenance side explicit: after a selector rename it walks the shared and slot-local callback
stores and rewrites any callback-name entry whose primary text still matches the old selector
name. One layer above the per-key helper, `0x596b10` now reads as the shared built-in key sweep:
it tries the same result helper `0x596970` across the shared store `[transport+0x18a8]` and the
three slot-local callback-name stores, stopping on the first success and then publishing callback
slot `27` through `0x5931b0`. The deferred callback shim
`multiplayer_transport_dispatch_selector_view_refresh_probe_result` then walks the keyed store
through `multiplayer_transport_finish_selector_view_refresh_probe_if_matching`, which only
completes entries whose pending latch `[entry+0x74]` is still armed and whose parsed marker
@ -306,12 +485,27 @@
string-key lookups such as `hostname` and `gamever`, and numeric-key lookups such as
`numplayers`, `numservers`, `numwaiting`, and `gsi_am_rating`. The route-binding side uses that
descriptor family's primary dword and host-order port plus the optional secondary tuple against
route-binding offsets `+0x54/+0x58` and route word `+0x30`. Current evidence still does not prove
route-binding offsets `+0x54/+0x58` and route word `+0x30`. The capacity-side gate above it is
tighter now too: `0x595d60` first tries that tuple match against the current bound route at
`[transport+0x1ecc]`, and on success immediately falls into
`multiplayer_transport_invoke_bound_route_callback_if_present` `0x592710`, which simply calls the
bound route's optional callback slot `[binding+0x14]` with companion argument `[binding+0x18]`.
When the tuple does not match, the same gate instead compares descriptor fields `maxplayers` and
`numplayers`; only a descriptor with spare capacity reaches that same callback handoff. Current
evidence now also closes the clone side of that staged path: `0x596270` copies the first nine
dwords of the source staged callback payload, clears the intrusive next-link, and then replays
the source keyed-property list through shim `0x596260`, which simply reinserts each owned
`(key,value)` pair into the clone's property store through `0x58d0f0`, before the clone is
stored at `[transport+0xb50]` for later callback publication. Current
evidence still does not prove
that descriptor tuple is the same field family as the selector-view marker companion integer at
`[entry+0x54]`. The higher compact decode owners are tighter now too: `0x5907d0` is the
allocate-and-append lane for one self-consistent compact payload, while `0x590d00` is the keyed
upsert-by-primary-endpoint lane that reuses an existing descriptor when possible and then notifies
the owner callback. The route-callback-table runtime above that decode side is tighter now too:
route-callback receive owner for one fresh compact payload, with a concrete return split of `0`
on malformed or undersized payloads, `-1` on the special global descriptor, and the consumed byte
count on successful decode through `0x58ff60`; `0x590d00` is the keyed upsert-by-primary-endpoint
lane that reuses an existing descriptor when possible, allocates only on miss, decodes in mode
`0`, and then publishes owner callback mode `1` before returning `0/4/5` for success, decode
failure, or special-global rejection. The route-callback-table runtime above that decode side is tighter now too:
`multiplayer_transport_route_callback_table_construct` `0x5905e0` seeds one transport-owned
table block, `multiplayer_transport_route_callback_table_release_decoded_schema_dictionary`
`0x5906f0` tears down the decoded schema dictionary rooted at `[this+0x08]`,
@ -330,14 +524,30 @@
The route-handle lifecycle above that decode path is tighter now too: `0x590740` cleanly resets
one table's live route plus decode-side runtime without destroying the outer object; `0x5907a0`
is the broader destroy path that also releases the active descriptor collection; `0x590ed0`
opens the live route handle into `[this+0x4a0]`, stages the initial outbound request, and seeds
state `3` plus the staged receive buffer; `0x5911e0` is the state-`2/3` socket-service wrapper
that reads new bytes, grows the staged buffer, and re-enters `0x5908c0`; `0x5912c0` is the
now reads as the real open-and-request owner rather than a generic connect wrapper: it bounds
both caller route-name strings to `0x100` bytes, stores the caller route-mode or flag dword into
`[this+0x5b4]`, seeds one staged request with fixed selector bytes `2/1/3`, appends
`[this+0x4a8]`, the route-label buffers `[this+0x0c]` and `[this+0x2c]`, the local label band
`[this+0x6c]`, the caller route strings, the converted host-order route scalar, and two optional
flag-driven branches, then sends that request through the live route handle at `[this+0x4a0]`
before seeding state `3` and the staged receive buffer; `0x5911e0` is the state-`2/3`
live-socket service wrapper, and it is tighter now than a generic feed loop: once one full frame
is buffered it switches on subtype byte `[frame+0x02]`, using subtype `1` for
`0x590c00` schema-dictionary rebuild, subtype `2` for `0x590d00` compact-descriptor upsert,
subtype `3` for raw payload forward through `0x5b3216`, and subtype `4` for `0x590cd0`
descriptor removal by primary endpoint before compacting the tail back to the front of the
receive buffer; `0x5912c0` is the
one-shot send-with-reopen-retry helper; and `0x590ea0` is the shared disconnect publication and
reset tail. The recurring service helper `0x591290` is tighter too: it now first clears the
staged intrusive descriptor list through `0x590490` before entering the state-driven seed-or-
receive branch. The upstream owners are tighter too: `0x5962e0` is now the field-subscription
route-table opener above `[transport+0xba4]`, while `0x596530` is the `gsi_am_rating` reopen
route-table opener above `[transport+0xba4]`: it clears prior field-subscription runtime,
releases any live route on that table, builds the route label from either the optional suffix
path or the default stem block, seeds the field-cache family `[transport+0x1724]` with fixed key
ids `1` and `0x0b`, appends per-field selector names from `0x00629958`, and then opens the live
route in mode `4` through `0x590ed0`. Success seeds cached progress percentage
`[transport+0x1774] = 1` and immediately enqueues one mode-`3` field snapshot through `0x592b50`;
failure falls back through the same clear path. `0x596530` is the `gsi_am_rating` reopen
path above `[transport+0x18bc]`. On that latter branch, `0x590dc0` is now bounded as the
state-`0` raw-endpoint seed pass over the live route handle, repeatedly pulling endpoint tuples
through `0x58bc7e` record type `0x1f3` before stamping descriptor flag byte `0x15` with `0x11`.
@ -345,10 +555,19 @@
byte-`0x15` bit `0x1` as a primary-endpoint-seed or endpoint-only marker. In the `gsi_am_rating`
dispatcher, clear-bit descriptors can take the richer direct transition lane, while set-bit
descriptors are staged through the queued enrichment path and still suppress that direct
transition even after the ready bit arrives.
transition even after the ready bit arrives. The later modes in `0x595e10` are tighter now too:
mode `3` forces route mode `2` only when the primary-endpoint table is empty, mode `4` stamps
`[transport+0x1ed4] = 1` and then picks route mode `1` or `3` based on whether deferred
descriptor pointer `[transport+0x1ed8]` is null, and mode `5` mirrors staged companion dword
`[transport+0x490]` into both `[transport+0x54]` and `[transport+0x1724+0x24]`.
The adjacent capacity-descriptor side is tighter too: `0x595bc0` now clearly publishes a
descriptor block from live descriptor properties `hostname`, `numwaiting`, `maxwaiting`,
`numservers`, and `numplayers` plus three carried sidecar scalars. That sidecar at
`numservers`, and `numplayers` plus three carried sidecar scalars. Its live mode `0` path reads
those descriptor properties through `0x58d1f0`, `0x58d170`, and `0x58d6d0`, then forwards them
through opcode-`2` builder `0x592ae0`; its replay-linked modes `3/5` instead enqueue an all-zero
descriptor payload while preserving only the borrowed callback-wrapper triplet from the cached
sidecar record and then unlink that cached record through `0x5933a0`; and its callback modes
`1/2/6` are now explicit no-op fallthroughs. That sidecar at
`[transport+0x1778]` is tighter now too: current evidence says it behaves as one cached pointer
into the transient work-record family at `[transport+0x1780]`, because every meaningful branch
in `0x595bc0` reads the same `+0x0c/+0x10/+0x18` metadata triplet and replay modes later consume
@ -381,8 +600,12 @@
longer the open edge; only the upstream sidecar producer remains unresolved. The neighboring
work queue is tighter too: `0x593330/0x593370/0x593380` now bound `[transport+0x1780]` as the
construct/clear/destroy owner family, while `0x5933a0`, `0x5934e0`, and `0x593570` ground the
remove, allocate, and completion side over that same collection. The small sibling `0x593400` is
tighter too: it is a pure work-record uniqueness predicate over field `+0x0c`. Its caller is
remove, allocate, and completion side over that same collection. The completion owner is tighter
now too: `0x593570` clears in-flight latch `[transport+0x44]`, stores the final attach result in
`[transport+0x48]`, stamps `[transport+0x50]` on success, refreshes local name buffer
`[transport+0x04]` from `0x58e630`, republishes the staged metadata triplet through opcode-`1`
trigger wrapper `0x592a40`, and only then unlinks the consumed work record. The small sibling
`0x593400` is tighter too: it is a pure work-record uniqueness predicate over field `+0x0c`. Its caller is
tighter now too: `0x58d720` is an immediate-drain quiescence gate over one transport context id,
using `0x593400` for the queued work family at `[transport+0x1780]` and `0x592970` for the
active opcode-record collection at `[transport+0x17fc]`. The strongest current read is that
@ -390,7 +613,14 @@
work field `+0x0c` and active opcode-record field `+0x14` before the immediate-drain roots wait
on one shared disappearance test rather than on a vague settle loop. The currently grounded
roots are `0x58df20`, the neighboring formatted selector-text publish path at `0x58dfb0`, and
callback-table registration at `0x58e200`. The active-opcode side is tighter too: `0x5927b0`
callback-table registration at `0x58e200`. The `0x58df20` owner is tighter now too: it seeds one
shared context id through `0x5934c0`, gives that same id plus the caller callback wrapper to the
fastpath `0x593d60`, and only when that fastpath declines does it fall back into `0x593170`
using `[transport+0x04]` as the worker-side text base. Its immediate-drain tail is the same
shared quiescence rule as the neighboring owners: pump `0x58d8d0(-1)`, then wait in `0x58d720`
until the context id disappears from both queued work field `+0x0c` and active opcode-record
field `+0x14`, then honor deferred-close state if `[transport+0x1ee0]` is armed and
`[transport+0x1808]` has reached zero. The active-opcode side is tighter too: `0x5927b0`
now bounds the per-record service-and-retire path, `0x592800` the wider context-or-idle sweep,
`0x5929a0` the remove-by-opcode-type sweep, and `0x5929f0` the narrower opcode-`3`
field-snapshot removal keyed by the subscribed callback-pair payload. That also corrects
@ -409,23 +639,31 @@
selector `4` lands on the row at `0x5e2044`, not the row at `0x5e2034`. The producer side is tighter too:
bound-route requests, selector-text route requests, and the type-`9` text fastpath also stage
that same triplet through `0x5934e0`, and the fastpath shim `0x593d00` now gives the cleanest
proof of the callback split by only re-emitting the follow-on lane when `+0x10` is nonnull and
then forwarding `(+0x10, +0x18, +0x0c)` into `0x593170` as callback function, callback
proof of the callback split by first copying the returned text into the transport-local name
buffer at `[transport+0x04]`, then only re-emitting the follow-on lane when `+0x10` is nonnull,
and finally forwarding `(+0x10, +0x18, +0x0c)` into `0x593170` as callback function, callback
companion, and trailing drain context. So the replay-side triplet is clearly a broader
transport callback-wrapper family, not one fixed route-only tuple. The nearby
field-subscription side is tighter too: `0x592b50` now clearly uses `[transport+0x1774]` as a
cached progress percentage under `[transport+0xba4]`, and `0x5962e0` seeds that percentage to
`1` just before the first immediate mode-`3` snapshot. The nearby route-callback-table
lifecycle is tighter now too: `0x596090` seeds `[transport+0xba0]` as the callback-plumbing
enable latch, clears staged payload slot `[transport+0xb50]`, and constructs the three owner
branches rooted at `[transport+0xba4]`, `[transport+0x1164]`, and `[transport+0x18bc]`;
`0x596210` is the recurring service sweep over those same three tables plus the local field
cache and queued-descriptor family; `0x596060` is the explicit `gsi_am_rating` reset; and
`0x596530` is the reopen-from-stored-label sibling above that same am-rating table. The
matching local cleanup is tighter too: `0x5962c0` is the explicit staged route-callback payload
clear on `[transport+0xb50]`, while `0x595ce0` now clearly resets only the capacity-descriptor
route callback table at `[transport+0x1164]`, not the field-subscription table at
`[transport+0xba4]`. The remaining gap on the capacity side is therefore narrower: the carried
lifecycle is tighter now too: `0x596090` is now the real constructor-side owner for the full
route-callback branch. It constructs `[transport+0xba4]` with callback `0x595a40`, seeds the
companion field-cache family `[transport+0x1724]` from fixed stem `0x00629d50`, constructs
`[transport+0x1164]` with callback `0x595bc0`, builds one fixed `0x20`-byte local route-label
buffer from the current local transport name at `[transport+0x60]` plus format `0x005dccfc`,
constructs `[transport+0x18bc]` with callback `0x595e10` and that stack-built label, seeds
queued descriptor family `[transport+0x1e7c]` through `0x595f70`, clears staged payload slot
`[transport+0xb50]`, and then sets callback-plumbing latch `[transport+0xba0] = 1`. `0x596210`
is the recurring service sweep over those same three
tables plus the field-cache and queued-descriptor families; `0x596060` is the explicit
`gsi_am_rating` runtime-and-queue reset; and `0x596530` is the reopen-from-stored-label sibling
above that same am-rating table. The matching local cleanup is tighter too: `0x595b80` is now
explicitly the field-subscription-side live-runtime reset plus field-cache clear plus active
opcode-`3` purge, `0x595ce0` resets only the capacity-descriptor route callback runtime at
`[transport+0x1164]`, `0x5961b0` is the full destroy-side owner over the three tables plus both
descriptor caches, and `0x5962c0` is the explicit staged route-callback payload clear on
`[transport+0xb50]`. The remaining gap on the capacity side is therefore narrower: the carried
sidecar fields themselves now read more cleanly as the cached callback-wrapper triplet reused
elsewhere (`drain context id +0x0c`, `callback fn +0x10`, `callback companion +0x18`), and the
negative result is stronger too: nearby replay-band fields `[transport+0x176c]`,
@ -466,7 +704,15 @@
forwards the caller trio into `0x596b90`, and then publishes callback slot `28`; that lower
helper indexes one slot-specific built-in string pair from `[transport+0x189c]` and
`[transport+0x18ac]`, reuses the generic per-key handler `0x596970`, and only republishes slot
`28` when that lower query path succeeds.
`28` when that lower query path succeeds. The descriptor-lane installer above those callback
roots is explicit now too: `0x59fc80` zeroes one `0x30`-byte callback table, stores the owner
transport pointer at `[table+0x2c]`, and installs the full second selector-descriptor callback
vector `0x59f720/0x59f850/0x59f8b0/0x59f9c0/0x59fab0/0x59faf0/0x59fc50/0x59fc20/0x59fb60/
0x59fbd0` used by the selector-text and selector-view request owners `0x593aa0` and `0x593c40`.
The two smaller helper slots in that same lane are now bounded as well: `0x59fc20` resolves the
caller selector name and forwards one byte mask into
`multiplayer_transport_set_selector_presence_mask` `0x594d00`, while `0x59fc50` resolves that
same selector name and publishes callback slot `12` through `0x592d70`.
The compact-header side is tighter now too: `0x58fe20` and `0x58ff20` now show that compact
payloads always carry the primary IPv4 dword and that header bit `0x10` only gates whether the
primary port word is inline or inherited from the owner default port. `0x58fe90` now validates
@ -479,8 +725,18 @@
descriptor-state side is tighter now too: the shared queue helper at
`0x005a09a0` stamps pending state `0x4` for the local field-cache family `[transport+0x1724]`
and pending state `0x8` for the `gsi_am_rating` queued-descriptor family `[transport+0x1e7c]`,
while later service through `0x005a0c80` promotes those pending tags into ready bits `0x1` and
`0x2` in descriptor byte `[entry+0x14]`. That makes the current transport-side tests cleaner:
while the adjacent active-send owner `0x005a07c0` now makes the fast path explicit instead of
looking like a missing growth helper: it stamps the descriptor into the active list, timestamps
`[entry+0x1c]`, and immediately emits the mode-selected outbound query packet through the queue
socket, with the secondary endpoint tuple `[entry+0x08/+0x0c]` only taking over when queue
companion dword `[queue+0x24]` matches the primary dword and descriptor state bit `0x2` is live.
The receive-side owner layer is tighter too: `0x005a0b40` drains queue socket `[queue+0x20]`,
matches inbound replies against the active list's primary or secondary endpoint tuples, and then
routes the matched entry into `0x005a0a00` for queue mode `1` or `0x005a0ad0` for the alternate
grounded mode. The broader maintenance pass `0x005a0c80` then adds the stale-active expiry sweep
`0x005a0c00` and the pending-to-active promotion pass `0x005a0c50`, so the ready-bit transition
now reads as a full queue lifecycle instead of one isolated state-byte write. That makes the
current transport-side tests cleaner:
`0x58d1c0` is the field-cache ready gate, `0x58d1d0` is the `gsi_am_rating` queued-descriptor
ready gate, and `0x58d230` is the remaining flag-byte split between direct primary-endpoint
handling at `[transport+0x18bc]` and the queued path at `[transport+0x1e7c]`. That byte-`0x14`
@ -494,17 +750,42 @@
it to suppress the direct `0x595dc0` transition even after queued ready bit `0x2` is present.
The descriptor body is tighter too: `[descriptor+0x20]` is now the intrusive next-link used by
the transport-owned primary-endpoint list headed at `[table+0x5bc]`, and `[descriptor+0x1c]` is
now the special numeric scalar behind the current `queryid`/`ping` fallback pair. The compact-only
now the special numeric scalar behind the current `queryid`/`ping` fallback pair. That special
numeric path now has one clearer owner too: `0x58d6a0` lazily bootstraps the shared key
dictionary at `0x00db8b48` for the grounded strings `queryid` and `ping`, using the local
dereferenced-string hash, compare, and release callbacks `0x58d690`, `0x58d070`, and `0x58d090`.
The descriptor property-store seam is tighter in the same way now. The keyed store rooted at
`[descriptor+0x18]` is allocated by `0x58d5b0` with explicit per-entry key callbacks:
`0x58d550` releases the owned shared key/value string pair, `0x58d570` hashes the dereferenced
key string through `0x58d510`, and `0x58d580` compares two dereferenced keys through the shared
locale-aware casefolded compare `0x5a57cf`. The fixed-reply side above that store is no longer
anonymous either: when queue mode-`1` reply owner `0x5a0a00` sees descriptor flag bit `0x4`
clear, it routes the payload into `0x58d3a0`, which first consumes one backslash key/value
prefix and then walks exactly two counted reply sections, each with its own NUL-stem dictionary;
the later value strings are reinserted under synthetic decimal-suffixed keys built from those
stems plus one running per-section index.
The compact-only
auxiliary dword at `[descriptor+0x10]` is tighter in a negative way too: local xref scans now
only show it being preserved by later generic helpers like
`generic_record_0x1c_deep_copy_with_owned_string_at_0x08` `0x591410` and the adjacent
callback-marshaling wrappers `0x591480` and `0x591510`, not read through any dedicated semantic
accessor yet. The route-event dispatcher side is tighter too: the mode-`5` tails in both
accessor yet. The route-event dispatcher side is tighter too: `0x595dc0` is no longer just one
vague transition shim. It first rejects when staged-route busy latch `[transport+0x1e8c]` or
selector-slot object `[transport+0x38c]` is live, then reuses `0x595d60`; only a positive
capacity result lets it refresh selector state through `0x5973b0`, reset selector slot `2`
through `0x5954b0`, and stage the descriptor through `0x5958e0` before route mode `0` is
entered through `0x595650`. The mode-`5` tails in both
callback families do not copy a descriptor-local field but instead mirror the transport-staged
companion dword at `[this+0x490]` into `[this+0x54]` and queue-side slot `[this+0x1724+0x24]`. The
`gsi_am_rating` maintenance lane is tighter now too: after pruning failed descriptors it sorts
the surviving primary-endpoint table through `0x590310` in mode `1` with key `gsi_am_rating`,
then selects the new head through `0x590480` before re-entering the route-transition path. The
owner above that handoff is explicit now too: mode `2` in `0x595f70` requires current route mode
`1`, no live selector object at `[transport+0x398]`, and no busy slot object at `[transport+0x38c]`;
it refreshes every surviving endpoint entry's `gsi_am_rating`, forces route mode `2` when the
table empties, and otherwise stages the fixed `gsi_am_rating` key for the current head entry
before falling into `0x5958e0`; only a submit failure drops that branch back to route mode `0`,
while success leaves the later `0x595860` callback to drive the `2 -> 3 -> 4` route-mode ladder. The
same service loop also owns a slower sidecar lane keyed off `[entry+0xa4]`:
`multiplayer_transport_select_stale_selector_view_progress_entry` walks the store through
`multiplayer_transport_pick_stale_selector_view_progress_entry`, picks one stale entry whose
@ -518,6 +799,20 @@
`[transport+0xaec]`. So the selector-view sidecar no longer looks like one undifferentiated
refresh bucket: it has a faster deferred-probe lane plus a slower progress-snapshot lane, both
still under the shell-owned multiplayer transport cadence. The two descriptor lanes installed by
`multiplayer_transport_submit_selector_text_route_request` are tighter in the same family too:
when the entry-local marker text at `[entry+0x9ac]` is empty, the request path falls back to
`multiplayer_transport_format_selector_view_probe_marker_fallback_with_fixed_template_0x5e2350`
`0x597710` before handing the text into `0x593c40`. The parser split is explicit now too:
`multiplayer_transport_parse_selector_view_probe_marker` `0x5977b0` consumes the wider
`X%sX|%d` form, while
`multiplayer_transport_try_parse_selector_view_probe_marker_core` `0x597860` only decodes the
wrapped request-id from the shorter sentinel form and leaves any decimal tail to the caller. The
linked pending-template strip is tighter in the same way: after
`multiplayer_transport_unlink_pending_template_node` removes a node from the list rooted at
`[transport+0x550]`, it now tails into
`multiplayer_transport_release_pending_template_node` `0x597960`, which frees the node-owned
payload graph, both selector strings, and the node body itself.
The two descriptor lanes installed by
`multiplayer_transport_attach_callback_table_descriptor` are now tighter too. The first lane
rooted at `0x59f5c0` can arm deferred-close state on the owner transport and then forward through
callback slot `23`. The second lane is no longer just a loose selector-view bucket:
@ -552,27 +847,126 @@
`localport`, `localip%d`, and `statechanged` strings, while
`multiplayer_gamespy_route_drain_inbound_packets` drains inbound datagrams and dispatches
semicolon lines, backslash-delimited key bundles, and `0xfe 0xfd` GameSpy control packets. The
transport-owned callback story is now narrower too. The shared route constructor
outbound side is tighter now too: `0x0058cd40` is the shared decimal-text appender beneath both
the route builders and the shell-side status publishers; `0x0058c950` is the dedicated
field-class-`8` `PING` sender that refreshes `[route+0xac]`; and `0x0058cd70` is the broader
mode-selected control-packet owner that appends `localip%d`, `localport`, optional
`statechanged`, the route-name text, and then either the encoded three-slice suffix through
`0x0058c300` or a bare terminator before `sendto`. The read side is tighter too:
`0x0058f4e0` is the zero-timeout socket-readiness probe that `multiplayer_gamespy_route_drain_inbound_packets`
uses immediately before `recvfrom`. The
local control-payload seam is tighter now too: the immediate three-slice emitter wrapper
`0x0058c300` packages predecoded slices as field classes `0`, `1`, and `2`, while `0x0058c340`
decodes one length-coded three-part payload and re-emits those slices through the shared
packet-field builder `0x0058c0c0`; that
builder uses `0x0058c010` for the field header, `0x0058c030` for the encoded payload append, the
RC4-style transform `0x0058bee0`, the Base64-like text appender `0x0058be50`, and the six-bit
alphabet mapper `0x0058be20`. The same local support strip also now includes `0x0058bcb0` for
bounded control-id list append and `0x0058bce0` for bounded C-string append into the shared
`0x800`-byte text builders. The backslash-query side is tighter too: `0x0058c3e0` is the shared
callback-driven field-group emitter that maps key ids through `0x00629958`, appends the key
stems into the same builder, and then dispatches value production through callback slots
`[route+0x88]`, `[route+0x8c]`, and `[route+0x90]` before `0x0058c5c0` adds the final
terminator. The transport-owned callback story is now narrower too. The shared route constructor
`multiplayer_gamespy_route_construct_and_seed_callback_vector` seeds `[route+0x88]` through
`[route+0x9c]` from the caller-supplied transport callback table, records the owner transport at
`[route+0x104]`, and explicitly zeroes `[route+0xa0]`, `[route+0xa4]`, and `[route+0xd4]` before
any later patch-up. For the transport-owned status route,
`multiplayer_transport_try_connect_status_route` then patches `[route+0xa0]` through
`multiplayer_transport_try_connect_status_route` then seeds the six-entry callback vector
`0x596fd0/0x5970e0/0x597180/0x5971b0/0x597270/0x5972c0`, chooses either default route id
`0x1964` or the caller route id, copies stored route-label pointer `[transport+0x9a8]` into
`[transport+0xb3c]`, and patches `[route+0xa0]` through
`multiplayer_gamespy_route_set_extended_payload_callback` to point at
`multiplayer_transport_forward_validated_extended_route_payload` `0x00597330`, which simply
forwards the validated payload wrapper into the owner callback at `[transport+0x17f4]` with
context `[transport+0x17f8]`. The grounded live-route connect path at
context `[transport+0x17f8]`; success also clears `[transport+0xb38]`. The adjacent owner strip
is now explicit too: `0x597350` releases the auxiliary status route, `0x597370` services that
route alone through the shared low-level tick helper, and `0x597380` is the broader recurring
sweep that services both the status route and the current live route. The connect-side endpoint
setup is tighter now too:
`0x0058f540` resolves the current local hostname into one hostent, `0x0058bd50` copies up to
five local IPv4 dwords from that hostent into the global table at `0x00db8a28`, and
`0x0058bd90` builds one `sockaddr_in` with `AF_INET`, `htons(port)`, direct dotted-quad parse,
and host-name fallback. In the grounded status-route path,
`multiplayer_transport_try_connect_status_route` formats `%s.master.gamespy.com`, uses port
`27900`, and feeds that pair through `0x0058bd90` before the route opens its UDP handle. The
local bind side is tighter too: `0x0058cb50` opens a UDP socket, retries a `0x64`-wide local
port range or an ephemeral bind through the same sockaddr helper, normalizes literal
`127.0.0.1` to `INADDR_ANY` before `bind`, and returns both the live socket and chosen local
port; `0x0058cc40` is the wrapper above it that hands that socket and port into
`multiplayer_gamespy_route_construct_and_seed_callback_vector` and then marks `[route+0xbc] = 1`
on the resulting object. The startup or teardown calls around that path are now explicit too:
`0x0058f470` is the local `WSAStartup(0x0101, ...)` guard and `0x0058f490` is the matching
`WSACleanup` wrapper. The direct Winsock thunk strip under the same family is now mostly named
too: `0x0058bc42/48/4e/54/5a/60/6c/72/78/7e/8a` line up with `gethostbyname`, `gethostname`,
`closesocket`, `sendto`, `htons`, `htonl`, `socket`, `WSACleanup`, `WSAStartup`, `recvfrom`,
and `bind`, while `0x0058bc3c` is the dotted-quad conversion thunk used under the `localip%d`
builder path. The local-address selection side is narrower too: `0x0058d750` resolves the same
hostent list and picks the first private or loopback IPv4 through `0x0058f580` before the
transport-side bring-up path consumes it. The grounded live-route connect path at
`multiplayer_gamespy_udp_global_callback_worker_bootstrap` now sits beside that route layer as a
separate helper family rather than more route-object state. `0x0059fe30` resolves an optional
host and port into a stack `sockaddr_in`, and `0x0059fe8e` then opens the global UDP socket
`0x00629f28`, applies `SO_REUSEADDR`, and binds that prepared address. `0x005a0000` seeds the
callback-state globals `0x00db9fd8..0x00db9ffc`, allocates the timeout-registration vector
`0x00db9ff0` and queued-callback vector `0x00db9fec`, and optionally opens the socket
immediately; `0x005a0120` is the matching shutdown path. The control-packet codec under that
worker is explicit too: `0x0059fd00` accepts only fixed `0x91/0x01` packets with kind `1..3`
and an optional trailing `0x18`-byte payload, while `0x0059fdc0` emits that same `0x20`-byte
packet shape back through `sendto`. The kind handlers above it are now bounded as well:
`0x005a0200` handles kind `1` by issuing the kind-`2` reply and optionally staging one
timeout-registration record, `0x005a02f0` handles kind `2` by resolving that staged
registration, optionally emitting kind `3`, and queuing the completed callback, and `0x005a03d0`
is the shorter kind-`3` completion path. `0x005a0440` is the dispatch switch over those three
packet kinds. The receive and timeout side now reads coherently too: `0x005a0490` waits on the
global socket, drains one datagram through `recvfrom`, timestamps it, decodes it, and dispatches
it; `0x005a0550` then sweeps expired timeout-registration records from `0x00db9ff0`, optionally
queuing timeout callbacks through `0x0059fef0`; and `0x0059ff70` drains and frees the queued
callback vector `0x00db9fec`. So `0x005a05d0` now reads cleanly as the one-shot service tick for
the whole global UDP callback worker rather than another anonymous transport loop. One layer
higher, `0x005a0600` is the synchronous send-side owner over that same worker: it emits the fixed
kind-`1` query packet, stages one timeout-registration record, and can then pump
`0x005a05d0` plus `Sleep(1)` until the registration clears before draining the queued callbacks.
The immediate queue-side support strip is explicit now too: `0x005a0700`, `0x005a0720`,
`0x005a0740`, `0x005a0760`, and `0x005a07b0` are the append, prepend, pop, remove, and clear
helpers for the intrusive list family that links nodes through offset `+0x20`, and
`0x005a08f0` is the constructor-side queue bootstrap that opens the queue-owned UDP socket and
clears the active and pending list roots. The grounded
live-route connect path at
`multiplayer_transport_try_connect_live_route` does not currently perform any matching
post-construction patch for `[route+0xa0]`, `[route+0xa4]`, or `[route+0xd4]`, and the higher
route-mode state machine now looks consistent with that: `multiplayer_transport_set_route_mode`
latches the requested small mode at `[this+0x18b8]`, then uses mode `0` for the direct-versus
queued `gsi_am_rating` split, mode `1` for the ready-bit plus queued fallback, mode `2` for
pending-descriptor cleanup, mode `3` for the empty-table fallback, mode `4` for deferred
route-status recovery, and mode `5` for copying the staged route companion dword into `[this+0x54]`
and queue-side slot `[this+0x1724+0x24]`. The current grounded mode transitions still switch by releasing route
objects through `multiplayer_gamespy_route_release_and_free` and rebuilding them through
`multiplayer_transport_try_connect_live_route`, not by mutating callback slots in place. The
parser behavior is now tighter as well: semicolon lines only dispatch when
route-mode state machine now looks consistent with that, but the owner is tighter than the old
flat mode list. `multiplayer_transport_set_route_mode` first applies one pre-dispatch gate:
when a bound route still exists at `[this+0x1ec8]`, requested mode `2`, and selector slot `2`
is not active, it submits one bound-route status request through `0x5959e0`. That request itself
is now narrower too: it derives one request token from the current binding through `0x5934c0`,
then forwards binding dword `[route+0x2c]`, binding word `[route+0x30]`, local counter
`[this+0xb48]`, and default sample text `0x005c87a8` into `0x593980` using completion callback
`0x595980`, and a submit failure immediately sets `[this+0x1ed8]` so the route-mode owner can
fall back without waiting for the callback. That callback is tighter now too: nonzero results
force mode `2` when `[this+0xac0] <= 1` and otherwise promote through mode `3` or `4` according
to `[this+0xb48]`, while zero results set `[this+0x1ed8] = 1` and then fall back through route
mode `0` or `1` according to deferred am-rating latch `[this+0x1ed4]`. On success the route-mode setter stores the current
mode at `[this+0x18b8]` and then runs one of the concrete branches: mode `0` refreshes
selector-route side effects through `0x5973b0`, resets selector slot `2`, tries to reopen the
`gsi_am_rating` callback-table family, and then falls back according to deferred route-status
flag `[this+0x1ed8]`; mode `1` conditionally reopens that family and then, when no live route is
present, tries to connect the live route through `0x597480`; mode `2` resets the am-rating
family and promotes a successful live-route connect into mode `1`; once that family is already
populated, the later callback-owner at `0x595f70` takes over by pruning stale entries, refreshing
`gsi_am_rating`, selecting the current head endpoint, and staging the route-callback payload
through `0x5958e0`; mode `3` resets the
am-rating family, refreshes selector-route state, resets selector slot `2`, and releases the
current route binding; mode `4` is the narrow status-route recovery retry; and mode `5` resets
the am-rating family, refreshes selector-route state, and releases the current route binding
without the selector-slot reset. The live-route connect path is tighter now too: `0x597480`
builds one `0x20`-byte local identifier from `[this+0x60]` plus suffix template `0x005dccfc`,
seeds the callback vector `0x596fd0/0x5970e0/0x597180/0x5971b0/0x597270/0x5972c0`, and chooses
either the default route id `0x1964` through `0x58cc40` or the binding-specific id in
`[binding+0x30]` through `0x58c9b0`; on the binding-specific path it also clears pending rebuild
cookie `[binding+0x34]` and marks the constructed route live via `[route+0xbc] = 1`. The stable
transitions therefore still switch by releasing route objects or route bindings and rebuilding
route state, not by mutating callback slots in place. The parser behavior is now tighter as well: semicolon lines only dispatch when
`[route+0xd4]` is non-null, and the subtype-`6` raw fallback only dispatches when `[route+0xa4]`
is non-null. For the currently grounded transport-owned status and live routes, those two branches
therefore remain optional and can cleanly no-op instead of implying a hidden mandatory callback
@ -604,4 +998,3 @@
`[route+0xa4]` and `[route+0xd4]` for the transport-owned status/live routes, or whether those
packet families are simply unused in this stack; and how far the Multiplayer preview-dataset
machinery is reused outside `Multiplayer.win` beyond the currently grounded `.gmt` save-mode hook.

View file

@ -47,7 +47,23 @@ The same brush strip is tighter now too:
trailing caller dwords at `[node+0x08..+0x1c]`, and appends the finished node to the singly
linked list rooted at `[state+0x66a6]`. The gameplay label for that queued-record family is still
open, but the structural link from periodic region selection into the scenario-state queue is now
direct instead of speculative. One neighboring narrow counter is bounded too: `0x00422850`
direct instead of speculative. One neighboring owner is tighter now too: `0x004358d0` walks the
same live region collection and services those pending amounts after linked-site refreshes. When a
region's pending amount at `[region+0x276]` is live and the city-connection peer probes
`0x00420030` and `0x00420280` can resolve one matching peer site plus linked company through
`0x0047efe0`, it formats one localized notice from region name `[region+0x356]`, world scalar
`[region+0x23a]`, and the pending amount, publishes that notice through `0x004554e0`, posts the
amount into company stat slot `4` through `0x0042a080`, then clears `[region+0x276]` and stamps
completion latch `[region+0x302] = 1`. When no peer-company branch is available and byte
`[region+0x316]` is still clear, the same owner publishes one alternate one-shot notice from the
same amount and region scalar before setting `[region+0x316]`. So the pending-region bonus lane
is no longer just a queued setup artifact: it has a concrete later service owner and an explicit
shell-facing fallback above the same queue family now too. `0x00438710` is the recurring queue
service owner above `[world+0x66a6]` and `[world+0x66aa]`, while `0x00438840` is the tiny
dispatch-or-fallback sibling: it forwards the currently active queue node at `[world+0x66aa]`
into the same node-handler table `0x00437c00`, or opens the fixed custom modal rooted at
localized id `0x153` when no active node is staged.
company-credit side effect. One neighboring narrow counter is bounded too: `0x00422850`
counts class-0 regions that pass a second `0x00420030` peer-probe variant with fixed flags
`(1,1,1)` plus one caller-supplied trailing dword, and current callers are the query/script
dispatch at `0x0042f856` and the later region-stats formatter at
@ -71,18 +87,67 @@ The same brush strip is tighter now too:
same `319` lane is tighter now too: after the route-entry collection refresh on `0x006cfca8` it
refreshes the auxiliary route-entry tracker collection `0x006cfcb4`, then runs
`placed_structure_collection_refresh_local_runtime_records_and_position_scalars` `0x004133b0`,
which first drains the queued local-runtime rebuild ids through collection `0x0062b2fc` and then
sweeps the live placed-structure collection `0x0062b26c` for the later position-triplet side
refresh,
then a flagged world-grid cleanup sweep through the compact grid-flag query
`0x00448af0` plus the neighboring local chunk-cell write helper `0x00533fe0`, and only after
that the later route-entry post-pass at `0x00491c20`. The same `319` lane is tighter internally
now too:
the surrounding placed-structure collection side is no longer just the per-record loader family.
`0x004131f0` now cleanly constructs and stream-loads the live placed-structure collection,
`0x00413230` constructs the empty runtime pool, `0x00413280` stream-loads tagged placed-structure
entries with progress publishing, `0x00413260` is the matching release-and-free owner, and
`0x00413550` now clearly resolves one site id, re-enters `0x0040e080` to release local runtime
and linked-site follow-on state, and only then unlinks the entry from the live collection. The
adjacent helper strip is tighter too: `0x00413620` is the collection-wide linked-peer overlay
refresh sweep above `0x0040d2d0`; `0x00413660` and `0x004136e0` are the neighboring owner-color
and scalar publish sweeps; `0x00413750` is the shared mode-`3/6` linked-site preview membership
refresh owner; `0x00413860` is the collection-side center-cell roster sweep above `0x0040cd10`;
`0x004138b0` is the route-link cleanup sweep keyed by one center-cell `u16` roster token;
`0x004138f0` counts live placed structures whose cached candidate id `[site+0x3d0]` matches one
caller-supplied structure id; `0x00413940` walks the same matching subset and accumulates source
field `[source+0x141]` from `0x0040cec0` with a floor of `1`; `0x004139a0` counts entries whose
linked peer passes the narrower station-or-transit gate `0x0040d230`; `0x00413a00/0x00413aa0`
narrow that same linked-peer subset to candidate class `3` and `4`; and `0x00413b40` is the
subtype-`4` companion counter whose last gate is the raw linked-instance candidate byte `0xb9`.
That `0x00413940` sum is now the direct link-count scale factor consumed by `0x0041e7be` above
the four cargo-summary banks.
One neighboring year-side owner is tighter now too: `0x00435b50` is the shared year-threshold
and structure-milestone news pass beneath periodic simulation and startup bring-up. It suppresses
itself when the cached previous year still matches or scenario gate `[0x006cec78+0x46c38]` is
live, then publishes fixed year notices for `1865/1895/1920/1958`, formatted numeric notices for
`1850/1900/1950`, and later structure-milestone notices keyed by live counts of specific placed
structures resolved through `0x00412af0` and counted through `0x004138f0`, appending the finished
records into the existing fixed-record/news lanes at `0x006cea4c` and `0x004337c0` rather than
through a separate hidden journal family.
before that later world and shell reactivation tail, `world_entry_transition_and_runtime_bringup`
runs one distinct post-bundle status and runtime refresh phase that posts progress ids `0x196`
and `0x197` through `0x005193f0/0x00540120` with paired `0x004834e0` follow-ons, refreshes the
live event collection at `0x0062be18` through
`scenario_event_collection_refresh_runtime_records_from_packed_state` `0x00433130`, rebuilds the
scenario-side port-or-warehouse cargo recipe runtime tables through `0x00435630`, and then runs
the named-candidate availability preseed through `0x00437743`. One later subphase is tighter now
too: before the broad world-reactivation sweep it posts progress ids `0x32dc/0x3714/0x3715`,
the named-candidate availability preseed through `0x00437743`. The recipe rebuild lane itself is
tighter now too: `0x00435630` resolves both supplied and demanded token strings through the exact
live cargo-name matcher `cargo_collection_find_entry_by_exact_name` `0x0041e9f0`, fills empty
token strings from the first live cargo entry before that match, and in mode `3` loops until the
supplied and demanded strings no longer compare equal. The importer-side bridge is tighter now
too: each of the twelve recipe books writes its active-line count into the paired runtime count
lane beside the imported `0xbc` descriptor strip, and after the full twelve-book sweep the helper
explicitly re-enters
`structure_candidate_collection_rebuild_runtime_records_from_scenario_state` `0x00412d70` when
the live candidate collection exists. That keeps the strongest current static split narrow and
concrete: mode-zero demand rows can still preserve readable cargo-name text in the saved recipe
books, but only the nonzero imported rows reach the live `0xbc` descriptor array, and the
unresolved supply-marker forms still have no special decode path before the exact matcher runs.
The immediate helper strip under that bridge is tighter now too: `0x00411d50` is the narrow
descriptor-pattern predicate that returns true only when every imported descriptor keeps mode `0`
and at least one descriptor has no subordinate rows, while `0x00411da0`, `0x00411e10`, and
`0x00411e50` are conservative fixed-table accessors over candidate slot `[candidate+0x798]`,
exposing one copied name plus either a scalar pair or scalar triplet from the same fixed row in
`0x005ed338..0x005edca4` rather than a separate loader family.
One later subphase is tighter now too: before the broad world-reactivation sweep it
posts progress ids `0x32dc/0x3714/0x3715`,
reloads one `0x108`-byte packed profile block through `0x00531150`, conditionally copies staged
runtime-profile bytes back into `0x006cec7c` while latch `[profile+0x97]` is set, mirrors the
grounded campaign-scenario bit `[profile+0xc5]` and sandbox bit `[profile+0x82]` into world
@ -94,6 +159,22 @@ The same brush strip is tighter now too:
adjustment branch: non-editor startup mode can decrement the lane by `1` or `3` depending on
shell-state editor gate `[0x006cec74+0x68]`, shell-side selected-year-adjust policy
`[0x006cec74+0x178]`, and the saved special-condition slot `[0x006cec78+0x4af7]`, and only that
save/load bridge is narrower on the candidate side too: the constructor-side load owner
`structure_candidate_collection_construct_and_stream_load_runtime_records` `0x004131f0`
seeds global pool `0x0062b268` and immediately re-enters the broader collection importer
`structure_candidate_collection_stream_load_rebuild_runtime_summaries_and_refresh_named_availability`
`0x00412fb0`. That owner streams each packed candidate body back through
`structure_candidate_stream_load_runtime_record_and_rebuild_cargo_state` `0x004120b0`, reruns the
scenario-side recipe projection at `0x00412d70`, refreshes the stem-policy lane at `0x00412ab0`,
rebuilds the collection aggregate subtotal band at `[pool+0x8c..+0x9c]`, repopulates the fixed
name catalog at `0x0061dbc2/0x0061dc09` for non-subtype-`1` zero-availability candidates whose
live ids stay within `0x6e`, and then reruns the named-availability pass at `0x00412c10` before
returning. The neighboring placed-structure side
is bounded too: global pool `0x0062b26c` comes from
`placed_structure_collection_construct_empty_runtime_pool` `0x00413230`, while the paired tagged
collection owners `0x00413280` and `0x00413440` now own the broader placed-structure stream
load/save path around tags `0x36b1/0x36b2/0x36b3` and the per-entry virtual load/save slots
`+0x40/+0x44`.
adjusted lane then feeds
helper `0x0051d390` before `world_set_selected_year_and_refresh_calendar_presentation_state`
`0x00409e80` stores the final absolute counter into `[world+0x15]` and refreshes
@ -170,6 +251,11 @@ The same brush strip is tighter now too:
profile name and writes that string into the same destination; and one compact runtime-effect
branch inside `world_apply_compact_runtime_effect_record_to_resolved_targets` `0x00431b20` resets
the same destination to the fixed placeholder token at `0x005c87a8`. That gives a grounded live
owner above the latch too: `simulation_service_world_outcome_mode_prompt_and_transition_effects`
`0x00436350` is the frame-serviced consumer of `[world+0x4a73]`, stamping completion latch
`[world+0x4a77]`, driving the outcome-mode prompt rooted at localized id `0x169`, and triggering
the world-side transition paths around `0x482150` while leaving `[world+0x4b47]` as the current
outcome-status payload source. That gives a grounded live
interpretation for the start of the tail: `[world+0x4b47]` is the start of a victory or outcome
status-text buffer, not a float lane. The same evidence also gives a useful caution: those live
helpers copy up to `0x12c` bytes into `[world+0x4b47..+0x4c73]`, so the current bounded file-tail
@ -188,7 +274,18 @@ The same brush strip is tighter now too:
`Starting Building Density Level`, `0x0f61` maps to `[world+0x4c7c]` `Building Density Growth`,
`0x0f65` maps to grounded dword `[world+0x4c80]` `leftover simulation time accumulator`, and
`0x0f6d` maps to byte `[world+0x4c88]` `selected-year lane snapshot`. The first later grounded
dword after that is `[world+0x4c8c]` at `0x0f71`. That means the simple 4-byte file-lane model
dword after that is `[world+0x4c8c]` at `0x0f71`. The frame-side follow-on above the outcome
prompt is grounded now too: after `0x00436350` stamps `[world+0x4a77]`, internal branch
`0x0043963d` keeps running only while `[world+0x4a7b]` still matches the current step-local
marker, then services the queued runtime-effect record family rooted at `[world+0x66a6]`
through `0x00438710`, conditionally opens `Overview.win` through `0x004f3a10` when the preview
fixed-record collection at `0x006cea4c` still has one admissible entry, and conditionally opens
`LoadScreen.win` page `0` through `0x004e4ee0` when shell latch `0x006d4000` is clear and
world flag `[world+0x4d]` is still nonzero. The same branch also conditionally toggles pause or
resume through `0x00437a60` when no live multiplayer session object is present at `0x006cd8d8`.
That splits the outcome prompt owner `0x00436350` cleanly from the later post-transition
follow-on strip instead of leaving both behaviors folded into one unnamed frame tail. That means
the simple 4-byte file-lane model
stops matching grounded live field boundaries immediately after the text-buffer edge: the post-
`0x0f58` file bytes are still offset-correlated to live state, but they are no longer naturally
dword-aligned with the next grounded object fields. The new byte-neighborhood probe makes the
@ -381,7 +478,22 @@ The same brush strip is tighter now too:
safest semantic read is that this shared catalog is the bundled source form of the scenario-side
named candidate-availability table later mirrored into `[state+0x66b2]`, with each entry's
trailing dword now reading as the same availability override bit later copied into
`[candidate+0x7ac]`. The loader-side coverage is tighter now too: the same table parser now
`[candidate+0x7ac]`. The candidate-side refresh strip is tighter now too: `0x00412c10` walks
the live candidate pool, forces `[candidate+0x7ac] = 1` whenever availability bytes
`[candidate+0xba/+0xbb]` are already set or subtype `[candidate+0x32]` is not `2`, and only for
the remaining subtype-`2` records does it consult `0x00434ea0` by stem before tailing into the
dependent cargo-economy filter rebuild `0x0041eac0`. The adjacent collection helpers also read
cleanly now: `0x00412bd0` is the collection-wide `0x00411ee0` cargo-summary rebuild sweep over
imported `0xbc` descriptor arrays, while `0x00412ba0` is the remove-and-release sibling that
clears one candidate's dependent runtime descriptor and cargo-membership tables through
`0x00411cb0` before erasing that id from the pool. One lower runtime detail is explicit now too:
`0x00411ee0` does not just “refresh summary tables.” It rebuilds the two emitted cargo-id tables
at `[candidate+0x79c]` and `[candidate+0x7a0]` from one temporary `0x35`-cargo mark band, stores
their counts at `[candidate+0x7a4]` and `[candidate+0x7a8]`, and accumulates the scaled runtime
rates into `[candidate+0xa1..+0xb8]`; mode-`0` descriptor rows use the shared production cap at
`[candidate+0x2a]` divided by the descriptor amount, while nonzero mode rows bypass that cap
scaling. The loader-side coverage is tighter now too:
the same table parser now
attaches both to the common-save bridge payload and directly to the fixed source range in
`.gmp` files and the non-common `rt3-105-scenario-save` / `rt3-105-alt-save` branches. That
makes the scenario variation explicit instead of anecdotal. `Alternate USA` keeps only three

View file

@ -31,6 +31,19 @@ The neighboring connection-state note pair now appears
through the wider multiplayer preview launch-state service. So the station-detail overlay
currently owns only the `Coming To`, `Going From`, `Current Supply`, `Current Demand`, `--None--`,
and `All` legend lanes.
That formatter boundary is tighter now too. `0x004207d0` returns `0` immediately when preview-global
`0x0062be84` is armed, forwards directly into the shared fallback formatter `0x00455860` when
subtype dword `[this+0x23e]` is nonzero, and only otherwise runs its own connection-status path. On
that main path it rounds the current normalized city coordinates, samples one world-view-dependent
alpha byte through `world_view_query_city_label_alpha_byte_from_normalized_xy_and_view_scalars`
`0x0043ad50`, and then tries to resolve one linked station-or-transit site through the active
selection or scenario fallback object. When that linked-site path succeeds, the formatter forces a
highlighted top color lane with alpha `0xff` and appends localized id `207` `(Connected)`; when it
does not, it only reuses the sampled byte from `0x0043ad50` when that value is nonzero and below
`0xff`. The tail also splits cleanly now: one branch returns style code `1`, while the other derives
one label-priority scalar from `[this+0x25e]` or the piecewise-scaled `[this+0x312]` path, clamps
that priority to `0x95`, resolves the final style through `0x0053de00`, and returns style code `3`.
#### Ownership side
One reusable site helper is grounded now too.
@ -60,12 +73,17 @@ The city bonus formatter no longer depends only on
The reusable bridge between the status formatter and the
company news lane is now bounded too. `city_connection_bonus_build_peer_route_candidate` at
`0x004046a0` reuses `city_connection_bonus_select_first_matching_peer_site` with both selector
flags forced on, samples the selected peer's derived coordinates through `0x0047df30` and
`0x0047df50`, and then either tries the shared heavy builder
`city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0` or falls
back to the smaller wrapper `city_connection_bonus_try_compact_route_builder_from_region_entry`
`0x00404640` before handing the result back to the company-side announcement sweep at
`0x00406050`. The score side of that announcement lane is tighter now as well:
flags forced on, rounds both the source-city and selected-peer normalized coordinates through
`0x005a10d0`, and then first tries the shared heavy builder
`city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0` when the
caller already supplied a live route-anchor tuple. When that direct attempt does not apply or no
peer survives, it falls back to the smaller wrapper
`city_connection_bonus_try_compact_route_builder_from_region_entry` `0x00404640`; and when both
early attempts fail it builds one mixed 10-byte candidate list from the dense pair store
`0x006cfcb4` and the route-entry store `0x006cfca8`, marks only route-anchor-eligible class-`2`
sites through the `0x0048a1c0/0x0048a1a0/0x0048f290` route-anchor tests, and then retries
`0x00402cb0` with the best surviving span-ranked candidate. The score side of that announcement
lane is tighter now as well:
`city_compute_connection_bonus_candidate_weight` at `0x004010f0` provides the per-city opportunity
weight, `company_query_min_linked_site_distance_to_xy` at `0x00405920` provides the nearest
linked-site distance term, `company_count_linked_transit_sites` at `0x00426590` provides one of
@ -97,14 +115,32 @@ The reusable bridge between the status formatter and the
narrower city-connection public-opinion lane or as part of a broader management-attitude family,
not the ownership of the connection-bonus formatter, peer-route candidate path, or company news
gate.
The ordinary `StationDetail.win` caller strip is tighter now too. In the non-scenario, non-class
`3/4` branch, `shell_station_detail_window_refresh_controls` `0x00506610` rebuilds the nearby-site
lane first through `shell_station_detail_refresh_nearby_structure_jump_rows` `0x00505470`, then
rebuilds the paired hauled-traffic widgets through two calls to
`shell_station_detail_build_to_from_haul_summary_widget` `0x00505150`. That hauled-traffic helper
does more than publish a heading: it normalizes the incoming float lane into a bounded ten-step
fill count, resolves per-step styles through `0x0053de00/0x00552560`, and on first build wires the
matching `0xb3f6` or `0xb3f7` click target back to
`shell_station_detail_present_to_from_haul_stats_popup` `0x00504770` through `0x00540120`. The
nearby-site helper has a similarly concrete split now: for each of the fixed five categories it
counts entries through `0x0047dc90`, emits the descriptive text block through `0x0051b700 ->
0x0053f9c0`, and then builds the paired jump-control payload through `0x0053b070 -> 0x0055a040 ->
0x0053f9c0`, with text rows under `0xb40a..0xb40e` and jump controls under `0xb410..0xb414`. So
the remaining uncertainty in the ordinary branch is no longer the ownership of those lanes; it is
the broader user-facing meaning of later callers above the row callbacks.
#### Route-list side
The neighboring helper
`placed_structure_append_unique_route_entry` at `0x0047f010` is now grounded as the
append-if-missing builder for the six-byte route-entry list rooted at `[site+0x462]` and
`[site+0x466]`. That matters here because the directional overlay query at `0x0047e690` consumes
the same list, so the remaining uncertainty is no longer list ownership. It is down to the exact
semantics of each entry's `u32` payload.
`[site+0x466]`. One tighter boundary closes the overlay-side uncertainty further: the directional
overlay query at `0x0047e690` only consumes the leading `u16` peer-site key when it walks that
list and does not currently read the trailing `u32` companion payload at all. So the remaining
uncertainty is no longer route-list ownership or overlay dependence on that payload; it is only
the broader meaning of the payload for other caller families.
#### Route-entry and Cache Side
The adjacent helper strip is tighter now too.