Microsoft Train Simulator Packaged Activity
The 2001 video game Microsoft Train Simulator (MSTS) allows players to install new routes to play in, new trains, and new activities. Activities are scenarios that apply on a specific route. They specify what AI traffic should be where and when, where the player starts and in which trains, which assignments they have (stopping at a station, coupling or uncoupling cars at specified locations, etc.), which messages should appear and when, and more.
Some tools are included to create routes, trains, train cabs and activities. MSTS was for a while the most popular train simulator, so it has a pretty large community that has developed even more tools and shared many additions. There even were paid additions to the game being sold on CDs or DVDs.
Routes and trains usually come in the shape of an archive with a README
file that explains how to install it into your game. But activities have their own format, called a Packaged Activity, with the .apk
extension. This has nothing to do with Android packages, which came in many years later.
The game provides ways to both pack and unpack activities into those Packaged Activity files, but the unpacking utility, TSUnpack.exe
, found in the UTILS
folder of the game, has proven to be quite unreliable or difficult to use. There are many unofficial extractor tools out there, or converters that can turn activities into ZIP files that are compatible with OpenRails, the open source successor to MSTS.
When I looked for an extractor that could run on Windows XP in late 2021, my options were quite limited. There was very little documentation or open source software available, so I decided to write my own software and document it.
File format
I wrote a Kaitai Struct schema for this format.
String
The file format uses UCS-2 little-endian as its text encoding. Strings are both fixed and null-terminated, with two null bytes since this is UCS-2.
- Length
- 32-bit unsigned integer. Size of the string, in characters, including the final null character.
- Text
- Text, encoded using UCS-2 little-endian, with a final null character (two null bytes).
File
- Size
- 32-bit unsigned integer. Size of the file in bytes.
- Path
- String. Path and name of the file, relative to the root of the game’s installation directory.
- Contents
- Uncompressed contents of the file, of the size determined by the
Size
field. Extracting only involves copying those bytes without any additional work.
Packaged Activity
- Route display name
- String. Display name of the route that this activity applies to. This value is not necessary to perform any extraction.
- Route ID
- String, repeated twice. Should match the name of the folder that contains the route that this activity applies to, under the
ROUTES
folder in the game’s installation directory. For example,USA1
for the Northeast Corridor. This value must not be concatenated to the file paths and is not necessary to perform any extraction. - 4 bytes
- Four unknown bytes. They are not necessary to perform any extraction.
- File count
- 32-bit unsigned integer. Number of files stored in this archive.
Implementation
I wrote a C# library based on Kaitai Struct and a command-line tool to replace the official TSUnpack
tool and allow extracting packaged activities more reliably. It is available on Tildegit.
By default, the tool will extract activities to the game’s installation folder, using the Path
value of the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Games\Train Simulator\1.0
registry key, just like how the original TSUnpack.exe
does. If a file already exists, the extraction stops. Some options are available:
-d
,--destination
- Destination folder to extract to, instead of the game’s installation folder.
-f
,--force
- If a file already exists, overwrite it.