Haxe Preloader – Back to Square One
(it’s going to be a rather long rant regarding the latest experiences with Haxe)
In the beginning, Haxe games couldn’t preload. What Flash IDE can do with a click (“export in frame 1″) and Flex can do with some lines of code, there was no way of doing it in Haxe. Truth is, in the beginning, there weren’t many tools to import assets (and you know…”assets are very important” 🙂 ). It was swfmill, that after several stormy updates felt into oblivion at v0.2.12, with a lot of loose ends, like missing wav and incomplete mp3 import (luckily, later solved later with a patch from Robin of Mindless Labs).
In any case, swfmill had support for splitting assets on multiple frames, but the resulted swf, imported through the “swf-lib” directive in Haxe only contained the first frame. While Nicolas, the maintainer of Haxe, promised support for this in 1.17, I believe that the issue was solved much-much later, in 2.01 release – almost a year later.
Meanwhile, feeble voices of game developers and whatnot asked for Haxe native preloader support on the mailing list. “We’ll investigate”, was always the answer, for the past 3 years.
Now, don’t get me wrong, I think Haxe is a great language and the maintainers of the project deserve lots of applause for their work (and donations and beer and whatever). It’s just I don’t understand why they were (and still are) so adamant to support a feature natively (for instance, the multiple “swf-lib” support enhanced with an additional parameter to set the frame?), given that the competing solutions from Adobe are at the finger tip, even for a rookie programmer.
So, even with the very rough interaction between Haxe pre-2.01 and the resources, there were some “primal” solutions for preloading. One outlined here and another that involved using a Flex preloader, details here (basically, loading the final swf in a Flex application), both being painfully awkward. Creative, in a hacker-ish way, nonetheless, but awkward.
That’s why my first games (Ninjas!, That Word Game and Orbital Decay) didn’t had a preloader. They were fairly small, to start of, around 1Mb, so a preloader wasn’t a must, and my patience is very short when I have to do all kind of hacks and workarounds to make a simple feature work. Did it in the old days for other projects, but it’s simply not my style, especially when the focus is game development, not hacking tools.
About one year ago, Mindless Labs released SamHaxe, a tool similar to swfmill, but a bit more evolved, and more helpful with the documentation department for the dummies. With the multi-frame swf-lib import now fixed in Haxe, doing a preloader was now a breeze – exemple is always here. Born of Fire TD was my first game and all the games developed later employed the same method.
Well, so here comes Haxe 2.06. One day, I was checking the download section and “hey! they released a new build! cool! let’s install and roll out!”. So, I modified the build path to point to the new Haxe, compiled and run the project. Well, surprise! No flying pigs moving on the screen. I shrugged and reverted to the old and trusty Haxe 2.05, where my flying pigs could do the flying that amazes the world.
I wasn’t even going to write this, but I hit a nasty wall with Haxe 2.05. “Error: Buffer.add: cannot grow buffer”. Wait, what?!? My flying pigs grew pretty large (what would you expect from a pig anyway?) and produced a binary asset of 15Mb, that imported through a SamHaxe bin:binary caused Haxe to panic and bail out nervously. I found it funny that someone apparently put a size check on a buffer and, in the age of the 2Tb hard-drives, the limit was set to 15Mb. Now, not to worry, compressed swf is about 4Mb, that binary compressed well, that’s for the people that will cry “a Flash game of 15Mb? That’s preposterous!”
So, apparently it was time to leave the comfy Haxe 2.05 and venture in the wild with the new versions. First thing, if you put a “-swf-header” directive, Haxe fails to import a multi-frame swf-lib – some details here. The solution: SamHaxe now has support for w, h and fps for the asset library, but in order to get this feature, you have to build SamHaxe from sources 🙂
Then, a SamHaxe bin:binary is imported incorrectly by Haxe, missing 4 bytes – bug here. Which left me with the only option to use a Haxe nightly build, in hopes that those issues above will be fixed. The second was fixed, the first, I don’t know, but probably not, but since there’s a workaround, it doesn’t matter.
To summarize, the preloader now works without any hacks (like using SamHaxe as a “linker” tool, to inject the code in the assets instead as the normal method), as in the previous Haxe 2.05, in the following setup:
- Haxe nightly build r3435 (November, 25th), probably later versions work too;
- SamHaxe build from sources from the SVN (r27);
- “-swf-header” directive removed from the Haxe command line/build file and w, h, and fps properties set for the shx:resources element;
- also, please note that some swf:swf or swf:library may break the build (make it from 2-frames to 1-frame), for unknown reasons. The workaround for this is to import the swf library as multiple “swf-lib” directives, if the swf is code-only (like, for instance, the Mochi API), otherwise you might get strange results.