Sunday 30 December 2012 4 comments

Unity, Futile & C# - Part 2

If you read the first part of this series you will know I am transitioning from Corona SDK to Unity. More specifically Unity and the 2D rendering framework, Futile. The purpose of this blog post is to further diarise the process as well as providing some level of documentation to Futile which is still in its infancy.

Day 8
This was very much a day of highs and lows. To match to the iOS version of Astavoid I wanted to replicate the screen transitions. However, within Futile at the moment there are no transitional effects between FContainers so they snap rather unattractively. Thankfully, and purely by chance, my screen transitions were straightforward and just gave the effect with text animations. As this has already been expressed in previous entries, this was achieved with the excellent GoKit by prime[31]. Definitely have a play around with this and to help you its featured heavily within the Banana Demo project.

With this in the bag I thought I would experiment with getting GameCenter integrated into the game as the one on the Appstore features OpenFeint which is now deprecated. I started off thinking this was going to be a straightforward exercise but got a little confused with how the GameCenterPlatform class worked with Unity, scripting and Futile.

This is where my day started to go a little downhill and this was typical of not knowing enough about how Unity worked. My first mistake having implemented the code was wondering why ads weren't appearing within the Game window of the Unity editor.

What I hadn't done was to enable GameCenter under iTunes Connect for a unique app. Only with this will ads works. To enable follow these steps:

  • Log on to iTunes Connect
  • Click on Manage Applications
  • Ensure you have an app which is in an edit state such as waiting upload or an equivalent to modify GameCenter state.
  • Click on Manage Game Center
  • Click "Enable for Single Game."
  • Click Disabled.

The Disabled button toggles between Disabled and Enabled. To disable your app for Game Center testing, click Enabled. Once you disable, you will no longer see your app in the Game Center sandbox. You are only permitted to disable up until a version of your app goes live with Game Center. Enabling Game Center for testing unlocks the Game Center interface to allow you to set up your leaderboards and achievements.

Once I had set this up I created one Leaderboard and one achievement to ensure there was content.

Alas, still no test advert coming through. It was at this point I thought that maybe they didn't come through within the editor and I need to test on my device. This was my second mistake of the day.

For some reason I didn't realise it was packaged into an Xcode project. Having come from Corona SDK this step didn't happen it just got compiled and you dragged the compiled .app file onto the iTunes to add to your device. This was when I realised I hadn't setup the bundle identifier properly either.

The next mistake I made was trying to compile the xcode project to the Xcode simulator. The reason I was trying this was that I wanted to ensure the project worked before trying to put it to my device. I was getting some fundamentals errors on compilation, over 200 in fact, which I felt just couldn't be right. After some twitter conversations and scouring the internet I found you can only compile to the device.

So after some wasted hours I now had my app on my device, but still no adverts. It was time to call it a day.

Day 9
A new day brought a clearer head and renewed vigor. When I first started out with game development I wanted to write my own code and therefore learn and understand the most. But having done it now for a year and having to balance my time with a full time job and two young children, I've concluded that using third party plugins is ok. Yes there is a cost to them sometimes but I weigh that up to cost I put on my spare time. Yes I may never make it back on my games in the near future but for the sake of $20 there is no point me struggling for a week trying to get something to work.

This clarity was reached to some degree during my investigations on Day 8 when I repeatedly came across postings and recommendations for prime[31]'s GameCenter and Ad plugins. Having already experienced the ease with which their GoKit was implemented I decided to take the plunge and bought the GameCenter and AdWhirl plugins.

The plugins are excellent and can be setup with a few very easy steps.

For AdWhirl first setup an account and get your Publisher ID as this is what the prime[31] plugin requires. In regards to ad providers I chose a distribution of iAd (70%) and AdMob (30%).

Assuming you have followed Matt's banana project to a point you would imported a futile package, dragged to the Unity hierarchy and assigned a script to your Futile game object. With this assumed open your script and declare a private variable such as private string publisherId = "your id goes here"; . Then within Start method, and this apparently is the important bit, make AdWhirlBinding.init( publisherId ); your first call.

Having implemented this I built for my device and tested and BINGO! adverts start coming through.

Again, buoyed on by this working I turned my attention to GameCenter. I had assumed I had setup everything up in the iTunes Connect steps explained above so I set about implementing it.

Like all implementation's of GameCenter you must first check that GameCenter is available and then you authenticate. For the purposes for testing I am resetting the achievements each time to ensure the banners etc come in. The code, again in my Start method is:

// Do gamecenter stuff ... Is GC available?
if(GameCenterBinding.isGameCenterAvailable())
{
	// Yep looks like it is so authenticate the player;
	GameCenterBinding.resetAchievements();
	GameCenterBinding.authenticateLocalPlayer();
	GameCenterBinding.retrieveAchievementMetadata();
	GameCenterBinding.showCompletionBannerForAchievements();
}

Before testing on your device ensure you log out of GameCenter as when testing on your new game and you log in it will go into Sandbox mode while in development.

Success!!

Day 10
A very successful day on day 9 so to continue on with this I thought I would hook up the achievements when a certain distance was achieved. All I do is create a method within the Update method of my game scene to check whether a certain diatance has been achieved:

