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.
Saturday, 28 April 2012 0 comments

Testing Testing Testing

After months of pain, suffering, late nights and refactoring you think you have finished your game. You have lived and breathed it and you want to see some return for your efforts. Up on app store or Google play it goes ... STOP!

As much as you, your girlfriend, wife, cat, gerbil etc have tested nothing beats fellow developers critiquing and testing your pride and joy. The challenge is crowd sourcing enough to get quality testers and thankfully for me my twitter followers and Ansca Mobile gave a great insight.

The benefit from getting testers from within the community is that they understand games, can spot things that normal people don't, know how to provide crash reports when the inevitable happens, as well as offer constructive criticism.

Astavoid was never developed to be the next best thing. It was developed to help me understand game development, understand the Corona SDK, understand the differences between iOS and Android platforms.

As well as finding bugs that I didn't find I went through a total of 9 iterations of testing with a team of 12 volunteers. I had a couple of very loyal testers as well as some great industry feedback from Matt Rix (Trainyard fame) and Keith Shepherd (Temple Run fame) to comment on the mechanics.

I learnt from these guys to look at similar mechanics of how the game works and apply it to those that are successful. An example of this is the change depth logic I had when entering beta was three depths that were controlled by double tap to move forward and one tap back. This to me was unique but as was pointed out to me could be cumbersome and not initiative. I was pointed to games like Jetpack Joyride as a hold and release mechanic that suited my game much better. As a result through this iteration process the game mechanics were refined and tested and I think a better more robust game has come out of it.

For iOS testing I used the excellent TestFlight to engage and manage my testers. I can't underestimate just how excellent this tool is and how it takes the hassle out of the process. Unfortunately at this time of writing the Testflight SDK isn't incorporated into Corona SDK to get the full benefit of realtime analytics and crash reports but was a huge problem to me given the people I had testing. Here is a short explaination of Testflight


What is TestFlight?
TestFlight is a free Over-The-Air platform used to distribute beta and internal iOS applications to team members. Developers can then manage testing and receive feedback from their team with TestFlight's Dashboard.


Wait! It's free?
Yes, TestFlight is free. The current features and SDK are part of the core functionality and will remain free to use. Our plan is to introduce paid features in the future that will be clearly labeled. Users will have the option to add these features or continue to use the service free of charge.


What apps does it support?
Currently we're only supporting iOS apps. TestFlight follows Apple's beta and internal distribution guidelines, so we primarily support Ad Hoc and Enterprise provisioned applications.

When will you support other platforms?
We will announce any official changes of the service before going live. We haven't made any announcements and currently we're only supporting iOS apps.

For Android its a slightly different story. I did look at thebetafamily but the depth of testers wasn't the same. The reason being is Android isn't anywhere near as strict over distribution as Apple so it just as easy to distribute via your own website. And this is what I did simply compiled by APK file for the various versions (Android, Nook and Amazon Fire) and fed back via my support email.

I guess the point of this post is to raise awareness of Testflight if you don't know about it, I didn't, and to really make sure you test as every 5 star rating is worth its weight in gold and not putting that cherry on the cake can be so damaging.
Tuesday, 24 April 2012 0 comments

Memory Optimisation and Refactoring

I can't find the person to attribute this to now but never a truer word was said when it was mentioned it took 4 hours to create the concept and then 4 months refining and finishing it. This is pretty much what happened to me with Astavoid. In December 2011 over the Christmas period I had pretty much got to grips with Corona SDK and its ease of creating Physics objects. However, from a reasonably simple concept the refactoring and attention to detail required was made more apparent the further I refined the concept. Before I go on further I wanted to point you all out to an excellent helper chart I found on the ansca forum around collision filters. This really helped me with optimising my physics objects but in the first instance actually explained to me how to make my whole game logic work. I would highly recommend you follow this link without delay, go now.

Told you it was good. So now you have bookmarked that page, printed off a few helper charts and worked out your physic logic you want to make sure when testing it not only works on the device in your hand but others who will inevitably download. I will talk about testing in my next post but what it really showed to me is just how important it is to not be lazy with your coding. I wouldn't say I was being lazy in the first instance but more a lack of understanding and this really came back to bite me. On newer devices such as the iPhone 4s (which I happen to have) it covers up all kind of sins and for that matter the Corona simulator isn't that reliable. So when testing on iPhone 3GS, for example, all kind of weird and wonderful things happen that I personally couldn't replicate.

