Tighten multiplayer transport callback ownership

This commit is contained in:
Jan Petykiewicz 2026-04-06 20:34:16 -07:00
commit 5c192b0fa4
5 changed files with 684 additions and 116 deletions

File diff suppressed because one or more lines are too long

View file

@ -43,7 +43,50 @@ What this note is for:
- City-connection announcement and bonus lanes - City-connection announcement and bonus lanes
- Annual finance-policy thresholds and same-cycle reaction latches - Annual finance-policy thresholds and same-cycle reaction latches
Current bounded linked-transit cache outputs:
- peer row `+0x05`: route-step count from the tracker metric chooser
- peer row `+0x09`: normalized continuity share `(steps - mismatches) / max(steps, 1)`
- site cache `+0x12`: raw surviving linked-transit site-score total
- site cache `+0x0e`: continuity-and-step-weighted companion total
- site cache `+0x16`: promoted final autoroute site-ranking lane
- `company_compute_owned_linked_transit_site_score_total`: converts summed site `+0x12` totals
into the train-roster target through year and site-count ladders, plus the special build-`1.03+`
two-site distance branch
Current bounded compatibility impact:
- the pre-`1.03` versus `1.03+` tracker metric split mainly perturbs peer continuity and weighted
site ranking
- that means it can change which site `0x00408280` prefers and which peer `0x00408380` seeds into
a train route
- current evidence says it does not directly move the company train-pressure target in
`0x00408f70`, because that target sums raw site cache `+0x12` rather than the weighted `+0x0e`
or promoted `+0x16` lanes
Highest-value open edge: Highest-value open edge:
- The remaining semantic meaning of the annual finance ladders and governance-support slots, not - The remaining semantic meaning of the annual finance ladders is now narrower:
ownership of the verbs or shell windows. stat-family `0x2329/0x1d` is now bounded as current `Book Value Per Share` in the stock-issue
denominator path, `0x2329/0x0d` is now bounded there as the current cash gate before the
bond-rate-versus-support ladder, the broader support-adjusted share-price or public-support lane
is now bounded through `company_compute_public_support_adjusted_share_price_scalar` `0x00424fd0`,
and its immediate feeder is now bounded as
`company_compute_cached_recent_per_share_performance_subscore` `0x004248d0`, which weighs recent
`Revenue Per Share`, `Earnings Per Share`, and `Dividend Per Share` lanes `0x1e/0x1f/0x20`
against current `Book Value Per Share`, while `0x21` now routes through
`company_compute_five_year_weighted_shareholder_return` `0x004246b0` and its paired hidden
shareholder-payout lane `0x23`,
raw slot `0x09` aligns with the Income Statement fuel-cost lane surfaced by tooltip `1309`, and
derived slot `0x2b` now reads as the rolling net-profits lane. The main remaining gap is the
lower policy interpretation of how those lanes are blended inside the annual bankruptcy,
dividend, and city-connection ladders. The current strongest read is:
bankruptcy = sustained revenue-band-selected cash-and-debt stress plus repeated net-profit
failures and fuel burden, with one later deep-distress fallback when cash is below `-300000`
and the first three recent profit years all sit at or below `-20000`; stock issuance = a
valuation-versus-borrowing screen over
support-adjusted price-to-book against the highest live coupon band; dividend adjustment = a
weighted recent-profit-per-share target with a small-unassigned-share cash supplement before the
board ceiling clamp. The debt-news tail is also now explicit: it compares total retired versus
newly issued principal to pick `2882..2886`, and the stock-buyback tail separately publishes
`2887` from the accumulated repurchased-share count.

View file

