36 KiB
Input, Save/Load, and Simulation: Event Editors, CompanyDetail, and LoadScreen
Event Editors and Scenario Action Windows
The event side is tighter too:
that 0x00433130 pass in turn materializes each live event record through
scenario_event_refresh_runtime_record_from_packed_state 0x0042db20. Current shell-side xrefs
now tighten that event branch too: the first rebuilt linked row family under 0x0042db20 aligns
with the standalone condition list later queried by EventConditions.win, while the second
rebuilt family aligns with the four grouped effect lists later deep-copied through
scenario_event_clone_runtime_record_deep_copy 0x0042e050 during event duplication and effect
staging. The condition side is tighter now too: the tiny helper cluster
0x0042df30/0x0042df70/0x0042dfb0/0x0042dff0 is no longer just "some adjacent list scans".
Current evidence bounds it as four predicates over the standalone 0x1e-row condition list,
testing class bits 0x01, 0x02, 0x04, or any of those bits in the static table
0x005f3e04 + id*0x81, with special fallback checks through event fields [event+0x7f9],
[event+0x7fa], and [event+0x7f0] == 0x63. The shell side is tighter too: vtable slot
0x005d0cd8 now binds shell_event_conditions_window_handle_message 0x004d59e0, and vtable
slot 0x005d0cf8 binds shell_event_effects_window_handle_message 0x004d7060. The effects
side is tighter too: the lower helper trio is no longer anonymous. 0x004d5d00 now reads as the
effect-type selector refresh under control family 0x4fb2, 0x004d5f50 reads as the selected
effect parameter-row repaint, 0x004d6090 is the heavier staged-effect editor refresh over the
0x4fc7/0x4fce/0x4ff6/0x4ff9/0x4ffc/0x5041/0x5044/0x5046/0x5047 bands, and 0x004d67f0
commits the current editor state back into the staged effect row at [this+0x78]. The verb side
is tighter now too: shell_open_event_conditions_modal_and_return_result 0x004d9dc0 and
shell_open_event_effects_modal_and_return_result 0x004d9e40 are the shared modal openers
above the two editor windows; 0x004da640, 0x004da700, and 0x004d9ed0 now read as the add,
edit, and remove verbs for standalone condition rows; 0x004da7c0, 0x004da860, and
0x004da920 are the matching add, edit, and remove verbs for grouped effect rows; and
0x004d8120 is now the heavier condition-row list panel refresh those condition-side verbs
re-enter after mutation. The conditions-side refresh split is tighter too: 0x0042d700
aggregates standalone condition-list class or modifier flags, 0x0042d740 aggregates grouped
effect-row type flags for one selected grouped list, 0x004d9970 owns the condition-class
summary and grouped-row status bands, 0x004d77b0 owns the grouped summary-band affordance gate
for 0x4fed..0x4ff0 when selector 0x5000 lands on 0x5002, 0x004d9d10 owns the smaller
grouped-effect territory-target affordance on control 0x500b, 0x004d9f50 owns the selected-event mode
strip and summary text panels, and 0x004d9390 is the mode-dependent detail-row switch beneath
that strip. 0x004da0f0 is tighter too: selector 0x5001 now has the strongest current
RT3.lng fit as the condition-side Test against... mode above 0x004d9970, while selector
0x5002 has the strongest current fit as the grouped-effect-side Apply effects... mode.
That 0x5002 branch now clearly builds control 0x5014 from RT3.lng 1160..1164 as to the company/player/player (i.e. chairman)/territory for which the condition is TRUE before
enabling the adjacent 0x5005, 0x500a, and 0x5014..0x501c family. The strongest current
RT3.lng fit for the remaining visible target-scope strip is now 0x5015 = to the whole game,
0x5016..0x5018 = to all/human/AI companies, 0x5019 + 0x500b = to territories, and
0x501a..0x501c = to all/human/AI players; the grouped effect-row type mask matches that split
directly through bits 0x08, 0x01, 0x04, and 0x02. The
selected-event strip is tighter now too: 0x004db120 is the broader selected-event repaint and
navigation refresh above those smaller helpers, 0x004db520 and 0x004db5e0 are the previous
and next selected-event stepping verbs, 0x004db8b0 is the add-or-clone event modal helper,
0x004dba90 is the rename verb, 0x004d9360 is the delete verb, 0x004db6a0 is the live
selected-event id setter behind control 0x4e84, and 0x004db6f0 is the callback-binding plus
pending-selection bootstrap path that seeds the strip during window bring-up. The larger
dispatcher at 0x004dbb80 now makes the strip explicit: 0x4e85..0x4e8a are previous, next,
add blank, clone selected, rename, and delete event, while the later grouped band commits current
summary state through 0x004d8d50 before changing grouped selector [this+0x9c] via 0x004dbf93.
The selection bootstrap side is tighter too: 0x004daf40 is now the placeholder reset helper for
the selected-event summary controls 0x4eaf, 0x4eac, 0x4ed9, 0x4edb, and 0x4fdf..0x4fe2.
The grouped target-scope side is tighter too: 0x004d8ea0 now reads as the commit helper for current
selected-event text panels before selection or grouped-action changes, 0x004d8d50 now records
the hidden selector family 0x5006..0x500e -> 0..8, and 0x004dab60 projects that ordinal
one-to-one onto the visible grouped-effect target-scope display strip 0x5014..0x501c. That
split is firmer now: 0x5006..0x500e are the canonical hidden selectors that get stored into
[event + group + 0x7fb], while 0x5014..0x501c are the visible mirror rows republished from
that same ordinal rather than a second independently named selector family. The grouped row and
stored-summary refresh side is tighter too: 0x004d88f0 is now the selected grouped-effect
row-list renderer for 0x4ed5, formatting the grouped 0x28-byte rows through RT3.lng
1154..1159, and 0x004da9a0 is the current grouped-summary-state republisher that reloads
0x500a, 0x500b, and visible action selection 0x5014..0x501c from [event + group + ...]
before tailing back into 0x004da0f0,
0x004dbfca as the grouped target-scope mode selector that persists the chosen control id into
0x00622074, with 0x5001/0x5002 now strongest-fit as Test against... and
Apply effects..., 0x004dbeeb as the pending shared summary-text triplet publish helper for
0x4eac/0x4ed9/0x4edb,
0x004d91e0 as the selected-event summary-header and grouped-mode commit helper above
0x004d8d50, and 0x004dbe7a as the narrower 0x4ec6/0x4ec7 choice-event single-player-only
warning modal branch rooted at RT3.lng 3887. The remaining gaps on
this lane are narrower again because the grouped-band 0x4dc09c table now closes one earlier
overclaim: controls 0x5001/0x5002 are the only 0x4fed..0x501c entries that route into
0x004dbfca on the 0xcf side, while visible rows 0x5014..0x501c only route to the smaller
0x004d9d10 affordance path and the rest of 0x4ff1..0x5013 are default no-ops. The open
question is therefore no longer whether those visible target-scope rows are direct selector verbs;
current evidence says they are not.
The local slot records are rooted at
[world+0x69d8],
[slot+0x01] polarity and the external role gate at [world+0x0bc3+slot*9] are now grounded, and
[slot+0x03] now looks like the distinguished primary-human-seat marker because current grounded
writes seed it only on slot zero and later logic moves it solely by whole-record compaction. The
open question is no longer whether the seeded trio lands in the visible shell company roster;
current evidence says it does, and ordinary Start New Company now looks like a fresh-company
allocator through start_new_company_dialog_commit_create_company and
start_new_company_request_create_company, not like the path that claims one of the seeded named
railroads. The immediate post-roster station branch is now clearly separate: current grounded
resource names and handlers put mode 8 on StationDetail.win, mode 5 on StationList.win,
and the subordinate modal selector helper on StationPick.win through
shell_station_pick_window_open_modal_and_return_selected_station_id above
shell_station_pick_window_construct. The company-side ownership question has therefore moved
down a layer rather than staying open. We now have a recovered CompanyDetail.win
owner family through shell_company_detail_window_refresh_controls,
shell_company_detail_window_construct, and shell_company_detail_window_handle_message; the
same owner now has one broader bounded read-side lane too, because control 0x9470 uses
shell_company_detail_render_financial_history_panel to draw the five-step Revenue or Expenses or
Interest or Profit or Lifetime strip, sibling control 0x9471 reuses
shell_format_company_financial_summary_card through
shell_company_detail_render_company_summary_card, controls 0x947d and 0x947e now ground a
bond maturity and repay panel through shell_company_detail_render_bond_maturity_and_repay_panel,
control 0x9488 now grounds the debt or credit or rate summary block through
shell_company_detail_render_debt_credit_and_rate_summary_panel, control 0x948a now grounds the
share-value and dividend-payout block through
shell_company_detail_render_share_value_and_dividend_summary_panel, while the broader six-row
per-share stock-data family is now bounded under shell_format_company_stock_data_panel, and the
adjacent territory selector lane is bounded through
shell_company_detail_select_territory_access_row,
shell_company_detail_render_territory_access_row,
shell_company_detail_sync_selected_territory_from_picker, and
shell_company_detail_refresh_selected_territory_access_summary; the first finance-action layer
beneath it is bounded through the bond, stock-issue, stock-buyback, and dividend-rate helpers; the
territory-access side is bounded too through
shell_company_detail_refresh_selected_territory_access_summary,
shell_company_detail_buy_territory_access_rights_flow, and the underlying company access-rights
helpers; and the full takeover and merger vote-result lane is now grounded through
shell_resolve_chairmanship_takeover_vote_and_commit_outcome,
shell_present_chairmanship_takeover_vote_outcome_dialog,
shell_resolve_merger_vote_and_commit_outcome, and shell_present_merger_vote_outcome_dialog.
The remaining company-side uncertainty is therefore narrower than before: the broader support and
valuation side is now tighter too because
company_compute_cached_recent_per_share_performance_subscore,
company_compute_five_year_weighted_shareholder_return, and
company_compute_public_support_adjusted_share_price_scalar bound the recent per-share
performance and investor-support/share-price blend beneath those vote resolvers; the recent
per-share feeder now has a grounded four-lane tail too, with current partial-year weight
(5 * [world+0x0f]) - 5, prior full-year weights 48/36/24/12 on 0x1f/0x1e, dividend
non-decline pair weights 9/8/7/6 on 0x20, lane weights 40/10/20/30, the startup age ramp
0/0/0/100 -> 25/25/35/100 -> 50/50/65/100 -> 75/75/85/100 -> 100/100/100/100, a strongest-lane
*1.25 boost, a weakest-lane *0.8 reduction, and separate bounded-intermediate versus final
difficulty applications under 0x005f33b8; the next consumer 0x00424fd0 is also tighter now,
with the young-company interpolation against [company+0x57], caller pressure clamped to
[-0.2, 0.2], one (shares / 20000)^0.33 share-count growth term, and the later threshold
ladder 0.6 / 0.45 / 0.3 / 1.7 / 2.5 / 4.0 / 6.0 before the issue-0x37 multiplier,
scenario_state_compute_issue_opinion_multiplier now bounds the
next layer of optional company, chairman, and territory-specific opinion overrides on the active
scenario state, and the broader stat-reader family around
company_read_control_transfer_metric_slot and
company_read_year_or_control_transfer_metric_value is no longer just a merger-premium helper.
Current grounded callers show the same metric family feeding the annual shareholder-revolt and
creditor-liquidation lane surfaced by localized ids 300..304, while the debt-side shell and
bond lane now separately close 0x38 as Credit Rating and 0x39 as Prime Rate. That means
the remaining gap is now mostly gone on the UI side too: issue 0x37 is already bounded to the
same investor-confidence family as the equity-support and governance-pressure paths, and current
grounded UI evidence still stops at the investor-attitude sentence family rather than one
standalone caption. The calendar side is tighter now too:
[world+0x15] is the absolute counter for the same mixed-radix 12 x 28 x 3 x 60
year-plus-subfield tuple packed by 0x0051d3c0 and unpacked by 0x0051d460, not just a vague
“calendar-like” blob. The TrackLay.win family now clearly owns Lay single track. Lay double track.
and Bulldoze as its three primary modes, its bridge selector, its wrapped frequency preferences,
and a strongly aligned pair of Auto-Hide Trees During Track Lay and Auto-Show Grade During Track Lay toggles; the StationPlace.win family now clearly owns its six top-level category
buttons, the station-style scroller, and the station-rotation controls. The older Building placement center string 671 no longer looks like a live StationPlace control label in the current
recovered flow, because the active constructor, preview, refresh, and dispatcher paths all use
neighboring ids such as 669 and 2208 without a direct recovered lookup of 671. On save or load the
broad serialize-versus-restore split is now grounded, the non-Quicksave .gmp/.gmx/.gmc/.gms
families are separated, and the auxiliary .gmt path is at least bounded to the preview-surface
side owner. The higher-value shell-facing gap has therefore shifted upward to the remaining
semantics of the post-load generation phases, the later recurring structure-population cadence,
the deeper vote-weight formulas inside takeover and merger resolution, and the still-open meaning
of the packed simulation calendar tuple.
CompanyDetail and Section Ownership
The shell detail family now has an explicit
section-selector lane in addition to the read-side panels already mapped. Controls
0x9472..0x9475 directly select the four visible CompanyDetail sections through 0x006cfe60,
0x9476..0x9479 are the companion visual controls for that same tab strip, and section 0 is now
bounded more tightly as the chairman or governance slice around the portrait-backed chairman band
on 0x9480 plus the dynamic overview widget 0x947f. That widget is no longer just a vague
status line: the section-0 refresh binds it through a dedicated stack-built dynamic text path,
and the strongest current shared formatter candidate is
shell_format_company_governance_and_economy_status_panel at 0x004e5cf0, which first renders a
five-line company-metric preamble through localized ids 1211..1215: Revenues from slot
0x2c, Profits from slot 0x2b, Load miles hauled from slot 0x17, Revenue per load mile from the derived slot 0x2c / slot 0x17 branch, and Average speed from slot 0x26
rendered through 1216 %1 m.p.h.. It then splits the governance summary more concretely: no
linked chairman emits 3045, wholly owned companies emit 3046 for the scenario-selected
chairman or 3047 for another linked chairman, and investor-owned companies emit the
investor-attitude lines 3048/3049 with one adjective from the table at 0x00622170. That
branch is no longer using unnamed helpers either: company_get_linked_chairman_profile_record
0x00426ef0 resolves the linked chairman profile and chairman_profile_owns_all_company_shares
0x004768c0 is the full-ownership test behind the 3046/3047 split. The salary side is tighter
too: the formatter computes one signed delta from [company+0x14f] and [company+0x0d59], then
chooses 3050..3052 for the scenario-selected chairman or 3053..3055 for another linked
chairman depending on whether that delta is negative, positive, or zero. The bonus line is
narrower still: it only appears when the display year matches [company+0x34f], using amount
[company+0x353] with 3056 or 3057. It then appends the
1218 Economy status - %1. tail caption and stages the adjacent selected-company report or
list help-title pairs 1219/1220 Income Statement, 1221/1222 Balance Sheet,
1223/1224 Haulage Report, 1225/1226 Stock Report, 1227/1228 Train List,
1229/1230 Station List, 1231/1232 Industry List, and 1233/1234 Cargo List.
Current evidence still does not recover separate CompanyDetail.win action controls for that
strip under shell_company_detail_window_handle_message, so it currently reads as staged
overview text or help content rather than as a closed launcher family. The direct 0x947f
formatter call is still indirect, but the widget boundary is tighter too: the generic shell
helpers shell_control_refresh_matching_dynamic_text_payload 0x00540a47 and
shell_control_release_dynamic_text_payload 0x005639d2 now show that type 0x6f controls
free or swap one heap-backed text payload and then short-circuit as a special dynamic-text case,
which strengthens the reading of 0x947f as a display-only overview widget rather than a normal
callback control. One adjacent boundary is tighter now too: the broader overview wrapper at
shell_render_company_overview_panel_header_and_optional_change_affordance 0x004e5a80 owns
the fallback no-company texts 1210, 3043, and 3888, styles controls 0x3f06 and 0x3f07,
and on the narrower selected-company branch appends 3044 Click to change company name and logo. plus the neighboring 1941 Change affordance before falling through into the shared
0x004e5cf0 text body. That keeps the name/logo affordance outside the ordinary
CompanyDetail.win action dispatcher and makes the 0x947f alignment cleaner. The message-side
action band is tighter too: 0x94b5 grounds
territory-access purchase, 0x94b6 grounds bankruptcy, 0x94cf..0x94d2 ground bond issue, stock
issue, stock buyback, and dividend-rate changes, 0x9493 routes into the destructive
company-clear helper that deactivates the selected company and clears chairman/share links,
0x94d6 grounds bankruptcy, 0x94d7..0x94da ground bond issue, stock issue, stock buyback, and
dividend-rate changes, 0x94db grounds merger, 0x94dc grounds resignation, and 0x9538 grounds
chairmanship takeover. The finance-side dialog family is tighter too: the bond-issue lane now has
the dedicated modal renderer shell_company_detail_render_issue_bond_offer_dialog 0x004c3560
for underwriter terms 968..972, the stock-issue lane has
shell_company_detail_render_issue_stock_offer_dialog 0x004c3b50 for the staged offer lines
975..978, and the buyback lane has
shell_company_detail_render_stock_buyback_offer_dialog 0x004c4300 for broker lines
981..984. The compact summary card on sibling control 0x9471 is tighter too:
shell_format_company_financial_summary_card at 0x004bfb30 now clearly renders Cash:,
Revenue:, and Profits: from company slots 0x0d, 0x2c, and 0x2b, rather than one looser
unnamed finance block. The dividend lane is now split the same way:
shell_company_detail_setup_dividend_rate_adjust_controls 0x004c4c70 binds the paired adjust
controls 0x99e8 and 0xc0f9,
shell_company_detail_render_change_dividend_rate_dialog 0x004c4e30 renders localized ids
988..990, and
shell_company_detail_handle_change_dividend_rate_dialog_message 0x004c5140 clamps the staged
dividend rate against company_compute_board_approved_dividend_rate_ceiling 0x00426260 and
raises localized id 991 when the board refuses a higher dividend, all before the existing
company commit path. All four finance verbs now converge through the shared
callback-driven modal opener shell_open_custom_modal_dialog_with_callbacks 0x004c98a0, which
is also reused by the multiplayer staged text-entry lane. The front controls in section 0 are
tighter too: 0x948b is a
tutorial-guarded escape or back control that shows localized id 3724 This option is disabled in the tutorial. before falling back to the shell detail-manager escape path, 0x9491 and 0x9492
only restyle the paired visuals 0x948f and 0x9490, and 0x9494 opens localized id 3635
Enter the amount that your company's cash should be and writes the accepted value directly into
the selected company cash pair. The neighboring debt section is tighter now too: controls
0x947d and 0x947e no longer read as one-off bond widgets, but as the owners of two repayable
bond-slot row bands, 0x94e8..0x950f and 0x9510..0x9537. Those row controls now clearly
converge on the same repayment path in the message dispatcher: they reject unaffordable repayment
through localized id 2990, open the early-repayment confirmation rooted at 2991, and then
either commit through company_repay_bond_slot_and_compact_debt_table 0x00423d70 or package
the request through the multiplayer shell transport. The render-side owner is tighter too:
shell_company_detail_render_bond_maturity_and_repay_panel formats Due %1 and Repay this bond. for the selected debt slot while the tiny binder
shell_company_detail_bind_bond_row_band_for_active_panel switches between the two row bands.
Current 0xcb dispatch does not treat 0x948f, 0x9490, 0x94d4, or 0x94d5 as standalone
action cases. The message-side jump table now makes that passive/action split explicit too: in the
dispatch byte map rooted at 0x004c6640, controls 0x94d6..0x94dc map to cases 0x06..0x0c,
control 0x9538 maps to case 0x0d, and the neighboring companion rows 0x94d4 and 0x94d5
stay on the default path. The refresh-side ownership is tighter too: the helper now explicitly
loops over 0x94d4..0x9537 as the selected-company-owned band and over 0x9538..0x959b as the
linked-chairman-owned band, and those two loops do not use the same style polarity.
0x94d4..0x9537 take style 0x65 when the selected company matches the scenario-selected
company and 0x87 when it differs, while 0x9538..0x959b take style 0x87 when the selected
company's linked chairman matches the scenario-selected chairman and 0x65 otherwise. The
selected-company action side
is tighter now too: scenario toggle 0x006cec78+0x4a8f re-enables bankruptcy 0x94d6 together
with passive companion row 0x94d4, +0x4a8b re-enables issue bonds 0x94d7 together with
passive companion row 0x94d5, +0x4a87 re-enables stock issue and stock buyback
0x94d8..0x94d9, +0x4a93 re-enables dividend 0x94da together with the same passive
companion row 0x94d5, +0x4adb re-enables merger 0x94db, +0x4acb re-enables resignation
0x94dc, and +0x4acf re-enables chairmanship takeover 0x9538. That makes 0x94d4/0x94d5
read more like passive companion or heading widgets than hidden verbs. The constructor boundary
is tighter too: current CompanyDetail.win setup still only binds explicit callbacks for
0x9470, 0x9471, 0x947d, 0x947e, and 0x948c..0x948e, not for the wider section-0 row
bands. That keeps the remaining 0x94d4..0x959b content looking more like resource-defined
display rows that are gated and restyled by refresh than like individually code-rendered widgets.
That leaves the main remaining CompanyDetail-specific shell edge at the exact 0x947f formatter
binding plus the still-unsplit render-side governance rows inside 0x94d4..0x959b.
Adjacent LoadScreen.win Report Family
The neighboring shell lane around controls
0x3ef6..0x4073 is now separated from CompanyDetail instead of being treated as one more
extension of the 0x947f overview path. The real outer owner is
shell_load_screen_window_construct 0x004ea620, which binds LoadScreen.win, randomizes the
LoadScreen%d.imb background family, stores the singleton at 0x006d10b0, and seeds the first
visible page-strip controls. Above the older page-specific work, the real message owner is now
shell_load_screen_window_handle_message 0x004e3a80: it owns page id [this+0x78],
page-local substate [this+0x7c], page-kind [this+0x80], current company [this+0x88],
current chairman profile [this+0x8c], display year [this+0x9c], and the page-local report
row latch [this+0x118], then fans back into the shared selector
shell_load_screen_select_page_subject_and_refresh 0x004e2c10, the company-step helper
0x004e3a00, and narrower page branches such as 0x004e45d0. The matching render-side owner is
now bounded too: shell_load_screen_render_active_page_panel at 0x004ea060 formats the common
heading and panel frame, then switches on page id [this+0x78] and hands control down into the
active page body. That older branch is now demoted to what it actually is:
shell_load_screen_profile_stock_holdings_page_handle_message, the page-specific handler beneath
the stock-holdings slice. Inside that same family,
shell_load_screen_render_profile_stock_holdings_summary_panel at 0x004e5300 grounds the
selected-profile holdings page: it resolves the current chairman profile from [this+0x8c],
renders the top summary rows 1204 Stock Value:, 1205 Total Assets:, and
1206 Stock Holdings:, then walks the active company roster and formats one row per positive
holding through 1201 Click to view details on %1., 1207 %1 Shares, and 1208 %1 Value,
falling back to 1209 None when no positive holdings survive. It also appends 3029
Click to change player name and portrait. plus the adjacent 1941 Change affordance only
when the rendered profile matches the scenario-selected chairman. The earlier pages are tighter
now too: 0x004e68e0 is the selected-company financial ranking page using the active company
roster plus 1235..1245 for revenue, profit, cash, track mileage, and report affordances; and
0x004e6ef0 is the active-chairman wealth ranking page using the chairman profile collection
plus 1237, 1241, 1246..1250 for cash, stock, total, and purchasing-power style comparisons.
The later sibling renderers are broader than that one holdings page now too: 0x004e7670 is the
selected-company train list page using 1235..1267, 0x004e8270 is the selected-company
building list page using 1268..1278, 0x004e8bb0 is the selected-company station list page
using 1279..1288, and 0x004e9460 is the map-wide cargo list page using 1289..1298 over the
live candidate collection rather than one company roster. The last broad early-page owner is
tighter now too: 0x004e9b20 is the shared multi-year company report-table renderer for page
4 Income Statement, page 5 Balance Sheet, and page 6 Haulage Report, all driven from
0x004ea060 with one caller-supplied mode byte and yearly company rows built through
company_read_year_or_control_transfer_metric_value. The row families are bounded too:
income-statement rows 1301..1315, balance-sheet rows 2816 and 1317..1322, and
haulage-report rows 1323..1335. The only special rows inside that family are now tighter too:
0x00425880 and 0x004258c0 provide the negative-cash and positive-cash interest-rate inserts
for the %1/%2 placeholders in strings 2815 and 2816, so they are no longer anonymous
private math blobs. The adjacent early siblings are tighter now too: 0x004e5130 is the
selected-company Stock Data page wrapper that falls back through 1299 and otherwise reuses
0x004c0160 to render the Largest Shareholders, Shares, and Per Share Data family;
0x004e6ef0 is the Player List page; 0x004e5300 is the Player Detail holdings page; and
0x004e51ea is the Game Status briefing panel that pulls current scenario briefing text from
the live scenario text store and appends the 1772/1773 Briefing affordance. The active-page
renderer at 0x004ea060 is now tighter too because its 13-byte page descriptor table at
0x006220a0 has been decoded directly as { page kind, title string id, 0x3ef8 backlink page, selected-company-header flag }. The currently grounded rendered title order is:
XXX, COMPANY OVERVIEW, COMPANY LIST, INCOME STATEMENT, BALANCE SHEET,
HAULAGE REPORT, STOCK DATA, PLAYER LIST, PLAYER DETAIL, GAME STATUS,
TRAIN LIST, TRAIN DETAIL, STATION LIST, STATION DETAIL, CARGO LIST,
and INDUSTRY LIST. Its live body bindings are now bounded too: page 0 falls back to
1203 Unable to display page, page 1 is the company overview wrapper, page 2 is the
company list page, pages 3..5 are income statement, balance sheet, and haulage report, page
6 is stock data, page 7 is player list, page 8 is player detail, page 9 is game status,
page 0x0a is train list, page 0x0b currently falls back to 1203, page 0x0c is station
list, page 0x0d currently falls back to 1203, page 0x0e is cargo list, and page 0x0f
is industry list. The row-click path is tighter now too: player-list rows re-enter page 8
directly, but train, station, and industry rows leave LoadScreen.win through the shell
detail-panel manager at 0x004ddbd0 instead of switching to title-table pages 0x0b or
0x0d. Page 0 is tighter now too: its descriptor is kind 0, title 1200 XXX, backlink
0, and header flag 0, and no current post-constructor selector path has been recovered for
it. The descriptor side now also bounds the only known reverse route for the dormant detail
titles: 0x3ef8 is the table-driven backlink affordance, so if page 0x0b or 0x0d were ever
selected, the known reverse path would return to train-list page 0x0a or station-list page
0x0c respectively rather than through a separate detail-only owner.
The launcher side is tighter too: current grounded shell_open_or_focus_load_screen_page
callers cover pages 1, 2, 3, 4, 5, 6, 7, 9, 0x0a, 0x0c, 0x0e, and 0x0f,
and no current recovered opener or row-click route selects 0x0b or 0x0d. So the
LoadScreen.win family now has a much cleaner shape: one outer message owner
0x004e3a80, one active-page render owner 0x004ea060, and then the narrower page-specific
handlers and renderers beneath them. The launcher side is tighter now too: 0x004e4ee0 is the
shared open-or-focus ledger-page owner above this family. Outside sandbox it either re-enters
shell_load_screen_select_page_subject_and_refresh on the live runtime at 0x006d10a8 or
allocates that transient runtime, seeds it through 0x004e4b10, and enters the visible modal
loop; inside sandbox it raises localized id 3899 The ledger is not available in sandbox mode.
instead.
The direct shell-command strip above that opener is now explicit too: 0x00440700..0x0044086e
are just tiny scenario-present -> open page wrappers for pages 1, 3, 4, 5, 6,
0x0a, 0x0c, 0x0f, 0x0e, 2, 7, and 9 respectively. So the recovered launcher range
is no longer only “callers of 0x004e4ee0” in the abstract; each of those small shell-command
stubs now just forwards one fixed page id into the shared opener.
instead. That narrows the remaining LoadScreen.win gap again: TRAIN DETAIL and
STATION DETAIL now read as dormant title-table entries unless some still-unrecovered nonstandard
selector reaches them. The live auto-load boundary is tighter now too: hook-driven
shell_transition_mode(4, 0) now completes old-mode teardown, reconstructs and republishes
LoadScreen.win, and returns cleanly, but the later post-transition service ticks still keep
[0x006cec78] = 0, [shell_state+0x0c] on the same LoadScreen.win singleton, and
[LoadScreen.win+0x78] = 0 through at least counts 2..8. So the next runtime edge is no
longer the old mode-4 teardown or publish band; it is the LoadScreen.win message owner
0x004e3a80 itself, because later service alone is not promoting the plain load screen into the
separate startup-runtime object path. One later runtime probe did not actually reach that edge:
the 0x004e3a80 hook installed, but the run never produced any ready-count, staging,
transition, post-transition, or load-screen-message lines, only ordinary shell node-vcall
traffic. So that result is now treated as a gate-or-cadence miss rather than as evidence against
the LoadScreen.win message path itself. The newer shell-state service trace tightens it again:
on a successful staged run the later service ticks do execute in mode_id = 4, but the
0x004e3a80 message hook still stays silent while the state remains frozen in the plain
LoadScreen.win shape. So the next runtime boundary is now the shell-runtime prime call
0x00538b60 beneath shell_state_service_active_mode_frame 0x00482160, not the message owner
alone. The first direct 0x00538b60 probe run is not trustworthy yet, though: it stopped
immediately after the first shell-state service-entry line, before any ready-count or
runtime-prime entry logs. So that result is currently treated as probe validation work, not as a
real boundary move inside RT3. The static service branch is conditional too: 0x00482160 only
enters 0x00538b60 when [shell_state+0xa0] == 0, so silence from the runtime-prime hook does
not yet prove the shell stops before that call unless the service-entry logs also show the +0xa0
gate open. The newer run now closes that condition: [shell_state+0xa0] is 0, and the
0x00538b60 runtime-prime hook enters and returns cleanly. The newer run closes the next owner
too: 0x00520620 shell_service_frame_cycle also enters and returns cleanly on the same frozen
mode-4 path, and the logged fields match its generic branch rather than a startup-promotion
lane ([+0x1c] = 0, [+0x28] = 0, flag_56 = 0, [+0x58] pulsed then cleared, and
0x006cec78 stayed 0). The static body under the same owner is tighter now too: 0x00538b60
first re-enters 0x0054f6a0, refreshes the primary timed-text lane from [owner+0x1c] through
0x005386e0 when that deadline has expired, walks the registered shell-window list from tail
[owner+0x04] backward through +0x54 while servicing each node through 0x0053fda0 and
0x0051f1d0, and only then conditionally presents the secondary and primary text lanes through
0x005519f0. So the next runtime boundary under the same shell-state service pass is now one
level deeper: the per-object service walker 0x0053fda0 beneath 0x00538b60. The newer run
closes that owner too: it enters and returns cleanly while servicing the LoadScreen.win object
itself, with field_1d = 1, field_5c = 1, and a stable child list under [obj+0x70/+0x74],
and its first child-service vcall target at slot +0x18 stays 0x005595d0. Since 0x006cec78
still stays 0 through those clean object-service passes, the next runtime boundary is now the
child-service target 0x005595d0, not the higher object walker. The newer child-service run
narrows that again: the first sixteen 0x005595d0 calls are stable child lanes under the same
LoadScreen.win parent, with [child+0x86] pointing back to the load-screen object,
field_b0 = 0, and a split where earlier children carry flag_68 = 0x03 and return 4 while
later siblings carry flag_68 = 0x00 and return 0. The static body matches that read too:
0x005595d0 is gated by 0x00558670 and then spends most of its work in draw or overlay
helpers 0x54f710, 0x54f9f0, 0x54fdd0, 0x53de00, and 0x552560, so it now reads as
another presentation-side service lane rather than the missing startup-runtime promotion. The
widened allocator-window trace then reconciled the runtime with
the static mode-4 branch one step further: the first transition-window allocation is 0x7c,
which matches the static pre-construct 0x48302a -> 0x53b070 alloc exactly, and the later
0x111/0x84/0x3a/0x25... allocations all occur before LoadScreen.win construct returns, so
they now read as constructor-side child or control setup. That means the allocator probe did not
disprove the still-silent startup-runtime slice; it simply exhausted its log budget inside the
constructor before the post-construct block. The later reset-at-return run is now the decisive
one: after LoadScreen.win construct returns there are still no further allocator hits before
publish and transition return, which matches the corrected jump-table decode because mode 4
does not own the 0x46c40 -> 0x4336d0 -> 0x438890 startup-runtime path.