top of page

The Development of Crashy Road

Introduction

I’ve always been interested in games development, ever since my Deputy Headmaster held up a ZX81 when I was in Primary School. Probably my first recollection of playing a game though was Skramble on my friend’s C64 (https://www.c64-wiki.com/wiki/Skramble). After that I was hooked, and despite not actually owning a computer (a second-hand ZX Spectrum) until 5 years later, I spent all my leisure time reading programming books and typing in small programs on the BBC Model B computers at school and the local WHSmiths on Saturday mornings.

 

However, it was 20 years later (2004) that I actually worked on a commercial game. I had been working as a financial software programmer at a bank but I decided to leave and follow my dream of being a games programmer. My first job in games was working at Morpheme, a developer of J2ME feature phone games (http://citystate.co.uk/archives/morpheme-1999-2008/). During my time at Morpheme I worked on a number of ports of existing titles, like The Fast and The Furious and Croc Mobile. I also got to develop some games from the ground up: Young Bond Silverfin, Pub Pinball and Phantom Mansion Origins. After a stint as a games programmer, I pursued a career on the commercial side of games and I still work in the industry to this day. Although I left the world of commercial programming, I have kept my hand in over the years, even if it was just to develop some simple applications in VBA! However, recently I decided to have a crack at releasing a game and set on down the path towards creating Crashy Road. Crashy Road is a very simple Android only game. You may be wondering why I would choose native Android development (Java) rather than one of the multitude of engines that are available? If so, read on!

 

​

Why Android?

I wanted a way to create a simple game that I could finish and not need to learn any complicated frameworks. Although I have previously released commercial games (albeit mobile ones) this was some years ago. So I began by looking at the simpler tools, starting with things such as AppInventor, Makeroid and Thunkable. These tools are great for prototyping non-game apps but having developed a scrolling road demo using Makeroid, I realised that the graphical performance wouldn't meet my needs. However, I would definitely recommend AppInventor or Scratch for that matter for someone first starting out in programming or game development. These tools are a great way to be productive quickly and also understand some of the key concepts of programming (logic, control etc.).

 

Naturally, I also considered Unity. In fact, during one of my previous dabbles into game development, I had gained some Unity experience through following this excellent course: https://www.udemy.com/unitycourse/

However, having worked through the examples, I found that there were too many settings and concepts to grasp for a very simple project.

Having been a Java (J2ME) programmer in a previous life, I then decided to look at Android. I had some previous (limited) experience of Android but had found the way Activities work with XML files etc. to be confusing. Looking at my options though, I realised my skills were strongest in Java and if I could push through the project setup then I knew I would be able to put something together. So I downloaded the latest version of Android Studio and set to work.

 

​

Using Android Studio

I was initially overwhelmed by all various project files and windows in Android Studio. However, after I got my head round it, I found it to be one of the most enjoyable IDEs I have used. The key thing I realised was not to get freaked out by all the build files and to just focus on your Java classes and resources. Everything else largely takes care of itself. However, I found that it helped a lot to go back refresh my memory on Android basics before jumping into Android Studio. It took me a while to find the right course that explained the Android app lifecycle and the way activities work in a way that I could understand. I would recommend this free Udacity course: https://eu.udacity.com/course/new-android-fundamentals--ud851

 

As part of the Android Studio setup, I added a number of emulators to the IDE and found these worked well. However, controlling the game with the mouse pointer is a bit fiddly. So, I also connected my own Nexus 6p using the on-device debugging and this worked excellently. In my experience, Google seem to have (as might be expected) nailed the Android development experience. I also found that the community is so large that pretty much any challenge I had was eventually resolved via a web search. The only real issue I encountered was with the Firebase integration. Unfortunately I still don’t understand what I did that resolved the issue (something to do with dependencies) but eventually it worked!

 

​

Game Design

You may be wondering how I arrived at the design for Crashy Road. I was very much inspired by this Gamasutra post (https://www.gamasutra.com/view/news/117521/Opinion_Indie_Game_Design_Dos_and_Donts_A_Manifesto.php) where the developer of Super Meat Boy, Edmund McMillen suggests that developers should make sure they build a project they can finish. So I took this advice to heart when selecting a game design.

 

Having grown up with 80’s arcade games, I fondly recall Spyhunter (https://en.wikipedia.org/wiki/Spy_Hunter). I felt that given my limited graphical skills, I might be able to finish a game like this. I was then also inspired by the randomness aspect of RogueLike games. Again, given time and resources, I felt like if I could design the game using random elements then this would further help me finish. Finally, I was inspired by the simplicity of endless runner games such as Subway Surfers. So I decided to build a Spyhunter-esque-Roguelike-Endless-Runner. You heard it here first!

​

 

Workflow

I used the following tools in the development of Crashy Road:

 

  • Android Studio

  • Google Drive

  • MS Paint

  • Adobe Photoshop Elements

  • Novation Blocs Wave App

  • Novation Launchpad App

  • Ableton Live Intro

  • Firebase Robo Testing Platform

  • MS Powerpoint 2016

 

All of the code was written in Android Studio. I also created the app icons in Android Studio via the Image Asset Studio (https://developer.android.com/studio/write/image-asset-studio), although the raw files were created in MS Paint and the gradient fill was created in Powerpoint. Powerpoint is an underrated game development tool!

 

For the graphics, I searched online for design inspiration and then set about creating sprites in MS Paint. For the animated assets such as the coins and pickups, I checked the animations and timing by uploading the source files into one of the many PNG animation tools. If I had used Unity, the animation tool would have helped a lot with this task but this was one of the trade-offs of choosing to roll my own with Android.

 

I created the title and in-game music mostly in Novation Launchpad, having first imported the Chiptune samples from Blocs Wave. For some reason, Launchpad doesn’t (at least at the time of writing) have a Chiptune sound pack so I used the Chiptune pack in Blocs Wave and then transferred this to Launchpad via the handy upload tool. Once in Launchpad, I then created an arrangement and recorded this live and saved it out as a WAV. I then cleaned this up in Ableton Live 8 Intro. Finally, I saved the file out as a WAV and then converted to MP3 via an online convertor tool. For the coin pickup sound effect, I recorded the sound of coins dropping from one hand to another (recorded live via a Blue Snowball mic) and then tweaked this sound and added effects in Ableton.

 

​

Code Structure

The code is initialised in a class called MainActivity. This was created directly in code rather than being created via an XML Activity file. I found that for a simple game structure (rather than an app with multiple views and UI objects) it was just easier to create it directly in code.

 

The meat of the game happens in the class GameSurfaceView which extends SurfaceView. Note I am not using OpenGL ES in Crashy Road although I am using the lockHardwareCanvas() method (https://developer.android.com/reference/android/view/Surface#lockHardwareCanvas()) when drawing to the screen. This method provides a hardware accelerated canvas to draw on. GameSurfaceView also implements Runnable and this is how the main game loop is created. The game is controlled by a finite state machine (https://en.wikipedia.org/wiki/Finite-state_machine). I have states such as STATE_TITLE and STATE_GAME etc. to control what happens each frame.

 

One of the key decisions I had to take in the course of development was how to handle different device resolutions. Generally speaking there are two approaches to this:

 

  1. Create a different size asset set for each device class (mdpi, hdpi, xhpdi etc.)

  2. Use a single asset size (stored in drawable-nodpi) and then dynamically resize these depending on the actual resolution

 

I decided to use the second approach. Crashy Road is essentially a skill based game, so it relies on dimensions being consistent across devices. Even between Android devices of the same class, screen resolutions can vary. Also, with a such a small number of assets, using dynamic resolution is manageable. However, I probably wouldn’t use this approach for a tile based game.

 

One tip I have regarding graphical assets is to be careful which resource folder they are saved to when you upload them to Android Studio. Early in development I had a bug on some devices that was traced to a file being accidentally stored in an incorrect dpi folder. In some cases a device would be looking in a certain folder and not find the resource and as a result an exception was thrown.

 

For the entity design, I decided to use a mix of functional and Object Oriented approaches. If I was making a larger game I would probably go more OO, but for a small game I found it quite manageable to have a lot of the logic in GameSurfaceView. As a side note, back in the Java feature phone days, some devices were limited to 64Kb memory. To save space, pretty much everything was declared as 'static' and 'final' and located in a single class!

 

However, for the game objects such as the coins, barriers and pickups, I decided to use an Object model. I started with a basic Sprite class which I then extended for specific behaviour such as having a points value for coins etc. This allowed me to use a single ArrayList object in the main class to manage all the game objects. I was then able to call update() and draw() on each of the objects in a loop which made things much simpler.

 

Many elements of the game were brought out into constants at the top of GameSurfaceView to enable me to tweak gameplay during development. This included things like the timing of the fade on the title text, the speed of objects and the animation timing on coins. I could have gone further and pulled these all out into a resource file (as I did with the in-game text) but for a small game like this I felt it would be overkill. Also, for a larger game, I would create a timeline class and get it to trigger events. In Crashy Road, I have individual timers for things such as controlling the road scrolling. This wouldn’t be sustainable in a larger game with more time controlled events.

 

One issue worth noting is the trouble that I had getting the width and height of the screen. Despite numerous web searches, the only way I could get the screen dimensions reliably was via the surfaceChanged() method of GameSurfaceView. The issue with this is that you can never be exactly sure when this is going to get called. Added to this is the fact that many elements in the game rely on knowing the height and width. So the solution was check the dimensions one time and then load the images after this (the image scaling relies on knowing the screen dimensions). It seems the surfaceChanged() method gets called when the splash screen is first drawn so the first time the splash screen is drawn it just paints a black background (presumably triggering the call to surfaceChanged()).

 

You may notice that ads are displayed when playing the game. Given that Crashy Road is such a basic game, I was clear that I couldn’t charge for it (in its current state) but I wanted to see if I could monetise it so I integrated Google AdMob. This works great but there are a few steps to go through so I will give an quick overview here as I feel the Google documentation is a little unclear in some places.

 

To get AdMob ads into your game, there are a few things you will need to do. These are:

 

  • Make sure that the Google Play Services SDK is installed in Android Studio (https://developer.android.com/studio/intro/update#sdk-manager)

  • Add the AdMob dependencies to your project and app (https://developers.google.com/admob/android/quick-start)

  • Import the relevant AdMob classes into your project. Note that I used a RelativeLayout to house both the GameSurfaceView and the ad banner. These were all initialised directly in code in MainActivity (not in GameSurfaceView)

  • The most confusing part of using AdMob is that there are three ways you can use it:

    • Default test ads: these are hard-coded Android test ads that just allow you to check that the ads have been integrated correctly

    • Test ads from your AdMob account but using a test device: Google doesn’t allow people to test live ads due to the obvious fraud implications. However, you can (having setup your AdMob account) use live ads but register your device as a test device. This tells Google to ignore any clicks on ads generated during testing

    • Live ads: the ads used in the final production version of your app

  • The quick start guide above shows you how to integrate the default test ads. Basically all ad setups need an App ID and an Ad Unit ID. In the default ads setup, Google gives you the test App ID that is the same for everyone and also gives you a test Ad Unit ID based on the type of ad you want to display (banner etc.)

  • If you want to test with live ads. You first need to setup an AdMob account (https://support.google.com/admob/answer/7356219?hl=en-GB). Once you have set this up you will be given an App ID and Ad Unit ID. These need to be passed to the AdMob API when setting up the ad as though it is the production version. However, the key extra steps are that you then need to run the app in debug mode and look for the following line in the logcat: ‘I/Ads: Use AdRequest.Builder.addTestDevice("XXXXXXXXXXXXXXXXX")
    to get test ads on this device.’

  • Then you need to add this line to your AdMob setup code substituting the XXXXXXXXXXXXXXXXX above with the actual code returned from the logcat:AdRequest adRequest = new AdRequest.Builder().addTestDevice(XXXXXXXXXXXXXXXXX).build();

  • Obviously when compiling the final version of the game, this line is removed

 

Hopefully the above pointers will save people some time!

​
 

Next Steps

In its current state (as at the end of 2018), Crashy Road is a very simple game. I could of course add more and more features to it. However, I am inclined to move on to the next project. Currently I have been thinking about the following ideas:

 

  • Re-skinning of Crashy Road to turn it into a vertical scrolling shooter. This would be the simplest next step. I could replace the car with a space ship, the road lines with stars and the barriers with asteroids etc. and add more gameplay elements

  • Creating a platformer:  In my very early experiments with game making on the ZX Spectrum, I always wanted to make a platformer. I was heavily influenced at the time by titles like Dynamite Dan and Manic Miner

  • A 3D title: In the mid to late nineties, I was in awe of 3D titles and the complexity of creating one. Back then there was no Unity or Unreal - well there was Unreal to be fair but you get my point!

 

Reflecting on the ideas above, I am mindful of the advice that Derek Yu quotes in his excellent book ‘Spelunky’ from Boss Fight Books (https://www.amazon.co.uk/gp/product/B01CYVHYSS?ref=dbs_p2d_P_R_popup_yes_alc_T2). Derek suggests that the best game to make is:

  • One that you want to make

  • One that you will be good at making

  • One which you would regret having not made

 

Want to make is easy - any of the ideas above! Good at making? Hmmm...well my main limitation is a lack of graphical skills to maybe I need to collaborate...One that I will regret having not made? That’s a tough one...I’m going to take Edmund McMillen’s advice and get Crashy Road out of the door first before I think more on that!

bottom of page