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

Shaders, and then on to game data and weapons

I spent the weekend mucking around with pixel shaders. I’ve not used shaders before, and tbh, the documentation for such things assume you already know how they work, which is insane. I was originally hoping to get some shockwave distortion effects in for ship explosions, and although I got it working, there are some artefacts I’m not happy with. I might still use shaders to do some simple stuff like tinting the whole screen certain colours in some of the nebulas (I think it looks kinda eerie). Of course, thsi kinda stuff will be optional for anyone with older cards.

So this coming week I’ll be turning my attention to game play balance issues and getting some proper data in there. I need to knock up a few decent, balanced enemy fleets to fight against and check the game mechanics as they are. My concern right now is that putting a ton of effort into shields and armour may ‘trump’ everything else. A small proportion of shots always penetrate each (lucky shoT!), so they are not absolutes, but still they are probably too beneficial.

One idea I had was for shields to operate only under certain ‘loads’. So say we have a shield with a strength of 20, and its hit by a laser beam with penetration of 11. That beam won’t make it through, which is fine, but I was considering allowing multiple beams at the same time to ‘overload’ shields.
So if you had simultaneous beams of a strength of say 40, all hitting a shield at once (or over some short period) they would knock the shield out entirely for a second or two. That would mean that large groups of frigates with relatively low power lasers could still take down a cruiser, despite its shields if they concentrate their fire.

Right now you have a damage and a penetration value for each weapon, so you might have a weapon with massive shield penetration but tiny damage, which always damages the shield strength a bit, or a weapon with tiny penetration and massive damage, which is easily deflected by a shield, but if it isn’t deflected, does major damage.
Hopefully a wide range of options on equipment like this will lead to the emergence of a ton of interesting ship designs. Maybe :D

Today’s worklog

8.00AM: Clement Freud has died. He gave me an award at my secondary school many years ago. He was very short. Also he was very funny

9.10AM: All the business email stuff is dealt with, time to start work on putting one of the new ships into the game, one I have declared to be the ‘Imperial Centurion Cruiser’. It looks badass

9.50AM: Most of the graphical stuff is done and dusted. Now I just need to add in the data defining this ships damage textures and module slots, and get it tested and in game

10.30AM: The Centurion cruiser is done and looks great in game. Took a screenshot to give feedback to the artist. Everything seems to look ok, so I don’t need to go back over any artwork. Plus the multiple beam lasers look fantastic. I’m pleased

11.10AM: There is definitely a shutdown problem with the game. Dev Studio churns for ages. Must be a huge and new memory leak somewhere. Damn.

11.50AM: It’s definitely a bug with the main battle screen. But where? The sound? graphics? AI?

12.00AM: Interrupted by door to door salesman, thus killing my efficiency. Time to release the hounds.

12.20PM: I suspect this isn’t a memory leak, but just my debug output backing up bigtime because every time I create a blast glare effect (also used for non-penetrating shield impacts), I tell the debugger about the texture I used. Clearly this code is inefficient anyway, because with dozens of the smaller glares I need to have that texture cached, not be looked up so often. The game now shuts down fine in debug, but I need to fix the underlying inefficiency. In fact, it’s worse than I thought. I need a newer, efficient system for shield impacts

12.35PM: Works fine but forgot the original texture was a quadrant and this one needs not to be. redoing it… Also just spotted a graphics glitch with the conĀ  trails pulsing on and off.

12.45PM: Having crash issues when trying to do some profiling, Grrrr. I will mull it over some wii-jogging and a cup of tea.

1.30PM: Still can’t get profiler to not crash. Time for tea.

2.20PM: it now crashes somewhere else. progress?

2.50PM: Sod it, I have a workaround, and bugs to fix. some lights in the wrong places, and an idea on how to make drawing running lights faster if they are zoomed out. (check rendered size > 1 pixel BEFORE checking if onscreen, which takes longer).

3.30PM: The debug copy no longer links. some obscure ANNOYING linker error to do with debug and not debug Microsoft crap. Very tedious and I’m not getting actual game stuff done :(

4.14PM: Think it’s fixed, plus I tracked down the flashing con trials bug. It was me not setting the render mode correctly before I drew them, and them getting drawn early if they filled up a vertex buffer before I was ready to render them all. Good old Nvdia perfHUD was my saviour. Now back to coding fun stuff.

6.25PM: Finally got the linking stuff fixed by a total wipe and rebuild. Grrrr. Next on the agenda is adding some better parallax effects, which are a nightmare with 2D + zoom + variable screen res and scrolling.

Changing some shield stuff

I did a fair bit of speedup code today, added a new ship, then put some effort into the shield effects. The old graphcis were 512px square, which is pretty big with mipmaps. A basic test showed 1024 px images looked noticeably better, but they get pretty big filesize wise.

So I did what lots of games did, and cut the images down to quarters, and in code I mirror/flip them to draw all four quarters of them. It’s an old trick to save filesize. There’s an image below showing it in game, and file itself.

I also added support for different shield graphics for different races, so you have aliens with their funny foreign-colored shields :D


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.