AS3 & Flash


2
May 10

The Grand Compromise

I propose the following Grand Compromise:

  1. The WHATWG and W3C revise the Canvas API to align with Flash’s Display List API.
  2. Adobe donates the Flash Player to the WebKit project to serve as an initial implementation of the revised Canvas API.
  3. Apple, Google and Microsoft adopt and implement the revised Canvas API in all of their desktop and mobile browsers.

I think this is an ideal compromise: everyone gives a little, everyone gains a lot. There are no losers.

I’ll address each point in more detail this week.


21
Apr 10

Flash is my platform.

Hi, my name is Troy. I’m a Flash Developer.

Like many people my age, I first experimented with Flash during college. It was the 90′s, the web was new and exciting, and honestly we’d try anything.

I got into it deep. I created the site OpenSWF.org. I maintained an updated SWF file format spec and built a Java-based player. In fact, this was pre-ActionScript, so I even designed an extension mechanism that leveraged Java’s dynamic class loading to allow on-the-fly, distributed updates to the player itself.

Then, I graduated from college, I got married, I got a grown-up job; I left my childish Flash ways behind me and got serious: C++, vector units, video game consoles, multi-million dollar projects.

Five years later I read an incredibly influential whitepaper from Scott Bilas, former Bungie engineer, based on his GDC 2005 presentation: What About Flash? Can We Really Make Games With It? I fell back in love.

Within a year I set out to launch my first (and only) startup, Mockingbird Games, with the goal of making game making as fun as game playing. Much like YouTube, we leveraged the Flash Platform to deliver our core experience to as many people as possible.

For the last 3 years I’ve been developing on the Flash Platform all day, every day. I’ve designed and built a flexible game architecture, a large and complex web application, and many games and apps for clients such as MTV, Paramount, Disney, Mattel and Hasbro. Me, myself and I programmed every single line of code. Millions of people have played these games and used these apps, and tens of thousands of games/levels have been made with just our apps.

During those 3 short years, the Flash Platform has gone from v8 to v10, from ActionScript2 to ActionScript3, from purely interpreted to a modern, JIT’d virtual machine, from a vector-only renderer to a high-performance raster/bitblit renderer. We’ve gotten a declarative markup language for building apps, a high-quality UI framework, multiple free & commercial IDEs and an open-source compiler.

I can write an app for the Flash Platform, compiled with free, open-source tools using a free, open-source SDK, and it will run on Windows, OS X, Linux, Android and iPhone with zero changes. I don’t need anyone’s permission to do this, or anyone’s blessing. My app sinks or swims based on its quality, including not only the work I’ve done but the work I’m building on top of, the Flash Platform itself.

Amazingly, I could have done this 4 years ago with Flash. In fact, in 2006 I could have used a freely available compiler (mtasc) and free toolchain (swfmill) to produce a SWF that would still work today, unchanged on these platforms. But I digress…

I’m not alone in my experience: there are thousands of Flash developers out there building fantastic interactive content. Fantastic webapps like Picnik, Audiotool, Playcrafter and Balsamiq. Even more fantastic games like Canabalt, Machinarium and Club Treasure World. And about a hundred thousand more examples.

There’s something all of these examples have in common: their monetization and distribution are entirely within the control of their developers, and they are freely accessible by virtually any modern desktop computer. For me, this is the definition of an open platform.

Furthermore, many of these apps were built with freely available, open-source tools. They’re all published to a bytecode format that’s documented, well-defined and backwards compatible. They run on a player that’s freely available and is actively being maintained, improved and migrated to new platforms. For me, this is the definition of an open platform.

Flash has provided some unbelievable shoulders for me to stand on. I have used Flash to make my livelihood, to create my dreams and to share them with millions. I’ve used dozens of others languages and platforms over my last 20 years of programming, and none have done as much for me.

I support Flash. I’ll defend its role in the modern web. Flash is my platform.


14
Apr 10

Auto-sized Windows

I asked around last week if anybody had suggestions for how to make an <mx:Window/> auto-size itself to its content. The general opinion was to simply override the measure() method setting width and height to the measured width and height. Never quite worked out.

So, I’ve kind of obsessed about it this evening and put together a pretty solid solution. I think you AIR folks out there will be interested in it. Very handy. Set autoWidth and/or autoHeight to true to lock that dimension to the ideal (based on the measured children).


