LibGDX (Or how I learned to stop worrying and love Game Development)

Category: Articles Created: Sunday, 05 October 2014 Published: Sunday, 05 October 2014 Written by Troy Peterson

Introduction

When James and I decided to write The Shaft last year we had no idea how much we would enjoy it. In fact, I don't think either of use actually expected to maintain interest in the project long enough to reach an actual release. But we did. Out of everything we learned through that process though, one of the most significant lessons was that although writing games is very different from writing enterprise software, like any development task some bits are fun... and some are not. Writing boilerplate is not.

 

We looked at Libgdx before starting The Shaft, but... call me stubborn I guess... I did not want 'help' with the task. I felt that our first game writing experience should be as pure as possible. I wanted to truly understand the capabilities and limitations of the Android platform that we were writing for so that we would have a baseline understanding of how an Android game works. Now that we do, it's not something I want to do again. I personally recommend this approach to future game developers too. Try writing something for your base target platform first without the help of any libraries. You will learn a lot about the platform and you will learn and appreciate the value of your library.

 

And do it was that The Shaft came into being through the sweat and tears of two developers using only IntelliJ Idea, the Android SDK, Java, and OpenGL. Now we understand. But what of the future? The Shaft is certainly not the end of it. Now with tons of new ideas for great games coming every day we need to explore options for streamline our processes and eliminating some of the low level work so we can focus on the games themselves. Libgdx sounds like the ticket, but what is it really like to work with? Before we commit to a larger project we decided to start by just taking an existing game concept that we knew we could do quickly and building it in Libgdx.

 

An Engine, a Framework, or a Library

There is no 'official' distinction or definition for what qualifies as a game engine, game library, or game framework. You will find this debated all over the internet with all sorts of conflicting advice. I personally feel that the three terms do have clear distinctions in terms of how close to the hardware you work. To me, a game library is just some source code (or a .lib, .dll, .jar) that helps you with your task. It makes no assumptions about what you want to do or how you want to do it, giving the ultimate in flexibility. A library should mix-and-match with other libraries cleanly. It should not stand on it's on, but instead require the developer to do all the work to put it together.

An engine, however, is at the other end of the spectrum. An engine is a stand alone product that runs by itself without any work from the developer. It requires only that the developer add resources and define work-flow and events. Engines are gui driven and allow the developer to focus purely on the game itself and not the nuts and bolts underneath. This means that you are restricted to features of the engine. Ultimately, you can only do things with it that the engine developers expect that you want to do. In theory this is the quickest way to bring a product to market... But not always. Not everyone can flex their minds to work inside the rigid structures provided. If you conceptualize things differently from how they are modelled in the engine then it can be difficult to adapt. And some of us just need to know what happens below the surface.

So then a framework is the broad grey area in between. It will take the form of a library with a large amount of open code available for you to modify and plug-in what you need. Thus you can create a game quickly by just modifying the bits you need, where you need them, but when required you can rip out the heart of it and rewrite it as required.

So which is Libgdx? I personally classify it as a Library, though some elements certainly fall into the 'framework' category. With LoggerBill we took Libgdx as a library and built our own framework to use for future games. We now only have to write a new engine class and drop it into create a new game.

What can LibGDX do?

