6.8 KiB
Locomotive Descriptor Tails (2026-04-21)
This note preserves the checked evidence behind the locomotives-page tail after the full local
.gms + .gmx save-corpus pass, so the short queue can treat the remaining work honestly as an
external-corpus or dynamic blocker rather than another repo-local static task.
Local Save-Corpus Census
The checked locomotive catalog tail census
now exhausts the full local save corpus under rt3_wineprefix/drive_c:
29candidate saves found26parsed samples5saves with a save-side named locomotive table and derivedlocomotive_catalog26saves with packed-event collections present- one save-stable catalog prefix through ordinal
58(VL80T) - two observed tail clusters beyond that prefix:
- one
63-entry tail ong.gms/Spanish Mainline.gmp:242 A1 / Class 460 / Class A1 / Class P8 / U1 - one
61-entry tail on the four 1.05 save families:GP 35 / U1 / Zephyr
- one
The added 18 .gmx sandbox saves still carry no reconstructed named locomotive table and no
derived locomotive_catalog, so they widen the local event corpus without widening the save-native
ordinal catalog evidence. The three classic rt3/ .gms saves (Autosave.gms, hh.gms,
kk.gms) remain catalog-free too, so the save-native tail evidence is still carried only by the
same five 1.05 .gms saves.
The scan still skips the three classic rt3/ sandbox saves (Autosave.gmx, aaa.gmx,
bbb.gmx) at save-slice load time, so the currently parsed sample set is 26 rather than the
full 29 candidate paths. That does not change the locomotive blocker: none of the successfully
parsed .gmx samples widens the save-native catalog, places Class QJ, or surfaces descriptor
carriers in 452 or 457..502.
Grounded Lower Bands
The lower descriptor bands are now grounded enough to execute through the existing save-native owner seam:
- availability descriptors
241..351already map directly onto recovered locomotive ids1..111 - cost descriptors
352..451already map directly onto recovered locomotive ids1..100 - the save-side named locomotive table already projects into
RuntimeState.locomotive_catalogas one ordinal id-to-name map derived from row order - that means the remaining lower-tail rows
302..351and413..451are no longer missing an owner seam; they are just later ordinals on the same catalog
The old “grounded executable prefix through save-backed locomotive id 61 (Zephyr)" boundary is
therefore retired. The whole lower bands are executable whenever the save or overlay supplies the
catalog context.
Grounded Shipped Name Cohort
The remaining lower-tail labels are no longer blocked on missing shipped engine names.
The checked export engine-type locomotive display census
now parses the fixed .car header fields for every shipped Data/EngineTypes locomotive pair:
66shipped.car/.lcolocomotive families61primary display names that match the broader checked shipped-name prefix5extra shipped named families not present in the current grounded prefix:242 A1Class 460Class A1Class P8Class QJ
That means the remaining lower-tail uncertainty is no longer “what are the extra shipped locomotive names?” It is where those five named families land in the live ordinal catalog that the save-side named availability table mirrors.
The full local save corpus tightens that further. The only observed nonclassic tail in the checked
census is rt3_wineprefix/drive_c/rt3_105/Saved Games/g.gms, which exposes one 63-entry named
locomotive table whose observed tail is:
59242 A160Class 46061Class A162Class P863U1
That observation matters because the four catalog-bearing 1.05 save families still carry the
classic 59..61 tail GP 35 / U1 / Zephyr. So the currently honest static descriptor-name
boundary is not the broader shipped-name prefix through 61; it is the last save-stable prefix
through ordinal 58 (VL80T). After that point, save-backed ordinal names are real and
executable, but they are no longer universal enough to hard-code in the static semantic catalog.
The same checked local corpus still does not surface Class QJ, even though the shipped
engine-type corpus proves that family exists on disk. So the current non-hook evidence only closes
the dynamic tail through the observed 63-entry family above; it does not yet place the fifth
extra shipped name in any live ordinal slot.
The same checked local corpus also exposes no packed-event rows in descriptor range 452..502, so
the remaining Unknown Loco Cost and upper-band frontier is absent from the local save-backed
event corpus as well as unmapped in the static descriptor metadata.
Remaining Blocker
What is left is narrower and cleaner, but it is no longer a repo-local static task:
- ordinal placement of the scenario-dependent locomotive tail beyond the save-stable
1..58prefix - descriptor
452Unknown Loco Cost - upper availability band
457..474 - upper cost band
475..502
The upper bands still carry only slot labels in the checked semantic catalog:
Upper-Band Locomotive Availability Slot 1..18Upper-Band Locomotive Cost Slot 1..28
The lower bands now split cleanly into two layers:
- ordinals
1..58keep fixed checked descriptor labels throughVL80T - ordinals
59+stay executable through recovered ids plus save catalog context, but the checked semantic catalog keeps generic slot labels because the local save corpus already shows scenario-dependent tails
Unlike the lower bands, the current checked row summary metadata does not yet recover live locomotive ids for the upper-band descriptors at all.
Blocker Result
The next question is no longer whether locomotive page descriptors can import through a save-native owner seam at all, or whether the shipped engine-type files even have stable names. The checked repo-local answer is already as tight as it can get:
- where the extra shipped named families (
242 A1,Class 460,Class A1,Class P8,Class QJ) land across the scenario-dependent tail beyond the save-stable1..58prefix, and - whether the upper bands continue the same ordinal locomotive catalog after the lower
1..111/1..100families, or - do they belong to a separate page-owned selector family that only sits adjacent in the recovered
EventEffectstable
Descriptor 452 should stay separate from that question until stronger evidence ties it to either
the lower cost band or the upper tails.
The current repo-local blocker is therefore explicit:
- the next honest non-hook step needs a broader save corpus than the eight local saves already exhausted here
- the next honest non-static step needs dynamic tracing or hooks