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

Minimizing Texture Swaps

Heres the other ‘big thing’ that sometimes causes 2D games like mine to slow down. Not drawing too many pixels, but changing what image is being drawn from too often. Video cards are great at drawing tons and tons of triangles using the same image to copy the pixels from. changing which image is ‘active’ will cause a major stall in the video cards rendering operation and waste time. Bizzarely, AFAIK you can only have ONE texture as the active texture for any specific moment (without doing multiple textures in different ‘stages’). So regardless how many pipelines your card has, you can’t be drawing from two different textures to two different polys at once. (is that right?)

Worst case scenario:
You render 200 sprites on screen. half have texture “ogre.bmp” half have “elf.bmp”. They have to be drawn from back to front, so that nearer ones obscure further ones. They are positioned (in distance from you)

Elf / Ogre / Elf / Ogre / Elf….

Etc. This is hell. because it means changing the texture 100 times. Ideally what you would do is get the video card to sort this stuff out. You would use Z values (distance from the viewer), and send all your sprites to the card with the right Z values and let the card sort it out.

Thats easy if you have a nice modular engine where every single rendering call goes through some nice sorted system where everything drawn on the screen is esentially some offshoot of the same base object. if you only ever draw sprites, then just send a huge bunch of Z-positioned sprites to the card and click go.

Unfortunately few engines work that simply, because there is no ‘one size fits all’ drawing object. Text is often composed of thousands of 2-poly characters, best sent as a vertex buffer. Some lines and primitives are drawn using direct 3dDevice rendering calls. And some are sprites with different render states. This is where it gets horribly messy. I’m slowly, with each game getting closer to a system where I am not blindly just rendering over the top of myself and hoping for the best. I can at least now bunch up a load of sprites called from different places, and have them drawn with a single call. What I don’t have is a perfect system that auto Z-sorts my sprites by position and texture, and makes the most efficient calls. maybe some 2D games have such a system, but I’m assuming most of them just don’t do enough fancy drawing for it to be an issue (or they ignore backwards compatibility with slower cards).

If I was a bigger company with a dedicated graphics programmer who just worked on the engine, I’d have a better system, but I’m still a one-man show doing everything, and there just isn’t time :(

Why use Directx7 (and dead links)

My games use directx 7. Not 8, 9 or 10. SEVEN. That is OLD. If you have windows XP and never installed anything, you already have Directx7 (or later, which is fine).

Why do I do this?

Several reasons. Firstly, DX7 is the version I learned when I first wrote a reusable graphics engine for use in multiple games. Re-writing an entire engine can be a slow process. Don’t get me wrong, getting it to WORK, is not a big deal, but getting it stable, bug free and (essential for an engine) FAST is very slow work. I know DX7 very well, I have optimized it to death, and know my way around the API really well.

Secondly, DX7 is all I need. I don’t even do 3D games, let alone ones using bump mapping and pixel and vertex shaders. I don’t stream geometry or use mip maps, or do multithreaded vertex processing or anything clever like that. DX8 and 9 *do* achieve some simplification of code, but don’t add anything I need.

Thirdly, DX7 means everyone who buys the game will have drivers that support the game. I don’t need to package the game with the directx installer or worry about such things. Some people playing indie games on laptops have very low spec cards, and you are best off sticking with DX7 if you can. A LOT of casual games use DX7.

The thing is, Microsoft REALLY don’t like this. Obviously they try and push you to use the newer versions, that’s natural, but it’s almost like they are insulted and annoyed if you want to stick with DX7. It is *impossible* to find a download of the directx7 SDK. Microsoft removed it from their website, including all earlier versions. They want to FORCE you to use the new stuff, even if its just pure hassle with no gain. After all, why would anyone make a game without bump mapping right?  I am rewriting part of my engine in an attempt to speed it up yet again, and I was forced to dig out the CD that came with an old book to find some source code, written by Microsoft that they refuse to let you have any more. It’s mad. I have released a lot better games that ‘Asteroid Miner’, but if you follow a link from a website not updated since 1997 to my homepage (which has moved servers 4 times since then), to an outdated zip file containing the game in the root of my site (before I knew not to do this) that zip file is STILL there. I just think it’s rude to move files people have linked to, for no good reason. Every time I follow a link to a companies website that’s dead, I just think they are LAZY. Web links last a very long time, why encourage inward pointing links to die?

Reducing OverDraw

When you make 2D, rather than 3D games, the two things that can slow your game down on older video cards (forgetting CPU limitations for now) are State Changes and Overdraw. State Changes are basically texture changes (drawing a different image). Doing this too often can really slow down older cards. Overdraw is the problem I was looking at yesterday on Kudos 2.

Kudos 2 is fixed at 1024 by 768 res. thats roughly 768,000 pixels, in 32 bit color, or just over 3MB to draw the whole screen. Because of the way video cards work, you have a front buffer, a backbuffer and the source art itself, so this equates to around 9MB in practice. Given that even the most wonky video cards have 32MB of RAM, this is no big deal, but this is assuming you just load up a 1024 x 768 texture and copy it to the screen.

The first problem is you can’t have a 1024 by 768 texture. DirectX prefers things to be ‘power of 2’ in each dimension, so you have to have 1024 by 1024, and as a worst case, waste a lot of space anyway. That’s only a minor problem though. The real problem is what happens if we end up drawing the same pixel too many times a frame. This is called overdraw, and its quite easy to let it slow down your game.

The best way to see how bad overdraw can be is to code a version of the game that draws every image as a fairly transparent white box. See below:

That’s kudos 2, AFTER I optimised some of it. The lighter the colour, the more times that same pixel is being redrawn. Sometimes, this is legit, because I am blending two images together, so you can’t just draw the top pixel, but in the majority of cases, it’s just inefficient. You can tell that one of the worst areas of overdraw (apart from the avatar, which is pretty inevitable) is the dialog boxes. These are a pain.

My dialog boxes are drawn on top of an existing background, theoretically giving me the opportunity to ‘punch a hole’ in the background and save some rendering. The dialog itself then has a ‘client area’ drawn using an additional image, which wastes space behind it. Any buttons on the dialog then add a third level of overdraw, and of course the text, or button icons are a fourth layer on top of that. If a tooltip pops up, we are at level five, and six for the tooltip text, seven if the cursor is above that! :D.

For video cards like mine, with an insane ‘fill-rate‘, it’s pretty irrelevant (The game runs at around 200 FPS right now), but I’m determined to make Kudos 2 easily usable on a low spec laptop with an Intel video card. I don’t lose *that* many sales due to poor performance with my existing games, but I’ve never made a game that looks casual enough for many owners of low spec PC’s to play before.