Shard Engine / Dead By Destiny
Dead by Destiny was originally intended to be a 3rd Year group project, for which I was going to be the lead programmer. The game was to be a combination sci-fi/western incorporating rudimentary 3rd-person combat and exploration on the ground and inside spacecraft, combined with sections of space combat using a Newtonian flight model. Transitions between these segments would be handled smoothly by dividing the world into "shards" which run in a cooperative multi-tasking environment, the idea being that as the player approached an airlock (or similar) the engine could begin to load the shard on the other side and set it running shortly before the player entered.
External circumstances prevented the project from going ahead, and the engine has since become a project in which I test out interesting techniques that I read about in the context of a full game engine. By placing it in this larger context I prevent myself from resorting to quick hacks and pave the way for the new technique to become a permanent part of the project.
At startup, a single shard is created and runs a Lua script to load whatever objects are needed - this would usually take the form of a menu object in which the buttons either run scripts themselves to create new shards or have hardcoded behaviour. Shards run concurrently, and can be commanded externally to run, pause, load and unload. The resource manager stores graphics assets in containers that are reference counted by the number of shards that use them, meaning that a temporarily paused shard can have its assets unloaded to free up space. Depending on the way the objects inside are simulated, it could even be possible to leave the shard running without its assets, so long as the player did not enter it.
Example object -"teapot.xml"
<object name = "spaceobject" description = "teapot" >
<graphics name = "Graphics">
<model>
<string name = "file"> teapothigh.x </string>
</model>
</graphics>
<physics name = "SimplePhysics" >
<string name = "shape"> teapotlow.x </string>
<float name = "mass"> 10 </float>
<vector name = "lindamping"> 0.1 0.1 0.1 </vector>
</physics>
</object>
Game objects are specified in an XML format which is then compressed into a binary format designed for easy reading. Some object types are component based, allowing the XML to select what kind of physics, graphics, etc the object will use, while others such as the player object are restricted to using a fixed method.
Similar to the Source Engine, the engine reinterprets a model's texture file names as material file names. The material files are text format, and specify a shader and a set of parameters. A central shader manager stores list of shaders and their associated materials, and objects enqueue each sections of themselves with the appropriate material to allow for fast and efficient batching. Objects also enqueue themselves separately with a depth-only shader allowing them to optimise themselves for a depth pre-pass at the start of the scene, as well as making any future shadow buffering techniques more efficient.
Physics is provided by the Newton Game Dynamics SDK, inside an object oriented wrapper, with each shard managing its own independent physics world. Game entities that wish to influence each other call functions during their update step to add forces and torques to each other, and have a separate post-update function called after the physics update to allow them to react locally to any changes before rendering occurs.
The engine itself compiles as a static library, in order to avoid discrepancies between demos, guaranteeing that a project like PreProcess will always produce compatible output and provide an accurate preview of its output.
Other features include:
- User-customisable key bindings
- HDR rendering and fullscreen postprocessing
- BSP environments loaded from Zalsoft Getic




