Archive for the ‘Technical’ Category


Presentation: Finding & Fixing Mem Leaks

Last Friday I gave a talk at FITC Mobile 2010 called “Finding and Fixing Memory Leaks in iOS Apps”. As promised during the presentation, I’m making both the slides and code from the presentation available. You can read the presentation slides on SlideShare:

The Menu button in the bottom left will allow you to view it fullscreen, if you wish. It can be downloaded as a PDF if you click “view on SlideShare” and click the “Download” button at the top of the presentation.

When you get to the code part, you can download the sample project here:

http://www.streamingcolour.com/presentations/memLeakExampleProject.zip

Note: The code and sample project are distributed under the MIT License. See the README inside the zip file for details on what that specifically means, but basically you’re free to use the code however you want as long as you keep the copyright notice and don’t blame me for anything. 😉

I hope those of you who attended the talk found it useful.

Update (2010-09-21 – 5:44PM) – If you’re not familiar with the Leaks Instrument tool, have a read through my tutorial on how to use it. I demonstrated how to use the tool during the session, but there were no slides for that part: Tutorial: Tracking iPhone Memory Leaks with Instruments

Owen


FITC Mobile 2010

Can you believe it’s September already? Where did the summer go? Here in Southern Ontario we didn’t even get a transition; it was 33C one day, then two days later it was 12C. Anyway, I digress. With fall comes back to school (for those still in school), and the start of a new season of conferences!

FITC Mobile 2010

I’m going to be speaking at FITC Mobile in Toronto, running Sept 16-18, 2010. I’m giving a talk on memory leaks in iOS on Friday the 17th, from 12:00-1:00pm. Specifically, I’ll be talking about memory management, what a memory leak is, some common ways they’re introduced in iOS programming, and show you how to use the tools to track them down and fix them. If you’re an iOS programmer and you’re coming to FITC Mobile, I hope you’ll check out my talk. Bring your coding hat, though; I’m going to be showing code, and actually demonstrating stuff in Xcode.

I hope to see you there!

Owen


LandFormer Postmortem

A couple of months after I launch a game, I like to sit down and take a hard and honest look at the things that went right and the things that went wrong: a postmortem. It’s a great exercise to go through after a game is launched to learn from your successes and, more importantly, your mistakes. I wrote up a postmortem after launching Monkeys in Space that was based on the structure that Game Developer Magazine uses. I’m going to use that same format for this LandFormer postmortem.

Introduction

If you haven’t played the game, LandFormer is a puzzle game for iPhone/iPod touch. Each level is made up of a 5×5 grid of terrain at different heights (oceans, up to mountains). The goal on each level is to use land forming tools to modify the heights of the terrain tiles to flatten things out. It’s a challenging game that starts off very easy, but get quite difficult in the harder levels. It’s a game that requires skill, patience, but most of all, intuition.

The game is free to download and try (there are 12 levels currently in the free version of the game), with In-App Purchase (IAP) available to upgrade to the “full” version of the game, as well as IAP for additional visual themes and additional levels. I think of it like a demo, where the user gets to try it and then decide if they want to spend money on more levels. The free version also contains ads, which are disabled if the player buys any content from the in-game shop.

The game launched on June 29, 2010 and has had 147,000 downloads of the free version of the game so far.

What Went Right?

1) Gameplay

I’m really happy with how the game itself turned out. LandFormer started as a prototype called “UpDown” that I did in 6 hours at the all-night GameJam for 360iDev Denver in September, 2009 (I participated via Skype). After I launched Monkeys in Space, I returned to the prototype in early 2010 and started playing around with ways to make it more fun, and settled on the terraforming theme, which helps players understand what they’re supposed to do, and why.

What I like most about the game is that I haven’t really seen other puzzle games like it. It’s similar in play-style to sliding block puzzle games (it requires a similar combination of spatial reasoning and intuition), but the up/down movement of the pieces makes it feel very new and requires new ways of thinking. It’s also very easy to learn how to play, but takes time to really master it and get good at the more difficult puzzles. In the end, I think the gameplay stands as being strong, and I’m very pleased with how the game turned out.

2) Strong Launch

