Posts Tagged ‘driving’

PENNZOIL JEEP BAJA VR

Saturday, September 16th, 2017

Push the limits of performance in the desolate beauty of Baja, Mexico, and find out what it takes to dominate the desert.

Pennzoil Jeep Baja is high octane VR experience developed from the ground up to showcase the unique performance of the Jeep Trailcat and Pennzoil Platinum.

I worked with the fantastic team at Shadow Industries on this wonderful project that included integration with a physical simulator. It was a beast of a machine, simulating the beastly 707bhp Trailcat. The goal was to make the player feel like they were wrestling with a tiger!

Unfortunately, unless you catch the exhibit at an event, you can’t play it. The best I can do is show you a 3 minute trailer made for the website.

Pennzoil Air Lift Drift

Saturday, April 9th, 2016

12138771_1710675969147169_400913326_nWatch a 707hp SRT Dodge Hellcat smoke it’s tyres to dust in this flat-out drift experience from Pennzoil. This project was built to wow the crowds at trade shows and racing events, but is also available publicly for Gear VR and Oculus Rift. If you’re lucky enough to have access to one of these devices, give it a go!

Download for Gear VR
Download for Oculus Rift

I worked on upgrading the existing app by Shadow Industries for multi-platform public release.

Hero Squad 2

Sunday, June 29th, 2014

HeroSquad2Race to the emergencies as fast as you can in this open-world driving game. This is a sequel to the original popular Hero Squad game, with all new missions, new gameplay mechanics and a new continuous score-attack mode.

 

Play Hero Squad 2: Rapid Response in your browser.

Hero Squad: Rapid Response

Sunday, November 18th, 2012

Hero Squad: Rapid Response, is an ambitious driving/flying/sailing game built with Aardman Digital for the BBC. It helps promote a new children’s show called Hero Squad on CBBC. Train for active duty in the rescue services alongside the kids in the TV show!

Play Hero Squad: Rapid Response.

This game plays much like the earlier GTA games (now available as fully legal free downloads), but with a lot less nefarious activities. It’s all about getting to the scene of an incident as fast as you can in either a fire engine, a lifeboat, or a coastguard helicopter.

There were quite a few technical innovations required to bring this game to life. We wanted the gameplay to exist in a large free-roaming game world so that you could plat your own route to each incident. You can take shortcuts if you want, and the road layout was meant to look plausibly like a fictional coastal town in the UK. This meant that roads should almost never be set on a grid, which always makes a game map look like an American city.

CGI

You view the action from essentially a top-down view, except that it’s not quite directly above. The camera looks to the north slightly so you can see the sides of buildings, vehicles etc. To achieve this, all relief sprites in the game were created by Aardman’s awesome CGI department, and rendered into 3D turnarounds of each item. Every car, boat, building, tree, fence and even lamp-posts is a multi-layered set of sprites, separated into a colour layer, a shadow layer and sometimes into a matte layer (for vehicle recolouring). The sheer amount of assets included is astonishing, and runs to several thousand separate bitmaps.

Map

The map itself is created in Flash, and composed of the aforementioned sprites for buildings and vegetation, dynamically depth-sorted above textured vector roads and fields. The area of the map is simply huge, being 20480px wide and 12288px tall. Far too big to work on in one piece in Flash. Simply viewing the full size map at once in the IDE easily causes Flash to crash, so the map is broken into 1024x1024px squares. These exist on individual frames in small groups of tiles, so that the seams can be worked on in-situ for each larger area.

At runtime, each tile is only added to the stage as needed, along with all the underlying physics logic for that tile. At any one time, there are only a few small chunks of the map in action, which keeps the number of items being depth-sorted low. It also keeps the amount of objects in Box2D to a minimum, making collisions faster to process. Tile graphics are cached to bitmaps as the vectors are rendered, of course. This doesn’t include buildings and other relief objects however, as these have to be depth sorted against the traffic on the roads.

We processed the map into a single 250 megapixel image after production. Placing it side-by-side with exports of the GTA-3 map, they are roughly equivalent! We believe this to be by far the biggest continuous, non-tileset game area of any Flash game to date. If you know of any bigger, post a comment!

Download large JPEG (1mb)

Download HUGE JPEG (30mb. Warning: This may crash your browser!)

 

 

 

Physics

