Chronicle Of A Failed Experiment

In the last year and a half, I’ve written about the different things that I’ve tried with Flower Garden and their effects on sales. From adding Facebook support, creating a free version, adding in-app purchases, or giving Flower Garden for free for a limited time. Some strategies worked and some didn’t.

Today I want to share my latest experiment, and how it was a total and complete failure: Adding the option to gift IAP items from within the game.

gift_this.png

Promo Codes

Before I can talk about how I implemented the “Gift This” feature, we need to talk about promo codes. Since Flower Garden has so many in-app purchases, I figured it would be very handy to have the ability to give some of them away to people for any reason: They mistakenly downloaded the wrong thing, they bought it in the free version and want to upgrade to the full one, or they supposedly paid for one but they never got it. Whatever the reason, having my own promo codes for in-app purchases was one of the best decisions I could have made. I would highly recommend it if you have IAPs, especially consumables.

The implementation of promo codes was totally straightforward. I have two tables in the Google App Engine: One for active promo codes and one for redeemed ones. The active promo code includes the code itself, the IAP item it refers to, the amount, and whether it’s limited to one user or not (if it’s limited to one user, the code goes away as soon as it’s redeemed, otherwise, any amount of users can redeem it).

Here’s an example of a code I just added (yes, feel free to redeem it in the Flower Shop):

promo_code.png

Whenever a promo code is redeemed, I enter that data in the other table. That way not only do I have a log of what codes where redeemed and when, but I can also check and prevent the same device from redeeming the same code multiple times.

