Tomorrow

Tomorrow is the day I’ve been working towards for the last 15 months. The day Terrella will finally be released on the App Store. I’m nervous of course. For the usual reasons, but also because of the decisions we made with regards to trying to monetize this thing.

I first had the idea for Terrella back in May of last year. Actually it was called Fours back then, but before I could finish, this little game called Threes came along. You may have heard of it. Anyway, it wasn’t long after we had a proof of concept that we started talking about pricing. For a while some of the gameplay was even being driven towards making a buck instead of a great game. We talked about expansion packs, consumable power-ups, features that you could unlock, advertising, all of it. It wasn’t long before we decided, look, let’s just focus on creating the kind of game and experience that we want, and worry about how (if) we can make money with it once we’re done. This is almost certainly contrary to the way the big name game studios go about designing games these days. Many big name studios employ psychologists to help craft compulsion loops designed to extract the maximum amount of money possible from their players. It seems to be working, but it’s not the way I wanted to do things.

Instead we ended up with a game that makes the majority of the content free, has no advertising at all, and charges $0.99 for a single expansion set that includes 12 additional levels. The other 18 single player levels are free. The multiplayer levels are free. The only power-up we have, Boost: also free. The levels can also be played in any order. No need to bother completing the prior level or making another IAP for this privilege as some games do.

Even with the name, we could have stuck with Fours and maybe gained some exposure from people looking for more games like Threes, but it didn’t feel right especially having read this. Although the game is nothing like Threes I felt we needed to change the name, though I really truly hated to let Fours go. We kicked around a series of uninspired names until one day, while reading up on magnetism, I stumbled across the wikipedia entry for Terrella and it seemed perfect. Little Earth. Now you know how Terrella got her name.

But back to the whole money thing. Not going to lie, I wouldn’t mind having a big pile of money to roll around in, but my expectations have always been tempered when it comes to my independent work, even before some of the posts that went around last month. However I hope that there are some gamers out there who, even if they don’t believe Terrella is a great game (bias alert: it is), might consider plunking down their $0.99 for the single IAP just on principle alone. That is, a vote for more games that take this approach. And who knows, maybe Terrella does take off and others can look towards it as an example that maybe you don’t have to nickel and dime your customers to death to have a successful game/app.

Anyway, I just wanted to toss those thoughts out there this evening as I wait for the countdown to reach zero. And, whatever happens, this has been an amazing journey and I’m anxious to finally have a chance to show you all how Terrella turned out.

Soon

A couple days back I posted a message to Twitter and Facebook that was just the word “Soon” followed by a link. If you didn’t follow the link, and maybe even if you did, you might not have understood the significance.

(this next bit is pretty close to what I posted earlier this morning on Facebook)

I was talking to my sister about Terrella this morning and she had no idea what I was talking about. If my sister doesn’t know then it’s a good bet the rest of you don’t either. I’d like to think I’m a pretty good software developer, but P.T. Barnum I’m not. So here’s the deal, for well over a year I, with a lot of help from my wife (Susie), my cousin (Bill), and so many other awesome people, have been working on a game for iPhone and we’re going to release it next week! Wednesday to be exact. If you have an iPhone we would love for you to check it out. In the meantime, here’s a little teaser I made.

What Am I Doing Again?

Two and a half years ago, when we started Quiet Spark, it was just supposed to be a hobby that my wife and I could work on together and, if we made a few bucks along the way, great! We went into this knowing full well that we were unlikely earn enough to become our primary source of income, much less anything approaching “rich”. And that’s pretty much how things have worked out… except, I can’t decide if it’s worth it anymore. At least not the way I’ve been doing things. It’s one thing to understand that an App Store success is a long shot, but when you think about all the effort involved, the sacrifices made, just the headache of dealing with taxes for god’s sake, it’s hard to not second guess yourself. All this for the chance of earning a customer’s $1.99 and/or 1 star review complaining that the app did not make them a sandwich. It’s hard to not get a little discouraged no matter how well you’ve tempered your expectations.

In addition I started Quiet Spark with the notion that I’d be able to write what I wanted, how I wanted. For whatever reason my brain has decided that each new app must be bigger and better than the last. That’s not exactly the perfect recipe for success in the App Store these days, except maybe the better part. Although a quick glance at the top charts may leave you second guessing that assumption as well.

