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

Gratuitous Tank Battles 1.005 released

So I’ve finally released patch 1.005 for Gratuitous Tank Battles, and I’ve been trying to get a patch a week released between beta and eventual final release. This patch might seem to have less stuff than the last, mostly due to one of the items taking a lot of re-working.

Here is a forum thread showing the full changelist:

http://positech.co.uk/forums/phpBB3/viewtopic.php?f=32&t=7210

And here are the highlights:

There is now a direct association between the flames and damage textures on a unit, and it’s current state of health, rather than the semi-random system there seemed to be before! That means that a unit that looks undamaged probably is (although shields and armor may be reduced), and a unit with several plumes of smoke streaming from it is probably in trouble. Of course, for player-units toggling ‘H’ or the health button will let you see the details (or select that unit). This took a lot of fairly tedious re-jigging.

On a similar note, shields now flicker in a strobey-way if they are below 33%. You probably won’t notice on units without big chunky shields, because once down to 33%, they are probably under attack and close to failure, but hopefully this makes things a bit clearer.

There is a gratuitous new visual effect for laser guidance. Previously, those red laser beams were on a lot of units, mostly mechs, semi-randomly. Now, they only appear if that unit is equipped with the top (VI) targeting system. They also swish across and illuminate some smoke, and pulse a bit and generally look pretty cool at night. Expect to see less of them, but for them to look better :D

There is a new campaign map (Tanks for the memories!) added at the end of the campaign. It’s another evening map, this time very trench-heavy, hopefully you will all enjoy it :D

There are some changes and improvements to the explosions, after a LOT of work on the explosion editor. I expect them to be better still in the next patch, now I have seriously tided up my particle & explosion editing code!

Enjoy the new version, and as usual, anyone pre-ordering the game right now gets the very latest version automagically (you won’t need a patch). Don’t forget to tell friends, family members and total strangers if you have played the game and enjoy it, it’s all much appreciated. There is an official patch 1.005 comments thread here:

http://positech.co.uk/forums/phpBB3/viewtopic.php?f=32&t=7225

Explosive fun

There is a todo list for the Gratuitous tank Battles beta, and something not officially on it (because nobody mentioned it) was to make the explosions and flames and so-on look better. People keep telling me they look great, but I want them to look tons better. That means a lot of tweaking, optimising and theorizing.

It’s amazing how many variables you need to get particles looking right, and then how much more code. I have special code for flames, for flamethrowers, for ground bursts, for smoke plumes, for debris, for emitters attached to moving units… and so on. It’s quite a spaghetti mess of complicated and differently designed systems, but it seems to work.

Hopefully by the time the game ships to final release, the effects will look a lot better. It’s one of those things I really enjoy coding (even on Good Friday when i should be eating chocolate!), so I can often justify silly amounts of time on it.

I also have grand plans for target designation laser effects, flickering shields and pulsing damage textures, but not enough hours in the day. How annoying…

First real players, first real bugs

So…. GTB is out there being played by real actual people, rather than just me and my cats, and of course, the first few bug reports come in.

It seems hard for many gamers to believe that developers do their best to reduce bugs, because the minute you play a beta build, you encounter crazy stuff that makes you think “how the HELL did they let this one go?”. I thought I’d give an example of the worst bug found so far, and what caused it, and why I didn’t spot it.

Alt-Tab hangs the game.

On the surface of it, that seems mad, and annoying. Surely cliff tested it? Yes… he did, massively so, and it worked fine. So when I got multiple bug reports, after I KNEW it worked, I did some digging. Did alt-tab work for me? yes. In release build? yes. In release-build run outside Visual Studio? Yes? In different maps? Yes? Nighttime? yes. units selected at point of alt-tab? paused? mid-explosion? shockwave being rendered? nightvision on? paths drawn? yes,yes,yes,yes… after a cold reboot? YES.

Testing all that takes longer than it sounds… So then I do what you *have to do* when you encounter stuff like this. You pretend to be playing innocently, and go through an entire mission, playing and ignoring the potential bug, winning an entire battle. Then you play a second battle, and alt-tab. HANG

Which makes you think that it is something to do with multiple battles. Cue lots of digging through code. Cue turning on the directx debug run-time and maximised error reporting, and running the game in debug. Also cue bouts of near-sobbing when I manage to play 2 battles and it NOT happen… Eventually I manage to reproduce the hang in the debugger. (This is a big win). The you get that infuriating directx error that basically says “Srry, can’t restore DX, you forget to release some directx resource. We know which one, but we are leaving it to you to guess..” or words to that effect.