Another important reason to keep a redeemed promo code table is that I want promo codes to be as valid as purchasing the IAP directly. That means that if you ever attempt to purchase an item, I check first to see if you’ve redeemed a promo code for it, and if so, you can re-download it for free. Same thing when you do a restore purchases (although I believe I haven’t gotten around to implementing that part yet ๐Ÿ™‚

Here’s my plea to Apple: Please, please, please, give us an “iTunes Account ID” along with the IAP data. Right now the best we can do is associate a purchase with a device (which is not good enough), or have a whole registration system for users (which is a pain and more time consuming for users). They’re already doing this with a Game Center ID, so why not with an iTunes Account?

Gift This

Once the promo code system was in place and field tested for a couple of months, I finally implemented the Gift This functionality. In the Flower Shop, users have the option to buy an item for themselves, or for someone else.

The first time you use the Gift This feature it explains how it works: You purchase the item and then you send it to someone else through email.

Under the hood, it purchases the IAP, contacts the server to generate a new promo code for that item, and then creates an email with the promo code and even a custom URL. Whenever someone receives a gift email, they can just click on the custom link and they immediately receive the item (assuming they have Flower Garden installed, of course).

gift_email.png

One interesting consequence is that to implement this, you need to create one new IAP item for every item you want to gift (especially if they’re not consumable). Otherwise, someone couldn’t gift an item they had already purchased, or they couldn’t gift it more than once. This can add quite a few extra IAPs in your list!

In the case of Flower Garden, I started with the easiest case, and I only implemented gifting for fertilizer purchases (because they’re consumable, so I don’t have to keep track of who receives them and restoring them).

Total Failure

I really had great hopes for the Gift This feature. I had already envisioned writing a blog post showing IAP revenue going up 20-30% because of that feature. Not quite! It was pretty much a complete flop. The only positive thing I can say about it is that it didn’t actually lower regular sales.

See for yourself. In a period of about a month and a half, all the fertilizer gifting in the free and paid versions of Flower Garden amounted to a whopping $191!

gift_revenue.png

Definitely not worth the 3-4 days it took me to implement it (and the opportunity cost of not being able to add some other feature or IAP).

Compare it to fertilizer sales during that period of over $7,000:

fertilizer_revenue.png

(That’s the spike of the new feature plus the Pocket Frogs cross promotion if you were wondering about it).

I’d love to know how the Gift This feature on the App Store is working out for Apple. I’m sure it’s doing better than my attempt at it, but I’m going to bet it’s still a very small percentage compared to regular sales.

Here comes the important question: Why was it a failure? Do people don’t like to gift? Was it presented badly? Did most people not know it existed?

There’s no way to know for sure, but my current guess is that people don’t like to gift something they don’t already own. Psychologically, there are several too many steps involved: Oh, I want to gift something, look for it in the store, purchase it, and send the email. Not a very fulfilling experience.

On the other hand, gifting something you already own is much more appealing. You have it in front of you, you’re proud of it and it looks great. You tap on a button and send it to someone. That is a lot more satisfying. So in the future I’ll take that approach and allow people to gift things they already own, even if they had to previously pay for it in some way.

What do you think? Do you have a better theory? How could it have been improved?

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

360iDev: The Conference You Can’t Miss

360idev.pngIt’s no secret that I like a good conference. Actually, I’m sure I can find something to enjoy even at a so-so conference. Each field has it’s big, ultimate conference: For games it’s GDC, for graphics SIGGRAPH, and for iPhone development WWDC. Those big conferences have the big announcements, the big crowds, and the big players. But the smaller conferences always have something a unique to them that the big ones can’t compete against.

I’m going to say this very clearly so it doesn’t get lost in the middle of a paragraph.

360iDev is the best conference you can go to if you’re doing any kind of iOS development.

There. I’ve said it. And no, they’re not paying me any to say that.

I’m clearly not the only one who feels that way either. Just earlier this week Mike Berg wrote a post about how awesome 360iDev is, and we didn’t even compare notes. Great minds think alike apparently.

Yes, Apple puts the big show for WWDC. It’s a unique experience: the keynote, the crowds, the unveiling of the latest technologies, the sessions, the labs… But in the end, it’s a big show from Apple to woo its developers. You’re getting the official message through very polished presentations. Which is fine, but it feels a bit… too polished. Too streamlined. Too overproduced.

Talk to developers who’ve been to WWDC multiple times, and you’ll quickly find out that the parts they like best are the labs (access to Apple engineers) and the networking (some with Apple, but mostly with other attendees). That’s why keeping track of the parties during WWDC is almost a full-time job!

For Developers, By Developers

360iDev on the other hand is a conference for developers by developers. You don’t get fed the official party line. Instead, you get to hear how some API really worked (or didn’t) in the trenches, how developers had to work around bugs, or, why not, how some technology was a dream to work with. Nothing like hearing it straight from the horse’s mouth.

Strong Game Development Track

There are usually three simultaneous tracks at 360iDev: Business, Sights and Sounds, and Development Tricks. As you can expect, sights and Sounds is usually entirely devoted to games, and there’s plenty of game-related info in the other tracks as well.

I’m going to be totally honest here: The quality of the sessions varies a lot from one to the other, and they can be somewhat hit or miss. When the presentations are awesome, they’re really awesome. And on the average, I’d say they’re very good. That’s the flip side of not having a super-rehearsed, super-polished presentations like WWDC.

Hacker Vibe

You walk into WWDC, and you get a very strong corporate feeling (trying to be developer friendly). The moment you walk into 360iDev, it has a palpable hacker vibe [1]. The people presenting might not have the most polished slides, but they can do some amazing things on the iPhone. There are even presentations on the internals of the iPhone and what’s going on under the hood, something you’ll never get from Apple!

Game Jam

As a perfect example of the hacker mentality, the Game Jam has become a regular feature at 360iDev. On the last night, developers get together in a big rooms, and either flying solo or grouping into teams, they create a game prototype in a few hours. The next day at lunch, we have a big gathering and get to demo the games created the previous night to everybody. What a perfect (and exhausting!) last day to the conference!

It’s Nimble And Agile

This might not seem like a big deal to some, but it’s very important: 360iDev happens twice a year. Technology conferences that happened once a year might have been fine 10-15 years ago, but as the pace of technological advance continues to accelerate, once a year doesn’t cut it anymore. Especially if you have to submit talk proposals 6-8 months in advance, they’re old news by the time the conference rolls around.

360iDev is much more agile than that. It happens twice a year, and you only need to submit a general overview a few months in advance. Given the content of a lot of the talks, they probably come together just weeks (if not days) before the conference itself. That’s part of the reason for the uneven quality of the talks, but it’s a price worth paying.

Networking

360iDev is a small conference. I don’t know the official numbers, but I think there are usually around 200-300 attendees. You’ll be seeing the same faces all three days, especially the ones that share your same interests and end up going to the same sessions as you do. Even if you’re a total introvert, you’ll end up meeting a bunch of new, very interesting people, and creating lots of new possibilities for your future.

Even better, the speakers are part of that small number of attendees, and they get to hang out with everybody else. There aren’t special VIP parties, or secret off-site invitation-only parties (if they are, they’re so secret I missed them). Everybody hangs out during the sessions, at lunch, and the evening festivities. So if there’s someone in the speaker list you particularly want to meet, this is your chance.

It’s not just other developers either. The iPhone media often comes to the conference as well, so you might get a chance to talk to people from TouchArcade or TUAW.

360iDev three full days of sessions, one day of tutorials, one night of game jam, three evenings or parties, and one conference full of awesome. And that for a fraction of price of the big conferences. How can you go wrong? [2]

[1] I mean hacker in the good sense of the word, not in the “cracker”, malicious one!

[2] If this doesn’t convince Gavin and Craig to come to 360iDev, I don’t know what will. Go buy the awesome Linkoidz so they’ll be forced to attend ๐Ÿ™‚

linkoidz-blog-banner.jpg

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Casey’s Contraptions And The IGF

casey.pngToday is the day! We finally announced my next game: Casey’s Contraptions.

This is a bit of a different project than some of my past ones. This one is a collaboration with Miguel รƒยngel Friginal from Mystery Coconut. I’m doing the programming, Miguel is doing all the art, and we’re both contributing equally to the design and everything else. It has been great having some awesome art to go with the game, but also to collaborate with someone really closely on the game.

Casey’s Contraptions was one of those ideas for a game that I kept wanting to make for quite a while, and now it was finally the right time. It meets the three main requirements that I’m looking for in a game project:

  • Something original
  • Has potential to sell well
  • It involves a creative activity (instead of something violent or destructive)

The idea of games based on mechanical contraptions is not new, but there are surprisingly few games based on it. We are hoping to bring a lot new to the table: Casey himself, unlockable items, interface built from the ground up for multi touch, modern physics simulation, social features, sharing of solutions, and even creation and sharing of new levels. We are really excited to be working on this project and we can’t wait until it’s released.

MainMenu.jpg

Development

Casey’s Contraptions started as a prototype back in the summer. After a day or two messing with physics engines and creating some objects, I knew there was something there, so I spent a two more weeks creating an initial version. It wasn’t much more than a tech proof-of-concept, but it was clear that there was a game there (even with my horrible stand-in clip art assets).

I sent that built to a couple of friends for initial feedback. It was laughably early, but that’s the time when it’s possible to really make radical changes to the design. I knew the people I was sending it to a) were used to seeing games at early stages, and b) were not afraid to tell me if something sucked. Actually, I told them to skip the nice parts and just focus on everything that they didn’t like. Not surprisingly, that initial feedback was crucial, and really shaped how Casey’s Contraptions evolved since then.

