Wednesday 19 February 2014

The Optimal Racing Line


I've recently reached the stage in the TORCS-Adaptive project in which I need to consider implementing some more sophisticated performance measurement than simply monitoring the player/AI driver's speed. I stumbled across a rather dated but still very relevant series produced by Brian Beckman, PhD, named The Physics of Racing. There were many useful articles here, however Part 4 and Part 5 were the most relevant to this project. Part 4 of the series introduces the idea of centripetal force (centre-seeking force), and is able to produce an equation from which we can derive the maximum driving speed for a given arc radius. I won't go into the details here - those interested can see the link at the bottom of this post - but ultimately the equation derives to:

Where v is the maximum possible velocity, a is the sideways acceleration and r is the radius of the curve. Here we can see that the radius is being used almost as a scalar for the velocity - the sideways acceleration multiplied by the radius gives the maximum possible velocity. Therefore we an infer that the optimal corner arc in terms of speed alone is in fact the one with the largest possible radius. The diagram below has been adapted from the diagram shown in The Physics of Racing Part 5:


Here, w is the width of the track and W is the width of the track minus half of the car's width. When considering the optimal path we are considering the trajectory of the car's centre of mass as opposed to the paths of individual wheels. Therefore, the width of the track is slightly lower to prevent the car dragging it's wheels off the sides. The optimal path can be seen here as Line M, the line that passes through points E, Q and X. Two more sub-optimal lines that hug the sides of the track are shown for sake of example, Line o and Line i. Ro and Ri are the inner and outer radii of the curve, and also happen to be respective to the arc radius of the curves in Line o and Line i. If Ri is the radius of the curve of line i and K is the radius of Line M, it can be seen that the speed possible on Line M is far greater.

References:
Beckman, B. (1993) The Physics of Racing [online] Available at: http://phors.locost7.info/contents.htm

Tuesday 4 February 2014

Pinball!

As part of a recent University project, I implemented a Pinball game using PhysX 3.3.0, GLUT and OpenGL for some basic rendering. I also made use of SOIL for simple image loading and BASS for audio. The game consists of a few different features, including switches, spinners and bumpers, and was designed to accurately model the physics of a pinball machine. It also marks my first ever complete (if small) game written entirely in C++! By complete, I mean an application consisting of rendering, input and audio, all of the components required for a basic game.



I have uploaded the game and it's source code (with a VS2010 solution, as anyone with more recent windows IDEs, i.e. Visual Studio 2013 should be able to open this). It can be downloaded from here.

TORCS-Adaptive Progress

I've been making some progress recently on TORCS-Adaptive, my final year project at the University of Lincoln. Thus far, I've managed to implement procedurally generated tracks into TORCS, that now function both in console racing mode and in graphical mode. The generation of new 3D models when adding new track segments still has some performance issues, however I've manage to set up a pipeline in which performance measurement and adaptive difficulty algorithms can be easily tested and analysed using AI drivers. Currently, I have a very simple AI driver set up. In order to build a completely random track, I use the 'Procedural' race mode. When in the runtime/runtimed folder, it is possible to run TORCS in console mode on Windows as follows:




This will run TORCS in the console, with the race manager contained in procedural.xml. This file can either be modified directly in a text editor, or the race can be set up within TORCS itself and it will be saved. At the end of the race, there is now a feature of the procedural library that builds the entire track, and writes it's data out to a .txt file with data readable by gnuplot. Gnuplot allows the user to then plot this track, with results such as the following:


This image shows a plot of the entire track, with accurate scaling. The values on the X and Y axis are both in metres. 

Tuesday 26 November 2013

TORCS Adaptive Real-Time Tracks

Since my last post I've managed to get a prototype of the track generation system up and running. It currently generates and loads an entirely new model file for each segment that is added to the track, running through TORCS' existing track generation functions. These functions have all been exported to a static library, and the client has access to these functions to enable what you see in the video below.


As can be seen, this is not the most efficient method for track generation at run-time within TORCS. It does however prove that it is possible without drastic changes to the existing framework. Possible optimizations would be to only generate a single track segment's AC3D file, and somehow merge this with the existing file. However, it is not yet clear where the computationally expensive part of this process is. It may be that removing and re-attaching the node containing the track from the scene graph is expensive, or it may be the track generation itself. This needs to be further explored before deciding on how it could be optimized.

Monday 18 November 2013

ScareJam!

Artist: Brooke Hayes (Blog, Twitter)

