764 lines
68 KiB
Markdown
764 lines
68 KiB
Markdown
# Input, Save/Load, and Simulation: Post-load Generation, PaintTerrain, and Save/Load Restore
|
|
|
|
### Post-load Generation, PaintTerrain, and Save/Load Restore
|
|
|
|
The same brush strip is tighter now too:
|
|
`0x004bc210` stores the selected ordinal and refreshes one scalar caption
|
|
from table `0x00621e24`, `0x004bc260` exposes the cached world coordinate pair plus the
|
|
currently selected scalar, and `0x004bc290` restyles the ordinal strip `0x0fa1..0x0fa7` plus
|
|
the mapped mode strip `0x0faa..0x0faf` against the current mode dword `[0x006d0818+0x8c]`. The
|
|
next unresolved layer is narrower and more semantic: the setup side now has one grounded
|
|
owner, `world_run_post_load_generation_pipeline`, and its building-side branch is no longer just
|
|
one opaque block. We now have a region family, a region-border overlay rebuild, a region-owned
|
|
structure-demand and placement dispatcher, and a deeper per-region worker that computes category
|
|
demand, subtracts existing coverage, and tries candidate placements. The category map is tighter
|
|
too: category `0` falls back to `House`, category `2` is the year-gated weighted region-profile
|
|
family that also feeds the localized `Industry Weightings` stats panel, and category `3` now
|
|
reaches a separate pool-driven picker whose fallback label is `Commercial` but whose aligned
|
|
player-facing stats bucket is `City Support`. The normalized region band is tighter too:
|
|
`world_region_normalize_cached_structure_balance_scalars` `0x00422320` no longer just writes an
|
|
anonymous cached preview band at `[region+0x2e2/+0x2e6/+0x2ea/+0x2ee]`. Current growth-report
|
|
evidence now grounds `[region+0x2e2]` as the weighted-profit-margin scalar and `[region+0x2ee]`
|
|
as the annual-density-adjust scalar later formatted as a percent in `Stats - City/Region`, with
|
|
`[region+0x2e6/+0x2ea]` left as the intermediate normalized-delta and clamped companion slots
|
|
beneath that final adjust term. The per-region prepass feeding that normalization is tighter too:
|
|
`0x00420d40` clears `[region+0x306/+0x30a/+0x30e]`, walks the linked placed-structure chain from
|
|
`[region+0x383]`, accumulates two local placed-structure metrics through `0x0040ca70` and
|
|
`0x0040ca80`, and only for class-0 candidates also folds source field `[source+0x141]` through
|
|
`0x0040cec0` into the third accumulator before tailing into the later scalar refresh. That tail
|
|
helper `0x00420560` is tighter now too: on class-0 regions it revisits the same linked chain and
|
|
folds a class-mix contribution into `[region+0x312]`, with one source-derived term for candidate
|
|
class `0`, a separate branch keyed by `[candidate+0x78c]` and `[site+0x246]` for class `2`, one
|
|
fixed increment for class `3`, and no current contribution from class `1`. One neighboring
|
|
collection-side dispatcher is tighter now too: `0x00433b80` only runs when global mutation depth
|
|
`0x0062be40` is back at zero and then conditionally fans into the optional refresh hooks
|
|
`0x00481430`, `0x00413860`, `0x004b2a90`, and `0x004931e0`. The periodic boundary
|
|
side is narrower now too. `0x00422100`, reached only from
|
|
`simulation_service_periodic_boundary_work` `0x0040a590`, first requires several live world
|
|
state gates to stay clear, derives one year-sensitive random threshold from selected-year fields
|
|
plus world width, then scans the region collection for eligible class-0 regions whose transient
|
|
dwords `[region+0x276]` and `[region+0x302]` are both clear and which fail the city-connection
|
|
peer probe `0x00420030(1,1,0,0)`. When the gate passes it picks one random eligible region,
|
|
derives one small severity bucket from `[region+0x25e]`, stores the scaled amount back into
|
|
`[region+0x276]`, and appends one queued `0x20`-byte record through `0x004337c0` with literal
|
|
kind `7`, the chosen region id, that amount, the fixed payload `0x005c87a8`, and sentinel dwords
|
|
`-1/-1`. That append helper is now grounded directly too: `0x004337c0` allocates one zeroed
|
|
linked `0x20`-byte node, copies one string or payload seed into `[node+0x04..]`, stores the six
|
|
trailing caller dwords at `[node+0x08..+0x1c]`, and appends the finished node to the singly
|
|
linked list rooted at `[state+0x66a6]`. The gameplay label for that queued-record family is still
|
|
open, but the structural link from periodic region selection into the scenario-state queue is now
|
|
direct instead of speculative. One neighboring owner is tighter now too: `0x004358d0` walks the
|
|
same live region collection and services those pending amounts after linked-site refreshes. When a
|
|
region's pending amount at `[region+0x276]` is live and the city-connection peer probes
|
|
`0x00420030` and `0x00420280` can resolve one matching peer site plus linked company through
|
|
`0x0047efe0`, it formats one localized notice from region name `[region+0x356]`, world scalar
|
|
`[region+0x23a]`, and the pending amount, publishes that notice through `0x004554e0`, posts the
|
|
amount into company stat slot `4` through `0x0042a080`, then clears `[region+0x276]` and stamps
|
|
completion latch `[region+0x302] = 1`. When no peer-company branch is available and byte
|
|
`[region+0x316]` is still clear, the same owner publishes one alternate one-shot notice from the
|
|
same amount and region scalar before setting `[region+0x316]`. So the pending-region bonus lane
|
|
is no longer just a queued setup artifact: it has a concrete later service owner and an explicit
|
|
shell-facing fallback above the same queue family now too. `0x00438710` is the recurring queue
|
|
service owner above `[world+0x66a6]` and `[world+0x66aa]`, while `0x00438840` is the tiny
|
|
dispatch-or-fallback sibling: it forwards the currently active queue node at `[world+0x66aa]`
|
|
into the same node-handler table `0x00437c00`, or opens the fixed custom modal rooted at
|
|
localized id `0x153` when no active node is staged.
|
|
company-credit side effect. One neighboring narrow counter is bounded too: `0x00422850`
|
|
counts class-0 regions that pass a second `0x00420030` peer-probe variant with fixed flags
|
|
`(1,1,1)` plus one caller-supplied trailing dword, and current callers are the query/script
|
|
dispatch at `0x0042f856` and the later region-stats formatter at
|
|
`0x004d2088`. The
|
|
remaining setup-side uncertainty has therefore narrowed
|
|
again: the region seed and border-overlay pair clearly complete before the `Setting up Players and
|
|
Companies...` banner is posted; `[0x006cec74+0x174]` now looks like the direct building-population
|
|
gate; `[0x006cec74+0x178]` now looks like the direct seeding-burst gate and selected-year-adjust
|
|
policy; and `[0x006cec74+0x68]` now aligns with editor-map mode because the same flag forces the
|
|
`.gmp` family in the shell file coordinators while suppressing the later building and seeding
|
|
branches and diverting the deeper region worker into alternate logic. One write side for that
|
|
`[shell+0x178]` policy is now grounded too: inside `shell_dispatch_ui_command` `0x00464410`,
|
|
command ids `0x9d26..0x9d28` store `command_id - 0x9d26` directly into `[0x006cec74+0x178]`,
|
|
yielding live values `0`, `1`, and `2`. That means the later restore branch is no longer gated
|
|
by an abstract hidden shell latch; at least one of its adjustment inputs is an explicit UI
|
|
launch policy and current evidence still does not show that value being recovered from saved
|
|
state. The `319` lane itself is no longer the
|
|
open structural gap; it now clearly owns chairman-profile slot seeding, profile-record
|
|
materialization, a shell editor surface over the same local record family, and a separate
|
|
live-company presentation path through the company-list window. The later interior order of that
|
|
same `319` lane is tighter now too: after the route-entry collection refresh on `0x006cfca8` it
|
|
refreshes the auxiliary route-entry tracker collection `0x006cfcb4`, then runs
|
|
`placed_structure_collection_refresh_local_runtime_records_and_position_scalars` `0x004133b0`,
|
|
which first drains the queued local-runtime rebuild ids through collection `0x0062b2fc` and then
|
|
sweeps the live placed-structure collection `0x0062b26c` for the later position-triplet side
|
|
refresh,
|
|
then a flagged world-grid cleanup sweep through the compact grid-flag query
|
|
`0x00448af0` plus the neighboring local chunk-cell write helper `0x00533fe0`, and only after
|
|
that the later route-entry post-pass at `0x00491c20`. The same `319` lane is tighter internally
|
|
now too:
|
|
the surrounding placed-structure collection side is no longer just the per-record loader family.
|
|
`0x004131f0` now cleanly constructs and stream-loads the live placed-structure collection,
|
|
`0x00413230` constructs the empty runtime pool, `0x00413280` stream-loads tagged placed-structure
|
|
entries with progress publishing, `0x00413260` is the matching release-and-free owner, and
|
|
`0x00413550` now clearly resolves one site id, re-enters `0x0040e080` to release local runtime
|
|
and linked-site follow-on state, and only then unlinks the entry from the live collection. The
|
|
adjacent helper strip is tighter too: `0x00413620` is the collection-wide linked-peer overlay
|
|
refresh sweep above `0x0040d2d0`; `0x00413660` and `0x004136e0` are the neighboring owner-color
|
|
and scalar publish sweeps; `0x00413750` is the shared mode-`3/6` linked-site preview membership
|
|
refresh owner; `0x00413860` is the collection-side center-cell roster sweep above `0x0040cd10`;
|
|
`0x004138b0` is the route-link cleanup sweep keyed by one center-cell `u16` roster token;
|
|
`0x004138f0` counts live placed structures whose cached candidate id `[site+0x3d0]` matches one
|
|
caller-supplied structure id; `0x00413940` walks the same matching subset and accumulates source
|
|
field `[source+0x141]` from `0x0040cec0` with a floor of `1`; `0x004139a0` counts entries whose
|
|
linked peer passes the narrower station-or-transit gate `0x0040d230`; `0x00413a00/0x00413aa0`
|
|
narrow that same linked-peer subset to candidate class `3` and `4`; and `0x00413b40` is the
|
|
subtype-`4` companion counter whose last gate is the raw linked-instance candidate byte `0xb9`.
|
|
That `0x00413940` sum is now the direct link-count scale factor consumed by `0x0041e7be` above
|
|
the four cargo-summary banks.
|
|
One neighboring year-side owner is tighter now too: `0x00435b50` is the shared year-threshold
|
|
and structure-milestone news pass beneath periodic simulation and startup bring-up. It suppresses
|
|
itself when the cached previous year still matches or scenario gate `[0x006cec78+0x46c38]` is
|
|
live, then publishes fixed year notices for `1865/1895/1920/1958`, formatted numeric notices for
|
|
`1850/1900/1950`, and later structure-milestone notices keyed by live counts of specific placed
|
|
structures resolved through `0x00412af0` and counted through `0x004138f0`, appending the finished
|
|
records into the existing fixed-record/news lanes at `0x006cea4c` and `0x004337c0` rather than
|
|
through a separate hidden journal family.
|
|
before that later world and shell reactivation tail, `world_entry_transition_and_runtime_bringup`
|
|
runs one distinct post-bundle status and runtime refresh phase that posts progress ids `0x196`
|
|
and `0x197` through `0x005193f0/0x00540120` with paired `0x004834e0` follow-ons, refreshes the
|
|
live event collection at `0x0062be18` through
|
|
`scenario_event_collection_refresh_runtime_records_from_packed_state` `0x00433130`, rebuilds the
|
|
scenario-side port-or-warehouse cargo recipe runtime tables through `0x00435630`, and then runs
|
|
the named-candidate availability preseed through `0x00437743`. The recipe rebuild lane itself is
|
|
tighter now too: `0x00435630` resolves both supplied and demanded token strings through the exact
|
|
live cargo-name matcher `cargo_collection_find_entry_by_exact_name` `0x0041e9f0`, fills empty
|
|
token strings from the first live cargo entry before that match, and in mode `3` loops until the
|
|
supplied and demanded strings no longer compare equal. The importer-side bridge is tighter now
|
|
too: each of the twelve recipe books writes its active-line count into the paired runtime count
|
|
lane beside the imported `0xbc` descriptor strip, and after the full twelve-book sweep the helper
|
|
explicitly re-enters
|
|
`structure_candidate_collection_rebuild_runtime_records_from_scenario_state` `0x00412d70` when
|
|
the live candidate collection exists. That keeps the strongest current static split narrow and
|
|
concrete: mode-zero demand rows can still preserve readable cargo-name text in the saved recipe
|
|
books, but only the nonzero imported rows reach the live `0xbc` descriptor array, and the
|
|
unresolved supply-marker forms still have no special decode path before the exact matcher runs.
|
|
The immediate helper strip under that bridge is tighter now too: `0x00411d50` is the narrow
|
|
descriptor-pattern predicate that returns true only when every imported descriptor keeps mode `0`
|
|
and at least one descriptor has no subordinate rows, while `0x00411da0`, `0x00411e10`, and
|
|
`0x00411e50` are conservative fixed-table accessors over candidate slot `[candidate+0x798]`,
|
|
exposing one copied name plus either a scalar pair or scalar triplet from the same fixed row in
|
|
`0x005ed338..0x005edca4` rather than a separate loader family.
|
|
One later subphase is tighter now too: before the broad world-reactivation sweep it
|
|
posts progress ids `0x32dc/0x3714/0x3715`,
|
|
reloads one `0x108`-byte packed profile block through `0x00531150`, conditionally copies staged
|
|
runtime-profile bytes back into `0x006cec7c` while latch `[profile+0x97]` is set, mirrors the
|
|
grounded campaign-scenario bit `[profile+0xc5]` and sandbox bit `[profile+0x82]` into world
|
|
bytes `[world+0x66de]` and `[world+0x66f2]`, and restores the selected year/profile lane through
|
|
a tighter two-stage calendar path than before. Current local disassembly now shows the raw saved
|
|
lane at `[profile+0x77]` first feeding helper `0x0051d3f0` with constant components
|
|
`(month=1, day=1, subphase=0, tick=0)`, which writes the resulting Jan-1-style tuple dwords
|
|
into `[world+0x05/+0x09]`. Only after that seed does the same lane enter one mode-sensitive
|
|
adjustment branch: non-editor startup mode can decrement the lane by `1` or `3` depending on
|
|
shell-state editor gate `[0x006cec74+0x68]`, shell-side selected-year-adjust policy
|
|
`[0x006cec74+0x178]`, and the saved special-condition slot `[0x006cec78+0x4af7]`, and only that
|
|
save/load bridge is narrower on the candidate side too: the constructor-side load owner
|
|
`structure_candidate_collection_construct_and_stream_load_runtime_records` `0x004131f0`
|
|
seeds global pool `0x0062b268` and immediately re-enters the broader collection importer
|
|
`structure_candidate_collection_stream_load_rebuild_runtime_summaries_and_refresh_named_availability`
|
|
`0x00412fb0`. That owner streams each packed candidate body back through
|
|
`structure_candidate_stream_load_runtime_record_and_rebuild_cargo_state` `0x004120b0`, reruns the
|
|
scenario-side recipe projection at `0x00412d70`, refreshes the stem-policy lane at `0x00412ab0`,
|
|
rebuilds the collection aggregate subtotal band at `[pool+0x8c..+0x9c]`, repopulates the fixed
|
|
name catalog at `0x0061dbc2/0x0061dc09` for non-subtype-`1` zero-availability candidates whose
|
|
live ids stay within `0x6e`, and then reruns the named-availability pass at `0x00412c10` before
|
|
returning. The neighboring placed-structure side
|
|
is bounded too: global pool `0x0062b26c` comes from
|
|
`placed_structure_collection_construct_empty_runtime_pool` `0x00413230`, while the paired tagged
|
|
collection owners `0x00413280` and `0x00413440` now own the broader placed-structure stream
|
|
load/save path around tags `0x36b1/0x36b2/0x36b3` and the per-entry virtual load/save slots
|
|
`+0x40/+0x44`.
|
|
adjusted lane then feeds
|
|
helper `0x0051d390` before `world_set_selected_year_and_refresh_calendar_presentation_state`
|
|
`0x00409e80` stores the final absolute counter into `[world+0x15]` and refreshes
|
|
`[world+0x0d/+0x11]`. That means the restore no longer reads as a direct
|
|
`[profile+0x77] -> [world+0x15]` copy; the raw lane seeds the tuple immediately, but the final
|
|
absolute-counter restore still depends on live shell/startup context. That dependency is tighter
|
|
now too: current local evidence shows `[shell+0x178] == 1` decrementing the restored lane by
|
|
`1`, `[shell+0x178] == 2` subtracting `3`, and otherwise a nonzero
|
|
`[0x006cec78+0x4af7]` supplying the fallback `-1` branch. That field is no longer unresolved:
|
|
current local disassembly now shows `0x00436d10` bulk-zeroing the dword table rooted at
|
|
`[startup+0x4a7f]` through `rep stos`, which includes `+0x4af7`, while the editor-side special
|
|
conditions owner at `0x004cb2b0/0x004cb8e0` counts and commits that same 49-entry table from the
|
|
static rule descriptors at `0x005f3ab0`. The `.smp` save or restore family now grounds that live
|
|
band directly too: `world_runtime_serialize_smp_bundle` `0x00446240` writes `49` dwords from
|
|
`[world+0x4a7f..+0x4b3f]` plus one trailing scalar at `[world+0x4b43]`, and
|
|
`world_load_saved_runtime_state_bundle` `0x00446d40` restores the same fixed `0xc8`-byte band
|
|
symmetrically. Slot `30` in that table is localized pair `3722/3723`
|
|
`Disable Cargo Economy`, so `+0x4af7` now reads as the live copy of that saved scenario rule,
|
|
not a startup-runtime-only mystery latch. The neighboring fixed reads line up with the same rule
|
|
cluster too: `+0x4aef` is slot `28` `Completely Disable Money-Related Things`, `+0x4af3` is slot
|
|
`29` `Use Bio-Accelerator Cars`, `+0x4afb` is slot `31` `Use Wartime Cargos`, `+0x4aff` is slot
|
|
`32` `Disable Train Crashes`, `+0x4b03` is slot `33` `Disable Train Crashes AND Breakdowns`, and
|
|
`+0x4b07` is slot `34` `AI Ignore Territories At Startup`. So the remaining loader gap is
|
|
narrower than before: the restore still depends on live shell policy `[shell+0x178]`, but the
|
|
`+0x4af7` input itself is save-derived scenario rule data rather than something that requires
|
|
runtime tracing to discover. Its read-side family is no longer isolated to the selected-year
|
|
restore either: it also shapes the chunk size in
|
|
`simulation_run_chunked_fast_forward_burst` `0x00437b20` and appears in candidate/local-service
|
|
selection and station-detail-side scoring branches around `0x0047f910`, `0x00410d87`, and
|
|
`0x005069c6`, which now makes this whole slot cluster look like broader runtime consumers of
|
|
scenario special conditions rather than one startup-only mode enum. One file-side anchor is now
|
|
tighter too: the checked classic and 1.05 `gmp/gms/gmx` corpus does expose the same aligned
|
|
`0x0d64..0x0e2c` `50`-dword band as the grounded `.smp` runtime save or restore copy into
|
|
`[world+0x4a7f..+0x4b43]`, but most checked file families only populate a sparse subset of that
|
|
band. The first `36` dwords still behave like the older inferred fixed rule matrix with hidden
|
|
slot `35` fixed to sentinel value `1`, while the trailing `13` unlabeled rule lanes plus one
|
|
scalar vary much more selectively by file family. Current local corpus scans make that split
|
|
concrete: the grounded 1.05 scenario-save family (`p.gms`, `q.gms`) stably lights lanes
|
|
`35, 37, 39, 44, 45, 46, 47, 48`; the base 1.05 save family (`Autosave.gms`, `nom.gms`) only
|
|
shares lane `35` stably and otherwise varies sparsely through `42`, `45`, and `47`; the checked
|
|
grounded 1.05 maps, the lone 1.05 alt save, and the visible sandbox-family `.gmx` files keep
|
|
only the sentinel lane `35` nonzero. So the current loader boundary is narrower than before: the
|
|
`.smp` path still gives a grounded direct runtime-band restore, and checked `gmp/gms/gmx` files
|
|
now show a partially populated projection of that same aligned band rather than a wholly separate
|
|
fixed record family. The overlap against the later scalar window is now explicit too: trailing
|
|
band indices `36..49` are byte-identical with post-window offsets `0x00..0x34`, so every nonzero
|
|
lane in that prefix of the post-sentinel scalar window is also a nonzero lane in the aligned
|
|
runtime-rule band. That means the real “other fields” boundary inside the post-sentinel window
|
|
starts only at `0x0e2c`: `0x0df4..0x0e2c` is the aligned-band overlap prefix, while
|
|
`0x0e2c..0x0f30` is the later tail that still looks like save-side scalar state. Local corpus
|
|
scans now make that tail split more specific. The base 1.05 save family
|
|
(`Autosave.gms`, `nom.gms`) shares a stable tail subset at relative offsets
|
|
`0xb4`, `0xc0`, `0xe0`, `0xfc`, and `0x100`, with additional per-file lanes around them. The
|
|
1.05 scenario-save family (`p.gms`, `q.gms`) has a much denser stable tail covering
|
|
`0x08`, `0x0c`, `0x10`, `0x14`, `0x20`, `0x24`, `0x28`, `0x30`, `0x34`, `0x3c`, `0x5c`,
|
|
`0x6c`, `0xa0`, `0xa8`, `0xbc`, `0xc0`, `0xc4`, `0xc8`, `0xcc`, `0xdc`, `0xe0`, `0xe4`,
|
|
`0xe8`, `0xf4`, `0xf8`, and `0xfc`; those values still differ per save, but the occupancy is
|
|
stable. The lone 1.05 alt save (`g.gms`) only lights `0x20`, `0x34`, `0xf0`, and `0xf4`.
|
|
Grounded map families and classic saves keep the tail zeroed, while the only current map-side
|
|
outlier remains `Tutorial_2.gmp` under the broad unknown map-family bucket. The immediately
|
|
following fixed file window at `0x0df4..0x0f30` is now bounded separately as well: checked maps
|
|
and classic saves leave that whole post-sentinel band zeroed,
|
|
while checked 1.05 saves carry sparse nonzero dwords there, many of which decode cleanly as
|
|
normal little-endian `f32` values. That makes the adjacent band look like a 1.05 save-only
|
|
runtime band rather than scenario-static payload, even though its semantics are still open.
|
|
One numeric alignment inside that band is now exact too: the tail start `0x0e2c` is the same
|
|
relative distance from the aligned runtime-rule base `0x0d64` as live object offset `+0x4b47`
|
|
is from grounded world-rule base `[world+0x4a7f]`, so the bounded tail window
|
|
`0x0e2c..0x0f30` is offset-aligned with live bytes `[world+0x4b47..+0x4c4b]`. The first
|
|
grounded live field at that boundary is no longer anonymous. `0x004367c0` sets one outcome mode
|
|
in `[world+0x4a73]`, zeros `[world+0x4d]`, snapshots the selected-year lane to `[world+0x4c88]`,
|
|
and then copies localized id `2923` `You lose.` or `2924` `You win, cheater...` into
|
|
`[world+0x4b47]`; `0x00472dd0` formats localized id `3918` `%1 has won the game!` with one live
|
|
profile name and writes that string into the same destination; and one compact runtime-effect
|
|
branch inside `world_apply_compact_runtime_effect_record_to_resolved_targets` `0x00431b20` resets
|
|
the same destination to the fixed placeholder token at `0x005c87a8`. That gives a grounded live
|
|
owner above the latch too: `simulation_service_world_outcome_mode_prompt_and_transition_effects`
|
|
`0x00436350` is the frame-serviced consumer of `[world+0x4a73]`, stamping completion latch
|
|
`[world+0x4a77]`, driving the outcome-mode prompt rooted at localized id `0x169`, and triggering
|
|
the world-side transition paths around `0x482150` while leaving `[world+0x4b47]` as the current
|
|
outcome-status payload source. That gives a grounded live
|
|
interpretation for the start of the tail: `[world+0x4b47]` is the start of a victory or outcome
|
|
status-text buffer, not a float lane. The same evidence also gives a useful caution: those live
|
|
helpers copy up to `0x12c` bytes into `[world+0x4b47..+0x4c73]`, so the current bounded file-tail
|
|
window `0x0e2c..0x0f30` cuts through the first `0x104` bytes of a grounded text field rather
|
|
than ending on a clean live-field boundary. One small continuation probe now tightens that edge:
|
|
the remaining file window `0x0f30..0x0f58` is exactly the last `0x28` bytes needed to reach the
|
|
clean live-field boundary at `[world+0x4c73]`, and checked 1.05 saves still carry sparse nonzero
|
|
bytes in that continuation window rather than a trailing text-looking suffix. Checked 1.05 save
|
|
bytes in the aligned region therefore still do not resemble preserved text; they stay mostly zero
|
|
at the beginning and many nonzero lanes decode as ordinary `f32` values. So the safest current
|
|
note is: the tail is offset-aligned with the live object beyond `+0x4b43`, but it is not yet a
|
|
validated byte-for-byte mirror of the live `[world+0x4b47]` status-text buffer, and the current
|
|
nonzero save-side content continues right up to the first clean field edge at `0x0f58`. The next
|
|
exact grounded fields after that edge are byte lanes, not restored dwords: `0x0f59` maps to
|
|
`[world+0x4c74]` `Auto-Show Grade During Track Lay`, `0x0f5d` maps to `[world+0x4c78]`
|
|
`Starting Building Density Level`, `0x0f61` maps to `[world+0x4c7c]` `Building Density Growth`,
|
|
`0x0f65` maps to grounded dword `[world+0x4c80]` `leftover simulation time accumulator`, and
|
|
`0x0f6d` maps to byte `[world+0x4c88]` `selected-year lane snapshot`. The first later grounded
|
|
dword after that is `[world+0x4c8c]` at `0x0f71`. The frame-side follow-on above the outcome
|
|
prompt is grounded now too: after `0x00436350` stamps `[world+0x4a77]`, internal branch
|
|
`0x0043963d` keeps running only while `[world+0x4a7b]` still matches the current step-local
|
|
marker, then services the queued runtime-effect record family rooted at `[world+0x66a6]`
|
|
through `0x00438710`, conditionally opens `Overview.win` through `0x004f3a10` when the preview
|
|
fixed-record collection at `0x006cea4c` still has one admissible entry, and conditionally opens
|
|
`LoadScreen.win` page `0` through `0x004e4ee0` when shell latch `0x006d4000` is clear and
|
|
world flag `[world+0x4d]` is still nonzero. The same branch also conditionally toggles pause or
|
|
resume through `0x00437a60` when no live multiplayer session object is present at `0x006cd8d8`.
|
|
That splits the outcome prompt owner `0x00436350` cleanly from the later post-transition
|
|
follow-on strip instead of leaving both behaviors folded into one unnamed frame tail. That means
|
|
the simple 4-byte file-lane model
|
|
stops matching grounded live field boundaries immediately after the text-buffer edge: the post-
|
|
`0x0f58` file bytes are still offset-correlated to live state, but they are no longer naturally
|
|
dword-aligned with the next grounded object fields. The new byte-neighborhood probe makes the
|
|
mismatch more concrete. In checked 1.05 scenario saves, the exact grounded byte offsets
|
|
themselves do not look like clean selector values: `p.gms` carries `0x33` at `0x0f5d` and `0x8c`
|
|
at `0x0f6d`, while `q.gms` carries `0xcc` and `0xba` at those same offsets. The only clean
|
|
float-looking starts in that neighborhood instead appear one byte earlier, at `0x0f5c` and
|
|
`0x0f6c`: `p.gms` decodes those as roughly `7.6` and `6.0172`, while `q.gms` decodes them as
|
|
roughly `23.6` and `44.6824`. That tightens the current read further: the checked save bytes
|
|
remain offset-correlated to the live `[world+0x4c74..+0x4c8c]` neighborhood, but they are still
|
|
not a validated byte-for-byte mirror of the exact live field layout. Local
|
|
A second byte-oriented neighborhood immediately after that now has the same kind of split rather
|
|
than a clean restored-field mirror. The earlier grounded anchors in that band all stay zero in
|
|
the checked 1.05 saves: exact file offset `0x0f87` maps to selected-year bucket companion scalar
|
|
`[world+0x4ca2]`, while `0x0f93` and `0x0f97` map to the two startup-dispatch reset-owned bands
|
|
`[world+0x4cae]` and `[world+0x4cb2]`, and the local corpus leaves all three exact dword starts
|
|
zeroed. The same is true for the later exact byte-owned policy lanes: file offsets `0x0f78`,
|
|
`0x0f7c`, `0x0f7d`, and `0x0f7e` map cleanly to grounded byte fields `[world+0x4c93]` and
|
|
`[world+0x4c97..+0x4c99]`: the linked-site removal follow-on gate plus the three editor
|
|
locomotives-page policy bytes `All Steam Locos Avail.`, `All Diesel Locos Avail.`, and `All
|
|
Electric Locos Avail.`. In the checked 1.05 save corpus those four exact byte lanes all stay
|
|
`0`, which is at least structurally clean. The later grounded dword fields in the same
|
|
neighborhood are less direct again. Exact file offset `0x0f9f` maps to `[world+0x4cba]` (the
|
|
station-list selected-station mirror) and exact offset `0x0fa3` maps to cached
|
|
available-locomotive rating `[world+0x4cbe]`, but the checked save bytes at those exact dword
|
|
starts do not look like clean preserved ids or floats. The only stable float-looking starts sit
|
|
three bytes earlier, at `0x0f9c` and `0x0fa0`: `p.gms` yields roughly `96.8754` and `186.4795`,
|
|
`q.gms` yields `329.9467` and the same `0x0fa0`-side candidate shape, `g.gms` yields `7.0` and
|
|
`95.8507`, and `Autosave.gms` only shows the later `0x0fa0` candidate at about `68.2629`. So
|
|
this later band now has the same conservative read as the post-text one: the save bytes are
|
|
still offset-correlated to grounded live fields, but the exact live byte or dword layout is not
|
|
yet validated as a direct on-disk mirror.
|
|
One more structural cut is now grounded beyond that neighborhood. The aligned scalar plateau
|
|
`0x0fa7..0x0fe7` ends exactly at the later recipe-book root `[world+0x0fe7]` already grounded in
|
|
the port-or-warehouse cargo editor and runtime rebuild path. We still do not have live semantic
|
|
names for the plateau itself, but its aligned dword run now splits cleanly by save family. The
|
|
base 1.05 saves (`Autosave.gms`, `nom.gms`) carry one stable signature with
|
|
`0x0faf = 0x8000003f`, `0x0fb3 = 0x75c28f3f`, repeated `0x75c28f3c` lanes through `0x0fbf`, a
|
|
sign-flipped lane `0x0fc3 = 0xa3d70a3c`, one tiny marker at `0x0fc7 = 0x0000003b`, and
|
|
`0x0fcb = 0x00300000`. The scenario-save family (`p.gms`, `q.gms`) carries a different stable
|
|
plateau over the same offsets, beginning `0x0faf = 0x4000003f`, `0x0fb3 = 0xe560423f`, then
|
|
`0x03126f3b`, `0x1374bc3c`, and paired `0x23d70a3c` lanes at `0x0fbf/0x0fc3`, with
|
|
`0x0fc7 = 0x0000003c`. The alt-save family (`g.gms`) follows the base signature through
|
|
`0x0fc7`, then diverges sharply into the same `0xcdcdcd..` fill pattern already seen in its
|
|
earlier header lanes. So the current best fit for `0x0fa7..0x0fe7` is a family-shaped aligned
|
|
scalar plateau that belongs to save-side runtime state and terminates immediately before the
|
|
grounded recipe-book block, not one more directly named live-field mirror. One conservative
|
|
loader-side summary probe now starts exactly at that recipe root instead of extending the plateau
|
|
model further. The fixed recipe-book block spans twelve books from `0x0fe7` with stride `0x4e1`,
|
|
and the checked map/save pairs `Alternate USA.gmp -> Autosave.gms`, `Southern Pacific.gmp ->
|
|
p.gms`, and `Spanish Mainline.gmp -> g.gms` preserve that rooted block byte-for-byte in the
|
|
sampled local corpus. The current probe therefore treats it as preserved scenario payload rather
|
|
than save-only runtime drift and only reports per-book signatures: a coarse head kind over the
|
|
pre-line region, the raw `book+0x3ed` annual-production dword, and one raw summary for each of
|
|
the five fixed `0x30`-byte cargo lines beginning at `book+0x3f1`: coarse line kind, raw mode
|
|
dword, raw annual-amount dword, and the raw supplied/demanded cargo-token dwords at `+0x08` and
|
|
`+0x1c`. That is enough to separate zero, `0xcd`-filled, and mixed books or lines without
|
|
overstating line semantics beyond the grounded editor/runtime ownership already documented below.
|
|
Local
|
|
corpus clustering now makes the remaining split more specific. The base 1.05 save family
|
|
(`Autosave.gms`, `nom.gms`) shares a narrow tail-heavy subset with stable relative offsets
|
|
`0xec`, `0xf8`, `0x118`, `0x134`, and `0x138`, while still varying in value across files. The
|
|
1.05 scenario-save family (`p.gms`, `q.gms`) shares a much broader stable set spanning almost the
|
|
whole window from `0x04` through `0x134`, again with per-file scalar differences but consistent
|
|
occupancy. Pairwise compare runs tighten that read further: `Autosave.gms` vs `nom.gms` does not
|
|
preserve one common numeric tail signature even at the shared base-save offsets, and `p.gms` vs
|
|
`q.gms` keeps the broad scenario-save occupancy pattern but still changes every shared value, with
|
|
`q.gms` additionally lighting two extra lanes at `0x78` and `0x84`. So the current best fit is
|
|
“family-shaped live scalar state” rather than family-default constants. The lone 1.05 alt-save
|
|
sample (`g.gms`) only lights up four lanes at `0x58`, `0x6c`,
|
|
`0x128`, and `0x12c`. The checked 1.05 maps and classic saves stay zero in that same bounded
|
|
window, which strengthens the current read that this is runtime-save scalar state rather than
|
|
generic map payload. One older unknown map-family outlier in the local corpus does still carry a
|
|
populated window: `Tutorial_2.gmp` under the classic install tree. So the safest current note is
|
|
“zero for grounded map families and classic save families, nonzero for observed 1.05 save
|
|
families, with one older unknown-map exception.” Static consumer grounding is still sparse for
|
|
that tail: direct object-offset hits currently only name the trailing scalar `[world+0x4b43]`
|
|
through the editor panel and `.smp` save or restore family, while local opcode searches do not
|
|
yet surface equally direct reads for the intervening `+0x4b0b..+0x4b3f` tail lanes. So the
|
|
save-file family clustering is now strong, but those later tail scalars remain structurally
|
|
bounded rather than semantically named. The
|
|
same branch is no longer world-entry-only either: current local
|
|
disassembly now shows the identical lane-adjust and
|
|
`0x51d3f0 -> 0x51d390 -> 0x409e80` sequence in the post-fast-forward selected-year tail at
|
|
`0x004370e0`, which lines up with the existing post-fast-forward callers already mapped under
|
|
`0x00433bd0`, `0x00435603`, `0x0041e970`, and `0x00436af0`. That restore now
|
|
also has some neighboring slot semantics bounded well enough to carry in the loader notes. Slot
|
|
`31` `[0x006cec78+0x4afb]` is no longer best read as an unnamed runtime cargo-economy latch:
|
|
local disassembly now ties it directly to the saved special-condition table entry `Use Wartime
|
|
Cargos`, and the strongest current runtime owner is
|
|
`structure_candidate_collection_refresh_cargo_economy_filter_flags` `0x0041eac0`. Inside that
|
|
candidate-collection sweep the branch at `0x0041ed37` only activates when slot `31` is set and
|
|
then treats the string family `Clothing`, `Cheese`, `Meat`, `Ammunition`, `Weapons`, and
|
|
`Diesel` as one special cargo set before writing the live candidate filter byte `[entry+0x56]`.
|
|
That makes the old read-side note around `0x00412560` tighter too: the neighboring descriptor
|
|
gate is now best understood as using the live copy of the `Use Wartime Cargos` scenario rule,
|
|
not an anonymous cargo-economy mode byte. Slot `34` `[0x006cec78+0x4b07]` is similarly bounded
|
|
on the runtime side: the wrapper at `0x004013f0`, which sits immediately above the broader
|
|
company-start or city-connection chooser `0x00404ce0`, snapshots region dword `[entry+0x2d]`
|
|
across all `0x18` live region records in `0x006cfc9c`, zeros that field while the chooser runs,
|
|
and then restores the original values on exit. That is a strong current fit for the editor rule
|
|
`AI Ignore Territories At Startup`, even though the exact meaning of region field `+0x2d`
|
|
remains open. Slot `29` `[0x006cec78+0x4af3]` is less semantically tidy but still worth carrying
|
|
as a bounded consumer family: the branch at `0x0041d286` activates one later placed-structure or
|
|
building-side scoring path only when that slot is nonzero and the linked candidate or era record
|
|
at `[entry+0x41]` equals `5`, while two already-grounded world helpers
|
|
`world_scan_secondary_grid_marked_cell_bounds` `0x0044ce60` and
|
|
`world_service_secondary_grid_marked_cell_overlay_cache` `0x0044c670` also gate on the same
|
|
slot. So the identity of slot `29` as saved rule data is grounded, but the downstream runtime
|
|
semantics are still mixed enough that the loader should preserve the raw value without trying to
|
|
rename its whole consumer family yet. The neighboring train-safety slots are now bounded enough
|
|
to keep as a cautious runtime split too. Slot `33` `[0x006cec78+0x4b03]`
|
|
`Disable Train Crashes AND Breakdowns` is the coarse gate in the currently recovered train-side
|
|
deterioration family around `0x004af8a0`: the very first branch at `0x004af8ab` jumps straight
|
|
to the function tail when the slot is set, bypassing the year-scaled threshold build, the later
|
|
random or threshold comparison, and the two follow-on state transitions at `0x004ad7a0` and
|
|
`0x004ada00`. Slot `32` `[0x006cec78+0x4aff]` `Disable Train Crashes` is narrower in the same
|
|
family: after the threshold path has already run, the branch at `0x004af9c1` uses slot `32` to
|
|
suppress only the lower failure-transition path and force the milder follow-on at `0x004ada00`.
|
|
That same slot-`33` read also appears in the smaller train-side scalar query at `0x004ac460`,
|
|
where setting it returns one fixed float immediately before the ordinary route-object-dependent
|
|
calculation runs. So the current best loader-facing read is: slot `33` is the broad train
|
|
deterioration bypass, slot `32` is the narrower crash-only branch inside that same family, but
|
|
the exact player-facing names of the two unnamed train helpers still need one more naming pass.
|
|
That restore now
|
|
also has one concrete file-side correlation in the classic `.gms` family: local save inspection
|
|
now consistently finds `0x32dc` at `0x76e8`, `0x3714` at `0x76ec`, and `0x3715` at `0x77f8` in
|
|
`Autosave.gms`, `kk.gms`, and `hh.gms`, leaving one exact `0x108`-byte span from `0x76f0` to
|
|
`0x77f8` between `0x3714` and `0x3715`. That span already carries staged-profile-looking payload
|
|
text such as `British Isles.gmp`, so the current static-file evidence now supports the atlas-side
|
|
`0x108` packed-profile note for the classic save family even though the exact field layout inside
|
|
that block is still unresolved. The same classic corpus is tighter now too: inside that
|
|
`0x108` span the map-path C string begins at relative offset `0x13`, the display-name C string
|
|
begins at `0x46`, the block is otherwise almost entirely zeroed, and the three local samples are
|
|
byte-identical except for the leading dword at `+0x00` (`3` in `Autosave.gms` and `hh.gms`,
|
|
`5` in `kk.gms`). The currently atlas-tracked bytes `[profile+0x77]`, `[profile+0x82]`,
|
|
`[profile+0x97]`, and `[profile+0xc5]` are all `0` in that classic sample set, so the current
|
|
file-side evidence grounds the block boundaries and the embedded strings but does not yet show
|
|
live examples of those branch-driving latches being set. One 1.05-era file-side analogue is now
|
|
visible too, but only as an inference from repeated save structure rather than a disassembly-side
|
|
field map: local `.gms` files in `rt3_105/Saved Games` carry one compact string-bearing block at
|
|
`0x73c0` with the same broad shape as the classic profile slab, including a leading dword at
|
|
`+0x00`, one map-path string at `+0x10`, one display-name string at `+0x43`, and a small
|
|
nonzero tail around `+0x76..+0x88`. In that 1.05 corpus the analogue bytes at relative `+0x77`
|
|
and `+0x82` are now nonzero in every checked sample (`Autosave.gms`/`nom.gms` show `0x07` and
|
|
`0x4d`; `p.gms`/`q.gms` show `0x07` and `0x90`; `g.gms` shows `0x07` and `0xa3`), while
|
|
relative `+0x97` and `+0xc5` remain `0`. The compared 1.05 save set is tighter now too:
|
|
`Autosave.gms` and `nom.gms` cluster together on `Alternate USA.gmp` with `+0x82 = 0x4d`,
|
|
`g.gms` carries `Spanish Mainline.gmp` with `+0x82 = 0xa3`, and `p.gms`/`q.gms` cluster on
|
|
`Southern Pacific.gmp` with `+0x82 = 0x90`; across all five files the same inferred analogue
|
|
lane at `+0x77` stays fixed at `0x07`, while the same map- or scenario-sensitive tail word at
|
|
`+0x80` tracks those `0x4d/0xa3/0x90` byte lanes (`0x364d0000`, `0x29a30000`, `0x1b900000`).
|
|
The leading dword at `+0x00` also splits the same corpus, with `Autosave.gms` alone at `3` and
|
|
the other four checked 1.05 saves at `5`. That is enough to say the wider save corpus does
|
|
contain nonzero candidates for two of the atlas-tracked profile lanes, and that one of them
|
|
varies coherently with the loaded scenario family, but not yet enough to claim that the 1.05
|
|
block reuses the exact same semantic field assignments as the classic one. The loader-side
|
|
family split is tighter now too: `p.gms` and `q.gms` no longer live under a generic fallback;
|
|
their save headers now classify as one explicit `rt3-105-scenario-save` branch with preamble
|
|
words `0x00040001/0x00018000/0x00000746` and the early secondary window
|
|
`0x00130000/0x86a00100/0x21000001/0xa0000100`, while `g.gms` now classifies as a second
|
|
explicit `rt3-105-alt-save` branch with the different preamble lane
|
|
`0x0001c001/.../0x00000754` and early window
|
|
`0x00010000/0x49f00100/0x00000002/0xa0000000`. That branch now carries the same bootstrap,
|
|
anchor-cycle, named 1.05 trailer, and narrow profile-block extraction path as the other 1.05
|
|
saves. The bridge just below that trailer is now explicit too: the common 1.05 save branch
|
|
carries selector/descriptor `0x7110 -> 0x7801` in `Autosave.gms` and `0x7110 -> 0x7401` in
|
|
`nom.gms`, and both still reach the same first later candidate at
|
|
`span_target + 0x189c`, well before the packed profile at `span_target + 0x3d48`; the
|
|
`rt3-105-alt-save` branch instead carries `0x54cd -> 0x5901` and its first later candidate
|
|
lands at `packed_profile + 0x104`, essentially on the profile tail; the scenario-save branch
|
|
still diverges locally with `0x0001 -> 0x0186` and never enters that later `0x32c8`-spanned
|
|
bridge at all. The common-branch bridge payload is narrower now too: both checked base saves
|
|
expose the same 0x20-byte primary block at `0x4f14` followed by the same denser secondary block
|
|
at `0x671c`, `0x1808` bytes later, and that secondary block now appears to run intact up to the
|
|
packed-profile start at `0x73c0` for a total observed span of `0xca4` bytes. The trailing slice
|
|
of that secondary block is now typed one level further: a small header at `secondary+0x354`
|
|
carries the observed stride `0x22`, capacity `0x44`, and count `0x43`, followed by a fixed-width
|
|
67-entry name table starting at `secondary+0x3b5` and running through names like
|
|
`AluminumMill`, `AutoPlant`, `Bakery`, `Port00..11`, and `Warehouse00..11`, with a short footer
|
|
(`dc3200001437000000`) after the last entry. The trailing per-entry word is now surfaced too:
|
|
most entries carry `0x00000001`, while the currently observed zero-trailer subset is
|
|
`Nuclear Power Plant`, `Recycling Plant`, and `Uranium Mine`. That footer is tighter now too:
|
|
it parses directly as `0x32dc`, `0x3714`, and one trailing zero byte, so the shared
|
|
map/save catalog currently ends on the same two grounded late-rehydrate progress ids that the
|
|
classic staged-profile band already exposed. The strongest structural read is therefore that the
|
|
entire `0x6a70..0x73c0` catalog region is shared verbatim between `Alternate USA.gmp` and the
|
|
derived `Autosave.gms`, not rebuilt independently during save. Combined with the earlier
|
|
grounded record-layout work under `0x00437743`, `0x00434ea0`, and `0x00434f20`, the current
|
|
safest semantic read is that this shared catalog is the bundled source form of the scenario-side
|
|
named candidate-availability table later mirrored into `[state+0x66b2]`, with each entry's
|
|
trailing dword now reading as the same availability override bit later copied into
|
|
`[candidate+0x7ac]`. The candidate-side refresh strip is tighter now too: `0x00412c10` walks
|
|
the live candidate pool, forces `[candidate+0x7ac] = 1` whenever availability bytes
|
|
`[candidate+0xba/+0xbb]` are already set or subtype `[candidate+0x32]` is not `2`, and only for
|
|
the remaining subtype-`2` records does it consult `0x00434ea0` by stem before tailing into the
|
|
dependent cargo-economy filter rebuild `0x0041eac0`. The adjacent collection helpers also read
|
|
cleanly now: `0x00412bd0` is the collection-wide `0x00411ee0` cargo-summary rebuild sweep over
|
|
imported `0xbc` descriptor arrays, while `0x00412ba0` is the remove-and-release sibling that
|
|
clears one candidate's dependent runtime descriptor and cargo-membership tables through
|
|
`0x00411cb0` before erasing that id from the pool. One lower runtime detail is explicit now too:
|
|
`0x00411ee0` does not just “refresh summary tables.” It rebuilds the two emitted cargo-id tables
|
|
at `[candidate+0x79c]` and `[candidate+0x7a0]` from one temporary `0x35`-cargo mark band, stores
|
|
their counts at `[candidate+0x7a4]` and `[candidate+0x7a8]`, and accumulates the scaled runtime
|
|
rates into `[candidate+0xa1..+0xb8]`; mode-`0` descriptor rows use the shared production cap at
|
|
`[candidate+0x2a]` divided by the descriptor amount, while nonzero mode rows bypass that cap
|
|
scaling. The loader-side coverage is tighter now too:
|
|
the same table parser now
|
|
attaches both to the common-save bridge payload and directly to the fixed source range in
|
|
`.gmp` files and the non-common `rt3-105-scenario-save` / `rt3-105-alt-save` branches. That
|
|
makes the scenario variation explicit instead of anecdotal. `Alternate USA` keeps only three
|
|
zero-availability names in this table (`Nuclear Power Plant`, `Recycling Plant`, `Uranium
|
|
Mine`), `Southern Pacific` widens the zero set to twelve (`AutoPlant`, `Chemical Plant`,
|
|
`Electric Plant`, `Farm Rubber`, `FarmRice`, `FarmSugar`, `Nuclear Power Plant`, `Plastics
|
|
Factory`, `Recycling Plant`, `Tire Factory`, `Toy Factory`, `Uranium Mine`), and `Spanish
|
|
Mainline` widens it again to forty-two, including `Bauxite Mine`, `Logging Camp`, `Oil Well`,
|
|
`Port00`, and the `Warehouse00..11` run while also flipping `Recycling Plant` back to
|
|
available. The header lanes just ahead of the table vary coherently with those scenario
|
|
branches too: `Alternate USA` carries `header_word_0 = 0x10000000`, `Southern Pacific`
|
|
carries `0x00000000`, and `Spanish Mainline` carries `0xcdcdcdcd`, while the structural
|
|
fields from `header_word_2` onward remain stable (`0x332e`, `0x1`, `0x22`, `0x44`, `0x43`)
|
|
and the 9-byte footer still decodes as `0x32dc`, `0x3714`, `0x00` in all three checked maps.
|
|
A wider corpus scan over the visible `.gmp`/`.gms` files makes those two anonymous header
|
|
lanes less mysterious too: the parser currently sees only three stable
|
|
`(header_word_0, header_word_1)` pairs across 79 files with this table shape, namely
|
|
`(0x00000000, 0x00000000)`, `(0x10000000, 0x00009000)`, and
|
|
`(0xcdcdcdcd, 0xcdcdcdcd)`. The zero-availability count varies widely underneath the first and
|
|
third pairs (`0..56` under the zero pair, `14..67` under the `0xcdcdcdcd` pair), so those two
|
|
lanes no longer look like counts or direct availability payload; the safest current read is
|
|
that they are coarse scenario-family or source-template markers above the stable
|
|
`0x332e/0x22/0x44/0x43` table header, with `0xcdcdcdcd` still plausibly acting as one reused
|
|
filler or sentinel lane rather than a meaningful numeric threshold. Current exported
|
|
disassembly notes still do not ground one direct loader-side or editor-side consumer of
|
|
`header_word_0` or `header_word_1` themselves, so that family-marker read remains an
|
|
inference from corpus structure rather than a named field assignment.
|
|
The new loader-side compare command makes the save-copy claim sharper too: for the checked
|
|
pairs `Alternate USA.gmp -> Autosave.gms`, `Southern Pacific.gmp -> p.gms`, and
|
|
`Spanish Mainline.gmp -> g.gms`, the parsed candidate-availability table contents now match
|
|
exactly entry-for-entry, with the only reported differences being the outer container family
|
|
(`map` vs `save`) and source-kind path (`map-fixed-catalog-range` vs the save-side branch).
|
|
has the explicit companion `world_refresh_selected_year_bucket_scalar_band` `0x00433bd0`, which
|
|
rebuilds the dependent selected-year bucket floats after the packed year changes; and then
|
|
rehydrates the named locomotive availability collection at `[world+0x66b6]` through
|
|
`locomotive_collection_refresh_runtime_availability_overrides_and_usage_state` `0x00461e00`.
|
|
That locomotive-side restore is tighter now too: its tail explicitly re-enters
|
|
`scenario_state_refresh_cached_available_locomotive_rating` `0x00436af0`, which rebuilds one
|
|
cached available-locomotive rating at `[state+0x4cbe]` from the current year plus the strongest
|
|
surviving available locomotive-side rating scalar `[loco+0x20]`, and the tiny query sibling
|
|
`0x00434080` is now bounded as the shell-side clamped read helper over that same cached field,
|
|
with the grounded shell-side reader later bucketing that value against `40/50/70/85/100`. The
|
|
same rehydrate band also refreshes the live structure-candidate filter and year-visible counts
|
|
through `structure_candidate_collection_refresh_filter_and_year_visible_counts` `0x0041e970`,
|
|
rebuilding the paired per-slot bands at `[candidates+0x246]` and `[candidates+0x16e]` and the
|
|
aggregate counts at `[candidates+0x31a]` and `[candidates+0x242]`; the same late checkpoint also
|
|
re-enters `placed_structure_collection_seed_candidate_subtype2_runtime_latch` `0x00434d40`,
|
|
which seeds runtime dword `[candidate+0x7b0]` across subtype-`2` candidate records before the
|
|
later world-wide reactivation sweep. That checkpoint also now has an explicit shell-facing scalar
|
|
publisher: `world_publish_shell_controller_progress_scalar_from_year_thresholds_or_selector_overrides`
|
|
`0x004354a0` writes one clamped `0..255` value into the current shell presentation object,
|
|
sourcing it either from the shell selector override pairs or from the scenario-side year-threshold
|
|
band rooted at `[state+0x3a/+0x51/+0x55/+0x59/+0x5d/+0x61]`; and just ahead of the later
|
|
scenario-side recipe rebuild, the same band also re-enters
|
|
`scenario_state_ensure_derived_year_threshold_band` `0x00435603`, which only falls into its
|
|
heavier rebuild body while `[state+0x3a] < 2` and otherwise leaves the derived year-threshold
|
|
companion slots `[state+0x51/+0x55/+0x59/+0x5d/+0x61]` unchanged. The neighboring late status
|
|
checkpoints around progress ids `0x196` and `0x197` also share one explicit stage gate now:
|
|
`world_query_global_stage_counter_reached_late_reactivation_threshold` `0x00444dc5` compares the
|
|
global counter `0x00620e94` against threshold `0x9901`, and the two current callers use a
|
|
negative result to clear `[world+0x39]` before the broader world and shell reactivation sweep.
|
|
The later reactivation tail is tighter now too: it includes the region-center world-grid flag
|
|
reseed pass
|
|
`0x0044c4b0`, which clears bit `0x10` across the live grid and then marks one representative
|
|
center cell for each class-`0` region through `0x00455f60`; its immediate sibling `0x0044c450`
|
|
then reruns `placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` across every
|
|
live grid cell. The small secondary-raster premark helper `0x0044c570` is bounded now too: it
|
|
only admits cells whose current raster byte has no bits in mask `0x3e` and whose parallel class
|
|
query `0x00534e10` is false, then rewrites that masked class field to `0x02` and widens the same
|
|
cached bounds-and-count band `[world+0x21c6..+0x21d6]`. The next helper `0x0044ce60` scans the secondary raster at `[world+0x2135]`
|
|
for cells with any bits in mask `0x3e`, caching min/max bounds plus a marked-cell count in
|
|
`[world+0x21c6..+0x21d6]`; the larger sibling `0x0044c670` then consumes those cached bounds to
|
|
normalize the same raster and rebuild one dependent overlay/cache surface before the later
|
|
route-style rebuild, shell-window, and briefing branches. That overlay side is tighter now too:
|
|
after `0x0044c670` resolves scaled surface dimensions through `0x00534c50`, it walks one local
|
|
`3 x 32` sample lattice through the static offset tables at `0x00624b28/0x00624b48`, keeps only
|
|
secondary-raster classes `4..0x0d`, folds several interpolated `0x0051db80` samples into one
|
|
strongest local score, writes packed overlay pixels into the staged surface buffer, and only then
|
|
publishes that staged overlay through `0x00534af0`. The lower helper layer under that overlay
|
|
pass is tighter now too: `0x00534e10` is the reusable secondary-raster class-set
|
|
predicate for classes `1/3/4/5`, `0x00534e50` is the smaller neighboring class-subset predicate
|
|
for `1/4`, `0x00534ec0` covers `2/4/5`, `0x00534f00` covers `3/5`, `0x00534e90` is the
|
|
marked-bit query over the same 3-byte cell family, and the nearby local counter `0x0044bdb0`
|
|
is now bounded as the 8-neighbor count companion for that same `2/4/5` subset, walking the
|
|
shared `0x00624b28/0x00624b48` offset tables and re-entering `0x00534ec0` on each bounded
|
|
neighbor cell. The first caller cluster around `0x0044bf9d..0x0044c37b` therefore reads as a
|
|
secondary-raster neighborhood service band rather than a generic map scan.
|
|
`0x00533e70` and `0x00534160` are the coarser siblings over the overlay table at `[world+0x1685]`:
|
|
the first clears coarse chunk objects across one clamped rectangle, while the second ensures one
|
|
chunk object and seeds local marks through its deeper stamp helper. One level up, the neighboring
|
|
rect owner `0x005374d0` now reads as the shared secondary-overlay refresh pass: it reruns the
|
|
local sample and unsigned-word reducers `0x00536230/0x00536420`, rebuilds the signed vector byte
|
|
planes through `0x00536710`, and then rebuilds the multiscale support surfaces through
|
|
`0x00533890`, whose inner reducers now explicitly target the packed sample-triplet buffer plus
|
|
the float and unsigned-word support planes rooted at the five-entry per-scale families
|
|
`[world+0x15f1..+0x1601]`, `[world+0x1605..+0x1615]`, and `[world+0x1619..+0x1629]`. The setup
|
|
side of that same family is tighter now too:
|
|
`0x005375c0` is the shared ensure-and-seed owner that allocates the sample, sidecar, mask,
|
|
raster, vector, and coarse-cell tables together; crucially, it seeds `[world+0x1655]` with byte
|
|
`0x02` and `[world+0x1659]` with byte `0x01`, which closes the default-fill split. The local
|
|
component-walk owner under the same neighborhood band is tighter now too: `0x0044c200`
|
|
allocates a temporary `width*height` visit bitmap at `0x0062c128`, seeds one class-`2/4/5`
|
|
starting cell, derives an initial direction index through the remap table `0x005ee5d4`, and then
|
|
fans into the deeper recursive walker `0x0044be20`. That deeper walker widens dirty bounds
|
|
`[world+0x21ad..+0x21b9]`, stamps one companion-word orientation lane through `0x005ee5cc`,
|
|
reuses `0x00534ec0` plus `0x0044bdb0` to filter admissible neighbors, tracks temporary
|
|
visitation in `0x0062c128`, and then applies the local byte-1 edge-bit `0x04/0x08` updates
|
|
before returning. So the `0x0044bf9d..0x0044c422` cluster now reads as a real connected-component
|
|
walk plus edge-flag refresh layer over the secondary raster rather than only a loose group of
|
|
local neighbor counters. The adjacent mutation strip is tighter now too: `0x0044dcf0` refreshes
|
|
companion-word bit `0x200` in one local rectangle by checking whether any neighbor belongs to
|
|
class set `2/4/5`, while `0x0044df10` clears three local sidecar byte planes, demotes class `4`
|
|
to `1` and class `5` to `3`, and then reruns that marked-bit refresh over the surrounding
|
|
`+/-1` window. One level up, `0x0044e500` is the rect-wide owner that recomputes byte-1 edge
|
|
bits `0x04/0x08` for class-`2/4/5` cells, dispatches `0x0044df10` on incompatible local
|
|
patterns, and finally consumes the pending global seed pair at `[0x006d1304+0x78/+0x7c]`
|
|
through `0x0044c200`. The shell-side owner of that pending pair is tighter now too:
|
|
`[0x006d1304]` is the live `PaintTerrain.win` shell singleton while the callback-heavy side also
|
|
keeps a second rooted pointer at `0x006d1334`; the tool constructor snapshots the broader
|
|
terrain-paint state into both families while the world-side raster owner still only consumes
|
|
`[0x006d1304+0x78/+0x7c]` as one pending component-seed pair. Its radial sibling `0x0044e7d0`
|
|
is narrower:
|
|
after validating world-space
|
|
coordinates through `0x00414bd0`, it stamps class-`2` marks into the secondary raster by walking
|
|
one clamped bounding box and admitting cells only when the radial falloff helper `0x0051db80`
|
|
stays positive before re-entering `0x0044c570`. The two small support predicates under that same
|
|
strip are now explicit too: `0x00414bd0` is the float grid-bounds gate, and `0x00449df0` is the
|
|
integer rectangle clamp-and-validity helper shared by the local mutation owners. One level up,
|
|
the broader rect-scoped owner is tighter now too:
|
|
`world_rebuild_secondary_raster_derived_surface_and_companion_planes_in_rect` `0x0044e940`
|
|
first reclamps the caller rectangle through `0x00449df0`, reruns the local edge-refresh owner
|
|
`0x0044e500`, lazily ensures one presentation target through
|
|
`0x0051f090/0x00534910/0x00534920/0x00534930`: the first helper resolves the shared
|
|
world-presentation owner, `0x00534910/0x00534920` expose the current staging flag and buffer
|
|
root, and `0x00534930` captures one normalized-bounds rect into that staging buffer before the
|
|
later publish step `0x00534af0`. The same family then resolves scaled target dimensions through
|
|
`0x00534c50` before allocating one temporary `width*height` mask. Its main scan then
|
|
walks the live secondary raster `[world+0x165d]` through the same class predicates
|
|
`0x00534e10/0x00534e50/0x00534f00/0x00534ec0`: class-`1/3/4/5` cells force `0xff` into the four
|
|
sidecar byte planes `[world+0x1631..+0x163d]`, while the broader per-cell pass writes packed
|
|
values into the ensured target through `0x00534730` and also updates nibble lanes at byte offsets
|
|
`+0x2` and `+0x5` inside the same three-byte secondary-raster cell family. After the publish it
|
|
notifies the shell owner at `0x0062be68`, re-enters `0x00449f80` and `0x004881b0`, frees the
|
|
temporary mask, expands the caller rectangle by dirty bounds `[world+0x21ad..+0x21b9]` through
|
|
`0x00536710`, and finally seeds companion byte `[world+0x162d]` with `0xc4` on cells selected
|
|
from mask plane `[world+0x1655]`. So the `0x0044e500 -> 0x0044e940` band is now a real
|
|
derived-surface and companion-plane rebuild family rather than only a loose collection of local
|
|
raster mutations. The local
|
|
evidence now also supports a stronger negative conclusion: unlike `[world+0x1655]`, that second
|
|
mask plane is not part of the actively rebuilt runtime overlay path, and in the grounded local
|
|
corpus it behaves only as a separately seeded, cleared, and persisted sibling plane. One level
|
|
lower, the
|
|
base-plane allocator `0x00532c80` now reads more cleanly too: it is the narrower owner that
|
|
clears `[world+0x15e1]`, optionally applies the current grid dimensions, allocates the base
|
|
float-summary plane `[world+0x1605]`, the four sidecar byte planes `[world+0x1631..+0x163d]`,
|
|
both one-byte mask planes `[world+0x1655/+0x1659]`, and the packed secondary raster
|
|
`[world+0x165d]`, then seeds those planes with the same `0x02/0x01/0x00` default split. The
|
|
load-side owner for those same planes is tighter now too: the constructor thunk `0x0044e910`
|
|
immediately feeds the heavier payload body `0x0044cfb0`, which reads the rooted chunk families
|
|
`0x2ee2/0x2ee3/0x2ef4/0x2ef5/0x2ef6/0x2ee4/0x2ee5/0x2f43/0x2f44`, allocates the core world-grid
|
|
and secondary-raster arrays `[world+0x2129..+0x2141]` plus the route-entry collection
|
|
`0x006cfca8`, initializes every grid-cell record through `0x0042ae50`, and only then hands off
|
|
into `world_compute_transport_and_pricing_grid` `0x0044fb70`, the neighboring presentation
|
|
refresh `0x00449f20`, and the shell-mode pulse `0x00484d70`. So the `0x0044e910 -> 0x0044cfb0`
|
|
load side is now bounded as the heavy world-grid and secondary-raster bundle-load body rather
|
|
than just another anonymous constructor tail. One
|
|
level higher again, the broader world-presentation reinitializer `0x00537e60` now sits above
|
|
that base allocator and the larger support-family ensure path `0x005375c0`: it stores the live
|
|
grid dimensions, hard-resets the whole overlay runtime family through `0x00532590`,
|
|
and that reset strip is no longer opaque either: the immediately preceding local helpers
|
|
`0x00532310..0x00532550` now bound one compact overlay-local state family under the same owner.
|
|
`0x00532310/0x00532360/0x00532370/0x00532380` own the seven-dword companion block
|
|
`[world+0x15b5..+0x15cd]` together with live flag byte `[world+0x15b4]`; `0x005323f0`,
|
|
`0x00532460`, and `0x00532490` are the ensure, publish, and query strip for cached surface root
|
|
`[world+0x478]` using saved dimensions `[world+0x159c/+0x15a0]`; `0x005324e0/0x00532500` are the
|
|
live-flag setters for `[world+0x159b]`; `0x00532510` is the direct setter for mode byte
|
|
`[world+0x159a]`; and `0x00532520/0x00532550` own the four-dword saved dimension quad
|
|
`[world+0x15a4..+0x15b0]`. So the broader `0x00532590` reset really does sit at the base of a
|
|
concrete local cached-surface and companion-block owner family, not just a pile of unrelated
|
|
presentation fields. The reinitializer then
|
|
reinitializes the secondary-overlay family for those dimensions, and then republishes the
|
|
neighboring overlay constants and support owners used by both the world-side reattach branch and
|
|
the `.smp` restore-side presentation rebuild path, including several owners that all funnel
|
|
through the shared static-template slot allocator `0x00532ad0` over the local `0x100` pointer
|
|
band at `[world+0x08]`. Those neighboring owners are tighter now too: `0x00535070` is the small
|
|
primary overlay-surface-or-template setup owner; `0x00535100` is the heavier requested-dimension
|
|
apply and four-slot overlay-surface rebuild owner used by the setup-side regenerate branch and
|
|
the load-side bundle path; while `0x005356e0` and `0x00535890` seed two
|
|
larger static-template slot bands rooted at `[world+0x1568/+0x156c/+0x1574/+0x1578]` and
|
|
`[world+0x1560/+0x1564]` respectively; the remaining heavier sibling `0x00535430` now reads as a
|
|
shared four-slot overlay-surface rebuild owner that resamples one source or fallback descriptor
|
|
into a short local slot strip above `[world+0x155c]`. The immediate helper strip under that same
|
|
family is tighter now too: `0x00534f60` is the small presentation-owner base init above
|
|
`0x00532590`; `0x00534f80` releases one transient surface handle at `[world+0x478]` and clears
|
|
byte `[world+0x159b]`; `0x00532760` releases the current overlay slot chosen by selector
|
|
`[world+0x1558]`; `0x005327a0` clamps two requested surface dimensions down to supported
|
|
power-of-two sizes while also enforcing shell display caps from `[0x006d4024+0x114243/+0x114247]`;
|
|
`0x00532860` is the local twelve-slot stitching pass over the parallel bands rooted at
|
|
`[world+0x08/+0x0c/+0x18]`, copying terminal rows and edge dwords between those sibling slot
|
|
surfaces before finalizing the primary band through `0x00541c10`;
|
|
`0x00532960` is the adjacent paired projection helper that maps two caller counters through the
|
|
current `16x16` and `4x4` rounded grid quanta and writes the resulting coarse offsets back to two
|
|
out-pointers;
|
|
`0x005329e0` maps one `(x,y)` pair into a `1`-based coarse `4x4` overlay region id using the
|
|
current rounded grid dimensions; `0x00532a30` is the direct getter for local dword `[world+0x1554]`,
|
|
which still reads only as the live count or tag for this overlay slot band;
|
|
`0x00532a40` and `0x00532aa0` are the time-selected query helpers over the first and second
|
|
template-seeded slot bands rooted at `[world+0x1568/+0x156c]` and `[world+0x1560/+0x1564]`; and
|
|
`0x00532a90` is the direct getter for trailing fallback slot `[world+0x1578]`. The next adjacent
|
|
owner is tighter now too: `0x00532b30` is the shared release/reset path for the local overlay
|
|
slot band at `[world+0x08]`, with a split release policy keyed by shell flag
|
|
`[0x006d4024+0x11422e]` and a special forced-direct range for slot ids `1..0x10`, after which it
|
|
clears band fields `[world+0x1554/+0x1568/+0x1570/+0x155c/+0x1560/+0x1564]`. The tail of that
|
|
same reinitializer is tighter one level up too: `0x00527ce0` is the broader ensure owner that
|
|
watches current grid extents plus world tag `[world+0x2121]`, re-enters `0x00532860` when those
|
|
cached values change, rebuilds or releases local helper `[this+0x65]`, and then clears the two
|
|
large global scratch planes rooted at `0x008f2520` and `0x00b33530`. The tail of that same
|
|
reinitializer is
|
|
tighter now too: after the larger support-family setup it seeds one seven-entry default overlay
|
|
companion set through `0x005373b0`, whose inner allocator `0x00535950` populates the local
|
|
`0x1b`-entry slot table from the static template rows `0x005dd300..0x005dd378`. The lifecycle
|
|
side is tighter in the same way now: `0x00536044` is the shared teardown owner that frees those same
|
|
three five-entry support families together with both mask planes, the packed secondary raster,
|
|
the vector-byte planes, the local staging buffer, and the neighboring sidecar or coarse-cell
|
|
tables. The remaining base-float lane is tighter too: the larger rebuild owner
|
|
`0x00538360` now clearly writes one base float-summary field into `[world+0x1605]`, clears both
|
|
one-byte mask planes, and then only repopulates the primary mask plane `[world+0x1655]` for the
|
|
qualifying class-`1` interior cells before re-entering `0x00532d90` to normalize that base
|
|
float-summary plane globally and `0x00532f60` to expand positive cells through one caller radius.
|
|
That asymmetry is now enough to close the local semantic edge: `[world+0x1655]` is the actively
|
|
rebuilt primary overlay mask, while `[world+0x1659]` is only the separately seeded and persisted
|
|
secondary mask sibling with no comparably grounded distinct read-side consumer. The only grounded
|
|
getter call to its root accessor `0x00533b60` is the shell staging branch at `0x00525bad`, and
|
|
that branch immediately discards the returned pointer. The bundle side is now explicit too:
|
|
`.smp` save-load treats the two mask planes as separate payloads with chunk ids `0x2cee` for
|
|
`[world+0x1655]` and `0x2d51` for `[world+0x1659]`, while the neighboring `0x2d49/0x2d50`
|
|
branches are the separate packed secondary-raster import lanes rather than alternate consumers
|
|
of the second mask plane. So, in the mapped local code, `0x1659` is best treated as a persisted
|
|
compatibility or seed-state sibling, not as a second actively consumed runtime overlay mask. The
|
|
transport/pricing preview side is tighter now too: `0x00538060` sits directly beneath
|
|
`0x0044faf0`, first seeds one preview handle through `0x00535430` using the short `C_`
|
|
descriptor, temporarily overrides shell globals
|
|
`[0x006d4024+0x11423b/+0x11423f/+0x114254/+0x114255]`, and then loads `%1.tga` through
|
|
`0x0053c1c0 -> 0x00541970`. It clamps that sampled image into the `0x401 x 0x401` range,
|
|
rewrites `[world+0x1605]` plus the mask/raster family `[world+0x1655/+0x1659/+0x165d]` from the
|
|
sampled pixels, optionally re-enters `0x00532d90/0x00532f60`, republishes the seeded preview
|
|
handle through `0x0053c000`, and then re-enters `0x005375c0(1, 0, 0)`. The small shell-global
|
|
owner it also touches is tighter now too: `0x006d401c` is constructed by `0x00538640`,
|
|
`0x005386e0` publishes the primary timed text lane, `0x005387a0` publishes the secondary fixed
|
|
`10000` ms lane, `0x00538810` finds the first registered shell window containing one child
|
|
control id by walking each window through `0x0053f830`, and `0x00538840/0x00538880/0x00538890`
|
|
manage the owner's local `1000`-slot active-token table keyed by child control id. The adjacent
|
|
list strip is tighter too: `0x00538990` is the registered-window virtual-slot-`0` gate that
|
|
stops on the first zero return, `0x005389c0` is the shared unlink helper for the same doubly
|
|
linked list rooted at `[owner+0x00/+0x04]`, `0x00538a60` is the zero-counter gate over
|
|
`[owner+0xc60]`, `0x00538a70` is the matching full reset-and-release body used during bootstrap
|
|
teardown, and `0x00538a10/0x00538a20/0x00538a30/0x00538a40` are the direct getter, setter,
|
|
increment, and clamped decrement helpers for the owner's scalar lanes `[+0xc5c]` and `[+0xc60]`.
|
|
The next shell-runtime strip is tighter now too: `0x005388d0` is the shared `12`-dword
|
|
descriptor dispatcher with the optional override validator at `[owner+0xc75]` and the recursive
|
|
`kind 6 -> 0xb7` rewrite; `0x00538c70` is the prioritized cached-text owner over
|
|
`[owner+0xbd8/+0xbdc/+0xbe0/+0xbe4]` that emits descriptor kind `0xae` through `0x005388d0`;
|
|
`shell_dispatch_synthetic_12_dword_descriptor_from_five_scalars` `0x00538e00` is the five-scalar
|
|
descriptor-synthesis wrapper above that same dispatcher;
|
|
`0x00538e50` is the sorted registered-window insert owner over node key `[node+0x21]`;
|
|
`0x00538ec0` is the refresh sweep over the indexed helper collection rooted at `[owner+0xc69]`;
|
|
and `0x00538f10` is the broader optional-window publish plus blocking descriptor loop used by
|
|
modal launchers and some shell transition paths.
|