Ismail Coskuner

Ismail's Personal Web Turf

Author: Ismail Coskuner

Flappy Bird – A Genius Exit Strategy

Nowadays everybody is talking about one huge success, and what happened to it afterwards. I am talking about Flappy Bird of course. There is a debate about its success, some people think that it is just luck where other people think that it is an act of a genius. Lots of people can not understand how can such a simple game become the #1 in Google Play and App Store, yet they still continue to play it. While these were happening, the developer “Nguyen Ha Dong”, decided to take the game down claiming that it is ruining his simple life. And of course everybody was shocked, considering that he was making around 50000$ per day just from ad revenues. He should be insane right? Why do you do that when you have such a great success? Well in my opinion, what he does is the best -an maybe the only right- thing to do, and he is a genius. Let me explain myself.

Keys for Flappy Birds Success

To explain why this outcome makes a lot of sense, we should start from the beginning. Flappy Bird was yet another application for a long time, but something happened on November 2013. There are two very important components of the growth that we see in the chart below.

flappy-bird-ranking

Flappy Bird Ranking History

First of all, you should start from somewhere, which means paid marketing/charting. There are many ways to do that, some services are perfectly legal, well-known and acceptable, where some services are shady and maybe a little illegal. A lot of people mention that most of the reviews look like they are generated by bots and even negative reviews have 5-star rating. It may be true, and I don’t actually see any problem with that, start-ups just do this kind of tricks to take off all the time. But this is not the component I want to focus, since the other component is probably more important.

The second component is virality. If we didn’t know already that people are going crazy for this game, we could tell that from the chart as well. If there was a linear growth, you would expect a logarithmic-like curve here, because it is ranking, and you are competing against other apps. But as you can see the angle is so steep all the time, which means there is an exponential-like growth, some kind of snowball effect. And since Nguyen was a one man show and probably didn’t have a big marketing budget, I think it is enough to prove the virality of the app. In my opinion, this is the real source of Flappy Birds success. Now I will list the elements that I find crucial for virality, keep these in mind because I will use them to make my point about Nguyen’s decision of taking the app down.

  • Simplicity: The game is so simple that there is almost no overhead for people to start playing. No tutorials no additional elements no nothing.
  • Hardness: It is a hard game which helps to keep your top score low and gameplay short. So everytime you are shooting for ’10 points’ instead of ‘20000000 points’.
  • Short Gameplay: You know how you want to play just one more time in every game right? Well it takes just 15 seconds in Flappy Bird, so why not? And you can play it pretty much anytime, anywhere.
  • Challenge: Somebody made just 10 points, looks like an easy challenge right?
  • Familiar Elements: Ask your subconscious, and it will tell you how it remembers the good old Mario days.

These elements are all very and almost equally important. You don’t want to break any of them, and in the next section I will show you how impossible it is to sustain the app without breaking at least one of these elements.

Why This Kind of Exit?

We made our assessment about the application and now we are ready to move on to the conclusion. We listed the success factors in the previous section, but there are two serious problems with this elements.

The first one is high churn rate and short lifetime. Since the game is so simple, it is very easy to go viral. But at the same time, it is very easy to lose bored users. This is caused by simplicity, hardness and short gameplay elements.

Another problem is possible copyright infringement. People already started accusing the developer with using the assets and game mechanics from other games. In business world when you get bigger and more noticeable, you will have more rivals that are waiting for your mistakes. Definitely it is not a good thing to have such a weak point. And this is the drawback of familiar elements.

So let’s list the exit strategies already, and see why the one Nguyen has chosen makes perfect sense.

1 – Selling the app

It was the first thing that comes to mind, why not selling the app instead of shutting it down? First of all, it is very hard to find a buyer when you have copyright issues. And even if there is such a company, the money that you will get for such a simple application will not be financially the best option. It may be making 50000$/day now, but companies are very well aware of concepts like lifetime value and churn rate.

2 – Maintaining it

First things first, with all these copyright claims, there would be sleepless nights. Moreover, we already talked about how the churn is high, and lifetime is short, and this popularity is not easy to get. The game is not open to iterations, add one thing and you will lose one of your core features: simplicity. On the other hand if you don’t give new features to your players, they will get bored eventually and abandon you. Hard decision indeed, so you can not expect things to stay the same for a long time.

3 – And taking it down

This is our winner. But why is it the best option?

  • No app, no lawsuits.
  • Do something crazy when you are on top, and ride the PR wave. He made the advertising of the history for free, made everybody download the app in one night. If you can get all your customers in one night, why wait?
  • Still getting ad revenue, and maybe 3-4X of what he was getting before.
  • Now one can not easily uninstall the app, because you can not find it anymore. Better keep it on the phone, and increase your lifetime right?

Considering all these, you can expect that he will make around maybe 6M$ in 2 months, and he will simply walk away with that, no strings attached. Isn’t it sweet?

That concludes my late post about Flappy Bird. I promise I will get better with my timing. I hope I helped you see Nguyen is not a crazy or a poor guy, but a rather smart entrepreneur. Flappy days everyone!

Javascript closures in loops

Well, even though I can write Javascript fluently, I am not anywhere close to being a Javascript guru. Working mostly on the backend side of the things makes me go back to square -not 1 but maybe 4 or 5- when it is time to write JS again. Today I faced with one of the most common pitfalls about closures in JS. Where closures are magnificent little things that ease asynchronous calls for you, not understanding them fully may result with a bit of pain as well. In short, I must say, closure and loops don’t mix well. And here is why:

