Here at Demiurge, like many other studios, we use Flash for authoring our UI. Marvel Puzzle Quest, being a 2D game and functionally acting like a series of UI screens, has almost 100% of its content created in Flash. While Flash has a lot of nice features that allow our developers to easily author, layout, and animate our UI screens, it also has its fair share of issues. Recently we ran into a fairly sneaky one with some very noticeable consequences.
For a couple of releases in a row, we would be wrapping up work on the next update for Marvel Puzzle Quest and like clockwork, on the last day, at least one of our files would start hanging Flash when we tried opening it. Since we couldn’t actually open those files, we couldn’t fix that version of it. On top of that, we couldn’t easily see what state it was in which was causing Flash to hang. The artists would have to (take a deep breath) grab an earlier version of the file and redo the work.
Eventually we noticed a pattern. The files that had these problems always had copies of our fonts in their library before the last fatal change was made. But where were the copies coming from? We knew of another issue where duplicate assets can sometimes get created when external content that is linked-in for authortime sharing gets updated in the source file (annoying, but not show-stopping). However, when Flash does that, it always added “ copy” to the end of the name of the asset so it would be a unique asset in the library. Unlike the copies from imported assets explicitly marked with “ copy” in the name, the duplicated fonts we were seeing had the exact same name. They were also in the root folder of the library instead of the “Fonts” folder where we always keep our fonts. In fact, while editing a text box and selecting which font to use, two fonts with the same name show up in the list. Also, whether you select the first or second one listed, when opening the drop down again, it always showed the first one as being selected. It was as if Flash thought they were the same exact font.
With this info we were able to find some forum threads online which confirmed our suspicions and answered our questions. It turned out that what was happening in our case was Flash created the duplicate font when we duplicated a library asset which had at least 2 text boxes directly on the stage of that movie clip (as opposed to the text box being wrapped in another movie clip) using the same font. This wouldn’t happen if there was only 1 text box, and it wouldn’t happen if duplicating a parent movie clip containing a movie clip which itself had 2 text boxes on its stage. Pretty sneaky, but it gets worse; since we had our fonts in a separate folder, the duplicate font was silently and (seemingly) harmlessly added in the root folder of the library, and life went on. New assets were added and Flash was happy...for a time.
Since Flash considered these as the exact same font, when an external asset which used that font got brought in, either new or updating it for authortime sharing, Flash would hang trying to resolve which font (the one in the Fonts folder or the duplicated one in the root folder) that movie clip should be using. Same problem if you tried to duplicate yet another problem movie clip (with two text boxes). The fact that we had our fonts in a separate library folder made the hang happen later on, after the bad duplication had happened, which was why it always seemed to happen near the end of our release work. That, and the fact that the change that caused the screen to hang could be a change made to an external asset in a different file, made it hard to track down which modification actually caused the issue.
Unfortunately it turned out that Adobe only fixed the issue in Flash CC and we use Flash CS6, so we knew the problem, but we still needed a solution. To work around the problem we added a step to our build process which scans all our Flash source files looking for duplicate fonts.
To do this, we used a not so obvious fact (which is made more clear if you save the .fla file as a .xfl file) that a .fla file is really just a zipped directory containing a bunch of xml files (in CS5 and later). Specifically, there is a file called DOMDocument.xml which lists all of the library contents. So now our builder has a script which unzips our .fla files and, using a regex, searches for fonts with the same name in the library as described in DOMDocument.xml and promptly yells at us to resolve any conflicts. This way we catch the problem right when it’s created and no work has to be redone later on. Our artists can can now sleep easy.