Codemon 3.0 – The Arcanes

It’s been a long time without updates on Codemon, finally, the wait is over.

Players asked for more Codemons and evolutions… well, players always ask for more creatures and evolutions in games like this.

There were a few limitations to give them what they were asking for.

In first place, the barcodes always generate the same result, by design. That makes impossible to make more creatures from scans.

Secondly, Codemons were already able to reach level 100 without any evolution, so that discards the easy way. In fact making the Codemons evolve will make it look more like a copy of Pokemon, and the idea is not to copy, but to just be inspired.

framed_new_home_screen_with_summon

We found a quire interesting solution: The Arcane Codemons.

Those were the original Codemons and they are extinct. That is why they can’t be scanned. Arcane Codemons need to be summoned.

To perform a summon, you need to use 2 Pure (a.k.a. having only one element) Codemons, they will be sacrificed and the Arcane will be summoned. Well, it is not that simple, there are several types of summoning and it depends on the Codemons involved.

framed_arcane_summon

This is a great mechanic, it puts more Codemons into the game, and it does it in something that “resembles” an evolution and at the same time does not break the existing game mechanics and is also different from other games.

The other big improvement of this version is cloud sync of accounts. That sounds easy, but it has been quite a nightmare. I needed to rewrite all the communication layer, the server side and the client cache… pretty much half of the game has been rewritten to make it work.

But all the coding and testing is done and it is available on Google Play, so grab it and play!

Speaking at GOTO Amsterdam 2013

GOTO Amsterdam is a conference designed for software developers, IT architects, agilists, product owners and project managers, it includes a total of 8 tracks with over 40 presentations.

As part of the mobile track I will be presenting “The Road to Publishing” on Wednesday (14:30-15:20).

This talk has received excellent feedback when I presented at DroidConNL, Appsterdam WWLL, AgileCyL and Delft University.

Abstract (as on GOTO website): “The process of building an App is slightly different from just Software Engineering, it is Product Engineering. In this talk I present several topics about Product Engineering that are relevant to anyone that is making or planning to make apps”.

Hope to see you there.

App Gold Rush: The gold is (almost) over

While the feeling of Gold Rush in the field of mobile apps and games still exist, my impression is that the gold has been mostly depleted for a while -at least for indie developers-. This post is the summary of the journey of MTG Tracker, and how it has performed over time.

Note: MTG stands for Magic the Gathering, a very popular collectable card game. MTG Tracker is a tool for players of this game, not a game on itself.

Not so long ago, in January 2012

Back then, the free version of MTG Tracker just won 3rd place on BestAppEver Awards 2011 and was by far the most popular mtg app on Android.  In a surprising twist of events,  WotC (the makers of the game) suspended the app via a copyright C&D letter. At that very moment it was over 220,000 downloads, averaging 400-500 downloads per day.

That attack on 3rd party mtg apps took down 3 other apps, leaving Android mtg players with crap apps and the paid version of MTG Tracker (why it was not targeted by the C&D letter is something I don’t know).

The side effect of that suspension was a significant increase on the downloads of the paid version, and also the growth of some apps that were not popular before.

Fast Forward to June 2012

As WotC seemed to not be targeting 3rd party apps anymore and they even removed their official app from Android and iOS App Stores, I decided to resume development of MTG Tracker, which was on maintenance mode since January.

The new features made the gap between my app and the rest even bigger.

The re-publishing: January 2013

With no news from WotC in 1 year, and 6 months since I resumed active development of MTG Tracker, I decided to publish the free version again, under a new package name (after removing all copyrighted material, of course).

The app is -as it was before- the best Android MTG app, since it has even more features than before and competition has not improved that much (one of the other apps has improved quite a lot, but still misses 2 key features)

The downside of using a new package is that it enters Google Play as a new app, starting with no downloads and no ratings. Only the name of the paid app to back it up.

One would expect that given the popularity of the old free version, the growth of the paid version and the lack of quality competition, this new release will quickly catch up with the pace of downloads it had before, specially given that there are much more Android smartphones out there.

