Making Of Exp3D: Architecture

People asked me a few times what kind of technology was behind Exp3D, which programming language I used and how I could come up with a Javascript version… so I thought I would explain a few things here.
I didn’t use any popular game engine (like Unity), rather I wrote all my code from scratch, for fun, because I do enjoy writing engine code and experimenting with low-level stuff.

What might surprise some is that Exp3D is entirely written in Java.

Exp3D is 100% pure Java

Why? Because when you make a game, you need iteration cycles to be as short as possible.
You want to see the result of your code changes immediately on the screen.

Traditionally you would write a game in C++, and as the codebase grows, compilation time gets longer. Change one line in some file and you won’t be able to see the result before a few seconds or minutes. The process ends up wasting a huge amount of time and the issue is extremely difficult to solve in C++.

Interpreted languages (Python, Ruby, Javascript…) don’t suffer from this problem, but unfortunately as of today they perform too poorly on mobile platforms to run a game, even when JIT compiled.

So this leaves us with only 2 viable options: JVM languages like Java, or CLI languages like C#.
They both have good performances and short iteration cycles.

Live-coding is the future

An argument in favor of Java is that, while C# dramatically reduces iteration time by having a fast compilation phase, Java simply has no iteration time – at all.
Basically, while your game is running, you change some source file, hit Ctrl+S and boom, your changes appear in the game.
This is true live-coding. After you got a taste of it, there’s no coming back to the old “stop – compile – launch” process.

This is how Notch can write games from scratch so quickly:

So the JVM is great in that it can transparently replace the code of a function during its execution. However that doesn’t mean Java is a silver-bullet, far from it.

The pitfalls

Java is not perfect: unlike C#, there is no mechanism to explicitly allocate memory on the stack, which is a real bummer for game programming. Also the Dalvik VM on Android is quite young and the performance is nothing like its Oracle counterpart on the desktop, but it’s improving.
C# can provide more flexibility than Java but be ready to open your wallet because Mono licenses are not cheap.

But whether you use Java or C#, the garbage collector is your worst enemy. Arbitrary GC pauses are simply not acceptable in real-time applications, so you end up implementing pools for your objects like I did in Exp3D, just to have an allocation-free game loop.

In the end it all boils down to trade-off: iteration time, performance, money, programming efficiency…

Code structure

The structure of the program is roughly like this:

The core of Exp3D is about 25,000 lines of Java. This is exactly the same source shared on all the platforms.
To be able to do this, the game code relies on a small framework which acts as an abstraction layer, hiding platform-specific implementation details.

The framework has 3 backends:

Android backend

The rendering uses the OpenGL ES API of the OS. Sound and IO also rely on Java APIs of the OS like the SoundPool, the MediaPlayer and the Android file system.

Desktop backend

Here, the rendering is done through JOGL which provides an OpenGL ES API for Windows, Linux and MacOS. Sound uses JOrbis, a pure Java implementation of an OGG Vorbis decoder.

Web-Browser backend

This is where it gets interesting: GWT is a tool originally developed by Google that transcompiles your Java source files into Javascript code.
All I had to do was create some bindings that would expose to Java the browser API related to WebGL and HTML5 Audio. It’s very easy to integrate already-made bindings like gwtGL or gwt-voices. WebGL API being almost the same as OpenGL ES 2.0, implementing the rendering part was straightforward.

I first saw GWT in action in 2010 in the Atlanta Google offices, back then they had a demo of a playable version of Quake 2 running in Chrome.
In 2011, a HTML5 version of Angry Birds was released, also powered by GWT.
So I figured GWT could probably do the trick for a simple game like Exp3D and indeed it worked like a charm.

What about iOS?

Until recently, porting a Java game to iOS was extremelly difficult. The only “hack” was to run your Java program with IKVM, running on the top of Monotouch, but at the expense of performance. The situation changed completely over the last few months when Niklas Therning did something that Oracle should have done years ago by releasing RoboVM, an AOT compiler for Java specifically targeting iOS.
If in the future I port Exp3D to iOS, this is definitely the middleware I will use.

Conclusion

For my requirements, Java proved to be a good match:

  • no iteration time
  • good performance
  • cross-platform
  • open-source libraries and runtime, with no license cost

It was a huge time-saver, and I got a HTML5 version with very little effort.
But again, I was mainly focused on programming-productivity and license-free tools, your priorities might differ in which case another language might be better for you.

On a side note if you’re interested in this kind of Java framework, there are already some popular ones out there like libgdx or PlayN, I highly recommend them.
When I started Exp3D, more than 2 years ago, those frameworks were very young and not as mature as they are today, that’s why I rolled my own solution – in part because of this but also for the fun of coding my own framework. ;)

Comments