This is my 3rd game, and thus my 3rd game launch. However, with LandFormer I decided it was time to try a new launch strategy. With my previous games, I launched the games as soon as Apple approved them. This caused all sorts of problems in terms of getting press materials out, and reviews trickling out gradually. With LandFormer, I decided to set a proper release date. When Apple approved the game, I set the release date for a week and a half into the future. I immediately sent out press releases to sites along with promo codes (yes, they work once the game has been approved, but before it’s available in the store) for press to try the game. Because my content is all IAP on my server, I could also make it available to the press for free during the pre-launch review period. Very handy.

The result of this new launch strategy was that several large review sites had reviews out within one or two days of launch. This helped pick up momentum for the game, then the first Thursday after launch Apple featured it as a Hot New Game. The Friday immediately after the feature, Gizmodo ran a review of the game, which boosted downloads tremendously for the following weekend.

I really couldn’t have asked for much better a launch. The only way it could have been better was by getting a front-page feature, or App of the Week feature from Apple. They’re probably just saving that for my next game (har har).

3) Free + IAP

As all developers do, I struggled a lot with the pricing model for the game. My other games are both paid games, but Dapple has a separate Lite version for players to “try before they buy”. The thing I don’t like about the Lite model is that it requires players to download two separate apps if they then want to buy the game. It always felt kludgy to me. Ultimately I decided to set things up like a PC or XBLA demo: free to download it, but if you like it, buy the full upgrade from within the game. This is the really exciting monetization path that IAP opened up when Apple introduced it.

Because I was implementing the in-game store for this anyway, it also allowed me to developing a theming system for the game and sell themes. It also means I can continue to release new level packs for users without having to update the game itself.

I think the model has a lot of potential on the app store. The free download gets you maximum visibility on the store (people are willing to download something just because it’s free), but then you have a way to earn some money within the app. However, it’s not all rainbows and unicorns: see the corresponding section in What Went Wrong.

4) Level Editor

When I started building the game, I was building levels as string of data then loading them into the game and testing them. This was ridiculous. I realized early on that building a level could be seen as solving a level in reverse. I was able to very quickly build a first pass at a level editor just by reversing the rules: start with a flat plane, and use the tools to deform it. This had two advantages: 1) it made building levels much easier, and 2) it meant that any level created in the level editor was guaranteed to have a solution.

Once I had it working for my own purposes I decided that it needed to be available to players in the game. The level editor is so easy and intuitive to use, I need people to be able to play with it. I’m happy I took the time to do the UI work required to build the level editor out into something that everyone could use.

The editor allows players to create their own levels, but beyond that, I implemented a sharing system based on URLs, where players could email a level to a friend. The friend clicks a link in the email and the level opens inside their copy of the game for them to play. It’s a simple system, that I think works quite nicely.

5) Doing Everything (Almost)

Since Monkeys in Space, I’ve been doing everything except the music in my games by myself. For both Monkeys and LandFormer I did all of the game design, programmer, artwork, UI design, sound design, PR, and marketing. I don’t do music, because that’s just something I’m not capable of doing myself. However, doing everything myself has given me a lot of freedom to make the game exactly how I want to make it. It also allows me to think about how a change will impact all the various aspects of the game. And, perhaps most importantly, it allows me to save a huge amount of out-of-pocket expense. I would love to have the funds to pay a full-time artist to work on the game, but that’s just not in the cards for me yet. I do have some art background, but doing all my own art for these games has helped me get a lot better than I was. I hope I’ll continue to improve. However, this is also another one of those things that also appears on the What Went Wrong section. So let’s get to that now.

What Went Wrong?

1) Free + IAP

I listed the reasons why I thought Free + IAP was great for LandFormer, but it’s also something that didn’t work great. One thing I was not at all prepared for was a backlash from users over the pricing model. I thought that players would be happy that they were given an opportunity to try the game before spending any money on it. However, the reaction from a lot of players instead was “The game says it’s free, but you have to buy stuff!” I got called a cheat, a liar, and a con artist.

My immediate reaction was that my app description clearly states that you only get the Beginner levels for free and have to buy the others. The app page in the store also lists the top IAP. But what I learned is that no one reads that stuff. I think I got a lot of downloads (especially after some of the big press stories ran) from people who saw the name, the icon, and “free” and downloaded it.

The problem is that there’s a disconnect between my view of the pricing model, and that of the minority of angry, vocal, app store consumers. I saw: “LandFormer offers you a way to try the game for free, and if you like it, buy it.” That customer sees: “Hey, a free game!” And then is angry when they discover they can’t play all the levels for free.

