This site is now just an archive over the rise and fall of Flash. The domain flashmagazine.com is available for sale
Login | Register

Odds and Ends

This section is for whatever didn't fit anywhere else in the paper. (I always seem to have one of these.)

By Scott Bilas, Oberon Media, Inc. 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 >>>

 

Next tutorial:
Flash Resources

Previous tutorial:
Flash Performance

Get new stories first

Click to follow us on Twitter!

 

Comments

No comments for this page.

Submit a comment

Only registered members can comment. Click here to login or here to register