In-game physics is provided by the ever-spectacular Box2D. The helicopter is a pretty simple vectored-thrust model. A torque is applied to turn it to a heading, and a rotational friction is applied to fight that action. Forwards/backwards are simple impulses.

Lifeboat physics is more complex. It consists of a virtual keel that opposes sideways motion, but not fore/aft motion. The motor just pushes the boat forwards, and a torque changes it’s heading. It’s actual path of motion however is determined by the sideways-force on the keel.

The firetruck (and all cars/busses/lorries) have the most complex physics model. It has two virtual wheels that operate a bit like the boat’s keel, but at each end of the vehicle. When the player steers, the front wheel is turned smoothly to an angle. Slip angles are calculated from the linear motion at the point of the wheel, and a sideways force is generated and applied. The resultant slip angle force is a simple model that works similarly to real tyres, where more angle means more force – up to a limit. After that, grip drops off progressively. Acceleration/braking is applied as a force along the line of the wheel, and steals from the traction circle available for sideways forces. Accelerating/braking also affects a weight-shift variable, which modifies the grip available (the size of the traction circle) at each end of the vehicle.

This attention to detail means that you can get all sorts of realistic looking situations happening with the firetruck dynamics. Accelerate through a corner and it will understeer. Brake mid corner and it’ll plow straight on. Lift-off mid corner and you’ll get oversteer, which you can catch with opposite lock and a powerslide if you’re skilled enough! If not, you may end up fishtailing, or spinning out entirely. You can do reverse J-turns, and even donuts if you set it up just right with a suitable piece of grass.

For the ground, the same physics are created no matter which vehicle you happen to be driving at the time. There can be sea, air and road traffic existing together no matter which vehicle you’re using. Extensive use of Box2D’s built in collision bits and categories helps differentiate the various things that should collide for each of the vehicles. For example, boats collide with the grass layer so that they never cross land. The helicopter only collides with the special tall building layer, which is not in the same position as the ground building collision layer. The firetruck collides with buildings, vegetation, fences and fields of course, but also collides with the grass layer but with no collision response. It is only used to determine when to put cars into a low-grip situation so they slide further on the grass.

Vehicle AI

Non-player-controlled vehicles in Hero Squad are driven by a computer AI. They follow guides built into the map tiles, but they have to be real drivers. To make collisions with other cars look as realistic as possible, all cars are physically modelled. That means the AI drivers have to actually use an accelerator, brakes and steering just like the player does. They measure their distance from a centre-line that runs down the middle of every drivable road, and try to steer such that they are a set distance to the left of it. When you press space to sound your siren, they internally alter this distance to be greater, and the AI automatically pulls them over to the edge of the road. Drivers are free to go wherever they like, and at any junction they just pick a random direction to drive in. Some roads are marked as one-way, so drivers don’t end up in dead-end streets with nowhere else to go.

Cars are added to the map to random road segments that are off-screen. The AI has to be smart enough to deal with what happens if there are no more road segments – remember there’s not much of the map available at any one time. When they’re lost, and don’t have a current road segment to follow, they are eligible for removal from the world, and are recycled into a new car somewhere else.

Wind/Water currents

When flying the helicopter, and driving the boat, you are pushed around by wind and currents in the water. Both effects are achieved with a bitmap vector field directing the flow of each particle. New particles are instantiated at random. Every frame, they look up the colour in the vector field bitmap. The red channel encodes the left/right force, and blue encodes up/down. The particle simply moves according to that force.

The vector field image itself was created by hand in Photoshop. I started with a simplified monochrome map of the land. Then I painted 0x800000 to the red layer, and 0x000080 to blue. These values are right in the middle, and mean “no force”. Then I painted bright red to the land anywhere I wanted the water to flow right, and black wherever I want it to flow left. The same with blue for up/down. If you want to reduce the amount of current in an area, you simply paint with 0x800000 or 0x000080 to bring the values back to the ‘middle. This is very similar to how Flash’s BitmapDisplacementFilter encodes values.

Once finished, the layers are set to blendmode “add”. The resulting bitmap encodes all the forces that make up the currents. You can use things like the smudge tool and blur filters to alter the smoothness and tweak individual areas. I managed to get the water flowing around rocks, up and down streams and so on with this method.

 

Speed Racer Chaser

Friday, April 25th, 2008

speedracerUse cursor keys to drive in this high-speed racing game. Hit spacebar to deploy your car’s weapon, and shift to launch into the air. Can you beat all the other players, which are recordings of other real human drivers?

