Logo About  Screenshots  Using  Developing  Blog  Forum  Download
Back to Using openBVE
A quick overview of the source code 

This is a very brief overview of the source code of version 1.0 in the case you want to study, mod or fork the source code. While I tried to keep the code organized, the sheer amount of code that was added in the initial days and the fact that many parts needed to be rewritten and reorganized for better compatibility with BVE Trainsim has led to a slightly chaotic structure.

The program flow in some modules is relatively strictly top-to-bottom (e.g. the parsers), while others are bottom-to-top (e.g. TrainManager.cs). Rationale for top-to-bottom order: The public entry function is at the top, and more specific private functions that are used within the module follow afterward. Rationale for bottom-to-top order: Public structures and classes are defined at the top, followed by small-scale private functions, followed by medium-scale private or public functions, and finally followed by a large-scale public function that serves at the entry point.

All modules are static classes, which may contain initializable classes (e.g. TrainManager.Train), but most of the time use static members. Rationale for static members: There is no need to initialize things like athmospheric properties or track geometry more than once, thereby eliminating unnecessary constructors and copying of variables from one place to another.

All physical elements in the source code solely use SI units, meaning meters for distance, seconds for time, meters/second for speed, meters/second² for acceleration, pascal for pressure, radians for angles, and so on. This eliminates conversion factors, but also means that all variables are simply called Speed, Pressure, etc., without further notice about the unit. Please note that within the parsers, variables might momentarily store quantities in other units before being passed to the game in SI units. This is not usually indicated and requires understanding of the respective file formats.

Please note that the current source code doesn't virtually include any comments. Sections in longer procedures are usually preceded with a comment that includes the caption of that section. In order to more easily spot these sectional comments, I suggest using a colorful background color for comments, e.g. white on green, instead of green on white.

Here are a few notes on the individual modules:


In order of execution:

Program.cs:
The program starts here in the Program.Main() procedure. The module hosts information about the platform (Windows/Linux/Mac) and the .NET architecture (Mono/other). Command line arguments are processed here, the main menu is shown if needed, the route and train is loaded via Loading.cs, the SDL window is created, then the main loop is entered in MainLoop.cs.

Loading.cs:
This Loading.Load() procedure loads a route and train (calling any of the parsers) and initializes all of the other game-related modules.

MainLoop.cs:
The MainLoop.StartLoop() procedure makes some final initializations, then performs the main loop for the running game. The main loop processes keyboard and joystick commands and updates all of the relevant modules with the time that has passed since the last frame. This passed time is universally labeled as TimeElapsed in all function calls throughout the source code. The time is derived from the timers hosted in Timers.cs. Updated modules include TrainManager.cs, Renderer.cs and SoundManger.cs, among others.


In alphabetical order:

Asynchronous.cs:
Hosts the background worker thread that currently serves to load parts of textures in the background. This calls some thread-safe functions in TextureManager.cs from the worker thread, while leaving the completion of texture loading via SDL to the main thread.

Fonts:
Provides character-based (not full Unicode) font support. Textures are registered via TextureManager.cs and rendered via Renderer.RenderString().

FunctionScripts.cs:
Provides the execution engine for function scripts as used in animated objects (both externally and internally). Also provides methods to create function scripts from postfix, functional and infix notation.

Game.cs:
Stores a variery of game-related structures and instances not covered by any of the more specific modules. This includes route-specific environmental features, the in-game menu, the score subsystem, the black box, the A.I., signalling and station management, among others.

Illustrations.cs:
Provides functions to create the map and gradient bitmaps for the main menu.

Interface.cs:
Provides IO-related functions, such as correcting file/folder names for cross-platformness, all of the load/save-functions for the various configuration files, as well as controls/keyboard-related stuff.

ObjectManager.cs:
Stores instances for all scenery objects (static/animated), provides functions to load and create objects, to modify objects and to update animated objects. Also informs the renderer about which objects to be drawn and which to be removed from the to-be-drawn list.

PluginManager.cs:
Manages interaction with the 32-bit Windows-only AtsPluginProxy.dll to provide support for legacy train security system plugins.

Renderer.cs:
The Renderer.RenderScene() function draws a whole frame and is called from within MainLoop.cs. The module provides functions to render objects, polygons and the UI. All objects/polygons to be rendered are stored in lists (which use delicate list indices not to be fiddled around with).

SoundManager.cs:
Registeres all sounds and provides abstract handles to these sounds which are used throughout the source code. Provides functions to register, play and stop sounds, and implements an additional distance attenuation on top of OpenAL in order to cut off distant sounds.

TextureManager.cs:
Registers all textures and provides abstract handles to these textures which are used throughout the source code. When Renderer.cs wants to draw a texture, TextureManager.UseTexture() is called with the abstract texture handle to return an OpenGL texture handle. TextureManager.cs provides methods to load textures in a delayed fashion and can also unload textures that haven't been used for a while.

Timers.cs:
Provides general and platform-specific timers. The Timers.GetElapsedTime() call returns the time passed since the last call to that function. Is used in MainLoop.cs, and the result (TimeElapsed) is distributed from there to a lot of function calls throughout the source code.

Timetable.cs:
Provides methods to create timetable graphics and also provides methods to update custom timetables.

TrackManager.cs:
Provides structures for track geometry, stores the instance of the track (TrackManager.CurrentTrack) and provides functions to update track followers that drive along the track. Updating the track followes can trigger events along the track that are invoked from here.

TrainManager.cs:
Provides structures that store information about trains and cars, stores the instances of all trains (TrainManager.Trains) and provides functions to update a variety of train components. PluginManager.cs and SoundManager.cs are often called.

World.cs:
Provides structures for vectors, vertices, meshes, colors, and the like, as well as functions to operate on them. Also stores instances of the camera and provides camera-related functions.


Additionally, there currently 9 parsers of the form SomethingParser.cs, which are relatively self-explanatory. One note though: SoundCfgParser.cs also loads the set of default sounds if no sound.cfg file is found in a train.