Oversteer Racing: Dev blog #18 – The one where we can’t count

It’s been an interesting month. I’ve not made much progress on new features but once I started adding AI cars into the game it uncovered a few issues…. so I’ve been focusing on fixing those.

1, 2, 3 … er

As I’m now able to add AI cars to the game I thought I’d add some code to show the current race order. Unfortunately that’s where things went awry…

The main issue was that the lap counter would sometimes lose count, particularly for the player car. Obviously being able to count the number of laps a car has done is fundamental to circuit racing. The AI cars accurately keep track of the number of laps completed but the player car would value would drift and end up one to two laps off. Fortunately the issue turned out to be fairly simple and one that was only triggered when more than one car was on track. This was why I hadn’t spotted the issue when I’d written the lap counter code and it only came to light at this stage. Easily fixed though.

The second issue was that there was a bug in the code that works out the split times between the player car and the car ahead and the one behind (as appropriate). This worked reasonably well but there was an intermittent issue whereby the time for the split to the car behind would occasionally be calculated as over 20 seconds when the gap was actually much, much lower. This turned out to only happen when cars were on different laps. So, when the lead car crosses the start/finish line it’s a lap further on than the following car. At this point the code should look to the previous sector entry times to determine the split. Instead it was using the current sector of the lead car and looking back a lap to when the following car entered the same sector – which explains the discrepancy. By the time the split was next calculated the cars had often moved to another track section and the code got the comparison correct and showed the correct split time.

Next month

I’ll be back working on the AI code for rival cars.

Oversteer Racing: Dev blog #17 – The one where we make plans

It’s been a very busy January and there’s always a bunch of “admin” stuff to do. So a lot of my time has been spent doing my personal tax return, company accounts and company tax return etc. Talking about that in my latest dev blog is not going to be a rivetting read so I’ve decided to focus on my plans for the coming year.

Get the game into players’ hands

OK, so this may be optimistic given that I’m working on this in my spare time but I think it’s possible. Afterall, I’ve been deliberately vague about what the above means. Ideally I’d have the game out and available but I think it will also be a reasonable achievement to have reached the point where the game can be tested by a few people. If you’re interested in doing this then do let me know although, in all honesty, I’m unlikely to have a ‘testable’ version of the game before the Autumn.

More of the time, all of the time

There’s no escaping the fact that the major issue affecting how the game is developing is a lack of time on my part. I can’t see this changing significantly but what I can try and do is set aside more time more regularly. The beginning of the year has been filled with a number of admin tasks as I mentioned but I’ve also had some coding work to do on other projects… and sometimes I just need a break from coding 😉 However, I think the only way I can improve the situation is to set aside the same bit of time each week to work on the game. this has the benefit of having a clear time that I can work towards each week. Odd things are bound to crop up from time to time and mean that this isn’t always possible but I think it’s likely to pay off overall.

Recent work…

This past month I’ve made some improvements to how the car behaves when it’s receiving a tow and when it’s entering/leaving the gravel traps etc. This makes the car behaviour seem more natural but also provides important benefits to overtaking. The changes mean that, when pulling out from behind a car to pass, the advantage of the tow now decreases gradually and allows the overtaking car to carry the extra speed for a bit longer and this helps it make the pass.

Next month

I’ll be working on the AI code for the rival cars. At present they’ll lap the circuit reasonably well and can take alternative lines. However, what they don’t do is challenge for position and that’s my next task.

Oversteer Racing: Dev blog #16 – The one where we take stock for 2017

At the end of 2017 I thought it would be a good opportunity to take stock and review what I’ve achieved with Oversteer Racing over the last twelve months.

Progress

Pit stops

If you’ve been following along with my dev blogs then you’ll know that I began the year by working on pit stops. This included the UI allowing the player to refuel the car, change tyres and fix damage and also animating the pit crew as they run to/from the car.

I also did my first video dev blog on pit stops:

User interface

I’ve created a functional user interface that allows players to name the drivers and teams and also place themselves in the team of their choice. Although the UI works it’s far from pretty at this moment in time.

Rival cars

