Kek or how I’ll waste my free time going forward

Screen Shot 2016-06-30 at 20.52.45-hLBpw5hl7K

It’s been a while since this blog had anything other to offer than “libGDX x.x.x released”. This was partly a result of my engagement with RoboVM, which, as you may have heard, is no more. And while I got plenty of real-world-ish stuff to do going forward, I also feel in need of something to challenge my old-farty brain a little in my spare time. For bonus points, I’d like to share my insights and failures with you. And maybe, and that’s a big maybe, something useful comes out at the other end.

You may be thinking: “But what about libGDX?”. Truth of the matter is, I have not been actively pushing code to libGDX in a very long time, save for some minor coding like the initial LWJGL3 backend, or helping out with the recent iOS backend shenanigans. My day to day (or better week to week) libGDX activities have mostly been limited to staying in contact with our fabulous core team, doing the occasional release, managing a libGDX game jam, or kicking our Mac build slave in the butt. My role has simply changed over the years. I’d like to focus my free coding time on something new. Fear not, I will continue to play the benevolent dictator and keep things going as before.

With all that out of the way, let me throw a bunch of thoughts at you. Using my usual wordy style of writing. Enjoy!

The computer science education gap

Disclaimer:I may use the terms “computer science”, “computing” and “programming” interchangeably. I’m aware of the differences, cut me some slack.

I’ve always enjoyed teaching. Let me rephrase that. I’ve always enjoyed telling people of my failures and successes, in the hopes that they can take something away from them. Past endeavours included writing a 700+ pages book, doing a ton of conference talks and workshops, lecturing at university, educating decision makers at companies, or simply talking about my day-to-day technical work with my non-technical SO.

I have also witnessed how kids are taught “computer science” and “programming” at school. It’s a small sample, but it’s generally not pretty. Kids are “fortunate” to come out of school with basic MS Office knowledge. Programming or basic computing, if taught at all, are mostly limited to Scratch like systems. There’s nothing intrinsically wrong with Scratch-like systems. A big number of scientific studies show that initial acquisition of basic computing concepts appears to be better served by exposing the learner to a visual programming environment. Go hit Google scholar, follow the citation graph of “Scratch: programming for all”. Fun fact: developing games has been identified as the best motivator across age groups and genders by multiple studies (and I conveniently lost the citations…).

However, some studies also indicate that kids themselves don’t feel like what they are doing is “real” programming when using Scratch-like systems. Without them being able to describe what “real” programming entails. It’s akin to giving a kid Duplo when what they really want is Lego Technic. Some manage to stay motivated and eventually make the jump to “real” programming. (Note: I view visual programming systems as “real” programming, albeit limited). Most stop engaging with computing in any shape or form.

And that is fine. While I do appreciate the recent push across the industrialised world for more early-age computer science education, I also recognise that computing does not have to and will not be for everyone. Still, nothing would warm my heart more if we can get more kids (and adults) to leave their walled-garden content consumption machines and join the community of digital makers. The earlier we can plant that seed, the better. But something is lacking.

10520_1-lego

51wkYbxWbIL

I believe there is a missing link between the visual programming systems ala Scratch and the text-based behemoths that make up modern day programming. The gap between Scratch and JavaScript/Python/Go/Rust/C/C++/Lua/C#/F#/Clojure/Java/Kotlin/Scala is huge. Not only is there a switch in input modality that comes with pesky de-motivators like syntax errors, slow typing speed, or concepts that need to be hand-waved away initially (everything is a class, et. al.). The overwhelming complexity of just getting set up and understanding the basic operation of these development environments is to much for many aspiring coding apprentices. On the other end of the spectrum, Scratch-likes are so far removed from real-world systems that the knowledge gained is often insufficient for further study.

On top of these “technical” issues, the social aspects of the communities around Scratch-like systems get lost as well. Trying to enter the circles of “real” programmers can be a rather frustrating experience. While there are exceptions to the rule, most communities I’ve been part of have been downright hostile to newcomers. Furthermore, where would you point a newbie interested in joining a community for “real” development platforms? Most communities are heavily fragmented, and it’s entirely unclear which of these sub communities are most suited for beginners. For something like Scratch, it’s very clear: simply go to the Scratch website and find like-minded people and mentors (and moderators).