In the end, I’m not sure if the pricing model I chose for LandFormer was the right call or not. I’m not convinced that I wouldn’t have made more money by distributing a Lite version and a separate paid version (or only a paid version). App Store customers have gotten used to that model. I think it’s a problem with the fact that IAP didn’t exist from the start. Users had a year to get used to a certain business model, now we’re trying to change that. It’s going to be a difficult transition.

Not to go on about this for too long, but I think the Free + IAP model works best for games where you’re giving away a complete game for free, and then selling IAP for additional content that’s not required. If I ever do another free game, I’ll be looking toward that model.

2) iOS 4 + Multitasking

Apple launched iOS 4 on June 21, 2010, 8 days before I launched LandFormer, but 2 days after Apple had approved it. I had time with the beta SDK to make sure the game didn’t crash and that the game could be put into the background and restored properly before shipping it. However, I spent a great deal of time over the next 3 updates fixing weird little issues that cropped up because of iOS 4 multitasking. Multitasking caused all kinds of problems with my level sharing system, as well as my save system. I believe there was also one crash that only showed up in iOS 4 because of a change in the way some touch events fired. I’m not blaming Apple, it was just bad luck on my part that I launched so close to iOS 4, and I couldn’t afford to delay the launch of the game any more to deal with all the little issues that cropped up.

3) Ad Network

I mentioned in the introduction that I decided to include ads in the free version of the game. This is in this section for several reasons. At the peak of LandFormer’s popularity, it was being downloaded about 12,000 times per day. This translated into about 50,000 ad impressions a day. However, my click-through rate (CTR) was abysmal. It turned out that the way I was loading ads meant that a lot of people never saw the ads I requested. On my best day, I made about $5 off of ads. In the first update to the game (v1.1) I released a fix that made sure that ads were displayed properly to users. However, by the time it was approved I was down to a few hundred downloads a day of the free game. Even though my CTR increased dramatically with the change, my earnings averaged out around $0.30-0.40/day.

On top of that, the ad network I used had a crash bug in its code. After a couple of weeks trying to help them track the problem down, they told me they weren’t going to look into it any further. I was getting several support requests a week from players about this crash, so ultimately I pulled their ad network out of my game and I wrote my own custom system.

The game now (in v1.1.2) pulls ads of my own server. This is cool for several reasons. Now I get to decide what ads get shown in the game, it means I can cross promote my other games, and it means that I can promote games that I actually buy and play. I use LinkShare to get a small royalty any time someone actually buys through this system, but that’s been next to nothing so far. Still, I’d rather help support developers whose work I respect and have no crashes, than get the $0.30/day but with 10% of users experiencing a crash every time they launch the game.

4) Themes

When I built the IAP system I was very excited to be able to sell themes (skins) for the game. The way I had set up the graphics engine meant that it would be easy for me to load different textures to change the look of the game. I thought players would like the chance to be able to customize their experience a bit more too, but I was wrong. I’m seeing about a 0.1% conversion rate on themes (i.e. about 1 in 1000 people download a theme).

At this point, I only have one theme for sale. So it could be that people just don’t like that theme. It could also be that people just like the default art more. Or it could just be that people really don’t care about theming this kind of game. Though, if you think about it another way, if 1 in 100 people buy the premium content, the users who would buy a theme are probably a subset of that 1 in 100. So that means about 1 in 10 of those people have bought the theme, so maybe that’s ok. Still, when you do the math, that’s about $100 made off the theme so far, and it took almost a week of art work to build it (not even counting the time it took to put the theming system in place). When you look at it like that, it’s not as worth it.

I’m currently working on another theme. If it doesn’t sell, I probably won’t be releasing more themes. I think themes would sell better in a game where you could play the whole game for free. I think people might be willing to buy a theme in that case.

5) Doing Everything (Almost)

I’ve already outlined why I thought this worked for the project, but doing everything by oneself also comes with some big downsides. The biggest is time. LandFormer took 5 months from start to launch (then another month of work after launch). I’d guess that at least 2 months of that was doing the artwork and UI design for the game. If I could have afforded to pay a professional artist to do that for me, they probably would have taken half the time, and they could have been doing it while I programmed.

The other big downside is not having someone to bounce ideas off of. Working with an artist allows you to brainstorm, to try new things, and play with the concepts in the artistic direction of the game. When you’re doing it all yourself, it’s easy to get caught in the trap of just doing the first thing that comes to mind. It’s hard to force yourself to try multiple things and to find the best artistic solution to a problem.

