Tuesday 31 July 2012

Pulling the level generation code into Run Bobo Run



I didn’t expect to be posting again for a few days, but it turns out smooshing the procedural level generation algorithm into the LibGDX project was really straightforward, so I figured I might as well post a little something about it today :)
I added the Level class that I posted previously, and just made a few little changes to it:
  1. I changed char[][] to int[][], no real reason for this, either would be fine
  2. I pulled in Bobo and Array<Block> from GameScreen
  3. I replaced the console print method with a method to translate levelLayout to blocks placed in the level
  4. Finally, a constructor pulls all this together to allow easy creation of a level with a Bobo in it
I could have included block creation in the generateLayout method (under the “levelLayout[row][col] = ’0′;” line) and left out the translateLayout method completely, but separating out layout generation and translation to world co-ordinates seemed like a good idea.
Here’s the full source for Level.java
 package com.mrdt.runboborun;  
 import java.util.Random;  
 import com.badlogic.gdx.math.Vector2;  
 import com.badlogic.gdx.utils.Array;  
 public class Level {  
  private Bobo bobo;  
  private Array blocks;  
  private Random randomGenerator = new Random();  
  private int levelHeight, levelWidth, pathWidth, pathOffset;  
  private int[][] levelLayout;  
  public Level(int levelHeight, int levelWidth, int pathWidth, int pathOffset) {  
  blocks = new Array();  
  generateLayout(levelHeight, levelWidth, pathWidth, pathOffset);  
  translateLayout();  
  bobo = new Bobo(new Vector2((GameScreen.WIDTH/2)-(Bobo.WIDTH/2), 0));  
  }  
  private void generateLayout(int levelHeight, int levelWidth, int pathWidth, int pathOffset) {  
  this.levelHeight = levelHeight;  
  this.levelWidth = levelWidth;  
  this.pathWidth = pathWidth;  
  this.pathOffset = pathOffset;  
  this.levelLayout = new int[levelHeight][levelWidth];  
  for (int row=0; row<levelLayout.length; row++) {  
   for (int col=0; col<levelLayout[row].length; col++) {  
   if ((col < pathOffset) || (col >= pathOffset+pathWidth))  
    levelLayout[row][col] = '0';  
   }  
   int stepModifier = (randomGenerator.nextInt(3)) - 1;  
   if ((pathOffset + stepModifier >= 0) && (pathOffset + stepModifier + pathWidth <= levelWidth))  
   pathOffset = pathOffset + stepModifier;  
  }  
  }  
  private void translateLayout() {  
  for (int row=0; row<levelLayout.length; row++) {  
   for (int col=0; col<levelLayout[row].length; col++) {  
   if (levelLayout[row][col] == '0') {  
    Block block = new Block(new Vector2(col*Block.WIDTH, -row*Block.HEIGHT));  
    blocks.add(block);  
   }  
   }  
  }  
  }  
  public Bobo getBobo() {  
  return bobo;  
  }  
  public Array getBlocks() {  
  return blocks;  
  }  
 }  

As a result of introducing the Level class, the GameScreen class needed a little tidying up.

Project is up on github, feel free to check the project out, have a play with it, and comment if you have any ideas or suggestions :)


          

Monday 30 July 2012

Getting Started with LibGDX


Exciting times… By the end of this post we’ll have something that loosely resembles the beginnings of a game! Not only that, we’ll be able to run it on the desktop or if we like on android (either a real phone or the emulator).
It really will be just the beginning though… Today’s focus is on creating a game world comprised of block objects, adding a player controlled object (Bobo) to the world, and locking the camera onto Bobo such that the level ‘scrolls’ and Bobo always remains within sight. Later we’ll deal with collision detection, game winning states, scoring, etc, but for now let’s just take it one step at a time!

Getting Started with LibGDX

I’ll assume you already have your environment set-up. If not, follow the instructions here, and come back when you’re done :)
Ok, now generate a new shell libgdx project using the gdx-setup-ui.jar. These are the values I used:


