The Pyrogenesis Engine/Printable version
| This is the print version of The Pyrogenesis Engine
You won't see this message or any elements not part of the book's content when you print or preview this page.
Pyrogenesis is an open source game engine developed for the real-time strategy game 0 A.D. by Wildfire Games. Wildfire Games originated as a mod developer, releasing the mod Rome at War for Age of Empires II: The Age of Kings in 2001. The same year, development commenced on their next title, 0 A.D. Originally envisioned as a comprehensive total conversion mod of Age of Empires II: The Age of Kings, the team eventually decided to instead develop their own engine for the project - the Pyrogenesis engine. True to its roots, the engine was designed from the ground up to be easily moddable and in 2008 the team finally decided to release the whole project, including the Pyrogenesis engine, as open source.
Features[edit | edit source]
Core[edit | edit source]
- Support for saving and loading games.
Graphics[edit | edit source]
- OpenGL-based rendering engine with support for both ARB and GLSL shaders.
- Realistic shadows with shadow mapping and shadow filtering (PCF).
- Materials system for both models and terrain.
- Normal, parallax, specular and emissive mapping.
- Ambient occlusion.
- HDR rendering and bloom.
- Animated water plane with refraction and reflection.
- Hierarchal skeletal animation and deformation system based on COLLADA.
- Particle effects.
- Triplanar texture mapping.
- Environmental lighting effects (time of day, sunset).
- Flexible terrain renderer using alpha maps to seamlessly blend terrain.
Audio[edit | edit source]
- OpenAL-based sound manager.
User Interface[edit | edit source]
Platforms[edit | edit source]
Supported languages[edit | edit source]
Supported operating systems[edit | edit source]
Windows, OS X and Linux.
License[edit | edit source]
Comparison and particularities[edit | edit source]
Where to get it?[edit | edit source]
The Pyrogenesis engine is not yet packaged separately, but all the source code for 0 A.D. can be downloaded from: svn.wildfiregames.com or github.com/0ad.
Pyrogenesis has two faces: one, the core engine itself, is written in C++. Ideally, only the most low-level functionality, which requires access to system interfaces or crucially needs to be very fast, is implemented here.
About scripting: engine creates multiple JS runtimes, one for simulation, one for AI, one for GUI and one for RMS. (Others?)
This section will introduce some of the high-level concepts used in the engine's design.
Components[edit | edit source]
Entities[edit | edit source]
View from main
Loading is handled by loading.js. Engine invokes init(), I think, and then at some point reallyStartGame().
The most important aspect of any game is its gameplay. In Pyrogenesis, the simulation can be thought of as the place where gameplay is executed. The simulation is the part of the engine that takes commands from the players (including the AI) and turns them into actions in the game world.
The simulation subsystem is defined in simulation2/Simulation2.cpp. Its central class, CSimulation2Impl is instantiated by ???, constructed from a unit manager (CUnitManager) and a terrain (CTerrain). From this alone, we can deduce that the simulation deals with how units interact with each other and with the terrain of a map.
When CSimulation2Impl is instantiated, it also initializes a component manager (CComponentManager?). Components are one of the most crucial concepts to grasp in order to understand how the simulation works. Programatically, components are merely subsystems accessed via the component manager. For instance, there is a pathfinder component for deriving the shortest path across a terrain, a sound manager component for outputting music and sound effects, and a projectile manager component for driving ballistic calculations of things like arrows and spears.
However, though each of these subsystems (components) are instantiated only once by the component manager (I think), they can be associated with any entity in the game world (I think) and will only ever be used in relation to one such entity at a time (I think). Thus, as a user of the simulation, it may be easier to think of the simulation as consisting of a set of entities, each "having" (being associated with) one or more components. For instance, a soldier unit may have a Pathfinder component, so it can find its way over the map, and an Attack component, so it can fight any enemies it comes across, and an Armour component, so it can handle damage dealt by other units.
Regarding how to load a single instance of a component for one whole session: For a single component you need to attach it to the system entity which unfortunately requires a C++ change. The location is: source/simulation2/Simulation2.cpp:128
source/graphics/MapReader.cpp is the tool loading maps.
"Actors" is a concept that is used when dealing with all the visual aspects of entities, such as which models and textures to use for rendering it etc. (TODO: give more examples).
The logic governing actors is mainly found in the VisualActor component (TODO: wikilinkify "component").
This function takes a "paramNode" as argument. I'm not quite sure what that is, but it's probably some kind of XML-derived data structure.
If the paramNode has a "Foundation" or "FoundationActor" child, that will be used as the "actor name". If it doesn't, it will use the "Actor" child of the paramNode as "actor name".
The function then creates a new "unit" from the "actor name", GetActorSeed() and null selections. (TODO: explain)
This function tries instantiating a new CUnit with the actor name, seed and selection given in its arguments and some private object manager. (TODO: explain)
If it succeeds in doing so, the new unit is added to the unit manager and returned to the call site.
This is a factory function.
First it finds the base object with the given actor name in the object manager. If a base object with that name is not found, it returns null.
It then calculates random variations from the seed.
It then finds the object that matches them. If object not found, return null.
It then returns a new CUnit with that object, object manager and selections.
This just initializes a bunch of variables.
While not the most prominent part of the engine, the GUI component is one of the first ones invoked by the game. When pyrogenesis is started, only GUI runtime is active.
The build system compiles all files in the source tree.