Posts Tagged ‘pokedroid’

Update on Pokédroid

I’m still getting lots of comments and emails about Pokédroid, which was taken down from the Android Market last month due to a DMCA notice from The Pokémon Company. (See these posts.) Most of my blog traffic still seems to come from Pokédroid-related searches, which is not surprising given the more limited appeal of my other apps. (What – you guys aren’t as excited about my system log reader?) So I thought I’d do a little round-up of the commentary on Pokédroid and get everyone up to speed on where the app currently stands.

Tim Oliver, the developer of iPokédex, informs us that the app removal process for iPhone Pokédexes has now begun. The timing seems about right, given that the TPC lawyer I spoke to said that Apple’s process takes a bit longer than Google’s. Tim and other iOS developers are in talks with TPC right now, but if their experience is anything like mine, we can expect iPhone apps to be removed shortly.

None of this should be surprising, given that TPC is now venturing into territory previously occupied by fan developers. The recently released Pokédex 3D app for 3DS, although not a true strategy guide like Pokédroid, makes it clear why TPC would start to view fan-made apps as unwanted competition. The rhythm-action Pokémon games coming to Android and iPhone make this point even less ambiguously.

Liam Pomfret, the head of Bulbagarden, has been my most helpful contact point throughout this whole process, and he has an interesting editorial on Bulbanews laying out TPC’s case for taking down Pokédex apps. It’s very persuasive, and if nothing else it splashes some cold water on the impulsively negative fan reaction. He points out that all fan-made media (including Bulbagarden itself) is in violation of TPC’s copyrights, and so TPC is within its legal rights to selectively allow or disallow whatever content it wants. It’s debatable whether or not taking down Pokédex apps is actually in TPC’s own self-interest (I’ve argued it’s not), but the legal case is pretty difficult to dispute.

And in fact, even if Pokédex developers like myself did have a good case, we probably wouldn’t be doing ourselves any favors by taking it up in court. Recently there was the case of the Miles Davis afficionado who ended up paying $30,000 for a copyrighted photo he used in a tribute album. This was without any admission of guilt, and despite the fact that his lawyers thought they would have had a decent case if they had actually pursued it. The $30,000 settlement was simply the least expensive option available to him.

Now this may surprise you, but Pokédroid, as a hobby app, is not worth $30,000 to me. And if you think I could just get 30,000 of my 150,000 active users to each chip in a buck and cover my legal expenses, then you’ve never developed a mobile app before.

This is why I’ve rejected requests to open-source Pokédroid. As Liam pointed out above, open-source licenses still presume ownership of the IP content in the code, which means I’d be making myself a legal target just by publishing the code base. Even though I’m a die-hard Linux user who loves open-source, I have to admit that this isn’t really the time or place for it.

Anyway, I’ve been on good terms with TPC so far, so I have no incentive to do anything to try and spite them. Everyone I’ve spoken to at TPC has been very courteous and respectful towards me, and they’ve taken obvious care to explain their point of view and avoid any misunderstandings. They’ve even mentioned reading my blog posts (hullo out there!), so they’ve obviously got their finger on the pulse of the fanbase, and aren’t acting hastily or thoughtlessly.

My hope right now is just that they will offer to license Pokédroid or rebrand it as an official Pokémon app. In my ideal world, they would also let me open-source it, possibly in exchange for my help with the rebranding process. That way, I could gracefully hand the reins over to other fan developers (who would probably be more hardcore Pokémaniacs than me, and thus more diligent contributors), but the app would still remain an officially licensed product. TPC could continue to disallow unofficial apps on the Android Market if they wanted, but anybody would be able to contribute to the official app. The same community involvement that made Bulbapedia strong could make Pokédroid the best Pokémon resource on any mobile platform.

Admittedly, this scenario is a little starry-eyed. But even if TPC wasn’t keen on the open-source idea, I still have 19,000 lines of code that could save them a ton of time if they decided to build their own Android Pokédex app. Hopefully they’ll take me up on my offer, so that Pokédroid can get back in the Market, and back in the hands of the fans who find it so useful.

On Pokédroid’s Removal

I posted the short version of this story to Pokédroid’s page on the Android Market:

Pokédroid will be removed from the Android Market shortly.

A legal representative of The Pokémon Company has responded to me via email. He has confirmed that TPC would like Pokédroid, and all similar apps, to be removed from the Android Market.

TPC’s stance is apparently that they don’t want any Pokédex or Pokémon-related apps at all for the Android platform. They feel that such apps infringe upon their copyrights and compete with the print versions of their strategy guides.

While I disagree with this decision, which I believe is detrimental to the interests of both Pokémon fans and TPC alike, I have decided to comply with their request. Thus, henceforth I will cease all development on Pokédroid and remove it from the Android Market.