LibGDX is first and foremost a 2d game library. Although it has support for 3d (which I havn't really evaluated yet) it's 2d sprite capabilities is really where it excells. This is good, because support for 2d sprites is almost non-existant in core Android. If you want to do any decent graphics animation for a game your only option is really OpenGL. OpenGL is a pure 3d library so you essentially have to resort to doing flat rectangle polygons with your sprites applied as textures to them. This is what LibGDX does, but you no longer need to worry too much about how it's doing it since it gets abstracted into a much cleaner interface. That's not to say that you should ignore what is happening underneath. In fact I think it's really vital for anyone using LibGDX to really understand what it's doing in order to get full benefits from it.

One handy feature, for example, is it's handling of "sprite sheets". A sprite sheet is simply a collection of your game images ('Sprites') all put together in a single file. This is standard practise for any gaming application, however there is no support for it in core Android or OpenGL.  For The Shaft we designed all of our sprites to use consistent dimensions and manually laid them out into a grid on the sprite sheet using consistent rules so that the game could go grab the part of the sprite-sheet that it needed. For example, along the top row we placed images of the ship without the retro-thruster firing. It was 5 ship-widths across, so right in the middle of the row was the plain ship. One slot to each side had images of the ship with the side manoeuvring thrusters firing on low (left and right respectively). Then the next slot over on each side had the thrusters firing on full. The line down then had the same layout of the ship, but this time with the retro-thruster firing in all positions. And finally, the bottom two rows contained frames of the ship explosion animation.

This manual-sprite sheet approach is time consuming and difficult to work with if you can't easily assign a logic to the image placement that can be determined programatically. The result for anything more complex is that you need to place your sprites on the spritesheet, determine the x-y coordinates and boundaries for each sprite and then save those into some structure that can be loaded into a sprite handling class. This is exactly what Libgdx does for you automatically.

Performance of the 2d graphics was pretty good for what we did. I can't say we really pushed any boundaries, but I have no doubt that it will scale up to much more complicated games with ease. One reason for this is the SpriteBatch class in Libfdx. This saves with the most performance-draining aspect of any OpenGL coding in Java - context switched. Basically, every time you communicate with OpenGL from within Java the VM (virtual machine) that it is running on (whether that is OpenJVM, the Oracle JVM, Dalvik, or some other VM) needs to call the native system drivers and pass a bunch of data back and forth. This can be expensive and represents a performance bottleneck. Libgdx gets around this by allowing you to build up your graphics commands in a batch and sending them to the OpenGL subsystem in one shot. It is very easy to use and well implemented.

The other main feature of Libgdx is portability. It gives you the hypothetical ability to write your game in Java and then run it on PC's, iOS, Android, or even in a web page. I say 'hypothetically' because you can't just assume your program will automatically work on all of the platforms without some special care and attention. This cross-platform capability however is central to Libgdx and comes at a cost - you loose easy access to the core libraries and capabilities of each system. For example, Android doesn't support a Swing GUI - so neither does Libgdx. Windows doesn't support Android GUI widgets... so neither does Libgdx. Because of this, all of the essential elements that you need to use in a game must be provided in Libgdx. The underlying implementations for each platform are hidden away within the Library.  The most important feature of course is the GUI elements. Since you cannot access the native GUI controls and elements of your platforms (and still maintain cross-patform capability) Libgdx provides a set of basic widgets as well as a layout manager mechanism.  However, I found this part of the library to be one of the hardest bits to work with. The widgets themselves are limited in capability compared to native components and the layout library (scene2d-UI) doesn't always do what I expect it to. You do not have any sort of drag-and-drop designer to work with (that I'm aware of... if someone has written one, please let me know!).

Other features provided by LibGDX that replace core system functions:

File Handling

Since the operating systems on different devices vary greatly in how their file systems work Libgdx needs to provide rudimentary file access itself that wraps the system calls. The functionality is Libgdx is basic, but good enough for most tasks. Games typically do not need advanced file capabilities. One great feature that is included is the Gdx.files.internal method that lets you easily access files saved inside your package (jar, apk, etc).

Fonts / Text

Unfortunately, text is something that is more complex than one would generally imagine when it comes to writing a game. OpenGL has no support for text built-in, and since fonts and their access methods also vary between operating systems you really can't use the OS provided features. The solution that Libgdx gives you is the ability to create a 'BitmapFont' which is essentially a sprite-sheet with each letter as a sprite. The text handling capabilities put the right letters in the right places. Don't expect miracles from this. You need to create font sheets for all of the fonts you want to use and because you are using rasterizations of your vector fonts they tend not to scale well... Also there are complications for non-latin character sets, etc. Solutions exist for using TrueType fonts by dynamically generating font sheets on the fly, but that adds to the complications.

Audio

Audio support in Libgdx is again, fairly rudimentary but it works. Audio is an important part of most desktop games games, but I think most people turn off the sound on mobile games... It's an essential feature for a great game, so LibGDX provides you with the basics, but no more. It works and is easy to use. We had no issues playing music and sounds.

 Other Useful Features