void checkAchievement(int _score)
{
	if(Main.instance.BestScore == 0)
	{
                // First play
		Main.instance.BestScore = _score;
		GameCenterBinding.reportAchievement( "AA001", 100.0f );
	}
	if(_score >= 5000 && _b5000 == false)
	{
                // Distance achieved
		GameCenterBinding.reportAchievement( "AA002", 100.0f );
		_b5000 = true;
	}
	if(_score >= 10000 && _b10000 == false)
	{
		GameCenterBinding.reportAchievement( "AA003", 100.0f );
		_b10000 = true;
	}
	if(_score >= 15000 && _b15000 == false)
	{
		GameCenterBinding.reportAchievement( "AA004", 100.0f );
		_b15000 = true;
	}
}

If a score has been reached then via the GameCenterBinding i.e. our prime[31] plugin, it sends a message to iTunes connect to see if an achievement has been completed. This is the case because we provide the id of the achievement and the percentage complete. As I specified GameCenterBinding.showCompletionBannerForAchievements(); in my initialisation method the player will get instant satisfaction as the achievement banner will be shown. This all happens on a separate thread so no effect on the game's performance.

The next challenge was to take on the music and sound effects within my game. I slightly misunderstood how this worked and didn't take advantage of Futile's sound manager, FSoundManager. So what I chose to do with this was to adapt the Banana project implementation and create a separate sound player class:

public class SoundPlayer
{
	static public void PlayBlipSound()
	{
		FSoundManager.PlaySound("Blup", 0.95f);
	}

	static public void PlayMusicSound()
	{
		FSoundManager.PlayMusic("music", 0.3f);
	}
}

This implements the in-game music and the button sound effect. The gotcha I had here for a little bit was I didn't notice the difference between the methods of PlaySound and PlayMusic. All I now need to do is within my Start method of my main class is to call SoundPlayer.PlayMusicSound(); and viola music a go-go. Similarly, in my SignalRelease (eventhandler) methods for my buttons I call SoundPlayer.PlayBlipSound(); to have a sound effect when my buttons are touched.

Day 11
Jumping around a little bit I refined the resolution logic:

FutileParams fparams = new FutileParams(true, true, false, false);
fparams.AddResolutionLevel(480.0f, 1.0f, 1.0f, "");
fparams.AddResolutionLevel(960.0f, 2.0f, 2.0f, "-hd");
fparams.AddResolutionLevel(1024.0f, 2.0f, 2.0f, "-hd");
fparams.AddResolutionLevel(1280.0f,	2.0f,	2.0f,	"-hd"); //Nexus 7

and worked on my Rocket retina graphics. Again, going back to old faithful in Texturepacker and recreating atlases with the appropriate suffixes.

I also worked on touch logic whereby a user clicking on the screen would allow the rocket to change "depths" giving the illusion of going in and out of the asteroids and in turn running the sprite animation of the rocket.

Day 12
I am unconvinced about whether the accelerometer is the right way forward for this rewrite. However, I want to make sure I don't over engineer this game as that was the original control system and move on to pastures new and new learnings. What I did decide to do is implement a Dpad and evade button just to see how it works.


I wanted to keep the style minimalist and non-intrusive as possible. How I implemented was to create shapes. One of the complete Dpad and then a further 4 for each direction which is then created as a separate FButton and placed over the top of the complete image. The evade button will be used to run the rocket sprite animation and change the alpha of the asteroids so the player knows which asteroids to avoid. Also a little rearranging on the screen to ensure it doesn't become too crowded. Tested on various resolutions to ensure all sits correctly.

Day 13
Back to graphics and animation today and that is to create a rocket flame / exhaust. I had a slight headache over how to implement this. In the current version using Corona this is a particle system using a third party plugin called Particle Candy which was very easy to use. However, the new Unity particle system Shuriken was something that my novice experience was struggling with and not one I could see how it could be directly implemented using Futile.

Instead I chose to animate via Flash and export the frames from Flash into my atlases and create an object to play and scale the exhaust appropriately. The effect I am pleased with but feel I will need to tackle the particle system sooner rather than later.

Day 14
Big subjects were tackled today, collision detection and multi-touch. Let's start with the latter.

Multi-touch is important for my game as I want to move and evade at the same time and the normal signal release (eventhandler) won't even queue messages as its first come first served.

I'll confess I made a major oversight with implementing this and wasted a lot of time. An important point is to ensure you also inherit your class from FMultiTouchableInterface and then to update your Stage Handlers to include and remove multitouchtargets.

Code:
override public void HandleAddedToStage()
{
	Futile.instance.SignalUpdate += HandleUpdate;
	Futile.touchManager.AddMultiTouchTarget(this);
	base.HandleAddedToStage();	
}

override public void HandleRemovedFromStage()
{
	Futile.instance.SignalUpdate -= HandleUpdate;
	Futile.touchManager.RemoveMultiTouchTarget(this);
	base.HandleRemovedFromStage();	
}

with the final thing being is to implement what should happen when multiple touches occur with the public void HandleMultiTouch(FTouch[] touches) method. This should now allow your game to detect and react to multiple touches.

The next thing to tackle was collision detection. I managed to setup a collision detection of sorts by again having a method within the Update method checking whether one FSprite's position overlapped with another FSprite's i.e. rocket and asteroids, While it worked I found it wasn't responsive enough.