7
Apr 10

Invalidation Pattern

Jesse Freeman asked for advice:

I’m not a stupid person but prop injection is retarded. I need both vars set before calling apply -> http://twitpic.com/1dz5d9 #Advice

This comes up quite a bit in Mockingbird since hot-swapping dependencies while a game is running is our major differentiator. In practice, it’s often not necessary, but it definitely always make your code more complicated, more fragile and (inevitably) buggier.

If your class has (or ever could have) more than two hot-swappable dependencies, you need a proper invalidation model in order to scale to the dependencies. You can also potentially have a faster object by deferring, and thus aggregating, validations.

Here’s a quick example class I just wrote-up because code speaks louder than words. To keep things conversational, I typed it up in a text editor and haven’t actually tried to compile and run it, which probably means there are typos and stupid mistakes. But the point (and pattern) should hold.

If USE_DEFERRED_VALIDATION is true, validation will not occur immediately when a property changes. Instead, a flag will be set and on the next frame validation will happen. This allows you to set multiple dependencies during one frame and they’ll all be applied at once the next frame.

The classic game engine loop basically embodies this invalidation model with update() (which invalidates) and draw() (which validates).


2
Apr 10

Preloader Base Class

UPDATE: Thanks to the suggestions of Casey, I’ve updated the base class to use events from the loaderInfo instead of checking each frame, as well as using the frame label as the class name (which I believe is the idiom that Flex’s [Frame] metadata follows).

I reread the preloader post I made earlier today and it occurred to me I should make this an actual re-usable class. So, I did. Here’s the Preloader base class:

Usage is very straightforward. I made everything protected for easy sub-classing, but you shouldn’t have to override the event handlers, onProgress(), onComplete and onRemovePreloader().

As I discussed in my earlier article on the subject, you have to include a compiler argument to force your main application class to be loaded on a secondary frame. You do this using the -frame compiler argument like so: -frame frameLabel fullyQualifiedClassName.

To customize the preloader animation, override addPreloader(), updatePreloader() and removePreloader().

To create your main application class you can either pass the application class’s name into the constructor, e.g. super("com.mycompany.myapp.Application");, or you can use the class’s name as the frame label in the compiler argument, e.g. -frame com.mycompany.myapp.Application com.mycompany.myapp.Application. If you need to do something more specialized than just constructing your class and adding it to the stage, you can override createApplication().

Here’s an example of a preloader that displays progress as a percent in the top-left corner of the screen:


2
Apr 10

Minimal Preloader for AS3

Saw this post on preloaders today. I see a lot of similar examples. What I don’t like about any of them is the fact that they use the [Frame] metadata, which—as far as I can tell—requires you to use IFlexModuleFactory which means you have to bring in some minimal portion of the Flex SDK. That, I don’t like.

I’m not sure why Adobe dictated this in mxmlc, there’s no reason that [Frame] would require this to be implemented correctly. Unfortunately, they did, so we have to resort to using a compiler argument to get the result we want.

[Frame] metadata basically equates to the -frame compiler argument, but a little reversed. With [Frame] you specify which class should be placed in the frame previous to the class it decorates; with -frame, you specify which frame a class should appear on.

My standard preloader is named for the application’s SWF (so I don’t have to add any extra compiler arguments in Flex Builder), and once it finishes preloading it instantiates the actual application’s root class, which I normally name Application.

Because the application usually does some additional remote service calls and asset loading after the SWF completes, I don’t remove the preloader until it’s notified by the application that’s it’s ready. I use an event to do this so that there’s no hard-references either way.

This is an important point: whatever you reference in your preloader will be placed in the first frame of your SWF, so you have to be sure and not reference your application class (or really, any classes outside of the flash.* packages) statically. What you do is load them by name using getClassDefinition() once you’ve determined that the entire SWF has loaded.


31
Mar 10

Club Treasure World

Last week saw the launch of Club Treasure World, the latest project powered by Mockingbird. Built in collaboration with Aspyr over the last four months, it’s the biggest project yet using our game making tech.

I suggest visiting CTW to get the full run-down of what’s offered, but a quick description: CTW is place for kids (and adults!) to build their own games and “chat worlds” to share with their friends. Everything is built from treasures that folks can purchase through micro-transactions or earn using the Nintendo DS game Treasure World which Aspyr shipped last year.