I wouldn't be exaggerating if I said I rewrote the code of Astavoid a dozen times. This became hugely time consuming and while the concept of the game and most of the screens were finished I probably spent a very long two months on optimisation and performance issues. I would highly recommend you start by having a read of the performance and optimization tips described in this article. This got rid of some of the basic errors I was making.

In addition, to this was the concept of memory leaks and where to find them, again this article was incredibly helpful. Half the challenge of course is in finding the memory leaks and performance spikes. I didn't really get on with compiling out to Xcode simulator and using instruments as I found it too cumbersome. Instead I use a few community scripts and tools. The ones I would recommend are:


These tools were very helpful in at least identifying issues. The following links were things to try to eradicate them:

These are really useful resources that at least made me understand the importance of tidying up after yourself and not relying on the more up to date devices to do this for you. This was no more prevalent to my development than truly understand the memory utilisation and management of the storyboard api. I would strongly recommend you read the introductory explanation on the subject which cleared things up for me.

Finally, the biggest stabilisation effort I got was from dropping my FPS (frames per second) from 60 down to 30. I had originally drawn 250 animations for the rocket but found that on the older devices the extra texture memory used up and the amount of computations needed was making it struggle. So I dropped the frame rate, minimised my spritesheets and followed the optimisation techniques described and I found I had a smooth action game, that worked across multi device and operating systems.

 Hope this helps.

Astavoid is available on Google Play and iTunes
Saturday, 14 April 2012 0 comments

Sprites and Animation

Creating great animations and sprites within your games is important to make your game stand out amongst 100,000s of apps. The challenge with being an indie developer is you have to be a master of a lot of skills and typically your skills fall into either designer / arty or coder.

I did't have the time to create a load of keyframe animations from scratch but I knew I wanted to have the rocket within Astavoid banking front and back. The way I went about this was to use one of my kids toys and skewer it so I had a steady x axis and then film myself doing the transitions that I was looking for.



Once I had the video in place I had a number of options open to me to extract the relevant frames. This could have cost me some money such as QuickPlayer Pro or similar but I decided to use the more manual command+shift+4+spacebar on Mac Lion to capture the selections I wanted. This was a little laborious but certainly far quicker than drawing from scratch.

Next I imported my keyframes (of the movie) into Flash CS3 and simply traced over the top of them. This was a pretty quick exercise and had all 250 keyframes done within a day. I later reduced the number of keyframes to 60 which I will discuss below as well as in memory optimisation post to follow.

Again, at this stage once you have your frames you have choices. As I had done my work within Flash exclusively I could have used the excellent SpriteLoq to aid the scaling and texture pack I have ended up with but at the time I wanted to use something more universal to learn techniques that weren't exclusive to Flash.