Next, fire up eclipse, file > import, general > existing projects into workspace, set root dir to wherever you specified when creating the shell project (in my case D:\Workspace), make sure all three projects are ticked, then click finish. If it all went well you should see the three projects in project explorer. Right click the desktop project, opt to run as java application, click on the Main item in the dialog, then ok. The default hello world app should open, it looks a bit like this:


Assets

I created a couple of sprites to get us started, bobo.png and block.png (both 16x32px per original spec). These should be placed in the assets/data dir of the android project. While you’re at it, delete libgdx.png, you won’t be needing it again.

Manifest

Open AndroidManifest.xml (it should be in the root of the android project). For now, all we need to do here is change the android:screenOrientation value from “landscape” to “portrait”.

Bootstrap

I renamed MainActivity.java (android project src) AndroidStarter.java, and Main.java (desktop project src) DesktopStarter.java. Just personal preference thing. Nothing needs changing in the android starter, but in the desktop starter we should set cfg.width to 240, and cfg.height should remain as 320, this just means the app we preview on the desktop will default to the target resolution of 240×320.

Getting down to business

With the initial setup out of the way, we can now get on with the business of making our game.
We’re only implementing the GameScreen right now, but we’re aware that there will be more screens added later on, so we should probably plan for that from the outset. There’s a nice little article here on the subject, makes a lot of sense to me so let’s do it!
Open RunBoboRun.java, delete all the contents, and replace with the following:

 // In anticipation of further screens being added, I followed this suggestion:  
 // http://code.google.com/p/libgdx-users/wiki/ScreenAndGameClasses  
 package com.mrdt.runboborun;  
 import com.badlogic.gdx.Game;  
 public class RunBoboRun extends Game {  
     GameScreen gameScreen;  
     @Override  
     public void create() {  
         gameScreen = new GameScreen(this);  
         setScreen(gameScreen);  
     }  
 }  


The libgdx-users wiki article does a great job of explaining so I won’t bother going into it any further here.

Game Objects

There are a couple of very obvious game object candidates – the world is made up of Blocks, and Bobo moves around the world, let’s create a class for each…

 // A simple class for Block objects  
 package com.mrdt.runboborun;  
 import com.badlogic.gdx.math.Vector2;  
 public class Block {  
     public static final int WIDTH = 16;  
     public static final int HEIGHT = 32;  
     private Vector2 position = new Vector2();  
     public Block(Vector2 position) {  
         this.position = position;  
     }  
     public Vector2 getPosition() {  
         return position;  
     }  
 }  

There’s not a whole lot to the Block class. A couple of constants define the size (measured in pixels), a Vector2 is used to record its position in the world (set during construction), and there’s a position getter/accessor method. That’s all there is too it.

 // A simple class for Bobo, all straightforward apart from maybe update method.  
 // From obviam.net:  
 // We simply add the distance travelled in delta seconds to Bob’s current position.  
 // We use velocity.tmp() because the tmp() creates a new object with the same value  
 // as velocity and we multiply that object’s value with the elapsed time delta.  
 package com.mrdt.runboborun;  
 import com.badlogic.gdx.math.Vector2;  
 public class Bobo {  
     public static final int WIDTH = 16;  
     public static final int HEIGHT = 32;  
     private Vector2 position = new Vector2();  
     private Vector2 velocity = new Vector2();  
     public Bobo(Vector2 position) {  
         this.position = position;  
     }  
     public void update(float delta) {  
         position.add(velocity.tmp().mul(delta));  
     }  
     public Vector2 getPosition() {  
         return position;  
     }  
     public void setVelocity(Vector2 velocity) {  
         this.velocity = velocity;  
     }  
 }  


