Home | Ghost cars are useful to compete with yourself while hotlapping. |
|
Introduction
Racer v0.8.3 introduced ghost cars. A ghost cars is a virtual car which is drawn so you can compete your current lap to your best lap (or someone else's lap, for that matter) while you are driving.
Ghost files are stored in a track's directory under 'ghosts' and have the .ghost file extension. For example: data/tracks/carlswood_nt/ghosts/test.ghost. They are a far simpler format than regular replays, since they only need to store position/orientation information, next to some extra (brake state, for example).
The ghost car will be displayed in a semi-transparent mode, to indicate that it's a virtual car. For this to work, a special clone of the car will have to be created.
The image below shows a Lambo with its virtual opponent just braking for the 1st corner of Carlswood.
Racer.ini settings
The following parameters influence ghost car behavior.
Parameter (in racer.ini) | Description |
ghost.enable | Enabling playback & recording of ghost lap information. |
ghost.load | If not empty, this will let Racer load the ghost lap replay from the track's ghosts directory. I.e. if you have ghost.load=test, then Racer will try to load data/tracks/<trackName>/ghosts/test.ghost |
Creating ghost cars
When ghost.enable=1, Racer will attempt to load a ghost car variant for the player car. The name of that car is the original name of the car, with _ghost appended. So, if you drive in the lambomurcielago car, it will try and load lambomurcielago_ghost. If not found, the ghost car feature is turned off.
To make a ghost car, you'll need to clone the original car and modify all the shaders so that the car becomes transparent. This means you have to modify the car.shd file in the car's directory. For every shader (material), it is recommended to:
The vf_ghost section would look like the following:
vf_ghost { vertex_shader { file=dyn_standard_ghost_v.cg } fragment_shader { file=standard_ghost_f.cg } }
It defines Cg shaders that will work for most ghost shader's you will ever need. These Cg shaders will apply more transparency as the car gets close to the camera, so that a ghost car smoothly disappears when coming too close to the player's car (to avoid the ghost car obstructing your view when it's close).
A typical ghost car shader itself then may look like this:
shader_tyre~vf_ghost
{
layer0
{
map=tiretread.tga
blendfunc=blend
} }
The blendfunc=blend line will make the shader blend with the view.
Creating ghost lap data
Creating ghost laps is easy. Set racer.ini's ghost.enable to 1, then run Racer. The car's current lap will automatically be recorded. Once the car passes start/finish, the ghost car will automatically start playing. Note that your first lap out you almost never cross start/finish at full speed, so you should continue for another lap. After your 2nd lap, you have a lap that is representative for a good full-speed lap (if you didn't make too many mistakes). Note that every time you improve your lap time, that lap will be used as the ghost lap. So everytime you improve yourself, your ghost car will improve too.
To save that lap for later comparisons, enter the script command 'ghost save <name>' (for example: ghost save myghost). The saves the currently playing ghost lap in the track's 'ghosts' directory. You can then optionally load it by default by setting racer.ini's ghost.load to the name (without the .ghost extension). But loading ghost laps will be improved in future versions to allow more flexible loading. In any case, once you improve the ghost lap, that lap will be taken as the next ghost lap, so just leaving ghost.enable at 1 and emptying ghost.load is a good base for hotlapping.
Hardcore information
Ghost cars are currently stored at 100ms intervals, so at 10Hz. The playback is linearly interpolated to get the situation inbetween keyframes.
There is currently a limit of 6000 samples for a lap, meaning 600 samples/minute, or a limit of 10 minutes for a full lap. This is enough for a lap on the Nurburgring with most cars.
The file format for v0.8.3 is:
struct Key { float posX,posY,posZ; float oriW,oriX,oriY,oriZ; // Quaternion for the interpolation int bits; // 1=BRAKE on, 2=LIGHTS on (lights currently unused) float suspHgt[4]; // Wheel suspension height }; struct GhostFile { char buf[4]; // "GHST" int version; // 1 for v0.8.3 int keyframes; int lapTime; // In milliseconds char buf[4]; // "DATA" Key key[keyframes]; };
Ghost replays are fun!
(last updated November 13, 2012 )