Wrong.

Looking at the figures

It has been 4 months since the initial release and a few weeks since an important update. The paid app is still keeping the same pace, but the fee app has barely passed 10,000 downloads in this period of time.

That is less than 100 downloads a day.

That is 20% of the downloads it had before, per day.

That is why I say that the gold is over.

Wait! What? It doesn’t make sense

Disclaimer: I don’t have any hard data to back the conclusions, they are just my hypothesis after analyzing the figures.

I think there are 2 main problems.

The first problem is lack of discoverability. Right now, doing a search on Google Play returns all sorts of apps, and getting in the top 5 of a search by the keywords you are targeting is quite difficult. Why my app is behind other apps with the same relevant keywords, even thou MTG Tracker has more ratings, more downloads and better average ratings… and it is also newer. It puzzles me.

The other problem is user weariness. Let me explain it: All the early adopters were eager to install and try each and every app. That eagerness does not last forever, I am actually surprised it has lasted that long, and the new users are nowhere close in activity as the early adopters.

TL;DR;

MTG Tracker was suspended from Google Play on Jan 2012, being the leader on its niche. When an improved version was republished in Jan 2013, the traction it got was significantly lower. One year of difference and a better app results in less downloads.

Playing music with an intro and a loop in Android

I just added background music for Codemon. It consists on 2 tracks: On for the Codiseum and one for everything else. Each track consists of an intro and a loop.

The main track plays the intro only once and the one for the Codiseum restarts from the beginning each time you enter the battle arena.

It turns out, this is not as trivial as it should be, but I won’t spoil the fun.

Initial solution (almost good)

To play long music tracks on Android, we have the class MediaPlayer, and the easiest way to do an intro+loop is to use 2 MediaPlayers and play one after the other. We will create a utility class IntroAndLoopMusicPlayer to handle it for us.

Below is the code for creation, load and unload for the utility class, which has an intro player and a loop player as members. This class loads the music from the assets directory given the path of the 2 files.

public IntroAndLoopMusicPlayer(AssetManager assets,
   String introMusicPath, String loopMusicPath)
{
   mAssets = assets;
   mIntroMusicPath = introMusicPath;
   mLoopMusicPath = loopMusicPath;

   mIntroPlayer = new MediaPlayer();
   mLoopPlayer = new MediaPlayer();

   load();
}

private void load()
{
   mLoopHasStarted = false;
   AssetFileDescriptor afd;
   try {
      afd = mAssets.openFd(mIntroMusicPath);
      mIntroPlayer.setDataSource(afd.getFileDescriptor(),
         introfd.getStartOffset(),afd.getLength());
      mIntroPlayer.setLooping(false);
      mIntroPlayer.prepare();

      afd = mAssets.openFd(mLoopMusicPath);
      mLoopPlayer.setDataSource(afd.getFileDescriptor(),
         afd.getStartOffset(),afd.getLength());
      mLoopPlayer.setLooping(true);
      mLoopPlayer.prepare();

      mIntroPlayer.setOnCompletionListener(this);
   }
   catch (IOException e) {}
}

@Override
public void onCompletion(MediaPlayer mp) {
    mLoopPlayer.start();
    mLoopHasStarted = true;
}

public void unload() {
    mIntroPlayer.stop();
    mIntroPlayer.release();
    mLoopPlayer.stop();
    mLoopPlayer.release();
}

Simple enough, the intro player is not looped, and when it completes, the loop player starts, which is looped. Only missing part is to just call start on the intro player to get the music started.

Next step: Since we want 2 music tracks, we need to be able to pause and resume each one of them, so let’s add some code to handle this

public void pause() {
    if (mIntroPlayer.isPlaying()) {
        mIntroPlayer.pause();
    }
    if (mLoopPlayer.isPlaying()) {
        mLoopPlayer.pause();
    }
}

public void start() {
    if (!mLoopHasStarted) {
        mIntroPlayer.start();
    }
    else {
        mLoopPlayer.start();
    }
}