Postmortem:

Ah, a chance to do a pure arcade racing game, with actual racing cars rather than trollies or reindeer or airport baggage karts! Brilliant. I was determined to make a really good Flash racing game, with arcade but partially realistic handling, fun tracks, weapons and a little bit of a multiplayer twist.

AI in racing games is hard. Even the big name consold games don’t get it right, and have either unrealistically good AI drivers or comically bad ones. In a lot of games, the computer AI just bulldozes through your car sticking to its pre-programmed lines like a limpet. It feels unfair, and it’s not good enough! Rather than build a crappy AI for this game, I came up with the idea of recording people’s gameplay whilst they were racing and storing them on the server (stored by their starting position and overall performance). Then, when a new game is started, the server puts you in a random grid position and sends out 8 replays – one from each remaining grid slot. They are picked at random, but in a skewed way so that you play against a mix of the best, worst and mediocre players out there. That’s self-ballancing – the range of opponents you meet is determined by the actual range of skills out there, from good to bad. There is a par time over which your score isn’t recorded to avoid skewing the results towards people who just leave the game running forever, but other than that it’s a level playing field. This strategy really worked for this game, and everyone gets opponents who play roughly at their level – and some who are faster that they can work towards beating.

The big problem with storing and serving replays is that there’s a lot of data. AS2 doesn’t handle binary data very well except in pre-given formats that are delt with internally like jpegs, sounds or SWFs. So, a replay consists of a great long string of car coordinates etc in a text format. There’s very little encoding, as I found that simply processing the raw strings was enough of a task for Flash, let alone processing an encoding on top of that. I’d have liked to have compressed the strings, or base-64 encoded them or similar, but it just wasn’t feasable. The remaining problem was that each play of the game required about a 1mb download of replay data from the server, which was very bad for bandwidth when the number of plays started to climb dramatically. We had to trim back the number of replays sent to the client to just 4, then 2, then none as the load increased. The URL presented here allows you to have all 8 opponents switched on, as it’s going to be pretty low-load from this website.

Car handling was a major area of improvement in this game over previous racers I’ve built. The cars have a single giant virtual tyre that they run on, which resists sideways motion and promotes forwards motion. When the car turns, this virtual tyre turns with it, causing the car to grip and change direction. This is reasonably analogous to the way a real car turns in many ways, and leads to a decent feel. Rather than programming in effects like sliding if you turn too fast, or if you land a jump facing sideways to the direction of travel, it just naturally falls out of the physics model. Likewise, slow speed turning works better this way too. The model is also very tunable to different car styles, so some are fast but have little grip, some have too much grip and are hard to control, some are ballanced and so on. There is no ‘best’ car, although there tends to be a couple per track that people end up using predominantly over the others.

A big part of the Speed Racer film was the twisting looping jumping corkscrewing tracks. In a 2D game you’re limited to how far you can recreate these effects, but the tracks certainly do have these stunts in them, which is a nice effect. Even better, you can short-cut them in cunning ways using your car’s jump ability, which adds a little depth.

Another requirement from the film is the use of car-to-car weapons. This poses a problem with the replay technology, as a replay is by its nature an asynchronous event. It does not contain data saying how the human player reacted to being hit by a weapon at any random point. The simple rules I adopted were to never fire weapons at the human player (ie, weapon usage is not recorded in the replays), and if a replay car gets hit, to simply spin it around in a straight line along its direction of travel until it falls off the track edge.

The other thing you can’t do with a replay is car-to-car collisions. You can’t purturb the replay car from its course, as that would put you ‘off’ the replay line with no obvious way to get back on it. You can’t just slow or collide the human player either, since that would get recorded in their replay and when played back to another player, would look strange as they randomly react to a collision that didn’t happen. There was nothing better I could think of than simply allowing cars to overlap. Not completely satisfying, but that’s all I could do.

As cheating features quite heavily in the film races, I’ve deliberately allowed for it in the game. If you use your car’s jump facility carefully, there are a number of places you can take shortcuts by jumping sections of track. It’s risky of course – you stand a fair chance of falling off the track instead of saving time, but that’s good for ballance.

There’s an issue with the pace of the game and some of the cars. If the player picks one of the faster cars, it’s hard to see what’s coming and to keep the car on the track whilst cornering. Falling off track is punishing to your time at least, but doesn’t throw you out of the race because it’s really rather easy to do. If you opt for a slower, more controllable car, you stand less chance of keeping up overall.

