Earlier this year, we have finished porting our Action Script 3 codebase to Haxe. The codebase has been growing over the last couple of years (it started 2009, to be exact) and so we were very cautious if Haxe could deliver acceptable results, without nasty bugs that are hidden in the basement of that codebase forever unnoticed.
For the port we used AS3HX, a popular conversion tool, with a minor set of custom additions and fixes since we experienced some problems in our code with the default version. The whole process took a couple of months until all AS3 was replaced with Haxe and we were able to export our games from pure Haxe code. The first iteration of that port went live to all ours users at the end of February 2018 for web (Flash) and our mobile and desktop clients (with Air). Except for a couple of minor fixes that we had to add in the following weeks, everything went well and the team started to work on the HTML5 target at the end of March. From our initial tests it was already clear that even though we ported all codes to Haxe + OpenFL, a lot of refactoring would be needed to make HTML5 become a reality. In that sense, porting to Haxe while targeting Flash was easier, because the language changed, but the environment (Flash Player) was the same. This time, we had to replace the environment, and even worse, a couple of features hat we made heavy use of were not yet supported in OpenFL HTML5.
The Open Source nature of Haxe + OpenFL helped us a lot in the process, and we made a couple of fixes for problems or missing features we encountered. We also created pull requests to get our additions into the official builds, for example for MovieClip.buttonMode or blend modes during MovieClip animations. It took roughly six months until we were able to release the preview of the HTML5 builds to our players and we are currently evaluating feedback from our community to identify potential bugs and problems before we switch to HTML5 by default in the next months.
Here is a side by side comparison of the Flash and HTML5 versions at their current state:
Most prominently, we have replaced the font since the original font was looking blurry, especially when rendered in smaller sizes. We are also baking profile pictures on our server now, instead of masking them directly on the client, which means from now on all users will have squared avatars. (Previously we were supporting any dimensions of pictures). Some more details have changed, for example the alpha on “running games” has been removed for improved performance.
Other things that we plan to work on in future releases are filter effects (glows and drop shadows), removing blur on some of the textfields (this is likely a bug related to blendmode we intend to fix in OpenFL) and adding back our 3D ingame view. In the above example you can see that the filters on the dynamic text are still missing, since those are heavy on performance and sometimes produce undesired results.
The ingame view looks practically identical, but we found that bitmap resizing in HTML5 produces worse results than in Flash the further you get away from the original resolution. That means careful selection of the asset sizes for your use case. Some people describe better results with multi-step resizing if you need to display a large range of different sizes.
Performance wise the HTML5 version is slightly slower than the Flash version, on low end devices, which is most notable when browsing through the menu. Especially instantiating assets from swflite seems to be much heavier compared to Flash, which results in small lags when opening popups on low end devices. The team is still working on that, though, and we hope to achieve Flash-like performance over the next sprints.
At the moment we are exporting to Canvas because we noticed that it offers the best average performance. In our experience WebGL will perform faster on devices with a dedicated GPU but worse on devices without, so for low end devices, Canvas seems to be the better option. We plan to add a switch between both modes to offer the best experience based on user choice or automated discovery. Since Away3D is not supported in Canvas, a WebGL choice is also a requirement to enable our 3D game view again.
Of course we also had some learnings over the course of the last months, for example we made heavy use of strict Haxe casts which turned out to be a performance bottleneck. It will probably take a couple more months until we have all of those potential improvements identified and fixed.
However those performance decreases are most notable on low end machines and performance should feel the same for the average user.
And there are good things, too: HTML5 supports native refresh rates, which Flash doesn’t. So on my home screen I have a smooth 144 FPS experience, something that you would never have seen in Flash.
The games also run on mobile browsers out of the box now with good performance on modern devices. We consider to detect this and show our mobile views in this case, to offer a true mobile optimized browser performance. This is where we can benefit from having one single crossplatform codebase, since all the mobile view code is available in HTML5 already and just waiting to be switched on.
If you are interested in the current state of our HTML5 client, you can give it a go here: https://apps.facebook.com/rummy-palace?html5=1 You can use the bottom left button to switch between the Flash and HTML5 version.
Overall Haxe + OpenFL was the right choice and the only real option to keep our large codebase instead of starting over with a new technology. We can now export from one codebase to HTML5 and swf. We will continue to support Flash Player with the swf export as a fallback for the forseeable future, as well as packaging it with Air in our container projects for mobile and desktop clients. A couple of workflows had to be adjusted, but now we can still use our .fla assets like before and deploy a single codebase to all platforms. Way to go!