Shortly after that, Miguel joined me full time on the game and we dove right into it. For our development, we used a super light-weight agile approach: We have high-level “user stories”, and two week iterations. Iterations are somewhat flexible (plus minus a few days) and we don’t strictly estimate the tasks, just take on as many user stories as we think we can do in that time. The important parts are to always be focused on the most important stories, and to take them to completion each time.

Miguel lives in Seattle and I’m in Carlsbad, so we do all of our work remotely. We use Subversion hosted remotely, and we’re in constant communication through iChat and email. That allows us to iterate on a piece of art, an item behavior, or a menu item multiple times very quickly. It’s not as good as sitting side by side, but I haven’t felt like working remotely has gotten in the way at all.

After a busy month and a half, we got to where you see it today, and we submitted the game to the Independent Games Festival (IGF).

Screen1.jpg

Independent Games Festival

Some people have asked me why I wanted to submit it to the IGF. I have to be honest and admit that I had never really considered not submitting it.

I imagine everybody reading this blog knows about the IGF already. It’s the closest thing to the Movie Academy Awards that we have for independent games. There are many reasons why you’d want to submit your game. The amount of press and prestige associated with winning or even being nominated as a finalist is huge. The prize money is a nice touch, but it’s not really enough to make much of a difference in the game itself (I’m talking about the Mobile Category prize). Of course, there are many other fantastic games that are competing at the IGF (a total of almost 400 games!), so it’s hard to count on becoming a finalist.