Day 15
Having thought about this some more I was coming to a realisation that maybe I needed to dig a little further into the Physics system. While there isn't one setup specifically within Futile the community has written FPhysics which allowed more realistic collisions to happen between objects. This in itself through up some interesting points of research. The main problem still was that neither Futile nor FPhysics implement fully a method to programmatically initialise rigidbody and in turn a collider in order to take advantage of collision detection inbuilt to the Unity Physic system. Where it should be possible to create something like the following:

void OnCollisionEnter(Collision collision) {
    foreach (ContactPoint contact in collision.contacts) {
        Debug.DrawRay(contact.point, contact.normal, Color.white);
    }
    if (collision.relativeVelocity.magnitude > 2)
        audio.Play();
    
}
this will not fire in either of the two earlier instances. On discussion with Matt what it has highlighted is that it is very possible but in my novice state my understanding of Unity's components means that I am going round in circles.

So that brings me on to what to expect from part 3 of this series. The focus will be on bridging the gap between Futile and 2D in Unity to tackle the particle system (Shuriken) and the physic system to implement an equivalent experience to my Corona SDK game.

It should be noted for those that use Corona that this seems like a huge amount of work when Corona wraps this all up for you and that is indeed true and one of its big advantages. However, I have seen enough of the potential of Unity and getting familiar with its setup to know the short term pain will be more than worth it.

Until next time, Happy New Year!

Sunday 23 December 2012 3 comments

Spriter: helping your 2D animation woes

I'm no artist, in fact barely a coder but one thing I struggle with is decent 2D art / animation. I can't remember why or the date but I have used Flash on and off for doing my art and animation for over 10 years but have struggled to find a decent alternative. I think what I like about Flash is the nuances of the tool for drawing that I am yet to find else where.

Its for these reasons that I started an investigation into something that could replace or complement my current toolset.

If you look at my current game on the market, Astavoid, I have a distinct style. This more than anything is minimalist given the time I have to focus on the art. I was told, and I forget the source, that its important as an Indie to do your own art as you aren't reliant on someone else to do your work, minimises cost and therefore a master of your own destiny. With that of course comes budget. I for some reason, again forgetting why think its age, have a copy of Flash CS3 which is by no means a feature rich product by today's standards. However, it is something I am reasonably comfortable with.

My route of investigation took me to Spriter. Spriter if you don't know is an animation tool for 2D games. Larger, more smoothly animated characters, all running for your favourite engine and platform. It had a very successful kickstarter in April 2012, of which at the time of writing the product sits in Alpha.

It is for the purpose of this blog to see whether Spriter can compliment an art package to provide quicker animation techniques over maybe that of tweening in Flash.

So lets begin, to start this off I will create a little gun man type thing which is a concept I have been working on. To help you visualise my minds eye we jump ahead a little to the final image.

Having read the web pages of Spriter it looked like my animation needed to have component parts. This is because Spriter accelerates the animation process by transforms or skeleton rigging to provide pivots and movement where required.

My first step was to breakout my character into various body parts. As you see from the image above I have a character with a gun. What I will look to animate is the character shooting with a slight bit of kickback / recoil.

For that reason I split my character out into sections:
  • Head
  • RightHand
  • RightArm
  • Gun
  • Body
  • Feet
  • LeftArm

These are organised as such and this order to give the relevant layer depth to give the illusion of the character holding the gun etc.

With this now in situ I save out the layers one by one as PNGs hiding all but the layer I'm saving to have distinct images.

Next is to fire up Spriter, if you haven't done so already download here and then once installed create a project and then import all the images we have just saved out. We then in turn position the images on the worker area to reconstruct our character. All going well it turns out like the one below.

The next thing to do is create keyframes along a timeframe, identical to how implemented in Flash, to denote when something should happen. This is the point whereby you start your experimentation. For mine I will add a keyframe around frame 80 (assuming a 60fps game) to move the gun to an aiming position. To do this we simply click the object "gun" in either the "objects in frame" window, or on the working area and a transform box will appear

To make it do something you can either move it (replicating a tween within Flash where it will animate to), scale or pivot. For the purposes of what I am doing I will pivot on the bottom left corner so the top right is pointing up. It's as easy as that!

The process now becomes trial and error rather than complicated keyframe drawing only to find there is an error.

Once you have completed your keyframes are ready to export out ready to put into a spritesheet / atlas. Here is something you must watch out for. In the current version of Spriter, at time of writing the alpha version, only the keyframes will get exported and not every frame. This of course for an animation is next to useless.

However, not all is lost. Dependent on the length of your animation this workaround could be pretty tedious but what you need to do is add a keyframe to each frame of your animation. Then when go to File -> Export to PNG all frames will be exported for you. Now you are ready to put your keyframe animated images into atlases / spritesheets with a tool like Texturepacker for use within your game.

And there you have it an animation in next to no time. So what are my feelings of Spriter. To be honest huge potential as the process of pivot and move was very easy with the key being to split out my character to component parts and the rest is a doddle. I will certainly be intrigued to see how the beta and full release of the product turn out.

6 comments

From Corona & Lua to Unity & C# - Part 1