And while technically possible, sharing and remixing your and other people’s work is multiple orders of magnitude more complex using “real-world” systems than using projects like Scratch. I view this feature of most educational programming environments to be key in keeping newcomers motivated, offering additional sources for self-driven learning, enabling collaboration, and learning soft and organizational skills.

“But Mario you silly goose, there are a metric ton of such systems out there!”. Yes, there’s a ton of educational programming environments out there. Over the past few weeks, I got to enjoy many of them, including, but not limited to Tynker, Stencyl, Scirra, Snap!, CodeCombat, or MinecraftEdu. The last one is now actually called “Minecraft for Education” after the buy-out of MinecraftEdu by Microsoft. Leaving hundreds of teachers stranded without a backup plan.

Some of them are infuriatingly bad (no undo, slowness, glitches and bug galore) that I’d not recommend them to my worst enemy. Some have a weird understanding of pedagogy. Tynker for example has lessons specifically targeted at girls, including licensed assets from the Monster High brand. Interestingly enough, the lessons for girls on mobile devices are a LOT simpler than those targeted at boys. Because we all know, girls are stupid, right? Many are behind pay-walls or limited to a single platform and device class. (Looking at you, Swift Playgrounds. So close, but no cookie.)

The other solutions in that space are great to introduce extremely basic computing concepts to your kid (or adults), but are a long way from narrowing the gap to “real” development environments.

Project Kek

cute-unicorn-clipart-unicorn4

In short, I want to try creating that kind of missing link vaguely described above. Here’s what I believe are crucial features:

  • Free, open source (I hate money) and as cross-platform as possible
  • A programming language that scales with the user’s experience (imperative, structured, functional, object-oriented), with a low barrier of entry, and a high ceiling of what’s possible
  • A set of standard libraries tailored for each experience level, geared towards game development
  • A self-contained, extendable development environment that iteratively introduces concepts like code structuring, debugging, deployment & packaging, version control, dependency management, etc. and allows collaborative work out of the box
  • Newcomer friendly, localized documentation for all of the above, geared towards self-learning
  • A moderated community hub to share, remix and talk about your creations
  • A way to let educators create and share teaching materials

Yes, this sounds a bit insane. But consider that these features can be scoped. Take a look at Pico-8. It already does a lot of things right in my book. There’s nothing prohibiting the first few iterations to work on a similar complexity level as Pico-8.

I think of it as the training wheels version of a real-world programming environment. Another analogy would be a modernised version of the environments of old like QBasic, Turbo Pascal and so forth. These systems from the pre-internet age came equipped with enough material to let motivated people become self-starters. My hypothesis is that an internet-age version of such a tool might just be the right thing to fill the gap between Scratch-likes and “real” programming environments.

Next Steps

As a first step, I want to protoype the first few features from the list above. This includes the first iteration of the programming language, a minimal standard library, and potentially piggybacking on an existing editor like Visual Studio Code. All of this will be documented on this very blog.

Should the initial prototype be a complete disaster, I’ll try to recycle as much as possible and potentially head off into an entirely different direction. An agent-based, programmable, shared virtual environment could also be an interesting avenue to tackle this problem. From a technical side, this is quite a bit more advanced and resource intensive, which is why I want to hold off on spouting the finer details just yet.

All things considered, I’ll likely fail. But I’ll have a metric ton of fun doing so!

libGDX 1.9.3 released – New iOS backends

libGDX 1.9.3

Been a while since the last release. Here’s what’s new!