@ -33,5 +33,181 @@ What this note is for:
Highest-value open edge: Highest-value open edge:
- The remaining owner-side callback roles behind the validated GameSpy packet branches and the - The remaining multiplayer edge is narrower now:
exact user-facing meaning of the selector-view sample or companion fields. the status-route callback vector is bounded through selector-text or averaged-sample publication,
control-id-list seeding, scalar-query forwarding, and the validated cookie or extended-payload
callbacks. The selector-view sidecar is tighter too: `[entry+0x80]` now reads as the averaged
millisecond probe sample and `[entry+0x54]` as the displayed version/build companion integer from
the local `X...X|%d` marker family. Separately, the route-callback side now has its own compact
GameSpy-style server or route descriptor family with primary and optional secondary endpoint
tuples plus keyed fields like `hostname`, `gamever`, `numplayers`, and `numservers`, feeding the
route-binding compatibility gate. The compact decode owners are tighter too: `0x5907d0` is now
the allocate-and-append lane for self-consistent compact payloads, while `0x590d00` is the keyed
upsert-by-primary-endpoint lane that reuses an existing descriptor when one already matches and
then notifies the transport owner callback. The route-callback-table runtime above that decode
path is tighter too: `0x5905e0` now constructs one transport-owned callback-table block,
`0x5906f0` tears down the decoded schema dictionary rooted at `[this+0x08]`, `0x590540/0x5905a0`
acquire and release refcounted shared schema strings through the global pool, and `0x5908c0`
now reads as the live receive/decode state machine serviced by `0x591290` in table states `2/3`.
The higher transport bring-up split is tighter too: `0x596090` now clearly constructs
`[transport+0xba4]` through `0x5905e0` with owner callback `0x595a40`, then seeds the local
field-cache family `[transport+0x1724]` through `0x5a08f0` with helper `0x595b60`, and then
constructs `[transport+0x1164]` through the same `0x5905e0` path but with owner callback
`0x595bc0`.
The live-route lifecycle above it is tighter too: `0x590740` now 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 route
handle into `[this+0x4a0]`, stages the initial outbound request, and seeds state `3` plus the
receive buffer, `0x5911e0` is the state-`2/3` socket-service wrapper above `0x5908c0`,
`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 openers are tighter now too: `0x5962e0` is the
field-subscription route-table owner above `[transport+0xba4]`, while `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`. That makes the remaining flag-bit question much narrower too: current
evidence now supports reading byte-`0x15` bit `0x1` as a primary-endpoint-seed or endpoint-only
source marker. In the `gsi_am_rating` dispatcher, clear-bit descriptors can take the richer
direct transition lane, while set-bit descriptors are pushed through the queued enrichment path
and later still suppress that direct transition even when the ready bit is present.
The adjacent capacity-descriptor side is tighter too: `0x595bc0` no longer reads as a vague
progress helper. Mode `0` is now clearly the live publish lane, and it lines up with the generic
descriptor append-notify owner callback at `0x590370`: it samples `hostname`,
`numwaiting`, `maxwaiting`, `numservers`, and `numplayers` from the current descriptor before
publishing an opcode-`2` descriptor block, while still carrying three cached side scalars from
the local capacity sidecar at `[transport+0x1778]`. That sidecar 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 the replay modes later consume the pointer through
`0x5933a0`. The negative result is stronger too: local text-side xrefs still show no direct
store to `[transport+0x1778]`, and a wider sweep also failed to show any obvious `lea`-based
replay-band writer. So the sidecar writer remains upstream of this leaf capacity publisher. The
payload split is tighter too:
`0x592ae0` now grounds opcode `2` as a seven-dword descriptor payload with an owned string slot
at `+0x08`, so live mode supplies a populated payload while modes `3` and `5` deliberately
enqueue an all-zero payload and reuse only the sidecar metadata in the wrapper. Those two modes
are tighter now too: they are not generic replay guesses, they are the live receive-state owner
callbacks emitted by `0x5911e0 -> 0x5908c0`. So they are best read as delayed metadata replays
over one cached work record, not over a standalone custom cache object. The producer side is
tighter now too: callback-table attach,
bound-route requests, selector-text route requests, and the type-`9` text fastpath all stage
that same `+0x0c/+0x10/+0x18` triplet through `0x5934e0`, so the capacity replay sidecar is
clearly reusing one broader transport work-record family. The generic owner-callback split above that family is tighter now
too: `0x590370` is the shared append-notify lane in mode `0`, while `0x590430` is the distinct
remove-notify-and-stage lane in mode `2`. So `0x595bc0` only owns the live append-style publish
path plus delayed replay modes `3/5`, not the remove path. The neighboring transient work queue
is tighter too:
`0x593330/0x593370/0x593380` now bound `[transport+0x1780]` as a real construct/clear/destroy
collection owner, while `0x5933a0`, `0x5934e0`, and `0x593570` now ground the remove, allocate,
and completion side over that same family. The small sibling `0x593400` is tighter too: it is a
pure uniqueness predicate over work-record 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
`0x5934c0` seeds that shared drain context id first, then the transport copies it into queued
work field `+0x0c` and active opcode-record field `+0x14` before the immediate-drain roots wait
on one shared disappearance test rather than one vague “drain until something settles” loop. The
currently grounded roots are `0x58df20`, the neighboring formatted selector-text publish path at
`0x58dfb0`, and callback-table registration at `0x58e200`. The callback-table attach side now
has a tighter active-opcode owner stack too: `0x5927b0` services and retires one active opcode
record, `0x592800` performs the broader context-or-idle retirement sweep, `0x5929a0` removes
active records by opcode type, and `0x5929f0` removes only opcode-`3` field-snapshot records
keyed by the subscribed callback-pair payload. That also corrects `0x595b80`: its final cleanup
is not a queued field-snapshot drain, but an active opcode-type-`3` purge beneath the field
cache reset.
The adjacent route-callback descriptor-table lifecycle is tighter too: `0x590410` now grounds
`[table+0x5bc]` as a real staged intrusive descriptor-list head, `0x590430` is the generic
remove-notify-and-stage path, `0x590490` releases that staged list, and `0x5904d0` releases the
active descriptor collection before tearing the staged list down. That also tightens
`0x5962e0`: its earlier “release active descriptors” step is now explicitly this same
`0x5904d0` family, not a vague collection clear.
The callback-table attach side now
constrains the same work-record metadata family a little further too: `0x593650` deliberately
duplicates one caller metadata dword into both work fields `+0x0c` and `+0x18`, while preserving
the remaining caller callback function pointer in `+0x10`. The lower opcode wrappers are tighter
now too: both `0x592a40` and `0x592a70` consume that staged triplet in the order `( callback fn
+0x10, callback companion +0x18, drain context id +0x0c )`. So the replay-side triplet is
clearly a broader transport callback-wrapper family, not one fixed route-only tuple. The type-`9`
text fastpath confirms the same split from the other side too: `0x593d00` only emits the
follow-on callback lane when work field `+0x10` is nonnull, and then forwards `(+0x10, +0x18,
+0x0c)` into `0x593170` as callback function, callback companion, and trailing drain context.
The nearby field-subscription side is tighter too: `0x592b50` now clearly uses
`[transport+0x1774]` as a cached progress percentage under the `[transport+0xba4]` callback
table, 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]`. 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 only
meaningful gap left on the capacity side is the still-unrecovered writer that stages
`[transport+0x1778]`. The carried sidecar fields are no longer anonymous: current evidence now
says they are just the same cached callback-wrapper triplet reused by other work-record families,
namely drain context id `+0x0c`, callback function `+0x10`, and callback companion `+0x18`.
The negative result is stronger now too: the neighboring replay-band fields
`[transport+0x176c]`, `[transport+0x1770]`, `[transport+0x1774]`, `[transport+0x177c]`,
`[transport+0x1780]`, and `[transport+0x1784]` all have direct local lifecycle owners, but
`[transport+0x1778]` still only appears as the single read in `0x595bc0`. So the remaining
writer is upstream and indirect rather than one ordinary direct field store in the local text
cluster. One adjacent staged-route callback is
tighter now too: `0x595860` is the submit-result handler below
`0x5958e0`, using the already-grounded third selector-generation counter at `[transport+0xac0]`
plus the target at `[transport+0xb48]` to choose whether staged route-callback traffic can
advance the route-mode state machine from mode `2` into `3` and later `4`. The counter beneath
that decision is tighter too: `0x594e30` now reads as a selector-view entry counter for slot `2`
flag bit `0x20`, optionally filtered by the current transport name buffer. The selector-view
mutation side beneath that callback family is tighter too: `0x594a30` is now the direct keyed
store remover, `0x594fb0` clears one selector-slot ownership pointer plus its slot-local flag
dword and drops the whole entry when no slots remain, `0x595010` rekeys one selector-view entry
under a new name while preserving the `0x40..` runtime band, and callback root `0x59f9c0` is now
bounded as the lane that clears one named selector-view slot, publishes callback slot `18`, and
can still re-enter the route-mode setter from the same slot-`2` state and generation gates. The
next adjacent callback roots are tighter now too: `0x5950a0` clears one selector slot from every
selector-view entry in the keyed store, `0x59fab0` is the rename or relabel sibling above
`0x595010`, `0x59faf0` updates one selector slot's fixed sample-text buffer and refreshes the
active selector object when present, and `0x59fb60` replaces one selector slot's name set,
requests the default profile-key bundle for that slot, and publishes callback slot `20`. Slot
`16` is tighter now too: current grounded caller `0x59f440` forwards the staged route-callback
payload handle from `[transport+0xb50]` through `0x592ea0` just before route mode `5`. The last
adjacent callback root in that block is tighter now too: `0x59fbd0` is the built-in
per-slot profile-key query sibling. It resolves the caller selector name into one slot index,
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.
The compact-header side is tighter 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. The variable tails are tighter too:
`0x58fe90` now validates the `0x40` inline keyed-property vector against the owner schema, and
`0x58fe50` validates the signed-`0x80` trailing string-pair tail before decode. `0x58ff60` then
grounds bit `0x02` as the inline secondary IPv4 dword branch, bit `0x20` as the paired
secondary-port word branch with owner-port fallback, bit `0x08` as one still-unresolved
auxiliary inline dword stored at `[descriptor+0x10]`, bit `0x40` as one inline keyed-property
vector decoded through the property-store writers, and signed bit `0x80` as one trailing
string-pair tail. The descriptor-state side is tighter too: queue insertion now cleanly splits
pending tags `0x4/0x8` from serviced-ready bits `0x1/0x2`, and the `gsi_am_rating` lane now
separates direct primary-endpoint handling from queued-descriptor handling. Current evidence now
also says byte `[descriptor+0x14]` is not queue-only: `0x58ff60` can also OR in bit `0x1` after
the inline keyed-property vector and bit `0x2` after the signed string-pair tail. Byte
`[descriptor+0x15]` bit `0x1` is source-side too, not queue-generated: it is explicitly seeded
by the primary-endpoint refresh path and preserved by the compact descriptor decode path before
the transport later uses it in the `gsi_am_rating` lane both to choose direct-vs-queued handling
and to suppress the direct `0x595dc0` transition even after 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, and `[descriptor+0x1c]` is now the special numeric scalar
behind the current `queryid`/`ping` fallback pair. The compact-only auxiliary dword at
`[descriptor+0x10]` is tighter in a different way: a local xref scan now shows it being preserved
by later generic preservation helpers such as
`generic_record_0x1c_deep_copy_with_owned_string_at_0x08` `0x591410` and the callback-marshaling
wrappers `0x591480` and `0x591510`, but still no dedicated semantic reader has been recovered.
So the main remaining uncertainty is the exact higher-level meaning of header bit
`[descriptor+0x15] & 0x1`, plus whether `[descriptor+0x10]` ever matters outside that
preservation path. The route-event dispatcher side is cleaner too:
the mode-`5` tails in both callback families do not copy a descriptor-local field. They mirror the
transport-staged companion dword at `[this+0x490]` into `[this+0x54]` and the local field-cache
family instead. The `gsi_am_rating` maintenance lane is tighter now too: it sorts the
primary-endpoint descriptor table through `0x590310` in mode `1` with key `gsi_am_rating`, then
selects the new head through `0x590480` rather than treating the table as pure insertion order.

