Nov 232010

I just ran into good ol’ Flash Error #2136. Here’s the entirety of the error message you get, not at compile time, but at runtime:

Error #2136: The SWF file contains invalid data.

What data exactly is invalid? LOL, as if!

I tried googling the error, and it gives a whole bunch of advice on how to disable a document class, or how you shouldn’t export SWCs with wacky options, or all sorts of other nonsense that doesn’t apply to me. Most seems to have been written years ago. Which kinda tipped me off…

Here’s what worked for me:

  • Flash: File > New > Flash AS3.0 File
  • Copy the entire “library” from your old FLA
  • Paste the entire “library” to the new FLA

That should resolve all your problems. I spent a good 4 hours on it. All the settings between the two files for the same; the only thing different was the original file used to be a CS3 file and the new file is natively CS4.

I hope this helps save someone else some time.

Sep 112010

I’ve gotten a bit of feedback on my performance posts from a few different sources. Enough to make a new article on the subject! See part 1 here, or jump to part two here.

The Source Code

So people can take a look at how I’m doing things, or what exactly the base code is up to, I’ve packaged up the source code for SolarCraft.  Remember: this was a two-hour hacked-together-from-scratch bunch of code. Don’t judge me too harshly! I think it’s a decent testbed for performance because it has a basic game-style logic loop and a few iterations through large arrays… But most of all, isn’t designed to be “perfect” or “most efficient”; this is to test real-world game-performance, not theoretical performance maximums.

Download the source here.

Rotating bitmaps by 90 degrees

User areagle of the FlashGameLicense forums asks if rotating bitmaps by exactly 90 degrees provides any sort of performance boost, since the math for doing so is much easier and less intensive on the CPU. Decent enough question! Let’s get some baselines first.

1000 collectors on-screen, .cacheAsBitmap true: 48.0 FPS

Adding +.01 rotation per tick: 14.0 FPS

Changing to +90 rotation per tick: 13.2 FPS

Changing to +180 rotation per tick: 14.5 FPS

Changing to +360 rotation per tick: 48.3 FPS

Well, it looks like the rendering engine is smart enough to know that a 360 degree rotation won’t affect speeds, which is nice; now I know that simply setting the .rotation property isn’t enough to cause a performance drop. 180 degree rotations were a smidgen faster than smaller increments, but that may  have been luck; I’m willing to call this one potentially true, but for game development’s sake, doesn’t matter.

Different loop styles

This one was brought up a few times in different places (twitter, forums, blog comments) and I can’t help but think people are missing the point. People are saying I’ll see a significant performance difference between the different loop styles.

Now, I will believe that a while loop might be a bit faster than a for loop. But compared to game logic and rendering times, I’m betting this speed difference is going to be less than a single percentage point. I’ll bet I can’t pickup the difference from the background noise. I believe loop speed differences are only useful to people crunching through massive amounts of data (like, one-million-entity-arrays or something).

Since I have my code open anyway, why not appease the masses?

There are two main game loops, both updated in the Update() function in (line 68); the first loops through a vector of 1000 collectors, removing any dead entries (there are no ways to die in this version, so no action is taken); the second loops through each collector and runs their respective .update() functions.

Baseline: Using two FOR (var i…) loops, 46.7FPS.

Converting both to be FOR EACH (var entity…) loops, 47 FPS.

Converting both to WHILE loops: 47 FPS.

Without getting too in-depth here I’m thinking my hunch was right: Loops might make a big difference in big data sets, but in games it simply doesn’t matter.

Debug vs. Standalone vs. Browser

Different Flash players get different performance values. I noticed this while performing other tests for this series of articles, and I know there is definite value here.

Using the standalone Flash 10 Debug Viewer – which I do my sole development in – I get 27 FPS with 2000 collector’s on screen. I kind of assume this is the performance that people will get when they play the game on the web; let’s test:

Using the Chrome & Firefox Flash Plugin Viewer, I get nearly 50 FPS in the same environment!

Using the Internet Explorer ActiveX Debug Viewer, I get 19 FPS in the same environment!

Out of curiosity, I downloaded the standalone Flash projector (non-debug) and maxed out at 60 FPS.

So there we have it. All debug viewers are nearly half the speed of their counterparts, and the web plugin is definitely slower than the standalone version of the player. Keep this in mind! If you do all of your development and testing in a browser-based debug viewer, you are essentially simulating a slower computer.