Conclusion

In the end, I’m extremely pleased with the way that LandFormer turned out. I think it’s my strongest game to date. The game was also an opportunity for me to experiment with several new things I’d never tried before: IAP, free games, ad-supported games, and user-created content and sharing. I’m very happy with the number of free downloads the game has had. I find it absolutely amazing to think that almost 150,000 people have downloaded my game! At the same time, I’d be lying if I said I was happy with the conversion rate I’ve seen from free to paid.

The game continues to get a couple hundred downloads a day, and it seems to have stabilized there. I hope that it will maintain this level (or higher) for quite some time. The fact that it’s free seems to help keep the downloads alive.

Every game is an incredible learning experience, and I’ve learned a lot in making and launching LandFormer. I’ll be continuing to support it and add new content, but I’m also looking ahead to what’s next. Onward!

Owen


The Xcode Expressions Window

Last week I asked folks on twitter whether they’d like a tutorial on using the Expressions window in Xcode for debugging. Many people replied that they’d never heard of it, so I decided it was probably worth doing.

I’ve just added the tutorial over on the Tutorials page: Using the Expressions Window

The Expressions window is a powerful debugging tool available in Xcode that allows you to evaluate expressions or even call methods on your objects while stopped at a breakpoint in your code. Check out the tutorial for an introduction to some of the cool things you can do with it.

You’ll also noticed that I added a new page in the sidebar for Essays. I’ll group blog posts related to art and video games under that page. Right now there’s just one from January of this year, but I’ve been working on a new one that I hope to have up soon.

Owen


Custom App URLs

Last week on twitter @mysterycoconut posted a blog post about his cool web-based level editor and that kicked off a discussion about us bloggers wanting to post more regularly to our blogs. With that, #iDevBlogADay was born and I’m happy to be a part of it. Each day of the week there are two iPhone developers blogging about whatever they want. The rules are simple: post a blog article on your day, or you’re out. I’ve been assigned to Mondays, so this is my first post because of iDevBlogADay. You can see a full list of participants in the right sidebar of the site. You can subscribe to an aggregate feed of all posts here: Group RSS Feed.

Have you ever thought “I wish there was a way to click a link in an email and launch my app…” Well there is, through the magic of custom app URLs. The basic idea is this: register a custom URL protocol with the iPhone, and if someone clicks a link with that protocol on that device, it will launch your app. But wait, there’s more: because it’s a URL, you can pass parameters into the app on launch. If you’re a C programmer, this is like being able to pass command line parameters into the application as an argv list.

I first started looking into this in detail while working on LandFormer. In LandFormer, I wanted a nice and simple way for users to share levels they had created without having to use a 3rd party social gaming system or Facebook. I started looking into custom URLs and discovered it could do everything I wanted. Using these URLs, I can encode a level’s data as a URL, embed it in an email, and let the user send an email to their friend. When the friend opens the email on their iPhone and clicks the link, LandFormer is launched, it parses the URL, and loads the level. It’s simple, elegant, and it’s easy to set up once you know where to look. So let’s do that now.

Define a Protocol

The first thing you need to do is decide on a custom URL protocol for your app. Choose something that other apps aren’t going to use. Don’t pick http, because that’s already taken. Pick something related to your app name, or website URL (e.g. “myAwesomeApp://”).

Once you’ve picked your custom protocol, you need to tell your app to register it with the phone. You do this through the app’s Info.plist file. Open the plist file in Xcode. Add a new row of type “URL types”. When created it will contain one item by default, “Item 0”. Expand Item 0 and you’ll see one element inside called “URL identifier”. This is an identifier that must be unique. Use the reverse domain naming system that Apple recommends (e.g. “com.mycompany.myawesomeapp”). Now add a new item to the array under the URL identifier row. Set the new item to “URL Schemes”. This creates an array with one item in it, “Item 0”. Set Item 0’s value to be your custom URL protocol (e.g. “myAwesomeApp”). Save the plist.

Setting up the custom URL in the Info plist

Great! Now you’ve told the iPhone that when a URL starts with “myAwesomeApp://” that it should launch your app. If that’s all you want to do, you’re done! Go have a soda. However, this method allows us a lot more power over how we launch the app, so let’s see what we can do with it.

Handling a Launch URL

When your app is launched with a custom URL, you have access to that string when the app launches. This means that you can take different launch actions based on what’s in that string. Let’s take a look at how to do that.

Right now in your app you probably have a function in your app delegate that looks like this:

- (void)applicationDidFinishLaunching:(UIApplication *) application
{
    // Do some launch stuff
}

That’s the application where you’d set up your connections between your window and your root viewcontroller, etc. However, in order to handle that custom URL, we need to handle things a bit differently. There are two options.

1) Leave your code in applicationDidFinishLaunching: and handle the URL in a later call to application:handleOpenURL:

