Archive for the 'Design' Category

iOS Development Optimizations Part 2 – Map Design

Closed

The key to having great content is having great tools.

Well, that, talent, and dedication.

We do have a great map editor that we use for our level design, though. †Not only does a custom-built tool make designing our levels much easier, it allowed me another opportunity to apply some optimizations.

A Scene in our Editor

For Townrs Defender, we developed the designer on the principle of re-use – if we could repeat the same texture multiple times across the map, we’d get a ton of savings in texture memory. †So, the background was composed of tiles that could be laid out like dominos. †Likewise, trees were many many instances of the same few tree sprites.

We had fallen into a trap, a trap everyone falls into at some point: Premature Optimization. †Strictly speaking, I suppose, this wasn’t premature–just mis-targeted. †You see, this time around I took some measurements and tested some theories. †It turned out that the scene overdraw–rendering a tree, then another one in front of it in the same place, for example–was the biggest performance killer for us.

Scene image on left, overdraw visualization on right

Because all of our sprites are alpha-blended, we necessarily have to render them back-to-front in sorted order. †This is a worst case scenario then, because for any sample pixel, we may:

  • Render the background tile (the ground)
  • Render a background widget (a flower, for example)
  • Render a tree
  • Render another tree that is in front of the first
  • Render a character
  • Render any spell effects (flames, arrows, etc)

This was terrible! †We needed to review our thought process.

  • The idea of tileable terrain grew out of our original design for terrain that could go on forever. †You could walk from one map to the next, for example. †That wasn’t even remotely true anymore.
  • Instancing the trees was supposed to save on texture memory. †Well, it did – very minutely. †Using a variety of widgets ate into those savings, and even worse, it cramped our design decisions: using a new widget would eat up valuable texture space, so we’d almost always choose to re-use an already placed widget than use a new one. †This made some of Townrs Defender look repetitive and homogenous.

Knowing now that this often hurt, rather than helped, we looked at it from another perspective. †What if, no matter how many widgets or background tiles we used, the texture space remained constant? †What if we could reduce the overdraw down to four or even three passes? How could we possibly achieve that?

In the end, it was simple. †Each level is rendered out as its own texture. †True, that means each level has its own dedicated texture, but only one is loaded at a time. † Disk space is cheap compared to resident memory. †Now, we couldn’t actually render out everything into one texture–characters have to be able to walk behind trees, after all. †So after saving out the ‘background’ of the map, we now go through and render out horizontal stripes of widgets, and save them one big texture atlas. †There is some fidelity lost here–all widgets act as if they were in the center of the stripe, so some gradations of depth are lost. †But, for the purposes of a small screen on an iPhone, it worked fine.

Background Texture for Level 1

A Foreground Widget Atlas

Our render pass was now more likely:

  • Render the background texture
  • Render the foreground pseudo-widget
  • Render a character

An added benefit was that there were now far far less texture changes, because 90% of our objects on the screen (somewhere in the hundreds) were now 15 objects. †Our frame rate actually more than doubled. †It also helped for memory budgeting–rather than an unknown number of textures, each level had a set cost that we could account for. And, much to the relief of our map designers, they were now free to use as many and as varied widgets in any level as their heart could desire.

And players benefit in-game too: where Townrs Defender could only put 15 enemies on screen at a time, Spires can render closer to 50!

Gauntlet mode pits you against a massive wave of enemies.

Since I originally wrote this article, Spires has actually been published on iTunes – so if you want to check out the engine performance yourself, go pick it up!