Performance is vital in a game like this. Keeping the framerate high was always a priority, right from the beginning. There’s a huge amount of stuff bitmap-cached to aid this. The background is a short loop, scrolled around as required and flipped to the other side of the loop when needed. There are a few layers of it, but each is just a series of bitmap cached effects. The track itself is created from segments at the start of the game. The track exists as metadata in the code, as a simple array of segment IDs. The IDs are itterated as the track is created at the start, and each segment is instantiated into its own movieclip from an end-marker clip in the previous segment, then bitmap-cached. This allows for much bigger tracks, as it neatly gets round the 2880px bitmap limits by having lots of smaller ones instead. It does take a while to produce the track at the start though. This is what’s happening behind the silver “creating track” screen before the race. Without the bitmap caching, the length of time that screen appears for (several seconds on most machines) would happen to be the in-game framerate too!

Generating the track in segments gives me a nice convenient way to tell how far through the track each car is. They are hit-tested against the segment they are in and the next one too, and their position is updated when they are in the ‘next’ segment. If they are over no piece of track, their position is hit-tested against all segments as they may be about to perform a shortcut jump. Whilst in the air however, they are considered to be on the piece of track they last touched. That’s where they get reset to if they crash, and where they are positioned in terms of the race order.

Lessons:

  • Multiply up the bandwidth for a typical gameplay by a best-case number of plays to see if it’ll work with your hosting provision!
  • Add subtle touches for more depth
  • Processing big strings in Flash is horribly inefficient
  • When used right, bitmap caching saves huge amounts of CPU time

Fred Claus Racing

Wednesday, November 7th, 2007

fred-claus-racingUse the cursor keys to race Santa in this sleigh driving game.  Hit space to use any pickup bonusses you might find, and look out for cheeky shortcuts!

This game makes heavy use of my AS2 physics engine again to simulate the sleigh movements behind the reindeer. You can bash and crash and swing about in quite a fun way!

The tracks left in the snow are worth a mention too. The track is one giant bitmap stored in memory and scrolled around to show the player’s position. The game stores the sleigh’s skids’ start and end points for the current frame and the previous frame, then creates a polygon for each skid around the four stored points. This is then drawn to the main bitmap with blend mode ‘add’. Then it is drawn again, half as bright, with blend mode ‘subtract’ and offset down/right a little. The result is what you see – a permanant skidmark with a bright highlight on the top/left side, and a dark shadow on the bottom/right edge. Because it’s combined into the track as a bitmap effect, it is permanant, and costs nothing in terms of CPU time for a longer skidmark. The only cost is a small amount of work per frame to actually update the bitmap. Because the sleighs slide about in all sorts of directions and rotations, the track width varies and slides about beautifully in response. It’s an effect I haven’t seen done quite as nicely in any other web games.

Rant

Monday, May 14th, 2007

rantCause the biggest pile-up you can in this quick-hit driving game. Use the cursor keys to race up the road and smash into the junction at the end. The more you hit, the better your score!

Postmortem:

Whilst messing about with an idea I had in my spare time, I ended up creating a basic AS2 physics engine for simulating masses and springs. It turned out to be just what was needed for the Rant game. Each car is two round masses joined together by a spring, with a car graphic pasted over the top. The resulting losenge shape isn’t really much like a car I know, but it is perfectly sufficient for the game as it stands.

Initially, I tried making the cars out of a box made from four masses and six springs holding them in position. This ran considerably slower as the collision detection had that much more work to do, and there were that many more springs to simulate. The results weren’t as good either, with boxes occasionally turning inside out and often wobbling like jelly. The two-mass system worked considerably better and was considerably cheaper on the CPU. All round win!

A typical game of Rant only lasts a few seconds. You race up the road, tap a few cars, get a score then it’s all over. It turned out in playtesting that the trick to making this addictive was to make it really easy to play again. So, spacebar to reset at any point (even before the game is over) was critical. Likewise, there’s no lengthy transition effect before you’re back in control. In fact, there’s not even a brief half-second transition – I found that it annoyed people to wait even for that when you can replay so rapidly.