Note: It is important to check if the player is playing before calling pause. In case you try to pause the intro after it has finished, or the loop before it has started the MediaPlayer will yield an error and the music will stop. Yes, seriously.

As mentioned, we want to restore the tracks either to the beginning of the loop or to the beginning of the track, so we need 2 more methods

public void restoreLoop() {
    mLoopPlayer.seekTo(0);
}

public void restoreIntroAndLoop() {
    if (mLoopHasStarted) {
        mLoopPlayer.seekTo(0);
    }
    else {
        mIntroPlayer.seekTo(0);
    }
    mLoopHasStarted= false;
}

And finally, from the sound manager, we can pause or start the music. Whenever we start/resume one track we will restore the other its the initial point.

public void pauseBgMusic() {
    mMainPlayer.pause();
    mCodiseumPlayer.pause();
}

public void resumeBgMusic(BGMusic bgMusic) {
    if (bgMusic == BGMusic.Main) {
        mMainPlayer.start();
        mCodiseumPlayer.restoreIntroAndLoop();
    }
    else {
        mCodiseumPlayer.start();
        mMainPlayer.restoreLoop();
    }
}

Note: I call pauseBgMusic inside onPause of all activities and call resumeBgMusic on both onCreate and onResume. This is the seamless way of playing music among several activities I have found so far, including pausing the music when the game goes to the background.

So this all looks fine. What’s the problem then?

The problem: Forward compatibility

This solution works… until you try it on a phone with Jelly Bean on it. Then you will notice that the music stops for almost a second after the intro finishes and before the loop starts. Note that this does not happen on older versions such as Gingerbread. Yes, I was quite puzzled.

It turns out that JellyBean has introduced a new method to have a seamless continuation of playing: setNextMediaPlayer. Which, as a side effect, makes the previous method useless.

So, forward compatibility, here we go. We have to replace this:

      mIntroPlayer.setOnCompletionListener(this);

With this:

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
         mIntroPlayer.setNextMediaPlayer(mLoopPlayer);
      }
      mIntroPlayer.setOnCompletionListener(this);

And then, onCompletion has to be updated to look like this:

@Override
public void onCompletion(MediaPlayer mp) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
    {
        mLoopPlayer.start();
    }
    mLoopHasStarted = true;
}

We have yet another problem: When the loop player starts via setNextMediaPlayer, the intro player gets released automatically.

The solution is to reset and reload the intro player, but then another weird side effect happens: When you reset the intro player, the next media player gets reset as well.

The problem is that MediaPlayer is very hard to debug:

  • Documentation is extensive, but incomplete.
  • It just yields cryptic errors when you call an invalid method for the current state.
  • There is no way to get the current state.
  • Whenever there is an error, all music stops.

It took me a lot of trial an error to discover in which state the players were after each call. Once you know that, the fix is fairly straight forward: Reset and reload both of them.

public void restoreIntroAndLoop()  {
    if (mLoopHasStarted) {
        // For JB this also resets the next player...
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        {
            mIntroPlayer.reset();
            mLoopPlayer.reset();
            load();
        }
        else {
            mLoopPlayer.seekTo(0);
        }
    }
    else {
        mIntroPlayer.seekTo(0);
    }
    mLoopHasStarted= false;
}

I also tried using a single MediaPlayer that seeks to the beginning of the loop whenever it completes, but has the same ‘glitching’ problem as the original solution.

I hope you find this useful and that it saves you the headaches I had to go through.

Android and the future of gaming

We are living interesting times for gaming. Everything is changing very fast. Social games, Free-2-Play and mobile are relatively new topics but they are all growing like crazy.

The new generation of the established consoles look like more of the same. But there are  promising new gaming consoles, which are Android based. We have OUYA and GameStick as small projects that have been kickstarted, but also Project Shield from NVidia and the Gamepad from Archos. Special mention to the XPeria Play for opening the path.

I do believe that Android has a lot to say in the future of gaming. I want to highlight two aspects of it, each one with 2 sides.

Gamepads: Same old paradigm hinders innovation