Multi-app same-page performance differences

Back in my last performance post I toyed with how the target FPS might affect performance (it didn’t). A few people said that this actually is a real issue even for us game devs, but the problem only crops up when an .SWF is hosted on an HTML page that has a bunch of other flash things playing — such as the portals we deploy our flash games on.

One side of the argument says that aiming for a higher framerate than what you can achieve, can actually tax the SWF player and produce a lower FPS than intended. Another side of the argument says the SWFs “compete” for slices of the timing pie when several instances are launched, and the more resources you demand – the more resources you get.

Seems like a perfectly reasonable assumption, and is indeed well worth testing out. Let’s give it a go.

For this test I’m going to use a baseline build of 4000 collectors running at a target of 30 FPS (using the non-debug browser player). I’m getting 21 FPS on (uploading my game but not ‘publishing’ it).

No matter what I set the target FPS to, the value is not wavering, despite there being flash ads and Kongregate’s achievement/chat interface on my screen.

Just out of curiosity, I opened two tabs (one set at 30 FPS and the other at 60 FPS, both hosted on Kongregate) and played each flash game tiled on my screen. Performance still did not waver from a solid 21 FPS for either copy.

Looks like I can’t replicate any web-based test conditions! I’ve now tested this “Target FPS” thing a dozen of ways and can’t seem to make it affect performance at all. I’m thinking that in the majority of cases for actual game development, this will not be a concern: set your FPS to whatever you feel is best and the game will perform as best it can. Why limit things? Set your FPS to 120 for all you care! (Note: Flash Player 10 does indeed limit max frame rate to your screen’s maximum possible refresh rate, so it’s not possible to ‘waste cycles’ doing this)

Off Screen Rendering

A curious thing I noticed in my performance graphs when playing things in tabs: flash skipped rendering cycles if the viewable area of the game was physically not visible on my screen. If my game ran minimized, was in another tab, or was scrolled off the edge of my monitor, my performance maxed out pretty quickly. It looks like Flash only bothers rending when it’s open or active (for the browser plugin, anyway)!

Good to know: Don’t do performance tests if the window isn’t open, front and center!


Throughout all of my testing, I’ve really only concluded one thing: The only place you can possibly optimize your game is in appropriate use of bitmap graphics. Any other “tweaks” you can make either have such little effect as to not be relevant to game developers, or have no effect at all.

Sep 102010

As I was waiting to be interviewed for FlashGameLicense, I decided to make a game to prove a point: That it’s possible to quickly prototype an idea, just to see if it might have legs.

The people in the FGL chatroom mentioned “Snails with Propellors flying around” and someone mentioned “Cooking” so I decided to merge the two:

You are an intrepid SnailCopter, looking to push the Eggs (green boxes) into the frying pan (red skillet). Avoid the falling Salt!

The game has pretty LOL-tastic physics (I coded them completely from scratch, and I ashamedly had to Google F=ma and v=v+a.. sigh). Using the performance enhancing techniques I learned in the last few articles, I’m getting a solid 60 FPS with all these objects on screen :)

Not bad for an hour! I think this game has promise; might sell for a grand or two on FGL if I polish it up.

Sep 062010

Following up on my previous article, I wanted to test a few more things. For the sake of generating clear numbers, I’m using yesterday’s 2-hour game SolarCraft as my testbed.

Throughout these tests I’m spawning 2000 collectors with cacheAsBitmap enabled, and running the test for 30 seconds and providing the average FPS (which will therefore include, but hopefully minimize, startup lag throwing the numbers off a bit). As I mentioned in my previous article, I’m trying to get real-world numbers (using believable in-game item counts) with other things going on (such as graphics and game logic loops).

Vector vs. Array

Vectors are new in Flash 10 and are, put simply, a typed array. Many claims have been made on the huge speed increases when using Vectors (I’ve heard 250%+); let’s test it out!

A 2000-length vector iterating twice per frame generates me an average of 26.5FPS.

Converting the code to untyped Arrays provides me an average of 26.0FPS.

That difference can easily be chalked up to various other things and is pretty much indistinguishable. It looks like, for the purposes of this game, Vector iteration isn’t much faster at all.

However, I still love vectors for being typed. Still worth using, no harm in it and your code will be easier to work with!

Loop Iterations

