Lessons of a Java game developer

I’d like to spend a few moments discussing my learning experiences with the rather unorthodox decision to develop Remnants of the Precursors in Java. For reference, anyone can download and try the game (it’s free) from this link: https://remnantsoftheprecursors.com/2017/09/01/alpha-4-is-available/

If you want to discuss the game or report any bugs, please use our subreddit at http://www.reddit.com/r/rotp

When I first sat down to write this recreation of original Master of Orion (not MOO2!), it seemed very natural to me to choose Java as the development language. I knew the language well, it was well established, and I knew it could handle graphics and sound. Even though I had never developed a video game before, I knew that Java was a Turing-complete language so what could go wrong?

Well, for starters Java has a reputation as being a slow-performing language. It will never be as fast as C, nothing is, but very few teams write large applications of any real complexity in C anymore. C++ is also much faster, but that language is a hot mess with object-orientation bolted onto C. I’ve some done work in C++ in the past with the Trinity MMO project, but otherwise I’d rather avoid it.

Possibly the biggest problem with Java is that it makes it very easy for someone to write slow code. It’s also a widely-used language for corporate server applications, so there is a tremendous emphasis in the Java community on coding patterns that result in faster development and simpler maintenance. Performance problems are then worked only as they pop up and only when it’s more expensive to throw cheap hardware at the problem than to pay for expensive developers to fix them. This is not an exaggeration. We are that expensive!

On the other hand, game development is on the opposite end of the spectrum. Teams are small and performance is absolutely vital. As an example, the Remnants team has one developer (me) and the Raspberry Pi Zero (512Mb) is targeted as the minimum viable platform. This is exactly opposite of my real job, where we have several large teams writing code for servers in the cloud.

As a result, I now often have to pretend I’m writing in C — just like my old days! I am slowly rewriting a lot of code previously written in my well-traveled object-oriented Java style into leaner, C-like code that relies heavily on primitive data types and a data-oriented design. Variables originally defined as List<StarSystem> or List<Empire> quickly get reduced down to int[]. Objects and classes are still used and extremely useful, but as much for code organization as anything else.

Fortunately, Java is syntactically very much like C. This was very useful when I found a neat, publicly-available program for generating realistic-looking planet maps from a random seed. The code was written in C, so it took me only part of an evening to rewrite what I needed in Java. I even wrote some custom code to make the 2D image appear to rotate as if it were 3D!

While the resulting code in my game would look like heresy to most Java developers, the proof is in the pudding. The game now runs noticeably faster and uses a lot less memory to boot. It’s looking less and less like a stereotypical “Java game” and more like just a video game.

To give you an example of the difference… most commercial space 4X games top out with maps around 1000 star systems. Remnants has options for much, much larger maps that I originally added for diagnosing scaling problems (that’s from my corporate developer side). Here are some recent quotes from players talking about their map sizes while testing:

“I was testing the larger galaxy sizes to see if my PC could handle them. 471k has a bit of slowdown, but 100k is flawless.”

“Oh yeah, I got almost a million star galaxy! Very nice! Slow, but maybe even playable. I didn’t try that more than a few turns and went for a much smaller galaxy.”

And of course, there’s this screenshot of a coworker friend playing the latest Alpha on his Raspberry Pi Zero:


What’s the point of all of this? That the Java language turns out to be perfectly fine for writing video games, only you can’t approach it like a Java developer. You have to approach it like a game developer.

So why choose Java, then? I can think of two good reasons: 1) you are already proficient with Java, and 2) Java is the most-known programming language in the world, making it an ideal choice for open-sourcing, which also applies to this project.

EDIT: I would like to add another reason to use Java provided in the subreddit thread:

“I think the best reason to write a game in Java is portability. With many languages, targeting multiple hardware platforms and OSes requires cross-compilation and sometimes separate native compilation. Each target also ends up needing its own binary. It took zero effort to make your game run on the ARM CPU of my raspberry pi thanks to the JVM. That’s awesome!”

Appendix: Game Development Engines

Game development engines like Unity are awesome because they allow you to exploit your video hardware to develop games with eye-popping 3D graphics. All commercial studios and most indie developers use them because we all know that graphics are what sell games. It’s not uncommon for aspiring game developers to decide what engine they want to use before anything else.

However, these engines are essentially 3rd-party kits driven by their own languages and coming with their own set of advantages and disadvantages. For the vast majority of game developers, those advantages far outweigh the disadvantages.

So why am I writing in straight Java and not using an engine? The game I am remaking has 2D graphics, so I don’t need the 3D capabilities of video cards. This means that I can do everything in straight Java, even the animations, and not deal with even the few disadvantages of the engines. For example, “3D artwork and modeling” is the name of the graveyard where video game budgets and deadlines go to die, so I don’t have to worry about that.

As a consequence, Remnants runs completely on your CPU. If you don’t have a video card, no problem. You don’t have to worry about updating DirectX or video drivers or anything like that. Just drop the file in a folder and double-click it to play the game.

That’s all I’ve got to say, thanks for reading!

Discuss on Reddit

3 thoughts on “Lessons of a Java game developer”

  1. Nice writeup. One thing to remember working with performance-critical Java is off-heap memory storage and memory mapped files. That comes in handy even in server-side enterprise development.

    How about GC pauses? Which GC do you use? G1?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s