This is something that worries me. When I started making games for phones I wanted to make use of their special capabilities. They have lots of sensors (the controls of SpaceCat), a touchscreen (Chalk Ball is not playable with a mouse), a camera (main element for Codemon) and that are just the ones I have already used in some game.

Smartphones have lots of possibilities for new game interaction mechanics, but if we make Android consoles and put them on the living room we are coming back to the same old paradigm and, to my personal taste, that is a step backwards.

Gamepads: Old paradigm is good

On the other hand, plenty of companies have been porting games designed to be played with a gamepad to Android with the result of horrendous on-screen pads. All those games are suddenly nice to play on this new Android consoles.

The paradigm of playing with a pad is deeply entwined with many game mechanics and designs. These games are even full genres and they are big and well known. The Android phones with pads are in fact solving a need that is already there.

Indie Studios: Lower entry barrier than ever

It is very cheap to get started on Android. The SDK is free, publishing a game requires no intermediates and the fee to publish on Google Play is merely symbolic. The entry barrier can not be lower.

This is great news for all the indie developers that want to try out something. Which is what I always loved of Android. No need of publishers or arrangements with distributors. Just you and the players.

Indie Studios: Difficult to succeed

Making money with games for Android is hard. Very hard. If Android becomes a mainstream gaming platform, the big studios are going to step in, making it even harder.

The platform lacks a proper discovery channel, and even thou there are millions of potential users, only a few are really interested on games.

Yes, there are companies that make shitloads of money, but there are very few. The success ratio is lower than in other areas and there is a situation when winner takes all, everyone will play the most well known games and forget about the rest.

But…

There is an important remark to do: The people that buy these devices are gamers, and they are buying an Android device to play games with.

This is a difference much bigger than what it looks like, because this public will consume more games, more often than your usual smartphone user (maybe not more than an average tablet user, but anyway)

There will be specialized channels, blogs, etc about games for Android and that may help new tittles to be discovered and maybe create a healthier ecosystem for indie companies.

Reaching 50K downloads

Things have changed quite a bit since I published my first Android App back in 2009. Let’s talk about a figure that is sort of a magic number (pun intended) for a free app: 50K downloads.

Why 50K downloads?

Google Play displays the amount of downloads in blocks: 1K+, 5K+, 10K+, 50k+ and so on. Sometimes you need to double the number of downloads to move up and sometimes you need five times the amount. This makes 50K downloads an official milestone on Google Play and one of the “hard” ones.

Also, this number has some interesting properties.

First let’s see a niche app: MTG Tracker.

I observed that after reaching 50K downloads, the grow accelerated. While I am sure this has multiple causes, I believe one is that it reached some critical mass and word of mouth started to make an impact. It was sort of an inflection point.

When we talk about games, the story is quite the opposite.

At The Pill Tree, we observed that 50K downloads was sort of an upper limit. Each of our games quickly grew to 40K+ downloads, but after that, reaching 50K seemed more and more difficult. It looked like an asymptote.

It took Chalk Ball 2 months to get there. For SpaceCat it was 5 months. Both games had a remarkable amount of reviews in specialized blog that helped them to get to that point. But both were stuck at 50K until they were featured.

During the time SpaceCat was featured, it had 50K downloads per day. Same number again. This was February 2012, when the estimated amount of Android phones was “only” 300M.

What about now?

During 2012, It has taken Codemon 8 moths to get to 25K downloads, even with a fair amount of reviews on its bag (not as many as the other games, but still quite a few).

I’d like to highlight that the game Barcode Beasties (very similar to Codemon) has over 100K downloads, being IMHO unfinished and less polished (but it was launched a long while ago, more on that later).

This does not make sense

There are much more Android phones out there, so getting downloads should be easier, not harder,  right?

android_device_gowth

Disclaimer: This is just my hypothesis that tries to explain this situation.

There are more users, yes, but the mayority are not power users. The amount of people that continuously checks Android news and is looking for new games and apps has barely grown. These guys are mostly early adopters and that phase is long gone.