A lot of work this year has been on rival cars. The first step was to get the cars to drive the circuit and put in competitive lap times. I then worked on tracking the race position of the cars and calculating split times between the cars. I also worked on aerodynamic tows and this made it easier for cars to overtake each other. The final part of this work for 2017 was to work on code to allow rival cars to return to the circuit if they had left the track.

I also published a second dev blog:

What’s gone well?

I’ve been pleased with some of the developments I’ve added to the game during the year and, in particular, the work on rival cars and their AI. After all, it’s not a racing game without other cars to race against.

What’s not gone well?

The main issue has been a lack of time and that’s meant I’ve achieved far less than I’d hoped this year 🙁

Next year

My main focus will be to complete all the functionality of the game so that I have a working implementation of everything. I will then do a lot more play testing and refine the game further.

Happy New Year!

Oversteer Racing: Dev blog #15 – The one where it’s slow going

Mucky Creature is a company run by one person and sometimes it’s difficult to find the time to work on these projects. Unfortunately November has been one of those times. Lots of other things crop up that demand your attention and, when you do find a bit of time, you’re a bit too frazzled to be able to focus on code. So, it’ been pretty slow going this month…

That said, the work I have managed to do has been focussed on how AI cars recover after leaving the track. The AI does make mistakes and, most of the time, this just means they go a bit wide in a corner but sometimes they do end up off the track. Also, when going wheel to wheel with anther driver the “aggression” factor of the AI driver can mean that a more placid driver won’t turn in on a competitor and can then run out of room to make it through the corner. The other situation is where a car has been bumped by another car and has ended up off the track.

In simple situations the AI car can work out where it’s meant to be going even if this is not the waypoint it was originally aiming for. This process of skipping a missed waypoint is often enough to allow the car to recover and carry on racing.

However, in some extreme cases the AI car may end up in the gravel or in such a position that it can’t drive its way out. In these situations we have to “break the spell” somewhat. I could implement a solution that allows cars to execute a series of back and forth movements to return to the track. This would be a lot of work and it’s not something that I think is a wise use of my time at present as it doesn’t significantly improve the game. So, currently my solution is to allow the car time to recover on its own but, if that doesn’t happen, it is moved to the next waypoint, correctly rotated and released.

This seems like a reasonable compromise between the work needed to achieve something and the actual impact it has on the game. I’m hoping this is one of those situations where a shortcut is acceptable.

Oversteer Racing: Dev blog #14 – The one where we get a tow

For this dev blog I’ve created a video showing the progress I’ve been making with the game. The transcript for the video follows.

Transcript

Welcome to the second dev blog for Oversteer Racing. I had hoped to produce these video dev blogs more frequently but it’s been a busy year so this is my second… only nine months since the first.

The focus of this video is to show you some of the progress I’ve been making on the game. Specifically I’ll be talking about the work I’ve been doing on rival cars and AI. We now have more than one car on track and that’s a major step for a racing game. I’m driving the blue and white car and the AI is driving the red car. On track you’ll see some diamond markers. When playing the game these would be hidden but they’re used by the AI to determine where the track is and the best route. Currently this setup of track markers allows the AI car to follow different routes around the track, such as taking different lines through a corner, and the lap times are comparable to those I can achieve with the player car.

The other work I’ve been doing is on the situational awareness of the AI cars and also modelling the effect of an aerodynamic tow on cars following another closely. So, as you see me drive around the track you may notice a yellow line extending from the front of the blue and white car. This is not something that will be visible in the final game but demonstrates when the car is getting an aerodynamic advantage by following the car in front. The size of the advantage is proportional to the how closely the cars are to each other. The closer they are the more of a tow the following car gets and the faster it can go.

In the footage you can see me using the aerodynamic tow to catch up with the car in front and then pass it on the inside of the first corner. When the player car is alongside the red car you may be able to see a yellow line extend from the side of the red car. This is used for me for debugging and shows that the red/AI car is aware that another car is alongside and it adjusts the line it takes through the corner to allow the passing car room. In the actual game I plan to link this to an aggression factor so some drivers are more likely to turn in on passing cars and defend strongly than others.