There isn’t much more to the Bobo class. In fact, looking at the two classes I think maybe there should be a parent Tile object that Block and Bobo extend, but let’s forget about that for now, we can always come back to this later if we like. So what is different about the Bobo class? Put simply, it’s capable of movement. Bobo has a velocity (a Vector2), the value of which is set via a setter/mutator method. On each update Bobo’s position is altered in accordance with his velocity. I pinched the update method from obviam.net, he explains it as follows – “We simply add the distance travelled in delta seconds to Bob’s current position. We use velocity.tmp() because the tmp() creates a new object with the same value as velocity and we multiply that object’s value with the elapsed time delta.”
So far so good. Time to implement the GameScreen!

GameScreen

I’ve said this many times already, but I’ll say it again… I’m learning as I go, and I may not be doing things the “right” way. This class should probably be split into smaller pieces, maybe I should have distinct renderer and controller classes, etc. For now I’m just working on making things work, I can worry about doing things the “right” way later on. When you’re making a game who cares if you did it the “right” way anyway, it just needs to work! With that out of the way, let’s have a look at the code:

 // This basic GameScreen class demonstrates:  
 //  How to create a game level comprised of multiple block objects  
 //  How to create a dynamic bobo object that moves around the level in response to user input  
 //  How to create a 2D camera that follows bobo on the y-axis  
 package com.mrdt.runboborun;  
 import com.badlogic.gdx.Gdx;  
 import com.badlogic.gdx.Input;  
 import com.badlogic.gdx.Screen;  
 import com.badlogic.gdx.graphics.GL10;  
 import com.badlogic.gdx.graphics.Texture;  
 import com.badlogic.gdx.graphics.g2d.SpriteBatch;  
 import com.badlogic.gdx.graphics.OrthographicCamera;  
 import com.badlogic.gdx.math.Vector2;  
 import com.badlogic.gdx.utils.Array;  
 public class GameScreen implements Screen {  
     private static final int WIDTH = 240;  
     private static final int HEIGHT = 320;  
     private RunBoboRun game;  
   private Bobo bobo;  
   private Array<Block> blocks;  
   private OrthographicCamera cam;  
   private Texture boboTexture;  
   private Texture blockTexture;  
     private SpriteBatch spriteBatch;  
     public GameScreen(RunBoboRun game) {  
         this.game = game;  
         boboTexture = new Texture(Gdx.files.internal("data/bobo.png"));  
         blockTexture = new Texture(Gdx.files.internal("data/block.png"));  
         createLevel();  
         // orthographic camera (2D camera) of fixed width and height, larger screens will scale to fit  
         cam = new OrthographicCamera(WIDTH, HEIGHT);  
         // camera focus: x-axis middle of level, y-axis 100px below bobo, z-axis ignored  
         cam.position.set(WIDTH/2, bobo.getPosition().y - 100, 0);  
       spriteBatch = new SpriteBatch();  
   }  
     private void createLevel() {  
         // create bobo and add him to the level  
         bobo = new Bobo(new Vector2((WIDTH/2)-(Bobo.WIDTH/2), 0));  
         // create an array to hold all the block objects  
         blocks = new Array<Block>();  
         // nasty temp cludge to blat out a bunch of blocks... will be replaced by level generation algorithm soon!  
         addBlock(new Vector2(0, 32));  
         addBlock(new Vector2(16, 32));  
         // -- add lots more blocks here if you like...  
         addBlock(new Vector2(224, -448));  
     }  
     private void addBlock(Vector2 position){  
         Block block = new Block(position);  
         blocks.add(block);  
     }  
   @Override  
     public void render(float delta) {  
         handleInput();  
         // user input has an impact on bobo, so update his state  
           bobo.update(delta);  
           // following bobo update, move camera accordingly (focus rule same as in constructor)  
         cam.position.set(WIDTH/2, bobo.getPosition().y - 100, 0);  
         // clear screen  
           Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
           // call cam.update() after changes to cam (http://code.google.com/p/libgdx/wiki/OrthographicCamera)  
           cam.update();  
           // set projection and model-view matrix after update (http://code.google.com/p/libgdx/wiki/OrthographicCamera)  
           cam.apply(Gdx.gl10);  
           // setProjectionMatrix before drawing sprites (http://code.google.com/p/libgdx-users/wiki/Sprites)  
           spriteBatch.setProjectionMatrix(cam.combined);  
     spriteBatch.begin();  
       for(Block block: blocks) {  
           spriteBatch.draw(blockTexture, block.getPosition().x, block.getPosition().y, Block.WIDTH, Block.HEIGHT);  
       }  
         spriteBatch.draw(boboTexture, bobo.getPosition().x, bobo.getPosition().y, Bobo.WIDTH, Bobo.HEIGHT);  
         spriteBatch.end();       
     }  
     private void handleInput() {  
         // if a valid keypress, respond accordingly (set bobo's velocity such that he moves in that direction)  
     if(Gdx.input.isKeyPressed(Input.Keys.DOWN)) {  
         bobo.setVelocity(new Vector2(0, -100));  
     }  
     if(Gdx.input.isKeyPressed(Input.Keys.UP)) {  
             bobo.setVelocity(new Vector2(0, 100));  
     }  
     if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) {  
         bobo.setVelocity(new Vector2(-100, 0));  
     }  
     if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {  
             bobo.setVelocity(new Vector2(100, 0));  
     }  
         // if no valid keypress, respond accordingly (set bobo's velocity such that he does not move)  
     if   
     (!(Gdx.input.isKeyPressed(Input.Keys.UP))&&!(Gdx.input.isKeyPressed(Input.Keys.DOWN))&&!(Gdx.input.isKeyPressed(Input.Keys.LEFT))&&!(Gdx.input.isKeyPressed(Input.Keys.RIGHT)))  
     {  
         bobo.setVelocity(new Vector2(0, 0));  
     }  
   }  
   @Override  
   public void resize(int width, int height) {  
     }  
     @Override  
     public void show() {  
     }  
     @Override  
     public void hide() {  
     }  
     @Override  
     public void pause() {  
     }  
     @Override  
     public void resume() {  
     }  
     @Override  
     public void dispose() {  
     }  
 }  