[1.9.3]
- Switched to MobiDevelop's RoboVM fork (http://robovm.mobidevelop.com)
- Addition of Intel Multi-OS Engine backend for deploying to iOS
- Updated iOS native build scripts to iOS 9.3 and TVOS 9.2
- API Addition: GestureDetector#pinchStop() called when no longer pinching
- API Addition: Gdx.graphics.setUndecorated/setResizable API added to Graphics https://github.com/libgdx/libgdx/pull/3847
- API Addition: Gdx.graphics.getGLVersion(), grab the GL version and implementation type. https://github.com/libgdx/libgdx/pull/3788
- API Change: Lwjgl3WindowListener -> filesDropped(String[] files) adds drag'n drop support for the lwjgl3 backend
- Added isComplete() to ParticleEffect to make it easier to know when all the emitters are done, behaves the same as in the 2D API.
- API Change: renamed Lwjgl3WindowListener.windowIsClosing() to closeRequested() to better communicate its intent.
- Add IndexData.updateIndices method to increase performance when used with IndexBufferObjectSubData. 
- Added FlushablePool
- Added ShapeCache see https://github.com/libgdx/libgdx/pull/3953
- API Change: moved shape builder logic out of MeshBuilder, see: https://github.com/libgdx/libgdx/pull/3996
- API Change: Table reset now calls clearChildren, not clear.
- Fixed crashes in AndroidMusic.java when isPlaying is called. Errors are now logged only rather than crashing the app.
- Added emulation of ScreenUtils for GWT
- Improved performance of glReadPixels() on GWT. New method is 20-30 times faster
- Fixed crash on Mac when using LWJGL2, custom cursors and embedding the game in an AWT window
- Fixed getDisplayModes(Monitor monitor) returning wrong data on LWJGL2 backend
- Fixed Gdx.input.getCurrentEventTime() not being set on LWJGL3, fixes GestureDetector and flick scroll not working
- Fixed not being able to select non-latin characters in TextFields
- Bullet: added CustomActionInterface, see https://github.com/libgdx/libgdx/pull/4025
- Add window size limits option to LWJGL3 app and window configurations

Please update your projects as usual.

Now for the juicy bits. New iOS backends!

Re-evaluating our iOS strategy

A few weeks ago, we announced changes to our iOS backend strategy. With RoboVM winding down, we need a new way to get to iOS in the future. After an analysis of various alternatives we decided that Intel’s Multi-OS Engine is the way forward.

The post received a ton of feedback from all over the community. Many people within the community and the libGDX core team feel uncomfortable with relying on yet another proprietary piece of technology like Intel Multi-OS Engine. BugVM was mentioned as an alternative, which is a fork of the old RoboVM OSS project.

MobiDevelop and Xoppa gave BugVM a whirl and concluded that its name is not too far from the truth. The Gradle and IDEA plugins are broken in various ways, everything has been renamed, and many fixes of dubious quality have been applied. It is also unclear who is behind BugVM, what the release schedule is, and how contributions are handled. Finally, the whole repository is a mess and hard to maintain.

As a result, MobiDevelop created his own cleaned up fork of the last OSS release for RoboVM (version 1.8) from September 2015. Since then, Xoppa, MobiDevelop and Tomski have added various improvements to the fork. The guys have performed the first release of the fork, version 2.1.0, so there’s a stable version out there already. If you plan on using RoboVM in any capacity going forward, I’d suggest using this fork over any other forks. Keep in mind that there’s still the bitcode issue which is unlikely to ever be fixed.

Going forward, we have decided to provide two iOS backend options:

  • The new Intel Multi-OS Engine backend
  • MobiDevelop’s RoboVM fork

In order to support both Intel Multi-OS Engine and the MobiDevelop’s fork, we had to make some changes to the setup UI that generates your libGDX projects. You can now select either “ios” or “ios-moe” (or both if you want to compare) in the setup UI.

Each backend comes with pros and contras that we’ll look into below.

Using OSS RoboVM

When selecting “ios” in the setup UI, the resulting iOS project will depend on MobiDevelop’s fork, with groupId “com.mobidevelop.robovm” and version “2.1.0”. If you have an existing project, change the RoboVM related groupIds in your build.gradle to com.mobidevelop.robovm and the roboVMVersion to “2.1.0”.

New projects will automatically use the MobiDevelop RoboVM fork. If you want to switch a new project to the last official RoboVM build, change the com.mobidevelop.robovm groupIds to org.robovm and the roboVMVersion to “1.14.0”.

