2026-04-01 23:15:20 -07:00
|
|
|
Analysis and reimplementation of Railroad Tycoon 3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The old executable is at ./rt3_wineprefix/drive_c/rt3/RT3.exe
|
|
|
|
|
|
2026-04-02 23:11:15 -07:00
|
|
|
Our first task is to understand the executable's high-level control loops and subsystem boundaries well
|
|
|
|
|
enough to choose good rewrite targets. As we go, we document evidence, keep a curated function map,
|
|
|
|
|
and stand up Rust tooling that can validate artifacts and later host replacement code.
|
2026-04-01 23:15:20 -07:00
|
|
|
|
2026-04-02 23:11:15 -07:00
|
|
|
The long-term direction is still a DLL we can inject into the original executable, patching in
|
2026-04-14 19:37:53 -07:00
|
|
|
individual functions as we build them out. The active implementation milestone is now a headless
|
|
|
|
|
runtime rehost layer that can execute deterministic world work, compare normalized state, and grow
|
2026-04-14 22:09:09 -07:00
|
|
|
subsystem breadth without depending on the shell or presentation path. The current packed-event
|
2026-04-15 09:50:58 -07:00
|
|
|
frontier is broader real grouped-descriptor coverage on top of the existing save-slice, snapshot,
|
2026-04-15 09:13:51 -07:00
|
|
|
overlay-import, compact-control, and symbolic company-target workflows. The runtime already carries
|
2026-04-15 12:11:29 -07:00
|
|
|
selected-company and controller-role context through overlay imports, and real descriptors `2`
|
|
|
|
|
`Company Cash`, `13` `Deactivate Company`, and `16` `Company Track Pieces Buildable` now parse and
|
2026-04-15 23:24:08 -07:00
|
|
|
execute through the ordinary runtime path, and descriptors `1` `Player Cash` and `14`
|
|
|
|
|
`Deactivate Player` now join that batch through the same service engine. Synthetic packed records
|
|
|
|
|
still exercise the same runtime without a parallel packed executor. The first grounded
|
2026-04-16 18:03:17 -07:00
|
|
|
chairman-profile runtime slice now exists too: save-slice or overlay-backed chairman/company
|
|
|
|
|
context plus the hidden grouped target-subject lane let those same real descriptors `1` and `14`
|
|
|
|
|
execute on the grounded chairman scope ordinals `0..3` (`condition_true`, `selected`, `human`,
|
|
|
|
|
`ai`), while wider chairman ordinals remain explicit parity. The first grounded
|
2026-04-16 17:30:42 -07:00
|
|
|
chairman and governance condition batch is broader now: selected-chairman cash / holdings / net
|
|
|
|
|
worth / purchasing-power thresholds and company book-value-per-share / investor-confidence /
|
|
|
|
|
management-attitude thresholds now import through the normal event-service path, while wider
|
2026-04-16 18:03:17 -07:00
|
|
|
chairman ordinals remain explicit frontier. Checked-in save-slice
|
2026-04-16 17:08:03 -07:00
|
|
|
documents can now also carry explicit company rosters and chairman-profile tables, so the current
|
|
|
|
|
company-targeted and chairman-targeted descriptor and condition batches can execute from standalone
|
|
|
|
|
save-slice fixtures without overlay snapshots when that context is present; raw `.gms` inspection
|
2026-04-17 14:56:41 -07:00
|
|
|
now reconstructs both collections automatically: the fixed save-side `0x32c8` world block still
|
2026-04-17 17:10:43 -07:00
|
|
|
supplies selected company/chairman ids plus the campaign override byte, the grounded issue-`0x37`
|
|
|
|
|
value/multiplier pair, and chairman slot/role-gate analysis bytes, and the tagged company /
|
|
|
|
|
chairman-profile direct-record families now populate
|
2026-04-17 14:56:41 -07:00
|
|
|
save-native roster entries for real `.gms` imports and exports. The current raw-save boundary is
|
|
|
|
|
narrower now: company/chairman identity, active flags, links, chairman cash, chairman holdings,
|
2026-04-17 16:36:48 -07:00
|
|
|
chairman purchasing power, company debt, and company track-laying capacity are grounded directly
|
|
|
|
|
from save records, while
|
2026-04-17 14:56:41 -07:00
|
|
|
broader company finance/governance scalars and controller-kind reconstruction still remain
|
|
|
|
|
conservative defaults until their raw lanes are pinned more strongly. The offline runtime analysis
|
|
|
|
|
surface also now exposes `runtime inspect-save-company-chairman <save.gms>` for those remaining raw
|
2026-04-17 15:18:13 -07:00
|
|
|
company/chairman scalar candidates, including fixed-world chairman slot / role-gate context,
|
2026-04-17 16:36:48 -07:00
|
|
|
explicit company dword candidate windows, richer chairman qword cache views, and derived
|
|
|
|
|
holdings-at-share-price / cached purchasing-power comparisons. The same fixed `0x32c8` world
|
2026-04-17 22:14:08 -07:00
|
|
|
block is now probed for the grounded issue-`0x37` pair at `[world+0x29/+0x2d]`, and the adjacent
|
|
|
|
|
raw issue-byte strip `0x37..0x3a` now also flows through save-slice/runtime restore state as
|
|
|
|
|
first-class owner data for later credit / prime-rate / management-attitude readers. One broader
|
2026-04-17 22:00:12 -07:00
|
|
|
fixed-dword finance neighborhood rooted at `[world+0x0d]` that now carries the saved calendar
|
|
|
|
|
tuple and absolute-counter owner lanes directly, and the separate
|
2026-04-17 18:58:41 -07:00
|
|
|
six-float economic tuning band, but current atlas evidence still keeps that editor-facing
|
2026-04-17 17:10:43 -07:00
|
|
|
tuning family distinct from the governance issue lanes behind investor confidence and prime-rate
|
2026-04-17 18:28:53 -07:00
|
|
|
math. The next shared company-side slice is now rehosted too: save-native company direct records
|
|
|
|
|
flow into a typed company market/cache map on runtime service state, carrying outstanding shares,
|
|
|
|
|
saved support/share-price/cache words, chairman salary lanes, calendar words, and connection
|
|
|
|
|
latches for each live company. That map now appears in runtime summaries and save-slice exports,
|
2026-04-17 20:42:28 -07:00
|
|
|
and it now also carries the first grounded stat-band root windows at `[company+0x0cfb]`,
|
|
|
|
|
`[company+0x0d7f]`, and `[company+0x1c47]`, so later company stat-family / finance readers can
|
2026-04-17 20:46:23 -07:00
|
|
|
build on owned state instead of another round of single-field save-offset guesses. The first
|
|
|
|
|
runtime-side `0x2329` stat-family reader seam is now rehosted too for the currently grounded slots
|
|
|
|
|
`0x0d` (`current_cash`) and `0x1d` (`book_value_per_share`), so later annual-finance logic can
|
2026-04-17 20:49:07 -07:00
|
|
|
extend one shared reader family instead of hard-coding more direct field accesses. Those saved
|
2026-04-17 21:27:38 -07:00
|
|
|
stat-band windows are now widened to 32 dwords per root in save-slice/runtime state so later
|
|
|
|
|
year-series finance closure has a broader owned raw state band to attach to. The matching world-side issue
|
2026-04-17 20:50:35 -07:00
|
|
|
reader seam is now also rehosted for the grounded `0x37` investor-confidence lane on top of the
|
2026-04-17 20:55:42 -07:00
|
|
|
save-native world-restore state. The selected-company summary path now also exposes the
|
|
|
|
|
unassigned share pool derived from outstanding shares minus chairman-held shares, so later
|
|
|
|
|
dividend / stock-capital logic can extend one owned market reader instead of another ad hoc
|
2026-04-17 20:58:41 -07:00
|
|
|
counter. The next bundled annual-finance reader seam is now rehosted on top of that same market
|
|
|
|
|
state too, deriving assigned shares, public float, and rounded cached share price from one shared
|
|
|
|
|
company market reader instead of scattering more finance helpers across the runtime. A checked-in
|
2026-04-17 22:00:12 -07:00
|
|
|
The fixed-world finance neighborhood itself is now widened to 17 dwords rooted at `[world+0x0d]`,
|
2026-04-17 22:14:08 -07:00
|
|
|
so later finance closure can build on a broader owned restore-state window rather than another
|
|
|
|
|
narrow one-off probe; that same owner surface now also carries the saved absolute counter
|
2026-04-17 22:00:12 -07:00
|
|
|
as first-class runtime restore state instead of leaving it on “requires shell context” metadata.
|
2026-04-17 22:05:29 -07:00
|
|
|
The same save-world owner surface now also carries the packed year word and partial-year progress
|
|
|
|
|
lane behind the annual-finance recent-history weighting path, so later finance readers can attach
|
|
|
|
|
to real world-calendar state instead of candidate bytes.
|
2026-04-17 22:00:12 -07:00
|
|
|
The next company-side seam is now bundled too: a shared company
|
2026-04-17 21:04:23 -07:00
|
|
|
market reader now exposes outstanding shares, assigned shares, public float, rounded cached share
|
2026-04-17 21:34:53 -07:00
|
|
|
price, salary lanes, bonus amount, and the full two-word current/prior issue-calendar tuples from
|
|
|
|
|
the owned annual-finance state instead of leaving that logic spread across summary helpers. The
|
|
|
|
|
same annual-finance state now also
|
2026-04-17 21:07:41 -07:00
|
|
|
derives elapsed years since founding, last dividend, and last bankruptcy from the runtime calendar,
|
2026-04-17 21:16:42 -07:00
|
|
|
which lines up directly with the grounded annual finance-policy gates in the atlas. Live bond-slot
|
|
|
|
|
count is now carried through the same owned company market and annual-finance state too, which
|
2026-04-17 21:24:53 -07:00
|
|
|
matches the stock-capital branch gate that requires at least two live bonds. The same grounded
|
2026-04-17 21:31:28 -07:00
|
|
|
bond table now also contributes both the largest live bond principal and the chosen
|
|
|
|
|
highest-coupon live bond principal into owned company market and annual-finance state, so the
|
|
|
|
|
stock-capital approval ladder can extend one rehosted owner-state surface instead of hunting
|
2026-04-18 00:41:35 -07:00
|
|
|
another isolated finance leaf. The same bond-slot owner state now also exposes the highest live
|
|
|
|
|
coupon rate, which is enough to run the stock-capital price-to-book approval ladder as another
|
|
|
|
|
save-native runtime reader instead of a notes-only threshold table. A checked-in
|
2026-04-18 00:09:09 -07:00
|
|
|
fixed-world finance-policy seam now also carries the raw stock, bond, bankruptcy, and dividend
|
|
|
|
|
policy bytes from the `0x32c8` save block, and the first annual creditor-pressure branch now runs
|
|
|
|
|
headlessly as a pure runtime reader over owned annual-finance state, support-adjusted share price,
|
2026-04-18 00:13:31 -07:00
|
|
|
and current world finance policy rather than as a notes-only atlas fragment. The later deep-
|
|
|
|
|
distress bankruptcy fallback is now rehosted on that same owner surface too, using the save-native
|
|
|
|
|
cash reader seam plus the first three trailing net-profit years instead of another ad hoc probe.
|
2026-04-18 00:45:35 -07:00
|
|
|
The annual bond lane now runs on that same owner surface too, using the simulated post-repayment
|
|
|
|
|
cash window plus the linked-transit threshold split to stage `500000` principal issue counts as a
|
2026-04-18 01:00:21 -07:00
|
|
|
pure runtime reader. The annual dividend lane now runs there too: the runtime now rehosts the
|
|
|
|
|
shared year-or-control-transfer metric seam, the board-approved dividend ceiling helper, and the
|
|
|
|
|
full annual dividend adjustment branch over owned current cash, public float, current dividend,
|
|
|
|
|
building-growth policy, and recent profit history instead of leaving that policy on shell-side
|
2026-04-18 01:12:36 -07:00
|
|
|
dialog notes. `simulation_service_periodic_boundary_work` is now beginning to use that same owner
|
|
|
|
|
surface too: the runtime chooses one annual-finance action per active company and already commits
|
2026-04-18 01:38:42 -07:00
|
|
|
the shellless creditor-pressure-bankruptcy, deep-distress-bankruptcy, dividend-adjustment,
|
|
|
|
|
stock-repurchase, stock-issue, and bond-issue branches by mutating owned company activity,
|
|
|
|
|
dividend, company stat-post, outstanding-share, issue-calendar, and live bond-slot state instead
|
|
|
|
|
of stopping at reader-only diagnostics.
|
2026-04-18 01:48:09 -07:00
|
|
|
Those bankruptcy branches now follow the grounded owner semantics too: they stamp the bankruptcy
|
|
|
|
|
year and halve live bond principals in place instead of treating bankruptcy as a liquidation path.
|
2026-04-18 01:43:35 -07:00
|
|
|
The same save-native live bond-slot surface now also carries per-slot maturity years all the way
|
|
|
|
|
through runtime summaries and annual bond policy state, which is the next owner seam needed for
|
|
|
|
|
shellless repayment and bond-burden simulation instead of another round of raw-slot guessing.
|
2026-04-18 01:46:08 -07:00
|
|
|
That same seam now also derives the current live coupon burden directly from owned bond slots, so
|
|
|
|
|
later finance service work can consume a runtime reader instead of recomputing from scattered raw
|
|
|
|
|
fields.
|
2026-04-18 00:28:54 -07:00
|
|
|
The same seam now also carries the fixed-world building-density growth setting plus the linked
|
|
|
|
|
chairman personality byte, which is enough to run the annual stock-repurchase gate as another
|
|
|
|
|
pure reader over owned save-native state instead of a guessed finance-side approximation.
|
2026-04-18 00:13:31 -07:00
|
|
|
The working rule on the remaining frontier is explicit now too: when a lane is still ambiguous, we
|
2026-04-17 17:10:43 -07:00
|
|
|
should prefer rehosting the owning source state or the real reader/setter family rather than
|
|
|
|
|
guessing one more derived leaf field from nearby offsets. A checked-in
|
2026-04-16 19:03:07 -07:00
|
|
|
`EventEffects` export now exists too in
|
2026-04-16 20:20:41 -07:00
|
|
|
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer now
|
|
|
|
|
exists beside it in `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`. Recovered
|
|
|
|
|
descriptor rows now land on explicit semantic frontier buckets such as
|
|
|
|
|
`blocked_shell_owned_descriptor`, `blocked_evidence_blocked_descriptor`, and
|
|
|
|
|
`blocked_variant_or_scope_blocked_descriptor` instead of generic anonymous descriptor residue. The
|
|
|
|
|
first recovered governance descriptor tranche now imports through the generic
|
|
|
|
|
company-governance scalar effect surface:
|
2026-04-16 19:03:07 -07:00
|
|
|
descriptor `56` `Credit Rating` and descriptor `57` `Prime Rate` execute from ordinary real packed
|
|
|
|
|
rows, while adjacent recovered finance/control-transfer descriptors such as `55` `Stock Prices`
|
|
|
|
|
and `58` `Merger Premium` now land on explicit shell-owned parity instead of anonymous unmapped
|
2026-04-17 13:01:26 -07:00
|
|
|
descriptor residue, and tracked shell-owned fixtures now pin finance, scenario-outcome, and
|
|
|
|
|
control-transfer shell rows explicitly. The
|
2026-04-17 11:26:07 -07:00
|
|
|
recovered whole-game scalar economy/performance strip `59..104` now has a
|
2026-04-16 20:20:41 -07:00
|
|
|
bounded runtime landing surface too: representative descriptors import into
|
|
|
|
|
`RuntimeState.world_scalar_overrides` through stable normalized keys such as
|
|
|
|
|
`world.build_stations_cost`, `world.track_maintenance_cost`, `world.all_engine_speeds`, and
|
2026-04-17 08:18:34 -07:00
|
|
|
`world.hotel_revenue`. The runtime-variable strip `39..54` now executes too through bounded
|
2026-04-17 08:50:35 -07:00
|
|
|
event-owned scalar maps on world/company/player/territory state, and the matching ordinary
|
|
|
|
|
condition strip now gates records through those same maps too, without widening save-native
|
2026-04-17 08:18:34 -07:00
|
|
|
reconstruction or adding a second packed executor. The grounded aggregate cargo-economics
|
|
|
|
|
descriptors now have bounded
|
2026-04-16 21:42:20 -07:00
|
|
|
runtime landing surfaces too: descriptor `105` `All Cargo Prices` plus descriptors `177..179`
|
|
|
|
|
`All Cargo Production` / `All Factory Production` / `All Farm/Mine Production` import into
|
2026-04-16 23:44:55 -07:00
|
|
|
event-owned cargo override state, and the grounded named cargo-production strip `180..229` now
|
2026-04-17 13:41:44 -07:00
|
|
|
imports into named cargo production overrides too, and the named cargo-price strip `106..176` now
|
|
|
|
|
imports into named cargo price overrides as well. The checked-in static selector reconstruction is
|
|
|
|
|
now explicit: the broader 1.06 CargoTypes corpus has `51` names, the Cargo106 `cargoSkin` corpus
|
|
|
|
|
has `70`, and the rehosted offline selector builder now closes the `71`-row named price strip as
|
|
|
|
|
`cargoSkin` plus the core `Rock` carry-over. The checked-in
|
2026-04-17 11:49:20 -07:00
|
|
|
`artifacts/exports/rt3-1.06/economy-cargo-sources.json` report parses both `CargoTypes` and the
|
|
|
|
|
`Cargo106.PK4` `cargoSkin` descriptors, normalizes localized `~####Name` tokens into visible
|
2026-04-17 13:41:44 -07:00
|
|
|
names, builds a merged live cargo registry, and now derives exact named cargo-production and named
|
|
|
|
|
cargo-price selectors from the checked-in bindings. Dedicated CLI inspector commands now expose
|
|
|
|
|
both grounded selectors directly, while the same report still makes the residual live-registry gap
|
|
|
|
|
explicit by showing the nine excluded CargoTypes-only industrial names outside the 71-row price
|
|
|
|
|
strip. The
|
2026-04-17 11:26:07 -07:00
|
|
|
add-building strip `503..519` is now explicitly classified as recovered
|
2026-04-17 08:50:35 -07:00
|
|
|
shell-owned descriptor parity rather than generic unresolved residue. The first grounded
|
2026-04-15 23:24:08 -07:00
|
|
|
condition-side unlock now exists for negative-sentinel `raw_condition_id = -1` company scopes, and
|
|
|
|
|
the first ordinary nonnegative condition batch now executes too: numeric-threshold company
|
|
|
|
|
finance, company track, aggregate territory track, and company-territory track rows can import
|
|
|
|
|
through overlay-backed runtime context. Exact named-territory binding now executes, and the runtime
|
|
|
|
|
now also carries the minimal event-owned train roster and opaque economic-status lane needed for
|
|
|
|
|
real descriptors `8` `Economic Status`, `9` `Confiscate All`, and `15` `Retire Train` to execute
|
|
|
|
|
through the same path. Descriptor `3`
|
2026-04-15 20:53:35 -07:00
|
|
|
`Territory - Allow All` now executes too, reinterpreted as company-to-territory access rights
|
2026-04-15 21:41:40 -07:00
|
|
|
rather than a territory-owned policy bit. Whole-game ordinary-condition execution now exists too:
|
|
|
|
|
special-condition thresholds, candidate-availability thresholds, and economic-status-code
|
2026-04-15 22:38:13 -07:00
|
|
|
thresholds now gate imported runtime records through the same service path, and that world-side
|
|
|
|
|
condition batch now decodes from checked-in metadata instead of fixture-only ids: real
|
|
|
|
|
special-condition label ids, real economic-status ids, and the recovered `%1 Avail.` candidate
|
|
|
|
|
template plus candidate-name side strings all lower into the runtime condition model. Checked-in
|
2026-04-15 22:19:09 -07:00
|
|
|
whole-game descriptor metadata now drives the first real world-side effect batch too:
|
2026-04-15 23:03:18 -07:00
|
|
|
special-condition and candidate-availability setters import natively, and descriptor `110`
|
|
|
|
|
`Disable Stock Buying and Selling` now lowers into the keyed runtime flag
|
2026-04-16 08:28:50 -07:00
|
|
|
`world.disable_stock_buying_and_selling`. The recovered whole-game toggle batch is broader now
|
2026-04-16 09:20:49 -07:00
|
|
|
too: descriptors `111..138`, with descriptor `122` `Limited Track Building Amount` now landing in
|
|
|
|
|
the bounded `world_restore.limited_track_building_amount` scalar and the remaining boolean lanes
|
|
|
|
|
lowering into keyed `world_flags`, cover finance/trading, construction, and governance
|
|
|
|
|
restrictions. Explicit the late recovered special-condition toggles now execute too where current
|
|
|
|
|
evidence is equally
|
2026-04-16 08:28:50 -07:00
|
|
|
strong: `Use Bio-Accelerator Cars`, `Disable Cargo Economy`, `Disable Train Crashes`, `Disable
|
|
|
|
|
Train Crashes AND Breakdowns`, and `AI Ignore Territories At Startup`. Whole-game condition decode
|
|
|
|
|
is broader now too: checked-in world-flag condition ids can lower into `world_flag_equals` gates
|
|
|
|
|
for boolean equality/inequality forms, so real packed records can gate whole-game effects on
|
2026-04-16 09:27:47 -07:00
|
|
|
existing `world_flags` without fixture-authored placeholder ids. The tracked parity save-slice no
|
|
|
|
|
longer depends on a raw `unsupported_framing` placeholder either: its remaining residue is now one
|
2026-04-16 22:26:23 -07:00
|
|
|
recovered locomotives-page `real_packed_v1` record that now lands on explicit descriptor parity
|
|
|
|
|
instead of a generic unmapped bucket. The next recovered descriptor band is now partially
|
2026-04-16 09:55:58 -07:00
|
|
|
executable too: descriptors `454..456` (`All Steam/Diesel/Electric Locos Avail.`) now lower
|
|
|
|
|
through checked-in metadata into keyed `world_flags`, while the wider locomotive availability/cost
|
2026-04-16 12:18:13 -07:00
|
|
|
scalar bands are now save-native too. Raw `.smp` inspection/export reconstructs the persisted
|
|
|
|
|
`[world+0x66b6]` locomotive name table and derives a minimal `RuntimeState.locomotive_catalog`, so
|
2026-04-16 22:26:23 -07:00
|
|
|
standalone save-slice imports can now lower the grounded lower locomotive availability and
|
|
|
|
|
locomotive-cost rows directly into `RuntimeState.named_locomotive_availability` and
|
2026-04-16 12:18:13 -07:00
|
|
|
`RuntimeState.named_locomotive_cost` without needing overlay snapshots when the save carries enough
|
2026-04-17 08:18:34 -07:00
|
|
|
catalog context, and the grounded executable lower prefix now extends through save-backed
|
|
|
|
|
locomotive id `61` (`Zephyr`); the unresolved lower tail and upper locomotive bands now stay on
|
|
|
|
|
explicit parity instead of synthetic execution. The remaining recovered scalar world families
|
|
|
|
|
execute too:
|
2026-04-16 22:26:23 -07:00
|
|
|
cargo-production slots `230..240` lower into `cargo_production_overrides`, and descriptor `453`
|
|
|
|
|
lowers into
|
2026-04-16 13:48:55 -07:00
|
|
|
`world_restore.territory_access_cost`. Whole-game ordinary-condition breadth now aligns with those
|
|
|
|
|
same world-scalar runtime surfaces too: named locomotive availability thresholds, named
|
2026-04-16 14:23:43 -07:00
|
|
|
locomotive cost thresholds, named cargo-production slot thresholds, aggregate cargo-production
|
2026-04-16 15:26:37 -07:00
|
|
|
thresholds, factory/farm-mine/other cargo-production thresholds, limited-track-building-amount
|
|
|
|
|
thresholds, and territory-access-cost thresholds all gate imported runtime records through the
|
2026-04-16 20:20:41 -07:00
|
|
|
same service path. Explicit unmapped world-condition frontier buckets still remain where current
|
|
|
|
|
checked-in metadata stops, and
|
2026-04-16 12:18:13 -07:00
|
|
|
`blocked_missing_locomotive_catalog_context` is now reserved for intentionally incomplete save-side
|
2026-04-16 15:26:37 -07:00
|
|
|
catalog context instead of the normal save-slice path. Cargo slot identity and class metadata are
|
|
|
|
|
now save-native too: the recipe-book probe lowers into `RuntimeState.cargo_catalog`, so save-slice
|
|
|
|
|
documents can carry slot labels, class tags, and token-stem evidence alongside the executable
|
|
|
|
|
`cargo_production_overrides` surface without introducing a live cargo-economy model. Shell
|
|
|
|
|
purchase-flow, Trainbuy refresh,
|
2026-04-16 12:18:13 -07:00
|
|
|
cached locomotive-rating recomputation, and selected-profile parity remain out of scope. Mixed
|
|
|
|
|
supported/unsupported real rows still stay parity-only. The PE32 hook remains useful as capture and
|
|
|
|
|
integration tooling, but it is no longer the main execution milestone.
|
2026-04-01 23:15:20 -07:00
|
|
|
|
2026-04-02 23:11:15 -07:00
|
|
|
## Project Docs
|
|
|
|
|
|
|
|
|
|
Bootstrap design and workflow documents live in `docs/`.
|
|
|
|
|
|
|
|
|
|
- `docs/README.md`: handbook index and target hashes
|
2026-04-11 17:55:16 -07:00
|
|
|
- `docs/control-loop-atlas.md`: compatibility index for the split atlas
|
|
|
|
|
- `docs/control-loop-atlas/`: canonical atlas section files
|
2026-04-02 23:11:15 -07:00
|
|
|
- `docs/setup-workstation.md`: toolchain baseline and local setup
|
|
|
|
|
- `docs/re-workflow.md`: repeatable reverse-engineering workflow
|
|
|
|
|
- `docs/function-map.md`: canonical function-map schema and conventions
|
|
|
|
|
|
|
|
|
|
The first committed exports for the canonical 1.06 executable live in `artifacts/exports/rt3-1.06/`.
|
|
|
|
|
|
|
|
|
|
## Rust Workspace
|
|
|
|
|
|
|
|
|
|
The Rust workspace is split into focused crates:
|
|
|
|
|
|
|
|
|
|
- `rrt-model`: shared types for addresses, function-map rows, and control-loop concepts
|
2026-04-14 19:37:53 -07:00
|
|
|
- `rrt-runtime`: headless runtime state, stepping, normalized event service, and persistence-facing
|
|
|
|
|
runtime types
|
|
|
|
|
- `rrt-fixtures`: fixture schemas, loading, normalization, and diff helpers for rehost validation
|
|
|
|
|
- `rrt-cli`: validation, runtime fixture execution, state-diff tools, and repo-health checks
|
|
|
|
|
- `rrt-hook`: minimal Windows DLL scaffold for low-risk in-process loading, capture, and later
|
|
|
|
|
integration experiments under Wine
|
2026-04-02 23:11:15 -07:00
|
|
|
|
2026-04-14 19:37:53 -07:00
|
|
|
For the current headless runtime smoke path, use `cargo run -p rrt-cli -- runtime summarize-fixture
|
|
|
|
|
fixtures/runtime/minimal-world-step-smoke.json` or one of the broader runtime fixtures under
|
|
|
|
|
`fixtures/runtime/`.
|
|
|
|
|
|
|
|
|
|
For the current hook smoke test, run `tools/run_hook_smoke_test.sh`. It builds the PE32 proxy,
|
2026-04-02 23:11:15 -07:00
|
|
|
copies it into the local RT3 install, launches the game briefly under Wine with
|
|
|
|
|
`WINEDLLOVERRIDES=dinput8=n,b`, and expects `rrt_hook_attach.log` to appear.
|