Scirra cog

About Us

We're a London based startup that develops Construct 2, software that lets you make your own computer games!

Archives

Browse all our blog posts

Latest Blog Entries

We love brains!

Join us! Joiiinnn ussss! Mooooree brains!

Under the hood: Spritesheets in Construct 2

by Ashley | 29th, May 2012

Construct 2 has typically exported object's animation frames as separate PNG files. Spritesheets - a new feature in the latest beta r92 - means Construct 2 now exports bigger images with several animation frames arranged on each. For example, here's a single big PNG file with some animation frames from Space Blaster arranged on it:

A sprite sheet from Space Blaster

Spritesheeting can help speed up the game loading time. However, in development a number of interesting issues came up. This resulted in us taking a slightly different direction to other tools which also implement spritesheeting. For example, rather than use one giant image with absolutely everything on it, Construct 2 instead exports a series of smaller tiles with parts of different object's animations. This blog post explains why it's done this way, and what we had to take in to consideration.

Technical limitations

Due to the way graphics processors work, images are usually actually held in memory in a power-of-two size (e.g. 128x128, 256x256, 512x512, etc). For example a 150x150 image will have to be placed on a 256x256 surface, with the rest of the pixels transparent. Notice that means it uses a lot more memory: out of the whole 256x256 area, only about a third of the pixels are actually used for the image. The other two-thirds is simply wasted, but still sit there taking up memory! If you have a long animation with 150x150 frames, it can end up wasting several megabytes of memory - and just for one animation.

As a result sprite sheets have to be a power-of-two size, otherwise it will be wasting space that could have been used. A nice additional benefit is it's possible to reduce wasted memory - those 150x150 frames can now sit side-by-side on a single power-of-two texture. Many modern desktop systems can actually deal with non-power-of-two size images, but they might still use power-of-two images behind the scenes, and mobile devices generally still must use power-of-two sizes as well. So the only candidate sizes for sprite sheets are power-of-two sizes.

Suppose you want to put an entire game's images on to one sprite sheet. How big can you go? Again, more technical limitations: not all systems support 4096x4096 images (often on mobile). Therefore the biggest size that can even be considered is 2048x2048, else some systems will fail to display anything at all.

Memory can still end up being wasted with sprite sheets. If a 1024x1024 sheet is only half filled, half the pixels are wasted memory again. If this happens, Construct 2 will instead slice the sprite sheet in to two or three 512x512 sprite sheets to reduce wasted space.

Progress feedback

A problem with placing everything on one giant texture is the game progress bar becomes useless. Space Blaster could just about be squeezed in to one giant 1024x1024 image weighing in at 2 megabytes. Unfortunately the browser does not say how much of an image has been loaded - only whether it has finished loading. With lots of images the progress bar advances gradually as each individual animation frame is loaded. With one giant image, it does not advance at all until it's finished loading. This means the progress bar sits at zero, then after a while jumps to to 100% and immediately starts the game.

It might seem trivial to worry about progress bars. But consider users on slow connections: if they are sitting looking at a progress bar reading zero and not moving at all, they may be inclined to think it is not working and leave the game before it finishes loading. In reality it was gradually downloading a 2mb image, but with no feedback that things were actually moving, you lost a player.

This means it is probably best to split images over a few sprite sheets rather than one mega-sheet. That would help players see the loading really is working.

Image compression

I've previously blogged about image compression in Construct 2, which you may want to read to understand this section better. You can choose three formats for each animation frame individually: PNG-32, PNG-8 or JPEG. This is combined with some sophisticated processing during export that helps reduce the download size of your game as much as possible. However, it raises an interesting question: if a sprite sheet contains a set of images with different formats set, what format should the sprite sheet be saved in?

It's easy to say "whichever is the best quality". But this answer could substantially increase the download size of the game. Remember PNG-8 is often less than half the size of PNG-32, and JPEG even less than that. If a lot of your game's images are PNG-8 and JPEG, a single image using PNG-32 could cause everything to be saved as PNG32... causing the download size to more than double! It would be a shame if everyone had to wait twice as long for your game to load because it used sprite sheets!