The MobiDevelop RoboVM fork comes with an Eclipse and IntellIJ IDEA/Android Studio plugin which you can install in your favorite IDE, just like the official RoboVM. This will allow you to compile and run your iOS app without a command line. The Gradle plugin is also fully functional and used by your Gradle builds. Find out more on the MobiDevelop RoboVM fork site.

The existing RoboPods have a dependency on the last official RoboVM release. They have not been tested with the MobiDevelop’s OSS RoboVM version. MobiDevelop will eventually also fork the RoboPods. Contributions welcome!

Pro & Contra OSS RoboVM

Since the MobiDevelop’s RoboVM fork is based on the last OSS RoboVM release from September 2015, there are of course a lot of limitations:

  • No debugging support
  • No TvOS support
  • No interface builder support
  • No bindings for the latest iOS versions
  • None of the proprietary bug fixes done by the RoboVM team since September 2015 are included. Everything that got fixed in the open-source portions has been included in the fork
  • RoboPods may or may not work
  • No Maven support, as libGDX is Gradle based
  • No Junit support, not useful for libGDX anyways
  • No RoboVM Studio. IDE plugins are enough, and RoboVM Studio doesn’t add much for libGDX game development
  • Not bitcode compatible

Here are the upsides:

  • Drop in replacement for RoboVM
  • Working IDE plugins for Eclipse, IDEA and Android Studio
  • Working Gradle plugin
  • Known source, release schedule and contribution policy
  • Stable and tested

Using Intel Multi-OS Engine

When selecting “ios-moe” in the setup UI, the resulting iOS project will depend on Intel Multi-OS Engine. Before you can create a new project, you need to install Intel Multi-OS Engine.

Once your project is generated, you can follow the Intel MOE documentation to get a better understanding of how it works. The workflow will be very similar to RoboVM, i.e. you create iOS run configurations in your IDE of choice, or invoke Gradle tasks on the command line. Tomski is working closely with Intel to improve the workflow and stability of Intel MOE together with libGDX. Due to that collaboration, Intel MOE now also installs a plugin for IntelliJ IDEA instead of just Android Studio.

Pro & Contra Intel Multi-OS Engine

Let’s start with the contras:

  • The libGDX backend is not as mature
  • RoboPods won’t work, all 3rd party libraries need to be bound anew (though that may be easy with the binding generator)
  • You need to have Multi-OS Engine installed for the Gradle build to work. The MOE Gradle plugin is not available in any repository. If you haven’t installed MOE locally, your Gradle build will fail
  • No Eclipse support
  • Higher build times on code changes as everything needs to be proguarded and dexed

Here are the pros:

  • Actively maintained, with bitcode in the pipeline
  • Debugging support
  • Interface builder support
  • Automatic-binding generator
  • Bindings for latest iOS APIs
  • Can compile from Windows if you have a Mac OS X build slave

Up Next

We believe giving you the choice on what technology stack to build your games is the right thing to do. Which of the two options will ultimately pan out is hard to say at this point. There are risks associated with both of them.

For Intel MOE, we hope to receive feedback over the following weeks and months that we can communicate to Intel to improve their solution. Please report any issues you find on the Intel MOE forums or on the libGDX issue tracker if it’s a problem with the libGDX MOE backend.

For RoboVM, it’d be great if the community could look into RoboPods and see if and how they work with the OSS RoboVM version. The best course of action would be to integrate them with MobiDevelop’s fork, push them to that repository and integrate them with the build. Furthermore, Xoppa and Tomski are working on getting line numbers in exceptions working, which is the precursor for (non-JDWP) debugging.

We have updated most of the wiki with new instructions for Intel Multi-OS Engine. If you miss something, speak up on the issue tracker!

Happy coding,
The libGDX team

RoboVM is no more, what now?

For the better part of 2 years, RoboVM has been my life. Today, RoboVM announced its discontinuation, abruptly ending that chapter. The amount of things I learned during that short period has easily overshadowed anything I learned during previous jobs, both on the technical and non-technical side. I’ll deeply miss this daily experience.

So, what does this mean for libGDX? There’s good and bad news. Let’s get the bad news out of the way.

RoboVM is dead, what now?

