Don’t exactly remember how, but last night I came across Code Analyzer, an open source Java desktop utility that counts lines of code. Out of curiosity, I downloaded the runnable jar file and tried it with Libgdx.
I was very much aware that Libgdx was a pretty big project but certainly didn’t expect it to be that large. At the time of writing the HEAD of the repository contains 1.048.646 lines of Java, C and C++. 712.016 of which are actual code, 17% are comments while the rest are just whitespaces.
Not bad, huh?
Although this is obviously not a quality indicator, it shows how big of a baby it is.
Developers love Libgdx, it’s an extremely efficient, easy to use, open source, feature rich, cross platform framework. It has a huge community, and a very active repository. What’s not to love? The fact that 1.40% apps on AppBrain use Libgdx backs that up.
Have you thought about contributing back?
Yes and here’s why.
So much win
The beauty of a healthy community driven project such as Libgdx is that decisions are crowd-sourced and code is always peer reviewed. Although this may feel intimidating, don’t let it put you off, take it as the fantastic opportunity to learn that it actually is. The most active developers over there are talented, very talented. That’s the kind of people you want to hang out with, just so eventually, you end up absorbing some of their skills.
Personally, that’s what I do.
Some pull requests contain interesting discussions about software design and programming.
Low barrier of entry
Regardless of your level of expertise, there surely is something you can do. From maintaining the documentation to fixing that annoying old bug or introducing a small feature. All contributions are welcome. Actually, even the tiniest thing will bring you closer to the codebase and lead you to a better of understanding of it.
Everyone makes mistakes, and when that happens, people will politely point it out, giving the contributor a chance to fix it and resubmit. The community is understanding and I haven’t seen any attempts to bring shame to anyone.
Even from a purely selfish standpoint, there are pretty strong reasons to get involved with open source projects. Even more so if you’re a student or will be looking for a job in the foreseeable future.
Yes! I want to get into the industry!
Sorry to break the bad news for you, once you finish university you’ll be out in the wild with thousands of other employment hungry graduates. They tend to complain no one will hire them because of their lack of industry experience. See the vicious circle? Luckily enough, that’s nothing more than a bad excuse in the software industry, where the requirements to ‘make it yourself’ are negligible. All it takes is a computer with an Internet connection, which I’m pretty sure you already have.
Working on personal projects that you might eventually open source is fantastic and will make you stand out. However, collaborating on a big project with other people reflects so much better on you. Companies need people to jump into projects and get the hang of it ASAP. That involves being comfortable with gigantic codebases written by people you don’t know or just met and being able to identify as well as fix the problems within it.
A big open source project gives you that education, for free. Companies will appreciate that enormously.
I’m experienced and looking for a job.
No doubt other similarly experienced people are seeking similar positions right now. You will compete against them in the hiring process. What’s going to set you apart? Exactly, going the extra mile, possibly through open source projects, being active in a community, blogging or public speaking… You get the hang of it.
I guess if you’ve read this far, we agree to some degree and you might be interested in getting involved.
In order to start contributing back to Libgdx, it’s advisable to read the Contributing wiki page. Later on you should do the following.
Fix your Timestep is a fantastic article by Glenn Fiedler that explains the different ways to tick a physics simulation. Show some self-respect, go read it and check some of his other articles on physics and network code. Some might be 8 years old but still totally relevant.
Essentially, it covers different approaches to pick a delta value to pass through to the physics engine along their strengths and weaknesses. The topic is complex but has an undeniable impact on games’ behaviour.
I thought it would be a good idea to show how it translates to a Libgdx application using the Box2D physics engine. Note that it also applies to Bullet, changes would be minimal.
Simple but wrong approaches
It starts with a fix time step of 1/60th of a second, which makes for a stable simulation but fails terribly when the game runs at less than 60fps, a very common situation in mobile devices.
The logical upgrade is to pass exactly how much time has passed since the last frame. Obviously, not every frame takes the same, which means the simulation could be unstable. Moreover, it will vary across devices as they can feature a wide range of specifications. This is definitely not the way to go.
Everything is lost!
If only we had the best of both worlds! A fixed timestep and a mechanism that caters for the render loop being too slow. As the article explains, the physics will always be stepped by a fixed amount, let’s say 1/60s. Some machines may be too fast and render at 120fps, so we can run the physics twice. However, others might be too slow and render at 30fps, in which case we’d only step the physics one every two frames.
What happens when the game runs at 50fps?
We need an accumulator where we can put the time spent by the renderer. Then we step the physics by a fixed amount until they sync as best as possible. There might be still be some time left, but we can save it for the next frame.
The accumulator >= step condition in the while loop means we can still have some time left in the accumulator but not enough to step the physics at 1/60s. This results in some visual stuttering, as the physics can get slightly out of sync for a while. Glenn Fiedler’s suggests we interpolate our entities’ transforms between the previous and current physics state based on how much time left is in the accumulator.
I entirely made EntityManager up, it simply should maintain a collection of your game entities. We assume entityManager.update() iterates over the list of game entities and updates their position and rotation according to the current physics state. On the other hand, entityManager.interpolate() should do something like the following.
Although it’s been simplified for the purpose of this text, the following snippet comes from SionCore.
A working sample
Libgdx community memeber, Just4phil, pointed out in the comments the advantages of using a fixed timestep with interpolation. He kindly provided a working sample that lets you switch between all approaches explained in this article. Not only that, he also linked to the source, which is really awesome. Kudos.
Today I created a repository on Gihub to keep track of my code base and I named it SionCore. This wasn’t made overnight, it’s the result of several small game projects, such as game jam gigs and Math Maze.
Slowly, it became obvious that some components were highly reusable and game agnostic. That is why I thought it would be good to make it public.
Who knows, maybe someday someone might even contribute!
This small game engine is built on top of Libgdx and Ashley among others and it’s compatible with desktop, Android and iOS platforms.
SionCore is currently under heavy development, so expect constant API changes and a good deal of instability. Hopefully this one will last longer than my poorly executed previous attempts and will stabilise in a while. If that’s what floats your boat, you’re more than welcome on board.
Regardless of whether you use the whole thing or grab specific ideas, feedback is more than welcome.
Currently implemented and working.
Data driven entities
Entity components and system collection: rendering, animation, physics…
Localisation with automatic generation of template CSV files.
Easy screen management
Data driven sprites
Data driven physics
Grouped asset management
Basic state machine implementation
Populate your Box2D world from map data
Multiple aspect ratio support
As of now, all the .jar files SionCore needs are included in the repository. However, switching to Gradle or Maven is something I want to get out of the way sooner rather than later.
If you find a bug or would like a particular feature, please open an issue. On the other hand, if you want to get more involved, clone the repository and open a pull request!
After approximately 5 months of work, Math Maze went live on Google Play on September the 2nd, so I thought a little postmortem was in order. For those who are not aware, Math Maze is a very simple brain teaser math based game.
The player has to move a purple block across a labyrinth towards the exit. However, there are numerical conditions blocking the way. In order to traverse them, the purple block has to combine itself with operations. I can imagine you’re deeply confused by now, so please check the trailer to see what’s the deal.
Adobe Flash and Adobe Premiere to produce the trailer
Most of the time I worked on my own but, luckily enough, I got help from a bunch of people in areas such as localisation, SFX (Ross Tregenza) and OST (Evergreen Studio).
Math Maze packed textures
Downloads, ratings and press coverage
Despite the fact of having worked hard on PR, its non existence price barrier and the complete absence of adverts, Math Maze has a negligible download count. Don’t get me wrong, I didn’t have delusions of grandeur for the game, but I’d have hoped something slightly better to be completely honest.
Here’s a chart showing the current user installs over time, each pin corresponds to one of the app updates released up until now.
Current user installs over time
On the other hand, reviews and ratings have been quite positive. 33 people rated the app giving it an average of 4.88 stars. Judging by feedback I got from reviews and emails, users seemed to like the core mechanic as well as the music and the overall simplicity of the game, which was very nice to read. I hugely appreciate the fact that people went through the trouble of contacting me.
Current ratings on the Google Developer console
Along Math Maze, I also released a pressKit() site and the trailer you saw at the start of the article, which took me ages to put together. After reading tons of articles about PR and how to approach the press, I proceeded to do so. My target audience are kids and their parents who would presumably introduce the former to the game. That’s why I sent dozens of emails to educational and indie games websites as well as schools in the East Midlands area.
It didn’t help much, though.
Here’s a video illustrating the progress of Math Maze’s Git repository during development. For those interested, it’s rendered using Gource, an open source project that grabs your Git history and creates an interactive time lapse using OpenGL. Truth be told, it doesn’t provide a great deal of useful information, but hey, it’s really pretty!
What went wrong
Math Maze is mostly for kids and I wanted it to reach as many territories as possible, so localisation was pretty much mandatory. I wrote a simple LanguageManager that grabs the system’s locale strings from a CSV file, so they would be easily editable by potential contributors (let it be with Excel or Calc). A neat Python script would scan the project directory in search of strings that needed localising using regular expressions so as to generate the CSV templates.
Math Maze ended up being localised to English, Spanish, German, French, Romanian, Finnish, Portuguese and Polish.
I was very happy with the system, it was clean, fast and, overall, made me happy.
However, I missed one tiny but painful detail. I could only maintain the English and Spanish languages, so adding new strings in subsequent app updates ranged from tricky to impossible. Next time I shouldn’t translate such a simple project to so many languages in order to retain more control over future content.
With Math Maze I had the goal of learning the basics of PR and games. Despite the fact that such goal could be considered met, Math Maze didn’t do well in the media at all. Basically, nobody cared.
Make a trailer: I’m no film director and I did what I could, but I think the result is acceptable.
Carefully choose your target: only emailed small indie games and parenting sites as well as schools.
Tidy and up to date pressKit().
Links to download and trailer always on sight.
Personalise every single email, be friendly but polite.
Come up with a hook: AI programmer in the AAA industry working on free mobile titles for kids on his spare time.
Use Twitter and Facebook.
You get the gist of it.
In the end, only The Android Parent and AndroidTapp seemed to pay Math Maze any attention, for which I’m truly grateful. As for the rest, I honestly don’t know the reasons behind the lack of interest. The scope was tiny but I believed in the game’s quality. I should probably analyse this one more deeply and carefully. If you’re reading this and have any suggestions, by all means, leave a comment with your ideas.
Early in development, some people started to point out that the game lacked a tutorial to explain the core mechanics. To address that issue I just added some help text at the beginning of each level where a new concept was about to be introduced. Although this did the job, I should have worked harder on a completely integrated in game tutorial system that relied more on icons rather than text.
Help tip before one of the levels
Level creation was exclusively data driven and required zero programming work. However, the ratio between the time it took me to make a full level over an average user finishing it was ridiculously high. This made content generation a lengthy and cumbersome process which resulted in a short game that could be completed in less than half an hour.
To be completely fair, the time I had to work on Math Maze had always been very limited so this was to be expected. Next time I intend to explore the realms of procedural content generation. Even though it requires a huge investment up front, I think it’d pay off in the long run given my circumstances.
Designing a level in Tiled
The corollary of the previous point is that player engagement became impossible once they finished the 40 levels Math Maze puts on the table. Mistake that I believe it really hurt the game. These days, every single game comes with a mission system, leaderboards and achievements. Math Maze’s design should have been built taking mid to long term player engagement into account.
The mission system in Jetpack Joyride is a very engaging feature
What went right
LibGDX and the third party libraries I used were clearly an excellent choice, I could not be happier with the framework and its community. So helpful and kind whenever I needed any assistance.
LibGDX has a brilliant performance and, as long as you don’t write crappy game code, your game will run on a massive variety of phones. The lowest end I got to test was an outdated HTC Wildfire and it was absolutely flawless. Development was also smooth and every problem I faced came out of my own incompetence as opposed from a potential tech bug.
Currently, there is no other open source framework that can rival LibGDX and I’d dare to say it tops some commercial packages thanks to its flexibility, performance and access to the source. Eat that Corona & company.
Working in the triple A games industry can be demanding and, if you still want to have any kind of social life, you’re going to struggle to find any gaps for personal projects. This made me realise the only way I could only pull this off was if I managed to keep the scope as reduced as possible. Looking back, I think I did reasonably well. Surely 5 months is a long time for a game like this, but it’s not that much when you consider the context in which it was developed.
You’ll read this an unholy amount of times, do not over scope.
I was very much aware of the importance of early playtesting. From the very beginning I showed Math Maze to those closest to me. Just gave them the phone and let them experiment. Immediately I could detect a thousand usability problems and got to address them from then on. Had I released the game like that, it would have been much more of a disaster than it already was.
Moreover, I decided to organise a little Closed Alpha among a broader circle formed by friends and people from the development community. Sending instructions and APK by mail is a pain in the arse but luckily enough, Google provides a nice system for this.
The process goes as follows:
Upload your alpha/beta build to Google Play as such
Create a Google+ community and invite people to it
From your developer console, provide the community with access to the build
Now everyone invited can download the game as if it was any other Google Play app and provide feedback through comments on the community. Moreover, you can update your test build and everyone will automatically get it. It’s comfortable and highly convenient.
Anyway, I’m very happy I invested time on this because it made Math Maze a much better game after I addressed all the issues people kindly pointed out.
Math Maze art is not super fancy but I think it works because I decided to keep it simple by sticking to the little I knew. Quite some time and patience with Inkscape helped me find a consistent style that could be apply to the whole thing. Big icons, simple shapes, bright colours and some basic shading, that’s all it is.
Fortunately, that alone makes a difference and it’s the takeaway from all this. No need for flashy effects, just give the product a clear, consistent style. As if this wasn’t hard enough already!
Math Maze UI in Inkscape
Indeed, localisation was a bad part but also a positive one. The fact that so many people could contribute their translations for Math Maze so promptly proved that the system worked flawlessly. I will probably go through it in detail and share the Python script at some point so you can also benefit from it.
Would I do it again?
I won’t lie by saying everything went as expected. As a matter of fact, it was a bit tough to see how much effort I had invested in the project and how almost literally nobody cared. However, that’s just how I felt for a while after the release. Later on I realised how much I had learned by putting this together and that’s what really matters.