The next obvious thing to do is have a PNG-32 spritesheet, and another PNG-8 spritesheet. However, this can still cause big increases in the download size! As mentioned in the previous image compression blog post, Construct 2 counts the colors in images on export. It automatically converts PNG-32 images to PNG-8 if they use fewer than 256 colors, even if the setting is still PNG-32. I think this is a really nice feature: it's a hands-free saving, significantly reducing the download size without you having to do anything at all. However, some animations mix low-color (under 256 colors) and high-color (over 256 colors) frames. This means as individual frames, some would come out as PNG-8 and others as PNG-32. When combined in to a single sprite sheet, the entire sheet has over 256 colors, so would export as PNG-32. It's even possible that every frame in an animation could individually be low-color, but taken all together they'd have over 256 colors (since each frame could have a different 256 colors). Then they end up being saved in PNG-32 which can be over twice as big.

I was really surprised by the effect of this. Despite the fact a sprite sheet of a number of frames should compress better than each frame saved to a separate file, the effect was significant enough to make the Space Blaster export bigger than not using sprite sheets at all! One example was one of the explosion animations, where the last frames tended to be very dark and be able to save to PNG-8, but sprite sheeting saved everything as PNG-32. I was not comfortable releasing the feature if it would make your games even bigger to download - that seems to me to be an anti-feature.

So the end result is a middle ground: a sprite sheet per sprite. A single sprite sheet will at most contain all the animation frames for one object. We also went with a maximum sprite sheet size of 512x512, which is smaller than the biggest supported size. This makes it more likely long animations are spread over multiple sprite sheets, which has two effects. Firstly, the loading bar problem is alleviated, since there are more images to download and therefore more progress updates. Secondly it is more likely an entire sprite sheet can be saved as PNG-8, which helps reduce the download size. For animations like the explosion with lots of dark low-color frames at the end, the last sprite sheet or two can still be separately color-counted and saved as PNG-8 where possible. Finally, JPEG images are never sprite sheeted and are always saved as individual .jpg files.

Since multiple frames in one PNG file compresses better than several separate files, you also can get around a 10-15% reduction in the total size of exported images. Since there are also fewer separate images, fewer HTTP requests need to be made during loading, which makes the download even more efficient. Space Blaster without sprite sheets is 276 images, requiring 276 separate HTTP requests; with 512x512 sprite sheets, it's only 49.

Other objects

Currently only sprites are assembled in to sprite sheets. This is mainly for backwards compatibility. Since only Sprite is affected no other plugins using images (either official or third party) need to be changed. There's not much more to be gained, anyway - objects like Tiled Background and Particles tend to use fewer images which are completely different (as opposed to lots of very similar animation frames), and it is much more difficult to deal with the image format problem in that case.

Performance

Often performance is cited as a reason to use sprite sheets: apparently, the graphics card does not have to swap textures so often while rendering, allowing it to work more efficiently. However I was unable to measure any performance difference at all between any system. Individual images, a single mega-sheet and our middle ground of 512x512 sheets all scored about the same on our performance test, even on mobile. So I think performance is simply not an issue either way here.

Benefits

In the end this turned out to be a lot more complicated than I anticipated! Done wrong, spritesheeting can make your game take longer to download and frustatingly not display any progress at all during that time. Our middle ground hopefully covers everything:

  • The total download time is reduced since sprite sheets compress better, PNG-32 or PNG-8 is still used where appropriate, and the download makes fewer HTTP requests
  • Runtime memory use is reduced by eliminating the unused space around power-of-two sized images.
  • Players still see loading progress so they don't get fed up and quit.
  • Third party plugins using images aren't broken (apart from any which alter Sprite's images, which I will help plugin developers fix).
  • Runtime performance is not affected.

This was a pretty challenging list to satisfy. However it will help ensure Construct 2 is doing the maximum it can to optimise your projects on all fronts, without making negative tradeoffs.

Now follow us and share this

Tags:

Comments

4
orrence 3,099 rep

Very sophisticated --> nice!

Tuesday, May 29, 2012 at 2:32:19 PM
4
Kyatric 69.3k rep

