| 
          	   What is a Flash Game? 
              Say we decide to use Flash. We now have a bunch of MP3,  SWF, and XML files. What’s next? We need to be able to play these back somehow,  which means using the Flash Player. But it’s missing features such as  fullscreen mode, support for right-click, and reading and writing save games.  Plus our SWF’s, being an open format, are easily reversible, so we’d like to  protect our intellectual property with some encryption or at least obfuscation. 
              Macromedia has a program to license source to the Player, which  would let us add the features we need, but this is meant more for hardware  manufacturers looking to port Flash to their platforms (cell phones, set-top  boxes, kiosks, etc.). It’s not a very game developer-friendly program – they  want about $150,000 for the source, and royalties on top of that. This is  ridiculous compared to what that would buy us in the 3D commercial engine  space. So we can forget about licensing Flash’s source. 
              There have been several efforts to clean-room engineer a  Flash Player, but nearly all have fizzled out. One that continues to see  regular updates is gameswf, contained in Thatcher Ulrich’s public domain  tu-testbed project over at SourceForge. Unfortunately, while gameswf looks  extremely promising, it is OpenGL-based, and this won’t work for us. 
              So we’re stuck with the Flash OCX. We have a couple  options here. Either build a host application in C++ that adds in the features  that are missing, or buy one off the shelf. Putting together a host for Flash  is not a trivial amount of work. We created one at Oberon using C++ and ATL 7  that adds fullscreen mode, right click handling, crash detection and reporting,  support for JPEG2000 graphics, OGG and OXM playback through the FMOD library,  encryption, save game reading/writing, splash screens, Flash embedding, and a  bunch of other features, in a very small package. Flash can communicate with  its host using async COM events in one direction, and in the other direction,  perform direct variable setting/getting or function calls. This can be used to  add support for any operation that Flash doesn’t support natively. For example,  the OCX host application would subscribe to the fscommand event, and  respond to fscommand( “fullscreen”, “true” ) to do its resolution  changing. Macromedia has documentation on this available here: 
              http://www.macromedia.com/cfusion/knowledgebase/index.cfm?id=tn_12059 
              COM events are async, which means the SWF will not be able  to call a function like fscommand( “getComputerName” ) and expect to  wait for a response. Flash will continue executing, and the request will not  get posted to the hosting application until after some time has passed. To deal  with this, we must use a sequence where the SWF makes a request, then goes  about its business until the host app has a chance to receive and process the  request, and then set a variable in the SWF with the results. The SWF will have  to notice this independently (probably by a “watch” on the variable – a great  ActionScript feature), and be able to handle the time in between. This can be  annoying, but Flash developers should be accustomed to programming  asynchronously – everything from loading a SWF to a JPEG to getting data from a  TCP socket is all done asynchronously. 
              There are also some off-the-shelf packages available, such  as SWF Studio from Northcode, and mProjector from ScreenTime (Google for “SWF  to EXE” to find all of them). These have varying sets of features, and may  include scripting and the ability to make plugins in C++ to extend the system  further. As they are general purpose tools, they tend to add a lot to the size  of the EXE. They will usually package the SWF’s and other support files in with  the EXE, along with the Flash OCX itself, to help prevent reverse engineering.  Recently these types of tools have also been adding save-as-Mac EXE support.  And at least one of them has managed to fix the async COM event problem, where  the Flash app really can call out synchronously to its host to get information.  These tools are always royalty-free and so cheap that they’re essentially free,  and worth checking out. 
              So here are the pieces in our game: the “projector” EXE,  the Flash Player OCX, and the content in SWF’s, XML files, and other resource  formats. This can be distributed royalty-free – Macromedia basically only requires  some minor logo placement when we use their Player. Be sure to check the  license agreement for all the details. 
              Developing with Flash
            What’s different about developing for Flash than a roll-our-own  engine? For artists, it’s about the same. Make art in Photoshop and check it  into source control – Flash can import a variety of formats, including PSD. For  audio, hand off MP3’s to Flash, or give it WAV’s and let Flash do the  compression itself. Of course, Flash is much more flexible in that it’s easy to  find artists with Flash animation experience for contract or full time work. We  can simply have them make SWF’s and integrate that directly into the game via loadMovie() or dragging and dropping the SWF onto the stage or into a symbol. Or they can  edit our FLA’s directly, if they’re careful. Audio engineers can do the same  thing, if sequencing audio into animations. 
              The real difference with using Flash comes with assembling  the game – the work our content engineers will do. 
              Setting Up for Debugging
              Flash is an extremely tolerant platform. It will  accept and silently ignore any error. This understandably sounds harsh to C++  or C# programmers accustomed to crashes or exceptions, but we’ve all been to  web sites that have put up annoying modal JavaScript errors, or other problems  resulting from bad programming. Macromedia understood that not everyone coding  Flash tests their work thoroughly, and that most of the problems that result can  be ignored to avoid ruining the user experience. So they only permitted two  types of errors to throw up a system dialog: an infinite recursion (greater  than x levels of call stack), or a code hang (greater than x seconds of code  execution without returning to the system). In either case, Flash will put up a  dialog. In all other cases, whether a function call is spelled wrong, or a  member is accessed on an object instance that doesn’t exist, Flash ignores  it. This is great for the web experience, but is horrible for development.  Important exception: the compiler will catch it, but only when using classes  and strongly typed variables – more on this in a little bit. 
              To help work around this, we need to configure the system  to use the debug Player. This involves the following steps: 
              
                - Exit  all browsers and the Flash IDE.
 
                - Download  the uninstaller at:
 
                     
                    http://www.macromedia.com/cfusion/knowledgebase/index.cfm?id=tn_14157 
                     
  …and run it. 
                - Install  the Debug Player found at C:\Program Files\Macromedia\Flash MX  2004\Players\Debug. This can be verified by going to any site with Flash on it  (such as the banner on the top of  www.macromedia.com)  and right-clicking on it. If there is a “Debugger” grayed out in the menu, then  the debug version is installed. This menu selection doesn’t do anything except  show that the Debug version is installed (i.e. it’s always grayed out).
 
                - Create  a file mm.cfg in C:\Documents and Settings\(username) containing:
 
                     
                    TraceOutputFileEnable=1 
                      ErrorReportingEnable=1 
                      MaxWarnings=0 
               
              Now, when any errors occur that are caused by accessing  runtime members that don’t exist, or if a trace() is called, Flash will  output to the flashlog.txt file in C:\Documents and Settings\(username).  This can be watched during development with a tail program. If using MX  components, it’s best to filter tail through a grep that removes  all the errors that the components cause (those components are not exactly  “clean”). 
              Next, we’ll need to add the development tools that any game  engine would require – a console, logging features, error reporting, and  assertions. Note: Flash has no concept of a modal dialog that is callable from  code, so asserts that stop the game are not possible. The trick to work around  this (assuming we really want to make sure the game stops executing when  something bad happens) is to just go into an infinite recursion. Flash will  instantly put up a dialog that testers can catch, and the game screen will  still be in the state it was at the time of the failure, for a screen shot. 
              Finally, when we code, we need to make sure to do  everything in classes using private access protection when necessary, and use  ActionScript 2.0 with strongly typed variables, parameters, and return types on  methods. Without classes and strongly typed variables, we don't get any type  safety at all – Flash reverts to ActionScript 1.0 mode which will  tolerate pretty much anything it tries to compile. But when using them, the  compiler will catch almost all of the errors for us. In practice, it’s really  only necessary to tail flashlog.txt when something bizarre is happening  in the code that makes no sense. More often than not, it’s a typo. 
              In order for the strong typing to really work, we need to  modify the factory-installed Flash class stubs. The type safety feature of  ActionScript 2.0 is disabled on a per-class basis by the “dynamic” tag attached  to the class. Macromedia apparently did this in Flash MX 2004 for backwards  compatibility. So in order to maximize our chances at finding errors, we need  to go through every one of the .as files shipped with Flash and remove the “dynamic”  keyword, then fix all the errors that come up from that (as mentioned before,  Flash ships with unclean classes). These classes are found in an obscure  location – deep breath – 
              C:\Documents and Settings\(username)\Local  Settings\Application Data\Macromedia\Flash MX 2004\en\Configuration\Classes 
              It’s best to take this whole folder (minus the ‘aso’  subfolder, which is for intermediate object files), check it into version  control in a standard location, and delete it from its original goofy location.  Then update Flash’s global classpath settings to point to the location  mapped by version control for these files. This is similar to what we would do  with Visual Studio for include or lib paths. Then go through the  .as files one by one, removing “dynamic” from each, except for the Function  class, which really needs to keep its dynamic tag otherwise many things in  Flash will break. 
              Note: many of the MX components will throw up a lot of  compile errors if used with this classpath. At Oberon, we don’t use components  except for prototyping, because they are so heavyweight, slow, and difficult to  skin how we like. So in our projects that use the components that throw errors,  we simply set the classpath for each project to point at an unmodified classes  folder. It’s not the best solution, but then again, MX components are evil. 
              Organization
            Here are some tricks to help keep Flash projects  organized, under control, source control friendly, and team friendly. 
              
                - Use .as (AS2 class) and .asi (#include from FLA) files as  much as possible. Keep all code out of the FLA files, other than the one- or  two-liners. Because FLA files are binary, they end up getting exclusive-locked  in source control, plus they cannot be diff’d for changes. Developers will end  up fighting over who gets to keep the FLA checked out when only code changes  are required. If the code is #include’d, or stored in classes (.as  files), then this problem is avoided.
 
                - Ok, well avoid using .asi files too. They are a necessary evil in  just a few cases where classes can’t be attached to objects (such as startup  code for the root timeline). Flash compiles them as AS1 code, so they will not  be typesafe and can have easy errors creep in. It might even be better to take  all that code and store it in a class as a static function, then call that  function from where the #include would normally be.
 
                - Use externally shared FLA’s for “content” art, broken down by  content type (game board pieces and animations, cut scenes, etc.). This will  permit art integrators, or perhaps artists, to work on FLA’s without affecting  code, layout, or running into exclusive-lock problems with other developers. It  also helps with keeping large FLA’s under control. Whether or not this is  necessary really depends on the project size and team dynamics.
 
                - Keep everything off the main timeline in the core FLA, and work  exclusively in symbols. Symbols are the most powerful concept in Flash.
 
                - Keep data in external XML files. Audio can go in external MP3  files, if it’s more convenient that way (it certainly speeds publishing up).
 
               
              Flash Performance
              In this paper so far we’ve covered many disadvantages of the  Flash platform, nearly all of which are fairly minor and can be worked around.  Flash is like any platform, with its own list of weird quirks and annoying  features and bugs. However, there is one major problem that deserves its own  section: performance. 
              ActionScript can be very slow. Bytecode execution is ok, probably  on par with other scripting languages, but there is a significant problem with  entry points. Setting up the execution context to call into the virtual machine  and tearing it down again after a function exits is extremely expensive. Less  expensive, but still significant, is a script-to-script function call. 
              Optimizing ActionScript is straightforward: 
              
                - Minimize entry points into the code. For example, use a  traditional game main loop rather than a lot of onEnterFrames attached  to MovieClip-derived classes for every game object on the screen.
 
                - Profile, profile, profile. Nothing shows what’s slow like ASProf  (see Flash Resources at the end of this paper).
 
                - Manually inline functions when necessary. When in inner loops, use  local variables, which are specifically optimized in “registers”, instead of  global variables.
 
                - Publish for Flash 7, which is much faster than Flash 6 (mostly  due to the “registers”).
 
                - Scan the blogs and mailing list archives for tips on optimizing  ActionScript performance. There are many tricks out there, too many to cover  here, but this site gathers a lot of analysis and links in one place:
 
                     
                    http://www.oddhammer.com/actionscriptperformance/old_index.htm 
                     
                  Note that many of these may be out of date due to Flash 7 and need re-testing. 
               
              Worse than scripting performance is graphics performance.  Flash is basically a 2D rasterizer in software with zero caching other than on  the primary surface. Each bitmap being rendered is actually a textured fill of  a four-sided shape, rendered through a generic rasterizer. It’s very pretty,  but can be very slow. Little work is apparently done inside the Player to  optimize for bitmaps on integral coordinates with an identity texture  transform. There is a dirty rectangle system that works fairly well, but it is  spoiled by a final step in the renderer that unions all the dirty rectangles  together for the final update area. This means that on a screen with a lot of  detail, a flashing icon in one corner of the screen, with the gameplay action  in the other corner, causes the entire screen to be redrawn each time the icon  changes. There is also overhead in maintaining each graphical object on the  screen, and managing it as part of the display list. 
              Optimizing graphics is also straightforward, although it  may not be very appealing: 
              
                - Avoid making action games where the whole screen is scrolling.  Feeding Frenzy is a great example of something not to attempt in Flash.
 
                - Minimize the number of objects onscreen at once.
 
                - Avoid UI designs that have animated indicators at the edge of the  screen. These will expand the final union size for dirty rectangle rendering,  increasing the update cost.
 
                - Avoid large full-screen effects unless the screen is very simple  (such as on a rewards screen). If possible, downshift the quality temporarily  while a large full-screen effect is playing.
 
                - Target frame rates for 16 or 20 fps. A consistent frame rate  feels much better than a high frame rate, and it reduces the per-frame overhead  that Flash incurs from maintaining its objects.
 
                - Use lower resolutions – the graphics problem only really kicks in  at higher resolutions. For web resolutions, we can get away with pretty much anything.  At 800x600 though, the pixel throughput of Flash really starts to hurt.
 
                - If an animated object needs to be hidden, remove it from the  screen instead of setting its _visible member to false. An  invisible animating object still (inexplicably) dirties the screen.
 
               
              There’s really no way around it. Flash is not designed for  fast paced full-screen animated graphics of any complexity, but with careful  optimization and some modifications to the game design we can still make it  work for us. 
              Odds and Ends
              This section is for whatever didn’t fit anywhere else in  the paper. (I always seem to have one of these.) 
              Tricks
              Useful random tricks: 
              
                - ActionScript 2 and JScript.NET are 99% the same. The Oberon  multiplayer platform (one of its installations is at http://arcade.icq.com/multi.htm) has  a feature on the server that lets it use JScript.NET or C# for the server  script. So we can take a common rule set that needs to be implemented on both  the client and the server (say a chess game, which has complicated rules), put  it in a common class, and have both the FLA and the server both reference the  class. JScript.NET even has some nice features to let us /*@if ( XYZ ) */ out code  so Flash doesn't see some code, but the server does, or the other way around. For  a complicated piece of code that is difficult to debug in Flash (perhaps a  level generator, or pathfinder), we could throw together a quick JScript.NET  front end to it, get it debugged and working via Visual Studio, then switch  back to Flash, which can use it immediately.
 
                - It is possible, although it can be messy, to diff a FLA by  publishing the old and new versions to SWF’s, then using KineticFusion (see  Flash Resources at the end of this paper) to convert the SWF’s to XML, and  diffing the XML files. This can be useful when trying to figure out exactly  what changed in a FLA from one version to another, such as when that weird bug  was introduced a couple weeks ago in version #27 that just got discovered, and the  engineer who checked it in (who will surely be punished) used “made some fixes”  in the check-in notes. The “fixes” could be anywhere. With standalone .as files  it’s simple to diff the history, but with binary FLA files it’s impossible. The    FLA-to-XML conversion makes it possible.
 
                - Flash renders at a variable frame rate if streaming sound is not  playing. Every single frame in an animation sequence is guaranteed to be  played. This means that if the system gets bogged down with a lot of script or  expensive graphics, the game will appear to slow down as well. For gameplay  controlled by code, this won’t be a problem, because the code will be  time-based rather than frame-based. However, it will affect animations created  using the Flash IDE. The solution to this is to write a “frame advancer” that  takes over responsibility of advancing frames from Flash. It will simply check  what time it is, and decide which frame to gotoAndStop() to based on the  delta since the last check (divided into the target frame rate). When using a  frame advancer, be careful not to skip past frames that have code attached to  them that needs to run.
 
                - Any object placed in the Flash authoring tool receives a negative  depth. When Flash goes to another frame, it will only destroy objects that do  not exist on the new frame, but only if they have a negative depth. This means  that objects created in code will stay around forever unless also removed by  the code. It also means that in order to destroy objects that were placed in  the authoring tool, it must be moved to a positive depth first.
 
               
              Traps
              Here are some things to watch out for during development: 
              
                - When odd compile or runtime errors are coming up that make no  sense, before spending an hour debugging it, try deleting the ASO cache files.  These are to .as files what .obj files are to .cpp files – temporary object  files that Flash creates in the process of compiling. Unfortunately, they  apparently only perform a basic greater-than test on file timestamps, so reverting  an .as file in source control will not get noticed by Flash, and not get  recompiled, which can result in results that turn hair gray. The solution is to  just delete all the ASO’s. Mike Chambers makes this easy with his “Clear ASO  Cache” command, available here:
 
                     
                  http://www.markme.com/mesh/archives/005686.cfm 
                - Classes have a limit of 32,000 bytes, because of the way  Macromedia had to shoehorn AS2 into an AS1 bytecode Player. Avoid making  gigantic, monolithic classes – keeping them under 1500 lines should be safe. At  Oberon we’ve run into this problem when creating our “Constants” classes, which  we use to store fake enums etc. – we usually just divide the constants down  into multiple classes to deal with this.
 
                - Fonts in Flash are rendered very poorly at small sizes (under 12  points or so) and can look fuzzy or jagged. If using a font that is pretty much  guaranteed to be installed on the system (such as Arial) then it’s possible to  cheat by not embedding the font glyphs, and instead rendering the text as a  “device font”. This lets the operating system render the font instead, and has  the advantage of using the OS’s antialiasing (in Windows’ case, that may mean  ClearType).
 
                - There is a 12-layer alpha limit – after 12 images are overlapping  with alpha channels, Flash stops rendering the layers underneath. This is  enough objects on top of each other that it usually shouldn’t be a problem, but  it did come up in our testing and is a known issue.
 
                - Flash renders the edges of images it imports very poorly sometimes.  A thorough explanation of the problem and its very simple workaround is  detailed here:
 
                     
                  http://www.fatorcaos.com.br/flashimagebug/ 
                - It’s easy to get collisions between classes (which are installed  into the global namespace), global variables, and instances on the timeline. It  saves a lot of debugging time to simply name things with a convention based on  scope. At Oberon our standard is to prefix class names with a ‘C’, and member  variables or instances on the timeline with an underscore. That’s been enough  to prevent collisions so far. It also avoids problems when publishing as Flash  6. For example, this code, while fine in Flash 7, can wreak havoc in 6:
 
                   
                  var myClass :MyClass = new MyClass(); 
                - Long-running scripts can cause the dreaded “A script is running  slowly” dialog to pop up. This is incredibly unprofessional in a game, and if  the user hits “Yes” on the dialog, it will break the game, because it kills all  scripts from then on. For the downloadable version, it’s possible to set the  timeout before this dialog comes up by hacking the SWF. Better still, though,  is to simply make sure that any functions that could run long are iterative. A  level generation function will need to return back to the system every once in  a while so Flash doesn’t think that it has hung. Remember that there are  machines of all kinds out there – have such a function return to Flash no later  than half a second per increment, just to be safe.
 
                - Avoid MX Components. They are tempting to use, because they can  just be dropped right in and we can start working right away, but unfortunately  they have a lot of problems: they are enormous in bytecode size, extremely slow  to render, cause focus issues, and do other odd things like install “managers”  at high numbered depths on _root. Plus they’re very difficult to skin. Instead,  make a simple button class, an edit box, etc. – it’s takes five minutes to do  in Flash.
 
               
              Finally, here is a special note to people intending to use  Flash on a console: you may be able to get what you need from gameswf, but  forget about writing your own Player from scratch that can process SWF’s. It’s  an enormous task – a lot more complicated than just drawing some  triangles or interpreting some bytecode. Look into using GameFace from Anark  instead. This product is currently in beta testing but looks to be a great  Flash-in-3D. 
              Flash in the Future
            There is a new version of Flash that Macromedia has been  demonstrating at user group meetings, and at their conferences, supposedly  entering beta soon (as of this writing). The new version is Flash 8, and it  looks like it could really solve a lot of the performance problems mentioned in  this paper, in addition to adding a lot of impressive new features.  
              On the performance front, supposedly the new ActionScript  interpreter is much faster. But more importantly, they have added “bitmap  caching”, which should solve many of the graphics related performance issues  we’ve run into. Normally, Flash does a full render of anything on the screen  that has changed, clipped to the dirty rectangle. With bitmap caching, we can  have Flash cache a render for a MovieClip into a bitmap, rather than  re-rendering the same pixels over and over. 
              As for new features, they are adding advanced pixel shaders  (although still rendered in software) like glow, shadow, and blur. And they are  fixing the font rendering problem, adding ClearType quality font rendering called  “Saffron” that also includes hinting for rendering small fonts properly. 
              Conclusion
              Let’s see how Flash stacks up to our original  requirements: 
              
                - The executable code must be small. The Oberon host  application plus Flash’s OCX adds up to about 1.1 megs, compressing down to  829K. Not great, but not bad, considering all the toys in there. Grade: B.
 
                - The content must be small. Flash supports JPG and MP3, and  its bytecode is tight enough to be negligible in comparison to the bitmaps and  audio. We’re good to go. Our Oberon Flash host application adds support for  JPEG2000, OGG, and OXM (Ogg-compressed .xm format), all of which are even  smaller. Grade: A.
 
                - We’ve got to grab players’ attention. Flash is an  excellent animation tool. With the right talent we can really grab people,  although we need to be very careful about doing large full screen effects. Grade:  B+.
 
                - The engine needs to avoid fancy API’s that probably don’t  exist on the client machines. Flash runs on a default install of Win95, so  it’s up to the host application to limit its API use, which isn’t difficult.  Grade: A.
 
                - Performance is a huge concern. This is the worst problem  with Flash, and it gets a C here. Although while we can’t bet on Flash 8’s  release date, it looks like we may be able to bump this up to a B in a few  months.
 
                - The toolset needs to support rapid iteration. This is  perhaps the most powerful ability Flash gives us. Grade: A+.
 
                - We’re going to want to make a web version of the game as a  teaser. The route to a web game from a deluxe game (or the other way  around) is clear and direct in Flash. Grade: A.
 
               
              At Oberon in Seattle, we’ve developed and shipped two  successful downloadable Flash games (Betrapped! and A Series of  Unfortunate Events) plus online web versions, a multi-thousand-user real-time  multiplayer system that uses Flash and UDP on the client, and are working on  additional Flash-based downloadable and web games to ship this year. 
              Flash has been a great experience for us. As described in  this paper, it has a number of pro’s and con’s. We’ve worked around nearly all  of the disadvantages, which have turned out to be minor in practice, and we  would expect similar issues with any other platform we were to choose. The  biggest disadvantage with Flash is of course CPU usage, which is a challenge,  but we still think it’s worth fighting through. At the moment we’re betting on  Flash 8 to give us the performance boost we need, but if that doesn’t work out,  we may have to consider alternatives such as Torque 2D for our more action  style fast paced games, and continue to use Flash for the slower paced games.  And even if we weren’t using Flash as our primary development platform, we’ll  still use it as a rapid prototyping tool to get us through the first couple  stages of preproduction. Nothing beats being able to create an entire game  prototype in a few days. 
              Flash Resources
              Flash has an enormous community, with people of all skill  levels, from many backgrounds. These aren’t just amateur web designers messing  around with a few buttons and animations for a silly menu navigation bar. The  heavy hitters in the community tend to be involved in “rich” client enterprise  applications, and frequently have backgrounds in C# or Java. 
              Here are key resources for any Flash developer: 
              
                - Fullasagoog’s RSS feed. Available at http://www.fullasagoog.com/feeds.cfm,  this is an aggregator for all of the best Flash related blogs out there, and has  valuable information popping up daily. This is the One True RSS Feed that  everyone should subscribe to.
 
                - Any book by Colin Moock. His latest is Essential  ActionScript 2.0 – anyone coding with Flash must stop what they are doing,  and buy this book.
 
                - Extending Macromedia Flash MX 2004 by Keith Peters and  Todd Yard. Writing JSFL? Automating common Flash tasks? Building custom  panels and extending the IDE? This is the book to buy.
 
                - The FlashCoders mailing list. Every question about Flash  has been asked here, and answered here, many many times. All known bugs have  been analyzed, discussed, and worked around. The mailing list carries extremely  heavy traffic, but that’s what the archive search is for. It’s available at http://chattyfig.figleaf.com/mailman/listinfo/flashcoders.  This archive contains or links to everything ever written on Flash that  matters.
 
               
              At Oberon, the tools we use that really speed up  development are: 
              
                - PrimalScript by Sapien (www.sapien.com).  The text editor that does IntelliSense with ActionScript, mentioned previously  in this paper.
 
                - ActionScript Viewer by Burak Kalayci (http://www.buraks.com/asv/). There  are probably ten great decompilers for SWF’s out there right now, but this is  the one we use at Oberon. It can reverse engineer all classes used in a SWF,  and does a pretty decent job of naming variables. This tool is really useful  for figuring out “how did they do that?” when visiting a site that shows off  some interesting effect in Flash.
 
                - Flash Resource Manager by Mike Chambers (http://www.markme.com/mesh/archives/004700.cfm).  Already mentioned earlier in this paper, this is a critical tool.
 
                - KineticFusion by Kinesis Software (http://www.kinesissoftware.com/index.php).  This tool can roundtrip a SWF to/from XML, which can really aid in automation  during the build process, or for making tweaks to a SWF after it’s made without  needing to recompile (such as to change its frame rate, or alter some code).
 
                - AdminTool by AcmeWebWorks (http://acmewebworks.typepad.com/admintool/).  This is a remote debugging tool for Flash in two parts – the admin interface (a  standalone program), and a component that goes onto the stage in the SWF for  communication with the admin interface. This tool can walk the object  hierarchy, take snapshots for inspection, execute code in the SWF, control  objects in the SWF, gather traces, and much more. Nobody should develop for Flash  without this tool.
 
                - ASProf by David Chang (http://www.nochump.com/asprof/).  This is a real-time profiling library that can dynamically hook different parts  of the code and collect execution times, delivering the results in a table  format. Required for optimizing ActionScript.
 
                              |