I think the code and comments (don’t miss the links in the comments!) should make sense without too much further explanation.
On entry we:
  1. Create our assets (in this case our two textures)
  2. Create a level comprised of an array of Blocks and a Bobo
  3. Create a camera focused on Bobo
  4. Create a spritebatch to allow drawing of sprites to screen
The render method can be thought of as the main game loop, it’s called repeatedly while the GameScreen is active. Here’s what we need to do every time render is called:
  1. Handle user input – if a valid key is pressed (or not), set Bobo’s velocity accordingly
  2. Update Bobo
  3. Update camera position (lock on to Bobo)
  4. Draw the sprites to screen
That’s basically it :)
The controls are more than a little bit dodgy (no diagonal movement, and you’re stuffed if your phone has no cursor keys), the ‘level’ is hardcoded, the assets aren’t disposed cleanly on close, and there’s no doubt a lot more that needs tidying up, but this post is getting a bit long so I’m going to leave it there for now. When all is said and done, we have an application that will run on the desktop and on android, and the camera follows Bobo around the world, that’s exactly what I hoped to achieve today, so this seems like a good place to stop.
Here’s a screenshot of the ‘game’ as it stands:


Next post I’ll probably look into pulling in the level generation algorithm, and maybe do some collision detection, or maybe investigate accelerometer controls, I don’t really know yet!


          

Saturday 28 July 2012

Procedural Level Generation


I’ve written a little example program to illustrate the level generation algorithm that I’ll be using in “Run Bobo Run”.
The Game class is the main entry point, it simply creates an instance of Level, calls the generateLevel method (supplying relevant parameters), then calls printLevel (which outputs a representation of the level to standard out).
Here’s the sourcecode:
 public class Game {  
  public static void main(String args[]) {  
  Level level = new Level();  
  level.generateLevel(45,15,5,5);  
  level.printLevel();  
  }  
 }  
