previous arrow
next arrow


At the end of my formation at Creajeux, I had to look for an internship to validate my diploma, this is how I found myself at Kylotonn. This studio had released WRC 5 (game with which they obtained the licence) and was beginning the production of WRC 6. It has been the first professional game I worked on and I was really pleased to begin with this one, being satisfied to work on a racing game (a kind of game I like) but also to use C++ on a proprietary engine. This last, called Kt Engine, allowed me to discover something else than Unity or Unreal, which I studied in school.

WRC 6 is a racing game where you can play solo just launching races or in career mode, or in local or online multiplayer.

I principally did gameplay tasks including these ones.

Versus races gameplay

The game had special tracks in some countries where the route buckled on itself so it had two parts of the track side by side for the most part of the circuit. One of my longest and hardest tasks was to make the versus gameplay work on those tracks. This gameplay, requiring two players, consisted of making each car appear on different parts of the track so they start side by side but with a route difference.

As you can see on these two pictures, each player starts at the middle of the track of the other. They won’t have the same difficulties at the same time of their race.

This game mode has provoked many issues because it wasn’t intended by the race system in place. For example, when the second player went through his first checkpoint, he was teleported by the anti-cheat verifications because it wasn’t the first planned in the race in the defaultversion, the player couldn’t complete his run. An other problem was caused by the spline used to indicate the route to follow to the vehicle, telling him if the player goes to far or not, here again the second player could be teleported to the wrong places of the race where he shouldn’t be.

I managed to give another spline to the race component for the second player and created a filter system on the checkpoints so they ignore one of the players going through. Other components created issues like other checkpoints used for anti-cheat purposes or the pacenotes display system which we filtered the same way.

The HUD of the second player caused trouble too as it displayed his progression cursor in the wrong spot, so I changed the calculation of his position by taking into account the location of the start line on the race spline.

Vehicles progression tracking and interface

The addition of the versus mode and tracks with special routes brought numerous issues regarding the tracking of the vehicles progression through the race. The calculation I mentioned earlier consisting of taking in account the position of the start line being done a multiple places and being used for many things, I created a structure to do it allowing to only read the right values when the time comes.

We can se, on the picture above, the calculation of the start line position from the beginning of the spline.

At first, this structure contained only the position of the start line, the vehicle position according to it and the total length of the spline, allowing the re-calculation of the checkpoints position and other triggers laying on the road.  Each vehicle getting its own structure, there was no issues with the second player when following his progression or make him respawn to the right place.

Accomplishments and achievements

The game contains an intern accomplishments system rewarding the player for doing specific actions during races. Some of those accomplishments are achievements (or trophies) aswell for Steam, XBox Live or the PSN.

I spent a good amount of time making the unlocking of all of them possible by the update of some being already in the game or the addition of new ones, all requiring the tracking of the player’s actions at several places in the game, those places being in the menus (tweak the vehicle settings, watch the credits…) or in game (win a race, do a flip over, finish with a puncture…). Fortunately, a lot of them were manageable at the same spot, unlocking at the end of the races, but others required more thoroughness. I ended up creating a Google Sheet keeping track of my progression in this task where I was easily lost.

An important part of this task was also to allow the player to re-obtain achievements if he resets them, like it is possible on Playstation. Some conditions went from “win a race” to “win one or more races”, the function in charge of the achievements unlocking checking itself if it is already unlocked or not.

Sound related tasks

On several occasion, I had to work on the game sound effects.

First, I made sure that left and right wheels were separated, allowing to have, for example, asphalt sound on the left and grass sound on the right when the player begins to go offroad. Before, we used the higher surface index (say, 0 for asphalt, 1 for grass, 2 for snow, etc..) among the detected surfaces under each wheel, and we played the corresponding sound at the middle of the car. Split the sounds between left and right allows a little more realism and immersion. To make this possible, I had to duplicate a good amount of the variables used to manage the wheels sounds, like slipping, rotation force or brake values. I also doubled the sound events instances so we can play the same sound twice when the two sides are on the same surface.

Next, I changed the sound events used for the pacenotes to use only sounds loaded when needed then streamed. This made me change the management of those sounds, especially on the recovering of their informations such as the length, accessible only when the sound has been fully loaded. I also had to change their loading in the engine because they where unloaded automatically after they were played and were loaded only when played, but I wanted to load them before for some of them. The pacenotes being stored in a pile as the player goes forward, we wanted to load them when they were detected so they’d be ready when we wanted to play them.

I also added tutorial voices in the menus which describe to the player what’s going on in it. To do this, I added a new sound bus child of one of the fourth already existing (Music, Sound effects, Voices and Interface) and I managed the sounds the same way I did for the pacenotes by loading them when needed.

Finally, I updated the system used to handle the sounds reverberation in the forest. The code already in place was going through the chunks (cubic zone containing game assets) around the player to detect trees in them during all the gameplay, which was really performance heavy. I used an Oriented Bounding Box (OBB) placed around the vehicle to replace this code and detect the trees in this zone only, and then calculate a weight relative to the impact that each of them will have on the sound reverberation. Once the weights of each side of the vehicle go beyond the required threshold, a reverberation value is calculated.

Keyboard & controller bindings update

Some bindings were already in the game but on the wrong buttons, others were simply not there. The important part of this task was to create a binding which scrolls through the gameplay cameras in reverse from the one that was already done, so the player can navigate both ways to get the view he wants. The functions managing the camera change being intended to go only in one way, I had to adapt some and create new ones, which took quite some time.

I’ve done other minor tasks which I won’t detail here, like the application of a red glowing on the brakes according to their temperature or the activation of particles when the player is rolling on the rim of his car.

I appreciated a lot this project as a first professional experience and the atmosphere with the other employees was really good. I found the majority of my tasks interesting and rewarding, which helped me to always give the best of myself even if it was complicated at times.

I was also very honored to have my name in the credits of a commercialised game for the first time !



previous arrow
next arrow
previous arrownext arrow