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

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!

Deprecations all ya need lalalalalalala

Ok, so you have be over 40 to know what the song is or who this guy is…

But anyway… deprecation gets me down. What is deprecation?

http://en.wikipedia.org/wiki/Deprecation

“In the process of authoring computer software, its standards or documentation, deprecation is a status applied to software features to indicate that they should be avoided, typically because they have been superseded”

Sounds reasonable enough but it’s a real pain. I discover today that directinput is ‘deprecated’. presumably Microsoft declared it thus, whilst also being the people who wrote it, and also writing a ton of other stuff that I’m probably not supposed to use anymore, despite the fact that when they released it, they tell everyone it’s the best thing EVER, and we are all luddites for not switching to it.

I really cannot keep up with what is right, and modern and usable and standards-compliant etc, and what is old, unsupported and unhip.

Is C# still cool? what about GDI+ did that even happen? What about DirectX Graphics? or maybe .NET? do people use Java still? and is it OK to use flash? or is it now HTML 5? and is Ruby On Rails new or old now?

I reckon a game developer needs to write at least three whole games using a technology before they really are on top of it. I’m on top of directx9 now, and feel quite confident about it, but I’m pretty sure some genius at Microsoft reckons I should be shot for not using directx 10, or is it 11 or 12 now? or is directx not even used now? How are programmers supposed to keep up? It’s fine if your job is something cushy like ‘engine architect’ where you just go to Microsoft conferences and read technical papers all day, but for people who have to ‘ship an actual product’, we actually have other stuff to do too.

Is it just me? what technology have you finally sat down to use, or ordered a book for, only to discover that all the cool hip kids (ones who never tend to ship anything) already think it’s out of date? I reckon the lifecycle of programming technology goes like this:

Bah…