Logo About  Screenshots  Using  Developing  Blog  Forum  Download
The new architecture in more detail 

Date2009-05-03

In order to allow for a large range of new features, openBVE is soon going to be radically redesigned. In the article The potential future of openBVE, this was already mentioned, and I am going to present some more practical issues and questions regarding the new architecture in this document. The following is mostly aimed at developers.

First of all, openBVE will be split in two: There is the core engine and the standard library.

 The core engine 
The core engine is the main program, and its tasks include managing and rendering objects, managing and playing sounds, storing the track geometry, storing the cars that make up trains and providing the user interface.

Actual train simulation components, such as accelerating the train, performing brakes, simulating the safety systems, etc., are not at all part of the core engine. Neither are the parsers that load a route or a train. Instead, the core engine provides an API which allows to do all of these things in external plugins.

You could say that the core engine is merely a building kit to create any kind of game, however, it will of course be geared toward the needs of a train simulator. But from the engines' point of view, you could also create a bus simulator or a flight simulator if so desired. All that is needed are the appropriate plugins.

The core engine's API allows communication with plugins. There are two kinds of plugins: loading-stage plugins, and runtime plugins.

 Loading-stage plugins 

Loading-stage plugins are responsible for loading a texture, a sound, an object, a route, a car or a train. For example, whenever a route is selected to be loaded from the interface, the core engine will look for a plugin that reports to be capable of loading that particular route. In turn, the route loading plugin may call back to the core engine to request loading a particular object, which in turn might be handled by yet another plugin. This way, there will be endless possibilities of processing new file formats, and to combine them in any way.

 Runtime plugins 
Runtime plugins are what make up the functional parts of the train. The core engine will be able to handle any amount of plugins at the same time (compared to only one currently). As there are no built-in functions to simulate the engine, the brake system or the safety system, plugins are required which simulate these components.

In current plugins, you might be used to the idea that one plugin handles multiple things, e.g. the security system, cab-effects (such as wipers), engine sounds, etc. In order to more easily combine functionality and not to have to rewrite simple things over and over again, I envision a degree of separation between plugins which take over different parts of a train's functionality. These are described in the following.


Physics plugin: Is responsible for calculating the exact world position and orientation of a car, and to report this to the core engine. The plugin is in no way restricted to leave a car on the underlying track. It can query the shape of the track, but how it uses the track to determine a car's position and alignment is up to the plugin. As such, detailed and realistic collisions and derailments can be simulated here. The plugin could even simulate a bus or an airplane if so desired. Different physics models for normal railways, monorails and maglevs are probably the most important aspects, though.

Engine plugin: The plugin would provide the engine, thus calculating the amount of acceleration (or force) provided at a time. This should be reported to the physics plugin, which would actually handle this aspect of physics. The plugin is also responsible for playing all engine-related sounds. Different plugins might be used for electric trains, diesel locomotives, etc., as they have vastly different requirements and effects. A diesel plugin could, for example, simulate fuel consumption and report the loss of mass due to fuel consumption to the physics plugin, thus effecting the physics, e.g. acceleration characteristics.

Brake plugin: The plugin would simulate the brake system, e.g. Westinghouse air brake, vacuum brake, etc., and play the corresponding sounds. The physics plugin would need to be told to apply a certain acceleration/force.

Safety system plugin: Basic responsibility is evaluating beacons, signals, track and other trains, and feeding the engine and brake system plugins with instruction to cut power, apply the brakes, etc. Also plays related sounds.

Environment plugin: Everything that concerns the car chassis, e.g. run sounds, flange sounds, general effects such as wipers, headlights, etc., is handled here.


All runtime plugins would be able to play sounds, once or in a loop, and changing pitch and volume of them.

All runtime plugins would be able to query the core engine for data, e.g. track geometry (upcoming speed limits, gradients, etc.), route characteristics (air pressure, height above sea level, etc.).