Our first app, Super Speller has been far and away the most successful. Although when I say “success” we’re talking about an average of ~$1,000 a month over the last 2 1/2 years. From initial commit to initial release was roughly 1 month of work. Of course we’ve continued to update and improve Super Speller, but it was a project that was easy to work on in my spare time.

The second app, Goalposts, went from initial commit to release in roughly 5 months and has been, there’s just no other way of putting it, a magnificent failure. The biggest mistake was trying to be all things to all people and ending up serving none particularly well. If I’d given myself time to examine both the response to Goalposts and the trend towards smaller more focused apps I might not have had second thoughts before starting the next project. But I jumped on the next thing almost as soon as Goalposts was approved.

Our next app has been in development since May of last year and we should be ready to submit it for Apple’s approval very soon. This time around I’ve written a game. So, not only was there an app to develop including the art, sound effects, soundtrack, etc, but hey while were at it I’ll need an OS X based level editor to create all of the levels. And some of the levels were nearly as much work as a single app. It’s been a marathon. Remember, I’m doing this in my spare time, generally early in the morning before I head in to my “real” job and on weekends. And while I am really pleased with the results, there’s no doubt that it’s had an impact on the rest of my life.

I’m not really sure what to expect when Terrella is released. It seems that it’s an easy game to learn but hard to understand. It’s a bit thinky. It can also be a bit frustrating and may make you want to break your phone and/or punch the developer. And it also has very little to do with Kim Kardashian, so we’ll just have to see what kind of traction it gets in today’s environment.

So, as things wrap up I’d already been thinking I need to take a step back and figure out how I want to manage Quiet Spark development going forward. And this afternoon I see this post by Jared Sinclair where he talks about the difficulties in earning a living on the App Store and it really resonated with me. With a full time position to fall back on, I’m not under any pressure but my own to succeed or fail. I can’t imagine trying to make a go of it full time. There are ways to do it certainly, but do those ways exclude more complex apps or those not willing to resort to riddling an app with an assortment of in app purchases or losing focus on quality? I’m not sure at this point.

Your App’s Not As Fast As You Think

It was all going so well. Until suddenly it wasn’t.

I have an app that started as a experiment. A toy. It eventually evolved into a full fledged game. Because it started this way it was built using things I know well. Specifically CALayers and other assorted Core Animation goodies. Despite reading the occasional warning that I should be using OpenGL ES or one of the many 2D game engines, I pressed on. After all, periodic spot checking of performance revealed no issues. In fact the frame rate was great and I appeared to have plenty of headroom. Plenty.

Actually, I did at one point decide to create a small test app just to see how OpenGL might perform in comparison and was surprised to discover that it seemed to require more CPU. Seeing as I was fairly ignorant about OpenGL I chalked this up to Apple doing clever things to somehow optimize CA in certain situations. “Lucky me!”, I thought!

So I pressed on. At the start of development my primary phone was an iPhone 4S. Later I upgraded to a 5s, but continued to test on my old phone and all seemed well. Then I tried it on my son’s iPhone 4. That’s when the trouble started. The game, which was buttery smooth on my device, was unplayable on the 4. Granted the iPhone 4S offered a big boost in performance over the iPhone 4, but was it really that big of a difference?!

I fired up Instruments to get to the bottom of the problem and Instruments told me… everything is fine. CPU usage was maybe 30-40%. Graphics device utilization fine. Everything’s awesome! And yet clearly it wasn’t. What the?

On a hunch I decided to use the Activity Monitor in Instruments to look at CPU usage for all processes and discovered that backboardd was using ~70% of the CPU.

So what the hell is backboardd and why does it hate me?!

Google says backboardd is primarily responsible for event handling in iOS but it’s also seemingly responsible for doing much of the heavy lifting required by Core Animation. Remember back when I mentioned how my OpenGL experiment seemed to indicate it was slower than Core Animation? Well that’s because I was only looking at half of the picture.

So at this point I have a big problem. I suppose I could somehow limit support to iPhone 4S or newer and it would appear to run fine, but I’d be releasing an app that I now know to be fantastically inefficient. Or I can completely replace my rendering engine (such as it is). I decided to break down and learn Open GL ES. I could have also looked at Cocos2D or Unity but I’ve had “Learn OpenGL” on my todo list for far too long and I really want to understand what’s going on at the lowest levels. Mmm, shaders.