CTW was the first project I used Robotlegs on. Even though we didn’t use it extensively—the other developer on the project was not familiar with dependency injection—it provided a nice solid architecture to jump off of. And due to its minimal nature, even when we weren’t leveraging it, it was never in the way.

While we were working on this project I also started several other smaller projects leveraging Robotlegs (none yet released) and have gradually refined my own workflow with it. I’m still a fan, though I’m quite curious about Swiz because it appears to be even more minimal, if that can be believed. I am completely sold on the idea of dependency injection and have started applying it to my API designs.

My latest Robotlegs project is also my first project to leverage Rob Penner’s excellent AS3 Signals. These two together have significantly cleaned up my code and are definitely quashing many of the architectural issues I ran into when developing the original Mockingbird app. In fact, I’m itching to go back and rebuild the whole app and site—not to add features but to clean up the codebase in such a way that it’d be ready for some rapid feature addition in the future. Robotlegs definitely provides a very agile framework.

For CTW we also used SmartFoxServer for the first time. In the end, I was less enthused about this choice. While it got us up and running really fast with it’s simple API and built-in chat functionality, it was a pain to develop with and debug, and I wouldn’t choose to use it again. The API originates from AS1/AS2, so there’s very little type safety and none of the current AS3 conventions. The documentation leaves out a huge amount of caveats present in the API that don’t necessarily make sense, even though it’s clear from the support forums that developer after developer encounter the same issue. The next time around I plan on using a more robust option, like ElectroServer, or possibly the still-in-alpha Union Platform.


24
Mar 10

Running Multiple Flex Builder Workspaces

Frustrated by the fact that you can only run a single Flex Builder workspace at-a-time? Well, I did a bit of digging and found several solutions (related to Eclipse, which is the basis for Flex Builder), best summed up in this Stack Overflow question: Open multiple Eclipse workspaces on the Mac.

I didn’t like popping open a Terminal window; and all of the options resulted in multiple instances of the Flex Builder app running, but they were indistinguishable from each other in the Dock or when task-switching. So, I figured out how to fix that.

First, create a copy of your Flex Builder.app. Fortunately (in this case), the app file references files located elsewhere, so it’s pretty small (a few hundred K), so you’re not duplicating the entire app (as you would be with most Mac apps).

Second, rename your copy to whatever you want to call it—I used the name of the workspace.

Third, right-click on the app and choose to Show Package Contents. In Info.plist, change the Eclipse key (which is an array) to include two additional strings (at the end), the first being “-data” and the second being the full path to your workspace, e.g. “/Users/troygilbert/Documents/Flex Builder Workspaces/Acme Dashboard/”.

Now edit MacOS/FlexBuilder.ini. Change the -Xdock:name option from “Flex Builder” to whatever you want the name to be in the Dock.

Last but not least, replace or edit the icons in Resources/flexbuilder.icns with icons of your choosing. Personally, I like to go to Icon Factory’s fine collection of freeware icons and find something whimsical (and memorable) to use. The Futurama icons are quite nice.

Now you can create a shortcut to your new app anywhere you want, or access it through your favorite app launcher, like Google Quick Search Box.


7
Sep 09

Events vs. Callbacks (revisited)

Just a follow-up on my post profiling events vs. callbacks. As pointed out in the comments, EventDispatcher will ignore successive calls to dispatchEvent() with the same Event object. Thus, you must allocate new objects for each dispatch.

So, just chop off the last few paragraphs of that post and go with the original point of the post: if you don’t need bubbling, you can get a significant speed-up by using callbacks.


3
Sep 09

Events vs. Callbacks

Before there were events, there were callbacks.

I remember finally grasping callbacks… it gave me a perspective on my code where different components could have an asynchronous conversation — you know, just like we do every day with email (and any other form of messaging).

Finally getting events, and in particular AS3′s event model, was a similar revelation. Components could be oblivious to each other, or even how far away they were from each other in the giant graph of your application, and still carryout a conversation of signaling and acknowledging various messages.

Of course, this isn’t new to anyone who learned to code in SmallTalk — which seems to be the language that nailed every good thing about OOP without tripping over any of the bad things. No surprise, it came out XEROX PARC. Damn, did those guys invent all of modern computing like 30 years ago?