Quite a few libGDX folks have free RoboVM license keys to deploy their libGDX app on iOS. These license keys will continue to work until the 17th of April 2017. However, there will be no further updates to RoboVM, be it new features or bug fixes. The same is true for all the RoboPods the community came to rely on. Moreover, new sign-ups for free RoboVM Indie licenses will also no longer be fulfilled.

In short, if you have a game using RoboVM already, you can continue using RoboVM until the license expiration date. If you start a new game, RoboVM is not an option. In either case, you should move to an alternative as soon as possible.

What are the alternatives?

There are many alternatives to RoboVM, however, none comes quite close to what RoboVM offered. Let’s examine all the available options. We’ll look at them from various viewpoints: tooling support (IDEs, Maven, Gradle), bindings support, binary size, performance and Bitcode compatibility.

Before we dive in, let me elaborate on the Bitcode compatibility, as it is probably the most important feature. Apple recently introduced a requirement that prohibits submission of apps in raw machine code form for watchOS and tvOS. Instead, Apple wants you to submit your apps as Bitcode. Bitcode is a (not quite) machine independent intermediate language from which Apple generates actual machine code on app submission. Any solution that has no clear path to Bitcode is hence at a big disadvantage.

Mobile OpenJDK 9

Oracle recently announced OpenJDK 9 availability for both iOS and Android. While this seems like the most sensible option, it has a metric ton of down-sides as of this writing.

  • Tooling: No integration with IDEs, Maven or Gradle
  • Bindings: No bindings for Objective-C/Swift APIs. No easy consumption of Objective-C/Swift APIs, everything goes through JNI
  • Binary size: The generated binaries include all of OpenJDK, both native code and the class libraries. Apps are huge
  • Performance: It uses Zero VM on iOS, which is essentially an interpreter. Say goodbye to performance
  • Bitcode: Uncertainty about Bitcode compatibility, the interpreter relies on some assembler and signals, both of which don’t work in Bitcode land

None of this is likely to change in the short- to midterm future, so OpenJDK 9 is out.

CodenameOne

No. Next.

J2ObjC

A while ago, Google open-sourced J2Objc. It falls under the category of “transpiler” meaning it translates one high-level source (Java) to another one (Objective-C). Google is successfully using it for a few of their apps, like Google Inbox. Conceptually, it’s very close to GWT, which we employ to get your libGDX games running on the web.

  • Tooling: Essentially a command line tool. There exists a Gradle plugin that takes away some of the pain, but no other tooling is provided
  • Bindings: J2ObjC is mean to allow you to share business logic while you write your UI in ObjC/Swift. As such, there are no bindings. Also notable is the lack of support for most of the Java SE APIs. This makes including 3rd party Java libraries a no-go.
  • Binary size: very good, mostly due to the fact that it doesn’t have to ship a proper managed environment or Java SE APIs.
  • Performance: very good, it’s essentially Objective-C
  • Bitcode: Out-of-the-box, as things are compiled to Objective-C

With a lack of support for Java SE level APIs, the use of reference counting instead of GC, and the fact it only works for Java source code, J2ObjC is not fit for use with libGDX. One GWT based backend is enough 🙂

Avian

Avian is a great piece of OSS tech. JMonkeyEngine chose Avian as their driver on iOS a while ago, so there is some precedent. Avian let’s you chose whether you want to use the Android class library or OpenJDK’s class library, definitely a plus. However, Avian suffers from a few minor and one major shortcomingy.

  • Tooling: No integration with IDEs, Maven or Gradle, save for the integration JMonkeyEngine did with NetBeans
  • Bindings: No bindings for platform APIs, no easy consumption of Platform APIs, JNI hell it is
  • Binary size: Not terrible when using Proguard
  • Performance: The AOT mode essentially takes the JIT mode output and bakes it into an executable. The JIT is rather primitive, and performance isn’t where it should be
  • Bitcode: No path forward to be compatible with Bitcode, as the AOT directly generates machine code. This is the big one

Avian has always been a favorite of mine, as the engineering behind it is top notch. However, using it in production is just a major pita, and the missing path to Bitcode rules it out completely.

Xamarin + IKVM