For those of you who have followed my blog for a while you will see that title and think: "Changed his mind again!!", and you'll be right. I was taking my last blog a little further and experimenting with Cocos2D and Kobold2D. Both proved excellent and Steffen Itterheim's book Learning Cocos2D gave me a good grounding in both.

I think the thing that I started to get disheartened by was as soon as I finished the book Steffen announced he would be transitioning from Kobold2D to KoboldTouch. While that is no great shakes in that I hadn't really started I thought to myself given that I was looking to transition did I want to go with something that was closer to my core, .Net. The rationale behind this is that although I have released apps in Lua and Objective-C they took longer than I wanted as I got used to the syntax and idiosyncrasies of each.

Like a lot of people I am a follower of Matt Rix (@mattrix of Trainyard fame) who had spoken of a 2D code centric rendering framework he had been working on called Futile for Unity. I was intrigued by this as I had wanted to dabble with Unity for some time but had been put off by the plethora of buttons and options as well as a third axis I hadn't even contemplated :).

To start off with I watched the videos on Matt's website http://struct.ca/futile which gave me a decent insight into what it was capable of. I'll be honest I had to watch them each about three times to break through my mental block of Unity but what was becoming clear is that Unity only forms about 20% of this approach. MonoDevelop would become my friend and that was the point, code centric. So I thought I would take the plunge. First off I followed the steps on Matt's Github page:

How to open the project

  • Grab the project from github and put it somewhere - For the lazy, here's a zip of the whole repo
  • Make sure you have Unity installed
  • Go into BananaDemoProject/Assets/Scenes and open FutileDemoScene.unity
How to make sure you're running it at the right resolution
  • Go to File -> Build Settings -> Click "PC and Mac Standalone" -> Click "Switch Platform" (if it's already greyed out, you're good)
  • On the Build Settings page, choose Player Settings
  • Under Resolution and Presentation, set the size to 960x640 (or 480x320, or 1024x768)
  • Go to the "Game" tab
  • In the top left dropdown, choose your resolution (instead of "Free aspect")
  • In the top right, make sure "Maximize on Play" is enabled.

Having followed these steps and watched the video while playing around with the code I personally started feeling quite comfortable with the concepts. In particular the third video of just over an hour really helped cement my understanding

For the purposes of clarity I am using Unity 3.5 (not 4.0) and took advantage of Unity's April 2012 give away on iOS basic. The latter is obviously required for publication and distribution but the free one to PC and Mac can still be designed to and just change the player settings to 480 x 320 for example.

Like most things when you start with something new I need a focus to adapt to my own requirements. This is the only way I find I can learn is to play around with things and try and try again. What I thought I would do is document my day to day transition from Corona and Lua to Unity and C# which the latter seems a popular option. For me the code for Astavoid was actually very similar to Matt's BananaDemoProject so unless I make paricular reference to code I would strongly recommend having a nose around there.

What should also be noted is I'm a hobbyist Indie (not sure that even exists!!) but means I can only afford at best 4 hours a day in the week and perhaps a little more at weekends. So my definition of a day is actually quite short so your progress could be even quicker.

I thought writing a new game would probably be too challenging so instead I focused on porting Astavoid from Corona SDK and Lua to Futile/Unity and C#.

For those of you who haven't had the pleasure of playing my first game its a very straightforward space evasion game that is available free on the App store. Why not download it for reference, its free after all :).

Day 1
First and foremost I didn't want the same hassle I had when I first wrote Astavoid concerning fonts. On the iOS and Android devices handle paths differently so I followed the lead of Matt's video tutorial and purchased Glyphdesigner. Really not sure why I didn't do this the first time but is an excellent tool to ensure compatibility of fonts across devices. Furthermore, I could include this font image within my textures / atlases. The font mapping file (.txt) also needs to be included within your resource folder in Unity.

The next tool to your arsenal is the excellent Texturepacker this proved to be a lifesaver when I first wrote the game with Corona and is equally as effective for Unity. The only difference being that it outputs a text file rather than a Lua file but the transition is seamless. I couldn't recommend the product enough and, again, if you watch the video's on Matt's page this is what he is using.