Naturally, when we built Mockingbird we used events to notify the view of changes in the model. Very standard MVC stuff, folks have been doing it for decades. And like everyone doing it with AS3, we used the Flash Player’s native EventDispatcher class. In fact, since we were using the Flex Framework, we even used the [Bindable] tag to do all of the work for us.

Well, everything has a catch. And even though EventDispatcher is a native part of the Flash Player and an integral aspect of AS3 coding, it still has overhead that you may not need and can cut out by crafting your own solution.

Up front, let me say that premature optimization is the root of all evil. And by evil, I mean you’ll waste your time on it with no apparent benefit. The following information is really only useful if you’re dispatching tens of thousands of events per second. You’re probably not, or at least not very often. We were, but Mockingbird is a special case.

One thing bugged me about using EventDispatcher: it made a copy of my event every time I called dispatchEvent(). Now, my pesky lizard brain that I honed while working on the PS2 taught me that lots of little memory allocations every frame — in a garbage collected environment — is not the ideal for steady, consistent performance.

If EventDispatcher was a standard class we could hopefully just subclass it and try to plug in a pooled memory allocator or similar. But it’s native, so we can’t do that.

So, our only choice is to create our own event dispatching mechanism.

It’s actually not that hard, particularly if you don’t need features like bubbling or propagation control. We didn’t even need priorities as it was purely notification of change, usually to just one or two listeners. I ended up with a couple of methods for adding and removing functions to an array and a dispatch method that simply iterated through the array calling each function in turn (callbacks!).

And boy, did it work. Zero memory allocations. Even simplified the API compared to IEventDipsatcher. Here’s a quick performance test I built to show the benefits in a theoretical context.

Source | SWF

It runs 100,000 iterations on each test, and each iteration “dispatches” an Event object that has 3 registered listeners. I don’t time registrations, just the dispatch. The listeners are actually do-nothing functions, but since mxmlc doesn’t dead-strip empty functions the test should be representative.

On my machine, comparing dispatchEvent vs. a Function callback is 1275ms vs. 80ms. That means the callbacks are 15.9x faster. I didn’t test the memory usage, but there would be a significant difference there as well, which means eventually you’ll have to pay the garbage collector his timeslice, compounding the overall performance cost for your application.

Damn, I was proud of myself. I just found a 15.9x performance gain in an integral part of our technology that’s been a hotspot on the profiler since forever. So, I went and swapped all of our event dispatch code for callbacks, tweeted several times about my success, and patted myself on the back.

Then I started writing this blog post. And in the process of consolidating my thoughts and cleaning up my source code I had an idea.

What if EventDispatcher didn’t do any memory allocations? How much faster could it run?

You’re probably asking yourself, didn’t we already go over this a few paragraphs up? You can’t hook EventDispatcher‘s allocator. Or can we?

How does EventDispatcher allocate new instances of your custom events? It calls the clone() method, which you’re supposed to override if you need those clones to be typed as your custom event. The default clone() returns a new Event instance. How about a clone() that didn’t allocate any memory? What if we returned this?

Source | SWF

This performance test compares dispatchEvent with custom events that don’t allocate memory when cloned vs. Function callbacks. You can view it here.

Results? 7 ms vs. 83 ms That’s right, when you take the new out of dispatchEvent() it becomes 182x faster… 11.8x faster than a callback!

How fast is it? Well, the theoretical maximum speed for calling functions can be determined by inline the callbacks (instead of using an array of Functions, which have closure overhead). This runs around 2ms.

What does this mean? Well, it means that I need to go back and revert some of my commits from this afternoon. It also means you should check out your profiler and see if event dispatch is a hotspot for you, and if it is, try subbing in custom events that don’t allocate.

What do we lose by not allocating? No idea. I’ve not done that testing yet. Some suggested (based on the docs, I believe), that there’s something with EventDispatcher not being able to change the target property after an event has been dispatched, so it has to create a clone if you re-dispatch the event, but that just doesn’t make sense — I can’t think of an implementation that would require that or benefit from it. It could affect bubbling, not sure how though.

In the end, it may just be a safety measure to ensure that events can’t tamper with the original event before other events get a chance to consume it. Kinda like cloning a private array before returning it through a public method (for example, in collection classes). I’d be curious to know.

NOTE: My timings were done in the standalone Flash Player. Testing out this post I’m noticing that the numbers aren’t quite the same in the browser (not surprising).