Libtrainsim

Main Project

Libtrainsim is a library to create train simulators. It handles file formats, video decoding and rendering to allow the developers to focus on creating a good user experience without much hassle. The project is still in the alpha phase please expect large changes that may break compatibility. The latest release is version 0.9.2 and the supported format version is 0.6.0. Libtrainsim is written in C++17 and published under the LGPLv3 license. Below are a few screenshots from the reference implementation.

Subprojects

In addition to the library there are other projects that make using libtrainsim easier.

First off there is the reference implementation simply called simulator. It uses libtrainsim to implement a very basic train simulator. This is a good starting point if you plan on developing your own train simulator. The reference implementation is licensed under the GPLv3 license. If you want to try it out you can use the snap package. Please not that you have to download the data separately. You can get the example data by cloning the data repository or by installing the libtrainsim-data-munich-u6 snap package.

One of the most important projects are the setup scripts. These allow a fast setup of all of the required dependencies and also of all of the simulator. There are working scripts for apt (debian, ubuntu, …) and dnf (Fedora, REHL, …) based linux distributions. For windows there is the msys2 script, that should work (msys2 tends to have problems on some machines so your mileage may vary…). There is also an initial script for OSX. That one is not tested and has no guarantee to work at all (it should but I guarantee nothing).

One other project is the format converter used to convert Track data from a csv format to the json format used by libtrainsim. If you used older train simulators before you might be interested in using this but most people probably won’t need this. This project is written in go and it is published under the LGPLv3 license.

Because the number of projects increases a lot I will not update the list any more. Just take a look at the projects and their README. It should give you an overview on how large the whole project is getting.

Future plans

There are a lot of things planned for the next versions of libtrainsim.

One of the most important things is to improve the physics component. At the moment it is a simply calculation where the driver directly controls the acceleration and no drag is taken into account. In the future the driver should control the torque of the engine which allows a more accurate calculation and creates a more realistic experience.
Version 0.9.0 was released with this brand new physics system. This should make adding things like drag forces pretty easy.

The other very important improvement is a major overhaul of the control subsystem. The acceleration and breaking should be implemented as one axis. This would allow implementations using real hardware which usually allow more than simply full break and full acceleration. The control subsystem will probably be more event based but I don’t know how exactly it will look like.
Version 0.7.0 added the input_axis and there have been some changes to the control system. It is now possible to use keymaps, to assign any ‘function’ to any button. This way a simulator can have custom events to handle events specific to that implementation.

Last but not least the rendering portion will also receive some updates. At the moment the rendering and video decoding are part of one single class. They need to be split. Splitting them will allow easy implementations for more windowing backends and allow more redering backends as well. At the moment the only usable backend is ffmpeg/sdl2 so soon after the split I want to get ffmpeg/glwf3 working as an alternative or maybe even ffmpeg/gtk4.
The backend is now split into renderer and window_manager. This was merged in Version 0.8.0 and required large changes to the video component. However implementing a glfw3 based window manager should be quite easy, now that the window management and renderering are split.

At the moment the main focus is on getting hardware inputs to work. The API for hardware inputs is in development at the moment and once that is done first implementations are soon to follow. The API will be a REST API and exchange data between hardware and simulator using several endpoints. All of the data should be json. There will be a repository just for this API documentation, since there are a lot of things to cover. For older hardware that uses other interfaces, there will be bridges. The bridge communicates with the hardware directly and creates the HTTP(S) server that the simulator needs. This design should maximize compatibility and flexibility while not giving up a lot of performance. Since all of the code is open and modular, a direct interface can be implemented if for whatever reason required.

The physics still needs more improvements.
One thing that will be added in the near future is drag. At the moment there are no drag forces that slow the train down when you do nothing. Because of this there needs to be a variable that specifies the top speed. That one can be removed in the future, since the top speed can be calculated from the balance between drag an force of the engine.
To get the drag working there will be separate fields for the rolling resistance and standing resistance. This will require large changes to the json formats and will break them.

Another thing that will break the json formats are time based formats. This way the simulator does not break, when the framerate is changed. This also allows to interpolate positions way better and should make many things easier. Note that this will again require large changes to the video component as well as the core component, but the sooner this is done the better.

Also the track format should be able to include things like height, rotation angles and lots more data. This could allow for way more accurate simulations and can be especially helpful for other more complex simulator implementations.

On that note, I would like to have a new and more elaborate simulator implementation, which also handles things like selecting a track and maybe even driving another track after one has ended.

I also want the project to work on windows without having to rely on msys2 but that will be a whole different story.

Tutorials