So with my font and background graphic within my texture I was now in a position to create my first scene. Nothing too strenuous as really I was dealing with 5 text objects and a background image. Needless to say this was very straightforward. I created my Main.cs (C# script) which I dragged onto my Futile object. Then I open MonoDevelop and put the appropriate logic into the Start method of the Main class. Ensuring of course to add the labels and sprites as children of the scene (AddChild(object) so that they show up. Missed this one a few times :)

The result was a fair reflection of the original title page, other than the fact it didn't do anything at this stage:

Day 2
Buoyed on by my first day's achievements, and when I say day I only mean about 2 hours, I set about bringing the asteroids into my texture and look to provide some movement.

I started to organise my code a little and create an FContainer (or scene) to split up the various screens I was going to need. So I created a TitlePage and a GamePage.

Within my Start method on the Main class I did a call to the title page which in turn did a call to my game page. To conclude the navigation my game page, via the pause button, would return me to the title page. This simple transition meant two classes representing the scene, and my Main class with its singleton instance controlling which one to display. At this point I was calling the scene methods directly and not by button touch.

With this now working well I revisited Texturepacker and dug out my asteroid artwork and added it to my texture. I then re-published and added my new texture to the Unity project.

There is no specific physics engine built into Futile specifically aimed at 2D at the time of writing. Unity of course contains the powerful NVIDIA® PhysX engine but the whole purpose of using Futile was to make my life easier. So on day 2 of my adventure I focused specifically on animation

Thankfully Matt has considered animation / tweening and incorporated Prime31's GoKit library into Futile which makes animating the Futile objects very easy. All I had to do is create a base class for my asteroid object and derive from this for my different asteroid types to give the perception of depth. I then used the GoKit library to tween these asteroid objects relative to their size and depth and then cull when off screen.

Day 3
The aim of day 3 was to hook up the title buttons via touch. Again this is straightforward enough through Futile's touch manager. By reviewing the code of the Banana demo project it is straight forward to see how the touch events via a signal release and then the relevant method to call. From these methods I was then calling my instance to call the scenes on the stack. This makes traversing the scenes easy.

An additional update was to apply the distance counter to the update method of my scene. My game by this point is running at a very smooth 60fps which exceeds the 30fps I was running at with Corona. Not a limitation of Corona I should say but mine in writing efficient objects and caching correctly. I remember probably spending about 2 months on this subject alone optimising my lua code and get it done in a day with Futile / Unity! I use a modulus to only update the counter every other second (or update) to keep the distance score a little more realistic.

Day 4
With the principles of the scene setup I turned my focus to the rocket sprite. Its worth noting at this point that I am using existing assets that may need to be modified dependent on what control mechanism I go for.

With this in mind I created another texture atlas in texturepacker for my rocket and therefore not over bloating my other atlas. This is in part because I made the decision to add in my space background to the original atlas as it would be used on multiple scenes.

I also revisited my asteroid code and inherited more from my base class to streamline my code and adhere to the DRY approach of Don't Repeat Yourself. With this refactoring done I created a fourth size of asteroid to run in the background as a form of parallax asteroid belt.

Day 5
This was a big update day! The first was tackling how to handle storing of data within Unity. I learnt that this was done with key value pairs that could have certain types attributed to them such as strings, floats, etc. I looked at using the PlayerPrefs class to store information for my best score but thought this needed to be extended a little to create my local leaderboard. I found something that I could base my class on here and adapted appropriately. Having returned all scores to my list they are sorted and then limited for my purposes

As well as adding in my best score logic and leaderboard I ensured that all buttons triggered events. This meant converting the FLabel to an FButton and in my case adding a transparent image behind the text for the hit state.

Day 6
To mimic the Astavoid app that is already in existence I applied the GoKit tween logic to my Flabels and FButtons for the transitions between pages / scenes. The transition effect is done within the constructor of the scenes FContainer class while I wrote a specific TransitionOut() method to handle the text and image objects movements back to the start. This works really well with smooth movement and some nice effects such as easing in and bouncing.

Day 7
Android was definitely an area that took a lot of development time up with the original release of Astavoid. The fragmented screen resolutions took some thinking and some adjustment in the code. While iOS isn't there yet its certainly heading in that direction which is why I was relieved to see that Matt had given it some consideration within Futile.

To tackle this I revisited by trusty tools of Texturepacker and Glyphdesigner and increase the size to be scaled appropriately for retina screens. I looked into Matt's Banana project to get a feel for the text sizes he used for this project and played around with my ratios as I had three different text sizes to his one. From this I setup the AutoSD feature of Texturepacker which works to the principle of largest size and then scales down the different ratios as are relevant.

Obviously we would work to the Retina x2 (or even x4) normally but I haven't had a chance to go back to the drawing board on the graphics so just want to work out the logic for the resolution switching.Highly recommend if you are starting out you work to the largest resolution. There are lots of guides out there but this one is pretty useful.

The result being that I have simple parameters set as part of the Futile init that determines the width that is relevant to that resolution, the scale factor and the suffix of the atlas file to pull in. For debugging purposes the scale ratio and the file being used is echoed to the Unity console so you can make sure you are scaling correctly.

A pretty productive first week I think you agree. I have learnt loads in this time and while have lots to learn I feel confident of getting this simple game ported.

Thing to note is that Futile is in its infancy at the moment so documentation is pretty light. However I found Matt Rix (@Mattrix) and Whitaker Trebella (@wtrebella) of Polymer fame, to be incredibly helpful with my annoying question. I can also help with the basics and can be found at MyGamingProject @gameproject10k where I will be happy to help. Part 2 can be found here covering Collision Detection, Multi-touch and sound will be tackled. Another busy week :)

Thursday 15 November 2012 0 comments

Six months in turmoil

Having released Astavoid back in April I very much saw that as a springboard to my 10,000 hour project. I had delivered on a lifelong dream to write a game, however basic, and now I was ready to make something more complicated.

This was my first error. Having remained focused on Astavoid to make a game that was simple and therefore achievable meant I got it finished. However, on reflection I bit off more than I could chew meaning my ambition outweighed my ability and I become disillusioned a little. I was attempting to write a grid library that meant I could do a game like train yard, polymer, letterpress etc and have a formula that was repeatable to get more games out. However, as I evolved the grid I lost focus on my goal of the library and started dabbling with no real purpose.

As writing this its a little like therapy and maybe I'm being harsh on myself but I feel I had lost 6 months development time and certainly hoped to have at least one more game released in my first year.