One very real and concrete reason to enter the IGF was to have a very well-defined milestone. It wasn’t that different from one of our iterations, except that we had a real customer (the IGF judges) and a non-flexible deadline. That made us really focus our efforts and put in some extra effort in the last couple of weeks to get it in shape for the IGF. Looking back at the game just a couple of weeks ago, it’s amazing how far it came in that time.

igf.gifFor me personally, the biggest reason to enter the IGF is because it’s something I’ve always wanted to do. I’ve followed the IGF since the first one in 1999 (which was, coincidentally, the first GDC I attended). Every time I walked through the booths or watched the award ceremony, I wanted to be part of it. So finally, this was my chance to do it. It was a great experience going through the process. Now the next life goal will be to actually make it as a finalist.

Submitting Casey’s Contraptions had another, unexpected side effect: It tipped our hand and forced us to announce the game sooner than we were planning on doing. It wasn’t until a few days before the submission that we realized the list of IGF games would go public right away. Originally we were planning on announcing the game at 360iDev in mid November, but this forced us to move the schedule up somewhat. Hopefully that will be a good thing and will allow us to build some good buzz in the upcoming months all the way until the release. Keep an eye out for a gameplay video and some hands-on previews in the next few weeks.

If you want to keep up to date with Casey’s Contraptions development, join the Facebook group, follow Miguel and me on Twitter, or keep an eye on the Touch Arcade thread.

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Games, Resources, And XCode

Up until a few weeks ago, I never had any problems with iPhone game resources. I just added whatever I needed to the XCode project, and it was ready to load from within the game. That simple.

But that was because of the kind of games I was making, which were very light on content, with mostly procedurally generated assets (the consequence of working by myself and being much better at programming than at Photoshop).

That game that Miguel and I are working on right now is a lot heavier on assets. It has locations, and levels, and the whole shebang. And that’s where XCode starts falling short.

Explicit Resources

copy_bundle_resources.pngBefore, I was adding all my game assets to the Resources folder in XCode. That adds the file to the “Copy Bundle Resources” step. And as you expect, when you do a build, it checks the date of the existing file, and only copies it if the source file is newer than the destination file.

Personally, I really like this approach. I like to be explicit about what gets included in a game, and I don’t mind at all having to add files manually to the project.

Unfortunately, it has one major flaw: It collapses all assets at the root of the application directory, ignoring the directory structure where they came from. I have no idea what the rational is for this “feature”, but someone needs to be taken out to the public town plaza and whipped for that. Actually, make that a double-whipping session if the reason was “convenience”.

The reason this becomes a big deal now is that we have per-level resources. To keep things sane, we decided to use a directory hierarchy, so Levels/Level00 contains all the files necessary for that level. Same thing with Level01, etc. The problem comes that both those levels have similarly named files: Background.jpg Layout.bin, etc.

Any guesses what happens if you add to XCode two files with the same filename in different paths? Yup. One of them overrides the other. Not a single warning either. Let’s make that a triple-serving of whipping, please.

I briefly considered prefixing all the files with the level name (Level00_Background.jpg), but if later I decide to move Level00 to Level05 that’s a lot of files to rename, so I would end up having to write scripts, or create a separate file with the level ordering, or just generally waste my time doing something that should have been taken care of by the tool.