The Level class is where the level generation algorithm lives. Let’s think about what we need it to do:
  1. Create a 2D level comprised of a set amount of tiled rows and columns
  2. Create a path of a certain width that runs down the level
  3. Potentially shift the path one tile left or right on each consecutive row that is created (randomising means unique levels on repeated playthroughs)
  4. Ensure the path never strays outside the world bounds
Here’s the sourcecode:
 /********************************************************************************************  
 * RANDOM LEVEL GENERATOR  
 *  
 * This algorithm procedurally generates levels for use in simple 2D games where the object  
 * is to remain on the path and avoid crossing any blocked tiles.  
 ********************************************************************************************/  
 import java.util.Random;  
 public class Level {  
     int levelHeight; // Height of the level measured in tiles  
     int levelWidth; // Width of the level measured in tiles  
     int pathWidth; // Width of the path measured in tiles  
     int pathOffset; // Number of tiles to the left of the path  
     char[][] level; // Two dimensional array representing the level  
     Random randomGenerator = new Random();  
     public void generateLevel(int levelHeight, int levelWidth, int pathWidth, int pathOffset) {  
         this.levelHeight = levelHeight;  
         this.levelWidth = levelWidth;  
         this.pathWidth = pathWidth;  
         this.pathOffset = pathOffset;  
         this.level = new char[levelHeight][levelWidth];  
         for (int row=0; row<level.length; row++) { // for each row in the level  
             for (int col=0; col<level[row].length; col++) { // for each element in the row  
                 // set value based on elements location in the array  
                 if ((col < pathOffset) || (col >= pathOffset+pathWidth))  
                     level[row][col] = 'X'; // this tile is not on the path  
                 else  
                     level[row][col] = ' '; // this tile is on the path  
             }  
             // generate a random integer (-1 or 0 or +1)  
             int stepModifier = (randomGenerator.nextInt(3)) - 1;  
             // apply modifier to path offset provided the path would remain within world bounds  
             if ((pathOffset + stepModifier >= 0) && (pathOffset + stepModifier + pathWidth <= levelWidth))  
                 pathOffset = pathOffset + stepModifier;  
         }  
     }  
     public void printLevel() {      
         for (int row=0; row<level.length; row++) {  
             System.out.print("|");  
             for (int col=0; col<level[row].length; col++) {  
                 System.out.print(level[row][col]);  
             }  
             System.out.println("|");  
         }  
     }  
 }  
A two dimensional array is the perfect data structure for a 2D tiled level. In this toy example it’s an array of char’s (so I can output a human readable representation to console), in the real game it’ll be an array of Tile objects.
I use nested iterators to touch every element in the array. In English-ish - “For each row in the Level do {for each column in the current row do {depending on what column you’ve reached, set the value to something or other}}”.
How do we decide between setting the value to ‘something’ or ‘other’? This condition should shed a little light “if ((col < pathOffset) || (col >= pathOffset+pathWidth))”. If we have not yet reached the column that that marks the start of the path, or we have reached/passed the column that is the end of the path, we should set the current element to blocked. If the evaluation of the condition returns false, set the current element to be part of the path.
Finally, how do we introduce the random change in path offset per row? First, we generate a random integer between -1 and 1, “(randomGenerator.nextInt(3)) – 1″. Next, we check to see if applying this randomly generated modifier to the current path offset would result in the whole path remaining within the world bounds, “if ((pathOffset + stepModifier >= 0) && (pathOffset + stepModifier + pathWidth <= levelWidth))”. If the condition returns true, we apply the modifier, but otherwise we do nothing.
I think that about covers it. Next time I’ll likely be looking at how to move a sprite around the game world, and forcing the camera viewport to follow it. For now I’ll leave you with a super exciting screenshot of a procedurally generated level output to the console:


          

Friday 27 July 2012

First android game - project outline


Time for a new project, you’re welcome to join me on the journey!

Step one, outline what you want to achieve…

  1. Game procedurally creates its own levels
  2. The project should be good tutorial fodder
  3. Game should be fun to play
  4. Game should be complete enough to be deployed to market
  5. Keep it simple, stupid!