All plugins would be able to communicate with each other for arbitrary data (e.g. the brake plugin tells the physics plugin to apply a certain force, the safety system tells the engine to cut off power, etc.).

All plugins would be able to process keystrokes. In particular, there wouldn't be any standard key assignment for train-related things, e.g. no built-in power handle, no build-in brake handle, no built-in reverser, etc. I envision to dedicate the whole A-Z range to plugins. There is a good reason for this: We have already seen trains which feature vastly different kinds of controls, e.g. no power/brake handle, but a speed/acceleration handle. In order to accomodate for such trains, and in order to provide for more memorable keys (e.g. S for sanding, H for horn) and for more keys in general, this is, I think, a good design decision. Of course, standardization would be required in order for the most common commands to appear on the same keys.

 Further things 
Apparently, the communication between the plugins, the key assignments, and so on, require some effort for standardization. The same applies for beacon types, run sounds, electrification assignments, and so on.

But, not only the trains need new flashes of though, but so does the route. Currently, the communication of the route and train consists of at least the following items, which are all handled in special ways: Run sounds, flange sounds, beacons (transponders).

On a low level, the API will know about point-based events in the route (e.g. transponders), and spans (e.g. a region of a particular run sound, a segment of electrification). The runtime plugins will also be able to query all spans currently in, and are informed about point-based events that are passed. Currently, openBVE simulates two axles per car, which each follow the track and process events. Likely, you would want a beacon receiver to be at a different location but at any of the axles (which is currently the case). As such, "track followers" (as I have been calling them so far) will be able to appear in multitudes. For example, the train could employ a dedicated beacon receiver which triggers at the correct location, and cars could share axles to simulate articulated trains correctly.

On the same low level, any route will be able to define any event and any span, and it is left to the runtime plugins to process them. The core engine will neither know nor care about them. This means that developers would be able to create more organized ways of communicating with various train components besides using beacons for everything. And again, this approach will of course require standardization.

In particular, run sounds and beacon types are things that I want to standardize from the beginning. For beacons, it might be worth thinking about using their frequencies instead of arbitrary numbers. Furthermore, as developers and users would like to use a new train on an old route or vise versa, many developers will want to retain compatibility with their legacy standards. This requires some thought, and your input is very welcome.

So far, so good. If the core engine doesn't actually simulate anything, then are you required to program plugins for everything? Of course not, and this is where the standard library comes into play...

 The standard library 
The standard library is a set of plugins that I will personally create and maintain, and they will provide all the functionality to process existing routes and trains in the same way are they are now. The standard library will thus include about the following plugins:

Object loaders:
  CSV/B3D object loader
  X object loader
  ANIMATED object loader

Route loaders:
  CSV/RW route loader
  new route format loader

Train loaders:
  panel.cfg/panel2.cfg cab loader
  new 3D cab loader
  train.dat/extension.cfg/sound.cfg characteristics loader
  new characteristics loader

Runtime plugins:
  normal railway physics plugin
  electric train engine plugin
  diesel train engine plugin
  air brake (and variants) brake system plugin
  (uncertain: vacuum brake (and variants) brake system plugin)
  ATS/ATC safety system plugin
  default environment plugin (for run/flange sounds at least)

Unsorted new features:
  Routes with multiple isolated functional tracks and traffic on them (e.g. opposing traffic)
  Coupling operations, e.g. combining or separating trains on the same track
  Time of day, e.g. smooth transitions from day to night
  Weather effects, e.g. rain and snow

 Summarizing 
The new architecture will be based around a core engine which allows plugins to load any content, and which allows plugins to carry out every aspect of the simulation. At the same time, I will be maintaining the standard library, a set of plugins which handles current content and introduces new features.

This will be taking some time, and I expect the final version 2.0 to appear in about a year from now. Just as with the approach to 1.0, parts of the final functionality will be available earlier, of course. However, there is no explicit roadmap yet for version 2.0, which stills needs to follow. More information will come in time...