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

What would Jack Thompson think?

When I create particle emitters they normally have a parent object, but some, such as missiles being shot down and exploding, do not and are ‘orphaned emitters’.

These die out, but if you quit mid battle, some orphans are left. If you then start a new battle, you see the smoke clouds from the previous one for a few seconds.

So I need to clear them and fix that. So I am writing a new function called

KillAllOrphans()

What would Jack Thompson or the tabloid press think?

Even Bigger, Better Explosions

It’s no good doing a game called gratuitous space battles without serious ship explosions. My current benchmark explosion is this one from revenge of the sith:

I’ve watched it hundreds of times, and taken about 30 still frame captures from the DVD to use as reference. I have quite a complex particle and effects system for GSB, and it’s coming along nicely. Currently, the average cruiser will have 17 distinct events as it explodes, not counting the release of escape pods

Those 17 events are scripted like this:

[explosions]
1 = 0,128,80,EXP_FRIGATE
2 = 11,97,149,EXP_DESTRUCTION_PLACED
3 = 20,199,205,EXP_DESTRUCTION_PLACED
4 = 20,196,238,EXP_DESTRUCTION_PLACED
5 = 101,108,41,EXP_DESTRUCTION_PLACED
6 = 120,143,163,EXP_DESTRUCTION_PLACED
7 = 200,47,189,EXP_FRIGATEBREAKUP
8 = 210,0,0,EXP_STARTBREAKUP
9 = 270,128,128,EXP_CRUISERDEBRIS
10 = 274,53,226,EXP_DESTRUCTION_PLACED
11 = 290,59,229,EXP_DESTRUCTION_PLACED
12 = 310,171,209,EXP_DESTRUCTION_PLACED
13 = 388,61,204,EXP_DESTRUCTION_PLACED
14 = 400,128,175,EXP_FRIGATEBREAKUP
15 = 400,128,175,EXP_PLUMES
16 = 400,128,128,EXP_BLASTGLARE
17 = 900,128,128,EXP_ANGLED_DEBRIS

They relate to particle effects and other graphics. So there are a number of different particle emitters called from different points on the hull, then at 210 milliseconds after detonation the sprite starts to tessellate into pieces. At the same point, the damaged hulk texture starts to cross fade into existence behind it, and the hulk components start to drift.  At 270 milliseconds a shower of permanent debris is spawned. At 400 milliseconds, plumes of wandering particles appear, accompanied by a bright flickering white glare which also generates a shockwave blasting existing debris out of the way. A final shower of temporary particle system debris is triggered right at the end.

This is all configured per-ship-hull, so different ships can detonate in different patterns and styles.

It looks cool :D

Faster Debris management. (coding stuff)

Today I did some tests on GSB as I expect it to be played eventually by hardcore gamers. That means the biggest mission in the game, hundreds of fighters on each side, huge fleet, huge map, with all graphical options turned on and fullscreen in 1920×1200 (highest res on my monitor). To my delight, it handles it pretty well, dipping below 60FPS only a few times when viewing complete mayhem. (Geforce 8800 GTS on vista, Core 2 Duo)

That’s a release build, but with debug symbols in it, so it might get a tad faster.

In this build, under those circumstances, one of the slowdowns is the debris. Not the rendering of it, but the creation of it. I cap the debris at 4,000 items. 2,000 in each of two ‘pools’. The slowdown was some code that basically did this:

for(each debris item)
{
if(isfree)
{
return debris item
}
}

(It was cleverer than that, in that it only started its search from where it left off last time, to minimize wasted checks, but you get the idea.).

The slowdown was literally the loop hassle of going through maybe 2,000 checks of the ‘free’ flag, with theoretically it being the case that only number 1,999 is free for re-use (or none of them).  Readers with long memories may recall I had implemented a periodic debris-defragger, which makes this stuff easier. However, I can’t be doing that every frame, so I tried out a new system today. (after a few false starts). The new system is fiendishly more complex and works like this:

There are 10 debris ‘free registers’ which are basically indexes into the array of debris. These registers identify debris items that are currently free by their index. Whenever I’m processing some debris, if it becomes free (fades out size or alpha-wise) I notify the pool to stick its index in any empty ‘free register’ that it has. This means finding an empty free register, but there are only 10, so it’s super quick.

Then the new piece of code to get some free debris does this:

for (each free register)
{
    if(register is valid)
    {
        return register[x]
    }
}
for(each debris item)
{
    if(isfree)
    {
        return debris item

}
}

This checks if any of the registers have any free pieces of debris, and if they are free, I re-use them (and note that the register is now blank). If all the registers are blank, I must have allocated more than 10 debris since I last let any fade out, so I need to go through the whole list as usual to try and find some free ones. If that fails, I check for some that are offscreen (I maintain a separate register of those), and if even that fails (we have 2,000 live debris onscreen!), I just randomly kill one and use that.

This chunk of code takes half the time the old one did, despite having more code in general. Does that mean its 50% faster? or 100% faster. I can’t get my head around that. If anyone can spot anything I’m doing thats stupid, I’m not above being humiliated in the comments with a smarter algorithm :D. I picked 10 as my number of registers in an arbitrary fashion. I should fine tune it really.

Formatting code in wordpress is a nightmare. BTW, this isn’t C++, this is simplistic pseudocode with about a quarter of the detail :D

Level-of-detail in particles and debris

It took me a while to get support for this in. I still need some decent tools to get my particle effects placement faster and easier.

Anyway…. there is now some basic LOD support for particle emitters and the debris particles. That means I can have buckets of both and only render what I need (although tragically you still need to update a lot of it for consistency sake). here’s a screenshot showing debris increasing as you zoom in. It doesn’t look like I’m zooming in the way I cropped the screens, but I am :D

It’s faked a bit with a sudden detonation, so the screen looks a bit sparse, but it looks very cool in the game :D. It’s nice that it fades into view rather than having any popup.

I’ve been adding in hulk textures for all the frigates today, doing texture-atlases for the fighter hulks, and re-rendering some of them to prevent black jaggies around them at low zoom, designing some more AI fleets and generally fixing and tweaking.

Fighter Hulks and some aborted stuff

I spent most of Saturday wasting my time on code that I reverted. Long long hours were spent working on bloom effects and shadows for ships passing over each other.  Eventually both were rejected. The bloom code simply didn’t look that good, and the shadow stuff proved to be hideously involved and likely very slow. I know people might assume you can do it simply by just rendering the ships to a separate render target complete with shadows, then slotting in the background later, but you can’t, due to laser and particle effects lying ‘between’ ships and also needing to be blended with the map background at render time.

Anyway… who cares :D

What I *have* got working is hulks for fighters. Previously a destroyed fighter was just obliterated by a fairly low res particle effect. The effect still needs improving, but now destroyed fighters linger as debris. Crucially, the fighter hulk maintains its momentum for a while, so they look like their engines just got shot out, and they also drift faster than the big lumbering cruiser hulks. This all looks a bit nicer than before where they just vanished. I also went through and got 4 variants of hulk done for each fighter.

Now I’m rendering out a few more loading screens, and later I’ll work on some improvements to particle stuff. Monday onwards will be ai-fleet design and general game balancing.