That’s in order of importance for this project. Usually ‘fun to play’ would be number one, but what I really want to achieve with this project is first and foremost a bit of learning of my own, and secondly I’d like to turn it into a tutorial that might be of interest to other people just getting started with android game development.
Here’s a basic game idea that should do the job nicely…

Run Bobo Run!

Bobo is running along the path, he’s training hard to become the fastest clown in the world! Can you help him stay on the path and beat the level record? Try to avoid the walls, bumping into them slows Bobo down!
  • 2D game
  • Camera viewport locked onto Bobo
  • Tilting the device left/right moves Bobo in that direction
  • Procedurally generated level consists of a ‘path’ surrounded by wall ‘blocks’
  • Level fits the screen horizontally, and scrolls vertically
  • Bobo moves down the level automatically
  • Bobo cannot leave the path and colliding with wall blocks slows him down
  • Aim of the game is to get to end of level as quickly as possible, beat the level record!
  • The closest you get to ‘losing’ this game is finishing in a bad time – ideal for small children
This game could be extended to include multiple levels (vary level length, path width, Bobo speed), bonus pickups, speed boosts, new speed record facebook bragging, level grades (e.g. one star for sub 40 seconds, two stars for sub 35 seconds, three stars for sub 30 seconds, platinum cup for perfect level – sub 30 seconds, no wall collisions, all bonus pickups collected), a level select screen for direct access to previously unlocked levels, particle effects on collision with blocks, 3D graphics, story mode, character select… But honestly, it’s all getting a bit silly. We just want a very simple casual game for people to play when they’re bored (or to keep children amused for a little while), and one of the project tenets is to Keep it simple, stupid! We can always come back to some of these ideas later if we want, but for now let’s just make a working game!

What screens will the game need?

I figure a screen each for Menu, Game, Results, Best Time, Instructions, and About.

All screens transitions (bar one) will be as a result of UI button events. The transition from Game screen to Results screen is to be triggered when the level end is reached in the game. I know the transitions could be improved, maybe add a ‘Retry’ button to the Results screen, introduce a pause screen, a level select screen, etc. But I’m keeping things simple to start with.
To start with I’ll just focus on the Game screen, that’s where the real meat of the project lies.

What devices will the game run on?