2) Replace your applicationDidFinishLaunching: method with application:didFinishLaunchingWithOptions:

[EDIT (2010-07-30): As Jerrod pointed out in the comments below, if you want your app to handle URLs when your app is in the background in iOS 4, you must use handleOpenURL. When an app regains focus because the user clicked a custom URL, you will not get a call to application:didFinishLaunchingWithOptions, but you will get a call to application:handleOpenURL.]

I’m going to talk about the 2nd method, since I’m assuming we’re in a situation where we want to set up a different initialization sequence based on the URL passed in. So lets replace our applicationDidFinishLaunching: method with this:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Do our launch stuff here now
}

Notice that we now get an extra parameter passed to us in the form of an NSDictionary of launch options. One of these options is our launch URL, so let’s fish that out:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Get our launch URL
    if (launchOptions != nil)
    {
        // Launch dictionary has data
        NSURL* launchURL = [launchOptions objectForKey: UIApplicationLaunchOptionsURLKey];
 
        // Get the part of the URL after the ://
        NSString* queryString = [launchURL query];
 
        // Escape the string
        NSString* escapedQuery = [queryString stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
 
        // Parse the URL string
        ...
    }
 
    // Do our launch stuff here now
}

So all I’ve done there is grab the URL out of the dictionary. The call to [launchURL query] grabs the part of the URL after the ://. So if the URL was:

myAwesomeApp://?myString=test&myInt=0

then calling -query on the URL returns:

myString=test&myInt=0

The call to -stringByReplacingPercentEscapesUsingEncoding will convert all the URL-safe characters (like %20 for a ‘space’ character) back into the proper ascii char (or in this case, UTF8 char).

Parsing the data can then be done with your favourite parsing method (in LandFormer I used NSScanner to parse each element). You could also parse the data and store the vars into an NSMutableDictionary so that you could then do key-based lookups on the data.

After that, it’s up to you how you want to use that data. You can make decisions about how you want the game to load.

The LandFormer Example

To put this into perspective, the LandFormer URL looks like this for a created level that someone is mailing to a friend:

landformer://?title=Over%20The%20Hills%20And%20Mountain&moves=13
    &level=3343333333141222311002000
    &check=13F24CFE848198A8BDB8196494904B16

So you can see that the URL is made up of 4 variables: title, moves, level, and check. The check is a checksum done on the data to make sure that the URL hasn’t been messed around with (so as to stop players from sending their friends impossible levels). The rest of the data is self-explanatory.

When the game loads, if a URL is found, it parses the data to get all the information it needs to load that level, then lets the user start playing the level. So if the user has loaded the game directly from clicking on a link, they aren’t taken to the Main Menu, they’re taken straight into the game so they can play their friend’s level.

Cool Side-Effects

One of the really cool side-effects of this method for sharing levels is that these links work from inside a web browser, email, or even a twitter client. So if someone creates a level, sure, they can send it to a friend via email inside the game. But, they can also collect level URLs they’ve created and create their own level packs by posting the links to their website. Then anyone can click those links to play their levels. They can also share the links on twitter, and anyone browsing using an iPhone twitter client (who also has the game), can just click the link to download the level. The possibilities are endless!

Another cool potential use for this would be to allow you to pass data between two of your own apps. Say you make a new game. You could register a custom URL protocol for it, then add a special link inside your old game that allows users who have that game to click it to unlock something in the new game.

A Word on Error Handling

So far everything I’ve mentioned is all of the “look how awesome this is” variety. However, it’s important to mention code security. Any time you allow the user access to data that affects your game, you need to be careful. When parsing the URL coming into your app, make sure you’re handling failure cases well. You don’t want your app to crash if someone starts messing around with the URL manually. You don’t want to give them access to your app’s memory. Be careful with how you parse that data, make your error checking and handling robust, and you should be fine.

Now go have fun!

Owen