Another way to reduce user friction was to store their high-score in their Flash Shared Object. I found that people got into a routine of restarting rapidly, and sometimes did so when they had a highscore by accident. Rather than lose the chance to submit it, I allow them to submit it at any point in the future after a game too. The highscore table automatically allows just one entry per person, so there’s no chance of one person filling the table when they’ve achieved a top score.

Ultimately, Rant is a game of luck. If you’re lucky, you can hit all three of the randomly placed speed boosts, catch a few cars just right on the junction itself and hit lots of parked cars for that magical score. The game keys into that ‘one more go’ trap that we’re all succeptible to, and a little bit into the semi-gambling gene that makes us play dice games like Yahtzee, even when there’s nothing other than a highscore at stake.

Lessons

  • Very short games can increase replayability and addiction, since people don’t have to invest much time in each go
  • … as long as there’s very little friction before playing again
  • When simulating physical objects, go for the simplest underlying representation that will suffice
  • You don’t always need a lot of gameplay to generate addiction

Travis: Trolley Dash

Friday, March 30th, 2007

travisUse the cursor keys to race your trolley around the supermarket in this Travis oriented racing game.

Postmortem:

This game was written as a development of the Unaccompanied Minors racing game, and used much the same engine underneath. The major change here is that the trolley doesn’t have to behave like a car, and as such needed to be much more slippy-slidey. The simple way to achieve that is with a basic vectored thrust and momentum movement model – something I’ve written many times over for space rocket style games in the past. It’s easy to get it feeling great for rockets (and trolleys), although it really doesn’t feel right for anything but the slipperiest of cars (think ice-racing rally cars, for example).

There are other enhancements over the Unaccompanied Minors game here too. The tracks have a clearly marked out path you can follow, so you needn’t get lost at every corner. Track design in general is much better too: There are shortcuts for the observent to find, pickups to collect for bonus points and the game runs better too due to better prepared graphics (the artist for this one followed my direction perfectly in terms of what would affect performance).

The mood of the game is a little depressing for my taste. The yellow floors and dimly lit store rooms remind me of the bad strip lighting in stores like Lidl and Aldi. That’s on purpose of course – it’s like that to fit in with the Travis song/video, but it still drags the mood down a bit for a racing game.

The biggest mistake in this game however is the collision response. It’ s much improved over Unaccompanied Minors, and you can do a lot more when you have a momentum vector hanging around that you can modify. The edge approximation still sucks however, and it’s not hard to find yourself accidentily rotated into a wall. There are all sorts of horrible special-case hacks in the code for recovering from such incidents, but luckily they don’t have to be used much, unless the player attempts some of the tighter shortcuts where it’s easier to get stuck.

Lessons:

  • Half-decent collision response still isn’t good enough!
  • Decent performance makes everything feel better
  • Everybody likes sliding around

Bareback

Thursday, January 18th, 2007

barebackTranquilise warewolves and bring them back to the safehouse in this moody driving game.

Use cursor keys to drive around and the mouse to aim/shoot. Use the minimap to navigate.

Play Bareback

Postmortem:

This game was written to promote a novel called Bareback, about lunes (warewolves to you and me). It has nothing to do with what you’ll find if you google for ‘bareback’, which I don’t suggest you do if you’re in the office!

The premise is that there are various people out there who turn into wolf-like creatures by night. It’s your job to drive around in a pickup truck tranquilising them and locking them in a safehouse until the morning. It’s got good ingredients: Driving, shooting, dangerous creatures. Unfortunately, the overall effect just doesn’t work in this game, as you’ll see if you play it for a few minutes.

I think the core problem here is that there’s too many concepts mixed together. You have to drive around in the dark, slowly, navigating. Then you have to do shooting and dodging and collection of knocked-out-animals. Then you have to get them back to the safehouse with more dodging/navigating/driving in the dark before one of them wakes up.

Another problem is that none of the tasks ended up much fun! The van is slow so that you can keep it on the road. What’s fun about driving a slow van? Might as well do it for real and earn some dosh for it. Navigating is hard, as the mini-map is small and whilst the zoom works well, a lot of the time your attention is entirely focussed on a tiny part of the screen. The roads are dark and colourless, meaning you’re squinting endlessly to see what’s happening. That’s an eyetest, not a fun pastime. Shooting is difficult and restrictive, so isn’t very rewarding. Then when you do get a vanload of warewolves all sorted, you probably won’t make it back to the safehouse in time before the buggers wake up, undoing all your hard work.

This game went through a lot of itterations before it’s final state. We spent much longer than we normally would on trying to get it right. We knew at each itteration that it didn’t play well, but no matter what we did it just didn’t improve much. 

Lessons:

  • Sometimes, the core concept is just broken. Give up on it already!
  • There’s truth in the saying: Throwing good money after bad
  • Games must be fun. MUST
  • If it feels like work, it probably isn’t fun
  • They can’t all be hits!

Unaccompanied Minors

Friday, November 24th, 2006

unaccompanied-minorsRace against the computer drivers in this all-action speed game! Use the cursor keys to steer your cart around the airport, avoiding crashing into things!

There are three tracks of varying difficulty to race on, and practice/race modes to try out.

Postmortem:

I’ve always loved cars, driving and everything associated, including racing games. I was thrilled to be building a driving game to promote a film, even if the film was one of those Christmas cash-in kids flicks that hardly anyone had heard of (I haven’t even seen it myself, several years later).

Having never built a driving game before, I had a lot of technical issues to solve in a relatively short project build time. Given that the cars in question were airport baggage handlers, I thought it perfectly acceptable to cheat and give them perfectly sticky tyres, which made dealing with things like realistic skids, oversteer, understeer, handbrake turns etc much easier: They simply didn’t exist in this game.

Surprisingly, this technique worked just fine and the game feels perfectly OK. There’s an issue with not being able to see far ahead on the track (partly solved by scrolling the player’s car to the opposite side of the screen to the direction of travel).

To give the illusion of sliding, I added faux skidmarks that fade in whenever the player has been accelerating and turning for more than a set amount of time, and also when they brake. This turns out to be easily sufficient for an arcade racer like this! It’s surprising what shortcuts you can get away with sometimes. Skidmarks are attached permanantly to the track, which is bad for performance but looks great after a few laps.

Graphically, it’s pretty easy to get lost on-track sometimes. You kind of have to learn which way to go on a slow lap, then put your foot down later. I suppose that’s what the practice mode is for, but I can’t help but think it would have put some players off to be constantly crashing into the walls.

On the subject of crashing, the collision detection and response was another technical issue. Car to car collisions were done by detecting when two cars were within a certain distance of each other and tweaking their position apart like billiard balls, then applying a small speed penalty. This works remarkably well, and gentle nudges don’t penalise you much so you can go for those risky overtake opportunities without fear of ending up miles behind. It helps the AI to stay on course too.

Collisions between the cars and the track edges however are not so good. I built several test concepts, none of which really worked before settling on one that was more or less adequate. It still isn’t good though, and really could have done with lots more work if the project were given extra time. The way it works is to test the corners of the player’s kart against a giant hit shape that covers the track. If a corner is in collision, a circle of samples is taken around that point. An approximate line is generated here, and the player’s car is pointed along the reflection vector of this line. The problem however is that the line approximation is a bit flaky, and varies considerably depending on exactly where the samples fall. This means you can be turned unfairly into the wall rather than away from it, or bounced inside the collision shape and all sorts of other horrible artefacts.

One aspect of this game I’m quite proud of is that the AI players are driving cars that are identical to yours. I.e. each AI player has a virtual left, right, up and down control that they can press. The rest of the sim of the car is identical to the human’s car. Except it isn’t collided with the scenery! The AI isn’t smart enough to get out of a bad collision with the edge of the track, and at the time most people’s computers weren’t really fast enough to run the collision detection for all 6 cars together either. The AI follows a virtual track path that differs for their ability. A good AI driver follows a neat track path. A bad AI driver follows a wonky path that misses apexes etc. The path doesn’t define exactly where to drive, but defines a line to be followed if possible. The computer measures its distance from the path and steers towards it appropriately, following an algorithm that real industrial robots use to navigate warehouses. This means it can deal with moderate perturbations from the given path if the player collides with it and pushes it off course.

The game was well received by people who played it, it seems. This may be to do with the fact that most Flash racing games are total junk! In fact, I don’t think I’ve played one yet that I really like a lot, including my own!

Lessons:

  • Racing games are popular!
  • Racing games are tricky to write and balance
  • AI drivers are hard to program!
  • If you spend the time to make a good driving game, spend a bit longer filling it with plenty of tracks too. Three isn’t enough.
  • If you add a bit of code that doesn’t work very well, don’t just accept it! Find a way to make it better or suffer the consequences