So, I hope that’s given you an insight to the work I’ve been doing and how Oversteer Racing is shaping up.

Oversteer Racing: Dev blog #13 – The one where we work out where we are

This month I’ve been tackling two fairly difficult tasks…

Where are we?

It’s a simple question and one that’s fundamental to a racing game. You can’t have a racing game unless you can work out which cars are in which position and split times between those cars. It seems like an easy problem to solve but in circuit racing there are lots of things to consider (such as lapped cars). In other games they rely on keeping a linear representation of the track in code and, based on track position, move the cars along that linear representation. In my case it’s hard to generate that linear representation without adding something that would allow me to determine exactly what point a car is on the track itself (probably by tracking the outer and inner edges of the circuit and using that to determine the car position). This sounds like quite a lot of overhead and, as I’m targeting mobiles, I felt it was overkill.

The track is already divided into three sectors and I record sector times but this isn’t accurate enough to allow me to work out race position. I can tell if two cars are within the same sector but working out which car is ahead in that sector is not possible when just recording current sector and current lap.

To solve the issue I decided to track three pieces of information:

  1. Current lap
  2. Current sector – incrementing each time a car enters a new sector and not resetting each lap
  3. Current sector entry time

I could then turn these three pieces of information into a numerical representation of each car’s race position:-

car_progress = (current_lap * 100000000) + (current_sector * 100000) + (100000 - (sector_entry_time * 10))

(The numbers are held in variables obviously.)

Using current lap and current sectors multiplied by modifiers is fairly clear to understand but to determine position within a sector I add the value for an additional sector and then subtract the sector entry time. By subtracting the time we make sure that a car that enters a sector later than another (i.e. with a greater sector entry time) ends up with a smaller number than a car that entered earlier.

Once we have this figure for each car then ordering them is easy and from that we can determine the race order. It’s important to use an appropriate data type as, if using floats, you may find they get rounded.

The multipliers are used to stop the data from each piece of information overlapping in a reasonable length of time; we basically separate the individual bits of information by several orders of magnitude. The size of the multipliers depends on the game, if the lap was longer then you’d need to adjust the modifiers accordingly. Your mileage may vary 😉

I also worked on calculating split times for the player. This can be summarised as the time elapsed between the player and, say, the car that’s ahead reaching the same point on the circuit. I could calculate only when the player crosses the start/finish line but I think it’s more fun to be able to calculate this more frequently. To do this I tracked sector entry times for each car and then it’s a case of looking up the entry time for the relevant sector and relevant car. Knowing the race order allows me to work out the “relevant car” and we already know what sector the player car is in. We then determine the difference between the times to determine the split.

Where is everyone else?

The other task I’ve started work is helping the rival cars become more situationally aware. I’ve started adding “sensors” (ray casts) to the cars so they can detect other cars that are near them. This will allow me to control how the cars behave to defend or attack a position. It will also allow me to implement changes to allow cars to get a “tow” (get into another car’s slipstream) for other cars.

Next month

I’ll be carrying on working on car sensors and behaviour. If there’s time I’ll work on code to allow AI cars to recover from spins as I didn’t manage to work on that this month.

Oversteer Racing: Dev blog #12 – The one where we set the pace

This month has been slightly better than the previous two and I’ve been able to put a bit more time in on Oversteer Racing.

Teaching rivals how to drive

A lot of this month teaching the rival cars how to drive. I’ve spent quite a lot of time planning how to implement the code allowing rival cars to race around the track. In the end I went with a waypoint system but allowing rival cars to follow different routes on the track. This means that they can move into a defensive position for a corner or pull out to over take another car etc. The same system will also allow the cars to navigate through the pit lane.

At present their lap times are within 0.5-1s of my best time around the test track and that’s pretty good for testing. As the rival cars are not currently aware of other cars on track they are difficult to pass as they will, with another car alongside, turn in on them when going through a corner. This does result in some pretty spectacular crashes. Until the rival cars are aware of other cars it’s not clear how close their lap times should be to that of the player to create the best racing experience. With that in mind, the rival cars are “good enough” at the moment. Something that was important to me is that the rival cars are controlled in the same way as the player car so that the racing is as fair as possible – there are no “cheats” for the AI cars.