“Hey wait,” I hear you saying. “Why do you loop through the 2000-length vector twice per frame?

Good question! It was because I made sloppy code and thought it would be a good idea to simply loop through everything again rather than fix it (that’s how you make 2 hour games!).

For clarity, one loop is simply cycling through all game objects (in this case, 2000 collectors) and running their “update” function. This function calculates where the collector wants to go, runs a few randomization jitters, and does some simple coordinate translations to produce a vector. Then they “walk.” Nothing exciting, no big maths.

The other loop is just checking for dead collectors and culling them from the Vector (not that anything is dying in these tests).

As a baseline, we are currently getting 26.5 FPS.

So I’m curious.. let’s comment out the useless dead-check loops and see what kind of performance boost we get. Looks like 27.2 FPS. A slight increase, maybe even one worth sticking with; a single frame per second optimization in a few places might add up.

Let’s remove the walk-logic loop and see how that fares. Looks like 29 FPS. This one was to be expected; removing all the art movement and gamelogic from the game should very well speed things up. To be fair, the “current FPS” was locked at 30 for a long time, and we only got 29 FPS because of my 30-second-average including bootup delays.

Well, let’s play with this dead-check loop again. What happens if I make it run 10 times, thus iterating the game through 22,000 vector entries per frame? We get a result of 22 FPS. That’s a significant hit for a loop that doesn’t even do anything.

I think it’s safe to conclude that iteration through long lists – regardless of content or actions – is a big performance hit. But putting in a useless duplicate iteration 10x over? Not exactly a “big problem” in game design, I think. You’re better off ignoring this issue and optimizing what happens in the loop itself.

Playing with Target FPS

If you tell Flash to run 30 frames per second, it might run at 25 FPS thanks to your inefficient code. I’ve heard, however, that if you tell Flash to run 60 times per second with the same code – that 25 FPS might drop to 10FPS. Trying to over-achieve can actually hurt you!

I’m really interested to see if this holds true in my game.

I’m currently running at about 27FPS, on average, with a target framerate of 30.

Changing the target framerate to 60…  Has little effect! I’m averaging only 1 less: 26FPS.

Let’s crank the target framerate up to 120… Hmm. My monitor refresh is 60hz, I wonder if Flash can sense that and scale down my request? I’m showing a target of 60 still, and still hitting 26FPS. Oh well.

Just for kicks let’s drop the framerate down to 10 an see what happens: Wew, a solid 10 FPS. At least I know there wasn’t some weird overhead preventing me from hitting 30FPS before; it looks like my code really is a bit too slow (or I have too many dudes on the screen).

Sep 062010

I’ve done a lot of reading on performance enhancements and testing solutions for Flash, but I’ve never actually done any A/B testing of my own. Let’s fix that.

I’m using yesterday’s SolarCraft as a template; it has a few game logic loops and a bunch of movement on the screen, vector calculations and Vector iterations. I think it’s a good “realistic” platform, as opposed to looping through display-less routines or something. I hope to gain practical data here, not theoretical!

For each of my tests I simply adjust the number of  ”collectors” that spawn when you click on the base in SolarCraft. This gives me a quick and easy item count, and I’ve tacked on a profiler to see my memory use and framerate.


Setting the “.cacheAsBitmap” property to “true” on DisplayObjects is supposed to make normally-vector art display faster, but only if the art translates (not if it rotates or scales). Let’s see!

With cacheAsBitmap set to FALSE, I can maintain a constant 30FPS with a maximum of 800 collectors on screen. Memory use peaks at about 8.25mb. Or roughly 0.010mb per collector.

With cacheAsBitmap set to TRUE, I can maintain a constant 30 FPS with a maximum of 1,900 collectors on screen. Memory use peaks at about 26mb, or 0.013mb per collector.

A slight (but marginal) increase in memory usage for more than double the performance! That’s pretty good.

Adding Rotation

As it stands, the collectors are only translating; let’s see what happens if we add a slow rotation to the collectors each frame ( collector.rotation += 0.01 ):

Eek. Using the previous 1,900 collectors,  my performs drops from 30FPS down to 8FPS. Attempting to regain my 30FPS, I had to drop my collector count to 500 – below our baseline 800 figure when cacheAsBitmap is turned off.

With cacheAsBitmap turned off and rotations left on, I easily reach back up to the 800 mark at 30 FPS.

