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.

Working on tweaking the mechanics

It’s easy to get caught up with features, graphics, optimising and going through a checklist of items to do when you work on a game, and not set aside time to keep fiddling with the mechanics. There are an absolute ton of variations to the mechanics of any game. The only real way you know if the mechanics are right, is by trial and error.

If you wonder what the hell I’m on about with ‘game mechanics’, it’s basically the rules and systems by which the game is played. For example, in chess, the pieces all move in different ways. Some can only move forwards, some can only move 1 square at a time… None of the chess mechanics are obvious. Imagine designing it from scratch. We take for granted the idea of a knight moving over other units, or castleing, or units like bishops having infinite ‘range’, but none of them is ‘obvious’.

Right now, my bugbear is support units. GTB has repair trucks and ambulances for attackers, hospitals and repair yards for defenders. My current mechanic is this:

The support units pulse out ‘waves’ of effect at a certain interval and radius. Any damaged vehicle (repair) or soldier (hospital) within that radius at the time gets X of their health replaced.


Look! Neither side is bothering with hospitals or repair units…

This seems ineffective, and there is little real incentive to use these units. I might have just set the costs for them too high or the effect too small, but in fact i think it’s more fundamental. By the time people are losing health, they are a lost cause, and the interval between lost health and death is too slow to enable a health pulse to really do much good.

Possible solutions:

  • Ultra-rapid health pulses to ensure timing not an issue,
  • Reduce armor and shields and increase health of all units
  • Make support units dirt cheap so they are worth it anyway
  • Allow recently destroyed / killed units to be revived by the pulses.
  • Change the mechanic entirely so that the units don’t use pulses, but act as damage modifiers to protect everyone within their radius, effectively making them mobile buffs.

I’m planning on trying out the last option. It involves a lot of fiddly code, but what doesn’t eh?

BTW, stuff like this takes AGES, and it’s why I REALLY hate clones of games, where some talentless drone comes along and just copies an existing game design but slaps on some new textures. Yes, it really is easy to copy the mechanics of a popcap game, but coming up with those mechanics took a ton of work. This stuff is never obvious, and I personally don’t think it can be reliably learned from books. I think you have to just keep trying stuff.

Debug Tools and defensive AI.

Life is so much simpler when you bunch up all your hotkeys and toggles for debugging the game into a single menu. I feel like I have a rough idea what’s going on now. I also feel more confident about coding decent defensive AI when you play as the attacker:

The code for defending basically needs to manage three things. The play style (Is it spamming units, hoarding points, or steadily placing), The choice of units (Does the enemy have units weak Vs lasers? Are there lots of infantry needing flamethrowerising?) And the choice of unit placement. I’ve been concentrating on the unit placement debug UI today, so I can see what the AI is thinking when it chooses to place a turret at X rather than Y. More work to do, but currently it evaluates proximity to enemies, their size, victory-point value, closeness to the exit and proximity to the placement, plus it also has bonuses for being able to cover multiple paths from a single location.

It all needs lots of tweaking and balancing obviously, but it’s getting there. Attacking AI is much simpler.

After getting this stuff done, I’m thinking of experimenting with a unit ‘cooldown timer’ beyond a certain level to prevent spamming the same unit everywhere. Essentially there are supply delays if you plonk down 4 heavy tanks all very quickly, as new ones need to be dispatched from your offscreen HQ. I think it might be a good mechanic that encourages variety.

Shadow maps make me happy

I’ve been watching some WW2 footage, some war movies, some video game footage, etc, in a bid to up the visuals in GTB. A lot of it can’t be seen in a screenshot, it’s moving-picture stuff really. UI’ve also been re-visiting how I make the shadow maps, and massively boosting their resolution. What PC’s can’t handle a 2048 square texture these days? None, I suspect.

Anyway here is a very sparse GTB screenshot:

And here is the same frame, but without the shadowmap.

I think the shadowmap wins by a huge margin. (It’s more apparent full screen, when moving and zooming etc. Combining a grayscale shadowmap with tileable textures not only makes it look less 2D, but it also means you can detect the repeating tile patterns a lot less. I am using a tile-based system to afford easy level design for players. I’m also toying with the idea of automatically generating the shadow maps from the player-designed paths. I think it’s quite doable, although non trivial, and better than expecting players to use photoshop etc.

Comments?

Running to keep up

About 8 years ago I was chatting to the receptionist at a games company I worked for, and she was telling me about a conversation she had recently with the lead coder (and general all round engine god) of the company. He had been working late (as usual) and looked up at her, a bit vacant and said “I can’t handle this any more”. By which he meant the long long hours of coding, coding, staring at a screen (he had 3) and pouring over complex algorithms to get the code to be faster, faster… He wasn’t an 18 year old student any more, and it hit him really suddenly.

That’s kind of the whole lifestyle trying to keep up in the world of game production.

It’s not just games. I remember a quote by Glenn Tipton, guitarist for Judas Priest, where he said he loved the new wave of neo-classical heavy metal guitarists, because even in his forties, it meant he couldn’t put his feet up and know he was good. They were always pushing him every year to be faster, flashier, better.

There's always someone who can play faster than you...

I’m sure it’s true in every field, weight lifting, (any kind of sport really), comedy, writing… the pressure goes up and up each year. In order to suceed, you need to be better than the people who came before, and every year, the cumulative pile of stuff that came before gets bigger and better.

I am VERY aware of the fact that you can go to steam right now and buy a lot of once-big-budget games for the same price as buying one of mine. I’m not trying to play AAA games at their own game, but I’m trying to keep my games as fresh and modern and polished as I can. The harsh fact is, I can’t expect to make a game that’s just *as good* as Gratuitous Space Battles, and expect it to sell as well, three years later. That’s planning to fail. I need to address every single thing I know was wrong with GSB, and if I achieve that, I expect to maybe match that games sales, nothing more.

So in comes better online integration, achievements, better unlocks, hopefully better user customisation. Better artwork, better all-over-polish, better play testing and bug testing. And that means hiring more artists,  spending more time, being more obsessive with detail. This is not an easy gig. This is anything but an easy gig. And yet I love it. When I tried the battlefield 3 beta, I was noting everything that impressed me about it, knowing I need to get that sort of detail into GTB. When GTB comes out, BF3 will be old news. It will be yet another rung on the ladder of what gamers expect.

Note: I’m not just talking about graphics. I couldn’t begin to compete with the shaders and the pixel-pushing power of the frostbite engine. I’m talking about polish, all those little things that make games more playable, approachable, long-lasting and easy to use. Stuff like animated menus, text that nicely fades in and out, and is pin-sharp. intuitive GUI’s that are in just the right place, taking up just the right amount of space. Really well thought-out color palettes, sounds that all seem to fit together, flawless execution of UI stuff, great tutorials etc.

Back to work…