Back in the olden days, Michael Bayne of PlayN fame took it upon himself to create a somewhat functional path for Java bytecode to live on iOS. The solution consisted of compiling Java bytecode to .NET CIL via IKVM and shipping a heavily cut down version of the OpenJDK class library. I added support for JNI so we could also use it with libGDX. Suffice it to say, it was a Frankensteinian monster of epic proportions. But it worked. Until Xamarin released a new version, in which case non-trivial bug fixes had to be made. Let’s give this a fair shake:

  • Tooling: No integration with IDEs, Maven or Gradle. Integrates with Xamarin Studio and Visual Studio though, including debugging. Otherwise it’s a bunch of shell scripts.
  • Bindings: Excellent, you are able to call into pretty much all native APIs through the IKVM C#/Java bridge
  • Binary size: Good, were it not for the fact that you also need to ship a huge Java class library next to the Xamarin runtime.
  • Performance: Pretty good, although IKVM introduces some suboptimal paths, which makes this solution slower than RoboVM
  • Bitcode: clear path forward, as Xamarin is based on LLVM

Note that the IKVM fork Michael and I worked on is mostly defunct. The cut down class library is also a huge problem, with things like java.net completely missing. Were it not for the last alternative in this list, this solution would probably win.

Intel Multi-OS Engine

Formerly known as Migeran, Multi-OS Engine is a pretty nice piece of tech that let’s you run Java bytecode on iOS. Under the hood, Multi-OS Engine is powered by ART, Android’s virtual machine, which has an AOT compilation mode Multi-OS Engine exploits.

  • Tooling: Integrates with Android Studio, IntelliJ IDEA and Gradle. Used to have support for Eclipse, but it seems that’s no longer available. Also let’s you build and deploy from a Windows machine (using a Mac as the build slave).
  • Bindings: Provides a custom bridge called Nat/J, which is quite similar to RoboVM’s Bro, albeit quite a bit more cumbersome. It appears that all native APIs are accessible from Java via Nat/J, and 3rd party libraries can be bound (semi-)automatically.
  • Binary size: OK but not great. Bigger than comparable RoboVM binaries.
  • Performance: Good, faster than RoboVM in some workloads, slower in others.
  • Bitcode: Currently unsupported, but apparently Intel is working on it.

Multi-OS Engine comes closest to RoboVM along all these axes.

What is the future of libGDX on iOS?

Tomski has already written a new libGDX backend for Multi-OS engine. Here’s the roadmap for libGDX:

  1. Clean-up the Multi-OS backend, integrate it with the libGDX Setup UI, and update the documentation. We are at a 95% status with this, i hope to have the code drop sometime this weekend
  2. Release a new libGDX version next week, that will make Multi-OS engine the default iOS backend for newly created libGDX projects
  3. Begin creating bindings for popular 3rd party iOS libraries. This is where we hope the community can jump in
  4. Keep the RoboVM backend around until the licenses expire (April 17 2017). We’ll try our best to fix any bugs in the backend, however we won’t be able to fix bugs in RoboVM itself

The roadmap of your existing apps should look something like this:

  1. Keep publishing updates using RoboVM 1.14.0 and the corresponding backend
  2. Immediately start adding a Multi-OS engine based version of your app for iOS
  3. Test it and report bugs on our issue tracker
  4. Switch over to Multi-OS Engine as soon as possible

In Closing

There will be some rough edges with the new Multi-OS Engine backend. We are in contact with Intel, who have been very reactive in fixing issues we identified while creating the new iOS backend. Please help test the new backend and report issues, so Intel is able to fix problems on their end.

Multi-OS Engine is free to use, but not OSS. Before you guys start screaming for my head again, I’d like you to read the above analysis carefully one more time. None of the OSS options are even close to production ready. I will however happily merge any and all backend based on those OSS options.

I’d be grateful if everyone funnels their emotional energy created by this announcement into helping out with the new backend, e.g. testing, bindings, reporting bugs etc. I believe this is a much better use of everyone’s time. If you feel the need to vent, I understand. But please don’t expect me to vent with you. The winding down of RoboVM is already emotionally taxing enough for me. My goal is it to keep things running smoothly for everyone, I have no intention to waste time on a screaming contest.

Happy coding,
Mario