What I chose was to export my now traced images and apply relevant scaling using Preview for Mac Lion (again free) and then importing my images into TexturePacker. As I said in my previous post (http://mygamingproject.blogspot.co.uk/2012/01/physic-and-texture-editors.html) TexturePacker is an excellent tool and very quick to work with. What I will note here is and to save you a few months of redoing your work is that Corona SDK has significantly changed with its sprite and image optimisation and as such I downloaded (at time of writing) the beta version (TexturePacker-3.0.0b3.dmg (MacOS X 10.6/10.7 – 32/64bit)) to make use of the changes.




In Corona SDK daily build 2012.759 significant changes were made to help with the challenges around the infamous texture memory on older devices. While the use of sprite sheets has been simplified for all the benefits come for older devices (iPhone 3GS) in handling more sophisticated sequences. As I put in my post the other day the daily builds are a blessing and a curse as I probably spent about 3 weeks optimising performance but still struggled on older devices, this was a change I was prepared to make.

I won't repeat what is already an excellent blog post by Jonathan Beebe (http://blog.anscamobile.com/2012/03/image-sheets-image-groups-and-sprites/) but the bit I was most concerned with was was optimising my sprite sequence but using an interim technique while third party tools caught up with the 2012.759 changes. At time of writing SpriteLoq is the only one making full benefit of this.

So in order to use TexturePacker and the new Sprite Api I do something like this:

display.setStatusBar( display.HiddenStatusBar )
-- Enable physics so that we can determine collisions
local physics = require ("physics")
physics.start()
-- Normally the gravity to simulate earth is around 9.8 but we don't
-- want a gravitorial effect in this game just the benefit of collision detection
physics.setGravity(0,0)
--physics.setDrawMode( "hybrid" ) 

physicsData = (require "astavoidPhysics").physicsData(1.0)

local oldStyleSpriteSheetData = require("rocket").getSpriteSheetData()
rocketPosition = "middle"

local options = { spriteSheetFrames = oldStyleSpriteSheetData.frames }
local imageSheet = graphics.newImageSheet( "rocket.png", options )

local sequenceData = {
    { name="back", start=1, count=32, time=750, loopCount=1 },
    { name="forward", start=33, count=32, time=750, loopCount=1 }
}

local gameRocket = display.newSprite( imageSheet, sequenceData )
gameRocket.x = 200
gameRocket.y = 200
physics.addBody(gameRocket, physicsData:get("middle"))

-- The use has clicked on the screen 
function screenTouched (event)

    if event.phase == "began" then
     if not(rocketPosition == "background") then
      local currentFrame = gameRocket.frame
      gameRocket:setSequence( "back" )
      if(currentFrame > 1) then
    currentFrame = 32 - currentFrame 
    gameRocket:setFrame(currentFrame)
   end
   gameRocket:play()
   rocketPosition = "background"
   physics.removeBody(gameRocket)
   physics.addBody(gameRocket, physicsData:get("back"))
  end 
 elseif event.phase == "ended" then 

  if not(rocketPosition == "middle") then
   local currentFrame = gameRocket.frame
   gameRocket:setSequence( "forward" )
   
   if(currentFrame < 32) then 
    currentFrame = 32 - currentFrame
    gameRocket:setFrame(currentFrame)
   end
   gameRocket:play()
   rocketPosition = "middle"
   physics.removeBody(gameRocket)
   physics.addBody(gameRocket, physicsData:get("middle"))
  end
 end 
  
 return true
end

Runtime:addEventListener( "touch", screenTouched )

Pretty simply huh!!!

There are always different or better ways of doing these things but pretty happy having worked this out with minimal cost and what has turned out to be a reasonably professional effect.

Let me know your thoughts or techniques if you are happy to share.
Thursday, 12 April 2012 0 comments

From clueless to novice

Been a while since I have blogged but that is because I have spent so much time with my head in code, books, forums etc to fully embrace the project and to ensure I embrace inde game development.

The intention is for me to dump my brain of all that I have learnt now I have notched up over 400 hours in game development and very close to my first game being released. The blog was meant as a bit of a diary of my progress but also to help others who want to go on a similar journey. I have been so grateful to the indie development community in getting advice, constructive criticism and invaluable testing resource that hopefully this will help.

Let me roll back a few months....

Having started this journey back in October I tried to go about it in a constructive manner. I know, unless I am very fortunate, that I'm not going to write the next Angry Birds or Temple Run but that doesn't put me off just different tactics. Choosing Corona SDK was always part of the tactics and ultimately why I chose this over Cocoa2D as I wanted to write little games that got the maximum exposure particularly with emerging devices and markets like Amazon Fire and Nook.

I had been keeping a little book of ideas for the best part of a year. A useful tip as I always found I had new ideas or developed on others but totally forgot by the time I got round to do anything about it. Its fair to say I got a little carried away in the first 6 to 8 weeks. While I was learning I wasn't really moving in a direction. From my blog you will probably have seen that I spent the first 4 weeks reading up on game design. This was a useful exercise in things to consider but I didn't really have a developed idea to immediately apply it to. I also was very keen to start programming ...

Corona SDK is based on LUA, one of the few programming languages I haven't programmed in. I will digress a little here to give a bit of background about me as it has context going forward. I have a degree in Business and Marketing but not really applied it like most people's degrees. I also have A-Levels (UK qualification) of which one is in Art, so I definitely have a creative streak. This is why I got into programming as I am a problem solver that wanted a medium to tangibly solve the problem, hence I decided to become a computer programmer. All in I have probably spent close to 15 years programming mainly around Microsoft technologies and qualified as a Solution Architect but my first love was always wanting to be a games programmer. Over the last 5 to 10 years I have moved further and further up the corporate ladder and away from my first love of programming, this was why this project was born. I have managed teams on and off shore, delivered projects for brands you have all heard of, but very few of late has been my code. This had to change...

So with my little black book in hand (no girls names in this one!) I set about a few of my ideas as prototypes. I got some initial rewarding results and was amazed with the Corona SDK engine just how much could be achieved with so little code. However, after about 3 weeks of developing an idea I soon realised I couldn't do it justice. I felt I had lost and wasted a lot of time on the project but took a step back and realised this was part of the rich tapestry of learning from ones mistakes. This was around mid december when I came up with the tactic to learn as much as possible with the simplest idea. I felt if I kept the component parts as simple as possible then I could redo parts if not all if I suddenly came to a dead end which I hadn't considered. This is why animations etc that I have created have no moving parts as when it comes to scaling images / sprites etc I would have no idea how this would work.

This was where Astavoid was born in mid December. A simple scrolling space game (yes another one!) that has stars as a background and a space rocket should be easy to implement and maintain with the concept of avoiding asteroids.

The rest of the series of blogs around Astavoid will focus on specifics such as game design, sprites and animation, memory management, testing and marketing amongst other things but before I go I will share with you the tools and money spent in getting me to this point.

These aren't things I indulged with on day one but things I have found and are useful as I have progressed. All prices are in sterling (GBP) as I live in the UK and wanted to bring it back to a common denomination. Im sure you can do the relevant exchange rate:

Corona SDK (http://www.anscamobile.com/) 218.58
I started off with the trial version but found the official released version is someway behind the daily build functionality. So putting up a query on the excellent community forum would often be met with "this has been resolved in X daily build". So I bit the bullet and bought the iOS licence and made use of the daily builds. To be honest these are a blessing and a curse, the bad thing being is they feel like a line in the sand that is constantly moving. Just when I thought I had finished the game and inevitably done some workarounds the "right" way was released or bugs resolved which put me back a day or a week. When I got closer to a finished game I upgraded to the pro developer licence to include Android, Amazon Fire and Nook.

Gimp (http://www.gimp.org/) - Free
Used to touch up my graphics. I use Inkscape and Preview (Mac) for some vector work or scaling.

Adobe Flash CS3 - Free
Don't know why but I had an old copy of Flash CS3 knocking around which I used for drawing the rocket and asteroids. Since then though (as Flash can be pricey) I found Pencil (http://www.pencil-animation.org/) or ArtPigEditor (http://www.artpigsoft.com/)

Image Optim (http://imageoptim.com/) - Free
This is by far the best tool I use. Really simple but compacts your PNG files by loads. Reduced my app size by 60%!!

TexturePacker / Physics Editor (http://www.texturepacker.com/) - Free to bloggers
Lots of things out there to do texture packing and physics editing (Zwoptex or SpriteLoq as alternatives) but found the ease of use and support excellent at Code n Web. Much to my surprise I got it free as Andreas liked my blog :)

Sublime Text 2 (http://www.sublimetext.com/2) 36.95
The lack of IDE was my biggest frustration with Corona SDK and is to date. The recent release of Corona Cider may be a saving grace with the Visual Debugger but up to now I have used the excellent Sublime Text 2 editor and Corona's console debugger to do my development. I used the NotePad2 autocomplete plugin with this to help. Really like the tool would highly recommend.

Screenflick (http://www.araelium.com/screenflick) - 18.16
Used to create my first sneak peak of Astavoid. Much to learn but seems to come highly recommended.

Audio Micro (http://www.audiomicro.com/) 43.67
Despite the skills I mentioned earlier I possess very little musical ability and while I can play the guitar a little this is not something I would want to soil my games with. Luckily an excellent resource in Audio Micro provides sound effects and music alike at very afforable amounts, royalty free and professional.

Corona Profile (http://www.mydevelopersgames.com/site/) 5.87
I won't go into this too much now as I will write a whole separate blog entry on the subject of my hell with memory management and optimisation but needless to say this tool was invaluable.

Particle Candy (http://www.x-pressive.com/ParticleCandy_Corona/index.html) 34.57
To add a little polish to my game and a slightly more professional feel the rocket's trailing smoke and explosions were created with Particle Candy. Probably something I could have animated or created but at this time there was far more things to cover off.

Right thats enough for now. Next in the series sprites and image optimisation.
 
;