Oversteer Racing: Dev blog #28 – The one where we review the last season (year)

I thought it might be helpful to list out some of the tasks that I've completed this year as a way of reflecting on how the game has developed. There have been a lot of little changes but the main pieces of work have been:-

  • Race order - keeping track of the order of the cars. This is a pretty fundamental thing for a racing game
  • Bug fixing - I've uncovered and fixed quite a lot of bugs and little issues throughout the year
  • AI car pit stops - the AI cars can now decide when to make a pit stop, enter the pits, drive to their 'box', stop for the correct amount of time and then exit the pits. Adding this to the game is a significant piece of work and it now brings a strategic aspect to the racing.
  • Car avoidance - I spent a lot (it feels like months and months) working on code to get the AI cars to avoid other cars. This is now working reasonably well. It may, like a lot of the game, need a bit more tweaking as I add more features and play test the game but it's functional for now.
  • Defensive driving - the last task completed this year was to add code allowing AI drivers to make a decision to take a defensive line when being followed by another car.

Why is it taking so long?

There's a simple answer to this… Oversteer Racing is a hobby project for my spare time. A lot of things affect the amount of spare time I have and, on top of that, a lot of things affect how much energy I have in my spare time to work on the game. I'll be the first to admit that I haven't been able to put in as much time as I'd hoped this year... and I really can't promise that the situation will change for 2019. I'll do my best but hobby projects have to fit around other things.

One game dev blog I regularly read is the blog by Jake Birkett from Grey Alien Games. Early in 2018 Jake wrote a blog post called "You are spending too long making your game" - it's a great read (like all of Jake's blog posts) but it hit home a bit. I've been making Oversteer Racing for some time now and still have a long way to go... but it's taking too long. Obviously I'm not a full time game dev and that brings a whole host of challenges and, as should be clear, I'm not able to work on it full time or expect a return that matches the time put in. With that in mind I plan to start 2019 with a review of my plans for the game and to see what things I can cut from the initial release. There are definitely some nice to haves but I can always add these later so that I can get the game out as soon as I can given the constraints I have.

Oversteer Racing: Dev blog #27 – The one where we go on the defensive

It's been a relatively quiet month in terms of Oversteer Racing. I've managed to do a few things but not as much as I'd hoped and, due to Christmas etc, I expect next month to be less productive than November.

Going defensive

One thing I did look at this month was getting the rival cars to start following a defensive line. I've already added slipstreaming/tows to the cars but I also want the rival cars to react to the player and each other and defend a position. There's a fine balance here as racing cars that are always on the the defensive probably won't be fun. Conversely, racing against a car that seems ambivalent to your presence won't be fun either.

For some time I've been able to create alternative routes on the race track and allow cars to switch between them. This is also how I get AI cars to enter the pit lane etc. Up until recently switching between routes on the main race track has been a random choice by the AI. I've now set up the AI cars to be more likely to take the more defensive line if the car behind them has been within range of a tow during the previous lap.

I plan to also change the likelihood of a driver defending their position to be linked to the "aggressiveness" value of the driver in the car. Aggressive drivers will be more likely to defend than more passive drivers. On a related issue, cars being lapped should not defend the position.

Next month...

Next month will be very busy so it's unlikely I'll get much done on Oversteer Racing unfortunately.

Oversteer Racing: Dev blog #26 – The one where we toe in rather than toe out

It's been another busy month and once again I've been focussing my efforts on obstacle avoidance... it's been some time now since I've looked at anything else!