Folder References

Even though I had read they had their share of problems, I decided to look a folder references (at Miguel’s prompting mostly).

When you add some resources to XCode, you have an option to check “Create Folder References for any added folders”. That option automatically adds any files in those folders without having to explicitly add them to XCode. So you could add the Levels folder, and then any files you create there will be copied with the game.

folder_references.png

I’m not a big fan of assets copied automatically, but as a side effect, that step preserves the directory hierarchy each of those files was in. So any files copied this way can be accessed from within the game by using their full directory structure.

I have to ask again: Why are directory structures preserved here but not with explicit resources added to the project? The mind boggles.

But hey, at least it works, right? Not exactly. There are a couple of gotchas.

The big one I had read in multiple places, is that XCode doesn’t detect any changes to files inside the referenced folder. So you can be making all sorts of changes, building the game, and not seeing anything different. The recommended solution was to add an extra step to the build process that would start by touching the reference folder, forcing a full copy of all assets.

I tested that, I’m glad to report that at least in XCode 3.2.4, that’s not the case. If you modify any file inside a referenced folder, the file will get copied over correctly during the build process without the need of extra steps.

The bad news is that all the files in the referenced folder will be copied. Why oh why??? They clearly know which file changed, why do they feel the need to copy all of the other files? No idea. This is not a big deal early on, but as you start to accumulate dozens and hundreds of megabytes of assets, build times start increasing quite a bit, especially on the device itself.

This is what the copy command looks like for referenced folders:

CpResource build/Debug-iphonesimulator/Test.app/Levels Levels
cd /Users/noel/Development/Test/trunk/Test
setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Developer/Library/PrivateFrameworks/DevToolsCore.framework/Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -Testve-src-symlinks /Users/noel/Development/Test/trunk/Test/Levels /Users/noel/Development/Test/trunk/Test/build/Debug-iphonesimulator/Test.app

It’s nice touch that it automatically excludes .svn directories though. I was wondering why they use CpResource instead of plain, old cp, but I guess that’s to be able to -exclude specific files. Fair enough.

However, what CpResource apparently doesn’t do is to process any of the resources in ways that were processed before by XCode. For example, a png file would have been processed by premultiplying it and byte swapping it so loading it in the iPhone would be slightly more efficient. CpResource just does a regular copy and leaves it alone. So if you were relying on that behavior, you need to do it explicitly yourself in your asset baking step.

What I Really Want

For now, I’m using folder references for the levels, and explicit references for everything else. That way I keep the data size to a minimum but I get to have the directory hierarchy. Not ideal, but at least it works.

This is what I would really like thought:

  1. Easiest: Explicit assets with paths. I really want to just add resources to XCode and have it preserve the directory structure. It’s not that hard. If XCode were open source, I would have made that change a long time ago. Can we at least have this as an option?
  2. Second easiest: Folder references that only copy the changed resources. That would also be OK in my book, and I can’t believe it would be much harder to implement either.
  3. Best: A remote file system hosted on the Mac during debug build. All file references go out to the host machine and get loaded on the fly. This would allow for fastest build times and loading times would not be that different from a fragmented drive on an old device probably. I know some of you already have something like this. Has anybody made one open source (preferably minimalistic and standalone)? I’d love to check it out.

Of course, all of this has probably changed already with XCode 4, but I’m deathly afraid of installing it while working on a production game. Has anybody tried it yet? Have they fixed anything, or is it even more broken?

To wrap things up, and since Miguel is spilling the beans on Twitter, I’ll share a few assets from our current game. Now back to the game because we’re submitting it to the Independent Games Festival on Monday. Next Thursday I’ll talk about the IGF. Wish us luck!

clock.png

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Life In The Top 100 And The Google App Engine

A few weeks ago I wrote about using the Google App Engine as a back end for Flower Garden. One of the comments I heard from several people is that the Google App Engine pricing scheme is “scary” due to its unpredictability. What if your server gets very busy and you find yourself with a huge bill?