I appreciate the concern about slow connexions (having not the fastest around myself) and I also appreciate the concern towards the end user (a progressive download bar that does not just only freeze until all assets are loaded).
I tested GM's demos HTML5 games, and it seemed it was the solution they adopted which stinks in an user perspective imo.

Thanks for your hardwork, and the time put on disserting it with the community.

Kudos as usual, keep up the good work.

Tuesday, May 29, 2012 at 2:35:23 PM
2
gammabeam 13.8k rep

Love it! Spritesheets are needed as the projects increase in complexity, this is a great feature!

I believe creating a (or maybe incorporating @mipey's) Spritefont's would make a nice addition.

I'm away from the PC, so I can't test, but can I ask about the sorting? Are the frames arranged in a uniform way, or is there a method (automatic, or manual) to position them in a way they use less space?

Tuesday, May 29, 2012 at 2:45:15 PM
3
Ashley 193.7k rep

@gammabeam - ideal sorting on spritesheets actually turns out to be an unsolvable problem (sort of a spacial equivalent of the knapsack problem, which is NP-hard). So it just uses a really simple approximation: start with the biggest frames and fit smaller ones on afterwards. It works OK and many animations have all the same size frame anyway.

Tuesday, May 29, 2012 at 2:57:22 PM
1
xeed 4,977 rep

Thank you for the information.

I often got the feeling of reduced image quality after sprite import. Especially resizing images does a lot of better when doing before in paint.net. It does not create antialiasing, while c2 seems to do so. Any suggestions to this very welcome.

Anyway, keep cool [:)]

Tuesday, May 29, 2012 at 2:58:02 PM
1
Ashley 193.7k rep

@xeed - try setting pixel rounding or point sampling in project properties - otherwise you can get a 'softening' from linear sampling.

Tuesday, May 29, 2012 at 2:59:19 PM
1
gammabeam 13.8k rep

@ashley
Nice! I'm asking because I tend to create "scenario" sprites with lots of different width/height images and simply change their frame number.

Tuesday, May 29, 2012 at 3:03:03 PM
1
NRABrazil 8,878 rep

Great News!!!

I will use it now!

Tuesday, May 29, 2012 at 3:45:26 PM
2
Nimtrix 8,452 rep

"Construct 2 counts the colors in images on export. It automatically converts PNG-32 images to PNG-8 if they use fewer than 256 colors, even if the setting is still PNG-32. "

Great idea ^^,

Tuesday, May 29, 2012 at 4:09:36 PM
2
TELLES0808 22.1k rep
Tuesday, May 29, 2012 at 4:46:36 PM
3
noirfluo 6,981 rep

Very interesting ! ! ! !
And... Welcome to "Spritesheets" feature ! :))

Tuesday, May 29, 2012 at 4:49:27 PM
1
Kiyoshi 13.3k rep

Congrats @Ashley, perfect setup of spritesheets. About the performance about using a spritesheet vs using separate images: On modern hardware it's not very aparent, since current video boards are heavily optimized for texture switching. So where it really makes a difference, i believe, is on more modest desktop and mobile hardware, i think even on more powerful ones like IPad and company. Pretty much every single game engine oriented towards mobile games uses spritesheets. It's almost a necessity. So , again, well done.

Tuesday, May 29, 2012 at 5:11:37 PM
2
stemkoski 19.7k rep

I love learning the details about what goes on behind the scenes at Scirra HQ. Keep these great blog posts coming!

Tuesday, May 29, 2012 at 6:26:05 PM
1
srealist 3,273 rep

Great updates at a dizzying pace! I don't see a lot of people asking for shader support though I know it is on the development list. I think perhaps this is because some people don't realize what it will mean to have shaders but once they see it, they will be unsure how they ever got by without them. Even just normal and spec maps would be a huge contribution.

Obviously this will require a lighting system as well. It's going to take C2 to a whole other level.

So anyway...SHADERS pretty please!

Tuesday, May 29, 2012 at 8:32:04 PM
2
Kiyoshi 13.3k rep

Omg yes Shaders!!! Most wanted too :D Effects on Construct Classic was so perfect....

Tuesday, May 29, 2012 at 9:00:44 PM

Leave a comment

Everyone is welcome to leave their thoughts! Register a new account or login.