What I ended up with was a partially complete grid library and some prototyped game ideas but none of which I particularly wanted to play once complete so why would anybody else.  This is also when I started doubting whether Corona Labs (renamed from Corona SDK) was actually for me.

To qualify this I had chosen Corona after research because of its ease to build to iOS and Android devices. I had launched on both including Kindle with reasonable ease but found the effort to support both outweighed the returns. I found i was getting about 8 times the download on Apple devices. Also I personally found setting up a developer account for Nook tortuous and still to this day haven't pursued so why were my main drivers multi-platform.

Also the true lack of Gamecenter (matchmaking) and iAD support personally limited the direction I wanted to go in. Also having spent $349 on a Corona Pro license I felt pressured to churn out games, to make money to provide a return. On reflection completely the wrong way to manage my projects. While Corona do other an Enterprise license that may overcome these issues with access to native code that is further investment. My biggest bug bear was a lack of IDE and visual debugging. The writing to console was painful and extremely time consuming and took me back 10 years when I wrote classic ASP websites. While in fairness there are third party IDEs such as LUA Glider now on the market they still dont offer the tools that others already have in place.

This led me to Unity. Without a doubt the tool to use at the moment and the possibilities are endless and having made my way though tutorials had quite an affinity for it. The use of C# is closer to my experiences as well. I dabbled with it for about 6 weeks I again found I had lost focus. The trouble I was finding was that it was just such a large tool and again the costs were prohibitive for somebody who had 3k downloads and no revenues. Since I last looked at it fellow Indie Matt Rix has brought out a library called Futile to work in a way I am more accustomed but feel I need some more games under my belt that has more community examples and support.

This is when I made my choice which I'm now content with and refocused and that's Cocos2d / Kobold2d. Its not just one of cost but also the support and maturity of the community. While Cocos2d has proved really successful to date it had suffered in the frequency of its updates, this is where Kobold2d comes in in terms of its efficiencies it brings to the development process such as ARC and full Gamecenter support to name a few. The use of Xcode again gives me tools which I feel have been lacking.

So looking back over my first year as an indie I haven't achieved my ambitious goals in fact got nowhere near (for example Astavoid achieved a highest position of 82 in action category in Spain) but I still continue. A vast number of Indies don't make a second game and to be honest I can see why but importantly I addressed my challenges, refocused and am looking to continue.

 Look out for my second game in the New Year.


Saturday 9 June 2012 5 comments

Astavoid: A postmortem

The last six months have been a hell of a journey and have learnt so much.  What I don't understand are those people who write a game, expect it to become the next Angry Birds and then give up. What I have learnt from writing Astavoid has been invaluable but more importantly it is what I do next and having learnt from my mistakes are key to me achieving my goal.

This project and reaching out into the indie development world has been brilliant and would like to share some of the snippets I have received either directly via email or gleaned from other postmortems, blogs, tweets and browsing the interweb.

The general feedback I got about Astavoid was that it was a great first effort, that it was complete and polished with some neat twists but ultimately too hard and not sticky enough. This is supported throughout my analysis.

Keith Shepherd of Temple Run and soon to be released Temple Run: Brave fame was kind enough to feedback via email on my blogs and design of Astavoid with a number of pointers. Probably the biggest pointers I got from him were don't do soft launches but instead make a big impact by publicising your predefined launch date while also ensuring you never pay for reviews on review sites.  The other main point was making sure you keep player retention and he used the analogy that 50% of Temple Run's users were still playing after a month.

Another Indie I have had the good fortune of exchanging dialogue with is Whitaker Trebella.  He too has just launched his first game but his launch day tactics were exceptional.  He really got the word around and while he has some contacts in the industry having done some excellent scores for games such as Tilt to Live, Super Stickman Golf and Casey's Contraptions, he ensured he got the word around.  Again, tips I  have picked up from him were use Twitter, use blogs and forums (Reddit, Touch Arcade etc) and create a decent game trailer, the latter of which I was disappointed in my own efforts. Whitaker wrote a very good article on using Twitter to support your game launch: http://www.whitakerblackall.com/blog/a-guide-to-using-twitter-to-promote-your-game/.

