Flash is dead, long live OpenFL!
I've been a stalwart Flash developer for 15 years, so nothing bothers me more than greatly exaggerated reports of Flash's premature demise. Even today, Flash remains a very viable platform with a large install base and a relatively healthy commercial ecosystem. Many awesome games have been written in Flash and/or Adobe AIR, including our own Defender's Quest, which to date has sold over 125,000 copies.
They dropped support for the mobile flash player as well as AIR on Linux, handed Flex over to Apache, and cancelled the long-awaited ActionScript 4 standard. Although right this minute the flash player still has a big install base, and AIR remains a great way to reach mobile devices, there's no signs of strong future support. Flash just doesn't seem like a priority for Adobe any more. And MochiMedia's recent shutdown is the canary in the coal mine. As a developer, I don't give a damn whether this is a good financial decision for Adobe -- they yanked the rug out from under me after 15 years of loyal support. "Sorry you invested in our platform and tools, you suckers! But hey, you can totally trust us to support you next time! Subscribe to Creative Cloud!"
So where do we go from here? Unity3D is a popular answer, but it's got major downsides - I have to pay for each platform I want to support, and the web browser target depends on a clunky plugin with a low install base. But worst of all, it's just another proprietary platform. Sure, Unity is the bee's knees now, but who's to say it'll always be that way? Just ask all the loyal XNA developers who Microsoft left hanging out to dry. And if there's a bug or missing feature, I have to wait for Unity to get around to fixing it. This works for some people -- and I wish them all the best -- but it's just not for me.
I've learned my lesson -- whatever my next platform is, no-one should be able to take it away from me.
I could try HTML5, but that precludes releasing high-performance desktop-ready games for Steam.
I could try going with a custom engine in raw C++, or something like Java or C#, but it'll be a lot of manual work to get true cross-platform support, especially if I want a unified code base to compile it all from.
I need something open-source, so I don't have to wait months or years for basic features or bugfixes. And shucks, it'd be nice to have the same API as Flash so porting my old code isn't a nightmare.
What's that you say? This magical chocolate pony of dreams exists? Why yes, it's called OpenFL!
Basically, you write your code in Haxe, then you link against the OpenFL library to get the functionality of the Flash API. This means:
You just keep making flash games, but you also get mac, windows, linux, and mobile targets, all at native speed!
Even better, you can keep using a lot of the same tools. The FlashDevelop IDE, very popular with Actionscript coders, has excellent support for Haxe. "Fine, fine, I can port my code over easily enough. But what about all my flash art stuff?" Not to worry - you can keep using the Flash authoring tool and its native flash vector animations if you like. That's because OpenFL recently released their swf library for free, which lets you use SWF animations and assets in both your flash and C++ targets.
Don't believe me?
Many of you might have heard of Haxe and/or OpenFL before, and I admit it can be really confusing to get started, so let me break everything down real easy.
(Don't try googling TD-RPG, that's my own proprietary engine. The rest of it is all online and free, though!)
Haxe - the language layer
I should mention that I'm simplifying things a bit here. Before we get to lime/OpenFL, there's some crazy magical bootstrapping that happens in the background, with the Haxe compiler using the hxlibc and/or hxcpp libraries, but I'm trying to make this as friendly as possible for newcomers without getting lost in all the details. Just keep in mind that I'm giving you a broad-strokes overview.
Lime - low-level graphics layerOne step up from bare-metal haxe programming is lime, which stands for "Lightweight Media Engine." Lime is part of the OpenFL project, and provides a simple, lightweight, and cross-platform drawing API. This handles things like windowing, asset loading, blitting pixels, drawing routines, and interfacing with OpenGL, OpenGL ES, and SDL stuff.
You can totally make games just with lime, without ever touching OpenFL. In fact, having lime as a separate library is a recent development -- before all of those routines were just part of OpenFL. This caused two problems:
- OpenFL had a lot of boilerplate stuff that wasn't related to the Flash API, which was confusing
- Some Haxe developers wanted cross-platform support, but didn't want the Flash API
OpenFL - high-level graphics layer + the Flash APIOn top of lime is OpenFL itself. Here we have higher-level graphics calls, with abstraction layers and a flash-style display list. In fact, we even have the same package structure. In Flash Actionscript, you could always do stuff like this:
var mySprite:Sprite = new Sprite();
In OpenFL, you can do the same exact thing. Sprites, MovieClips, the display list, the stage, events, etc, are all handled just like in Flash.
Some minor differences include audio -- it works fine on different platforms, but since OpenFL is a fully open-source project, they can't cover the draconian world of mp3 licensing the way Adobe can, so mp3 playback only works on flash target. For everything else, you use ogg or wav files. In my experience, this isn't a huge downside since I really hate the limitations of the mp3 format (every Flash dev who's ever tried to get seamless mp3 looping to work knows what I'm talking about!)
One thing to drive home -- if you use OpenFL, you can create exactly the same flash content you can create right now in ActionScript. That's because in the Flash target, you're making an actual swf file, and all you have to do to access the Flash API is use it -- the flash player has all that functionality built-in. On native targets, the OpenFL developers had to actually re-build the same functionality with C++ code, etc. So far there's feature parity for pretty much everything except for some of the less-common features (filters and shaders, as well as right-to-left font support for Hebrew/Arabic text, for instance). It's open-source of course, so those little gaps can always be filled later. At the moment, mirroring the Stage3D API on non-flash targets requires some special libraries, and there are many alternative 3D engines for Haxe (see below).
OpenFL also tacks on a few quality-of-life features that the Flash pipeline doesn't have. Chiefly, asset libraries. In the old days, if I wanted to embed audio or image assets into my swf file, I had to add them all line by line, and set up individual class names to instantiate them with in my code. With OpenFL, thanks to the crazy black magic of Haxe Macros, OpenFL scans your game's asset folder at compile time and automatically generates all the necessary embedding boilerplate. All you have to do is put assets in the folder, then fetch by filename with one line of code:
var image = Assets.getBitmapData("filename.png");
Whereas embedding hundreds of images in Flash games is a huge chore, in OpenFL it's as easy as hitting "compile!"
Many game developers will want to stop at this layer -- at the OpenFL stage, you have the same amount of functionality as you'd have using the FlexSDK to make a flash game. But some of us like fancy game frameworks like Flixel, FlashPunk, and Starling that handle cool stuff like collisions, states, controls, cameras, etc. These and many others have been ported to Haxe as HaxeFlixel, HaxePunk, and HaxeStarling.
HaxeFlixel (my personal favorite), is the most popular, and I can't recommend it highly enough. The others I've never used so I can't vouch for them directly, but I have heard many good things about HaxePunk.
HaxeFlixel - game framework layerHaxeFlixel is the Haxe project that I use most. Not only is it the #1 most-starred Haxe repo on all of github, it's simple, easy-to-use, and comes chock-full-of documentation and examples. Contrary to what many of the pixel-tastic example games might imply, it handles HD-style graphics just fine.
HaxeFlixel has built-in support Nape Physics, Gamepad support, Collision & Grouping, Cameras, Tweening, User Interface, and much more! Some of these features (physics, gamepad, etc) come from separate libraries (Nape) or emanate from lime/OpenFL (Gamepads), but HaxeFlixel wraps them up and makes them easy to use in games. Do keep in mind all those web demos use the flash target -- the native targets are so much faster.
Obviously, I'm biased since I'm now part of the core HaxeFlixel team -- I maintain the flixel-ui and flixel-editors add-on repositories. Some other Haxe projects I've contributed to include my open-source localization framework firetongue (as seen at GDC 2014 localization summit!), and my economic simulator, bazaarBot.
If you want to get started making a nice 2D game in Haxe right now, and you want to deploy to Flash, Mac/Windows/Linux, Android, iOS, or OUYA, HaxeFlixel has got your back.
What about HTML5?So, HTML5 is a buzzword these days -- how does Haxe/OpenFL stack up in that regards?
If you don't want to reinvent the wheel, you can use OpenFL. Now, OpenFL's HTML5 target, as of this writing, is the least mature of all its supported platforms. However, it's been getting a lot of love recently and in the last few weeks has made some amazing strides. I predict we'll have a fully mature HTML5 target very soon.
How cool will it be when you can natively compile your game not just for mac/windows/linux, iOS, Android, and flash, but ALSO HTML5, all from the same source code base?
Just a few hours after I posted this, OpenFL just posted this on their website:
Flash AND HTML5, Unicorns exist!
What about consoles?Okay, so Haxe/OpenFL can target all these amazing platforms. What about consoles?
First of all, Haxe/OpenFL already has great support for the first wave of "Microconsoles," such as the OUYA, Gamestick, Nvidia Shield, MOJO, etc. Also, Grapefrukt Games' Rymdkapsel uses Haxe/OpenFL and some crazy black magic to somehow run on a PlayStation Vita. As for Valve's Steam Machines, those run SteamOS, which is just linux, so that's already in the bag. Theoretically, there's no reason the community couldn't get Haxe up and running on any arbitrary platform, even your toaster. Heck, it's already running on a Raspberry Pi!
"Fine, fine, fine, but what about Next-Gen Consoles!?"
In practice, adding support for tightly-controlled proprietary consoles is tricky -- the biggest problem being the "NDA veil." The good thing is the whole Haxe/OpenFL stack is MIT-licensed, so there's no skittishness from console partners the way there is with GPL code. However, if OpenFL were to build a, say, native PS4 target, any proprietary bits could only be shared with other developers also under NDA's, which makes code hosting and collaboration difficult -- you can't just stick it on a public Github repo. There's currently a lot of community interest in WiiU, 3DS, PS4, and PSVita, but this will probably take some time (and paperwork!).
I think we will eventually make headway here as Haxe/OpenFL continues to gain adoption, but in the meantime we have an unexpected secret weapon:
It's public knowledge that the WiiU has Nintendo Web Framework, a first-class HTML5 target for making games and apps. It's also public knowledge that the PS4 uses WebGL and HTML5, though I don't know if any games actually use it just yet. And I've heard credible rumors that XBOX One might eventually have the same functionality -- it's in IE 11, after all, and they pushed it hard on their phones and tablets.
Based on some preliminary results, openfl-html5 has been able to push a pretty large amount of 2D sprites in HD resolutions when running on PC web browsers. That's more than enough for a 2D game like Defender's Quest, and it seems like a good way to get our foot in the door. Native console development would be way more powerful (and way more expensive) but if we don't need the horsepower, why not take the easy road for now?
Even better, on consoles, one of the big limitations of HTML5 goes away - cross-browser compatibility. Whatever HTML5 support they have on a console is a non-moving target, so you can just create a specific configuration optimized for Nintendo Web Framework, and whatever hypothetical things Sony and MS may or may not announce.
There's also another alternative HTML5 backend in the works, openfl-bitfive, which seems promising and should let us do similar things.
LimitationsOkay, so what's the catch? Haxe/OpenFL can't be all roses and sunshine, right? I'd be remiss not to mention some of the downsides.
Documentation is a bit thin
Haxe hasn't been well documented in the past. The community is steadily improving this, but the go-to way to learn Haxe still remains: "Find someone who knows Haxe and ask them lots of questions." Now that we've finally got actual organizations like the Haxe Foundation and OpenFL Technologies driving things forward, things are gradually getting better.
Here's some good starting points:
Haxe Reference Guide
Haxe Manual (Work In Progress)
OpenFL's getting started guide
HaxeFlixel's getting started guide
One thing to keep in mind is that the OpenFL API mirrors the Flash API -- so 90% of the time, you can just use the Flash API docs and the behavior should be the same. This isn't a perfect replacement for in-house docs, but it's still quite handy.
Also, I highly recommend looking at code samples. HaxeFlixel in particular has a large demo section, all with code samples and links to the relevant Github pages.
The best way to learn Haxe is to get involved with the community. There's a lot of really smart people there, even if it's a bit small. The best places to find Haxers:
#haxe IRC channel on freenode
#haxe and #openfl tags on twitter
Haxe Foundation on Github
OpenFL Technologies, LLC on Github
Haxe and OpenFL google+ communities
Open Source Be Crazy
You can get by just fine by using only the latest releases of OpenFL and Flixel, etc, but if you really want to dive deep you have to learn how to work with the flow of Open Source development. This means getting friendly with Git and Github, and interacting with people in the community. You'll want to get really good at using the "haxelib" tool that serves as a sort-of package manager for haxe libraries. It's crazy powerful, but it's not as simple as just opening Unity or GameMaker and having your legos all in one box.
Haxe Doesn't Hold Your Hand
One of the chief draws of GameMaker, Unity, and Flash (back in the day) is that they're easy to get started with, well-documented, and come in one monolithic box. Haxe is more of a constellation of little tools all working together, not unlike Git. It's fiddly, and it's not intuitive from the get-go. We're getting better at improving the early-user experience, but I'm not going to lie to you -- if you want to get started with Haxe, find someone who knows it already.
It's Not Magic
This is the most important caveat. Haxe/OpenFL is not some magical pixie dust you can sprinkle over your code and have everything Just Work on every platform. There are minor differences in visual output between C++ and flash targets, for instance ((the exact way rounded rectangles rasterize, etc).
Furthermore, you need to know where and how the abstractions leak, and shift your mindset to the meta-programming model. Most of you probably won't have to ever roll up your sleeves and add raw C++ code to one of OpenFL's native backends, but it's definitely possible. You also need to learn the subtle differences between the targets. It's also advisable to get good at understanding how haxe generates code for different platforms. That said, as long as you don't overload on premature optimization, you should mostly be fine.
The easiest way to start is to just use Haxe to keep making flash games -- that requires very little additional effort, and it will get you the same exact results as coding in ActionScript. You can even package swf files created in Haxe as AIR games if you want! (That's what Monster Loves You! did -- it's written in haxe, compiled to SWF, packaged in AIR).
C++ Debugging is still a WIP
Technically, nothing's stopping you from running a command-line debugger like gdb on the generated C++ code Haxe outputs, or trying to run it inside Visual Studio, but that's not exactly easy. You can, however, very easily use an IDE like FlashDevelop to debug your flash code, and if there's an error on flash, there will likely be an error in the other targets as well. That said, we really want 1st-class, integrated, easy-to-use, FlashDevelop-supported debugging for C++ targets.
Don't worry, it's coming:
That's a screenshot I took the other day of native Haxe C++ debugging in FlashDevelop. It's an experimental feature for now, but hopefully it will be ready for release soon.
To be clear, you really pretty much never need to directly touch your C++ code. The feature I'm alluding to above is being able to step through your original Haxe code line-by-line while running your generated C++ program in debug mode, to see where the errors are in your original source. And we're almost there!
Other Important things of NoteThere's a bunch of other little things I want to mention before we go.
What's NME? What's Neko?If you've looked into Haxe/OpenFL before, you've probably heard about "NME" and "Neko" and wondering what those are. First of all, Neko is Haxe's own interpreted virtual machine, not unlike the Java VM or the Flash player; Haxe can output to Neko bytecode that will run in the Neko VM. Entry-level haxe developers can safely ignore Neko -- it's a cool little cross-platform VM, but it's usefulness is mostly relegated to command-line tools, server-side programming, etc. I will mention one useful fact -- Neko uses the exact same rendering logic as the C++ targets, but compiles much, much, faster, so it's useful for testing your C++ visuals when you're impatient.
I'd be remiss if I didn't quickly mention Flambe. Flambe is an alternative Haxe media engine to OpenFL/lime, with a focus on web and mobile. Its chief targets are Flash, HTML5, iOS, and Android, and also lets you you render SWF content in the non-flash targets. For its mobile targets, Flambe exports your game as a SWF uses Adobe AIR to package it.
Flambe has attracted a lot of attention from the commercial sector, notably from Nickelodeon and Disney. So it's worth looking into. The top priority seems to be 1st-class HTML5 support across all platforms.
The biggest difference between OpenFL and Flambe seems to be that Flambe has more high-level stuff. So in Flambe-land, functionality that would normally be supplied by 3rd-party libraries like HaxeFlixel and HaxePunk in OpenFL-land, are built right into the core of Flambe.
Flambe is more monolithic, as it were. So if you're more of a "I want all my legos in one box" type person, check it out. Flambe also supports the new Firefox OS, and just hours ago OpenFL announced the same thing. Go Firefox!
Other Cool StuffOpenFL supports the new fully-open source Tizen mobile OS, which some are speculating might be replacing Android on mobile devices.
There's also Reach3DX, from the creators of Gamebryo, which is built on the Haxe/OpenFL tech stack.
And if you're really interested in making 3D games with Haxe, you might be interested in these Haxe 3D libraries:
H3D (as seen in EvoLand)
Other miscellaneous tools include:
Spinehx (skeletal animations)
haxe-openfl-ffmpeg (playing video)
And much, much more!
Thanks to these fine folks for providing useful information:
Joshua Granick, Nicolas Cannasse, Hugh Sanderson, Nilsen Filc, Bruno Garcia, Jesse Kurlancheek, Philippe Elsass, Damjan Cvetko.
Haxe, OpenFL, HaxeFlixel, HaxePunk, and Flambe communities.
(And anyone I left out)