Google App Engine Costs

At the time I wrote that post, the bandwidth of Flower Garden (and Flower Garden Free) was just under the free bandwidth allowance, so I didn’t have to pay anything. However, this last week, after riding the Pocket Frogs rocket, Flower Garden Free shot up to the #56 overall app in the US. And boy, did that make a difference in server usage!

serverload.jpg

That screenshot shows the Google App Engine dashboard with the number of requests per second for a 4 day period. Can you guess when the Pocket Frogs cross-promotion started? It went from an average of 1.5 requests per second, to a peak of about 16. That’s a factor of 10 right there.

Let’s see what that means in terms of cost. With the Google App Engine, you get charged for different resources you consume: CPU usage, incoming bandwidth, outgoing bandwidth, data storage, and recipients emailed. Of those, the only one that Flower Garden makes any dent on is outgoing bandwidth (mostly the HTML pages and images in the Flower Shop).

For each of those resources, you get a free amount every day. In the case of outgoing bandwidth, we get 1GB before we have to start paying anything. Afterwards, it’s $0.12 per GB. The peak day for Flower Garden Free, when it was all the way at #56, it consumed 7.8 GB. Now that it’s back down, it’s using up at around 2-3 GB of outgoing data every day.

That means, that the busiest day I was charged $0.82 in bandwidth, but the profits for that day were over $1500! I can only hope for days just as busy!

charges.png

As a reference, these are my Google App Engine charges for the busy week during the promotion. $3.28 for the week? Bring it on! ๐Ÿ™‚

Minimizing Bandwidth

When I first saw the first day’s bandwidth, I was pretty surprised it was taking up that much. I hadn’t tried to minimize it first, but 8 GB seemed like a significant amount.

The first thing I did was to forward any requests to the “More Games” and “News” section back to the Dreamhost account. After all, if that server goes down, it doesn’t really matter, and they can take up significant bandwidth with all the images.

To forward something, I couldn’t just do it from the configuration file. Instead, I set a handler for the moregames directory like this:

- url: /moregames/.*
  script: redirect.py

And the redirect script is very simple:

import os
import sys
import logging
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class RedirectMoreGames(webapp.RequestHandler):
	def get(self, params):
		url = "http://flowers.snappytouch.com/moregames/Snappy_Touch_More_Games/More_Games.html"
		self.redirect(url, permanent=True)
	
application = webapp.WSGIApplication(
							[(r'/(.*)', RedirectMoreGames),
							 ],
							debug=True)

def main():
	run_wsgi_app(application)

if __name__ == "__main__":
	main()

Another thing you can do is to turn on explicit caching of files in the app.yaml file for your Google App Engine app. I don’t know how much that helps with data requested from within an iPhone app, but it can’t hurt.

Finally, I made some changes to Flower Garden. I never had bandwidth minimization in mind, so for example, I was happily requesting updated news and other data at the beginning of every session. I wised up a bit and now it only requests that data at most once every few hours or days.

In case you’re ever getting close to using up your quotas, I learned that you can query them at runtime. I haven’t done anything about it yet, but I suppose I could start forwarding image fetches to a backup server whenever I get close to the limit. But for that, I’ll have to sell many more units of Flower Garden!

Google App Engine Shortcomings

Overall, I’m very happy with the Google App Engine. But it’s not all a bed of roses over here. I think the Google App Engine excels at scaling under heavy load, but surprisingly, it doesn’t have anything close to 100% uptime. I’m going to say it probably doesn’t even have 95% uptime! With such a massive system and all the redundancy underneath, I’m surprised they can’t have better uptime. Supposedly their status page makes you think everything is perfect, but it’s really far from it.

Apart from downtime, people are also reporting severe latency issues sometimes, and I’ve seen some errors like that in my log every so often. Chalk it up to being a beta I suppose. I imagine it’s only going to get better with time.

I would still use the Google App Engine for any new game I’ll release in the future, whether it has big or small backend needs. If nothing else, the ease of development and testing beats every alternative for me.

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.