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

Optimising day

I’m taking an afternoon to optimise all the code that I added recently. A lot of stuff that makes the game looks cool was being done in a really inefficient way. In some cases, it was a matter of remembering to check somethings onscreen before going to any effort to draw it. In other cases, it’s a matter of caching data.

Caching means ‘keeping a copy of’ effectively. If I ask you the date, and you tell me, I could then ask you the date in 5 minutes time, or I could make a note of the information you gave me earlier, and not bother you. A lot of optimising comes down to caching data. In this case, I was calling the cos() (cosine) function several times in short succession, and getting the same answer. sin() and cos() are pretty slow, if you call them several thousand times a frame, so it really makes sense to cache them.

Things seem much faster now, even with tons going on :D

A day optimising the debris

I love the debris effects when ships get hit or explode, but they are expensive because it creates so many objects, so today I’ll be optimising so I can expand the extent of them. Some of the debris is transitory (fades out) and roughly 1/4 of it stays on-screen all the time. It all spins, but it stops moving over time.

Currently the call to draw the debris makes up 3.49% of the time spent drawing the battle screen. That might not seem like a lot, but if I want to triple the amount I can draw, and support bigger maps, it could get out of control.

It’s 9.15Am and I’m starting to code a faster system. Currently, every single speck of debris is stuck in a big global list and I go through and draw each one, although I reject them very fast if they are offscreen. This is very slow though. At least 20% of the draw time is spent just iterating through the list. My proposed solution is to stick each cloud of debris into groups, and do the iteration of groups (rejecting obviously offscreen groups) and only go through individual specks if the group is visible. I think that should speed stuff up a lot.

9.30 Am. First test shows it’s dropped to 3.74%. Hardly a mind blowing improvement.

9.33 Am: Ooops, that’s the wrong exe being profiled. I need to set up a new project configuration (release symbol). Damn. That means total rebuild. Time for tea.

9.55 Am Somehow I can’t get this poxy release build + debug symbol build to run. grrrr.

11.00 Am Still getting my builds fixed. I have a debug build which runs with optimisations on, and that seems to at least work. Also I now cache the debris texture pointer so I’m not doing a string search every frame to find it.

11.30 Am. New system seems tons SLOWER. I need to flip back and forth so I can verify this is really true. It seems to be because of my use of STL lists, when each cloud of debris has very few members. I need to ensure my code isn’t using debug STL before going any further. It’s the same even with release, so I’m ditching the new system and will optimise the old one.

11.45 Am Creating and destroying debris objects is very slow. I’m going to have a fixed array rather than a global list, and use a series of flags instead. This does seem to be a bit faster, and makes much simpler code. However, the fixed array size and the method for finding an inactive debris item is inefficient and doesn’t scale at all.

12.15 PM Simple but major speedup. I was always searching the whole array, whereas clearly the solution si to always start the array search from the item one above the last one which was available, and wrap around. That sped up debris initialising by a factor of five. Time for Lunch!

1.30 PM I’m now precalculating some of the data thats used identically by each bit of debris and passing it to the update function. It’s maybe 20% faster. I just spotted I’m checking for alpha < 0 even for debris whose alpha does not fade. Fixed!. Ideally I need to update almost nothing for debris that’s offscreen, and yet have it still behave sensibly when it then appears onscreen later.

1.51 PM New system where I mark out debris that has practically stopped moving, and omit any further position updates for them has reduced the update time by another 20%

3.10 PM New graphical debug display shows me which debris array entries are persistent, in use and unused. Took 2 minutes, but its very helpful. May attempt a system to ‘defrag’ the array now.

4.10 PM Defragging system works great. Time to double the amount of debris everywhere and see how it all holds up.

5.45 PM Everything looking ok. Probably need to add some nice smoke effects at some stage. Time to work on gameplay code.

Gratuitous Debris

I got the wobbly cloak + damage textures stuff working in the end. I used a separate render target. Basically whenever a ship is cloaking it uses a separate texture to composite its damage and hull together, then renders from that. I’m not sure how slow SetRenderTarget() is, so I’m avoiding using it all the time.
Today I redid all the damage textures. I used a picture of an oil refinery at night, color-adjusted and light intensified, and use that to ‘paint’ sparks in gaps in the damaged ships hulls.
I also added debris. I cut out some parts of the ship, and scattered some of the damage texture magic on them:

I then emit some spinning bits of debris when a ship is hit or destroyed. The debris is all one texture and drawn collectively (on top of all the ships) so it’s a single vertex-buffered draw call and shouldn’t be too slow. I’m certainly getting awesome frame rates, even with tons of smoke trails, explosions, spaceships, debris and laser effects:

Tomorrow I’ll be doing some more of the AI behaviours for the ships.

Graphics problem

I’ve just encountered a bit of a dilemma.

I have this wibbly wobbly ‘not a cloaking device’ effect on the ships in GSB. The thing is, it wobbles the original ship sprite, and when I’m drawing ships, I’m also attaching some extra sprites for stuff like damage textures etc. Not to mention flashing lights etc.

When the ship cloaks, this means all those extra sprites effectively disappear, which is very jarring, and breaks the sense of ‘realism’ of it all. I’m not sure yet how to handle it. One idea would be to fade out all of those sprites over the few frames before the ship starts to wobble, so it’s less sudden, but that still makes no sense. Ideally, I would apply the exact same distortion to each sprite as I amd doing to the ship sprite, but that is problematic and complex (to put it mildly).

I could just wobble them ‘out of synch’ with the underlying sprite, but that would lead to some artifacts which would look crap. There is a video which i think shows it a bit below.

The way I wobble the ship is to basically split it into a grid and then wobble each point on the grid out of synch, the sprite is then drawn like a flat mesh grid, with bits of it stretched all over the place. If the damage sprites sat at exact grid intervals, this would be easy, but they do not.

It might make sense to actually burn the damage texture onto the ship texture. This would make things very easy, but suddenly if I have 10 frigates on screen, I have 10 times the texture memory (worst case).

Even as i type this, I realise the answer is likely to always align the damage textures themselves at grid wobble boundaries, and then to wobble them in synch. That doesn’t solve the issue of flashing lights though.

What A nightmare. i hope people use the wibbly wobbly effect a LOT.

Bigger Battles. Working on various bits…

I’ve been improving the explosion effects today (not shown below) and also adding a glow effect when armour takes a hit (not shown) and adding a few more spaceship graphics to the game. There is such a lot to do, but I’m already having great fun watching the fleets fight. I also tweaked some of the visual effects for a few weapons. I need much better beam laser effects now that you can zoom in and they are so big. They just blurp out of nowhere and look shit :D