Seems like vectors are indeed much better performers when it comes to rotation (and memory usage didn’t change).


I’m replacing my rotation code with scaling code ( collector.scaleX += 0.01 ) to see if we get similar performance numbers as we did with rotations.

With cacheAsBitmap turned off, I hit 30 FPS with 700 collectors on screen. a Slight performance drop from our Scaling experiment.

With cacheAsBitmap turned on, I hit 30 FPS with 500 collectors on screen.

So it looks like cacheAsBitmap performs equally as poorly with scaling as it does with rotation; but default vector behaviour handles rotation better than scaling.

Rotation AND Scaling

The results of this test were identical to the Scaling test, so I won’t reproduce them here.


It looks like Adobe’s documentation was factually accurate. cacheAsBitmap gives you significant performance gains if you don’t rotate or scale your vector art at all, and stick to simple x/y translations. cacheAsBitmap will also marginally increase your memory footprint.

But those results I expected.

What I didn’t expect to see was scaling performing worse than rotation in the vector realm. That’s interesting…

Sep 052010

I was challenged to make a game in 2 hours. I find it hard to turn down challenges. :)

Introducing: SolarCraft

This is a semi-automatic RTS; you start with $1000 and can buy Collectors by clicking on your red base. They will head out to collect resources; if they return to your base you earn $10.

You can also place towers for $100, which will shoot and kill your collectors as well as any badguys. Click on the tower to tear it down for $20.

Badguys will suicide bomb you. If you lose your base, you lose! (Game will auto-reset)

Built this from scratch in 2 hours; no development tools, graphics, or code libraries other than what is included with FlashDevelop and the Flex stand-alone MXMLC Compiler. Took me exactly 101 compile attempts. :)

Mar 262010

I like to think that I’m a responsible developer. I make good constructors and deconstructors to prevent memory leaks, I have fairly secure coding habits, I OOP the hell out of everything, and I do everything by-the-book.

Imagine my frustration, then, when all of my games (particularly my latest, Steambirds) have gigantic memory leaks. Like, 500+MB consumption in 5-30 minutes of gameplay.

At first I thought it was EventListeners keeping persistence on my trashed objects. I went through my code several times making sure I nabbed them all and set them to Weak.

Then I thought it was the weak listeners failing. My tests were showing orphaned objects still chugging away despite garbage collection making an observed pass. I’ve banged my head against several walls over the last year trying to figure this out, and in the end always giving up. “Restart the application if it gets slow!” was my only recourse. Flash doesn’t even let you force garbage collection on objects, so I couldn’t hack my way out of it.

Today I found a very interesting blog post. I always knew how the garbage collector worked; it traverses your tree of object references, and identifies any “islands”; that is to say, any objects that aren’t referenced by any variables in your code. At the end of it’s run, all the islands are trashed. What I didn’t know is that IF YOUR ISLANDS ARE BIG ENOUGH, FLASH GIVES UP AND ASSUMES IT’S NOT TRASH.

I guess by complexly-nesting my code, it resulted in something that was too much for the goddamn garbage man to handle. My games essentially think any object I ever create is for HOLDING ON TO FOREVER.

If you want some more technical data, I highly recommend you check out Tom Mason’s blog post on the topic. It was eye opening, to say the least. But now I have to go rewrite a shit-ton of code.

Aug 262009

I had a need for this routine in Protonaut, and Ryan Madsen was gracious enough to pseudo-code this up for me. I then converted it to proper AS3 and to suit protonaut’s needs.

It’s modifiable easily enough, but here’s the basic premise:
Input a decimal (say, the number 1) and request an array length in return (default 6 bits).
It will convert the decimal to binary, and store each bit into an array in reverse order for easy flag operation. Our example of 1 would then return [1,0,0,0,0,0].
  private function dec2bin(dec:uint, digits:Number=6):Array {   var result:Array = new Array();   for (var i:Number = 0; i <= digits-1; i++) result[i] = 0;    for (var i:Number=digits-1; i >= 0; i--) {    if ((dec - Math.pow(2,i)) >= 0) {      result[i] = 1;      dec -= Math.pow(2,i);    }   }   return result; // results are in reverse order... 1 == 1,0,0,0,0,0  }
I used this code for retrieving a single ascii charcode to store the combinations of the various 6 keys you can press in the game. I googled around and couldn’t find anything, so hopefully this will help someone else.
This is easily converted to outputing the Binary to String format, or reversing the Array, if you so need.
Aug 222009

EDIT: The free code-IDE FlashDevelop does a really good job of doing all these steps for you! I recommend everyone switch to it. :)

