There were a reasonable number of specific things to learn about compilation, packaging and handling things like device rotation, viewport sizes, etc. along the way. But we had a cleanish single codebase for all targets.
Documentation and real world examples were fairly slim on the ground at that point, but it certainly worked and ran well to very well across all devices. It certainly offered a pretty consistent experience across all the targets and ran at a decent framerate on everything we tested against. We couldn't really find much to fault it on once we had everything up and running. I seem to remember compilation times being incredibly fast.
I'm kind of surprised it's still a thing - it brings back some good memories & makes me want to have a go with it again as it was an enjoyable way of working for that type of 2D game project.
We used to do lots of Flex development back then for various commercial projects, then Flash/AS3/Flex got all but abandoned overnight, becoming almost hated. We managed a large cross compiled (iOS/Android/Windows/OS X) AS3/Flex project with native hooks for various platforms up until mid last year, parts of the codebase were nearly 10 years old, when we finally managed to convince the client it would cheaper to re-write in a mix of HTML/JS/Electon/JS bridges than continue to battle the existing codebase. We rewrote it all in around two weeks, improved the UI and fixed long term numerous issues that had plagued us for at least a couple of years, mainly due to being reliant on closed source 3rd party Windows/Mac integrations/hooks that had been abandoned by the original developers and Adobe also largely abandoning the AS3 iOS/Android compiler.
Also, it didn't really seem to have a huge community and everything seemed to be in a transitory phase with things like Flash being pushed out by iOS native development, the huge improvements in HTML/JS/CSS, etc. Then tech like Swift, React, etc. came along it just seemed to get forgotten as a tool in our arsenal.
We certainly started focusing more on other new stacks/approaches around the same time.
Half a decade is a lot in human years, let alone IT-years.
https://haxe.org/videos/conferences/wwx-2015/haxe-at-massive...
I don't think Nicolas worked with them, though. I'm one of Haxe contributors but I don't suppose you were thinking of me.
It predated Typescript, so at the time the killer feature was being able to write type-safe JavaScript, and being able to share code with a backend which is potentially another language (like PHP).
These days I’m at a company with a lot of TS, and too many other languages (Elm, Ruby, Kotlin, Elixir...) so we’re not looking to add something like Haxe, but I often still miss the expressive type system, the really nice language server integrations, having the multiple output targets so it’s the same language everywhere, and the type safe macro system.
So I often use Haxe for hobby projects still, but then I miss things from the JS ecosystem. You have access to NPM but there’s no equivalent project to DefinitelyTyped. Some of the tools integrate well (webpack as an example), some don’t (Jest). React works, but the way JSX works doesn’t integrate as nicely with the language server. Etc
I also missed some modern es6 syntax. Haxe finally got arrow functions in v4. The thing I’m excited by in this release is module level fields - previously everything had to be in a class, now they don’t. Haxe was already good for writing functional style code. Now when you read the source code it’ll look like it and not have the “class” keyword when you don’t need it.
1: https://haxe.org/documentation/introduction/compiler-targets...
Also, if you’re interested in OCaml, check out the source!
As the top comment mentioned, I was particularly impressed by the ease of cross-platform development in an age where bigger tools like Unity were still picking up steam. Coming from Game Maker, Haxeflixel felt like the natural step forward. I enjoyed it so much I wrote a book about it: https://discover-haxeflixel.com/
The people behind it launched a fairly successful fundraiser a few years ago so I'm happy the main developer and contributors got something back for their open-source efforts. As far as I know the library is stable - I just about updated the book a few months ago to re-rewrite references to the Flash (RIP) and move people towards the html5 exporter instead.
I still think that in an age of 10GBs+ AAA game development framewords, Haxe and Haxefixel still have a place for your typical 2D / Pixel Art-ish arcade game, although more ambitious and successful games have definitely been made, like Defender's Quest (http://www.defendersquest.com/) from Lars Doucet's, a huge fan of the framework.
A Haxe macro is just regular Haxe code with the same syntax and same standard library, except it runs at compile time, and it can operate on the AST of your program. They're like shaders, but for your compiler.
One of the coolest demos of Haxe macros imo (even though it's dumb) is where you can add code completion to your IDE via a URL (https://code.haxe.org/category/macros/completion-from-url.ht...). It works because the macro generates static fields for a class using data it downloads from the URL, and because the Haxe compiler provides a completion server, any IDE with Haxe support will automatically pick up the new fields and present them in a standard completion pop-up/drop-down menu. Just imagine the things you could do with something like that!
Unfortunately, Haxe never seems to get the attention it deserves. The sad fact is that the vast majority of developers are never going to try a new language or technology on their own unless their employer tells them to, or there is some viral article that reaches everyone, and makes it seem like the second coming of Javascript. Additionally, the Haxe foundation never seemed to take much interest in promoting the language. They do have funding, and they organize events/meetups every year, so it doesn't seem like they're going away anytime soon.
Oh well, such is life. People might not think I'm cool when I tell them I know Haxe, but at least I have Haxe!
Scala macros are the same way (but with an obtuse API until Scala 3, which should be out soon after all the syntax bikeshedding is done). It's also one of the things I love about Scala, though I'd understand why others might disagree. Metaprogramming is fraught; even moreso when it's plain that it's a program that runs at compile time (which is also the case with C++ templates, to fewer complaints per-capita for reasons I don't understand)
I use them to do compile-time code gen from Omnigraffle and iThoughts files.
Definitely a super power but probably one that only works if you're the sole developer. Macro magic in a team environment is problematic.
Two points of friction around it that tend to show up are in tooling and debugging. Haxe is what I like to call "parasitic" in that it leverages existing stacks really easily, but then the tooling of those stacks doesn't always offer the affordances you want.
For example, when Flash was still a major target, Haxe did have some SWF generation functionality, but it didn't accommodate every type of asset equally well and there was a bit of a puzzle - not an insurmountable one, but bigger and more opaque than anyone would face from Adobe's tools - in getting the binding of the embedded asset accessible from your Haxe code. The puzzle persisted through a lot of the SWF features(things like networking sandboxes, which would be used if you wanted to e.g. embed ads in a game, were related to how the SWF was built and delivered) and could result in a lot of timewasting.
Likewise, while the language is extremely savvy about offering access to the low-level functions of different targets - eventually you do come to debugging the generated code. Not because the compiler has failed(it's very reliable) but because there is some kind of platform-specific issue to be solved. And again, it's going to be more opaque to debug that than "doing it native".
The upside of this is that you can choose your target for everyday debugging, and therefore minimize the suck. It can actually be very productive and painless. (Edit: and the language is really up to speed with the idioms in current PLs, so it's often the better choice for writing abstractions.)
A healthy way to apply Haxe is to identify the places where you can put the platform code behind an interface, code that natively, and then code to the interface in Haxe for the rest. That way, you get the fluidity of being able to switch targets and you aren't jumping between layers so often. But this does come with the cost of having to build up a useful interface and really "own your own stack". It's not just-works technology, although it can come close with some of the frameworks.
- Papers Please
- Dead Cells
- Northgard
- Rymdkapsel
- Evoland
One of the creators of Dead Cells made a level editor called "LDtk" that has a Haxe API as well
Other random uses:
- lua target for a pokemon game, probably for scripting (no word from devs, just saw the licences)
- a video player made by feds to catch pedocriminals a couple years ago
- livejasmin (warning: NSFW!) is using it for its frontend (via docler holding) on a top 50 website
I'm also migrating the website (currently Python) over to it -- I can share data type declarations between server and client-side code, which give me compile-time guarantees that my api calls and return values are not malformed.
The actual language is great. I am a long time ago former flash developer, and heaps.io and haxe has captured a lot of the enjoyment I used to have making games for newgrounds
I've not touched it in years, but if I ever do a side project it'll be one of the tools I'm likely to use.
https://github.com/vshaxe/vshaxe/wiki/Debugging
Other than that, if really you need to debug some target-specific issue on a target without debugging support, there's usually still the option of debugging the generated code.
But this... actually looks pretty neat!
I'm curious how popular it is at this point? Is there a big benefit over something like Typescript now?
- LDtk: https://ldtk.io/
- Ogmo 3: https://ogmo-editor-3.github.io/
However at the moment we are struggling a bit to find talented programmers, so if anyone is reading this - knows Haxe well, and wants to work in Copenhagen with a company whose mission is "helping to save more lives" (we take that very seriously and hold that above simply making money) then send me a message ;)
Have you tried posting in haxe forums [0], posting [1] a job offer to be published in haxe roundups [2], or coming to haxe discord [3]?
[0]: https://community.haxe.org [1]: https://github.com/skial/haxe.io/issues [2]: https://haxe.io [3]: https://discord.gg/t5Bg3j6Bxz
I've been using Haxe for many applications; cli tools, generative art, websites, games, backends, tools etc.
Webdevs; There is a full-Haxe react alternative I've been using to create a website, which is called coconut.ui. Since its build with macros under the hood, it can have multiple outputs, which means you can output just its own renderer, but also react (+native), but you can use it to build reactive applications in other framework.
If you use lix (npm/yarn based) as dependency manager, you can require Haxe in CI, which also makes switching versions easily.
I used it back in 2009 or so and remember the compile times being incredibly fast, it was a joy to use.
I like learned on the front-page example a multi-state (?) switch statement. What is this called and any other languages support this?
switch [playerA.move, playerB.move] { case [Rock, Scissors] | [Paper, Rock] | [Scissors, Paper]: Winner(playerA);
...
> How does this work, do you code and specify a target output?
Indeed. You can specify multiple targets on multiple builds if your code is compatible with all of them (which happens without too much work when working with libs that do the abstraction for you, like openfl or heaps -- and yeah, that's mostly for games).
switch [playerA.move, playerB.move]
case [x, x]: Tied()
case [Rock, x]: Winner(if x == Scissors then playerA else playerB) let a = "Rock";
let b = "Paper";
let result = match (a,b) {
("Scissors", "Paper") => "A wins",
("Paper", "Rock") => "A wins",
("Rock", "Scissors") => "A wins",
("Paper", "Scissors") => "B wins",
("Rock", "Paper") => "B wins",
("Scissors", "Rock") => "B wins",
_ => "Draw"
};Ecma / JavaScript -> Typescript
Ecma / ActionScript -> Haxe
Haxe is truly fascinating and Neko is a great engine as far as I could test. But the language suffers from global scale adoption, not due for the quality but due to the lack of big names representing, I feel.
If you applied Typescript's philosophy and design to AS instead of JS, you'd get something much closer to Typescript than to Haxe, is what I'm saying.
TypeScript's main strength is its proximity and integration with js; it didn't seek to reimagine js, but build typing on top of it.
Haxe instead builds strictly typed ECMA language from a clean slate:
- Language features are simpler because it doesn't have to contend with legacy JS (importing a module is just `import X`, strings are always multi-line, `this` means current class etc)
- It's a hybrid functional language, so you can write haxe like you'd write TypeScript, but everything is also an expression, so you can use functional patterns:
// the switch statement is an expression and so evaluates to a value
var message = switch httpCode {
case 404: 'Not Found ($httpCode)';
case 200: 'Success ($httpCode);
case code if (code >= 500 && code < 600): 'Server Error';
default: 'Http Error $httpCode';
}
// even the for-loop is an expression
var array = [for (i in 0...10) i]; // array of Ints from 0 to 9
- Compile-time code execution removes the need for build tools – you can mark functions to execute at compile time, so you can do all your asset processing / DSLs / build-tool-fun as part of the regular compilation. (This is perhaps the biggest win over the traditional web stack for me; I _hate_ web build tools)- Smaller code output, haxe performs static analysis optimizations and dead-code elimination (see this example https://try.haxe.org/#4Baa5, taken further here: https://github.com/haxiomic/vector-math)
- Target other server backends like PHP or Python, which is handy if you're writing a web service and want to use libs from other ecosystems
- The compiler is many times faster
On downsides when compared with TypeScript:
- Is it can be harder to use js-centric libraries like Vue, which make use of JavaScript's `this` behavior in their API design (in contrast to libraries like three.js which are more traditional)
- Haxe does not consume .d.ts files directly but they can be converted to haxe files with the dts2hx tool. This works for many libraries, but isn't yet perfect. For complex libraries like React, it's best to use a hand written haxe-react project (e.g. https://github.com/kLabz/haxe-react)
- Haxe's type system is more strict than TypeScript's, in TypeScript you can perform complex type operations but to achieve the same in haxe you need to use compile-time macros. This is primarily an issue when using existing TypeScript libs which make use of advanced type expressions (which if too complex may become 'any' when translated to haxe)