View file

@ -65,6 +65,13 @@ Current bounded time-side cutover:
delegates through `0x0046a4b0` delegates through `0x0046a4b0`
- the recovered `>= 0x67`, `>= 0x68`, `>= 0x69`, and `>= 0x6a` caller pattern now lines up with - the recovered `>= 0x67`, `>= 0x68`, `>= 0x69`, and `>= 0x6a` caller pattern now lines up with
executable build values `1.03`, `1.04`, `1.05`, and `1.06` executable build values `1.03`, `1.04`, `1.05`, and `1.06`
- that makes the tracker cutover read more cleanly too:
`0x004a65b0` is now best treated as a pre-`1.03` versus `1.03+` route-metric compatibility
dispatcher, not as any gameplay-time or era-side mode switch
- the branch source is session-aware too:
when multiplayer state is active, the same cutover can follow the session-side build path rather
than only the local executable version, so mixed-version compatibility is now the strongest
current explanation for why this lower metric split exists at all
- nearby callers now make two more compatibility reads concrete: - nearby callers now make two more compatibility reads concrete:
build `1.04+` keeps one `Recycling Plant` stem-specific branch alive inside `0x004101e0`, and build `1.04+` keeps one `Recycling Plant` stem-specific branch alive inside `0x004101e0`, and
build `1.05+` skips one older descriptor-side attenuation fallback in that same rebuild family build `1.05+` skips one older descriptor-side attenuation fallback in that same rebuild family
@ -120,6 +127,8 @@ What this note is for:
Highest-value open edge: Highest-value open edge:
- The remaining semantic edge is why build `1.03+` selects the weighted tracker branch in - The remaining semantic edge here is narrower now:
`0x004a65b0`, now that the version gate itself is grounded and the linked-transit peer-cache side whether the pre-`1.03` versus `1.03+` tracker metric split has any meaningful downstream effect
is tighter as step count plus normalized continuity share rather than a generic ratio. beyond ranked linked-transit site choice and seeded peer-route choice, since current evidence
says the company train-pressure target still sums raw site cache `+0x12` rather than the
weighted lanes fed by step count and continuity.

View file