However, I'm starting to make progress and, although there are still a few collisions, the AI behaviour is getting to the point where some accidents are avoided and the cars are more challenging to race against. The key to the improvement was some time spent tweaking the values that control when an AI car will choose to avoid another car and how the AI cars detect other cars. On this last point I'd primarily been using three raycasts at the front of the car. These can be seen in this screenshot (from last month's devblog):-

Non-player cars failing to avoid each other

I was using a central raycast with another on either side angled out from the car. The result was inconsistent as, initially, AI cars would turn to avoid another car but but often wouldn't turn enough and, as a result, would clip the edge of another car.

By setting up scenarios where cars needed to take avoiding action and stepping through the action I could see the issue. Initially the cars would detect an obstacle and turn to avoid it. This change of direction meant the obstacle would not be directly in front of the car. At this point the left or right angled raycast would detect the obstacle. The car would then turn some more to avoid the obstacle. However, as the car got closer to the obstacle then the angle of the side raycasts meant that the obstacle wouldn't be detected when close to the car. This meant that the cars would move to avoid the obstacle but stop detecting it when it was close and therefore not move enough.

The solution was to "toe-in" the raycasts rather than have them "toe-out" as was the case originally. This means that the AI cars are more 'concerned' with objects that are directly in front of them at long range but less concerned about objects that are in front but off to one side. As the AI car approaches the obstacle then the side raycasts are increasingly likely to detect a side obstacle as well as one in front. The result is a more consistent move to avoid an obstacle.

Screenshot showing raycasts on an NPC car

The AI cars won't always avoid an obstacle but their behaviour is more consistent and they are generally "doing the right thing" now. One other benefit has been that AI car behaviour when racing wheel-to-wheel is also more challenging now - as can be seen by this clip of the red AI car racing against the player (blue and white car).

Animated gif showing AI racing behaviour

Oversteer Racing: Dev blog #25 – The one where it's hit and miss, although mainly hit

Recently I've been working on AI behaviour for the rival cars. The main focus has been convincing the non-player cars to avoid other cars rather than slamming into the back of them. As Oversteer Racing has a more realistic damage model than some top-down racers collisions tend to be more serious than in other games.

One downside of the non-player cars following a series of potential routes around the track means that they have no knowledge of where the edge of the track is. This makes things difficult when it comes to avoiding objects because it's hard to work out which way to turn to avoid the object. For example, if a car has stopped on track then can the non-player cars pass to the left or to the right without leaving the track?

The work I've been doing uses a number of ray-casts from the cars to detect obstacles. Once an obstacle has been detected I use the route markers to determine which side of the track has more space. The car then steers towards that space.

This is still a work in progress as the cars are not consistently avoiding obstacles. To some degree I'm happy if the cars don't always get this right because that seems more realistic but, at present, the non-player cars get this more wrong than right...

Non-player cars failing to avoid each other

Non-player cars failing to avoid each other

Oversteer Racing: Dev blog #24 - The one where we think about the money

Wow, dev blog 24.... that must mean I've been blogging about Oversteer Racing for two years... ouch. I'd have hoped to have more to show by this point but the game is something that I can only work on in my spare time and that's an unpredictable quantity. Also, the game is a labour of love, something I want to do but also something I don't want to feel like a chore.

Although the game is a labour of love I do want to include some sort of monetisation. It's not like I'm expecting to retire on the profits but having a bit of income to help pay for my business costs or assets for my next game or even updates to Oversteer Racing would be nice.

I've previously mentioned some of my thoughts on monetisation and I've given this more thought recently. Having read a few game reviews on the app store it seems that more and more players understand that free-to-play games aren't free to create and that it's important for developers to earn some money from their efforts (if only to fund future work rather than make a profit). However, there's a very clear dislike for large numbers of adverts and many players feeling like the number of ads they see are disproportionate to the amount of playing time they spend in the game. I've seen reviews talking about seeing a minute of video ads following a game session that lasted 30s.

In Oversteer Racing it's clear that the playing time will be quite long. I'm aiming for laps to take around 25s so, even a short 10 lap race would take at least 4 minutes. Consequently showing an advert after a race would not seem, on the face of it, to be disproportionate. I may need to make some concessions though. For example, if you crash out early then perhaps I wouldn't show an ad and maybe I wouldn't show an ad after all races. I definitely don't want to show adverts between menu screens as that, for me, seems pretty aggressive.

I also want people to be able to pay to remove the ads completely. As a parent, and from talking to other parents, I know that this is something that people often want to do for games that their children enjoy.


If people do want to see ads and, as a developer, I'm receiving money for that then I'd also like people to be rewarded. They may not have paid for the game but at some level the amount of income generated by an individual player watching ads would reach the level that someone might reasonably have paid for a game (even though it's free-to-play). At that point I think people should be "rewarded" even though this contradicts the view of some companies where players are "monetised" throughout the entire time they play the game.

I'm not sure what decisions I'll take in the end but it seems to me that if a player has invested a lot of time in the game then they could be rewarded for that. In a lot of games these people would be seen differently and as a source of continued revenue. My current thinking is that people who watch enough ads to have generated a certain amount of revenue should have access to similar content as anyone who pays. So, for example, if I have an option to purchase new tracks then anyone who "pays" a similar amount through ads should get that content too.

Next month...

I'll be returning to AI for the rival cars and specifically looking at how cars behave when near other cars and obstacle avoidance.

Oversteer Racing: Dev blog #23 – The one where we reverse a bit

So this month has been a bit interesting as I have found some time to work on Oversteer Racing, not as much as I'd have liked, but a bit.

Although I've found some time to work on Oversteer Racing I don't have a lot to show for it. I've spent a fair bit of time refactoring some code to make it more useful. Specifically I've taken the code that I use to determine how long a player remains stationary in the pit box and made it more generic so that it can be used to work out the length of a stop for all cars. So, whilst I've done a fair bit of work I've actually got very little to show for it from the outside 😉

I do have some tasks left on pit stops before I move onto something else (it feels like I've been working on this code for the entire year so far) but I'm definitely making progress. The remaining tasks are to hook up the code for calculating a pit stop with the AI code for the rival cars. I then need to make sure the rival cars are correctly fuelled, damage is fixed and so on. At that point I think I can move on to something else... 🙂

Next month

Next month I plan to finish off the remaining pit stop tasks and then start looking at obstacle avoidance for rival cars.

Oversteer Racing: Dev blog #22 - The one where the wheels come off

I have to be honest, it's been a really bad month for spending any time on Oversteer Racing. I had a huge piece of work (for another project) to finish at the end of May and that left me exhausted and the last thing I wanted to do was spend even more time coding. I've been surprised how much working at a consistently high pace for an extended period of time has taken out of me. As a result I've been spending some time doing other things and taking a bit of a break.

That said, I'm never a fan of stopping work on something completely as the overcoming inertia and restarting can be pretty difficult... so I have done some work on Oversteer Racing. The work I've been doing has still be focused on pit stops. Building on the work from last month (where the rival cars were passing through the pits without stopping), the rival cars now turn into their pit box and then move out into the pit lane again in order to leave the pits.

I'm also happy with the code that allows the rival cars decide whether they should be pitting or not. So there's a good amount of groundwork done for the "race craft" of the rival cars.

Next month

I need to determine how long rival cars should stop for.

Oversteer Racing: Dev blog #21 - The one where we pass through

As suggested last month, it's been another fairly quiet month in terms of work on Oversteer Racing. Part of the problem of being a 5-9 developer, or more often a 10pm to 12am developer, is that it's very easy for other commitments to get in the way of the small window of time you have to work on a project. Also, even when you do have a bit of free time, your day job can leave you exhausted and not in the mood to do more coding late into the night.

That said, I did manage to do some work on pit stops for rival cars. I've got a working version of the code allowing the cars to decide when to stop based on fuel usage, tyre life, their team mates, damage and the progress of the race. I've also set up the paths for the AI cars to follow so that they can enter the pit lane, turn into the pit box and then exit the pits.

At the moment the rival cars don't stop in their pit box and refuel, change tyre or replace damaged parts. This is the next piece of work that I need to do and I'm hoping that I'll have a bit more time to work on this in June.

Oversteer Racing: Dev blog #20 - The one where nothing happens

It's been a pretty poor month to be honest. I've had so many other things taking my attention away from Oversteer Racing that it's been very difficult to complete any tasks.

All I've managed to do this month is:

  • Fixed a bug that meant the dust particles kept playing after the car had stopped moving
  • Fixed a bug that meant the lap counter may occasionally miscount the number of laps completed
  • Fixed several bugs in the code for calculating the time gaps between cars and for also calculating lap split times

Unfortunately, for a variety of reasons, I don't think next month is going to be much better than this month in terms of my time. However, there is some light at the end of the tunnel for June.

Oversteer Racing: Dev blog #19 – The one where I had to do something else

It's been a really busy month and I've had to spend quite a lot of time on one of my other projects, my fantasy F1 competition. It's always the same this time of year because of the start of the F1 season and the hard deadline that the start of the season represents. The game needs to launch a couple of weeks before the first race in order to give people the time to sign up. The hard part is picking the right cost for the drivers and teams so that there is a high number of possible teams but it's not easy for players to pick teams with lots of good components. Once the game has launched I can't change the value of the components so, if I get it wrong, then it can have a detrimental effect on the game for the entire season.

But, back to Oversteer Racing, what have I achieved in the last month?

Unfortunately the answer is not a lot.... but I did do something, no really. I found and fixed a bug that caused the sand/dust particle system to continue playing after a car had left the track but was now stationary. Unfortunately that's all I've managed to do and that's pretty disappointing but, when you're one person working on a game then, when you have to stop to do something else, all progress stops.

Next month

I really hope to be back working on the AI code again. I need to get this finished off so I can move on to other things.