But the amount of users is growing, so, even slightly, the amount of power users should grow. Where are they?

Well, it becomes more clear if we look at how much competition we have.

google_play_apps

I consider myself a power user and an early adopter, and this is what happens for me:

  1. I am flooded with new good apps coming out every week I barely have time to run them even once, and the same is true for games. I just can’t keep up.
  2. I have most of my needs covered already. That means I have over 70 apps / games installed that I like and use every now and then. It feels like I don’t need more.

A while ago, I tried almost every game that looked interesting. As of today, I have around 10 apps in my wishlist waiting for a chance, for months.

So, I think power users are either satisfied, overwhelmed or no longer so excited.

Apps used to get more exposure given the bigger percentage of power users and mainly, less competition, but even then, it was not that great.

Is all dark and gloom?

If the amount of users grow, but is harder to get to them, what’s the point?

While this is discouraging, there are 2 main benefits from this situation:

  1. If you get to be featured / popular the growth is spectacular. SpaceCat was having 50K downloads a day, and that was one year ago. Nowadays is must be even bigger.
  2. There are more specialized users and that means the niches are bigger in size. I have observed how the growth of my niche apps (MTG Tracker, KendamApp & JuggleDroid) almost matches the grow of number of Android phones, just on a different scale.

TL;DR;

Over the past years, the amount of Android users has grown (over 500M now), and so has the amount and quality of apps and games being released daily (over 750K apps listed).

The number of apps that a user can check per day is limited, and it is independent of the amount of users, it just depend on the number of apps.

Getting the same amount of downloads for your app is harder than before, but if you are lucky, the difference is astonishing.

Maybe it is time for all of us to start spending more money and/or time on marketing, focus more on niche apps (even niche games)

2012 Year Review

2012 has been a very intense year. It has been first I have worked completely on my own, so I wanted to have a review of the most interesting parts of it. One per month.

January: Mtg Tracker wins 3rd place on Best App Ever – Reference. Few days later the free version gets suspended by Google upon a copyright infringement letter from WotC.

February: SpaceCat gets featured by Google Play, downloads go sky rocket and the server melts down during the first weekend.

March: I organize a Guru Session on Appsterdam about “Tools for developing android games” that is a great success in attendance and fun.

April: Codemon is launched on Google Play!

May: I start working part-time with Fashiolista to build their Android App.

June: Working on 3 projects: Fashiolista, Codemon and AppAffinity. Learning how to minimize context switching impact. Quite happy with the result.

July: Together with LoopBit, we launch AppAffinity, our take to solve the app visibility problem.

August: KendamApp is updated with the ability to track your progress and know how close you are to a certain grade. Then I traveled to the European Kendama Open, where I get pre-dan.

September: I participate on the V hack Android hackathon with Ronald and Ron. Winning the second prize with “Appy Birthday”

October: I speak at BubbleConf with a lightning talk about “Piracy on Apps”.

November: For the second year in a row, I speak at DroidCon.NL, this time in the main stage.

December: Codemon goes into the last big update adding facebook integration, with the idea in mind to give room for new projects next year.

Why Google Play sucks at discovery and how to do it better

The Visibility problem

App Visibility has been a big concern for a long time, and it is not going away. If anything, it is getting worse.

A few weeks ago, Google announced 3 new Nexus devices which are going to bring lots of new potential customers for App Makers.

Also that same week, Google announced that the Play Store reached 700,000 apps. That is quite a huge number of apps for people to discover, and for developers to compete against for visibility.

Why does Google Play suck at discovery?

Google Play has an issue with discovery; even search is not good. They have been trying to fix it, but with little success. Let’s go over their attempts.

A year ago they introduced a lot of new lists (Top Paid, Top Free, Top Grossing, Top New Paid, Top New Free and Trending) which almost nobody browses because there are too many of them, making them irrelevant.

The best discovery tool on Google Play is the feature area, and it is a great one. Unfortunately it only highlights 4-6 new apps a week. That is clearly not enough, not to mention that it is impossible to apply for it and the selection criteria is vague, to say the least.