Matt Rix of Trainyard fame and inadvertently Noel Llopis (Casey's Contraptions, Flower Garden),  were incredibly helpful in refining my game design for different reasons.  Matt was kind enough to be one of my beta testers and gave me some constructive criticism to make the game more accessible to the masses.  Like all good ideas (well good ideas to those that conceived it) you think that everyone will love it.  The challenge with apps is that you aren't dealing with gamers or a specific target audience specifically and for that reason you don't want to overcomplicate gameplay.  This is definitely something that Matt pointed out to me which meant I went through a number of iterations of beta testing based on his feedback to make the control mechanic more akin to Tiny Wings and Jet Pack Joyride et al.  Noel, on the otherhand, gave me insight into indie development as a whole which I have blogged separately about but I was able to be a beta tester on his Flower Garden game that gave me a view on to how games should be tested and user feedback being considered and adopted so late in development cycles. 

I have also read some great articles concerning the guys over at UsTwo who, amongst other titles, are reasonable well known for the very enjoyable Whale Trail. To paraphrase a few articles the tips from these guys are:
  • Give journalists a story to tell: the app store is too populated to just be about the game on the whole.  Have an angle to sell in and make you stand out from the crowd
  • And target the right journalists: Review sites may not be the write medium as not everyone is a gamer.  Look for other mediums such as newspapers etc
  • Get the right offering together before launching: make sure what you launch is right and not rushed to get something out on the market
  • Talk to your fans: ownership, involvement and loyalty will undoubtable helped mould a better experience
  • You don’t just need a good idea, you need a marketable idea: What do users actually want?
  • But it needs to be a marketable idea that you like: make something you want to make!
Along with this advice that I have gathered so far I thought I would share a few learnings of my own.  For what it is worth my game, Astavoid, hasn't been a great success.  It was launched mid April 2012 on iOS devices (iPhone, iPad and iPod), Android and Amazon Kindle.  The breakdown of stats are as follows:

iOS downloads: 2,297
Android: 270
Kindle: 89

Total: 2,656

To be honest I don't know what I was expecting from my first game but these seem respectable.  That said half my iOS downloads were on the first day.  But considering, despite my best efforts, to get reviews and press coverage this is purely word of mouth and one press release via prMac.

The only thing I have done is invest a total of $140 ($70 on iOS and $70 on Android) in AdMob advertising campaign.  The tactic of this was to see if this had an impact on sales and whether in app advertising was a future strategy I should consider.

I ran the AdMob campaign on separate weeks, with a daily spend of $10 and a click of $0.01 which should generate 1000 click throughs to the relevant app stores.  So for $140 I should get 14,000 click through to stimulate downloads.

The following two graphs are the effects that the advertising had on the downloads figures:

Android 

iOS 

The graphs are a little misleading as the spike on the Android one is much larger given the relative non existent downloads to that point.  What the graphs do show is that the ad campaign did stimulate spikes.  However, despite the campaign breakdown as shown below the relative click through rate and the resultant conversion to a download was negligible


As you can see my ad was show some 2.4m times but the general awareness didn't really stimulate anything.  This then brings me to the main point of monetarisation.  Going back to the advice that Keith gave the game must be sticky and there is no truer word then when you have a free app reliant on ad revenue.

Just to be clear about my goal although it is about making enough money to put my kids into private education and pay off my mortgage I wasn't expecting to make a dent in that with my first game.  In fact I see my first year making a loss and hope there are enough lessons to build on for year two to be profitable. With that in mind I will share with you my bag of loot.

[Update: As noted by AC in the comments this is timelapsed based on revenues per day]


Yep thats right $10!!! So just AdMobs alone I am at a $130 loss.  But this is what this is all about learning, experimenting and putting these skills and thoughts into action that mean the second, third and one hundredth game.

So what will I be taking forward into my next game? To summarise:

  • A paid for app [Update: main comments are to consider freemium, we'll see :)]
  • A game that allows short bursts but brings the user back
  • To engage far earlier in my marketing.  To fix a date some two or three weeks after the app is approved and let the media, forums, blogs and the world know its coming
  • Create a quality teaser video that does it justice
  • Make a richer, deeper but polished experience for the user
  • Try to instill some elements of community 
  • Learn more
  • Keep having fun
So for now I will leave Astavoid behind and have fond memories of fulfilling a dream of writing a game however simple it ended up being and move on to much bigger and better things.

Check out Astavoid on App Store and Google Play and download for free.
Sunday 29 April 2012 0 comments

Marketing and Revenues - Week 1

I thought I would disclose a warts and all appraisal week by week of my success of each game I launch.  Being that Astavoid was my first game there was little blueprint to work to other than read around and get a sense of what others were doing.

I released Astavoid on the 19th April 2012, a Thursday.  I am led to believe that this is important as far as the Appstore is concerned as this is their changeover day so launching on a thursday allow you to build up downloads, recognition etc over the week so more chance of getting featured the following week.  A wives tale I'm not sure.

I wrote a very basic website to support the launch on my main Parachuting Frog website as well as create a gameplay teaser on YouTube.


To be honest I'm not that happy with it as I don't have anything more than an iPhone 4 and a GorillaMobile tripod so the quality is pretty amateur but heh I'm learning.

For prerelease I also have two twitter accounts mygamingproject and parachutingfrog that help spread the word and keep people you to date.

For launch I released to Google PlayGetJarAmazon App Store for Android, Amazon Appstore for Kindle, as well as the Appstore for the universal app for iPad, iPhone and iPod including Retina support up to IPad 3.  So I had most bases covered apart from Nook Color which I am still waiting on administration.

I started off with a soft launch because there were some key upgrades I wanted released and approved by Apple before telling the world. Alas there review process takes so long (7 days for first version and a further 6 for the update) makes a coordinated multi platform release quite tough.

So on day of launch the only marketing was tweets and the trigger process that kicks in over the internet when new apps are out.  The weekend of 21 and 22 April I did two things.  I submitted my app to about 30 sites android review and probably 20 for Apple.  The frustration I have found with review sites it would appear is that nobody is prepared to write a review for free unless you have connections or prepared to pay for it, or wait a long time for it to become popular.  A little chicken and egg.

The reason I didn't want to pay too much in marketing in the first instance is that my game is free so I needed to understand what the click rates would be and recycle it into marketing.  The exception to this was a PR release I did via prMac.  prMac has various packages but for a reasonable $20 you can release a press release which can be distributed to over 700 press agencies. So I did that and here is my press release.

So now you know my prerelease and marketing efforts lets have a look at what the first week's downloads look like.


19th April 20th April 21st April 22nd April 23rd April 24th April 25th April
iOS 1130 379 157 130 75 36 18 1925
Android 3 1 1 5 2 5 2 19
Kindle Fire 1 6 2 0 2 4 0 15

1134 386 160 135 79 45 20

As you can see, and to my surprise, I had a massive launch day surge.  I can only assume this came about from twitter accounts and "watcher" services that broadcast when new games are out.  I have quite an eye catching icon logo and unusual name so seemed to catch the imagination of some.

The interesting thing is that iOS tailed off dramatically after that first day.  Android, however, given the same marketing efforts has had pitiful downloads.

So this is all very interesting but what does this equate to in terms of hard cash.  Well as I mentioned I am doing the first one as free so revenues are purely down to advertising revenues.  I have positioned ads on the front menu screen, pause menu as well as the game over screen.  This should mean that even the shortest of games should put in two ad requests.  The problem however with ad revenues is you get nothing for impressions but only for those that are clicked on.

The next area of analysis of how the people are of my app are engaging with it.  This is where Corona SDK provides a very useful tool called Launchpad that is by default is switched on for pro subscription developers that provide insight into these trends.

The first is the session length.  You will see that from this stat that iPad is by far the most popular device and that most are only playing my game for a maximum of 39 seconds.  The very nature of my game being a quick pick up and play is working against me in making it sticky enough to get those additional ad rotations in and therefore money.
The next is sessions.  The peak of sessions corresponds by day to the downloads and again supporting that the most popular device was iPad.
As for unique users this kinda shows that there isn't a great deal of return visits going on.  In my mind people are playing it, trying it and then deleting.  A concept of course which is well supported by having a free app as they have nothing to lose but ultimately not great for revenues.

So what does this look like for revenues.  As you'd imagine nothing life changing! I have implemented an aggregator into my code which first uses Admob and if this can't fill for whatever reason trickles down to Inneractive.  The reason for these two being used is in some part limited to what Corona SDK supports but also those that are around most countries.


As you can see from the stats again its supporting the the number of downloads to ad requests. But what is important is that there is only about one impression per download.  This means some people may not even be playing the game which seems a little odd.  Most important though I have only made $6 in revenue which is the equivalent of roughly having about 14 paid download apps. As you'll see from the clicks there weren't a great deal despite the reasonable impressions.

The final thing is to look at how the downloads faired across the world.  I am using the excellent Appannie to give me stats.  Also try the excellent Majicrank for realtime stats if your app reaches a rank of 200 or better.

For iPhone I had a reasonable spread across countries if not ranking that high ...
StoreActionArcade
# of top 500 stores67
# of top 1000 stores1919
Turkey166Apr 19, 2012375Apr 20, 2012
Mexico385Apr 20, 2012341Apr 20, 2012
Cyprus465Apr 19, 2012403Apr 19, 2012
South Korea479Apr 20, 2012394Apr 20, 2012
Sweden481Apr 19, 2012593Apr 20, 2012
Spain485Apr 20, 2012437Apr 20, 2012
France513Apr 20, 2012472Apr 20, 2012
United Kingdom599Apr 20, 2012380Apr 19, 2012
China602Apr 19, 2012549Apr 20, 2012
Netherlands641Apr 19, 2012634Apr 20, 2012
Brazil654Apr 22, 2012603Apr 22, 2012
Armenia705Apr 21, 2012599Apr 21, 2012
Italy706Apr 20, 2012670Apr 20, 2012
Japan724Apr 19, 2012643Apr 20, 2012
United States747Apr 20, 2012664Apr 20, 2012
Germany759Apr 20, 2012611Apr 19, 2012
Canada760Apr 19, 2012688Apr 19, 2012
Switzerland805Apr 20, 2012728Apr 20, 2012
Egypt945Apr 19, 2012844Apr 19, 2012

and for iPad a little greater success where in 4 countries got into top 100.  This of course is supported by the stats in the other graphs

StoreActionArcade
# of top 100 stores04
# of top 500 stores1015
# of top 1000 stores1015
Turkey104Apr 19, 201286Apr 19, 2012
Ireland104Apr 20, 201288Apr 20, 2012
Italy104Apr 19, 2012195Apr 20, 2012
Romania109Apr 19, 201280Apr 19, 2012
Denmark116Apr 19, 2012110Apr 19, 2012
Spain130Apr 20, 201288Apr 19, 2012
Japan172Apr 19, 2012-
Brazil173Apr 20, 2012153Apr 20, 2012
Sweden187Apr 19, 2012171Apr 19, 2012
Israel194Apr 20, 2012167Apr 20, 2012
Netherlands-170Apr 19, 2012
Mexico-176Apr 20, 2012
El Salvador-177Apr 24, 2012
France-180Apr 20, 2012
Saudi Arabia-190Apr 21, 2012
Switzerland-197Apr 20, 2012


As I said at the outset this is a warts and all reality of indie development.  I have learnt a lot in this second week about how I could have done it differently for next time but not sure I can retrieve the situation without some investment in a marketing budget.  But that is for another week.
 
;