This game is so simple that it should run on pretty much any Android device. I’ve decided to aim for global compatibility.
The smallest android phone resolution that I’m aware of is 240×320 (HTC Wildfire and HTC Tattoo), so let’s target that resolution. Higher resolution screens will simply scale to fit (the game won’t be Nexus 7 eye candy, but it should run all the same).
OpenGL ES 1.0 and 1.1 API spec have been supported since Android 1.0, OpenGL ES 2.0 since Android 2.2. Over 90% of devices support OpenGL 2.0 (http://developer.android.com/about/dashboards/index.html), and that percentage will keep on increasing, but what about the 10% with older devices, don’t they deserve to play this game too? Of course they do! I’ll target OpenGL 1.1.
I’m not aware of any Android devices (phones or tablets at least) that don’t at least have an accelerometer (tilt sensor) and touch screen support. I’ll avoid supporting more exotic inputs, a simple control scheme of touch for menu options and tilt for gameplay is plenty for this game. Note that for the purpose of being able to test on my dev laptop (much quicker than using the emulator or deploying apk’s to device) I’ll also include keyboard and mouse support.

Game Screen Mockup

Here’s a first stab at an example game screen:


  • 240x320px viewport displaying some of the level
  • Level is made up of 16x32px rectangular tiles
  • Tiles are either ‘path’ (beige) or ‘block’ (orange)
  • Bobo the clown is on the path (his sprite is also 16x32px)
  • Basic HUD displays progress percentage and current time
It’s not the most exciting looking thing we’ve ever seen, but it should be a good little project to work on nonetheless.
In the next post I’ll probably cover the procedural level generation algorithm, and maybe more if there’s time… See you then!

          

Saturday 21 July 2012

Focus on “Fun” and “Finished”…


Last week I installed the Java JDK, Eclipse, Andoid SDK, and the ADT Eclipse Plugin. I then followed the LibGDX starter project walkthrough.

That single class project weighing in at just 150 lines of code (including whitespace and proper formatting) does a lot. It uses an OpenGL camera, loads image files, draws them to screen, responds to user input, plays soundfx and music, and has a simple game mechanic that makes it a basic game. Not only that, the game could be played on my dev laptop, and on my Xperia Play with no code changes. I was impressed.

Instead of going on to create LibGDX pong and slowly working up from there (as was my original intention) I decided to play around with the example project a little. The bucket became a spaceship and the raindrops enemy UFOs (each had their own class), nobody had any weapons, the UFOs were kamikaze maniacs and moved at varying speeds, aim of the game – avoid being hit. I added the concept of score and health, for each successful evasion you earned 10 points, for each impact you lost 25 hp. Four hits and it’s game over. Still very simple, and kinda fun.

Next steps would have been to introduce weapons, after that more enemy types, then a highscore table, then animated sprites, then maybe an end of level boss, then lots of levels to work your way through. Before you know it I’d have my very own r-type clone on the marketplace! But that’s not what happened. I started worrying that I was doing it wrong, not following the ‘correct’ path, not making the right design decisions. I read a couple of great tutorials (obviam.net and steigert.blogspot.co.uk) and immediately tried to implement those best practices in my simple app. At this stage, as a beginner, it was overkill. I ended up with a confused mess of files, and when extending I was often unsure if I was putting code in the right place. It was so much more fun when I was freestyling, making it up as I went along. Sure it could end up biting me on the ass later, but maybe I should just deal with it later and focus on making a fun little app for now. That’s when I stumbled across this excellent blog post. Here are a couple of choice excerpts that resounded with me:


  1. Don’t Obsess – your code is your code and I know you love it but how beautifully shaped and how wonderful the architecture is doesn’t matter one bit to the end player, especially if the game doesn’t ever get to be playable. Do not obsess about your code. Make it work. Make it quick enough. Make it pretty. In that order.
  2. More than one way to skin a cat – there are many ways of approaching any problem in software. There are normally a set of “right” ways that are well explained in long tutorials on the web. You go off and read the tutorials and you start implementing… You’re not entirely sure you understand what you’re doing, but you just keep going. WAIT! STOP! How about you just code it the “wrong” way for now, just make it work and if it doesn’t feel right later replace it.

Wise words indeed.

Grand arcade games can wait. I’m going to follow my original plan – I’ll write a LibGDX pong game. Then I could take what I’ve learned and write a breakout game. Baby steps that result in regular releases of small working games. I’ll likely end up using really bad practices, but I’m doing this primarily for fun and the joy of creating a working game others can play, learning is a secondary concern. If and when bad design leaves me in a fix I will learn a first hand lesson and better understand the benefits of a rigid design pattern, but to start with I’m just gonna be jammin – I’m going to let myself make my own mistakes!

Android, a modern day Spectrum for amateur game devs


Way back in the 80's I received an Atari 2600 for Christmas. It was awesome. Let’s forgive and forget the crappy graphics, the dodgy one button joystick, the awful sound processor… None of that mattered. This was a machine that transformed my tv into a damn arcade machine – how could it be anything other than awesome!?

I loved my Atari. I spent hours playing classic games like space invaders, pacman, and centipede. But the following year Santa brought me a Sinclair Spectrum +2A… The Atari’s reign as toy-king was cut short. What can I say, I was a fickle child and this new machine could not only play games – it came with the promise of me creating my own games too!

The Spectrum holds a very special place in my heart. I know many of my generation can say the same. I still have it, it has survived numerous house moves and clearouts, I will probably still have it the day I die. Why? Was it the perfect machine? Blisteringly powerful and immune from Moore’s law? No. But just like the Atari, it was awesome all the same. My time was spent playing Dizzy, Manic Miner, Chaos, Arkanoid, Klax, The Great Escape, Deathchase, Potsworth and Co, Wonderboy, New Zealand Story, Blob the Cop, Wizball, numerous text adventures, and so many other great games that I can’t quite remember right now. There was also the bundle of games that came with the machine, pretty basic games but fun nonetheless, Treasure Island, Oh Mummy, Crazy Golf, Punchy, Disco Dan, etc – poor graphics and sound, but solid game mechanics that made them fun to play regardless. I’ve played worse playstation / wii / 360 games than some of these ugly spectrum games. Sure the modern platforms have the aesthetic upper hand and bags of processing power, but if the game itself is no fun, all it boils down to is an exercise in turd polishing. A fun ugly game beats a rubbish pretty game hands down.

Sinclair did all they could to make writing your own programs pain free. The +2A had a basic parser built in, and a tape deck for saving/loading your work. The manual was mostly dedicated to the basic language, and there were loads of third party books and magazines available that included sample code for you try out. In a pre-internet era I spent a lot of time with that manual, my Your Sinclair and Sinclair User magazines, and anything relevant I could find in the library. As a result I wrote some ugly fun games of my own. Pong, breakout, space invaders, that kind of thing. They didn’t really look much worse than some of the commercially available games, and played just as well, so it was quite a rewarding process! Of course distribution was limited to a very small number of my friends who were still in the least bit interested. The Sega Master System and Nintendo Entertainment System were out by this time, the Spectrum was decidedly uncool to those who were only interested in playing games, not making them. My audience was basically me, my family, and a couple of friends from school. It was a lot of fun creating though, I didn’t really care that the resulting game was pretty much just for me to play!

After the spectrum came the closed platform years. NES, Megadrive, PSX, GBA, PS2, PSP, Wii, Xbox360. Buy a consumer unit, play games on it, nothing more. Well, that’s not completely true, I did hack the wii and write a very simple target shooting demo a couple of years ago, but I felt way out of my depth and didn’t get very far at all. Similarly I started messing about with the kinect and unity, but felt like I was spending my time configuring someone else’s tool and not actually doing anything too interesting myself, so didn’t progress too far with those either. I’d say the nearest I got to writing games since the Spectrum days was either using the Game Maker engine to make some fun platformers, or writing basic Java apps for university assignments. Game Maker is a nice tool if you just want to create something fun to play, but I’d prefer to learn a language and more transferable skills than tying myself to an existing engine. The java assignments taught me some transferable skills (mostly forgotten by now), but weren’t all that fun. There’s another problem with writing desktop games too – trying to get people to play your basic puzzler with graphics the Atari/Spectrum could have achieved when they’re used to playing CoD and Battlefield is going to be an uphill struggle.

Enter Android, the saviour. It ticks all the boxes:

  • Open and free SDK
  • A thriving dev community
  • Chance to learn some transferable skills (java programming, game design, graphics and music creation)
  • Relatively mature LibGDX library – helps developers without reducing the whole process to a game engine config exercise
  • Loads of devices, lots of people already have a ‘console’ capable of playing any game you create
  • Marketplace to easily distribute end product (free after one-time setup fee of about £15)
  • A natural leaning towards casual games – people are more likely to play your basic 2D fun game

So for a grand total of £15 I can create some simple games in my spare time and anyone in the world can download and play them? All the while I’m learning new skills and having fun? I’m in!

I’m going to be approaching this as a complete beginner, I will make mistakes, I will be inefficient, my games will likely look like crap, and I’m certain nobody will want to pay for anything I produce. My games will be open source, and I’m hoping to get them to a “finished enough” state that I can make them available for free on the Google Play marketplace. All the while I’ll be re-learning what little Java I once knew, maybe picking up a few tips on pixel art, and hopefully learning a little about making music. Eventually, I’d like to get to the point where I could enter a game development challenge like Ludum Dare and actually end up with a working game at the end of it. I’ll post what I learn here, but please be aware that any tutorials will probably be as far from best practices as you can get – I’m just gonna be doing things my own way and posting the results!