Shouldn't the title be, "Another success story for Haxe"? I thought the massive success of Lucas Pope's "Papers, Please" is validation enough of the framework: http://en.wikipedia.org/wiki/Papers,_Please
(at least it was for me...I was amazed at how fast Pope built and ported a cross-platform game considering he's a one-man shop...though to be fair, he was also able to learn Flash and build games for Ludum Dare competitions...so he's probably an outlier :) )
While Haxe allows you to compile to pretty much everything using the same language, it doesn't use the same api for every target. Openfl[1], which is written in Haxe and allows you to use the flash api, compiles to pretty much anything using 1 codebase. "Papers, please" used openfl to achieve its portability so I guess it's a success story for openfl as well. Rhymdkapsel is another great game that uses it.
Learning Haxe is a great way of understanding how certain PL concepts map to different language implementations. You can write up a simple "hello world" example for the feature you're interested in, and see what it gets turned into in the output.
At first, I was hesitant to do much with the compiler since I don't know OCaml. But, I recently forked the source and am making an attempt at a lua target:
https://github.com/jdonaldson/haxe/tree/haxe_lua_rb1
It's been a great way to learn OCaml, and Lua. If you're interested in creating your own Haxe target, I'm hoping my commit log will be helpful.
We just released our second game in Haxe on iOS a few weeks ago and we're releasing the Android version in another 6 weeks. It's a Unity client with haxe-generated C# code and then javascript and node on the server. There have definitely been a bunch of hiccups and hitches along the way, but it's been pretty good overall.
Thanks! We had actually soft-launched before the cut-off, so we slipped in before that requirement got put in place. That said, we did just get it working with IL2CPP last week which was a few days of work for one engineer. More hiccups encountered but nothing show-stopping (though mostly in dealing with Unity's peculiarities than anything else).
I'm in the process of learning Haxe. I hope it becomes more popular since you can have macros, static type-checking and a shared code-base with one language. You can have all these things with Javascript but not at the same time (that I know of).
When you write Javascript, do you mean TypeScript, AtScript, something else? There's no type checking in JS, and there is no metaprogramming support in JS, let alone of the quality it can be found in Haxe.
Besides that, the type system of Haxe is far more expressive than those of most languages that also compile to JS. Ocaml, Scala and Haskell are the better known languages that are actual competitors in that regard.
Yes. "With Javascript" I mean via Typescript or Flow, you can have some static type-checking. You can use Sweet.js for macros with Javascript, but you can't use both of these tools together.
I'm unfamiliar with Ocaml, Scala and Haskell but OK.
I'm looking into potentially using Haxe as a way to share code between iOS and Android. Unfortunately, it doesn't seem like anybody has made a good, open source Objective-C/Swift target for it yet. (There is a Swift target here[0] but it hasn't been committed to since October 8 and doesn't seem production-ready by any means.) I would contribute one myself but I have no experience with OCaml, and don't currently have time to learn it.
I like the idea of this approach way more than the one that projects like Xamarin take (build a common runtime on top of each platform) because you don't incur any runtime overhead, and debugging would (in theory) be much easier because you can just debug the native language instead of needing to understand the extra VM layer on top. As a bonus, with Haxe you can also target the web, which you can't do with Xamarin/RoboVM/RubyMotion/etc.
Has anyone tried anything like this (not necessarily with Haxe) and had success with it?
I've been using haxe/openfl in production for 1.5 years and wouldn't really recommend it. Originally cross-platform code was a really good idea very few people had or executed well and haxe's warts were forgivable, today that's a capability many languages have without the hassle. I think the only unique value left in Haxe is outputting Flash.
Let's be careful not to limit Haxe to OpenFL, which the linked article isn't even using.
The article points out that Haxe is a great option for creating portable application logic while the game is using Unity for rendering.
Other uses for Haxe are the JavaScript target which a number of companies are using extensively in the same way you would be using typescript/coffeescript.
My favorite is Array.sort. Since it's consistent with many other languages you won't get to the docs until your app is crashing. Instead of being fixed it's had a recommended alternative buried in the docs for I think years:
The sort operation is not guaranteed to be stable, which
means that the order of equal elements may not be retained.
For a stable Array sorting algorithm,
haxe.ds.ArraySort.sort() can be used instead.
Every platform has its own gaps in the API. This is evident in this submission - after the author translated his JavaScript he then had to fix his haxe to work within the subset available to C#.
OpenFL isn't a mature platform and their releases are rushed and buggy. If you download and install <older OpenFL> their setup process will install the newest version of dependencies and their incomplete documentation will leave you to figure out what versions are actually compatible. Gestures are a pain in the ass with immature and incomplete libraries.
The one thing that makes it worth using - barely - is the decade and a half of ActionScript experience I also have.
You make it sound like you actually experienced crashes due to an unstable sort function in Haxe.
You even make it sound like that was a common occurrence due to a deliberate decision on part of the development team to not fix that alleged source of crashes, but rather refer to an alternative in the documentation.
You should clarify that you haven't made this experience, and that no one you know or have heard of ever has.
You seem to have no idea how unlikely it is that the various Array.sort implementations (they're usually provided by the respective target platforms, of course) all have some bug that leads to crashes, moreover, you seem to be unaware that most target platforms provide such basic APIs, which in turn shows how little you know about Haxe.
As the documentation already explains, "unstable" in the context of a sort function is about the order of elements that are equal from the perspective of the comparison function. That's basic CS terminology. It's not about crashes, and it's not about bugs in Haxe or the respective target platforms.
You simply misunderstood, but you keep insisting. Which sheds some light on the overall quality of your comments about Haxe here.
In our case on Android Array.sort throws exceptions. Pretend I nominated something the success story developer had to learn some OCaml to fix in the Haxe compiler instead, it is just an example and doesn't change the common narrative.
Please report that bug. The core team (or other devs familiar with Haxe like myself) will be happy to fix it.
Also, consider that 65% of the code in the haxe git repository is written in Haxe, not OCaml. There's a lot you can change, extend or fix without knowing OCaml at all.
I see. Are there a lot of these warts? To be fair, if all the inconsistencies are documented, that seems like a fairly minor inconvenience for the benefits you get. (I don't know how well-documented they actually are, so maybe the answer is "not".)
Also, if I were to use Haxe for mobile development, it wouldn't be through OpenFL; I would use the native APIs of each system and just write a thin wrapper in Haxe that's common for all platforms. I just want to reuse code, not adopt a completely separate UI toolkit.
I've known Haxe for almost 7 years and have been using it extensively in the past 4.
In my experience, inconsistencies between targets and undefined behaviour were common, but most cases have since been removed or documented.
Also, I find it's usually trivial to see how a given Haxe API (be it one in the standard Haxe library or from a third-party lib) maps to native calls.
Personally, the fact everything in the Haxe ecosystem is open-source and has reasonable scale (for instance, the std API by design isn't as big as Java's) is one of the reasons I like it so much. Even though I can't code in Ocaml and modify the compiler itself, I feel that can I solve most time-sensitive issues that might arise (bugs, unexpected behaviour, extending APIs, etc.).
Other reasons I code a lot in Haxe are: code reuse; powerful type system (ADTs, abstracts...); macros; reasonably pleasant syntax (although a bit verbose for my taste).
The success story mentions the dev had to learn OCaml to fix bugs in Haxe, other comments here by jdk and reallyRaoul refer to inconveniences too. Elsassph mentions some of the issues are specific to OpenFL not haxe, that's true both ways. I think you can reasonably expect to encounter issues.
Do you expect to encounter any bugs at all - outside your own code - in Java, Objective C etc when you do your native UIs?
> Do you expect to encounter any bugs at all - outside your own code - in Java, Objective C etc when you do your native UIs?
No, but I'd wager that I would spend more time re-writing the app for each native language than I would finding the inconsistencies in Haxe. (And either way, each platform has its own nuances that you have to know whether or not you use Haxe.) For the record, you'd have the same issues with solutions like Xamarin. The whole thing is a trade-off, and I have a (well-supported) hypothesis that the benefits of a (semi-)shared codebase is worth the cost of learning these nuances and inconsistencies.
I don't do that many UIs at all, so I wouldn't know about that. Even so...
These languages are certainly more mature than Haxe, but I do still expect to find some bugs in their standard libraries (in performance or security).
And when you factor in third-party libraries, the answer is always "yes you do expect to encounter bugs" independent of the language. For me, programming is in great part reading and fixing other people's code, and I still think most of them are much more skilled than me.
Of course you have to learn the language the compiler is implemented in when you're hacking the compiler. That's not an inconvenience, it's a tautology.
This is a strange complaint. Quicksort isn't stable in most implementations either. The docs are exactly where I'd look to see if a particular sort method was stable... where else?
I really don't mean to be condescending, but are you interpreting "stable" to mean "crash free"?
I don't think it is reasonable to blame me for encountering a bug in their code, the problem is in their code. Please read the success story - the person advocating for it describes plenty of time spent compensating for it for reasons much more diverse than this one example. This is a common experience - mentioned in several comments here too.
Well, it simply isn't a bug. Most sort algorithms aren't stable, and the only thing a generic _sort_ algorithm is supposed to guarantee is a sorted output according to the comparison function you supply it with. If however the method was called "stableSort", the situation would be very different...
The default Array.sort stability is inconsistent across targets _because_ guaranteeing it would prevent reusing implementations already available in the targets. And differently than what you claimed, many languages (and most Haxe targets) don't guarantee sort stability in their default "sort" APIs: C, C++, C#, JS, PHP and Neko.
Also, any remark placed in the official api docs for "Array" or in that very module, just next to sort method, can't be said to be "buried" in the docs.
It is not important we agree on this being a bug or not. If you have had a smooth experience you don't have to look further than the linked success story to find a counter-example.
Respectfully, it is important to understand whether sort stability is as bug or not. Particularly since you seem to have experienced exceptions on Android, and assuming that the problem was in the sort stability may have mislead you.
Do you have the same problem with a deterministic comparison function?
I'm not dismissing the existence of a bug just because of this (although the issue may be related to it), but non-deterministic comparison functions are problematic with many sort _algorithms_. You might experience (other) problems when using implementation independent "sort" APIs, since many algorithms need to rerun the comparison function several times and expect consistent behaviour; I would expect certain algorithms to, for instance, never complete.
I don't want to attach myself to further discussion of it, but it is still a crash reasonably isolated to their standard library and I took the time to document it so that my feedback could be helpful. If you don't pass it on they will miss this opportunity to improve their platform.
Could you explain what's wrong with Array.sort? Lots of languages' standard libraries have unstable sorts, including C. What kind of crashes could be caused by an unstable sort?
unity/unreal engine isn't really a fair comparison, you're either requiring a web view plugin (unity), or you're going with emscripten (unity/unreal). I couldn't find evidence of solid support for Xamarin there either.
Haxe has the ability to integrate much more cleanly across all of these platforms imho.
Regarding targeting the web, you can't do this directly with RoboVM, but you can use GWT to do so. This means that you can target Android, iOS, and web with Java. You would have shared code that all platforms could use, and then build the UIs natively.
This is pretty much the approach that Google use with Inbox, except they used j2objc instead of RoboVM.
When you take development time into account, GWT doesn't come for free. Yes, it's possible to compile Java to JS via GWT, but the toolchain is prohibitively slow. In contrast, the Haxe compiler is extremely fast.
Yeah, I agree that an Objective-C target makes more sense because it's more broadly useful (and Apple is still making backwards-incompatible changes to Swift). Thanks for the link!
If you have a critical bone in your body, prepare for a love/hate relationship. It is so good and yet so bad in various ways. I wrote a few unpublished games with 2.0 and NME back when (e.g. mzzl).
I agree. I've used haxe, and it's REALLY nice being able to cross-compile from one codebase, but there were several times it was more difficult than expected to get things to work. At this point I'd rather use C++ and just compile on different machines or in VMs. Or, since I'm looking at haxe from a gamedev perspective, I'd rather use Unity since it targets every platform haxe does, and has better docs (HaxeFlixel and HaxePunk are great, but apart from basic tutorials you're sailing without a compass or rudder - but this was about a year ago).
The sample program on the Haxe main page demonstrates a complete misunderstanding of the value of dictionaries. Not exactly inspiring one to learn more.
class Test {
static function main() {
var people = [
"Elizabeth" => "Programming",
"Joel" => "Design"
];
for (name in people.keys()) {
var job = people[name];
trace('$name does $job for a living!');
}
}
}
It's a simple example, but it's showing a lot of nice things.
The "people" instance is using anonymous syntax for a Map type. Haxe's Map types are actually abstract types: http://haxe.org/manual/types-abstract.html. I doubt many developers are familiar with this type of feature.
For instance, here's a "packed array" implementation that lets me store an array of integers in a fraction of the space usually needed for a standard array type:
https://github.com/jdonaldson/packhx
Abstract types let me use the same api that standard arrays use (including array accessors), even if the underlying runtime implementation is completely different.
The other nice things going on in the example is the simple for loop using an iterator, and the nice string interpolation. Granted, this is nothing super sophisticated, but it's great to have these same features across all the targets that Haxe supports.
Haha, I was the one that wrote that example for the homepage. It was never meant to be a comment on the ideal data structures for different use cases. Rather it's just there to give developers a taste of the syntax: there's more semicolons and brackets than Python, less explicit typing than Java.
If you have an example of a better code sample for introducing language syntax, I'd love to see it so I can learn from it.
My point is that if you're going to iterate through the entire dictionary, there should be a way to get full key-value pairs, so you don't have to look up the value for each key. There's no need to change the entire example. Something like this:
for ((name, job) in people) {
trace('$name does $job for a living!');
}
We recently adopted it to provide a sane base to our Javascript. Personally, I LOVE it. It's cleaned up our code so much.
My problem with it is that it seems to have gone somewhat stale. It's been almost a year since the last update, and at least for the JS target, a number of the great external libraries never made the hop over to the 3.0 codebase.
Development hasn't stalled at all, neither for the JS target nor for most other targets. The core compiler is being improved constantly, which benefits all targets, and there have been improvements in the JS code generator, too (which isn't easy, the code quality has been very high, already).
Oh I definitely have nothing bad to say about Haxe. I was mostly just referring about some of the external libraries that never made the jump over from legacy, which could be indicative of developers jumping ship.
You make a great point; just because a project doesn't put out updates once a week doesn't mean it's stale. There are some other great projects like haproxy and redis that are clean enough and stable enough that regular updates aren't necessary.
I guess you sort of grow accustomed to that mentality when dealing with some other common OSS projects
You should try the nightly builds or compiling straight from Git. They are stable enough for many purposes (and if you report a bug chances are that its fix will soon be available) and you can take advantage of new features.
By the way, there's a new release planned for the next weeks.
Making use of the same bits of code on both the client and server (or whatever platforms you need to support). So if you have, let's say, some code that formats relative dates, Haxe allows you to write that code in one language and reuse it on both the server- and client-side, whereas normally you'd have to write a separate version of that in Python and in AS3.
If you have a client and a server, you'll most likely need to handle input or state twice. You shouldn't trust the client but you also don't your user to depend exclusively on the server (you want less latency and/or more informative errors).
(at least it was for me...I was amazed at how fast Pope built and ported a cross-platform game considering he's a one-man shop...though to be fair, he was also able to learn Flash and build games for Ludum Dare competitions...so he's probably an outlier :) )