Back in October, I competed alongside an artist in the ScareJam at the University of Lincoln. This was an interesting experience as it's the first time I've done any rapid development, particularly focussed on programming, alone. I decided to use XNA and C#, as I have a lot of experience with this framework and can develop quite rapidly within it. The ScareJam was focussed on creating scary games, and the additional game mechanics were "Loss" and "Important Sounds". We came up with "Lost and Sound", a title with a subtle nod towards the game mechanics! Lost and Sound is a game in which you must go into an abandoned hospital in search of your lost daughter, as she's been kidnapped by the ghost that haunts it! Most of the game mechanics are intended for the player to discover alone, and the game is intended to be somewhat of a mystery. I will let you explore the rest for yourself! To play the game you'll need a wired Xbox 360 gamepad, and the XNA 4.0 redistributables which can be found here.

Download Lost&Sound.

TORCS Adaptive

For my final year project at the University of Lincoln, I am currently modifying TORCS (The Open Source Racing Car Simulator) to generate tracks at runtime. It is then intended that these tracks will adapt to the skill of the player, depending on several performance measures. The project is currently in it's very early stages, but some simple run-time track generation has been implemented alongside some telemetric functionality, though these values are not yet used in any kind of performance measure. The following videos show some of the current features.


This video shows telemetry printing data to the console at runtime about the current car. The car here is one of the 'robots' that come with TORCS, which are compiled AI drivers written in C++.


This video shows a single track segment that has been generated completely at runtime. TORCS stores all of it's 3D models, including tracks, in AC3D files. Here, a segment has been generated at runtime and an AC3D file generated for it all during the runtime of the application. The next step is to find a way to update the existing AC3D file with new segment data each time a new segment is added.

The project's Github page can be found here, and more information can be found on it's wiki.

Wednesday 10 April 2013

Component-Based Game Engines

I've been doing some reading recently into 'Component Based Game Engines', and wanted to share a few of my findings and thoughts about it, in the hopes it might interest someone. Component Based development has existed for years in the software development sector, so it only seems natural to attempt to apply this same theory to game engines. Before you read on, I'd like to point out that this is in no way going to be a tutorial or contain any implementation of Component Based Architecture, it simply serves to outline the theory behind it. I'd also like to mention that there is no RIGHT way of implementing Component Based Architecture - different approaches can be taken by different engines, depending on personal preferences and the requirements of the engine.

Imagine we're building an engine for a very generic 3D FPS. Usually, the first thing we would do is examine what 'objects' we have in our game, and create classes for them. We would also consider any shared behavior or data that certain objects need to have. For example, we have an 'Enemy' and a 'Player', which are both entities within our physical space. They'll need a position, maybe they each carry a weapon, and they each need health points. We'd then consider some objects further down our inheritance tree, for example different types of enemies would need different behaviors so we would probably be deriving enemies from our enemy class. This is the kind of game architecture that we are all used to. The following class diagram is one we should be comfortable with, it's a simple representation of part of the object hierarchy for a 3D FPS.


Familiar enough, yes? The Player inherits different behavior by overriding the virtual Update function in the ModelEntity, as does the PowerUp. The PowerUp then has two derived classes that add additional behavior on to that. This is a well established paradigm for structuring a game engine, as in our update loop we can treat all classes derived from ModelEntity uniformly in a single data structure, and make use of polymorphism and dynamic-dispatch to handle the different behaviors of each entity.

So, what actually is Component Based Architecture? Component Based architecture is different to our usual object hierarchy in that it focuses on making compositions of 'components' to form a game object, as opposed to the game object getting it's functionality through inheritance. When applying component based architecture to game engines, I find it is easier to refer to these components as 'Behaviours'. Each of these different Behaviours have their own Update() and Draw() functions that pretty much allow them to 'do their thing', and data members that are specific to that job. For example, the component 'ModelRenderable' may contain a Model and it's Draw() function may simply render that model. It may also have a velocity, or direction, or bounding box, the functionality of which is handled by it's Update() function. We can then group these behaviours together in composite classes in order to create what we consider to be a 'Game Object'. A player, for example, may contain a 'ModelRenderable' behaviour, a 'Health' behaviour that keeps track of their health, and any other functionality needed for that specific game. We can then refer to these 'Game Objects' polymorphically, just as before in our object hierarchy approach, in a 'Game World' object, that contains a collection of Game Objects. It's Update() and Draw() functions simply call the Game Object's Update() and Draw(), which in turn can carry out all of it's different behaviours. The following class diagram is a very light-weight outline of how Component Based Architecture could be implemented for games.

So the next question is - why use Component Based Architecture? We're all comfortable with object hierarchies, they're well established so that we can all understand one another's code. Well as to the answer to that - I'm not entirely sure as of yet. There are some cases in which code in object hierarchies can become very bloated, where base classes can implement code that is not used by some of it's derived classes. This makes sense however - as if a class uses most of it's base class' functionality, why re-write it just because it doesn't use some of the other base class functionality? It would add a lot of unnecessary code. But a component based engine would avoid this issue - as objects only implement the functionality or behaviour that you know they require. I've added some links to other resources and reading that might help you further understand Component-Based Architecture.