When this page goes down, please visit my site ( for more information. I will _not_ host the APK there.

It has been a pleasure to serve the Pokémon community. I hope you had as much fun using Pokédroid as I had writing it.

- Nolan

Going through this whole process of being targeted for copyright infringement, trying to fight it with argument and persuasion, and eventually being defeated has been a strange odyssey for me. I’ve learned a lot about how IP enforcement actually works in the real world, and I’ve lost a little bit of my naïveté. I’ve also lost the hundreds of hours of work I put into Pokédroid, and I’ve let down my 400,000+ users. It’s been humbling, to say the least.

When Pokédroid Donate was first taken down by Google, along with a dozen other Pokémon apps, I was not very surprised. I figured that either Nintendo was trying to crack down on paid Pokémon apps, or they were targeting blatant copyright infringements like wallpapers, games, and soundboards. I assumed Pokédex apps, which are really just strategy guides, would be safe.

Google sent me a copy of the original DMCA takedown notice from The Pokémon Company (which is an affiliate of Nintendo). But the fact that it listed my app, Khiry Arnold’s “Poké Pal”, and Stephen Willey’s “Pokédex” among a dozen-odd wallpaper and soundboard apps seemed to me like a mistake. Anyway, the notice itself looked very hastily thrown together – it was obviously the result of an entry form on Google’s website, and some of the app names were even misspelled. (“Pokédroid” was listed as “Pokédex,” although they spelled my name right.)

So when I started trying to get in contact with The Pokémon Company to rectify the problem, I figured the stakes were low. The free version of Pokédroid was still on the Market (probably due to an oversight from Google), and I couldn’t imagine TPC would want it removed. So I felt like I was mostly fighting for Khiry and Stephen, whose apps had been forcibly removed by Google while mine was overlooked. I had the most users out of the three of us, and therefore the most clout, so it seemed the responsibility had fallen on my shoulders to clear up the misunderstanding. Sort of like I was representing the Pokédex App Developers Union or something.

I honestly thought that the content of the apps was uncontroversial, and that as soon as I could get in touch with someone at TPC they would rescind the takedown immediately. I mean, there are plenty of fansites that offer the exact same content as Pokédroid, and nobody seems interested in taking those down, so why would Android apps be any different?

I did worry, though, that TPC might frown down upon monetizing our apps. So to be on the safe side, I deprecated Pokédroid Donate, which had only distinguished itself by including the “shiny” sprites anyway, and added the shinies to the free version. Now I felt Pokédroid was scrubbed clean of anything even slightly questionable – it was a free (and ad-free) app, with no content that couldn’t be found at a half-dozen popular fansites, and to boot I had gotten written permission from all the people who had given me their data (mostly Marriland, but there were a few other FAQ authors as well). A perfect representative of our little Union.

So like a fresh-faced Jimmy Stewart going to Washington, I penned the following polite email to TPC:


I’m the developer of the Android Pokédex app “Pokédroid.” A few days ago I received an email from Google explaining that my app was to be removed from the Android Market due to a DMCA takedown notice from The Pokémon Company (see attached). Several apps are mentioned in the notice, including “Pokédroid” and other similar Pokédex-style strategy guide apps.

Could you please explain why The Pokémon Company is targeting these particular apps? My understanding was that they fall under the category of “fair use,” in that they function as strategy guides (i.e. research) and are not directly competing media. Furthermore, there are plenty of iPhone apps and web sites (such as Bulbapedia and that offer the same content, so I’m perplexed as to why Android apps were singled out.

To be fair, many of the apps mentioned in the notice are clearly copyright-infringing – e.g. games, wallpapers, and soundboards. I can understand your desire to have these apps removed. But strategy guide apps, to me, do not appear to fall into the same category.

If this was indeed a mistake, please notify Google so that they can restore these apps to the Market. Hundreds of thousands of Pokémon fans use these apps as a resource when playing your wonderful games, so I’m sure that having them back in the Market would make those fans very happy.

If not, then I will be happy to keep “Pokédroid” off the Android Market, per your wishes.

Thank you for your time.

Nolan Lawson

For two weeks I received no response. I sent multiple emails and even left a voice message at TPC’s company phone number. Then finally, after finding the phone number of one of their lawyers and leaving a message there, I received this email:


I’m the position omitted for The Pokémon Company International, Inc. I’ve been given to understand that you’re trying to reach someone at TPCi to try to get some information about Pokédroid and Pokédroid Extras and more specifically about why we asked Google to have them removed from the Android Market. Since you’ve reached out to us and been reasonable about this, I wanted to take a moment to write you back and give you some insight into our thinking.

By way of background, and sorry but I do have to get legalistic for a minute, you have told us that you think your apps are fair use. Unfortunately that’s not the case. There are lots of websites that purport to give information about what is and isn’t fair use, but I find one good summary is from the US Copyright Office at Under US law all uses of a copyrighted intellectual property by anyone other than the owner of the IP are presumptively illegal, and it’s up to the person using the IP to demonstrate that their uses are permitted. So fair use isn’t an affirmative permission to do something, it’s a defense to an action that is otherwise illegal, which means that it’s your obligation to prove that you should be allowed to make apps based on Pokémon and unless you can prove that you’ve got a legal right to do that, your apps are infringing.

One thing that’s not commonly-understood by fan communities is that the owners of the Pokémon IP have the right to decide not to put this IP into the Android Market or anywhere else. Put another way: if we don’t create our own Android Market app, that’s not an invitation to other people to fill what they perceive as a gap, it’s a decision that they have to respect. You may think that Pokédroid and Pokédroid Extras don’t compete with our print strategy guides like the one for sale at Amazon ( or the one available for free at our website But as you can see from the Copyright Office link that’s not the only criterion in the test, and even if it was I’d have to say we don’t agree, and in any event we have chosen not to allow any Android Market apps for Pokémon.

I hope this helps you understand the situation and our position. I can’t ask that you agree with me, although I’d hope that after you’ve read this you’ll know that we didn’t act capriciously or lightly. But I do have to ask that you take Pokédroid and Pokédroid Extras out of the Android Market and not upload them anywhere else. Could you confirm to me by return email that you’ll do that?

I hope that you’ll find another way to contribute to the Android app community. Given how skilled you are at app development, I don’t think it will take long.

Name omitted

Needless to say, I was shocked. Were they serious? Why would Nintendo target apps that do the exact same thing as a half-dozen fansites, which they’ve never attacked before? (To be fair, TPC has attacked fansites in the past, but only for small portions of the content they publish.)

I’m not arguing that Nintendo doesn’t have the right to act in this way. They can do pretty much whatever they want with their own intellectual property. IP law, taken to its logical conclusion, means that they can prohibit me from whistling the Pokémon theme song as I walk down the street, for instance. This is kind of a silly example, but I’m just pointing out that determining IP infringement is not clear-cut. For this reason, most companies choose to act judiciously when they enforce IP, because too much enforcement could be dismissed by the courts or cause a backlash from fans. They have to find a middle ground.

And in the case of Pokédroid, IP enforcement seemed to me like a clear lose-lose for Nintendo. If there are no mobile Pokédex apps, then that seriously reduces the value of every Pokémon game that Nintendo publishes. Gamers love strategy guides because they increase their enjoyment of the games. Imagine if a resource like Bulbapedia were taken down – so much of the fun of playing Pokémon games would be sucked out of them! And it’s the same with mobile apps. Undoubtedly, taking down mobile Pokédex apps would cause fewer people to buy Pokémon games in the future, and Nintendo/TPC would suffer. They might sell more $10 strategy guides, but they’d sell fewer $30 games. They’d lose money.

Alternatively, TPC may be thinking of releasing their own app, which would explain why they’d want to eliminate competitors. But even that reduces quality for consumers. Undoubtedly TPC would release one monolithic app with a limited feature set, and if some fans wanted different features or a different presentation, then tough luck. With a lot of competing apps, though, choice is increased for consumers and everyone’s more likely to get what they want. This was already happening with “Poké Pal,” which was an app geared more towards serious, competitive players than my own. It was a free app, and it excelled in its own way, while Pokédroid excelled in other ways. Consumers could download one, the other, or both. Everybody wins.

I sort of doubt that TPC or Nintendo will release their own app, though. If anything, the author of this email seems to be suggesting that Nintendo is deliberately leaving a “gap” in the Android Market, and that I need to respect their decision to keep it that way. Similar to when Nintendo shut down that fan-made Zelda movie, or when Square Enix shut down the fan-made Chrono Trigger sequel, no replacement is intended. IP enforcement can be somewhat mindless in its destruction. I like to picture it as a grumpy old coot, waving his cane at those pesky neighbor kids when they’re having too much fun on his front lawn.

So at this point, reading the email, I kind of glumly realized that the game was lost. There was probably no way to convince TPC to take back the original DMCA notice. I felt a little frustrated that I had provoked them in the first place, since, if I had just done nothing, Pokédroid might have stayed on the Market awhile longer while they shuffled their paperwork around. But by buzzing in his ear, I had invited the giant to swat me down. It seemed there was nothing left for me to do but bow to their demands.

I wanted a little more clarification about their motivations, though, and I also hoped I could make an emotional appeal for them to reconsider. So I wrote the following:

Hi Name omitted,

Thank you so much for your response. I really appreciate you taking time out of your day to help explain these kinds of issues to me, especially since (as a layman) legal matters are obviously not my area of expertise.

I think I have a better understanding now of what is meant by “fair use.” I understand that TPCi has complete legal right to their intellectual property, and that therefore any third-party use of that IP is considered to be infringement until proven otherwise. Also, I’m perfectly willing to take down Pokédroid and Pokédroid Extras from the Android Market and not upload them anywhere else, per your request. In case you were wondering, the reason it’s still on the Market is because Google did not take it down themselves, probably due to an oversight on their part. I was confused about the situation, and so I left it up until I could get word back from your company.

I have to admit, though, that I’m surprised by TPCi’s decision, and I’m hoping you could tell me a little more about the motivations behind it. Specifically, why Android apps? To my knowledge there are about a dozen Pokédex apps for iPhone, and many of those are even paid apps. There are also popular web sites such as Bulbapedia and that offer similar content. Does TPCi plan on removing those sites and apps as well, or is there a specific reason that Android apps are being focused on? I’m not asking this in order to play “gotcha,” or to make some kind of “two wrongs make a right” argument; I’m honestly just trying to understand TPCi’s position on this issue. After having put several hundred hours into developing this app, I think it’s reasonable for me to want to know a little more about your company’s decision before shutting it down for good.

Also, I realize it’s sort of a “children’s letters to Santa Claus” argument that doesn’t carry much legal weight, but I do hope you’ll read some of the reviews for Pokédroid: Ever since I mentioned that the app might be taken down, there have been lots of comments expressing sadness and frustration over the news. Pokédroid has over 420,000 users, and it honestly saddens me to think about taking away what is obviously such a valuable resource for them.

Thank you again for your legal advice and courtesy towards me. I hope you know that, as a longtime Pokémon fan, I offer TPCi the same courtesy and will bow to any of its wishes regarding its own IP. But I also hope that TPCi will consider alternative solutions to this problem.

Nolan Lawson

The next day, I received the following response:


Not a problem to respond, and thanks also to you for your reply. It’s certainly not unreasonable for you to ask for a bit more background. Unfortunately and as you can probably imagine I can’t really discuss the specifics of other situations or other apps, except to note that we’ve sent a fair number of notices recently, will be sending some more, and if there are people out there who aren’t as great about this as you have been they may receive a slightly different form of communication from me. But you shouldn’t feel singled-out at all, and it’s not just Android apps. Apple has a slightly different approach to these kinds of things than Google does and so their process takes a bit longer to operate, for example.

Thanks again for your reply and for your understanding here.

Name omitted

He’s obviously not letting on very much here. He isn’t recognizing the contradiction in targeting Pokédroid while leaving Bulbapedia and Serebii up, and he doesn’t really explain why TPC has suddenly decided to go after mobile apps. The evasiveness of his answer was kind of a letdown for me, although I can understand why the legal team would want to keep mum about such things.

He’s also being very diplomatic about all this, which I appreciate. But I do detect a sort of “good cop” routine going on here (“as great as you,” “how skilled you are”), with the thinly veiled threat of the “bad cop” waiting in the other room in case I don’t play ball (“a slightly different form of communication”). He’s left little room for debate – the impetus is clearly on me to either follow directions or face the consequences. No response to my heartfelt Miracle on 34th Street reference, and no response to my suggestion to seek alternative solutions. I suppose I naïvely thought he might be touched by all the user comments, but it seems not.

So that’s pretty much the whole score. Nintendo: 1; me: 0. I wish I had the courage to fight this battle, but I searched my soul and came up empty. It just doesn’t seem worth it to me to stick out my neck and try to stop Nintendo from attacking their own customers. Also, I could do more harm than good if I continue this line of argument with them. I was worried enough that, when I mentioned Bulbapedia and Serebii, the lawyer might respond, “Hmm, shut down Bulbapedia and Serebii? Not a bad idea.” At a time when TPC’s legal team is clearly on the rampage, the last thing I need to do is draw attention to myself or anybody else. It’s like the T-Rex in Jurassic Park – stand still, and he might just leave you alone.

On a personal level, though, I’m deeply disappointed with this whole result. Although I haven’t been the most dedicated Pokémon fan (I tried but couldn’t really get into the newer games), I’ve poured my heart and soul into Pokédroid. In terms of Android app development, it’s my magnum opus. I put deliberate care into every inch of the interface, every function call in the code, every UI design decision.

Pokédroid might not look pretty (I don’t have an eye for design), but there are little touches that improve the experience in ways the user might not even perceive. For instance, the buttons’ “onClick” methods load in the background, so that the UI doesn’t slow down. The voice search uses string edit distance to try to find approximate matches. The moves and locations use dropdown lists, because I wanted to keep the interface clean and uncluttered. The “advanced search” uses optimized SQL indexes for the fastest possible searching.

All of these are things I put time and effort into, to please my 400,000+ users. I’ve spent hundreds of hours trying to improve Pokédroid, which, even with all my donations considered, was done at below a minimum-wage rate. And yet, I don’t regret any of it, because (and I’m going to get a little mushy here) I know Pokédroid has brought a little ray of sunshine to so many people’s lives. As of today, it’s in the top 50 free apps in the “Entertainment” category, it has a perfect 5-star rating, and it has hundreds of comments from satisfied users, all expressing how much joy, delight, and amusement Pokédroid has brought to them.

To say that this gives me the warm and fuzzies would be an understatement. In fact, Pokédroid was a great psychological boon to me, as I left the safety of college and entered into full “quarter-life crisis” mode. I wondered: What was my contribution to the world? What had I done to justify my existence? With Pokédroid, I could always point to it and say, “Right there. 400,000 people who got a kick out of my app. 400,000 people who reminisced about the cartoon show, looked up stats for their competitive team, or just giggled at the silly text-to-speech feature. 400,000 smiles. That’s what I’ve done for the world.”

I’d like to close this article with some of my favorite reviews from the Android Market. The fans are the reason I kept working at Pokédroid, and they’re the ones who gave me feedback and criticisms that helped me fix bugs, retool the user experience, and correct glaring flaws. I want to thank them for giving me a really cool project to work on for the past year, and for giving me lots of insights into application development. Thank you all.

  • this is the most amazing app i have ever seen, ive always dreamed of having a dex on my phone. i love you man<3 – Jonesyruless
  • Now i can trump my kids with my mad pokemon knowledge – Lisa
  • Kids love the talking pokedroid. Its a must have for any Pokemon fan! 5 stars – Ash
  • Is super great and I would buy the donate version but my mom said no haha but as soon as im off her plan I will if I still play Pokemon – Steven
  • I am donating asap. And I NEVER donate. Not to the homeless, friends in need of a buck for gas, never! – Philippe
  • Love it! Showed it to my office mate and we started getting all nostalgic – Lumpy
  • Why I bought Android – Nick
  • My 5 yo daughter loves this. – Eric
  • This app has amazing info, and the voice is hilarious! – Sean
  • I was out in the wild and a pokemon appeared. My friend asked me what it was but i didnt know. So i took out my Pokédroid and identified it! – Dal
  • I absolutely LOVE this app! My friends have become jealous and they want an android phone JUST for this app! Genius! ^_^ – Abigail
  • Incredible! This app has single handedly justified my Droid purchase. Please add egg moves! – |3reak
  • Thank you Thank youThank youThank youThank youThank youThank youThank youThank youThank youThank youThank youThank youThank youThank youThank youThank – Wonton
  • This is well cool. My friend’s all want android phone’s just for this app. :-) – Max
  • My daughter loves this app. Just like a pokedex from the cartoons! – Jessica
  • My son loves this keeps him occupied for ages – Lorna
  • Wow, this is simply awesome, no words to describe.. it just feels very special for some reason!.. thank you! =] – Cloud
  • I bought a Droid for this app! I love it. Keep up the good work. – Timothy
  • A real Pokedex? I love the future. – Craig
  • Would give it 1000 stars if I could, what an elaborately designed app. Thank you for sharing for free! – Zach
  • I use this pokedex on the regular. Helps with all versions. I am in college and I still use it to settle disputes. Great app. A+ – Dietrich
  • Fantastic! Work at gamestop and this app has gotten me some sales haha def donating. Game specifucations would be nice tho – Victoriano
  • I cant imagine playing the games w/out this app. I use it whenever i am in battle to help me choose what pokemon to use. Cant wait for b and w update. – Cameron
  • Being a programmer it takes alot to get 5 stars but he earned this – Jonathan
  • Awesome! My kid loves the black & white update. Really useful, and free! – Paul
  • Good resource! Great for keeping up with my 7 year old daughter ^^ – Midd
  • This is the best Pokédex app that is out there. It makes me feel like I’m part of the show. – Kohaku
  • Since the moment I downloaded this months ago I’ve loved it. The latest update makes the interface lightning fast and pretty much flawless. – Daenym
  • Thanks for B/W update! Scrolling is PERFECT now!!! Thank you for voluntarily working to satisfy such a prissy bunch of people! – Sidney
  • Perfect app for a beginner or veteran. Now I can stop getting on the PC to look up new Pokemon I haven’t heard of! – Frogmum
  • Best app on my phone – Tom
  • Childhood dream come true… enough said – Kevin
  • Not only is it a great app but the customer support is tops as well – Christopher
  • This has got to be the funnest/greatest app ever!! Absolutely in love w/ it! – Denise
  • So convenient! Considering that bulbapedia is down half the time! – Kathy
  • Best thing ever – Daniel
  • I love this app! Easy reference to help me train my pokémon in the best way possible! Plus getting to freak out my friends w/ random pokémon cries! – Bryan
  • 10 out of 10!!!!!! This is by far the most comprehensive pokedex I have ever seen. Fast, easy to use. Settings for different versions (Great for when I play Black and by daughter plays Platinum). Consistent updates. If you have not already downloaded this and the extras bundle… then you are dumber then a Magikarp! – Wayne

Nintendo used Takedown! It’s super effective!

UPDATE: I was in error when I wrote this post. Apparently, all Pokémon-related Android apps were cited in the DMCA takedown notice, not just paid ones. Every Pokédex app has been removed by Google except for Pokédroid and Pokédex Companion. It’s not clear why.

Today I received an email from Google explaining that Pokédroid Donate was removed from the Android Market due to a DMCA takedown notice from The Pokémon Company (a subsidiary of Nintendo). The email begins:

This is a notification that the application, Pokédroid (Donate) with package ID com.nolanlawson.pokedex.donate has been removed from Android Market due to a violation of the Developer Content Policy. Please review the Content Policies and Business and Program Policies before you create or upload additional applications. Note that repeated violations may result in a suspension of your Android Market Publisher account.

Mine wasn’t the only app removed – in total, about a dozen Pokémon-related apps were cited in the DMCA notice. These include “Poké Pal Donate,” “Pokédex,” and “Who’s That Pokémon?”, among others. Apparently only paid apps were targeted; the free versions of Pokédroid and Poké Pal, for instance, were not mentioned.

In response, I made an update to Pokédroid and added the following text at the beginning:

Google has removed Pokédroid Donate from the Android Market, due to a copyright claim by The Pokémon Company. In fact, all paid Pokédex apps (Poké Pal Donate, Pokédex) were removed. Free apps were not affected.

In response, I am adding the shiny sprites to Pokédroid for free. To the people who already paid for Pokédroid Donate, I apologize for the sudden bait-and-switch. So you won’t feel like you wasted your money, I am hereby donating all proceeds from the month of May (about $150) to Doctors Without Borders.

I disagree strongly with what The Pokémon Company is doing. It hurts Pokémon fans the most, because they are the ones who benefit from having a variety of apps on the Market. Also, the apps don’t even threaten Nintendo’s bottom line, because they’re strategy guides and not competing games. However, there isn’t much I can do, because Nintendo is a powerful company and I’m just one guy.

Please keep in mind that your donations sustain my interest in developing this app. You can still donate via PayPal at my website:

Thank you for using Pokédroid, and stay tuned for more updates! I have some very cool features in the works, and I will try to get them to you despite these legal hurdles.

- Nolan

And for the “pics or it didn’t happen” crowd:

Mostly what I’m doing here is damage control. Nintendo has backed me into a corner, and I’m too sheepish to fight back. So I’m just doing what I assume they want me to do – make Pokédroid 100% pro bono. But since this will irritate people who already bought Pokédroid Donate (and who are therefore my best and most enthusiastic users), I’m also doing the donation as a show of good faith.

This is my own, somewhat cowardly reaction to the news. I’m not sure what other app developers will do. I’m in contact with Stephen Willey, the developer of Pokédex, and Khiry Arnold, the developer of Poké Pal, but neither seems to have decided what their strategy will be. Admittedly, we’re all in a bad predicament. I feel especially sorry for Khiry, because he had just started doing a freemium model like me, and his app was really spectacular in terms of depth and detail.

Of course, none of these deleted apps really violate fair use, insofar as they might compete with Nintendo’s core product. There’s nothing about a strategy guide or a silly “Who’s that Pokémon?” quiz that diminishes anybody’s desire to go out and buy the next Pokémon game. If anything, these apps actually increase interest in the product, because they add value for current Nintendo customers and encourage them to learn more about Pokémon. And if nothing else, they’re free advertising.

But this is the tragedy of current copyright law. Presumably, Nintendo took out its copyrights to protect against blatant infringements, like game piracy. But here instead it’s using its IP to attack the Pokémon fan-developer community, at great cost to its customers and, indirectly, to itself. To be fair, though, none of this is really Nintendo’s fault. They’re just operating within the mad logic of a broken system.

People who know me personally know that I am very skeptical of copyright law and intellectual property in general. I tend to view patents and copyrights as government-enforced monopolies that drive up prices, reduce choices for consumers, waste money on litigation, and stifle more innovation than they spur. For your own interest, and to challenge any assumptions you may have about IP, I recommend reading these articles: here,
here, and here.

Your Froyo users are an army of testers

The error reports page in the Android Market Developer Console is one of my favorite additions to Android 2.2 (Froyo):

It gives you a nice, organized view of the stacktraces reported by users when your app has crashed or frozen. This is great because, for the most part, users are not particularly eloquent when describing bugs. Usually they just say something like “Doesn’t work anymore, please fix.” And when they do give more information, it’s often tantalizingly incomplete: “When I go to Settings I get a force close.”

Stacktraces, on the other hand, don’t beat around the bush:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { (has extras) }} to activity {com.nolanlawson.pokedex/com.nolanlawson.pokedex.PokedexActivity}: java.lang.NullPointerException
      at android.os.Handler.dispatchMessage(
      at android.os.Looper.loop(
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(
      at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
      at com.nolanlawson.pokedex.VoiceSearcher.guessMonsterUsingDirectLookup(
      at com.nolanlawson.pokedex.PokedexActivity.receiveVoiceResults(
      at com.nolanlawson.pokedex.PokedexActivity.onActivityResult(
 ... 11 more

NullPointerException. Bam. Go to the line in the code, figure out what’s null, and fix it. Nothing clarifies a bug like a good old-fashioned stacktrace.

Before Android 2.2, you had to get this kind of information from users by having them download a Logcat app and go through all the tedious effort of recording the log, reproducing the bug, and sending the stacktrace to you. Users can hardly be blamed for a lack of enthusiasm about this process. When you’re trying to complete a task and an app force-closes on you, the last thing you think is “Oh goody! I should tell the developer about this!”

Oh goody!

So Froyo’s error reporting framework is a godsend. From the user’s point of view, it’s a lot less painful to just click the “Report” button than to go through the rigamarole of downloading a Logcat app and emailing the developer. (Although, there is a splendid little Logcat app out there.) And from the developer’s point of view, your users have become an army of testers – and good ones, at that! They give you stacktraces and everything!

Plus, even when the stacktrace is not enough information, the additional comments from users are sometimes enough to squash the bug. For instance, I recently had an ArrayIndexOutOfBoundsException that was reported by almost a hundred Pokédroid users after the release of version 1.4.4. Try as I might, though, I couldn’t reproduce it. Then I noticed the user comments:

  • 셋팅 클릭시 프로그램 종료됨
  • Every time I open settings it shuts it self down. Galaxy ACE
  • se cierra al entrar en “Settings”
  • 렉 너무걸린다
  • När man ska gå in på inställningar så hänger programet sig
  • Happens every time I go to the settings
  • whenever I go to settings, the program crashes
  • I has updated this app and now when i want to change settings that not working! I mean i cant change settings! :-( sorry about my bad english :-(
  • It crashes while I try to enter the settings
  • trying to open settings. always happens. samsung galaxy s. android 2.2
  • when click on settings freeze
  • Telkens als ik naar settings wil gaan dan flipt ie
  • i was trying to go to the settings-screen… crashes whenever i try it…
  • Opened settings

Hmm… there sure are a lot of non-English comments here. So I set my phone to French and, aha! It turned out the bug only occurred if your phone’s language was set to something other than English. The bug was fixed and I shipped out 1.4.5 that same day. (Another great thing about the Android Market – no review process!)

When you have an app with a lot of downloads, though (like Pokédroid, which just hit 250,000), you start seeing some strange little bugs:


Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed
     at android.database.sqlite.SQLiteQuery.native_fill_window(Native Method)

     at android.widget.TextView.onDraw(
     at android.view.View.draw(

Caused by: res/drawable-hdpi/ic_dialog_alert.png
     at android.content.res.AssetManager.openNonAssetNative(Native Method)

Most of these just aren’t worth the effort to fix. For instance, they might only be reported by one or two users, and reflect situations that you, as a developer, don’t have a lot of control over (“database disk image is malformed”?). Others may be bugs in proprietary builds of Android, like the Motorola and Sprint bugs above. Obviously, I’m not going to go out and buy every flavor of Android phone just to test a few stray bugs.

If you’re lucky, you may also run into the Bigfoot of Android bugs:

java.lang.RuntimeException: Unable to get provider com.nolanlawson.pokedex.PokedexContentProvider: java.lang.ClassNotFoundException: com.nolanlawson.pokedex.PokedexContentProvider in loader dalvik.system.PathClassLoader[/mnt/asec/com.nolanlawson.pokedex-1/pkg.apk]
     at android.os.Handler.dispatchMessage(
     at android.os.Looper.loop(
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(
     at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: com.nolanlawson.pokedex.PokedexContentProvider in loader dalvik.system.PathClassLoader[/mnt/asec/com.nolanlawson.pokedex-1/pkg.apk]
     at dalvik.system.PathClassLoader.findClass(
     at java.lang.ClassLoader.loadClass(
     at java.lang.ClassLoader.loadClass(
... 12 more

I want to believe.

I call this the Bigfoot Bug because, if you Google it, you will find a lot of puzzled developers saying that they’ve only ever seen this bug reported in the Android Market, and they can’t reproduce it themselves. I mean, “ClassNotFoundException”? The class is right there! I was stumped by this bug myself, until I saw one developer suggest:

AFAICT, the installation process sometimes leaves the app in a corrupt state leading to weird errors like this.

So apparently, this bug is just one of those unavoidable parts of life, like sitting through red lights or having the sushi fall apart when you dip it in the soy sauce. You just have to put up with it.

Still, if you can manage to not get overwhelmed by the sheer number of reported bugs (Pokédroid has gotten over 500), and if you can prioritize them based on how many users they affect, the Froyo error reports can be an invaluable tool in making your app more stable. For instance, I had a layout-related bug a few months ago that I could not reproduce. It was reported by enough users, though, that I finally decided to rewrite that bit of the code and do some long-overdue optimizations. I haven’t seen the bug since.

Why it’s still your bug, even when it’s not

In the previous post, I talked about a workaround for a bug that occurs when integrating with the Facebook Android app. It brings up an interesting question: when software A integrates with software B, and software B has a bug, whose responsibility is it to fix it?

Intuitively, you might answer B. “It’s B’s fault. The developer of A can wash his/her hands of the whole matter and go to bed with a clean conscience.” Justice prevails, right?

But I disagree. In my opinion, the responsibility falls on whomever the user chooses to blame. Because when it comes down to it, the user does not care whose bug it is. They just want someone to fix it, or else heads will roll.

Case in point: the Facebook ACTION_SEND bug. To recap, the ACTION_SEND Intent is used to send arbitrary text from one app to another. Many apps answer the call – Facebook, Gmail, Twitter, Yammer – any app that may be interested in the text. Intuitively, Facebook should let you share the text as a status update, like Twitter and Yammer do, but instead they stubbornly interpret it as a URL. If it’s not a URL, then it barfs up an error.

In my own apps, I could have just used the ACTION_SEND Intent as-is. Let Facebook clean up their own mess – my hands are clean. But obviously, because I’m one man and because Facebook is Facebook, users would assume the bug is mine. So here’s what would have happened if I had chosen to ignore it: I’d get a ton of emails and Android Market comments saying, “Facebook doesn’t work” or “4 stars until you fix Facebook.”

Maybe then I would have smugly responded, “It’s Facebook’s bug, not mine.” Or, if the comments persisted, I might have added a popup saying, “Facebook doesn’t work correctly, due to a bug in their app. Please avoid Facebook.” But as we know from a previous post, users don’t read anything. So I would have continued getting angry comments and emails, and I would just have to respond to each one with a triumphant “Not my bug.” In the end, my users would be unhappy, but hey – at least I stood up for myself, right? At least I’d have the satisfaction of knowing I did the right thing.

But this is not the right thing. At least, not if you believe that the point of software is to make people happy. In fact, there’s a grand tradition of unsung heroes in software development fighting to fix the other guy’s bug. Once again, my main man Joel Spolsky explains:

[I heard this] from one of the developers of the hit game SimCity, who told me that there was a critical bug in his application: it used memory right after freeing it, a major no-no that happened to work OK on DOS but would not work under Windows where memory that is freed is likely to be snatched up by another running application right away. The testers on the Windows team were going through various popular applications, testing them to make sure they worked OK, but SimCity kept crashing. They reported this to the Windows developers, who disassembled SimCity, stepped through it in a debugger, found the bug, and added special code that checked if SimCity was running, and if it did, ran the memory allocator in a special mode in which you could still use memory after freeing it.

From Microsoft’s point of view, they had a good reason for doing this. If a customer was upgrading from DOS to Windows, and suddenly all their favorite applications stopped working, they’d simply return Windows. Microsoft would bear the fallout from the other guy’s mistake. Once again, the one who gets blamed is not necessarily at fault, but it’s still his/her responsibility to fix the bug.

In Android development the most infamous instance of this occurs in the Android Market, and it’s the bane of Android developers everywhere:

“Error 18″ occurs when the Android Market fails to download and install an app. And even though it has nothing to do with the app itself, this is the most common bug you will see reported by users. In fact, I’ve gotten so many reports of this bug that I’ve created a “canned response” in Gmail that I send out to all of them. I believe I recall reading that Arron La, the developer of the immensely popular Advanced Task Killer app, has said that he simply stopped responding to these kinds of emails, because he gets too many of them.

The reason that poor schmucks like Arron and me get inundated with these emails is due to the interface of the Android Market itself. When an app fails to install, the user will be on this page:

It may as well say, “Direct your frustration here.” And from the user’s point of view, this is understandable. When they get an error like this, whom are they supposed to ask for help? Google is not famous for their tech support. So, as the quaint proverb goes, shit rolls downhill. And it hits the developer first.

So we’ve established that the one who gets blamed is not necessarily the one at fault. But how do you determine who gets blamed? In the case of SimCity, it was the OS rather than the app. In the case of “Error 18,” it’s the app rather than the OS. I think the explanation for this is pretty simple.

In the smartphone world, your OS is wedded to your phone, and your phone is very dear to you. Perhaps you even consider it an extension of your psyche, the way some people might feel about a trendy haircut or designer jeans. So if an app breaks on your phone, you return the $2 app, rather than the $500, psyche-extending phone. In Microsoft’s case, the OS was not very closely tied to the hardware back in the 90′s, and the cost of an application was about the same as that of the OS. Or at least, the gap wasn’t as steep as $2 vs. $500. So in that case, it’s Windows that would get returned.

I think this can all be generalized as follows. The bug becomes your bug if:

  1. You are more accessible than the other guy, e.g. they represent understaffed call centers in far-flung corners of the world, whereas you represent a single ordinary person (who must have oodles of spare time to answer emails, if you can afford to waste it writing apps).
  2. You are more visible when the problem occurs, e.g. the bug pops up when you use the other guy’s library, and that library is invisible to the user.
  3. You will suffer the most from the blame. I think this is the big one. Even if user opinion is split 50/50 on whose fault it is, it becomes your bug if the blame hurts you more than the other guy. The Android Market bug is an instance of this, since “Error 18″ might cause a developer to lose a sale, but it hardly affects Google’s bottom line.

Unfortunately for me, even though the “Error 18″ bug is my bug by this definition, there’s not a whole lot I can do about it. There’s nothing I can change in the software that would stop the error from occurring, or lessen the pain for the user. So the best I can do is keep responding to these emails.

Or, if I’m feeling snarky, maybe I can link them here.

Respect your users by treating them like idiots

Working on Pokédroid in the middle of a huge boom in its popularity (it’s gaining 3,000 installs a day – not downloads, but cumulative installs) while reading Joel Spolsky’s User Interface Design for Programmers is teaching me a lot about designing UIs.  You can read some chapters of the book for free online; I especially like this post. I’m learning that Joel is absolutely right about many things, but especially this:

  1. Users don’t read anything.
  2. You must assume that users will not give your app their full attention.

Spolsky explains:

What does it mean to make something easy to use? One way to measure this is to see what percentage of real-world users are able to complete tasks in a given amount of time. For example, suppose the goal of your program is to allow people to convert digital camera photos into a web photo album. If you sit down a group of average users with your program and ask them all to complete this task, then the more usable your program is, the higher the percentage of users that will be able to successfully create a web photo album. To be scientific about it, imagine 100 real world users. They are not necessarily familiar with computers. They have many diverse talents, but some of them distinctly do not have talents in the computer area. Some of them are being distracted while they try to use your program. The phone is ringing. WHAT? The baby is crying. WHAT? And the cat keeps jumping on the desk and batting around the mouse. I CAN’T HEAR YOU!

Now, even without going through with this experiment, I can state with some confidence that some of the users will simply fail to complete the task, or will take an extraordinary amount of time doing it. I don’t mean to say that these users are stupid. Quite the contrary, they are probably highly intelligent, or maybe they are accomplished athletes, but vis-à-vis your program, they are just not applying all of their motor skills and brain cells to the usage of your program. You’re only getting about 30% of their attention, so you have to make do with a user who, from inside the computer, does not appear to be playing with a full deck.

The scroll thumb in Pokédroid

I’ve seen this “not playing with a full deck” situation play out over and over.  Recently, I had a user send me a very polite, carefully-worded email asking if I could make it easier to scroll to the new Black/White Pokémon, which are about 500 down from the top of the list. I was perplexed.  I wrote back and told him that, on my Nexus One, I can scroll down to the new Pokémon in about one second using the fast scroll thumb.  In fact, I implemented the fast scroll thumb to solve this exact problem. Was the fast scroll thumb not working on his phone?

Nope.  It turned out he just hadn’t noticed it.  He didn’t read the popup explaining the new feature, and he didn’t notice the scroll thumb at the right, even though it pops in and out as you scroll and is about 15% the width of the screen.  Now, it’s not that this person wasn’t intelligent – from reading the email, I could tell that he was highly literate.  It’s just that he wasn’t giving the app his full attention, because that’s what users do.

Several other users complained in the Android Market comments that there were no Black/White Pokémon:

  • Would be 5 stars but I can’t find the unova pokemon srry
  • Unova Pokemon don’t so up after update but all together its a good app
  • I just got the update and it had all of the improvements but it didn’t have the Black/White Pokemon
  • Huh?I updated but unova pokemon didn’t come out.HTC legend

This is because they’re updating from an older version of Pokédroid, and their game version is still set on HeartGold/SoulSilver, or some other version.  I told them in the initial popup that they needed to switch it.  I told them in the Android Market description that they needed to switch it.  I even put it at the top of the description preceded by the word “NOTE” in all caps.  Did it work?  Nope.  I still see these comments.

Of course, this is totally predictable given that, as Spolsky puts it so succinctly, “users don’t read anything.”  Again he explains:

This may sound a little harsh, but you’ll see, when you do usability tests, that there are quite a few users who simply do not read words that you put on the screen. If you pop up an error box of any sort, they simply will not read it. This may be disconcerting to you as a programmer, because you imagine yourself as conducting a dialog with the user. Hey, user! You can’t open that file, we don’t support that file format! Still, experience shows that the more words you put on that dialog box, the fewer people will actually read it.

The Black/White popup

So in the upcoming version, I’m implementing a popup to ask the user to confirm their game version when the app starts up.  Now, I know that users don’t read text, and I know that they hate popups, so I’m using some relaxing visuals instead – the box art from the games.  “Confirm Game Version: HeartGold/SoulSilver” pops up with a huge box art in their face.  Bam.  No confusion.  Except there is.  I realized as I was toying around with it that when it says “Confirm Game Version: Black/White,” I felt like I wanted to click on either the Black box art or the White box art.  I felt like it was asking me whether I wanted Black or White.  It was confusing to have to hit “OK” instead.  Which one am I confirming?

So I realized this: most users are going to assume that the game version is Black/White.  Why would they want anything else? Black/White is the most recent game.  If there are older Pokémon games with fewer creatures and different move sets, they sure as hell don’t want to know about it.  They just want to see some damn Pokémon, and they couldn’t care less whether I show the move sets from HeartGold, LeafGreen, or HotCherryPassion. Hardcore Pokémaniacs might scour all the settings and figure it out, but casual users won’t.

So my solution is to only show the popup if they’re on something other than Black/White. Normally, users expect popups when something is wrong, not when everything is A-OK. So new users, whose game version will default to Black/White anyway, would just be confused by a popup. “What happened?  Did I do something wrong?” So I figure: why even show it, if they’re already on the newest version of the game? This way, I can solve the immediate problem (people stuck on HeartGold/SoulSilver) without interrupting the majority of my users.

Another change I’m making is to shorten the introductory dialog and add pictures.  Given that the introductory dialog has traditionally been a wall of text, I should be surprised if users read anything in there.

Old intro popup

Just look at my pretentious little dialog, with its list of chores for the user to complete.  Are they really going to want to learn about the settings before they’ve even used the app?  Or where the “About” section can be found? I thought about it, and realized that there are only three pieces of information I need to convey in that dialog:

  1. You can download Pokédroid Extras to get footprints and cries.
  2. You can download Pokédroid Donate to get shiny sprites.
  3. The most recent changelog, for the 10% of users who want to know what’s updated and will actually read it.

Anything else, the user will only seek out on a need-to-know basis.  For the most part, they will just plow through the app and assume they can figure out how to use it as they go.  They don’t want pedantic lectures explaining how to change the settings or where to go for more information.  If they want information, they’ll come to me.

Pokédroid Extras and Pokédroid Donate are the only non-obvious components to the app, because you can’t get them in the app itself.  They require a separate download.  So I figure I’ll slap some pictures on the introductory dialog explaining what Extras and Donate do, and hope that the user’s eye will be attracted to the pictures, which will motivate them to read the 6-7 words to the right. They should be able to get the gist of the popup in one glance. They shouldn’t have to break out a cup of coffee and their reading glasses just to start the damn app.

New intro popup

This whole discussion may make it sound like I don’t respect my users.  But the beautiful thing, as Spolsky explains, is that by assuming my users are going to act like airheads, I actually am respecting them.  I’m saying, “I know you don’t care about this app nearly as much as I do.  I know you’re not interested in lectures about how I optimized the database, or all the cool little features I put in and why.  You’re a busy person, and you have better things to do.  You will put in the bare minimum of intellectual effort to understand my app, so that you can complete whatever task you’re trying to complete.  And that’s great.  I’ll be here to help you complete your task, and the rest of the time I’ll try to stay out of your way.”  What I’m doing is showing humility, and respecting my users’ valuable time.

Also, a lot of my conclusions about user behavior come from observations I’ve made about the way I use software (since reading Spolsky’s book, anyway). The fact is, I drive my phone like a reckless drunk drives a semi.  I pound the OK button to skip long dialogs.  I spam the back key to get out of an app.  I never read the changelog, the “About” section, or the manual – or maybe I glance through it, reading in an “F” shape (horizontal at first, then vertical down to the bottom).  If there’s a non-obvious Android feature that I actually use (holding down the home button to see recent apps, holding down the menu button to bring up the keyboard), it’s only because I’m an Android developer myself, so I saw it in the documentation.  It’s certainly not because I read the manual to either of my phones, because I didn’t.

When I download a new app, I usually just try to use it to accomplish one very specific task.  If I can’t figure out how to do that in ten seconds, I uninstall it.  For instance, I recently wanted an app that would let me uninstall other apps by clicking a widget on my home screen.  So I downloaded two or three of those “Task Killer”-type apps and tried to figure out how to do what I wanted.  When I couldn’t, I gave up and uninstalled them.  Each app probably spent all of sixty seconds alive on my phone before I flushed it down the memory hole.

When I manage to accomplish a task in a downloaded app, I rarely fiddle with the settings and just assume that the defaults are okay.  Sometimes this gets me in trouble.  A great example is the gStrings tuner app, which I use to tune my guitar.  The app is wonderful, and I’m happy to have downloaded the premium version to help support the developer.  The guy obviously knows his stuff – the settings are full of fancy options like “Playback Octave,” “Use Orchestra Tuning,” and “Use Harmonic Product Spectrum.”  Of course, I’m not going to change any of these, because they might as well be in Hebrew, but at least they inspire confidence that the developer is a real pro.

gStrings' settings

"Optimize For"

However, buried within those options is one called “Optimize For,” with the very scary-sounding description of “select an optimal target frequency range.” After you click on it, it gives you a choice between violin, viola, cello, double bass, guitar, and ukulele, with violin as the default.  When I discovered this, I was surprised.  I figured that, if anything, the guitar would be the default – everybody and their dog plays the guitar, but almost nobody plays the violin.  Also, who in their right mind would actually click on this option in the first place?  The only reason I discovered it myself is that I was evaluating my purchase of gStrings, and I wanted to see the differences between the premium and the free version.

Unfortunately for users of gStrings, this is exactly like my Black/White situation.  Everyone is going to assume that the default setting is guitar – if they even imagine that such a setting exists.  And nobody is going to cuddle up and read the settings menu, slogging through wordy descriptions like “shift target frequencies e.g. by redefining A: 440Hz -> 443Hz,” to figure out if they should change it.  I’m sure if the developer of gStrings did a random survey of 10 users, he or she  would discover that 7 of them play the guitar, but 6 of them have their app set on violin.  The other 3 users play the ukelele, the cello, and the violin, but none of them managed to find the “Optimize For” setting at all. So only two lucky users get to actually have the setting that’s right for their instrument.

Now that I’ve read Joel Spolsky’s book, I’m starting to see dumb programmer mistakes in every app I use.  Descriptions that are too long and complicated. Unhelpful popups that interrupt the workflow. Optimizing for edge-case usages (like searching by regular expressions), while ignoring common use cases (like just punching in a single letter and searching by the first character).

Searching logs in Catlog. Just start typing and it filters as you go.

Searching logs in aLogcat. Hit Menu, hit Filter, then get a free lesson on how your regular expressions need to conform to Java.

I’m starting to see it in my own apps as well, which is especially frustrating, because I had no idea I was making such elementary mistakes. The most egregious of these is probably App Tracker, which is so bad it deserves a post of its own.

Well, from now on at least, I’m going to work to make simpler, easier-to-use UIs for my apps. Hopefully it will result in a better experience for my users, because they are are all idiots. Just like me.


Get every new post delivered to your Inbox.

Join 568 other followers