Porting from HTML5 to Haxe: the Whys and the Hows

Written by jan on. Posted in Development

What follows is technical mumbo-jumbo for licensed geeks. Meanwhile, the rest of you could play our beta! :-)

Technically, our game Together Alone has a bit of a weird history. “Normal” casual/web games usually start out as Flash. Then, if the game is succesful and the creator wants to target multiple platforms, she may port it to Haxe/NME. The language Haxe is very similar to ActionScript and NME reimplements the Flash API, so porting is relatively easy. Together, Haxe and NME allow you to target not only Flash but also HTML5, Windows, Mac, iOS or Android.

However, we started with a HTML5 game, mainly because I didn’t know Flash at the time and was interested to see how much of the HTML5 hype was true. Turns out, quite a lot, but not all of it. Yes, it’s pretty amazing what you can do in a plain old web browser these days (Mozilla recently issued some impressive WebGL demos, for example), but getting your game to run smoothly (in all browsers) is still a royal PITA, mainly because of garbage collection pauses. I’m sure it will continue to get better though.

So, I decided to go with Haxe and NME, for maximum platform-agnosticism. As I said, I did not have any experience developing with Flash, so I had to learn both Haxe and the Flash API. Haxe is documented pretty well. The NME site has some nice tutorials and samples to get you started. Of course, it’s basically the Flash API, so for reference documentation and other stuff, there’s heaps of information available on the web as well – just search for “ActionScript <classname>”, for example. Adobe’s official AS3 book helped me a lot too. All in all, finding information was not a problem for this project.

If you’re considering a similar porting job, here’s some details. There are two big jobs to do when porting from HTML5 to Haxe/NME: translating from Javascript to Haxe, and translating from the HTML Canvas API to Flash.

The first is not that hard, but a bit of work. You need a good text editor with regular expression search and replace, or a full-fledged IDE (FlashDevelop is highly recommended: Haxe is supported) with same. Search and replace will help a lot, but it can’t do everything.

Most importantly, in Javascript, there are several approaches to faking classes, none of which are ideal in my opinion. Haxe on the other hand has a conventional class system. Translating you particular way of doing fake classes to real classes can be a chore.

Also, Haxe typing is much stricter in Javascript’s (which isn’t saying much :-), so you have to add types. The upside is that this forced me to fix ugly hacks and outright bugs that were in my Javascript version. This once again proves that, when working in Javascript (or any other really ‘loose’ language), just because you can change everything at runtime (add fields, change methods of objects, etc.), doing so is not necessarily a good idea. Tricks like these tend to lead to hard to maintain code. Also, it defeats most Javascript optimizations, according to several experts.

All in all, the language Haxe is nice to work with; while I’m comfortable developing significant chunks of code in Javascript, I much prefer the optional static typing of Haxe.

The other big thing was going from canvas to the Flash API. This can be quite a lot of work, depending on how you work with canvas. I think many people use canvas in ‘immediate mode’: they have a render function that’s called every frame and explicitly draws each object. Flash is more a ‘retained mode’ library: you tell it what configuration of objects you want, where you want them, if you want translucency,  rotation, etc. and Flash manages and draws all those objects for you. In other words, it’s more like the HTML DOM than like a big canvas you explicitly draw on. Fortunately, I already built a simple version of this ‘retained mode’ approach for the HTML5 canvas, so for our game the switch was not as big as it could have been, but this is definitely a different way of thinking about how your game is rendered.

Haxe/NME delivers on its cross-platform promise for, say, about 95%. You will always run into some slight differences between the HTML5 target, the Flash target, and the native targets. Of course, this means at some point you’ll have to start debugging generated code, which is a concept with high nightmare-potential. But in this case, it’s not that bad actually. The Flash target you can simply debug as normal in FlashDevelop (stepping through your Haxe code while the Flash runtime is executing it), and the code generated for the HTML5 and C++ targets, while not particularly pretty, is easy to match up to your Haxe original, so you won’t get lost in an unintelligable sea of spaghetti.