Problem

Okay, let’s have a look at this following simple piece of code:

var companions = ['Rose', 'Martha', 'Donna', 'Amy', 'Rory', 'Clara'];

for (var i=0; i<companions.length; i++) {
  window.setTimeout(function(){
    console.log(companions[i]+' is the best!');
  }, 1000);
}

At first glance, you expect that it should claim all the companions are the best right? If things were that way, none of us would be here. Let’s check what we got in our console:

undefined is the best!
undefined is the best!
undefined is the best!
undefined is the best!
undefined is the best!
undefined is the best!

That is interesting enough I hope. I should mention that I think all companions are the best in their own ways. So let’s fix this thing, shall we?

Background

Before dashing into solving our problem, let me give you some background about what is going on here. It’s better to start with the base and build it on top of it.

A scope means the environment of a function, basically everything that it can reach and use.
Lexical scoping (a.k.a. static scoping) is a type of scoping which allows a function to use the environment variables where it is defined.
A closure happens when a function uses a variable out of its immediate lexical scope.

JS uses function level lexical scoping, and what we did in the example above is a closure. Our anonymous function is using ‘companions’ and ‘i’ variables, which are both out of its immediate lexical scope.

Solution

The root of the problem is basically not being careful with closures. What really happens is, before our unsynchronous setTimeouts are being executed, the value of variable i changes. To make it easier to see, I will unfold the for statement with something almost equivalent:

var companions = ['Rose', 'Martha', 'Donna', 'Amy', 'Rory', 'Clara'];
var i = 0
var f0 = function() { console.log(companions[i]+' is the best!'); };
i = i+1 // (i=1)
var f1 = function() { console.log(companions[i]+' is the best!'); };
i = i+1 // (i=2)
var f2 = function() { console.log(companions[i]+' is the best!'); };
i = i+1 // (i=3)
var f3 = function() { console.log(companions[i]+' is the best!'); };
i = i+1 // (i=4)
var f4 = function() { console.log(companions[i]+' is the best!'); };
i = i+1 // (i=5)
var f5 = function() { console.log(companions[i]+' is the best!'); };
i = i+1 // (i=6)

f0();
f1();
f2();
f3();
f4();
f5();

During unfolding, I gave a name to all our anonymous functions, so they are not anonymous functions anymore. As you can see, their definitions are the same, and because of the lexical scoping, they all have access to the variables in global scope. That being said, we are interested in the values of variables in the lexical scope not at the time of defining the functions but running them. So notice the value of i before the function calls. It is 6, which is out of  array. No wonder why it is printing ‘undefined’.

Time to fix it. Here I will give the fixed code first, then explain it:

var companions = ['Rose', 'Martha', 'Donna', 'Amy', 'Rory', 'Clara'];

for (var i=0; i<companions.length; i++) {
  window.setTimeout(function(i){
    console.log(companions[i]+' is the best!');
  }(i), 1000);
}

And check the output:

Rose is the best!
Martha is the best!
Donna is the best!
Amy is the best!
Rory is the best!
Clara is the best!

Yey, looks like we did it! But how did that happen? Instead of using the variable i in global scope, we injected that variable to each functions immediate scope by passing it as a parameter. Since there is a variable i in the immediate scope, the functions does not search outer scopes anymore (called variable shadowing). If you are not familiar with shadowing, it is also possible to do it without shadowing the i variable. You just use a different name for the parameter like:

var companions = ['Rose', 'Martha', 'Donna', 'Amy', 'Rory', 'Clara'];

for (var i=0;i<companions.length;i++) {
  window.setTimeout(function(index){
    console.log(companions[index]+' is the best!');
  }(i), 1000);
}

Before I end the post, I should give a disclaimer. Here this method worked because i is a variable of a primitive type. Primitive types are being copied during function calls where complex types are passed as a reference. If for some reason you need to do this kind of thing with a complex type, you need to find a workaround, like copying it yourself.

Bug-free coding everyone!

New Website & New Blog!

Here I go, taking the first serious step with my online presence. I was always complaining about not having a website and a blog, and probably this is simply how everyone feels at some point in their lives. I noticed that until now, I always consumed whatever is on the internet and didn’t pay back. I read all the blogs and used all open source code that I need, this is my best attempt to make it worth. We’ll see how it will go.

Until now, all blogging stuff seemed so scary and intimidating. I just felt like everybody will see my posts from day one, and follow me, and find my mistakes, and make fun of my mistakes etc. Then there is this idea of not being accomplished enough to maintain a blog, especially when you see other awesome people and blogs. But in reality, everybody has something to teach. Any piece of information that one see very trivial may enlighten some other persons path. This is one of the two reasons why I am writing all of these here, in case somebody else is having same problems with me and reads this post: Just do it! The other usage is for me to read it if I have any doubts in the future.

So what am I planning to write about? I like learning new things, so I thought I can just take notes while I am learning them. The idea is keeping this blog as a collection of:

  • Summarized information about computer science out of all learning materials that I used
  • All gotchas and pitfalls I had while I’m coding
  • All open source projects that I will start/contribute
  • Business and entrepreneurship related posts
  • Personal posts (because this is what people do with blogs, right?)

Okay, time to end this uselessly long “Hello World!” post. Please don’t hesitate to make me a better person with your corrections and suggestions. Now, onto more useful things!

© 2019 Ismail Coskuner

Theme by Anders NorenUp ↑