This is the development blog for Hoard Lord: our Android game coming to Google Play. These blog entries will go over general and specific technical design issues we've come across during development of Hoard Lord, which is still ongoing. For reference, here's a recent video with most of our current gameplay:
I wanted to make a special post about how jumping mechanics work when you're using a physics system in your video game. Truth be told, I don't really consider this an ideal situation. Ideally, you would want your 2D game to be simple enough to not have to resort to using Box2D to handle platformer physics. There are a lot of things you basically lose control over once you start using a physics system. In the rest of this post you'll see how we can manage a "Mario style" jump in the Box2D physics system. The ideal situation would have been to have my own physics system that is much simpler than the complicated system of forces and collision responses of Box2D where you don't really control anything directly. If I had managed to roll my own that worked well enough (none of my own could handle all the many active collisions that the gameplay in Hoard Lord necessitates) I could have handled jumping in a much simpler way. But, since this is a situation many of us find ourselves in in game development, I thought I would go over it.
The basic idea is this: in order to jump, the player must be standing over some solid object. Here are some "simple" approaches that most people will try in this situation that don't really work:
- If we simply check his physics body to see if the bottom is touching anything, we will have all sorts of false positives and false negatives due to the uncertain nature of exact position values within a system physics system like Box2D, especially with so many bodies flying around as in Hoard Lord. In a physics system, a body will oscillate between being just above and directly on top of anything it "stands" on if there are any other forces at play - the amount will just be so small that the human observer won't notice. But this check will...
- If we check only his vertical velocity, you will have situations (like at the apex of his jump) where he is airborne, but his vertical velocity has stalled, so he'll be able to jump again in mid-air.
Here is the outline of what we must do to make this feel natural to the player, and not allow "false positives:"
- Create some number of "jump sensors:" physics objects that dont' actually collide with things, but can report when they would have collided with something. We attach these to the bottom of the player, slightly lower than his body.
- When our sensor hits a solid object, allow the player to jump.
- When our sensor stops contacting a solid object, remove the player's ability to jump if that was the only object in contact with the sensor.
So, by using these sensors we leverage the physics system's sanity checks and control of collisions to get reliable reporting on when the player body has begun or ended contact with another object that sits below him. There was a lot of trial and error in implementing this system. Here are some issues that came up:
- Initially I had one "foot" sensor below the player, sized as the width of his body and protruding about 10% of his height below him. The problem using this was that it was allowing the player to almost wall jump because the sensor would detect very brief contact with objects at the extreme sides of the player - so when the player should have been brushing up against the wall that was registering as a ground touch and it was allowing him to multi-jump up walls of objects.
- Next, I decreased with the width of the sensor. This removed the edge-touch problems, but created a new one: now if he was on the edge of an object he often couldn't jump.
- So, at this point I created an additional "foot sensor" for the player: this one is almost as wide as the player, but only barely extends below him. This will allow him to catch edges but isn't as permissive as the other sensor. The other sense has now had it's width drastically reduced and protrudes much further than the other sensor.
- This mostly worked, but I was still seeing some cases where the player could "edge jump" in an unacceptable way. So, I added one additional check before jumping: player vertical speed must be near-zero in order to jump. While this solution doesn't work on it's own, when coupled with these others it seems to do the trick.
Here's what the end result looks like - you'll see three boxes: the player's actual physics dimensions (largest pink rectangle), and two jump sensors at the bottom of his body, one wide that spans almost the width of the player body (highlighted red), and then a more narrow rectangle that protrudes further down than any of the others, but is more narrow (highlighted yellow).
You may notice that the top edges of his physics body rectangle have "cut off" edges. I "cut off" many of the edges of the rectangles when using physics systems because it smooths out something that you can normally see happen with these systems when lots of objects are moving across the each other - jittering when moving bodies encounter tiny edges of the other bodies and have their horizontal movement halted briefly. The best way I've found to mitigate this is to "cut off" the top edges of creatures, but leave their bottom edges intact. This way, they can still land on edges of things in order to be able to jump, but things moving across of the top of them won't "jitter." For stationary objects, though, I cut off all the corners.
Here are some more examples of what that looks like:
You'll notice that the cat has his own jump sensors. Also note that the "junk objects" have all of their corners cut off. This way, the player and the cat can smoothly run across the not-quite-aligned tops of a row of junk objects without losing momentum, and then jump away. The rounded corners combined with complete lack of friction means that objects will smoothly slide across each other without stopping, sliding up or down as necessary.
I hope this was interesting and even helpful - these are all extremely common problems that come up whenever you open the Pandora's Box of physics systems in your game. Every game is very different though: depending on the sizes, densities, and speeds attained by your objects the tweaking for all of these things will be quite different, but this basic approach works very well for Hoard Lord.
Riding high on our unexpected second place showing of Hoard Lord during the game jam, Brandon and I decided that our little Hoard Lord concept was strong enough, and simple enough, to make a full fledged mobile game. I set about learning what I had to do to make a game on Android.
The Technical Challenges
We had created our Hoard Lord prototype in Microsoft's XNA game framework, using the programming language C#. Using this XNA framework, you could write games for Windows PCs, XBox, or Windows phones. Back in 2012 when this decision was being made was right around when MIcrosoft had basically announced that they weren't developing XNA any further. When you are relying on a framework that you didn't develop yourself to make your life easier as a software developer you're always subject to the whims of the actual owner of that framework. In my case, Microsoft had decided that XNA wasn't worth pursuing anymore, so they weren't going to. We knew that we didn't want to restrict ourselves to just Windows phones, and since the platform was going to die a slow death of future incompatibility issues, I started looking around at other options. As I looked around at these other options, my choices seemed to fall into two categories: game development engines, and game development code frameworks.
An engine does most of the heavy lifting for you - you can usually quickly start dragging and dropping objects in a scene and with few, if any, lines of code have your placeholder boxes and spheres flying around the screen in no time. The drawback is that you can become restricted by the limitations of that engine. Using an engine you will sometimes find yourself hacking workarounds into place to avoid the default behavior of certain aspects of the engine. Of course, you can also hit the ground running much faster and get to the meat of your game more quickly.
A framework, on the other hand, provides you the raw functionality you need - there's usually some kind of menu system framework, input handling, and file system tools. But everything that's provided to you is in code - you have to actually put all the pieces together yourself. That means you have a lot of freedom to use those tools or not, and use them in whichever way you see fit. It also means that you are free to mess up the code and turn your game into a buggy mess.
I eventually found the libGDX framework. Like XNA, libGDX doesn't actually force you to design your game in any certain way, which as a programmer and designer I like. LibGDX is written in the programming language Java, though - which I didn't know. Java is very similar to C# (C# is basically Microsoft's version of Java) , so I decided it was worth it to learn Java (which would obviously come in handy for other things) in order to use this new framework. Learning Java wasn't so bad, in a couple weeks I could at least do the basics with the language, and I picked up more over time.
So at this point, we estimated it should take about 6 months to make the "new and improved" Hoard Lord - this time using LibGDX and targeting Android as the release platform. After a few months we got the basic game functioning - you could jump around and junk would fall on you. But, once again my home grown physics system that had been "good enough" for the game jam was proving not good enough for a "real" game! Boxes would collide into each other and the player, penetrate into objects they shouldn't, or be violently propelled away from each other. So eventually I decided to use the very well-documented and mature Box2D free physics engine code library, which would handle all that for me. At this point, I had learned Java (somewhat), learned how to use libGDX (mostly), and solved all the basic physics problems, but there was a different kind of problem surfacing now... There just wasn't anything to this game! This game felt too simple at this point even for mobile! So now we had an ever bigger challenge than any of the technical problems - we had to make the game fun!
Here's a video showing the game about 3 years ago - when it didn't have much more than the very basics of functionality and a working physics system:
Our Android game in development now, Hoard Lord, started as a game jam entry, back in 2012. The initial conception of this game was, of course, quite far from what we ended up creating.
We participated in the 2012 Chicago Game Jam, run by the Chicago chapter of the IGDA
and hosted at The Nerdery in Chicago. This was the first game jam my partner and I, Brandon, had participated in. We decided to go with the moniker "Team HDCheese," for some reason. The theme of this game jam was "The goal is to lose." With this in mind, our initial concept was for sort of a "runner" style game, where a hoarder was trying to outrun his junk that was chasing him. The junk would try to attach to the hoarder to try to slow them down and get in their way - you tried to "lose" the junk to win.
With our concept cemented (haha, or so I thought), I went to work creating a simple physics system where rectangular objects could collide and move properly and Brandon started creating our sprites. I had practiced for this - leading up to the game jam, I tried coding a simple physics system from scratch 3 or 4 times, arriving at a system that seemed to work quite well for basic platformer mechanics. So, at the game jam site, I built one of these systems again. I somehow deviated from my planning, because I ended up having to basically scrap and rewrite it... and now we found ourselves about 18 hours in to our 24 hour game jam! We regrouped and reviewed - we still had about a million mechanics to cement, code, and test - like everything related to the levels, the junk that chases you, and how that junk could attach to you and slow you down...
This is when we decided to scrap most of the functionality of our initial concept in the interest of actually finishing the thing. So, we reduced the concept to this: You are a hoarder in a vertical "endless jumper" where junk constantly falls from above and you have to ascend. You lose when you are "trapped" and can't proceed upwards for a specified amount of time. The problem with this concept is that it did not jive at all with the theme... So we created some weird mechanics to try to make it work: You gain score when you stay still surrounded by objects, and lose score slowly at all other times. The hoarder "likes it" when you stay still, but that will basically make you lose. It was odd and thrown together, but we went with it.
At this point we discovered that my simple, perfectly-serviceable-for-normal-platformers physics engine started behaving badly when you had tons of objects piled on top of each other and constantly colliding... There were lots of cases where you could shimmy around just right and manage to move through an object you were touching. Oh well - we had finish and it still worked well enough to get by! We fixed and hid all the bugs we could, Brandon recorded a bunch of sounds, found some free music to use, and created title screen and Game Over screen art, and we powered through getting this unholy thing working in time to be judged! We literally came up with the name "Hoard Lord" in the final seconds before officially submitting the game to the judges!
We were blown away to discover that people actually liked the game! We saw it as a terribly weird, buggy mess, but people seemed charmed by the odd concept, Brandon's great art, and I think the simplicity actually worked for it. We were awarded 2nd place! That's actually where our company name came from - at our next game jam we also placed second (which I'll probably post about at a later date), and it became a running joke that this was our destiny to always place second.
It was a great experience, and I would encourage anyone who's dabbled with game development to participate - the lessons you learn about scope management and what it takes to really finish a game are extremely valuable, as well as the connections you make with other developers!
Here are a few images from the game jam version of the game: