Code-base Overview
From Rigs of Rods Wiki
Contents |
Code-base Overview
This document is written while I study how RoR code-base is organized. I'm making assumptions and try to answer to questions as I write it. It's should not be used as a reference until I remove this warning. Thanks for understanding
About this Document
Ordering a documentation is not always easy task. I'll try to devise code according to features they provide to the user.
In RoR, there are four very basic things the user does:
- Launch the Application
- Select and Load a Terrain
- Select and Load a Truck
- Control a Truck in Simulator
We will see which classes handles those features, but first let's see the big picture.
Main Loop
Presentation
RoR's main loop is controlled by Ogre. Once per frame, Ogre calls ExampleFrameListener::frameStarted(). We will shorten ExampleFrameListener by EFL from now.
EFL works as a state machine. The application state is stored in loading_state, possible states are:
- In Menu (loading_state == NONE_LOADED)
- Selecting Vehicle (loading_state == TERRAIN_LOADED)
- Playing (loading_state == PLAYING)
- Exiting (loading_state == EXITING)
- Editing, Reloading, Pause Mode
Input events are retrieved by the InputEngine singleton, EFL::updateEvents() is in charge to handle them, performing the appropriate actions.
Example Case
For instance, when the quit event arise, InputEngine::getEventBoolValueBounce(EV_COMMON_QUIT_GAME) is set to true, EFL::updateEvents() will
- on first call: show the credits screen and set loading_state = EXITING.
- on second call: exit the application by setting shutdownall to true.
Maybe one should clean the state machine, for instance showcredits and loading_state = EXITING are equivalent. shutdownall could be replaced by loading_state = SHUTDOWN_ALL. And I guess we can find many examples like those, could then code be clearer to understand like this?
Initialization
main.cpp
No surprise, main.cpp is the entry point. There is defined the RigsOfRods class, which does initial setup and launch Ogre's main loop.
- Loads global resources in setup()
- Creates an empty scene in setup()
- Configures Ogre rendering parameters in setup() and createScene()
- Attaches ExampleFrameListener (EFL) to Ogre's main loop (through the RoRFrameListener class, which inherits EFL but brings nothing new).
ExampleFrameListener.cpp
Then, ExampleFrameListener also takes care of lot of initializations in its constructor.
Among other things, it parses command line options to setup the simulator in appropriate mode:
- Network
- Benchmark
- MOD
Then I'll try to classify what is initialized even though it is presented as a soup of things :)
- Graphic Elements
- Some Visual FX
- Initialize SkidmarkManager singleton
- Create a direction arrow (which doesn't have its own class but maybe it should?)
- HeatHaze effect (if enabled)
- Dust in initDust()
- Initialize OgreConsole singleton associated with a ScriptEngine (if enabled)
- Retrieves and configures many overlay elements, related to
- General GUI
- Lap Times
- Flash Messages
- Driving Boats, Cars, Airplanes
- Some Visual FX
- GUI
- Initialize MyGUI, a global object called MYGUI (instance of XXX)
- Create the main menu (GUI_MainMenu class)
- Initialize Picking (pickLine)
- Input
- Configure and starts INPUTENGINE (global instance of XXX)
- Simulator Logic
- Create ScriptEngine (if enabled)
- Starts the cache manager CACHE (global instance of XXX), regenerate it if required.
- Create AI Traffic, AITrafficFactory (if enabled)
- Network
- Network connection is established by Network class (connect())
- Beam
- Creates the god powered BeamFactory.
Then, the constructors continue by loading a map and truck if some have been preselected on command line. We'll skip that for the MapManagement section. In case no map is selected, the terrain selector is shown.
Terrain Management
Let's try to see how is performed map loading and how it is represented in memory.
Introduction
Before to start reading this, take time to read Terrain_Formats (or File_Formats_and_Configuration_Files for side informations).
Loading is performed by ExampleFrameListener, the loadTerrain()] method.
This method basically loads the terrn file, the Ogre .cfg file, scripts, and create collision models and visual effects.
Physical Scene
Height map is stored into a RAW elevation file. TSMHightFinder takes charge of finding collision points with the height map. Does it by projecting vertically a point onto the height map and interpolate returned height.
Graphical Scene
RoR relies on Ogre SceneManager::setWorldGeometry() to load the static part of the world (the big graphical mesh). It is given a file of type [Typical_terrain_cfg_file ".cfg"].
Terrain Scripting
Lua and/or AngelScript associated with the Terrain are loaded.
- see LuaSystem::loadTerrain for Lua
- see ScriptEngine::loadTerrainScript for AngelScript
GUI
MapControl is in charge of displaying an overlay showing preview of the map seen from above.
It contains a set of MapEntity, each being an element to display on the map overlay (icon + text).
Truck Management
- Load a truck
- Control truck
(see EFL:7400)
Simulator
This is the big part.
Collisions
- Collision engine (Collision) is created during Terrain loading. The object is EFL::collisions
- MOC::CollisionTools offers a set of methods useful to detect collisions.
