4k Game Contest – Some useful tips

4kOk so after the embarrassment of my first post on this subject, I wanted to present some findings that may help you out on your quest for smaller SWF sizes. More importantly, I know for a fact these all worked for me!

For those who didn’t read the previous post: I’ve been working on my entry for the 4k Game Competition, and have found the following information during the course of my coding:

Keep Event Listeners out of the constructor

I have a whole bunch of init stuff in my constructor (creating game graphics, setting up variables, etc) and at the end I kicked off the game by starting up the main events (keyboard, mouse, etc). But by moving the event listeners to their own function, and calling that function from the constructor, it reduced the size of the SWF.

If you know the size of something, use it! Avoid references where possible

When creating a Rectangle I passed in the width and height of a bitmap by reference (bulletBitmap.width). By removing this and passing in the actual known width of the bitmap (6) it saved a massive 20 bytes from the ActionScript code.

Before: bulletRect = new Rectangle(0, 0, bulletBitmap.width, bulletBitmap.height);

After: bulletRect = new Rectangle(0, 0, 6, 6);

Here’s another example where being explicit saves bytes:

Before: fullRect = stage.getRect(stage);

After: fullRect = new Rectangle(0, 0, 550, 400);

This saved us 6 bytes.

Make Bitmaps Transparent

I create a bitmap the size of my Stage to hold the game background in. It looks like this:

gridBitmap = new Bitmap(new BitmapData(550, 400, true, 0x0));

Now I don’t need this bitmap to be transparent (the 3rd parameter) as it sits at the bottom of the display list. But by setting the transparent parameter to “false” it increased the size by 3 bytes.

Even default values take-up space

Object instantiation is expensive in AS3, so it’s best to pre-calc objects you need in your main loops at the start. However who would have thought that the following:

zeroPoint = new Point(0, 0);

takes up 1 extra byte than:

zeroPoint = new Point();

Even though 0,0 are the defaults for the Point object. Every byte counts!

Avoid Array references in for loops

I have a loop in the game that checks through a pool of baddies (standard Array containing a custom Object that extends a Sprite). I started out doing it like this:

for (var a:int = 0; a < baddiePool.length; a++)

and then …

baddiePool[a].value = newValue;

But by pulling out the array element first at the top of the loop, then referencing that, I saved a massive 33 bytes in total:

ba = baddiePool[a];
ba.value = newValue;

Smaller than a ternary

Thanks to Kevin Luck for this one :) If you need to run a standard if/else on a value where it could be equal to zero then it can be shortened to:

x = lx || Math.random() * 550;

In the code above, x = lx unless lx = 0, in which case set x to Math.random() * 550. This is 3 bytes smaller than using a ternary/if-else equivalent.

Hopefully the above will help out those also entering the competition. Feel free to comment and add more tips!

Posted on February 18th 2009 at 3:05 am by .
View more posts in ActionScript3. Follow responses via the RSS 2.0 feed.

7 Responses

Leave a comment
  • Glenn
    February 21st 2009 at 4:00 am

    Make Bitmaps Transparent….

    Hmm…that’s interesting. Never knew that. Does that mean blitting should always use alpha transparency by default?

    Logically, opaque bitmaps means the engine needs to fill rect to black if transparent values are found. But at the same time, aren’t you reserving 32 bits compared to 24 bits in memory if using transparent bitmaps? Shouldn’t transparent bitmaps take up more disk space? What about performance and other factors?

    What you mentioned seems strange…

  • February 21st 2009 at 8:19 am

    Hi Glenn – You have to remember the advice has nothing to do with optimisation, disk space or memory. It’s purely about what results in the smallest amount of ActionScript Bytes used in the final SWF. I guess deep down the compiler just has to create less instructions for the transparent version.

    I’m nearly finished on my game and will post more findings shortly, it has been a fascinating experience!

  • February 24th 2009 at 10:12 am

    Neat tricks!
    I’ve found that skipping parenthesis altogether is often even smaller: zeroPoint = new Point;
    I also suspect a for each will be smaller than a full on for-loop.

    (btw, i updated my TinyKeyboard example with some of your tips. )

  • February 24th 2009 at 11:47 am

    I’ve tested new Point vs new Point() and didn’t find any difference to be honest! for each vs for depends on what you need to do with the values within the loop I guess – for (var x; x < y; x++) is really useful if you actually need to reference x within the loop (as I often do), because with a for-each of course there's no way to get "x" back again without further look-ups, should you want to then splice that entry from the array for example. I've got a few more tips I'll post later on today :)

  • HanClinto
    March 11th 2009 at 3:05 pm

    Great advice, thank you for sharing/posting! Good luck in the competition!

Make yourself heard