This was all not quite three weeks ago. At that time, on my iPhone 5s, the most complex level was using roughly 35% CPU while backboardd used 70%. GPU device utilization was around 10%. Since then I’ve learned enough OpenGL to be dangerous and replaced most of the Core Animation with my own rendering engine. I’m not quite finished and there is still tuning to do, but now I’m seeing about 40% CPU usage and 20% GPU utilization. Using more of the GPU is actually a good thing since I’m offloading work from the CPU that the GPU can perform more efficiently. Meanwhile backboardd has dropped to about 15%. Yeah there are still some lingering CALayers laying about that I’m not easily able to rid myself of yet.

So the takeaways from all this:

  • Really, seriously, spot check performance on all the devices you plan to support and don’t assume. My assumptions were based on an incomplete picture of performance data.
  • Keep an eye on CPU usage of all processes when running performance tests. With only one app visible at a time it’s easy to forget that your app doesn’t have the whole place to itself and needs to play well with others.
  • Pay closer attention to those that have gone before you. I read many times how Open GL or a purpose built 2D rendering engine was the way to go but shrugged it off. I should have tried harder to discover why my results seemed so much better than expected.
  • Open GL ES and Xcode’s Open GL analysis is pretty nice. I wish there were a Core Animation counterpart.
  • Don’t write a game next time.

Analytics and Logging Ideas

A couple weeks back I threatened to start making more regular posts. This is a threat I make from time to time and sometimes, like now, I actually follow through with it. In that same post I also alluded to some of the ways I’ve been using Parse and Dropbox while developing my game and that’s what I wanted to write about today.

First, Parse. I just want to touch on it briefly. Parse is primarily used to store / sync your app’s data in the cloud but offers an assortment of additional features to make things like push notifications and in app purchase easier to implement. It does these things well, but I’m using the data storage mechanism to create custom analytics. Parse encapsulates arbitrary key-value pairs in PFObjects which can be easily pushed up to their servers in near real time assuming you have an active network connection. Okay so perhaps this is an obvious use case, but I’m using PFObjects to note an assortment of information about each level that’s being played in the game I’m working on. It’s super easy to add a name, score, game-time, wall-time, result, etc., etc. to an object and store it for each attempt made on a level. I can then filter and analyze these results using their dashboard and see how long it takes a player to complete a level, or if they’ve giving up, got killed, etc., etc. Whatever information I feel is valuable is stored and easily accessible as I iterate over game and level design. Very easy to use and extensible. Plus it’s free (up to a point). Free is nice.

Okay next I really wanted to talk about how I used Dropbox to enable logging from multiple devices. So my problem was this: I needed to debug several devices simultaneously and it’s a bit of a pain to do this in Xcode especially when those devices may not be in the same room / city / state. I think TestFlight and maybe some others offer remote logging but these solutions weren’t exactly what I needed. Specifically I needed to start a multiplayer match with N-players and have an individual log created by each of the players in the match and deposited in a central location so I could reconcile any differences between them. I also needed this information as soon as the match completed.

It turns out that I was able to use Dropbox to do exactly this. I put together a demonstration project on github that you can grab and follow along if you like. Once you have that, head over to dropbox’s developer page and add a new app. Set up your app using the Dropbox API with Files & Datastores limited to its own private folder. I called mine QSLog. I don’t think you can reuse that name but if not it doesn’t really matter. Call it whatever. The important bits are the App key and App secret that you’ll find after you create the app. Copy those values and update the corresponding defines at the top of QSAppDelegate.m. Also replace db-appkey in QSLog’s URL Types with db-whateveryouractualappkey is. So far we’re pretty much following this basic Dropbox tutorial.

At this point you should be able to compile and run the app from Xcode. When you do, it should present you with a Dropbox connect screen. Log in and then check the console in Xcode for the User ID, accessToken, and accessTokenSecret. Take these values and again update the corresponding defines at the top of QSAppDelegate.m. Lastly change line 18 QSLog-Prefix.pch to #define HAVE_DROPBOX_TOKENS 1. Recompile and run the app again. Tap some of the Log Event buttons. When your ready tap the Upload / Reset button. That should upload a history of the button presses and reset the log. You should have a folder for your app in your Dropbox/Apps folder containing this log. And you should be able to run this app from any device and have the logs appear in the same folder.

Voila! Which is French for… Ta Da!

Okay a couple final thoughts. First, you really don’t want this in any shipping code. Actually I’m not even sure you want it in test code for an extended period of time. And second, the logging class in the sample project is really simple and you’ll probably want to replace it with something a little better. This is just something I whipped up for demonstration purposes.