I bet this guy wrote that one:

Anyway, to cut a loooong (6+ hours) story short, eventually, a whole lot of experimenting shows that the problem occurs only if the post-mortem dialog, or one of it’s many offshoots get launched. This does some multi-threading, which led me up a right blind alley. Anyway… eventually it becomes clear that displaying the unlock-choices dialog causes it…sometimes…

Then a sudden brainwave. The unlock choices *sometimes* gives you a new Hull, and to do that it needs to render that hull. As an optimisation, it doesn’t draw it in layers, it renders out a composite texture (multi-layered) as a sprite, and uses that (it will get re-used later in various dialogs…). That means some render-target code gets triggered. A bit of digging shows that when I create a render target to save out a new composite hull texture, I wasn’t calling Release() on it correctly, in two places. Arrghhh! bug fixed. (AFAIK).

So why didn’t I find it before I shipped? Well basically I implemented the unlock dialog after I’d already tested the hell out of alt-tab. By the time I was close to shipping, and double-checking alt-tab, I either tested it in the first battle (no probs) or I had already unlocked anything and didn’t see that dialog, or I got lucky and the dialog only offered modules or ready-rendered hulls.

But it’s swings and roundabouts. This bug was hell, but pretty much every issues everyone is experiencing on the unit design screen to do with saving and deleting turns out to be a single line where I used = instead of ==.

Don’t you just love C++?

Suprisingly complex health indicators

I’ve never liked health bars in RTS and Tower Defence games. They always seemed annoyingly crude to me, like the designer just thought ‘err…health bars? lets just copy the games from 1980 ok?’. They really break immersion badly for me. Worse still, if you wanted 3 different indicators, for health, armor and shields, you got 3 bars, which was silly.

Gratuitous tank battles solves this with cunning health ‘discs’ only on selected units. The image below shows some infantry with full armor and health, and a damaged turret that has lost some armor. I need to change the code a bit to make the colors relative, rather than always splitting them equally, for situations with high health/low armor etc… anyway…

The problem with this system is that to draw the discs programatically you need a lot of triangles to be smooth. Given GTB supports VERY high zoom in and out, that means either blocky hexagons when zoomed in, or triangle-calculation nightmare framerate if you select 500 guys when zoomed out.

The solution is ‘continuous level of detail’ which 3D engines sometimes do with meshes (not sure how common it is), where you basically add triangles as you zoom in, so you have a constantly varying image complexity. The human eye should never notice. With a simple triangle fan, it’s relatively easy. With a big complex mesh, it’s way harder. I know, I worked on Elixirs ‘infinite polygon engine’.

You might think drawing a few hundred triangles here and there makes no difference to frame rates, but it all adds up. I like to write the fastest code I can. It’s also pretty cool to play about with stuff like this. I can’t actually see it happen, even though I know it is, because I can see it happen in wireframe. Nobody playing the game will ever care, but it does add some polish to the game. it makes my GUI look much smoother than it otherwise could have done, given the framerate I’m expecting.

Glowing damage

On my todo list for ages was fixing damage sprites so they glow in the dark. It always bugged me that my damage sprites were not really good enough, to my mind. We have wood-burning stoves at my house, which I light almost every day right now, and for a lot of the time I worked on GSB I used to sit there staring an a blazing inferno of logs and coal and feel annoyed that the damaged bits of spaceships didn’t look that awesome. I am using a very similar system for GTB, although with less hassle for placing the individual damaged locations, which makes it a bit easier for modders. They still do not pulse and glow the way i want.

One complication though, is I have lighting in GTB (not real 3D lighting, but cunningly faked), which means they needed to glow in the dark like this:

Which they now do, and I’m very happy about it. Unfortunately it took 2 days work, because in investigating it, it turns out I had to totally re-write my lighting system. The game uses multiple render targets for the lighting and composes them right before displaying the end image, which means that anything that actually gives off any light, such as a searchlight, laser beam, particle, or damage sprite, needs to also render to the offscreen lightmap buffer. It also means you have to batch these, and there are all kinds of annoying  unlikely scenarios where it actually breaks down, in some way, although I doubt anyone will ever notice.

At the end of those 2 days, I was very glad I took the effort. Maybe one day I’ll manage to get them pulsing properly, and have particles flitting around ‘inside’ the damaged areas. Maybe!