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

Handy optimising tip

If you have a profiler like aqtime that can be remotely enabled and disabled try this.

  1. Have a flag that is ‘bprofileframe’ and set it to false by default
  2. Bind a keystroke to a function that toggles the flag on
  3. In your render loop, before rendering, if the flag is true, enable debugging
  4. At the end of the render loop, if the flag is true, set false, and disable debugging.

Voila! you have a keystroke that will capture a single frames profiling data and ONLY that frame, making for really easy profiling on very specific situations. Works a treat. Now I just need to work out how to make it all faster :D

Deferred Rendering / lighting. Balls, maybe not

For a while I’ve been thinking about putting deferred lighting with normal maps into GTB. This was something I talked about briefly during the development of GSB but it never happened. it basically a way to ‘fake’ the 3D lighting effect with a 2D image, *if* you have the original 3D model the  2D image came from, and thus can make a ‘normal map’.

Here is what I mean:

http://experimentalized.blogspot.com/2010/07/2d-deferred-normal-lighting.html

This stuff is definitely not my area of expertise, and to confound the problem, all of the tutorials and explanations of the effect seems to concentrate on XNA or doing it with actual 3D scenes, whereas mine is a 2D engine.

Plus, it seems that it doesn’t do what i wanted it to, which is to take a lightmap full of various light sources (image the whole scene, with just the ‘light’ rendered onto it), and convert that into realistic looking shadows on 2D sprites. it appears to be a single-light source only solution, involving pixel shaders. Bah.

As I type this, I wonder out loud if bump maps are the answer to my problem? It’s not a disaster if there isn’t a solution, as GSB looked fairly pretty, but I’d like to take things up a level with GTB. There is only so far you can go with 2D top-down view rendered stuff, but I’d like to be the prettiest, shiniest 2D game of it’s type, if at all possible. The other effect I tried once but wimped out of was those distortion-map effects where you get a sphere that distorts the pixels accross it, and thus get a ‘shockwave-air-blast’ style effect. I think Call of Duty 4 used it a lot. I ran into ‘tearing’ and other bugs and eventually abandoned it in a strop :D

Anyone got any tips for fairly awesome 2D top-down effects in games?

(The minute I have my logo finished I’ll talk about GTB)

 

Optimising my ‘dumb’ textures

I have this class in my code called ‘smart texture’. I’ve had it for several games now. It basically lets me tell a sprite to use “gun.dds”, and it transparently converts that to the LPDIRECT3DTEXTURE9  and doesn’t mention it. It keeps ‘gun.dds’ in memory, and if I ever lose the screen (alt+tab), and need to rebuild stuff, it will replace the invalid surface pointer the next time it gets drawn with a fresh copy.

MAGIC.

Trouble is, that means keeping a list of every smart texture, so that I don’t miss any when recovering from alt+tab. That’s easy, but I ended up using texturedsprites (with a built-in smart texture) everywhere, and thus the list, for a full battle could be 20,000 textures long.

F**k.

So here I am, effectively keeping a record of me trying to fix this…

It’s 5.35PM Sunday. The wonders of aqtime show me that when I ditch the current level and load in a new one, I am killing off about 8,000 smart textures. Every one is going through it’s destructor and removing itself from the smart textured list. This sucks. I need this to be faster. First instinct is to speed up the destructor, but obviously that’s treating the symptom, not the cause. The real problem is 8,000 smart textures. That isn’t so smart, when 2,000 of them are probably pointing to the exact SAME surface in directx… I need to rethink this system, and NOT break any other code…

I *do* have a system called GUI_TextureCache which does some ‘fixed’ storing of textures I use all the time, like UI stuff, buttons etc. This is obviously a similar task to what I want to do here, in that I need a dynamic dumping ground for commonly used textures pointers. I’m concluding that the cleanest way to handle a fix would be within my SmartTexture itself. it can do some clever caching, and then nobody will ever know any code changed!

Realisation that this means I still keep all these smart textures knocking about, with their ‘gun.dds’ strings. That offends me, as a programmer, but tbh, even ‘longcomplextexturefilename.dds’ is only 30 characters, so with 2,000 units I’m wasting 60k here. Big deal.

