Friday, February 5, 2010

Flash, Flash, Flash....

...Why you gotta be like that?

I was tempted to call this post my "Flash 'Dear John' Letter" in reference to Danc's Flash Love Letters, but since we're not actually dumping Flash (at least not yet), it wouldn't be accurate, just catchy.

So what is this post about then? My gripes with Flash. Many people have love-hate relationships with tools and products they use. We're finishing up our second premium Flash game right now, and while I love the good things about Flash more than ever, I'm increasingly frustrated by it. I hope that by joining with other Flash game developers in airing our grievances, Adobe might take notice and make some changes for us. If they don't, we won't be the only developers switching to Unity.

The Good

We use Flash for two reasons:
  1. Wide Reach – Almost all internet-connected computers can run our games.
  2. Rapid Development – Games come together quickly.

We like these things about Flash development:
  • Tight integration between assets and code.
  • AS3. I have to admit, I enjoy writing AS3 code. I have several years of C/C++ experience and a few more of C# experience, but I'm having a lot of fun with AS3. Yeah, it's missing some language features, and it can be quirky, but it's fun.
The Bad

These are things that are really hampering large-scale Flash game projects for us.

1. Two necessary tools that don't work together very well.

Flash CS4 doesn't cut it for software development—it's terrible. It's great for creating visual assets, laying out interfaces, and exporting compressed sound. Those things are necessary for game development, and Flex Builder can't do them, so Flash CS4 is a necessary tool (if there are alternatives that really work, I haven't found them).

Flex Builder is vastly superior to Flash CS4 for compiling and debugging code. Flex Builder 3 is the only Flash profiler, so it's necessary for game development, IMO. I know not all Flash game developers use it, but most don't create large programs that need it. Garbage-collected languages need memory profiling at the very least. That's about all I use the profiler for. The performance profiler just tells me what I already know: all the execution time is spent rendering the game.

In theory, CS4 could export a .swc that FB imports, and I could load the symbols and do my thing with them. But there are bugs.[1] The only way I've found for objects exported from CS4 to always work as expected when imported into FB is to export a .swf from CS4 and load it dynamically in my FB AS project.[2]
This integration is clunky and tedious to setup and maintain.

Solution: Fix the bugs, remove the hoops we have jump through.  Make FB and the Flash IDE work together seamlessly.

2. All asset data is contained in the .fla's.

We have a couple hundred MB of bitmaps and wave files in our game. All that data is imported into .fla's. The visual things are laid out and composed into symbols which I can use in code. The sounds and music are compressed and processed by Flash, which does a great job.

This leads to two problems:
  1. Tim and I (and our other contractors) all work at different locations, and our SVN repository is on the internet. We already have hundreds of megabytes to check in and update, and then the .fla's double it. While most check-ins and updates don't touch nearly that much of the project, sometimes they do, so I postpone my check-in until I'm done for the day so I can start it and walk away. If Tim needs something sooner, then I have to do it during the day and interrupt my work.
  2. Whenever a file on the disk changes, we have to open the .fla it's in and update it manually. This is stupid. That's the nicest word that accurately describes this "feature" of the Flash IDE.
Solution: Store references to files, not the file data itself in the .fla. Unity does this.

3. Flex Builder caches source files.

Ironically, FB has a similar problem as CS4. I can't stand the FB code editor or the Flash IDE's code editor, so I use an external one (gVim FTW!). Other people probably like it just fine—that's not the problem. Code editor preferences are personal, to each their own. The problem is that when I change the files on the disk, FB doesn't notice, so it doesn't recompile them when I build the project. This is true of the .swf's that I export and embed in the project and the .as files themselves.

There are 2 work-arounds for this problem:
  1.  Open the .as file in FB, because then it will say "Hey, the file changed, do you want to reload it?"
  2. Project -> Clean -> OK. Then it recompiles everything, which takes a lot longer. I have to clean the project whenever I re-export from CS4. If I just change code files, I have to estimate which work-around will be faster.
Solution: Don't copy all the source files, just use the ones I'm editing. It's trivial to detect when files change.

4. Both tools are bloated and slow.

It doesn't take a very complex scene for CS4 to start lagging, and I have a nice machine. While our projects might be big by Flash standards, they are small by the rest of the software world's standards. 8 years ago, working at Acclaim, I could build our much larger project (a AAA-sized title) on my totally garbage Win95 computer just as fast as my core i7 machine builds my much smaller Flash project today.

What gets me though is how the CPU on my computer is hardly doing anything while CS4 is exporting or FB is compiling. What the heck is the program doing? CS4 has just 1 file to read (as already covered), and it's even slower than FB. I have all my big music wave files in 1 .fla, and even exporting it doesn't use any CPU to process all that data. Yet it takes minutes to export, and during that whole time, CS4 is completely unresponsive. FB doesn't go unresponsive when compiling, but it still takes a long time and doesn't utilize the CPU at all. No CPU utilization means the process is spending most of its time waiting.  That is very poor software design.  All other compilers I've ever used are much faster.

Another result of this issue is that our game assets need to be split up into many .fla's to keep compile times reasonable. That adds additional headache for managing what is where, which compounds with issues #1 and #2 above, since more .swf's have to be dynamically loaded, and then assets need to be loaded from the right .swf's, and when changes are made, the right .fla needs to be manually updated.

5. The Flash Player is slow.

It uses a software vector renderer, which is never going to be fast compared with the hardware bitmap renderers that most games use. For small, simple games and ad banners, it's great. For large, complex, fullscreen games, it stinks. AIR does perform better fullscreen than the Flash Player does, but it's still nothing compared to hardware acceleration.

In our latest game, Clockwords, we've made almost everything bitmap-based to bypass the slow vector renderer, and that keeps our game working on slower machines. But this comes with another source of headaches: we need low-res versions of our art for the web game, and high-res versions for the AIR game. That means we need another set of .fla's and another set of art. If Adobe hadn't introduced conditional compilation, then this would have been way too retarded to accomplish. With conditional compilation, it's just retarded, but still possible.

Solution: Make real hardware acceleration a higher priority. There are opensource and proprietary products that can run .swf's in a hardware accelerated environment, so this is not an unsolvable problem. It just hasn't been a priority for Adobe. Don't worry about models, animations, shaders, or any of that stuff. Stick with 2D, it's OK. Just write code to transform vector shapes into triangle strips, and you're just about there. ;)


Flash has historically been targeted at small project sizes, like ad banners and short form games. Adobe is spending lots of time and resources on Flex, which is targeted at RIAs. Long form Flash games require the software dev tools of the Flex world and the visual tools of the Flash world (with improved support for large projects). We are stuck in the middle without good tool support on either side.

While we're reaping the benefits of wide reach, the poor tool support is greatly increasing our development burden. We're sore from hitting our heads against the ceiling Adobe has placed over the Flash platform.


It would be nice if Adobe addressed these issues, because then we could keep doing what we're doing. We've invested a lot of time and money into Flash development, and the libraries and community support are great. Companies like MochiMedia, FGL, and the countless Flash portals make game development and distribution much easier than other platforms.

I think Unity is positioned to grab some significant market share. All it needs to take off is content, and indie developers are already flocking to it now that it's free for indies (or at least poor ones). When there is sufficient content for the Unity browser plugin, users will install it, and portals will support it. We're not really that interested in making the jump to 3D, but we're definitely interested in hardware acceleration...and a sane art pipeline...and just 1 slick tool. As Unity gets more developer support, it will get wider reach, and so the #1 reason to use Flash will be reduced.

We're kicking around ideas for our next project after Clockwords, and we're pretty sure we want to do a bigger one. Unless the Flash scene changes significantly, taking on Flash's limitations and headaches to get its reach probably won't be worth it.

[1] The primary bug was that timeline script didn't always execute. Some animations need some script, and so I need the script to work.

[2] You can see how I do it in our Global Game Jam 2010 submission. The source is in the .zip file you can download from there. The file contains a list of all assets exported from the GameAssets.fla. That way, I can write my code against the file to let the compiler make sure all my references are spelled right.

Monday, February 1, 2010

Global Game Jam 2010

As many of you probably know, this past weekend was the Global Game Jam! We decided to do it, and we hooked up with the group at Newport, Wales, so we could start and end earlier than our own time zone. We partnered up with a great artist named Scott Thompson in Wales, and we made a game in 2 days.


Making a game in 2 days requires some different skills and thinking than making a game at a "normal" pace does. I had to set aside some of my OCD tendencies and make some last-minute, dirty hacks to get a couple things working.

Perhaps the most useful thing was the necessity to limit the scope of the project. It's really easy to say, "Oh! Let's add this!" We say that a lot when we're working normally. When prototyping, it's important to really stick with what's essential for the core gameplay. The reason is because until you have the core done, you don't even know if it's going to be fun. While we've always prototyped our ideas before making full games out of them, we tend to let our prototypes bloat a bit, and we've thrown some out, so we could have saved the time if we stuck with the core features.

With a 2-day limit, it's also a good idea to stick with what you know, just for practical purposes. Some might disagree with that because it can limit creativity, but it just depends on how complete you want your game to be after 2 days.

Game Overview

The theme for this year was "deception", and the GMT constraint was "a sink, a wink, a rink" (in no particular order). We made a game where you play as a mouse looking for cheese in a big kitchen. You have to sneak around, avoiding being seen by the humans in the kitchen. Cheese can be hidden in one of a dozen places, and you have to find it and get it back to the drop zone near where you start. Each time you collect one piece of cheese, another piece and a mouse trap spawns on the map. Running into a trap kills you instantly, game over.

To make things more interesting though, you can only see traps, cheese, and obstacles a couple feet in front of yourself. Also, some of the kitchen appliances can be used to distract the humans and make them look at them. Click on objects that glow green to start them up. Some take longer to activate than others (e.g. filling a sink to over-flowing takes longer than knocking over a garbage can). Gray squares can only be traversed when you don't have the cheese, so you have fewer sneaking options when you're carrying it.

You can play the game here:

This is the GGJ page for our game where you can download the source and stuff:


I'm not sure (at least at this point) if we'll do it again, because of the sleep deprivation and time away from families, but it was fun. Maybe in a year, we're be ready. In the meantime, we'll definitely keep our prototypes more focused.