Any of my regular followers who are so committed to the cause that they’ve also ventured to follow me on Twitter may have noticed sporadic postings in shaky phonecam footage of a curious little device known as an Arduboy. This credit-card sized GameBoy inspired curio is powered by that staple of the maker community, the Arduino, neatly packaged together with a sharp 1-bit 128×64 OLED display, 4 directional buttons, and 2 action buttons. It was a guilty impulse purchase sometime around October last year, and I wandered into it without holding out much hope that I’d get around to making anything worth releasing. I was initially drawn in by the promise of constraints, which is a strange pull, but I’ve often been amazed at how programmers for early systems were able to squeeze so much out of some very limited hardware (This article about the original Zelda is a great example). The Arduboy is a neat re-imagining of these early restrictions: A screen where each pixel can only be either on or off; The bare essentials of controls; and strict limitations on processing power, memory, and storage. The game making community has risen to this challenge with a wide range of neat offerings showing off just what can be done within about fixed envelope; the excellent Team-ARG and Jonathan Holmes (check out ‘Circuit Dude’) are just a couple of examples from the dedicated programmers who have adopted this little system.
It was an idle path of thought about 2D platformer movement which set in motion the development of my own humble title, “Not Just a Hat Rack”. One of the reasons that the first Mario games were (and remain) so successful was the delicately balanced charter movement which has been imitated many times since, not least of all in one of my favourite platforming titles, ‘Super Meat Boy’. My first foray into Arduboy programming was to better understand this type of charter movement by recreating it in my own primitive way.
I began by trying to coax a square to move left and right on the screen and even in this, a new appreciation for the programmers who develop vastly complex physics engines began to crystallise. I started with the simple idea which governs all onscreen movement:
“To make things move on screen, you must redraw it in a different position after a timestep”
The timestep is straightforward; setting the Arduboy to a 60Hz (Edit: I stand corrected on this; Scott over on the Arduboy community has informed me that 1000Hz is the theoretical maximum, but in reality will be slower. He posted an excellent explanation along with some tips for Arduboy developers on the forum here) refresh rate (the maximum) gives 1/60 s as the shortest time interval between any two positions; likewise the smallest distance something can travel in that time is 1 pixel. So off I merrily set making my square move 1 pixel every 1/60 s when I pressed either the left or right button. This dropped me into the territory of some early arcade games, but not even close to smooth platforming action. The problem is that no character goes from standing still to full speed instantly; acceleration was the first missing ingredient needed to add weight and realism to the character. On pressing that small directional button, the character must pass through turtle, hare, and finally peak at hedgehog (which is how games have taught me to rank animal speed). This could have been achieved by changing the framerate, but that would mess with anything else that was being animated, so it’s easier to skip a few frames between each pixel move then gradually reduce the number of skipped frames until we’re finally up at out 1 pixel/frame top speed.
This gave a nice acceleration (and deceleration) and the illusion of momentum; but I wasn’t just looking for ‘nice’, I wanted fluid fast paced platforming and one pixel/frame just wasn’t fast enough. Being up against a brick wall in terms of framerate, I shifted focus to the other variable, distance, it was a simple adjustment to have the square move two pixels each frame, rather than one. This looked horrible at low speed, the square juddered one way or the other noticeably due to the lightweight screen resolution. The solution was to accelerate as I had before until the magic one pixel/frame before switching to moving two pixel/frame for maximum zoom, then reversing this as the button is released.
… Given that this was just the basics of moving left & right, I began to realise just how much thought goes into character movement…
The complexity grew when I shoehorned in one type of deceleration for simply letting go of the buttons and allowing the square to drift to rest, and a second for if the player quickly shifts to pressing left as the square is still moving right. Trial and error pinned down the final values, so I decided to push on and start to think vertically.
The Second Dimension…
Jumping works roughly the same and ‘running’; pressing the jump button immediately launches the square skywards at top speed, but with a deceleration so that it eventually peaks, switches directions, falls, and lands. I initially decided to completely decouple vertical and horizontal movement so that the player has 100% left/right air control, but that wasn’t quite right. The ‘natural’ on-ground deceleration of just letting go of left/right no longer made sense in the air so I had to disable it whilst the square was in flight. Now if the player leapt forward then let go of the movement buttons, the square would continue on a natural ark, rather than slowing abruptly mid-air and falling to the ground. Even this turned out to be an oversimplification as we all know that just a tap on ‘the button’ provides a low jump, whilst a held button makes them jump higher. Adding this involved setting two different rates of jump-deceleration governed by ‘button held’ status, with the subtlety being that it must not be possible to ‘reinstate’ the original deceleration rate by pushing the button again mid-jump… or for that matter make the character jump again
I have a theory that a programming error in this whole mess of an area was how the first ‘double-jump’ was invented
At this point I’m guessing most of you have glazed over, or just closed the window entirely, but for the few who are still with me, I’ll spare the details of putting in wall-jumping other than to mention that as anticipated there is more to that particular ice-berg than breaches the surface.
Adding Some Game to the Game
Having now sunk way more time into this than I initially anticipated, I decided that a satisfied abandonment was no longer possible and that working it up into some kind of ‘game’ was really my only escape route. So I continued to add some game to this game.
The lead ‘character’ of my hypothetical platformer was the first challenge, and was partially dictated by how I decided to proceed with the game ‘engine’. At this point the 8×8 square was jumping around a single 128×64 static (and empty) screen. Making the character bigger would be necessary in order to allow for any detail to the sprite, but that would also mean that the stage needed to scroll as the character approached the edge to give room for content. I had in mind something different; stick to the constraint of the 128×64 screen and focus on short fast paced levels; an idea partially inspired by some of the retro stages in SMB. With this in mind I needed to limit the character to 8×8, so the idea of a simple shape… a TopHat… began to form. The Hat almost fills the 8×8 envelope meaning that changes to the wall jumping mechanic were minimal. With a hat flalumping around the level it started to feel more like a game than a technical exercise.
Level design became the next hurdle, so I once again delved into the trick bag and pulled out a tried and trusted gaming technique, using tiles to make up the level; 8×8 tiles neatly stack onto the screen in a 8 x 16 grid. Defining each tile once, but using it multiple times is a big storage saver. The levels are now defined as arrays of numbers, each number corresponding to a tile, which makes level design a matter of just typing out numbers.
Finally, collision detection was added to ensure that the appropriate ‘thing’ happens when the hat touches each different tile type; for example a standard block tile cannot be moved across.
So Where is This All Going?
To the Hat Rack… that is at least where Karlsville is going (that’s the name of the hat).. all hats want to end up safe and secure at the hat rack, right? Getting to the hat rack quickly became the goal of each level, and since then I’ve been filling out the game with a few more mechanics, a neat title screen, and an overall aim, finish all the levels as quickly as possible.
At this point it is about 75% done – I’m still making and polishing levels. More interestingly has been what I’ve learnt doing this… I can’t call myself a programmer with a straight face (believe me, I’m dreading releasing the source code to the world to be picked over by people who know what they’re doing), but it has given me a quick glimpse (on a small scale) into the decisions that need to be made as a game developer: how the technical limitations can influence the game; how nothing is done without thought; how things (like simple character movement) require at least as much consideration as those things that the player notices; and how an easy idea can be difficult to implement.
Is “Not just a Hat Rack” going to be released? yes, hopefully in the next few weeks, and if you have an Arduboy, I’d love to hear any feedback.