Game Design, Programming and running a one-man games business…

Programming AI in a tower defense game

This is not an easy task. It is for most Tower Defense games, because they are simply scripted. The level has a set number of enemies of certain types and times, and they appear as attackers. And of course, most TD games don’t let you play as the attacker, so programming the defense AI is not needed. I need both of these to be non-scripted for Gratuitous Tank Battles.

I need attacking AI that ideally adapts mid battle to your decisions, and this is harder than it sounds. The first approach I took was to have a system with 3 types of placement timing mode (steady placement, or hoard points for a big attack or spam the current unit) and two types of unit selection (random, and select the one that has been most effective so far…with some variation).

The AI would switch randomly between these combinations and it looked pretty convincing. Sudden waves of identical units followed up by who-knows what. The problem was, it obviously did so with little care as to what it was up against.The ‘most effective unit’ code was good, because it meant totally useless designs which charged into a hail of bullets would not see much repeat business, but something major was lacking. That was the anticipating of future events.

If the defender has placed 6 machine-gun turrets (rubbish, but devastating to infantry) you shouldn’t place down infantry, regardless how well they did earlier in the battle. If they have lots of laser turrets, place down shielded units to get past them…etc.

So today, at the end of a long day of video rendering and editing, and tweaking, and bug fixing, I’m starting work on a more generic system for opponent army composition analysis, that can take snapshots of the enemy forces and realise that its 63.2% anti-shield units, and thus we should de-prioritise shielded unit selection etc.

This is annoying, fiddly, long winded code that nobody will ever see, as such, but will make Gratuitous Tank Battles a convincing challenge, which is well worth spending time on.


15 thoughts on Programming AI in a tower defense game

  1. I had considered using a pathing cost system for this type of planning but never got around to actually trying it. If the AI is planning an attack on a specific goal, they can count the “cost” to reach that goal for each unit choice to determine feasibility. The cost can factor in the total threat presented by units and turrets that are within range.

    The major advantage of this over simply counting the opponent’s forces is that you can’t park a pile of machine guns in the middle of nowhere and thereby prevent the AI from using infantry even though the infantry could easily circumvent the machine guns.

    This also means that if you are generally well defended against a particular unit type, but leave a small hole in your defenses, the AI might surprise you with a rush through the gap.

  2. Doesn’t the fact that the “enemy” is smart in a TD game change it quite a lot? For instance, if you put down a load of machine guns so it stops sending infantry, there appears to be no point planning ahead.
    TD games are normally about planning, but what you’re suggesting sounds like it’ll be pretty much reactionary.

  3. True. What I want is not just another tower defense game, but a game with a tower defense mechanic, but feeling like a true RTS when you play it.
    So the paths, and the stationary nature of one side remain, but the gameplay style is different.
    Once I have that, having a scripted mode (as I suspect the online challenge games will be) is entirely trivial next to getting this mode right.

  4. Can these controls be exposed in some manner to allow the user who is uploading his map to have some control over AI preferences?

  5. Whoa there. I don’t think you should have the AI take away infantry from its deploys right away before the player even gets to ENJOY the machine guns scything down infantry. Instead, you should allow the player to enjoy the carnage… once. Then the AI should learn from its mistakes and stop using infantry after that, or send infantry down a different path.

  6. Have no fear, it takes a good while to go from one end of the map to the other, so the units already placed will be colorfully splattered.
    Besides, the attacker AI cannot stop you placing down machineguns after the units are deployed.

  7. Some degree of responsiveness can help the challenge. It’s probably also a good thing if you add some randomness and preferably multiple possible responses to a given concentration of player choices (or other factor) to make it a bit harder to “gap in the wall” the AI; if there’s 3 or 4 gaps that get randomly picked it’s still exploitable but more likely to still be a challenge.

  8. Hey Cliff,

    I am not sure you have heared of influence maps/potential fields. But if you haven’t, there are some good articles on AIGameDev about them (http://aigamedev.com/open/tutorial/influence-map-mechanics/).

    I would store an influence map on your grid, it should be incredibly easy to implement. Then have a couple of bytes reserved to track the mortality rate in a cell for various types of units. If the mortality rate for infantry is high at a certain point, the attacking AI can adjust after a couple of turns and take a different route, or send different units.

    The same goes for the defending AI, the influence map could store how many units pass through a certain position, how many die, etc. The AI can then use this information to place fitting defense on weak routes.

  9. I tried so many methods you would not believe it but eventually I actually ended up just painting them using some terrain images and a clone brush, and flattening out the areas for the paths by blending a blurred images where I’d painted the paths in white.
    I tried 3d modelling and rendering etc but it actually didn’t look as good for some reason.

Comments are currently closed.