Right, so the plan is when I call SmartTexture::SetTexture(“gun.dds”) it may, or may not add itself to a list of textures that would need rebuilding, based on if its already in the list.

Problem: I can’t do that, because it means checking the whole list every time I call SetTexture(). That might even be *slower*. However, my current ‘SetTexture’ goes through a list to grab the pointer, how slow is that? It looks like currently its about half as much time as all those smarttexture destructors, so it might be a win. Plus my SetTexture() stuff uses a MRU caching system which could make ti super fast when loading in 100 identical units…

5.50PM Actually realising I’ll need a totally new class to handle this. it needs to be done a different way, not with existing smart textures. Balls. Surely it can be done? Hold on.. Surely its just a matter of indirection. The purpose of a smart texture is to hold a surface pointer it can rebuild if needed, but it doesn’t have to hold a direct link. It could actually hold an indirect link.  One more piece of pointer indirection is trivial. I just add a new CLoadedTexture class that handles rebuilds, and the smarttextures can point at those, meaning no need to keep a list of them at all, as their pointers never go invalid or need rebuilding.

6.25PM everything coded except the actual rebuild() calls for alt+tab. I’ll comment the errors out for a quick test… GAH, it crashes immediately. fixed easily enoguh, and the code RUNS! hurrah, but it doesn’t seem AMAZINGLY faster,. Quick! to aqtime! what the hell… it’s slower?…

6.35OM. Hah! looking at it backwards, it’s about 75% faster. how much time does that knock off loading in a new level now? 5.28 seconds down to 2.1 seconds. That’s pretty good. I’ll code in the rebuilding stuff and give it a quick test…

6.50PM Alt+tab doesnt work, I get just a black window, but that may be something else. I’ve checked in my current code, and am investigating alt+tab issues now. It looks like the restore code hasn’t worked on this new game at all yet. I consider my (dumb) smart texture code fixed :D

 

AQTime

Yesterady I bought AQTime. It’s $600. That ain’t cheap. It’s profiling software, so basically its something that helps me write faster code. I’ve used it before, and it’s extremely good. I hope I can make my new game faster and smaller-memory-footprint than GSB by using it.

Already I’ve found out that some code that I thought was fast (searchlights) is in fact scarily slow. What’s more, I know the exact lines of code that cause the problem and it’s likely easily fixed. yay!

Plus fog of war code is done and dusted. Double yay.

I hope to have some interesting screenshots to show off in a few weeks. I’ve done the flashy graphics stuff before the gameplay balancing and level design, which means early screenshots of GTB will look nicer than the frankly awful early GSB ones :D

Also… there was a fox in the field opposite the house yesterday. It seemed to be just prowling about, midday, in the sun. Who needs springwatch when you have a fox? :D

Rendering to a texture

My new game does more rendering-to-a-texture stuff than the others have done. I’m very pleased with it so far.

What am I talking about?

Say you have a sprite, and that sprite is a ninja hamster wearing a bullet proof vest and wearing a crash helmet. This is a character in your game, and an icon used in various places. To allow customisation, the player has chosen the helmet and the vest, and maybe tweaked their colors. This gives them a slightly customised hamster.

When you draw this onscreen, you need to draw 3 layers (hamster, vest, helmet). That means drawing 3 sprites on top of each other, and 3 times as many pixels as normal. That can mount up quick, and is called overdraw. It also means changing texture 3 times, and changing textures is sloooowwww.

The solution, before the game starts, is to create a new blank texture in memory, and ‘offscreen’ (while the player isn’t looking) you draw the hamster, with all 3 layers and colors. You then save that texture to disk, with a unique name, Later, in the game, you just blap that single sprite, already composed, in a single draw call. If you are really obsessed, you could, at run-time, stitch together all the units textures into a single sprite-sheet to make it even simpler, and faster.

I have no idea if people tend to do this any more. Most people make 3D games with little or no alpha-blending, where you don’t worry much about texture swaps because you sort by Z and use a Z Buffer. My games can’t be done like that because it’s all soft-edged alpha-blended 2D, so these things start to matter. The code to do all this is a bit fiddly, but I’m already massively glad I’ve got it working. It will let me do all kinds of cool stuff in the next game, and means it will run fast as a race horse wearing rocket-skates.