Now that we have rival cars on track I’ve also been able to start work on code to track race position and this will lead on to showing race position in the user interface etc.

Two cars racing on track - alpha screenshot

Two cars racing on track – alpha screenshot

Next month

Next month I’ll carry on working on the code to determine race position (it’s not as easy as you might think). I’ll also be working on code to allow AI cars to recover from spins or trips into the gravel traps etc. If there’s time I also plan to look at race strategy for AI cars.

Oversteer Racing: Dev blog #11 – The one where the rivals turn up

Last month was another difficult month as I’ve been very busy and not able to put in as much time on Oversteer Racing as I’d have liked. That said I did manage to do some work on the user interface and also to work on improving the code that tracks performance (lap times etc) during the race.

The opposition

I did manage to do a bit of work on “the opposition” and some research on how best to tackle the artificial intelligence (AI) required to get the cars to compete reasonably realistically. How the other cars race against the player and amongst themselves is key, in my opinion, to a good racing game. I’ve been reading a few articles and doing some background research on a variety of topics including AI, neural nets, rules of various motorsports and racing technique.

Oversteer Racing screenshot showing two cars on track

Next month

My current plan is to spend a bit of time working on various ideas for how to control the rival cars. I also need to do some work on stats collecting for each car so that I can track the progress of the race and, ideally, present some graphs after the race. I don’t plan to create any of the graphs in the coming months but I plan to make some changes to allow me to record more telemetry from the cars.

Oversteer Racing: Dev blog #10 – The one where it feels like the brakes are stuck on

This month has been pretty difficult. I’ve really struggled to find time to work on the game. That’s largely due to lots of other things needing my attention and reducing the amount of free time I have. When I do find a bit of free time I’ve generally been pretty tired so I’ve not been as productive as I’d hoped. It’s all just part of the ups and downs of creating things in your spare time but it can be frustrating.

Functional UI

I have carried on working on a functional version of the user interface for the game… I say “functional” because it’s definitely not pretty. However, under the hood it’s doing what I want and later on I’ll revisit the scenes and work on the aesthetics. To be honest I find working with the UI system in Unity hard work. Obviously it’s a lot better than it used to be but stuff like validation with regex or displaying error messages etc still seems harder than it should be.

Thinking about live ops

I’ve been doing a bit of reading about “live ops” in games and whilst I think that might be a step too far for me at the moment it’s a really interesting topic. Given that my “day job” mainly involves server-side coding that side of “live ops” doesn’t concern me. However, I want to get the core of the game finished before I even think about things like “live ops”.

Next month…

Right, I really am going to park the UI stuff and get back to some game play work next month. Now that I’ve some teams and driver names to play with I’ll be tackling end-game scenarios and possibly the two championships (drivers’ and constructors’).

Oversteer Racing: Dev blog #9 – The one where we see what’s on the menu

This month has been interesting as I’ve been mainly thinking about some of the user interface issues and work associated with allowing users to customise the game.

How big will the game be?

As an indie dev, and the sole person working on the game, the size of the game is an important factor as it defines the amount of work I want/need to do and this also affects when the game will be finished. I can’t afford for the amount of work to increase because this means the game will take longer to complete. That said, I need to be able to provide enough content for players and hopefully some additional features that people might be willing to pay for.

As a result, I’ve spent some time considering how much content I want to create. My current plans are to create a game with five teams, each with two drivers (making ten cars in total), and nine tracks although not all tracks may feature in the free version of the game. I feel that this is achievable and should also provide a significant challenge in the races.

Making money

Making games is a lot of hard work and I’d like to help fund future work by generating a bit of money from Oversteer Racing. I plan for the game to be free and to charge for some additional content. Things may change but some features people may pay for include:

  • Extra tracks
  • Weather effects
  • Ability to change driver and team names
  • Functionality to change the design of the cars

Next month…

I want to finish off some of the menu scenes (at least in terms of functionality if not design) and will then focus on some of the code for managing races. This is likely to include work on handling the end of races either through the number of laps being completed or through retirement.