The port is now done and the game is running great under Flash. The Windows target is pretty close behind, but the HTML5 target still needs work to get the game to run perfectly. That’ll take some fiddling, but I’m sure I’ll figure it out.

Final verdict: if you have a HTML5/Javascript (or Flash/ActionScript) game and you’d like to take it to Windows, iOS and beyond, you should give Haxe/NME some serious consideration!

    Tags: , , ,

    Trackback from your site.

    Comments (6)

    • @maddec303

      |

      >>” Flash is more a ‘retained mode’ library: you tell it what configuration of objects you want, where you want them, if you want translucency, rotation, etc. and Flash manages and draws all those objects for you.”<<
      This is if you use the classic way of displaying through the display list. But if you use Stage3D or an API like Starling (built on Stage3D), the functioning is similar to the one of html5 canvas.
      http://forum.starling-framework.org/

      Reply

      • jan

        |

        Okay, thanks, I’ll look into that! Is Starling available for Haxe as well, and if so, what targets does it support?

        Reply

        • Joshua Granick

          |

          When Adobe introduced better hardware acceleration support, they did so with a separate API, called “Stage3D”

          It is completely separate from the standard “display list” in Flash. The normal events, Sprites, Graphics and other objects you use cannot be mixed with “display3d” objects. Flash Player is traditionally a software-based renderer. This is clearly connected to a separate 3D rendering layer.

          Although NME uses the display list, like Flash’s software renderer, NME has a hardware renderer. As a result, without using Stage3D (or a pseudo display list API like Starling), applications are much faster:

          http://esdot.ca/site/2012/runnermark-scores-july-18-2012

          …this is on native platforms, of course. If you absolutely must have Stage3D for the browser, you can use Starling with NME and the Flash target only by running “haxelib install starling” to fetch it from haxelib, then adding to your project NMML file.

          There are multiple ways to render projects. In addition to display objects like Sprite and Bitmap, you can work with BitmapData directly (copyPixels) or you can use batch rendering calls in the Graphics class (drawTriangles, drawTiles)

          One of the faster ways to render in Flash Player is using the pixel-based BitmapData method. This translates well to how the Flash software renderer behaves. However, this is one of the slowest ways you can render when using GPU acceleration. While software works with pixels, hardware works with geometry and textures. That’s why the display list performs better with hardware acceleration, or why batch operations like drawTriangles or drawTiles can perform even faster.

          I agree that the use of display objects translates more closely to DOM objects with CSS transforms, while the use of BitmapData or performing a batch Graphics drawing command is more like canvas.

          If you like, I’ll be glad to help with anything I’ve mentioned above, or any other things you may be looking for :)

          Reply

          • jan

            |

            Ah, that’s enlightening, thanks! I’m actually pretty happy with the ‘retained mode’ approach, and the possibility of GPU acceleration is hard to pass up. But maybe I’ll look into the other options you mention in the future.

            Thanks for the offer to help out, maybe someday I will take you up on that. And I hope to be able to contribute something back to NME as well, it’s a great project.

            Reply

    • Johnny

      |

      Hi,
      nice to see more people interested in Haxe with HTML5!

      I recently used a library called Flambe for Haxe:
      github.com/aduros/flambe

      It is really useful to target both HTML5 and Flash and avoids packing nor using the flash namespace of NME. It is also really neat performance wise since it’s aiming GPU acceleration and ease of development.

      There is some drawbacks like too much private functions/vars on the animation utilities but it’s easily to overcome since you can extend private functions in Haxe. It’s also hard to keep the project portable with a modified lib since the Flambe python scripts need to be in the global Haxe library (I used command line symbolik link creation)

      Wish the developer had more time and ressource to get the project forward! (Actually I would like to get involved, but I’m no mathematical genius…)

      Reply

      • jan

        |

        Looks interesting, I’ll keep it in mind! Thanks!

        Reply

    Leave a comment

    CAPTCHA Image
    *