Lately Google Play introduced the “Recommended for you” feature, and I was hopeful, but it does not actually work. I believe Google doesn’t care about this.

Why do Google Play Recommendations suck?

Let me show you a screenshot I took a couple of weeks ago to illustrate some flaws:

Google Play is recommending Codemon (Barcode Monsters) to me. This is thrice wrong because:

  • The game is published under the same account that is configured on the phone. Well, this one is tricky, so I can forgive that.
  • The game is already installed in this device. Ok, this is awkward.
  • It recommends it to me because “You, txema olmo and 3 other people +1’d this”. Aha! Since I’ve +1’d it I may like it. This is great.

To be honest, I have not seen this happening lately, so they may have fixed some of the cases, but this is just the tip of the iceberg of how terrible their recommendations are.

They mix “Top applications” with “Popular in my area” with “+1’d for my friends” with “Popular with similar users”. All in all, it is a mess and it does not feel personal at all. Does it for you?

I usually don’t care of what is popular in my area; I already know the top applications and what my friends +1’d. I usually got all that by word of mouth. “Popular with similar users” is close to good, but there are so few of these recommendations.

Maybe it is a hard problem and can’t be done better; they are Google after all.

Well, it CAN be done better and it has been done.

How to do it better?

Personal recommendations are the key to solve this problem, but they need to be implemented properly.

AppAffinity is a project done by a team of 2 guys: One back-end guy and one front-end guy. There are other teams trying to solve this problem, but hey, this is our project.

It is as simple as using the information of the apps you have installed to recommend new apps for you.

Not “Popular in you area”, not “+1’d by your friends”, not “Top Applications”. Just Apps linked to your interests.

Obviously, an app you have already installed will not appear in the list, neither will an app you have uninstalled.

About the presentation: It is not 7 lists where you get lost browsing. One single list (which you can filter by Paid, Free or All)

The effort on AppAffinity is to provide the best recommendations as easily and simply as possible, and by looking at the comments on the Play Store, we may be close to our goal. Definitely closer than Google.

Speaking at DroidConNL

For the second year in a row I’ll be speaking at DroidConNL.

DroidConNL is the best conference for Android Developers in the Netherlands. 2 days packed with interesting topics. Past year was a blast, and I expect it to be even better this year.

I’ll be presenting an updated version of “The Road to Publishing” which I presented earlier this year at Appsterdam lunchtime lectures, among other few places, including one in Spanish for AgyleCyL (online, of course).

You can check out the slides, but I encourage you NOT to do it, since they are mainly images that will help you recall the concepts, so they are interesting after the talk, but not before, anyway, they are already online here.

Hope to see you there!

Talk summary (as on DroidCon website)

The process of building an App is slightly different from just Software Engineering, it is Product Engineering. In this talk Raul presents several topics about Product Engineering that are relevant to anyone that is making or planning to make apps.

The points presented in his talk are the result of his work in many apps and games in a variety of teams and situations, from Solo Developer to Team Leader. From how and why make prototypes to what it means to be agile, the talk covers many points of the life of an app before it gets published (and a few from after it is).

AppAffinity goes out of Beta!

It has been a while since we released AppAffinity. It has been out in the wild for a few months and without any effort on advertising from our side it has grown over 1,000 users. Quite a success.

For the past week, I got LoopBit involved again on a new iteration, tweaking the UI using the suggestions we received and solving the bugs user reported. Now we believe AppAffinity is ready to go and we have removed the beta tag.

Now it is called just AppAffinity.

What’s new?

People asked to see the details of ratings of every app. Many were upset that apps without the banner had more information. We did not want to add clutter to the banner because the designers put a lot of effort on them looking nice, so we added a detail view you can get swiping to the left

We also added a few animations, which you will notice as soon as you open AppAffinity.

The ability to filter the installed and blocked apps was also requested, and it we included it as well.

And I won’t bother you with the other performance improvements and minor bug fixing.

Sincerely, the AppAffinity team.