Map auxiliary route-entry tracker helpers

This commit is contained in:
Jan Petykiewicz 2026-04-05 20:11:47 -07:00
commit b86dbb1e64
2 changed files with 312 additions and 5 deletions

View file

@ -638,7 +638,11 @@ anchor it, and where control is handed to neighboring subsystems.
exclusive primary mode buttons at `0x985e` `0x985f` and `0x9860`, and current primary evidence now
bounds those values as `Lay single track.` `0x1`, `Lay double track.` `0x4`, and `Bulldoze` `0x40`
from the localized strings 2054 2055 and 1721 plus the matching control-routing branches in
`track_lay_window_handle_message`. The same family also owns a bridge-type preference selector
`track_lay_window_handle_message`. The same family also owns the downstream route-entry policy
bridge at `0x004955b0`: current caller evidence says that helper maps the live TrackLay primary
mode into endpoint-synthesis policy `1` or `4` before the tool re-enters `0x00493cf0`, which is
the strongest current bridge from the player-facing single-track versus double-track buttons into
the lower route-builder policy bytes. The same family also owns a bridge-type preference selector
rooted at `0x006cec74+0x138`, two wrapped `Never` through `Common` frequency settings at
`0x006cec74+0x140` and `0x006cec74+0x13c`, two boolean track-lay preference toggles, and the
electrify-all-track action path. Those last two toggles are now tighter than before: current
@ -921,12 +925,248 @@ anchor it, and where control is handed to neighboring subsystems.
`city_connection_try_build_route_between_region_entry_pair` `0x00404c60`, and the direct retry
paths inside `simulation_try_select_and_publish_company_start_or_city_connection_news`
`0x00404ce0`. Internally it now has three bounded lanes:
an early explicit route-store attempt through `0x004a01a0`,
an early route-entry search or synthesis attempt through
`route_entry_collection_try_build_path_between_optional_endpoint_entries` `0x004a01a0`,
a single-endpoint direct-placement lane that scans `Maintenance` and `ServiceTower` candidates
and commits through `0x00403ed5 -> 0x004134d0 -> 0x0040ef10`,
and a later paired-endpoint fallback lane that seeds two endpoint candidates from the same stem
family, walks a temporary route-entry list, and commits through
`0x0040446b -> 0x004134d0 -> 0x0040ef10`.
That early lane can now be described more concretely: it can reuse supplied route-entry
endpoints, synthesize a missing leading endpoint from the caller's coordinates, seed the
route-store builder-state block, and then hand off to the deeper path-search core without
placing a new site. The previously vague side family at `0x006cfcb4` is tighter too: current
evidence now bounds it as a small auxiliary route-entry tracker collection with an allocator at
`0x004a42b0`, a refcount or destroy path at `0x004a4340`, a direct route-entry group-id setter
at `0x00489f80`, a boolean-latch refresh or owner-notify path at `0x00494fb0`, and a
two-endpoint merge or bind helper at `0x00494f00`. That bind side is tighter now too: the
trackers group route entries only when a route-key-like value from `0x0048aa70`, the route-entry
signature word `+0x22e`, and the boolean latch derived from byte `+0x44` all agree. The deeper
handoff under that lane is no longer anonymous either:
`route_entry_collection_search_path_between_entry_or_coord_endpoints` `0x0049d380` is now
bounded as the internal search core that runs the first candidate sweep, quality gates, and the
later route-extension fallbacks before returning one resolved route-entry id or `-1`. The first
sweep now has a bounded owner at `0x0049bd40`, and the two later fallback helpers are bounded as
the route-entry point-window coverage query `0x00494cb0` and the frontier-extension helper
`0x0049c900`. The math side is bounded more cleanly now too: the family reuses
`math_measure_float_xy_pair_distance` `0x0051db80` for its direct point-to-point scalar,
`math_compute_quadrant_adjusted_heading_angle_from_xy_pair` `0x004952f0` for heading-angle
construction, `math_normalize_subtracted_angle_delta_and_report_wrap` `0x004953c0` for wrapped
angle-delta checks, and `math_abs_double_with_crt_special_case_handling` `0x005a152e` for the
absolute-value side of the quality gates. Current evidence also bounds the threshold shape a
little more tightly: the initial sweep and later extension path both reuse one signed angle-bias
term `+/-0.181000038854627`, and the first sweep switches between a looser `1.4` and stricter
`1.8` quality multiplier depending on route-policy byte `4` or the broader display-runtime
preference `[0x006cec78+0x4c74]`, already grounded elsewhere as `Auto-Show Grade During Track
Lay`.
The small policy-byte semantics are still not fully closed, but current evidence is tighter than
before. Literal byte `1` is now the strongest current match for direct linked-site
endpoint-anchor creation or replacement, because the linked-site constructor and neighboring
repair branches around `0x00480463`, `0x00480a77`, and `0x00480b69` all feed that byte into
`0x00493cf0` before rebinding one chosen route-entry anchor through `0x0048abc0`. Literal byte
`2` now looks broader: the later world-side caller at `0x00480cd0` and the linked-site refresh
helper `placed_structure_refresh_linked_site_display_name_and_route_anchor` `0x00480bb0` both
reach `0x004a01a0` with both optional endpoint-entry ids unset and that byte, so the strongest
current read is a full linked-site route-anchor rebuild between optional endpoint entries rather
than the narrower direct creation lane. The TrackLay side now gives one tighter user-facing
anchor too: the live mode field `0x00622b0c` is already grounded as `Lay single track.` `0x1`
versus `Lay double track.` `0x4`, and the small mapper `0x004955b0` collapses that state into
the endpoint-policy bytes later passed to `0x00493cf0`, so the strongest current read is
`policy 1 = single-track endpoint synthesis` and `policy 4 = double-track endpoint synthesis`.
Bytes `1/2` are still the ones that enable the
auxiliary tracker lane in `0x004a01a0`, while byte `4` now reads more narrowly as the larger
company-side endpoint-synthesis charge inside `0x00493cf0`, because that helper feeds `-1`
versus `-2` into the saturating company counter helper `0x00423ec0` on `[company+0x7680]`
rather than skipping the company branch entirely. That counter is tighter now too: nearby
company initialization seeds it to `50` when scenario byte `0x4aaf` is enabled and to sentinel
`-1` otherwise, while the companion getter `0x004240a0` returns either the live counter or fixed
fallback `29999`. Current language-table correlation also gives `0x4aaf` a stronger
player-facing meaning: it is the live gate behind `Company track laying is limited...` and the
event variable label `Company Track Pieces Buildable`. So the current strongest read is
available track-laying capacity, not an abstract company route-budget. That site-side helper
also closes one adjacent ownership gap: beneath
`placed_structure_finalize_creation_or_rebuild_local_runtime_state` `0x0040ef10`, it rebuilds
one linked site's route-entry anchor and display-name buffer. That path is tighter now than just
“bind anchor then touch `0x006cfcb4`”: after the literal-policy-`2` rebuild succeeds it
re-enters `aux_route_entry_tracker_collection_refresh_route_entry_group_membership` `0x004a45f0`,
which can repartition adjacent route-entry tracker groups around the refreshed anchor, rewrite
compatible endpoint slots through `0x004950f0`, and refresh one nearby cached-match payload band
through `0x00495020` before the helper resumes the name-buffer work. The remaining display-name
side still matches the earlier
grounded text family: copy the resolved city name when available, append civic suffixes
`Township`, `New`, `Modern`, or `Renaissance`, append `Service Tower` or `Maintenance Facility`
on the linked-instance class branches, and otherwise fall back through the older
`Junction`..`Center` and `Anytown` text families.
The sibling policy-`1` side is tighter now too. The constructor lane no longer stops at “one
linked site id at `[site+0x2a8]`”: the subtype-`1` branch in
`placed_structure_construct_entry_from_candidate_and_world_args` `0x0040f6d0` now clearly
allocates that linked record through
`placed_structure_collection_allocate_and_construct_linked_site_record` `0x00481390`, whose lower
constructor is `placed_structure_construct_linked_site_record_from_anchor_and_coords`
`0x00480210`. That lower constructor seeds the linked record's own id and anchor-site id, clears
the local route-anchor and display-name fields, projects the anchor footprint into world space,
and then either binds an already-covered route entry through `0x00417b40` or falls through into
the neighboring policy-`1` route-entry synthesis family around `0x00493cf0` before rebinding the
chosen route entry through `0x0048abc0`.
The cleanup side is tighter now too. Linked-site removal now has a bounded owner at
`placed_structure_collection_remove_linked_site_record` `0x004813d0`: it resolves the linked
record through `0x006cec20`, runs the per-record teardown
`placed_structure_teardown_linked_site_runtime_state_before_removal` `0x00480590`, removes the
live entry from the collection, and only then re-enters the still-bounded company-wide follow-on
at `0x00429c10` when the removed record passed the narrower transit-like latch. That per-record
teardown is no longer just “clear some scratch fields.” It now clearly clears the route-style
scratch lane, clears the five proximity buckets at `[site+0x590..0x5b8]`, detaches or invalidates
the current route-entry anchor, frees the three per-site byte arrays at `[site+0x24..0x2c]`,
clears this site's indexed byte from the corresponding arrays of later placed-structure records,
and then re-enters `0x00436040` with the current site id.
That company-side follow-on is no longer just one opaque callback either. It is now bounded as
`company_collection_refresh_active_company_linked_transit_site_peer_caches` `0x00429c10`, which
walks the active company roster and re-enters
`company_rebuild_linked_transit_site_peer_cache` `0x004093d0` on each company. That per-company
fast pass stamps a refresh tick at `[company+0x0d3e]`, clears and repopulates the
placed-structure-side cache cells addressed through `[site+0x5bd][company_id]`, marks the
eligible linked transit sites for that company, allocates one `0x0d`-stride peer table for each
eligible site, and fills those peer rows from the route-side sweep through `0x004a6630`. The
adjacent timed wrapper `company_service_linked_transit_site_caches` `0x00409720` now shows the
cadence too: `0x004093d0` is the shorter-interval refresh, while the older heavier sibling at
`0x00407bd0` was only revisited on the longer interval.
That heavier sibling is now bounded too:
`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
peer-route deltas back into three per-site cache floats at `+0x0e`, `+0x12`, and `+0x16`, and
then feeds the neighboring selectors
`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
read more like a linked-transit autoroute cache family than a generic company maintenance pass.
The neighboring reachability gate is tighter now too:
`company_query_cached_linked_transit_route_anchor_entry_id` `0x00401860` caches one company-side
route-entry anchor, and
`placed_structure_is_linked_transit_site_reachable_from_company_route_anchor` `0x004801a0`
uses that anchor to decide whether a foreign linked transit site can still participate in the
current company's fast peer cache.
The first direct train-side consumer above that cache family is bounded now too:
`train_try_append_linked_transit_autoroute_entry` `0x00409770`. After servicing the owning
company's caches, it asks `0x00408380` for one staged `0x33`-byte route entry using the train's
current anchor site, then either appends that entry through `0x004b3160` and refreshes the new
trailing selection through `0x004b2f00`, or rotates one existing slot in place when the local
two-entry cap has already been reached. So this edge now reaches an actual train-side autoroute
append lane rather than stopping at anonymous company-side cache cells.
The train-side follow-on above that seed path is bounded now too. The owning company can count
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`
`0x00408f70`, and then rebalance that roster through
`company_balance_linked_transit_train_roster` `0x00409950`. Current grounded evidence says that
pass prunes or upgrades older company-owned trains, then 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
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
branch.
The subtype-`4` sibling side is bounded now too. The nearby-site bucket family now has:
`placed_structure_append_nearby_transit_site_distance_bucket_entry` `0x0047fdb0`,
`placed_structure_remove_site_id_from_proximity_bucket_lists` `0x0047dd10`, and
`placed_structure_clear_proximity_bucket_lists` `0x0047dcd0`, plus the two collection sweeps
`placed_structure_collection_append_site_into_all_proximity_bucket_lists` `0x00481480` and
`placed_structure_collection_remove_site_id_from_all_proximity_bucket_lists` `0x004814c0`.
Current evidence says those five buckets store `(peer site id, distance)` pairs for nearby
station-or-transit peers, grouped through the five-way classifier at `0x0040d350`. The older
stream-backed side is bounded too: `placed_structure_collection_load_dynamic_side_buffers_from_stream`
`0x00481430` walks the live placed-structure collection and re-enters
`placed_structure_load_dynamic_side_buffers_from_stream` `0x0047d8e0`, which repopulates the
route-entry list, the three per-site byte arrays, the five proximity buckets, and the trailing
scratch band from the caller-supplied persistence stream.
The linked-site route-entry list itself is tighter now too. The refresh or teardown branch at
`0x0040e102` re-enters `placed_structure_remove_route_entry_key_and_compact` `0x0047d810`, which
removes one matching `u16` key from the six-byte list rooted at `[site+0x462]/[site+0x466]`,
compacts the surviving entries into a replacement buffer, and decrements the stored route-entry
count.
The broader company-side owner above these pieces is tighter now too. The periodic service pass
`company_service_periodic_city_connection_finance_and_linked_transit_lanes` `0x004019e0` now
reads as the current outer owner for this branch: it sequences the city-connection announcement
lanes, the linked-transit train-roster balancer, the acquisition-side sibling
`company_try_buy_unowned_industry_near_city_and_publish_news` `0x004014b0`, the annual finance-policy helper
`company_evaluate_annual_finance_policy_and_publish_news` `0x00401c50`, and the shorter-versus-
longer linked-transit cache refresh tail through `0x004093d0` and `0x00407bd0`. That outer pass
also has one tighter temporary-state role now: it clears company bytes `0x0d17/0x0d18/0x0d56`,
mirrors `0x0d17` into scenario field `0x006cec78+0x4c74` only while the earlier route-building
side runs, and restores the original scenario value on exit. Current evidence now ties `0x0d17`
to the shared preferred-locomotive chooser `0x004078a0`: the override is only armed when that
helper picks one locomotive whose engine-type dword is `2`. That engine-type lane now best reads
as electric rather than an unnamed class slot, because the linked approval helper around
`0x0041d550` now reads as a real locomotive-era and engine-type policy gate, dispatching the same
`0/1/2` field across three scenario-opinion lanes while the local player-facing engine-type
family is explicitly `Steam / Diesel / Electric`. That same gate also now ties the later scenario
bytes `0x4c97..0x4c99` back to the editor-side `Locomotives` page rather than treating them as
anonymous availability flags: they are the live `All Steam Locos Avail.`, `All Diesel Locos
Avail.`, and `All Electric Locos Avail.` policy bytes behind `0x004cd680` / `0x004cf0d0`. The
current logic is also tighter than a plain override tier: a positive engine-family opinion result
can carry the gate by itself only while none of those three editor bytes is enabled; once any of
them is nonzero, `0x0041d550` instead requires one matching intersection between the record-local
family bytes and the enabled editor family bytes. The `WhaleL` carveout is narrower now too:
current data-file correlation ties that stem to the `Orca NX462` / `WhaleL_NE` locomotive family,
and it explicitly zeros that positive-opinion result before the later family-availability checks,
so it loses the shortcut rather than gaining a special approval path. The same
chooser now also has a bounded fallback below it, `locomotive_collection_select_best_era_matched_non_electric_fallback_id`
`0x00461cd0`, which explicitly skips engine-type `2` and chooses the lowest-penalty remaining
locomotive by era mismatch and approval gates. The route-search side is tighter too: this
electric-only override now clearly feeds the first path-sweep branch in `0x0049bd40`, forcing the
larger `1.8` initial quality multiplier instead of `1.4`, which is the same branch otherwise
chosen by explicit route-policy byte `4`. So the later annual finance helper is reading
same-cycle side-channel state from the earlier city-connection and linked-transit branches, not
unrelated long-lived finance fields. The inner
finance helper is not debt-only either. Current grounded outcomes include bankruptcy news
`2881`, the debt restructure family `2882..2886`, a later share-repurchase headline `2887`, and
the dividend-side adjustment branch. The main commit verbs under that helper are now grounded too:
`company_repay_bond_slot_and_compact_debt_table` `0x00423d70`,
`company_issue_bond_and_record_terms` `0x004275c0`,
`company_repurchase_public_shares_and_reduce_capital` `0x004273c0`, and
`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
`[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
`0x2b` and `0x2c`, chooses one negative pressure ladder `-600000 / -1100000 / -1600000 /
-2000000` from the current slot-`0x2c` bands around `120000 / 230000 / 340000`, requires public
support at least `15` or `20` depending on whether all three sampled years failed, checks 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
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
the broader linked-transit train-service latch `[company+0x0d56]` to decide whether to append one
or more `500000` principal, `30`-year bonds. The repurchase lane is separate again: when the
city-connection announcement-side latch `[company+0x0d18]` is set, growth setting `2` does not
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
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
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
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
flags.
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]`
clear, at least two bond slots live, and at least one year since founding, it derives one
1000-share batch with floor `2000`, requires public support at least `22`, requires the support
times batch product to clear `55000`, and then uses a piecewise approval ladder
`0.07/1.3 -> 0.14/0.35` before the share-issue path proceeds.
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
founding, then averages the last three years of slot `0x2b`, folds in the unassigned-share pool
and the current `0x0d` band, applies the map-editor building-growth setting `[0x006cec78+0x4c7c]`,
treats growth setting `1` as a `0.66` scale-down and setting `2` 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`.
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
two company-side linked-transit cache timestamps, forces one immediate cache rebuild through
`0x00409720`, strips route lists from company-owned trains in modes `0x0a/0x13`, and then
re-enters `train_try_append_linked_transit_autoroute_entry` `0x00409770` only when a train's
route list has become empty.
On the wider chooser question, the current evidence is also tighter than before: every recovered
external owner of `0x00402cb0` is still in the city-connection family, so the two later direct
placement lanes currently read as city-connection fallback behavior rather than a broadly shared
world placement service.
It can still unwind through route-state cleanup without committing new placed structures, so the
exact lower helper semantics are not fully closed, but the broader chooser is no longer
anonymous and its main policy split is now visible. The two lower helpers directly under those
@ -935,7 +1175,12 @@ anchor it, and where control is handed to neighboring subsystems.
projected-footprint offset helper over candidate bytes `[candidate+0xb8]` and `[candidate+0xb9]`,
and `placed_structure_validate_projected_candidate_placement` `0x004197e0` is the shared
go-or-no-go validator that checks company, territory, world-tile, and footprint occupancy state
before either direct-placement commit is allowed to fire.
before either direct-placement commit is allowed to fire. Its strongest current subtype branch is
a station-attachment or upgrade-style lane keyed by `[candidate+0x32] == 1`, which now has the
concrete failure family `2901..2906`: blocked upgrade footprint, ground not flat enough, not
your track, insufficient track-laying capacity, cannot connect to existing track, and ground too
steep. That tightens the chooser materially without yet proving that the validator is
station-only for every caller.
The recurring outer owner is tighter now too:
`placed_structure_collection_refresh_quarter_subset_route_style_state` `0x00413580` walks every
fourth live placed structure from a scenario-time-derived offset and re-enters the per-site