@ -226,7 +226,7 @@ transition.
is narrower now too: the entry-side match key `[entry+0x50]` is no longer just an opaque request is narrower now too: the entry-side match key `[entry+0x50]` is no longer just an opaque request
field. The profile-key callback lanes feed field. The profile-key callback lanes feed
`multiplayer_transport_parse_selector_view_probe_marker`, which decodes one local `X%sX|%d` marker `multiplayer_transport_parse_selector_view_probe_marker`, which decodes one local `X%sX|%d` marker
into a request id plus companion value, and into a probe request id plus displayed version/build integer, and
`multiplayer_transport_arm_selector_view_probe_tracking` stores those into `[entry+0x50]` and `multiplayer_transport_arm_selector_view_probe_tracking` stores those into `[entry+0x50]` and
`[entry+0x54]` before arming the live probe gate at `[entry+0x58]`. The current-selector callback `[entry+0x54]` before arming the live probe gate at `[entry+0x58]`. The current-selector callback
root at `0x59f8b0` is now bounded as well: it resolves and upserts the active selector name, root at `0x59f8b0` is now bounded as well: it resolves and upserts the active selector name,
@ -248,17 +248,194 @@ transition.
`[entry+0x98]`, clears `[entry+0x7c]`, stamps the last-success tick at `[entry+0x6c]`, appends the `[entry+0x98]`, clears `[entry+0x7c]`, stamps the last-success tick at `[entry+0x6c]`, appends the
returned sample into the short rolling history at `[entry+0x84..]`, grows the bounded sample-count returned sample into the short rolling history at `[entry+0x84..]`, grows the bounded sample-count
`[entry+0x94]` up to four, computes the current average into `[entry+0x80]`, and then publishes `[entry+0x94]` up to four, computes the current average into `[entry+0x80]`, and then publishes
that averaged sample through `multiplayer_transport_enqueue_callback_slot24_record`. So the that averaged `ms` sample through `multiplayer_transport_enqueue_callback_slot24_record`. So the
publication boundary is explicit and the request-id ownership is explicit, even though the exact publication boundary is explicit and the request-id ownership is explicit: `[entry+0x80]` now
user-facing meaning of the sample and the companion value at `[entry+0x54]` is still open. The reads as the averaged millisecond probe sample and `[entry+0x54]` as the displayed version/build
companion integer. The adjacent route-callback side is tighter too, but it is now kept separate:
the staged route-callback path at `0x5958e0` and the later compatibility gate at
`multiplayer_transport_route_binding_matches_route_callback_descriptor_tuple` `0x595d00` operate
on a compact GameSpy-style server or route descriptor family with a primary endpoint tuple at
`[descriptor+0x00]/[+0x04]`, an optional secondary endpoint tuple at `[descriptor+0x08]/[+0x0c]`,
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
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:
`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]`,
`multiplayer_route_callback_runtime_acquire_shared_string_copy` `0x590540` and
`multiplayer_route_callback_runtime_release_shared_string_copy` `0x5905a0` now bound the shared
string pool used by that decoded schema, and the higher bring-up owner `0x596090` now clearly
splits between `[transport+0xba4]` with owner callback `0x595a40`, the local field-cache family
`[transport+0x1724]` seeded through `0x5a08f0/0x595b60`, and `[transport+0x1164]` with owner
callback `0x595bc0`, while
`multiplayer_transport_route_callback_table_service_receive_decode_state_machine` `0x5908c0`
is the current live receive/decode state machine serviced by `0x591290` in table states `2/3`.
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
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
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`.
That makes the remaining source-flag meaning narrower too: current evidence now supports reading
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.
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
`[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
the pointer through `0x5933a0`. The negative result is stronger too: local text-side xrefs still
show no direct store to `[transport+0x1778]`, and a wider local sweep also failed to show any
obvious `lea`-based replay-band writer, so the sidecar writer remains upstream of this leaf
publisher. Mode `0` is now also tied more cleanly to the generic descriptor append-notify lane
at `0x590370`, while mode `2` stays outside this helper as the separate
remove-notify-and-stage path at `0x590430`. The opcode-`2` payload boundary is tighter too:
`0x592ae0` now grounds that payload
as a seven-dword block with an owned string slot at `+0x08`, so live mode supplies a populated
payload while modes `3` and `5` deliberately enqueue an all-zero payload and reuse only
the wrapper-side sidecar metadata. Those two modes are tighter now too: they are the live
receive-state owner callbacks emitted by `0x5911e0 -> 0x5908c0`, not loose generic replay
guesses. So those paths are better read as delayed metadata replays over one cached work record,
not over a separate anonymous cache blob. 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
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
`0x5934c0` seeds that shared drain context id first, then the transport copies it into queued
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`
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
`0x595b80`, whose final cleanup is an active field-snapshot purge rather than a queued-work
drain. The adjacent route-callback descriptor-table lifecycle is tighter too: `0x590410` now
grounds `[table+0x5bc]` as the staged intrusive descriptor-list head, `0x590430` is the generic
remove-notify-and-stage lane, `0x590490` releases the staged list, and `0x5904d0` releases the
active descriptor collection before tearing that staged list down. That also makes the earlier
`0x5962e0` “release active descriptors” step explicit. The callback-table attach side now constrains the
same work-record metadata family a little further too: `0x593650` deliberately duplicates one
caller metadata dword into both fields `+0x0c` and `+0x18`, while preserving the remaining
caller callback function pointer in `+0x10`. The lower opcode wrappers are tighter now too:
`0x592a40` and `0x592a70` both consume that staged triplet in the order `( callback fn +0x10,
callback companion +0x18, drain context id +0x0c )`. 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
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]`. 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: mainly the still-unrecovered writer that stages `[transport+0x1778]`. 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]`,
`[transport+0x1770]`, `[transport+0x1774]`, `[transport+0x177c]`, `[transport+0x1780]`, and
`[transport+0x1784]` all have direct local owners while `[transport+0x1778]` still appears only
as the single read in `0x595bc0`. So the remaining writer looks upstream and indirect rather
than like one missing ordinary field store in the local cluster. The adjacent staged-route
callback side is tighter too: `0x595860` is now bounded as the
submit-result handler beneath `0x5958e0`, and the old `[transport+0xac0]` ambiguity there is now
gone. That branch is using the already-grounded third selector-generation counter at `[0xac0]`
together with target `[0xb48]` to decide whether staged route-callback traffic can push the
multiplayer route-mode ladder from `2` into `3` and later `4`. The selector-view counter beneath
that gate is tighter now too: `0x594e30` counts slot-`2` entries whose flag dword carries bit
`0x20`, optionally filtered by the current transport name buffer. The selector-view mutation
family under that same lane is tighter too: `0x594a30` is now the direct keyed-store remover,
`0x594fb0` clears one selector-slot ownership pointer plus its slot-local flag dword and drops
the whole entry when no slots remain, `0x595010` rekeys one selector-view entry under a new name
while preserving the `0x40..` runtime band, and callback root `0x59f9c0` now reads as the
sibling lane that clears one named selector-view slot, publishes callback slot `18`, and may
still re-enter the route-mode setter from the same slot-`2` status and generation gates. The
neighboring callback roots are tighter now too: `0x5950a0` clears one selector slot from every
selector-view entry in the keyed store, `0x59fab0` is the rename or relabel sibling above
`0x595010`, `0x59faf0` updates one selector slot's fixed sample-text buffer and refreshes the
active selector object when present, and `0x59fb60` replaces one selector slot's name set,
requests the default profile-key bundle for that slot, and publishes callback slot `20`. Slot
`16` is tighter now too: current grounded caller `0x59f440` forwards the staged route-callback
payload handle from `[transport+0xb50]` through `0x592ea0` just before route mode `5`. The
last adjacent callback root in that block is tighter now too: `0x59fbd0` is the built-in
per-slot profile-key query sibling. It resolves the caller selector name into one slot index,
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.
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
the `0x40` inline keyed-property vector against the owner schema, and `0x58fe50` validates the
signed-`0x80` trailing string-pair tail before decode. `0x58ff60` then grounds bit `0x02` as
the inline secondary IPv4 dword branch, bit `0x20` as the paired secondary-port word branch with
owner-port fallback, bit `0x08` as one still-unresolved auxiliary dword stored at
`[descriptor+0x10]`, bit `0x40` as one inline keyed-property vector decoded through the
property-store writers, and signed bit `0x80` as one trailing string-pair tail. The
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:
`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`
story is no longer queue-only either: `0x58ff60` can also OR in bit `0x1` after the inline
keyed-property vector and bit `0x2` after the signed string-pair tail. The flag-byte split is no
longer purely behavioral either: current evidence now says byte `[descriptor+0x15]` bit `0x1` is
a source-side descriptor header bit, explicitly seeded during the primary-endpoint table refresh
around `0x590dc0` and preserved by the compact descriptor decode path at `0x58ff60`, rather than
a queue-generated runtime state. The `gsi_am_rating` dispatcher side is tighter too: that same
bit no longer just looks like a direct-versus-queued routing split, because `0x595e10` also uses
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
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
callback families do not copy a descriptor-local field but instead mirror the transport-staged
companion dword at `[this+0x490]` into `[this+0x54]` and the local field-cache family. 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
same service loop also owns a slower sidecar lane keyed off `[entry+0xa4]`: 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_select_stale_selector_view_progress_entry` walks the store through
`multiplayer_transport_pick_stale_selector_view_progress_entry`, picks one stale entry whose `multiplayer_transport_pick_stale_selector_view_progress_entry`, picks one stale entry whose
progress latch `[entry+0x9c]` is clear and whose last progress tick `[entry+0x70]` is old enough, progress latch `[entry+0x9c]` is clear and whose last progress tick `[entry+0x70]` is old enough,
and then hands it to `multiplayer_transport_stage_selector_view_progress_snapshot`. That helper and then hands it to `multiplayer_transport_stage_selector_view_progress_snapshot`. That helper
now looks more bounded too: it rebuilds the marker text from `[entry+0x50]` through now looks more bounded too: it rebuilds the core `X%sX` marker text from `[entry+0x50]` through
`multiplayer_transport_format_selector_view_probe_marker`, formats one `PNG %s %d` line around `multiplayer_transport_format_selector_view_probe_marker_core`, formats one `PNG %s %d` line
that marker and the entry-local selector-view sample at `[entry+0x80]`, appends bounded around that marker and the entry-local averaged millisecond sample at `[entry+0x80]`, appends bounded
selector-slot `PNG` fragments for live overlapping slots, marks progress-snapshot state in flight selector-slot `PNG` fragments for live overlapping slots, marks progress-snapshot state in flight
at `[entry+0x9c]`, and stamps both `[entry+0x70]` and the transport-wide throttle tick at `[entry+0x9c]`, and stamps both `[entry+0x70]` and the transport-wide throttle tick
`[transport+0xaec]`. So the selector-view sidecar no longer looks like one undifferentiated `[transport+0xaec]`. So the selector-view sidecar no longer looks like one undifferentiated
@ -322,7 +499,14 @@ transition.
seed to `multiplayer_transport_handle_validated_route_cookie_event` `0x005972c0`. That helper seed to `multiplayer_transport_handle_validated_route_cookie_event` `0x005972c0`. That helper
either marks route progress and re-enters `multiplayer_transport_set_route_mode`, or forwards the either marks route progress and re-enters `multiplayer_transport_set_route_mode`, or forwards the
event id plus payload into the owner callback at `[transport+0x17f0]` with context event id plus payload into the owner callback at `[transport+0x17f0]` with context
`[transport+0x17f8]`. Subtype `6` still validates the same cookie, dedupes one 32-bit cookie or `[transport+0x17f8]`. The surrounding status-route callback vector is tighter now too:
`0x005970e0` publishes either the active selector text or the averaged probe sample at
`[entry+0x80]` and otherwise falls back to owner callback `[transport+0x17e0]`;
`0x00597180` is a straight owner-forwarding lane through `[transport+0x17e4]`;
`0x005971b0` seeds the local status-control id list and can then notify owner callback
`[transport+0x17e8]`; and `0x00597270` returns the third selector-slot generation counter
`[transport+0xac0]` on its bounded local branch before falling back to owner callback
`[transport+0x17ec]`. Subtype `6` still validates the same cookie, dedupes one 32-bit cookie or
packet id, and then dispatches the trailing payload through the natneg-or-raw callback layer packet id, and then dispatches the trailing payload through the natneg-or-raw callback layer
rooted at `[route+0xa0]` and `[route+0xa4]`. This separates the shell-frame preview refresh at rooted at `[route+0xa0]` and `[route+0xa4]`. This separates the shell-frame preview refresh at
`0x006cd8d8` from the actual transport cadence at `0x006cd970`, and also separates that transport `0x006cd8d8` from the actual transport cadence at `0x006cd970`, and also separates that transport
@ -505,10 +689,11 @@ transition.
resolver is tighter now too: `scenario_state_compute_issue_opinion_multiplier` `0x00436590` is no resolver is tighter now too: `scenario_state_compute_issue_opinion_multiplier` `0x00436590` is no
longer just an abstract issue table lookup because its merger callsite uses issue id `0x3a`, which longer just an abstract issue table lookup because its merger callsite uses issue id `0x3a`, which
lines up directly with localized id `726` saying merger votes depend on public attitude toward the lines up directly with localized id `726` saying merger votes depend on public attitude toward the
management of the two companies. By contrast the public-support helper management of the two companies. By contrast the broader support-adjusted share-price helper
`company_compute_public_support_vote_scalar` `0x00424fd0` uses the broader issue id `0x37`, which `company_compute_public_support_adjusted_share_price_scalar` `0x00424fd0` uses the broader issue
currently looks like a more general company-management or public-sentiment slot rather than the id `0x37`, which currently looks like a more general company-management or public-sentiment slot
merger-only attitude term. The supporting stat layer is bounded more cleanly now too: the rather than the merger-only attitude term. The supporting stat layer is bounded more cleanly now
too: the
surrounding `0x0b` setup in the merger and takeover offer builders is formatter mode rather than a surrounding `0x0b` setup in the merger and takeover offer builders is formatter mode rather than a
player-facing issue number, while the company-side stat wrapper player-facing issue number, while the company-side stat wrapper
`company_read_year_or_control_transfer_metric_value` `0x0042a5d0` now reads as a generic `company_read_year_or_control_transfer_metric_value` `0x0042a5d0` now reads as a generic
@ -1025,8 +1210,10 @@ transition.
shared hundredths-scaled build-version query shared hundredths-scaled build-version query
`runtime_query_hundredths_scaled_build_version` `0x00482e00` over `0x006cec74`. The current `runtime_query_hundredths_scaled_build_version` `0x00482e00` over `0x006cec74`. The current
caller thresholds `>= 0x67`, `>= 0x68`, `>= 0x69`, and `>= 0x6a` now line up with executable caller thresholds `>= 0x67`, `>= 0x68`, `>= 0x69`, and `>= 0x6a` now line up with executable
build values `1.03`, `1.04`, `1.05`, and `1.06`, so this split is no longer best-read as a build values `1.03`, `1.04`, `1.05`, and `1.06`, and the version source itself can come from
time- or era-side cutover at all. That lower split is tighter now too: the multiplayer companion path as well as the local executable, so this split is no longer
best-read as a time- or era-side cutover at all. It now reads more cleanly as a pre-`1.03`
versus `1.03+` route-metric compatibility dispatcher. That lower split is tighter now too:
`0x004a5280` is the weighted recursive branch with heuristic ordering, per-tracker best-cost `0x004a5280` is the weighted recursive branch with heuristic ordering, per-tracker best-cost
cache `0x006cfcac`, and prune threshold `0x006cfcb0`, while `0x004a5900` is the alternate cache `0x006cfcac`, and prune threshold `0x006cfcb0`, while `0x004a5900` is the alternate
recursive neighbor-walk branch that stays within compatible component labels through recursive neighbor-walk branch that stays within compatible component labels through
@ -1137,9 +1324,17 @@ transition.
`0x00407bd0` was only revisited on the longer interval. `0x00407bd0` was only revisited on the longer interval.
That heavier sibling is now bounded too: That heavier sibling is now bounded too:
`company_rebuild_linked_transit_autoroute_site_score_cache` `0x00407bd0` no longer looks like a `company_rebuild_linked_transit_autoroute_site_score_cache` `0x00407bd0` no longer looks like a
generic tail refresh. It reuses the fast peer tables, rolls candidate-local service metrics and generic tail refresh. It reuses the fast peer tables, rebuilds candidate-local amount bands plus
peer-route deltas back into three per-site cache floats at `+0x0e`, `+0x12`, and `+0x16`, and normalized issue-opinion scales, and then folds the peer-side route metrics back into three
then feeds the neighboring selectors per-site cache floats with a cleaner split:
`+0x12` is the raw surviving site-score total,
`+0x0e` is the continuity-and-step-weighted companion total,
and `+0x16` is the promoted final site-ranking lane chosen from the strongest grouped candidate
bands.
That also closes most of the cross-version impact question:
the pre-`1.03` versus `1.03+` tracker metric split now looks like it mainly perturbs the weighted
`+0x0e` lane and the promoted `+0x16` lane, not the raw `+0x12` total.
That final lane then feeds the neighboring selectors
`company_select_best_owned_linked_transit_site_by_autoroute_score` `0x00408280` and `company_select_best_owned_linked_transit_site_by_autoroute_score` `0x00408280` and
`company_build_linked_transit_autoroute_entry` `0x00408380`. That makes the company-side follow-on `company_build_linked_transit_autoroute_entry` `0x00408380`. That makes the company-side follow-on
read more like a linked-transit autoroute cache family than a generic company maintenance pass. read more like a linked-transit autoroute cache family than a generic company maintenance pass.
@ -1160,9 +1355,19 @@ transition.
its live roster through `company_count_owned_trains` `0x004264c0`, measure one aggregate linked its live roster through `company_count_owned_trains` `0x004264c0`, measure one aggregate linked
transit site pressure through `company_compute_owned_linked_transit_site_score_total` transit site pressure through `company_compute_owned_linked_transit_site_score_total`
`0x00408f70`, and then rebalance that roster through `0x00408f70`, and then rebalance that roster through
`company_balance_linked_transit_train_roster` `0x00409950`. Current grounded evidence says that `company_balance_linked_transit_train_roster` `0x00409950`.
pass prunes or upgrades older company-owned trains, then fills any remaining deficit by either The aggregate helper no longer reads as a raw sum either:
packaging multiplayer opcode `0x75` or locally re-entering it starts from the site-cache `+0x12` totals, converts that into one tentative roster target
through year and site-count ladders, and on build `1.03+` adds one special distance-side scaling
branch when exactly two eligible linked transit sites survive.
Because it consumes `+0x12` rather than `+0x0e` or `+0x16`, current evidence now says the tracker
compatibility split is more important for seeded route choice and ranked site choice than for the
final company train-count target itself.
The balancer then applies two age bands to company-owned trains:
very old trains are removed when the roster already exceeds target or upgraded when it still
needs capacity, while the mid-age band can trigger one narrower upgrade pass.
After that it fills any remaining deficit by either packaging multiplayer opcode `0x75` or
locally re-entering
`company_try_add_linked_transit_train_and_publish_news` `0x00409830`. The two visible news `company_try_add_linked_transit_train_and_publish_news` `0x00409830`. The two visible news
helpers under it are bounded too: `0x00409830` emits RT3.lng `2896` for a newly added train, helpers under it are bounded too: `0x00409830` emits RT3.lng `2896` for a newly added train,
while `company_publish_train_upgrade_news` `0x00409300` emits RT3.lng `2897` for the upgrade while `company_publish_train_upgrade_news` `0x00409300` emits RT3.lng `2897` for the upgrade
@ -1228,12 +1433,15 @@ transition.
`company_issue_public_shares_and_raise_capital` `0x00427450`. The threshold side is tighter now `company_issue_public_shares_and_raise_capital` `0x00427450`. The threshold side is tighter now
too. The earliest creditor-pressure lane requires scenario mode `0x0c`, the bankruptcy toggle too. The earliest creditor-pressure lane requires scenario mode `0x0c`, the bankruptcy toggle
`[0x006cec78+0x4a8f]` to be clear, at least `13` years since `[company+0x163]`, and at least `[0x006cec78+0x4a8f]` to be clear, at least `13` years since `[company+0x163]`, and at least
`4` years since founding year `[company+0x157]`; it then scans the last three years of slots `4` years since founding year `[company+0x157]`; it then scans the last three years of the
`0x2b` and `0x2c`, chooses one negative pressure ladder `-600000 / -1100000 / -1600000 / derived net-profits and revenue lanes `0x2b` and `0x2c`, chooses one negative pressure ladder
-2000000` from the current slot-`0x2c` bands around `120000 / 230000 / 340000`, requires public `-600000 / -1100000 / -1600000 /
support at least `15` or `20` depending on whether all three sampled years failed, checks slot -2000000` from the current slot-`0x2c` bands around `120000 / 230000 / 340000`, requires the
`0x09` against `0.08` times that ladder, and requires the three-year slot-`0x2b` total to clear broader support-adjusted share-price or public-support scalar at least `15` or `20` depending on
one final `-60000` gate before it falls into the bankruptcy commit and RT3.lng `2881` headline. whether all three sampled years failed, checks the current fuel-cost lane in slot `0x09` against
`0.08` times that ladder, and requires the
three-year slot-`0x2b` total to clear one final `-60000` gate before it falls into the
bankruptcy commit and RT3.lng `2881` headline.
The middle debt-capital layer is split more clearly now too. With `[+0x4a8b]` clear, one annual The middle debt-capital layer is split more clearly now too. With `[+0x4a8b]` clear, one annual
bond lane first simulates full repayment through `company_repay_bond_slot_and_compact_debt_table` bond lane first simulates full repayment through `company_repay_bond_slot_and_compact_debt_table`
and then uses the post-repayment cash window with fixed `-250000` and `-30000` thresholds plus and then uses the post-repayment cash window with fixed `-250000` and `-30000` thresholds plus
@ -1243,24 +1451,35 @@ transition.
suppress it, and `[+0x4a87]` is clear, it starts from one `1000`-share batch, can replace its suppress it, and `[+0x4a87]` is clear, it starts from one `1000`-share batch, can replace its
default `1.0` factor with one linked-chairman personality scalar, scales that by `1.6` when default `1.0` factor with one linked-chairman personality scalar, scales that by `1.6` when
growth setting `1` is active, and then runs one `800000` stock-value gate plus one growth setting `1` is active, and then runs one `800000` stock-value gate plus one
support-times-factor-times-`1000`-times-`1.2` affordability gate before the repeated `1000`-share support-adjusted-share-price-times-factor-times-`1000`-times-`1.2` affordability gate before the
buyback commits behind RT3.lng `2887`. The ordering above this helper is tighter now too: repeated `1000`-share buyback commits behind RT3.lng `2887`. The ordering above this helper is
tighter now too:
`company_service_periodic_city_connection_finance_and_linked_transit_lanes` clears those latches `company_service_periodic_city_connection_finance_and_linked_transit_lanes` clears those latches
first, runs the city-connection and linked-transit branches, and only then enters the annual first, runs the city-connection and linked-transit branches, and only then enters the annual
finance helper, so these look like same-cycle reaction gates rather than long-lived balance-sheet finance helper, so these look like same-cycle reaction gates rather than long-lived balance-sheet
flags. flags.
After the earlier debt or bankruptcy outcomes stay inactive, the later stock-capital lane also After the earlier debt or bankruptcy outcomes stay inactive, the later stock-capital lane also
has a bounded first threshold layer: with the bond and stock toggles `[+0x4a8b]` and `[+0x4a87]` has a tighter bounded shape now too: it only opens on build `1.03+`, only after the earlier
clear, at least two bond slots live, and at least one year since founding, it derives one bankruptcy, bond, and repurchase outcomes stay inactive, and with the bond and stock toggles
1000-share batch with floor `2000`, requires public support at least `22`, requires the support `[+0x4a8b]` and `[+0x4a87]` clear, at least two bond slots live, and at least one year since
times batch product to clear `55000`, and then uses a piecewise approval ladder founding. It derives one issue batch from outstanding shares rounded down to `1000`-share lots
`0.07/1.3 -> 0.14/0.35` before the share-issue path proceeds. with floor `2000`, trims that batch until the broader support-adjusted share-price scalar times
batch no longer exceeds the `55000` gate, requires that scalar at least `22`, resolves the
highest-coupon live bond slot, and then uses current cash from `0x2329/0x0d` as a gate against
that slot's principal plus a small fixed buffer before it compares the chosen bond-rate lane
against a normalized scalar ratio built from the same support-adjusted share-price lane and
current `Book Value Per Share` from `0x2329/0x1d` through the piecewise approval ladder
`0.07/1.3 -> 0.14/0.35`. On success it issues two
same-sized tranches through repeated `company_issue_public_shares_and_raise_capital` calls and
publishes a separate equity-offering news family rooted at localized id `4053`, not the earlier
debt or buyback headline family.
The dividend side is bounded too: it requires the dividend toggle `[0x006cec78+0x4a93]` to be The dividend side is bounded too: it requires the dividend toggle `[0x006cec78+0x4a93]` to be
clear, mode `0x0c`, at least `1` year since `[company+0x0d2d]`, and at least `2` years since clear, mode `0x0c`, at least `1` year since `[company+0x0d2d]`, and at least `2` years since
founding, then averages the last three years of slot `0x2b`, folds in the unassigned-share pool founding, then averages the last three years of the net-profits lane `0x2b`, folds in the
and the current `0x0d` band, applies the map-editor building-growth setting `[0x006cec78+0x4c7c]`, unassigned-share pool and the current `0x0d` band, applies the map-editor building-growth
treats growth setting `1` as a `0.66` scale-down and setting `2` as a zeroing pass on the current setting `[0x006cec78+0x4c7c]`, treats growth setting `1` as a `0.66` scale-down and setting `2`
dividend, quantizes surviving adjustments in tenths, and finally clamps against as a zeroing pass on the current dividend, quantizes surviving adjustments in tenths, and
finally clamps against
`company_compute_board_approved_dividend_rate_ceiling` `0x00426260`. `company_compute_board_approved_dividend_rate_ceiling` `0x00426260`.
The linked-transit route-seeding side has one tighter sibling now too: The linked-transit route-seeding side has one tighter sibling now too:
`company_reset_linked_transit_caches_and_reseed_empty_train_routes` `0x00401940`. It clears the `company_reset_linked_transit_caches_and_reseed_empty_train_routes` `0x00401940`. It clears the
@ -1507,9 +1726,11 @@ transition.
`shell_format_company_financial_summary_card` through `shell_format_company_financial_summary_card` through
`shell_company_detail_render_company_summary_card`, controls `0x947d` and `0x947e` now ground a `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`, bond maturity and repay panel through `shell_company_detail_render_bond_maturity_and_repay_panel`,
control `0x9488` now grounds the debt or capital or dividend summary block through control `0x9488` now grounds the debt or credit or rate summary block through
`shell_company_detail_render_capital_and_dividend_summary_panel`, control `0x948a` now grounds the `shell_company_detail_render_debt_credit_and_rate_summary_panel`, control `0x948a` now grounds the
per-share metrics block through `shell_company_detail_render_per_share_metrics_panel`, and 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 adjacent territory selector lane is bounded through
`shell_company_detail_select_territory_access_row`, `shell_company_detail_select_territory_access_row`,
`shell_company_detail_render_territory_access_row`, `shell_company_detail_render_territory_access_row`,
@ -1523,10 +1744,13 @@ transition.
`shell_resolve_chairmanship_takeover_vote_and_commit_outcome`, `shell_resolve_chairmanship_takeover_vote_and_commit_outcome`,
`shell_present_chairmanship_takeover_vote_outcome_dialog`, `shell_present_chairmanship_takeover_vote_outcome_dialog`,
`shell_resolve_merger_vote_and_commit_outcome`, and `shell_present_merger_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 public-support side The remaining company-side uncertainty is therefore narrower than before: the broader support and
is now tighter too because `company_compute_cached_recent_performance_support_score` and valuation side is now tighter too because
`company_compute_public_support_vote_scalar` bound the recent-performance and public-support blend `company_compute_cached_recent_per_share_performance_subscore`,
beneath those vote resolvers, `scenario_state_compute_issue_opinion_multiplier` now bounds the `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,
`scenario_state_compute_issue_opinion_multiplier` now bounds the
next layer of optional company, chairman, and territory-specific opinion overrides on the active next layer of optional company, chairman, and territory-specific opinion overrides on the active
scenario state, and the broader stat-reader family around scenario state, and the broader stat-reader family around
`company_read_control_transfer_metric_slot` and `company_read_control_transfer_metric_slot` and
@ -1916,15 +2140,24 @@ transition.
weight, `company_query_min_linked_site_distance_to_xy` at `0x00405920` provides the nearest 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 linked-site distance term, `company_count_linked_transit_sites` at `0x00426590` provides one of
the company-side caps, `company_compute_connection_bonus_value_ladder` at `0x00425320` supplies the company-side caps, `company_compute_connection_bonus_value_ladder` at `0x00425320` supplies
the bounded company-side value scalar, `company_compute_issue39_opinion_bias_scalar` at the bounded company-side value scalar, and
`0x00424580` contributes one smaller issue-`0x39` opinion term, `company_compute_prime_rate_from_issue39_scenario_baseline` at `0x00424580` now bounds the
shared prime-rate-side helper that this lane reuses beside the raw issue-`0x39` total,
`scenario_state_sum_issue_opinion_terms_raw` at `0x00436710` now bounds the raw additive `scenario_state_sum_issue_opinion_terms_raw` at `0x00436710` now bounds the raw additive
issue-total helper beneath that term, and `company_connection_bonus_lane_is_unlocked` at issue-total helper beneath that term, and `company_connection_bonus_lane_is_unlocked` at
`0x00427590` is the small boolean gate above the ladder. Wider governance and CompanyDetail xrefs `0x00427590` is the small boolean gate above the ladder. Wider governance and CompanyDetail xrefs
now tighten slot `0x2b` into a rolling shareholder-facing performance lane reused by annual now tighten slot `0x2b` into the rolling net-profits lane reused by annual finance checks and a
shareholder-revolt or creditor-pressure checks and a per-share/history formatter, while `0x09` per-share/history formatter, while the report-history descriptor table now aligns raw slot `0x09`
remains the narrower current governance-pressure term read after those broader gates. The wider with the Income Statement fuel-cost lane surfaced by tooltip `1309`. The wider result now reads
sibling news owner above the same city-pair route family is bounded now too: more like recent net profits minus recent fuel burden than a governance-pressure term. That now
also sharpens the annual finance lane at `0x00401c50`: the first bankruptcy branch reads as
sustained cash-and-debt stress over recent profits and fuel burden, the later fallback branch as
a deeper `-300000` cash / three bad years cleanup trigger, and the later stock-issue branch reads
as a price-to-book-versus-coupon approval ladder rather than a generic support vote. The tail is
cleaner now too: it compares total retired versus newly issued principal to choose the `2882..2886`
debt headline family, then publishes `2887` separately from the accumulated repurchased-share
count. The sibling news owner above the same
city-pair route family is bounded now too:
`simulation_try_select_and_publish_company_start_or_city_connection_news` `0x00404ce0` `simulation_try_select_and_publish_company_start_or_city_connection_news` `0x00404ce0`
filters and scores candidate city entries, re-enters the same shared heavy builder through filters and scores candidate city entries, re-enters the same shared heavy builder through
`city_connection_try_build_route_between_region_entry_pair` `0x00404c60` for the dense pair `city_connection_try_build_route_between_region_entry_pair` `0x00404c60` for the dense pair