Math

LibGDX provides a few simple Math functions that complement what is already provided. The most useful of these, in my opinion, are the interpolation functions. These are functions that calculate transitions between two endpoints and are great for animating movements. We use one of them to animate our paused dialog box in LoggerBill, but because they are generic they can be put to many other uses. The algorithms for these interpolations are not complex and can be hand-coded quite easily, but since LibGDX provides them conveniently there's really no reason not to take advantage of them. Also in the math section of the library you'll find classes for producing curves which is great for more natural path animation, and some model classes for geometric shapes. There's nothing ground-breaking in here but the implementations are clean and handy when you need them so you don't have to re-invent the wheel.

 

XML / JSON parsing

I personally believe XML is over-used... In enterprise programming you see XML everywhere and it is hellish to work with and the overhead is inexcusable for high performance systems... Yet it remains pervasive. There are some few cases where XML is great though... I won't get into those here... I generally find name=value pairs to be an ideal method for encoding information in most cases but it does have limitations, especially in terms of nesting... That's where JSON comes in. JSON is sort-of in the middle between XML and Name=value pair files. It effectively describes data in name=value pair format, but can be nested and contains some extra syntatic rules for formatting that helps with readability. In the Web world JSON is great because it is itself valid Javascript code and can be parsed in directly. Java can't parse in JSON directly, but thanks to Libgdx it's not hard to work with. LibGDX provides some great serialization/deserialization functions for dealing with both XML and JSON. It also provides parsing functions that don't require reflection. This is a great way to store data such as levels and such in your code. The built in 'skin' functionality lets you define properties of your GUI elements outside of the code for easy swapping and tweaking of styles. This is fantastic functionality that we expect to use extensively in future games.

 

Limitations

 When you decide to use a cross-platform library like Libgdx there are some sacrifices that must be made. Basically, anything that is native to a specific platform is no longer available. So when moving from Android to Libgdx we missed Android's wonderful layout mechanism. Scene2D-UI works... but not nearly as well as the core Android gui. We also missed the ability to run services in the background. You can do multi-threading, but the Android Services are really quite handy... Now it would be possible to still integrate background services using the Android launcher, but it's much more difficult and limited...  One of the biggest paradigm shifts when moving from core Android to Libgdx is the fact that everything is a single screen as opposed to being able to have multiple 'activities' in Android. It's rather like the old Dos days when you have to handle everything on a single screen yourself. Libgdx does provide a Screen interface to allow you to easily build and switch screens, but ultimately you're just designating which class has access to draw on the screen at any given time. Android activities are far more flexible in this regard.

The learning curve

 Surprisingly easy. I started out with the only book that I could find on Libgdx, called "Learning Libgdx Game Development" and it was a good place to start. The book is a little dated now because the library moves fast, but it covers the essentials and gives a good grounding in the basics. Still, there is a lot of room for other books on the subject and there don't seem to be any. The library itself is fairly well documented for a project of it's type, but there are holes. Especially when it comes to extending it. For example, I tried creating a Scene2d-UI widget myself and found that the methods that I needed to override were not clearly documented. I wasn't sure what they were supposed to do. I found myself referring to the source code for Libgdx for many things. For writing OpenGL shaders I found that samples which I grabbed from the internet would just not work. That's because the Libgdx framework expects certain uniforms to be present and named specifically... I found documentation on this to be a little slim. There are a lot of tutorials out there though if you look around and there is a lot of sample code available (including LoggerBill).

Conclusion

In building a simple game on Libgdx we've built a framework that can easily be ported to other future games. We've decided to stick with Libgdx for most of the games that we have in mind since Libgdx provides everything we need for them.  There have been some painful moments with it, but the joys of the library outweigh the pain.  I reccomend for most people to play with core Android (or iOS) first to get an idea of what's going on below... It's extreamly valuable experience. But for just writing games Libgdx is a viable option that gives you some great capabilities without sacrificing too much in the way of control and you don't have a huge amout of overhead from engine code that you do not use.

Hits: 4559