One of the things that has been vexing me lately is trying to get a Flash PreLoader working for my games. I’ve tried Googling it, but there are too many like-terms: Flex Builder, FlashBuilder, Flex, CS3, CS4… The all have different methods, and my method is the least googleable: Flex 3.3 SDK, AS3 only.

I don’t want others to run into the same problem, so here’s a tutorial on how to make a flash preloader for AS3 with nothing more than notepad.
STEP 1: Why a preloader?

The first thing you have to do is arm yourself with knowledge. Why do you need a preloader?
As you may or may not know, every single SWF file is a movie. Even if it’s a simple Hello World application, it is a movie with a single frame. It’s hard to remember this sometimes, because working in the AS3 environment we don’t have easy access to the stage’s timeline, and everything we do happens on the first frame. Here’s the key to remember, though: The entire current frame must be loaded before the frame starts to play. Most AS3 applications are built on a single frame (#1), which means your entire SWF must be downloaded, and loaded to memory, to display anything.
“But SWFs aren’t all that big,” you say. “Why would I need a preloader for that?”
The average connection speed in the United States is probably way lower than you think, or what you currently have. The fact that you are reading this blog at all probably means you have a 5mbps+ broadband connection. But that’s how us geeks roll, and we only ever talk to other geeks. I’m on a 10mbps line with access to 50mbps if I wanted to pay extra for it.
The US has made several headlines recently beacuse the average broadband speed in the US is 1mbps. That is 128 kilobytes per second. But did you note the italicised term there? Over 60% of the United States does not have access to Broadband, so dialup is the connection type for many people. But what does that mean in real terms?
Here at Build 35 of Protonaut, the game is sitting at just under 600Kb – not counting audio assets. On the average broadband connection, it will take around 5 seconds to load and display the game to your screen. On a standard dialup connection, it will take over a minute. Many users will leave your page if they see a blank window for more than a second or two. 5 seconds of load time is absolutely painful, and is faster than the average connection!
STEP 2: Setting Up an AS3 Preloader

Allright, now that I’ve convinced you to use a preloader for your FlexSDK application, let’s take a look at what is required.
First, you will need a whole new class file that will be your entire preloader. Here’s some sample code for what I’ve used, and placed inside “” in the root directory of my project:
package {

import flash.display.DisplayObject;import flash.display.MovieClip;import;import flash.utils.getDefinitionByName;

[SWF(width='800', height='450', backgroundColor='#E5E5E3', frameRate='30')]

public class Preloader extends MovieClip {

   public function Preloader() {       stop();       addEventListener(Event.ENTER_FRAME, onEnterFrame);   }

   public function onEnterFrame(event:Event):void {       if(framesLoaded == totalFrames) {           removeEventListener(Event.ENTER_FRAME, onEnterFrame);           nextFrame();           init();       } else {           // Show your preloading graphic or animation here       }   }

   private function init():void {       var mainClass:Class = Class(getDefinitionByName("Main"));       if (mainClass) {           var app:Object = new mainClass();           addChild(app as DisplayObject);       }   }}}

It’s a very simple application. It simply adds an event listener that waits until ALL frames have loaded, and once that happens it will launch your “Main” class. At this point in the game, we still only have a single frame, so it won’t do much. In this case, “” is my main class for Protonaut and also exists in the root folder of my project. You will have to edit this to match the main class name for your project – use “BobJones” if “” is the primary class in your project.

I’ve placed a comment where your preloading graphic, animation, advertisment – or heck – minigame, should reside.
If you compile and run this code alone, without following the extra steps below – the preloader will “blip by” in an instant and not show up until the whole SWF has loaded. So we aren’t quite there yet, but we’re prepared!
STEP 3: Reconfigure Your Compiler

Now that we have “” in place, we want to move the rest of your application off of Frame 1 and onto Frame 2. This will allow the preloader to show itself first, and wait on the loading of the second frame.
Here’s a slice of my compiling instructions:
    "mxmlc.exe" -frame two Main -file-specs=""
They key statement here is “-frame two Main“. This tells the compiler to move the class “Main” onto the second frame of the movie, and thus preventing it from loading before displaying the preloader.
For advanced users, note that you can specify any number of frames this way – possibly breaking up your application into several loading chunks, which can silently load in the background while people navigate your menus!

STEP 4: Correcting for Errors

That’s it, Unless of course you were referencing the Stage a whole lot in your code. Now that the concept of the “stage” resides in frame 1, the stage is outside of the scope for your “Main” class on Frame 2. Any references in your code to “stage” will now return Null, and probably cause you some headaches.
There’s nothing stopping you from passing the stage to Frame 2 as a variable, though!
I dove back into and changed:
    var app:Object = new mainClass();
    var app:Object = new mainClass(this);
Then, in’s constsructor, I had it accept this as a variable and stored it for later reference. Couldn’t be simpler!
STEP 5: Basking in your Glory

Now it’s about time to crack open that beer because you’re done. If you had any questions, or if this helped you at all, please leave a comment! I’ll try to update this with any answers to questions people have.
Apr 292009

While working on Build 45 today I noticed something – that my file size for the project had almost hit 200KB.

That’s a lot of KB. And considering a pretty big chunk of the population in the US is still on Dialup, it’s an unacceptably large number of KBs. It was taking 2-5 seconds to load on my broadband connection; I shudder to think how many people would scare away from a slower network!
I took a look back through the history of the game, and took a look at how the filesize grew with time.
  • Build 1 was 2KB. This was built in Flash directly, not in the current framework I am using now.
  • Build 2 was 54KB. This was my first setup in my actual dev environment, with all the physics libraries and various plugins I needed. I call this my baseline – this is as small as my code will get. A lot of this – probably 45KB of it – is the Flex Framework.
  • Build 11 was still 54KB.
  • Build 12 was 90KB. You may notice very little difference between build 11 and 12; indeed, the difference is absolutely miniscule in terms of code or assets. The extra 40KB in weight is entirely from debugging statements.
  • Build 26 broke 100KB for the first time (109KB to be precise). It’s not surprising either – it’s the first build that includes graphics (albeit basic graphics).
  • As I added more and more art assets, the game ballooned to 158KB by Build 38. By this time the game is really starting to look like the final product, and some of the art assets are still in place in the game today.
  • Build 39 took the cake for the largest single asset size jump – hopping from 158KB to 176KB just for the new menu components.
  • Finally, build 44 weighed in at 182KB.
Build 45 was nearing 190KB when I first compiled it early this morning. That’s when I noticed it, and started trying to slim it down:
  • I had been lazy and was importing files I didn’t need in my source code. By removing these, I slimmed my code down to 169KB – that’s 21KB saved just by commenting out a few lines!
  • I turned off debugging – Which got me 30KB back. 139KB!
  • Finally, I turned on compiler optimization, which apparantly swung me right down to 129KB – which is my latest upload to the server, and the version you are playing right now.
I’m OK with having 70KB worth of art. Mentally subtracting that from my total I’m left with that oh-so-familiar 59Kb – right where I started.
After much Googling this evening it turns out that this is the price I pay for using the Flex SDK instead of the proper Flash IDE. The Flex development framework has a bunch of “features” it includes to help develop things in this pure-code environment wheras the proper, paid-version IDE is a bit more on-the-ball with what you actually need. Up until this point I had not seen any good reason for using the Flash IDE – but now I’m wondering if it’s worth the 50KB penalty to stick with the Flex SDK and MXMLC.
I didn’t wonder too long, though. The answer is Yes. :) Big bloatware notepads-on-steroids is not what this industry needs! rawr!
There are a few other ways I can reduce filesizes – but to be honest, it’s beyond me. I’m not even sure if I can make the suggested changes to this particular project. But let it be known, that there are mythic stories floating about the ether; proclaiming in a dream-like voice that a programmer somewhere… Somewhere far, far away… Has compiled a Flex SDK application in under 10KB.
I guess I have something to dream about at night while comfortably nuzzling my pillow with a smile on my face.
(For comparison; Colin Northway used the Flex SDK to build Fantastic Contraption, and it is 274KB – so I guess I should stop bitching. :) )
Edit: None of the sizes quoted above include audio assets, which are dynamically streamed from the server. For the curious, I have 63KB in sound effects and 2.25MB in music.