<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Games from Within &#187; Featured</title>
	<atom:link href="http://gamesfromwithin.com/category/featured/feed" rel="self" type="application/rss+xml" />
	<link>http://gamesfromwithin.com</link>
	<description>Indie iPhone game development</description>
	<lastBuildDate>Thu, 09 Sep 2010 19:59:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>IAP Bundles: More Than Just Good Deals</title>
		<link>http://gamesfromwithin.com/iap-bundles-more-than-just-good-deals</link>
		<comments>http://gamesfromwithin.com/iap-bundles-more-than-just-good-deals#comments</comments>
		<pubDate>Thu, 29 Jul 2010 15:34:28 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[flower garden]]></category>
		<category><![CDATA[sales data]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=1072</guid>
		<description><![CDATA[
			
				
			
		
In-game point bundles are nothing new. Even before the time of in-app purchases, Zynga was famous for releasing &#8220;points&#8221; apps to increase your game reputation or other stats. The fact that they released not just one way of getting points, but many different apps at different price points, was something I dismissed as a marketing [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p><img class="alignright size-full wp-image-673" src="http://gamesfromwithin.com/wp-content/uploads/2010/07/fg_bundles.jpg" alt="fg_bundles.jpg" border="0" width="256" height="216" />In-game point bundles are nothing new. Even before the time of in-app purchases, <a href="http://www.zynga.com/">Zynga</a> was famous for releasing <a href="http://itunes.apple.com/us/app/mafia-wars-170-reward-points/id311944014?mt=8">&#8220;points&#8221; apps</a> to increase your game reputation or other stats. The fact that they released not just one way of getting points, but many different apps at different price points, was something I dismissed as a marketing tactic to try to get noticed on the charts.</p>
<p>Fast-forward to now, and as more companies are jumping into the bandwagon of <a href="http://itunes.apple.com/us/app/we-rule/id339274852?mt=8">games that need &#8220;points&#8221; to make progress</a>, we&#8217;re still bundles. Again, I chucked that up to legacy reasons and doing what worked with the standalone apps.</p>
<h3>Discovering Bundles</h3>
<p>It was at the last <a href="http://www.360idev.com/">360iDev in San Jose</a>, that <a href="http://twitter.com/markjnet">Mark Johnson</a> said something that really stuck with me. I can still hear him say it with his fine British accent: &#8220;I think we might be underestimating how much people are willing to pay for in-app purchases&#8221;. Really?</p>
<p>As soon as I had a chance, I looked at the best-selling IAPs for some popular games. The screenshots below were taken today, not back when I looked at them, but the results are very much the same. I let you guess which games these IAPs came from.</p>
<p><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/werule.png" alt="werule.png" border="0" width="217" height="134" /><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/wefarm.png" alt="wefarm.png" border="0" width="215" height="113" /><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/castlecraft.png" alt="castlecraft.png" border="0" width="220" height="193" /><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/farmville.png" alt="farmville.png" border="0" width="215" height="174" /></p>
<p>I was very surprised with what I saw. The top-selling IAP was never a $0.99 one, and there were bundles of $49.99 or higher towards the top! That was crazy! I was indeed underestimating what players are willing to buy by only offering a measly $0.99 fertilizer bottle in Flower Garden!</p>
<h3>Bundles In Flower Garden</h3>
<p>As part of the next Flower Garden update, I decided to run a little experiment and add two more fertilizer options: A $2.99 one and a $5.99 one, each of them giving you a slightly better deal on fertilizer (20, 70, and 150 doses). That was still nothing compared to the price tags I was seeing in those other games, but I didn&#8217;t want to alienate users by slapping some ridiculously high bundle prices.</p>
<p>The results?</p>
<p>The most popular item by number of sales was still the single fertilizer bottle for $0.99. But a lot of people took advantage of the the other two bundles as well. This is how fertilizer sales for Flower Garden Free have been for the last two months: </p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://gamesfromwithin.com/wp-content/uploads/2010/07/fertilizer_sales.png" alt="fertilizer_sales.png" border="0" width="567" height="371" /></p>
<p>But now, let&#8217;s look at that same period by plotting revenue (again, only Flower Garden Free, the full version is very similar but it wasn&#8217;t easy to combine the two to display them here):</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://gamesfromwithin.com/wp-content/uploads/2010/07/fertilizer_revenue.png" alt="fertilizer_revenue.png" border="0" width="569" height="370" /></p>
<p>Now the two bundles are a lot closer to the single bottle, especially the larger, $5.99 bundle.</p>
<h3>More Than Meets The Eye</h3>
<p>In the end, were bundles effective, or are people buying the same amount of fertilizer and leaving less money in the process? Unfortunately I can&#8217;t answer that question from a pure data point of view. Looking at fertilizer sales before and after I introduced the bundles is no good because the number of users increased dramatically at each update. I can&#8217;t even normalize them by the number of sales, it would have to be by the number of daily users, and unfortunately that&#8217;s not a statistic that I&#8217;m tracking.</p>
<p>However, I think we can argue two really good points about why bundles are great.</p>
<h4>1. More choice</h4>
<p>Having different levels of bundles give players more choice on how they want to purchase something. From what I&#8217;ve read about buyer psychology, people love having choices when buying something (just don&#8217;t give them <a href="http://www.columbia.edu/~ss957/whenchoice.html">too many choices</a>!). They are more involved in the buying process, they evaluate it, and they feel better about the decision they eventually make. So that seems to indicate that more people might buy fertilizer if there are a few bundle options than if there&#8217;s only one.</p>
<h4>2. Commitment</h4>
<p>This is the biggie. Whenever a user purchases a $5.99 bundle (or a $49.99 one!), they became more committed to your game. You can also guarantee they will come back again to get their money&#8217;s worth from that purchase. Even if they had the intention of coming back to your game without the purchase, having spent that money is a nice reminder to do so. And having people come back to your game is what this is all about: They will explore more of the game, get hooked more, make more in-app purchases, show it to more of their friends, and send more bouquets to their family. </p>
<p>I have no doubt that I&#8217;ll be using bundles in the future. Players get a good deal, and you get committed players. It&#8217;s a win-win situation.</p>
<p><br/></p>
<p><i>This post is part of <a href="http://idevblogaday.com/">iDevBlogADay</a>, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the <a href="http://idevblogaday.com/">web site</a>, <a href="http://feeds.feedburner.com/idevblogaday">RSS feed</a>, or <a href="http://twitter.com/#search?q=%23idevblogaday">Twitter</a>.</i></p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals&amp;title=IAP%20Bundles%3A%20More%20Than%20Just%20Good%20Deals&amp;bodytext=In-game%20point%20bundles%20are%20nothing%20new.%20Even%20before%20the%20time%20of%20in-app%20purchases%2C%20Zynga%20was%20famous%20for%20releasing%20%22points%22%20apps%20to%20increase%20your%20game%20reputation%20or%20other%20stats.%20The%20fact%20that%20they%20released%20not%20just%20one%20way%20of%20getting%20points%2C%20but%20many%20di" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals&amp;title=IAP%20Bundles%3A%20More%20Than%20Just%20Good%20Deals&amp;notes=In-game%20point%20bundles%20are%20nothing%20new.%20Even%20before%20the%20time%20of%20in-app%20purchases%2C%20Zynga%20was%20famous%20for%20releasing%20%22points%22%20apps%20to%20increase%20your%20game%20reputation%20or%20other%20stats.%20The%20fact%20that%20they%20released%20not%20just%20one%20way%20of%20getting%20points%2C%20but%20many%20di" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals&amp;t=IAP%20Bundles%3A%20More%20Than%20Just%20Good%20Deals" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals&amp;title=IAP%20Bundles%3A%20More%20Than%20Just%20Good%20Deals" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals&amp;title=IAP%20Bundles%3A%20More%20Than%20Just%20Good%20Deals" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=IAP%20Bundles%3A%20More%20Than%20Just%20Good%20Deals&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fiap-bundles-more-than-just-good-deals&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/iap-bundles-more-than-just-good-deals/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>The Power of Free (aka The Numbers Post #3)</title>
		<link>http://gamesfromwithin.com/the-power-of-free</link>
		<comments>http://gamesfromwithin.com/the-power-of-free#comments</comments>
		<pubDate>Thu, 08 Jul 2010 17:38:53 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[flower garden]]></category>
		<category><![CDATA[sales data]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=989</guid>
		<description><![CDATA[
			
				
			
		
It has been two months since the last &#8220;numbers post&#8221;. It covered the Valentine&#8217;s Day promotion, spike in sales, and subsequent settling out at a very nice level. Here&#8217;s a recap of what things looked like at the beginning of May (revenue was about $1500 per week):

The Plan
Mother&#8217;s Day happens at the beginning of May [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p>It has been two months since <a href="http://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store">the last &#8220;numbers post&#8221;</a>. It covered the Valentine&#8217;s Day promotion, spike in sales, and subsequent settling out at a very nice level. Here&#8217;s a recap of what things looked like at the beginning of May (revenue was about $1500 per week):</p>
<p><center><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/fg_before.png" alt="fg_before.png" border="0" width="650" height="417" /></center></p>
<h3>The Plan</h3>
<p>Mother&#8217;s Day happens at the beginning of May (in the US and Canada anyway, I&#8217;m afraid I was too busy in April and I missed Mother&#8217;s Day in a lot of European countries). I figured it would be the perfect time to do another push.</p>
<p>If there&#8217;s something I learned from past experience, is that the more you manage to concentrate any kind of promotion, the more effective it will be. So in preparation for Mother&#8217;s Day, I created a new update (with iPad support), a couple of new in-app purchase items (new set of seeds and some fertilizer bundles), and sent out the usual announcement on the <a href="http://gamesfromwithin.com/">Flower Garden mailing list</a>, <a href="http://www.facebook.com/iphoneflowergarden">Facebook page</a>, and <a href="http://twitter.com/SnappyTouch">Twitter</a>.</p>
<p>But in addition to all of that, I tried a new strategy: <a href="http://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day">I gave Flower Garden away for free</a>. Yes, completely for free.</p>
<p>The idea sounded really scary at first. After all, I would be giving away my baby for free. Would I lose a lot of money doing that? Would it depreciate the perceived value of Flower Garden? Would it annoy loyal users seeing an app they paid for given away? Fortunately it appears that the answer to those questions was no.</p>
<p>The reason I decided to give Flower Garden away for free was mostly to get it into more people&#8217;s hands. I was thinking I would lose some money initially, but then more than make up for it when I turned it back to paid because of all the extra users and word of mouth. There is already a free version with a limited number of pots and seeds, but people are hungry to download paid apps for free. </p>
<p>To add extra impact to this price change, I had Flower Garden featured as the free app for Mother&#8217;s Day weekend in <a href="http://www.freeappcalendar.com/">Free App Calendar</a>. Unlike other free app web sites, the <a href="http://www.twitter.com/freeAppCalendar">folks at Free App Calendar</a> are very developer friendly and are not out to take a cut of your profits or charge outrageous fees. It was an absolute pleasure dealing with them.</p>
<h3>Mother&#8217;s Day</h3>
<p>On Saturday May 8th, a few minutes past midnight the day before Mother&#8217;s Day, I switched Flower Garden over to free. Now I was committed!</p>
<p>Right away there was a lot of positive reaction around the announcement. Everybody on Twitter and Facebook were responding really well and spreading the word. Major sites like <a href="http://toucharcade.com/2010/05/08/flower-garden-for-iphone-ipad-free-this-weekend/">Touch Arcade</a> and <a href="http://www.148apps.com/news/flower-garden-free-mothers-day/">148Apps</a> covered the Mother&#8217;s Day promotion and got lots of extra eyeballs on the sale.</p>
<p>After the first day, the data was in: Flower Garden had been downloaded 12,500 times. That was great! As a reference, Flower Garden Free was usually downloaded between 800 and 1,000 times per day, so that was a 10x improvement.</p>
<p>On Sunday, Mother&#8217;s Day, things got even better. News had time to propagate more, and people were sending bouquets like crazy, so by the end of the day there had been an additional 26,000 downloads. That&#8217;s exactly what I was hoping for!</p>
<p>As a matter of fact, it was doing so great, that I decided to leave it for free as long as the number of downloads was significantly higher than what the free version was normally getting. After Mother&#8217;s Day downloads started going down, but they were still pretty strong the following Sunday. Here&#8217;s what the download numbers looked like for those 9 days:</p>
<p><center><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/fg_week_downloads.png" alt="fg_week_downloads.png" border="0" width="648" height="416" /></center></p>
<p>The important question is how much revenue was there during that time? I was giving the app away for free but it had in-app purchases. Would they make up for it? The answer was a resounding yes!</p>
<p><center><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/fg_week_revenue.png" alt="fg_week_revenue.png" border="0" width="638" height="418" /></center></p>
<p>Mother&#8217;s Day went on to become the biggest day in terms of revenue since Flower Garden was launched. Bigger even than Christmas or Valentine&#8217;s Day! Things started going down after that, but still at a very high level. The little bump towards the end of the week is a combination of the weekend (which always results in more sales), and the <a href="http://gamesfromwithin.com/flower-garden-selected-as-an-apple-staff-favorite-across-europe">feature of Flower Garden on the App Store across most of Europe</a>.</p>
<p>These numbers took a bit to sink in. It really shows that in-app purchases are definitely tied to the number of downloads. If you manage to give away twice as many copies, you&#8217;ll probably get close to twice as many in-app purchases. That effect is amplified if you have multiple in-app purchase items available.</p>
<p>It&#8217;s also interesting to notice that revenue didn&#8217;t follow the same drop-off curve as downloads. It wasn&#8217;t nearly as sharp. I suspect two things are going on in there:</p>
<ul>
<li>Some users downloaded Flower Garden during the sale weekend and weren&#8217;t interested in it at all. Downloading it was a knee-jerk reaction to any app that goes free, so that never translated into an in-app purchase. Users later in the week however, probably downloaded it because they received a bouquet or were interested in it, so they had a much higher likelihood of buying something through the Flower Shop.</li>
<li>Fertilizer. Fertilizer is the only consumable item available for purchase in Flower Garden. Unlike a non-consumable item, the number of sales is not tied to the number of new users, but to the number of current, daily users. The more users launch your app every day, the higher the sales of consumable items. Some of the new users of Flower Garden went on to buy fertilizer later in the week, making revenue higher than you would expect from the download curve.</li>
</ul>
<h3>Flipping The Switch</h3>
<p>The number of downloads on Sunday May 16th was slightly over 2,000. At that point I decided that it was close enough to the number of downloads Flower Garden Free was normally getting, so I flipped the switch back to paid. Things were going great, so messing with it was a pretty scary thing to do. Even scarier than it had been setting it free in the first place. </p>
<p>During that week, Flower Garden rose up on the charts. It reached #73 in the top games in the US and was charting very high in all the subcategories and on the iPad charts. As soon as I flipped the switch back to paid, it dropped out of sight from the charts. Fortunately, within a couple of days it came back to its position before that crazy week. </p>
<p>Most importantly, Flower Garden Free, which had dropped quite a bit during that promotion, immediately went back up to the top 100 in the Kids and Family subcategories like before.</p>
<p>As you can expect, as a result of giving it away for free, the ratings on the App Store went down quite a bit. While it was a paid application, the ratings were around 4 stars, but they dropped down to 2.5 stars after that week. It seems people love a free app, but are very quick to criticize it and give it a low rating (especially if it has in-app purchases).</p>
<p>Fortunately bad ratings can be easily fixed with a new update, and some encouragement to users to <a href="http://gamesfromwithin.com/increase-your-app-ratings-on-the-app-store">leave positive rating on the App Store</a>. Now it&#8217;s back up to over 4.5 stars.</p>
<h3>Aftermath</h3>
<p>Now it&#8217;s two months later and the dust has had a chance to settle down. Apart from the very nice sales spike during the sale, was it worth it? Again, the answer is a definite yes.</p>
<p>Here&#8217;s the revenue since the start of the promotion:</p>
<p><center><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/fg_two_months.png" alt="fg_two_months.png" border="0" width="649" height="418" /></center></p>
<p>As you can see, it quickly went down, but it settled at a reasonably high level. In fact, compare this two-month period (highlighted in blue) with the previous sales:</p>
<p><center><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/fg_after2.png" alt="fg_after2.png" border="0" width="650" height="418" /></center></p>
<p>Before the promotion revenue was hovering around $1,500 per week, now it settled down to about $2,400 per week. An average day today is bigger than Christmas day! Very nice change!</p>
<p>I think the reason why it settled at a higher revenue level than before is because it got more exposure during that week. Lots of people sent bouquets, which introduced new users to Flower Garden. It&#8217;s the viral effect I was hoping for from the start, and although it never reached epidemic proportions, it has been enough to keep Flower Garden alive and well.</p>
<p>Adding iPad support as part of the latest update probably helped too. The iPad market is smaller than the iPhone one, but a lot of early adopters are eager to find good apps for their new toys. The smaller market size also allowed Flower Garden to appear in the iPad charts more easily, increasing exposure that way.</p>
<p>Here&#8217;s a breakdown of where revenue came from in the last month (I&#8217;m excluding the period where Flower Garden was free to get a more accurate view):</p>
<p><center><img src="http://gamesfromwithin.com/wp-content/uploads/2010/07/sales_breakdown.png" alt="sales_breakdown.png" border="0" width="332" height="311" /></center></p>
<p>As you can see, consumable items (fertilizer) account for almost half the revenue. Consumable items are a factor of your current userbase, so getting a large influx of new users can result in a permanent revenue increase instead of just a sales spike. It also shows what a small percentage actual app sales are, which explains why even while Flower Garden was free, revenue was still up.</p>
<h3>Conclusion</h3>
<p>This was a wild ride again! It was definitely worth doing the promotion and it definitely brought home how powerful free can be. However, I&#8217;m trying to decide the pricing scheme for my next game, and even though free plus in-app purchases is very tempting, I&#8217;m not sure it&#8217;s the way to go. </p>
<p><strong>What do you think? Are new games better off being free with in-app purchases, or can indie games be successful being paid (and still having in-app purchases)?</strong></p>
<p><br/></p>
<p><i>This post is part of <a href="http://idevblogaday.com/">iDevBlogADay</a>, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the <a href="http://idevblogaday.com/">web site</a>, <a href="http://feeds.feedburner.com/idevblogaday">RSS feed</a>, or <a href="http://twitter.com/#search?q=%23idevblogaday">Twitter</a>.</i></p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free&amp;title=The%20Power%20of%20Free%20%28aka%20The%20Numbers%20Post%20%233%29&amp;bodytext=It%20has%20been%20two%20months%20since%20the%20last%20%22numbers%20post%22.%20It%20covered%20the%20Valentine%27s%20Day%20promotion%2C%20spike%20in%20sales%2C%20and%20subsequent%20settling%20out%20at%20a%20very%20nice%20level.%20Here%27s%20a%20recap%20of%20what%20things%20looked%20like%20at%20the%20beginning%20of%20May%20%28revenue%20was%20about%20%2415" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free&amp;title=The%20Power%20of%20Free%20%28aka%20The%20Numbers%20Post%20%233%29&amp;notes=It%20has%20been%20two%20months%20since%20the%20last%20%22numbers%20post%22.%20It%20covered%20the%20Valentine%27s%20Day%20promotion%2C%20spike%20in%20sales%2C%20and%20subsequent%20settling%20out%20at%20a%20very%20nice%20level.%20Here%27s%20a%20recap%20of%20what%20things%20looked%20like%20at%20the%20beginning%20of%20May%20%28revenue%20was%20about%20%2415" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free&amp;t=The%20Power%20of%20Free%20%28aka%20The%20Numbers%20Post%20%233%29" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free&amp;title=The%20Power%20of%20Free%20%28aka%20The%20Numbers%20Post%20%233%29" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free&amp;title=The%20Power%20of%20Free%20%28aka%20The%20Numbers%20Post%20%233%29" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=The%20Power%20of%20Free%20%28aka%20The%20Numbers%20Post%20%233%29&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fthe-power-of-free&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/the-power-of-free/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Increase Your App Ratings On The App Store</title>
		<link>http://gamesfromwithin.com/increase-your-app-ratings-on-the-app-store</link>
		<comments>http://gamesfromwithin.com/increase-your-app-ratings-on-the-app-store#comments</comments>
		<pubDate>Mon, 14 Jun 2010 18:22:55 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=930</guid>
		<description><![CDATA[
			
				
			
		
Every iPhone developer fears the one-star-on-uninstall rating. I understand Apple&#8217;s reasoning for adding the prompt for rating on uninstall, but since that&#8217;s the only time users are prompted, it becomes a very biased, negative rating. There may be hundreds of users happy with your app who never rate it on iTunes, but everybody who uninstalls [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p>Every iPhone developer fears the one-star-on-uninstall rating. I understand Apple&#8217;s reasoning for adding the prompt for rating on uninstall, but since that&#8217;s the only time users are prompted, it becomes a very biased, negative rating. There may be hundreds of users happy with your app who never rate it on iTunes, but everybody who uninstalls it gets asked to give it a review. That&#8217;s quite unfair from the developer point of view.</p>
<p>First one bit of good news: That prompt-on-delete feature seems to be gone on iOS 4.0. That should make everybody happy. Even so, taking a pro-active position on this can only benefit developers.</p>
<p>Next a personal opinion without any real hard data to back it up: I don&#8217;t think App Store ratings matter very much. I see plenty of quality, 5-star apps that never go anywhere, as well as horrible apps with close to 1-star rating on the top 10. I&#8217;m sure good ratings help a bit, but not as much as some people may think.</p>
<p>One of the little features I snuck in <a href="http://www.facebook.com/iphoneflowergarden?v=wall&#038;story_fbid=130406023644468&#038;ref=mf">the latest update of Flower Garden</a>, was a prompt to rate (or re-rate) the app. <a href="http://www.mobileorchard.com/fighting-back-against-the-app-stores-negative-rating-bias/">This idea isn&#8217;t new</a>, and I&#8217;ve seen quite a few apps doing it already. I think it makes a lot of sense and provides rating that is much more balanced and representative of how users feel about the app.</p>
<p>You have to be careful about how you prompt users though. This are the priorities I had in mind when I implemented the rating prompt in Flower Garden, roughly in order of importance:</p>
<ol>
<li>Don&#8217;t be annoying!</li>
<li>Disrupt the user as little as possible</li>
<li>Make rating the app as easy as possible.</li>
<li>Prompt at every update.</li>
</ol>
<p><img class="alignright size-full wp-image-673" src="http://gamesfromwithin.com/wp-content/uploads/2010/06/fg_prompt.jpg" alt="fg_prompt.jpg" border="0" width="240" height="360" /></p>
<h3>Don&#8217;t be annoying</h3>
<p>This is by far the most important priority. If your prompt for review is annoying, you might get more angry users and one-star reviews than you would have without it. Be respectful of the user and don&#8217;t nag. </p>
<p>For quite a few versions, I&#8217;ve had a review button in the &#8220;Feedback&#8221; tab in the settings screen. Not many people use it or even know about it because it was several taps away from the normal flow of Flower Garden. That&#8217;s  an example of a feedback prompt that is <b>too</b> unobtrusive. Clearly, I needed something a bit more noticeable.</p>
<p>What I did was to add an actual alert view with the prompt. That alert comes up very infrequently, and gives users the option to either rate it right away, be reminded later, or just stop asking altogether. Many more users rated the app through this mechanism (and I haven&#8217;t gotten a single complaint about it being annoyed yet&#8211;keeping my fingers crossed).</p>
<h3>Disrupt the user as little as possible</h3>
<p>First of all, you should never ask the user to rate the first time they launch it. They haven&#8217;t had a chance to check it out yet! Give them a few days (or a few launches of the app). That will benefit you in two ways: users will have a better chance to give an honest rating, and users who didn&#8217;t like your app probably won&#8217;t be around in two days, so they&#8217;ll never see the prompt.</p>
<p>Second, choose a good time to ask. Please, don&#8217;t ask me as soon as I launch the app! Chances are I want to do something with it, so being pestered with a review prompt is disruptive, especially because adding a rating involves leaving the app and going to iTunes. At the same time, don&#8217;t ask me in the middle of a level or when I&#8217;m engrossed in game. A good moment to ask for a rating would be after completing a level or two, or, in the case of Flower Garden, after sending a bouquet.</p>
<p>For extra bonus points, catch the user on a &#8220;good&#8221; moment. Maybe only ask them to rate the app if they actually beat the level. They&#8217;ll probably leave a better review than if they just lost and are in a bad mood.</p>
<p>The exception I made was if a certain amount of time went by and the user never got to the point of being prompted (some people just don&#8217;t send bouquets in Flower Garden). In that case, I will ask at startup or at some other, non-ideal point.</p>
<h3>Make rating the app as easy as possible</h3>
<p>This is the funnel principle at work. For every action the user has to do in order to leave a review, the fewer users will actually do it. It would be ideal if users could rate the app directly from the alert box. That would involve no extra actions (or leaving the app) and would result in the maximum number of ratings [1]. Unfortunately, that&#8217;s not the case, so we have to do the best we can with what we have.</p>
<p>So we want to minimize the amount of actions from the moment the user taps &#8220;Rate now&#8221; until they can enter the rating. We could send them to the product page on the App Store, but that would still involve them scrolling around, finding the rating button, tapping it, and entering the rating. We can do better than that: We can send them directly to the rating screen. Check out <a href="http://bjango.com/articles/ituneslinks/">this great post</a> for a dissection of iTunes links and how to create one to the review page. Make sure the technique you choose works on an iPhone (not all of them do!).</p>
<h3>Prompt at every update</h3>
<p>This one is easy: Just store the number of the last version the user wrote a review for, and if it changes, start from scratch again. That way you don&#8217;t have to write any custom code at every release. Also, make sure to respect the &#8220;Don&#8217;t ask anymore&#8221; option if the user selected that in a previous update.</p>
<h3>Source code</h3>
<p>Here&#8217;s the <a href="http://gamesfromwithin.com/wp-content/uploads/2010/06/ReviewRequest.zip" title="ReviewRequest.zip">review request source code</a> (released under the MIT license). It consists of only two standalone files, and all the review state is kept in the default, global settings. There are only three functions and it should be very self-explanatory: </p>
<pre>
	bool ShouldAskForReview();
	bool ShouldAskForReviewAtLaunch();
	void AskForReview();
</pre>
<p>The ShouldAskForReviewAtLaunch() function simply adds an extra condition of launching it X number of times before asking for review (this is in case the user never triggers the review condition).</p>
<h3>Results</h3>
<p>Does this prompt for ratings work? This is a screen grab from iTunes 5 days after Flower Garden 2.4 was released:</p>
<p><center><img src="http://gamesfromwithin.com/wp-content/uploads/2010/06/fg_itunes_ratings.png" alt="fg_itunes_ratings.png" border="0" width="429" height="171" /></center></p>
<p>A few interesting observations:</p>
<ul>
<li>Ratings are higher than they were before. Before the free day, Flower Garden had an average of 3.5 to 4 stars.</li>
<li>Reviews are often shorter and less useful than unprompted reviews. There are a lot of 5-star &#8220;I love this app!&#8221; reviews without much more substance. (I&#8217;m not complaining, really).</li>
<li>Still a huge number of users chose not to leave a review. There are only 148 ratings, but there have been 30,000 upgrades to the latest version. A lot of people might have upgraded and not launched it, but even so, it&#8217;s a very small percentage.
</ul>
<p>Overall, it was a very small time investment and the results show it was definitely worth it. I&#8217;ll be using this approach in my future projects (unless future iOS versions take care of it automatically somehow).</p>
<p><br/><br/></p>
<p>[1] Apple, can we fix that? How about a REST API for leaving ratings and reviews? Pretty please? </p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store&amp;title=Increase%20Your%20App%20Ratings%20On%20The%20App%20Store&amp;bodytext=Every%20iPhone%20developer%20fears%20the%20one-star-on-uninstall%20rating.%20I%20understand%20Apple%27s%20reasoning%20for%20adding%20the%20prompt%20for%20rating%20on%20uninstall%2C%20but%20since%20that%27s%20the%20only%20time%20users%20are%20prompted%2C%20it%20becomes%20a%20very%20biased%2C%20negative%20rating.%20There%20may%20be%20hu" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store&amp;title=Increase%20Your%20App%20Ratings%20On%20The%20App%20Store&amp;notes=Every%20iPhone%20developer%20fears%20the%20one-star-on-uninstall%20rating.%20I%20understand%20Apple%27s%20reasoning%20for%20adding%20the%20prompt%20for%20rating%20on%20uninstall%2C%20but%20since%20that%27s%20the%20only%20time%20users%20are%20prompted%2C%20it%20becomes%20a%20very%20biased%2C%20negative%20rating.%20There%20may%20be%20hu" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store&amp;t=Increase%20Your%20App%20Ratings%20On%20The%20App%20Store" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store&amp;title=Increase%20Your%20App%20Ratings%20On%20The%20App%20Store" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store&amp;title=Increase%20Your%20App%20Ratings%20On%20The%20App%20Store" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=Increase%20Your%20App%20Ratings%20On%20The%20App%20Store&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fincrease-your-app-ratings-on-the-app-store&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/increase-your-app-ratings-on-the-app-store/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Making A Living (Comfortably) On The App Store (aka The Numbers Post #2)</title>
		<link>http://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store</link>
		<comments>http://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store#comments</comments>
		<pubDate>Fri, 14 May 2010 19:12:32 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[flower garden]]></category>
		<category><![CDATA[sales data]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=922</guid>
		<description><![CDATA[
			
				
			
		
A few months ago, I wrote a post analyzing how Flower Garden had done since it was released. It was a story with lots of ups and downs, tales of trials and failure, but ending on a positive, optimistic note. It went on to become one of the most read posts in this blog, and [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p>A few months ago, I wrote <a href="http://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store">a post analyzing how Flower Garden had done since it was released</a>. It was a story with lots of ups and downs, tales of trials and failure, but ending on a positive, optimistic note. It went on to become one of the most read posts in this blog, and the comments were all very encouraging. Clearly, people, and especially other developers, are hungry for this kind of data.</p>
<p>So here we go with the second part. How did Flower Garden fare after the new year? Was it just the Christmas purchasing frenzy that had a momentary effect on sales, or was there something more to it?</p>
<h2>Recap and Overview</h2>
<p>Here&#8217;s where we left off last time. The unusual part was how profits increased as soon as I added in-app purchases to Flower Garden in early December. It made for a very atypical sales plot.</p>
<p style="text-align: center;"><img class="size-full wp-image-816 aligncenter" title="Flower Garden profit" src="http://gamesfromwithin.com/wp-content/uploads/2010/01/Full.png" alt="Full" width="650" height="449" /></p>
<p>And here is how things look now. This plot includes the previous data so it&#8217;s easier to contrast before and after. The area in blue is the new data since the last post.</p>
<p style="text-align: center;"><img src="http://gamesfromwithin.com/wp-content/uploads/2010/05/fg_total.png" alt="fg_total.png" border="0" width="603" height="440" /></p>
<p>Just glancing at that chart makes it clear that that the increase around Christmas wasn&#8217;t a fluke. It actually wasn&#8217;t even done going up. After all the spikes, and the weekly ups and downs, Flower Garden ended up settling to about $1,500/week. And that, even in California, I would consider it to be a comfortable living. What a different from the $50/day it was making last year!</p>
<p>So what exactly happened there? Let&#8217;s look at the new data in more detail.</p>
<p style="text-align: center;"><img src="http://gamesfromwithin.com/wp-content/uploads/2010/05/fg_recent.png" alt="fg_recent.png" border="0" width="609" height="446" /></p>
<p>At a glance, there are three, very different sections.</p>
<h2>The Feature</h2>
<p>The first one starts with a significant increase in sales (A), and is in large part due to <a href="http://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide">being featured on the App Store worldwide as a Staff Favorite</a>. It&#8217;s a nice spike, but it&#8217;s nothing like the x10 spikes other developers have seen with App Store features. That&#8217;s because the Staff Favorite slot, even though it&#8217;s a very prestigious one, it does not appear on the iPhone, only on iTunes. I do all my browsing and shopping through iTunes, but apparently I&#8217;m in the minority, so the effect on sales is greatly reduced.</p>
<p>That spike is also in part due to <a href="http://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store">my last &#8220;numbers post&#8221;</a>, which happened right at the same time (not completely accidentally). The page attracted about 15,000 views in a few days, so I&#8217;m sure a few of them translated in people checking out Flower Garden out of curiosity.</p>
<h2>Valentine&#8217;s Day</h2>
<p>The second spike isn&#8217;t hard to guess: It&#8217;s the weekend of February 14th, Valentine&#8217;s Day. The more things happen at once and the more something is in the public eye, the more of an impact it has. PR people have known that for a long time, and it was really brought home for me back <a href="http://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store">in December</a>.</p>
<p>Fortunately, I managed to make quite a few things happen in the days leading to Valentine&#8217;s Day weekend:</p>
<ul>
<li>I released an update with couple new in-app purchases: A new set of seeds (Seeds of Love), and a greenhouse garden, for $0.99 each.</li>
<li>I sent out a newsletter to the 25,000 subscribers to <a href="http://www.facebook.com/l.php?u=http%3A%2F%2Fymlp.com%2Fsignup.php%3Fid%3Dgemmyyugmgj&#038;h=cf570">the mailing list</a> announcing the new items.</li>
<li>I put Flower Garden on sale for $0.99 (down from the regular price of $2.99).</li>
<li>Several web sites, <a href="http://toucharcade.com/2010/02/14/valentines-day-picks-for-that-special-iphone-in-your-life/">including TouchArcade</a>, covered the sale and the new update, giving it lots of visibility.</li>
<li>Flower Garden Free was the free app for February 14th on the <a href="http://bit.ly/iPhoneValentine">Valentine&#8217;s Day Calendar</a>.</li>
</ul>
<p>All of that combined to cause the big spike in profits (B). You really need to look at the first plot to put it in perspective. Two days in around Valentine&#8217;s Day had higher profit than the initial release spike back in April of last year!</p>
<h2>Winding Down</h2>
<p>Of course, everything that goes up, must eventually come down. So the weeks following Valentine&#8217;s Day profits went rapidly down. It was at the very end of April that I started working on <a href="http://gamesfromwithin.com/dr-seuss-lorax-garden-up-the-charts">Lorax Garden</a>, so for that period of time I wasn&#8217;t able to do anything related to Flower Garden. For a while sales were dropping quite rapidly, but they eventually flattened out to about $1,500/week (C).</p>
<p>The good thing about having consumable items as in-app purchases (fertilizer in this case), is that profits are related to active user base, not just initial sales. So even though the amount of downloads decreased significantly during this time, the user base had grown a large amount, and with it, the daily profits.</p>
<h2>Flower Garden Free</h2>
<p>Back in December, there seemed to be a connection between the amount of downloads of the free version of Flower Garden and profits. They both picked up right around the time I added in-app purchases, although I was never able to tell if it was cause or consequence.</p>
<p>This is the amount of downloads of the free version for this period of time.</p>
<p style="text-align: center;"><img src="http://gamesfromwithin.com/wp-content/uploads/2010/05/fg_free.png" alt="fg_free.png" border="0" width="608" height="446" /></p>
<p>It stays pretty regularly at about 800 downloads per day (which is not much compared to a lot of free versions out there), and has a massive spike on Valentine&#8217;s Day (caused by word of mouth, lots of sent bouquets, and the <a href="http://bit.ly/iPhoneValentine">Valentine&#8217;s Day Calendar</a>).</p>
<p>Notice that the App Store feature for Flower Garden (full version) in January had virtually no effect on downloads of the free version. It seems that people are willing to buy something full price without trying the free version first if Apple features it.</p>
<p>Both versions of Flower Garden (free and full) have in-app purchases in them. Even though there&#8217;s a higher percentage of users with the full version that buy in-app purchases, the free version is much more popular and the majority of the revenue comes from the free version (orange). This is a tren that was already noticable around the holidays, but now is much more clear, with over 50% of the revenue coming from in-app purchases in the free version.</p>
<p style="text-align: center;"><img src="http://gamesfromwithin.com/wp-content/uploads/2010/05/iap_profit.png" alt="iap_profit.png" border="0" width="600" height="414" /></p>
<h2>The Future</h2>
<p>The data for this post stops at May 5th. That&#8217;s because on May 6th I released a new set of seeds and <a href="http://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day">gave Flower Garden away for free as part of the Mother&#8217;s Day promotion</a>. As soon as the dust settles from that, I&#8217;ll write a third post detailing how it turned out.</p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store&amp;title=Making%20A%20Living%20%28Comfortably%29%20On%20The%20App%20Store%20%28aka%20The%20Numbers%20Post%20%232%29&amp;bodytext=A%20few%20months%20ago%2C%20I%20wrote%20a%20post%20analyzing%20how%20Flower%20Garden%20had%20done%20since%20it%20was%20released.%20It%20was%20a%20story%20with%20lots%20of%20ups%20and%20downs%2C%20tales%20of%20trials%20and%20failure%2C%20but%20ending%20on%20a%20positive%2C%20optimistic%20note.%20It%20went%20on%20to%20become%20one%20of%20the%20most%20read%20" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store&amp;title=Making%20A%20Living%20%28Comfortably%29%20On%20The%20App%20Store%20%28aka%20The%20Numbers%20Post%20%232%29&amp;notes=A%20few%20months%20ago%2C%20I%20wrote%20a%20post%20analyzing%20how%20Flower%20Garden%20had%20done%20since%20it%20was%20released.%20It%20was%20a%20story%20with%20lots%20of%20ups%20and%20downs%2C%20tales%20of%20trials%20and%20failure%2C%20but%20ending%20on%20a%20positive%2C%20optimistic%20note.%20It%20went%20on%20to%20become%20one%20of%20the%20most%20read%20" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store&amp;t=Making%20A%20Living%20%28Comfortably%29%20On%20The%20App%20Store%20%28aka%20The%20Numbers%20Post%20%232%29" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store&amp;title=Making%20A%20Living%20%28Comfortably%29%20On%20The%20App%20Store%20%28aka%20The%20Numbers%20Post%20%232%29" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store&amp;title=Making%20A%20Living%20%28Comfortably%29%20On%20The%20App%20Store%20%28aka%20The%20Numbers%20Post%20%232%29" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=Making%20A%20Living%20%28Comfortably%29%20On%20The%20App%20Store%20%28aka%20The%20Numbers%20Post%20%232%29&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-comfortably-on-the-app-store&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Going The iPad Way: All You Wanted to Know About Creating Universal Apps</title>
		<link>http://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps</link>
		<comments>http://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps#comments</comments>
		<pubDate>Mon, 10 May 2010 00:53:24 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[flower garden]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=900</guid>
		<description><![CDATA[
			
				
			
		

It&#8217;s one thing to go on record saying I wouldn&#8217;t be creating an iPad-specific version of Flower Garden, and another seeing the iPhone version running on an iPad with all the ugly jaggies and huge, pixelated text. So when it came time to do a new update, I decided to at least take advantage of [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p><img class="alignright size-full wp-image-673" src="http://gamesfromwithin.com/wp-content/uploads/2010/05/flower_garden_ipad.jpg" alt="flower_garden_ipad.jpg" border="0" width="256" height="347" /><br />
It&#8217;s one thing to go on record saying <a href="http://gamesfromwithin.com/figuring-out-the-ipad">I wouldn&#8217;t be creating an iPad-specific version of Flower Garden</a>, and another seeing the iPhone version running on an iPad with all the ugly jaggies and huge, pixelated text. So when it came time to do a new update, I decided to at least take advantage of the iPad capabilities to make the existing app prettier by making Flower Garden into a universal app. It&#8217;s <a href="http://bit.ly/fg_gfw">now available on the App Store</a>, so go get it and check it out!</p>
<p>Surprisingly, there wasn&#8217;t that much documentation on how to go about making a universal iPhone/iPad version. There&#8217;s <a href="http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html#//apple_ref/doc/uid/TP40009370-CH9-SW1">a document from Apple showing some initial steps</a>, but that&#8217;s about it. So I wanted to share what I learned along the way, including some very useful tips I learned through trial and error or by doing a lot of digging through Twitter and the development forums.</p>
<p>Flower Garden is a <a href="http://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl">strange hybrid of OpenGL and UIKit</a>, which made things more complicated than if it were just one or the other. Learning curve and all, it took two full days of my time. If you&#8217;re using just OpenGL or just UIKit, the conversion to a universal app will be significantly faster.</p>
<h2>Universal Project</h2>
<p>The first thing you need to do is understand what&#8217;s going on with all the SDK versions. At this time, the latest iPhone OS version is 3.1.3, but you&#8217;re going to be developing the universal app with SDK 3.2. You want the resulting binary to run on both 3.X OS on iPhones and 3.2 OS on iPad. It&#8217;s a very similar situation to when we were <a href="http://gamesfromwithin.com/targeting-2-x-with-3-0-features-trouble-ahead">writing apps that worked on both 3.X and 2.X</a>.</p>
<p>So fire up XCode 3.2.2 (yes, all those version numbers start getting very confusing&#8211;that&#8217;s the XCode version that comes with SDK 3.2), and load your iPhone project you want to make into a universal one. If you look under the Project menu item, you&#8217;ll see an entry called &#8220;Upgrade Current Target For iPad&#8221;. The Apple documentation even warns you not to create a universal app in any other way.</p>
<p>Go ahead and use it if you want. It will work&#8230; as long as you have a single target you want to convert. For some inexplicable reason <a href="#1">[1]</a>, it will only work once per project (even though it&#8217;s phrased as working with whatever the current target is). When would you have more than one target executable? If you have a <a href="http://gamesfromwithin.com/from-full-to-lite-in-under-an-hour">free and a paid version</a> for example.</p>
<p>Besides, I&#8217;m uncomfortable with automated &#8220;smart&#8221; tools that do things behind my back without me knowing exactly what&#8217;s going on, so I upgraded by hand by looking at the diffs of what the upgrade command did. It turns out it&#8217;s extremely simple.</p>
<ol>
<li>Under the project properties, set your base SDK to 3.2.</li>
<li>Set Architectures to &#8220;Optimized (arm6, arm7)&#8221;</li>
<li>Uncheck &#8220;Build Active Architectures Only&#8221;</li>
<p><img src="http://gamesfromwithin.com/wp-content/uploads/2010/05/proejct_settings_1.png" alt="proejct_settings_1.png" border="0" width="564" height="208" /></p>
<li>In the Deployment section, set it to SDK 3.1.3 (or whatever 3.X you want to target)</li>
<p><img src="http://gamesfromwithin.com/wp-content/uploads/2010/05/project_settings_21.png" alt="project_settings_2.png" border="0" width="560" height="68" />
</ol>
<p>That&#8217;s it, really. That&#8217;s all you need to compile and run your app both on an iPhone and an iPad. When you build for the device, it will compile both arm6 and arm7 versions and create a combined fat executable with both. And yes, this means the size of your executable is going to double (which could be an issue if you&#8217;re near the 20MB limit). In the case of Flower Garden, the combined executable is 3.4MB, so that&#8217;s not a big deal.</p>
<h2>iPad Functionality</h2>
<p>What about that new xib file that the upgrade process creates? You don&#8217;t really need it. It&#8217;s there in case you want to have a different set of xibs for each platform, and it&#8217;s hooked up to the info file so the app knows to load it at startup.</p>
<p><img class="alignright size-full wp-image-673" src="http://gamesfromwithin.com/wp-content/uploads/2010/05/ib.png" alt="ib.png" border="0" width="273" height="256" />For the universal version of Flower Garden, I wasn&#8217;t trying to make a whole new brand experience on the iPad. Instead, I was looking for a quick and easy way to make it look much better. Because of it, I decided to reuse the same xib files as for the iPhone version.</p>
<p>That meant I had to go in Interface Builder, and adjust the autosize properties for a lot of the views. Some of them I wanted to stretch and get bigger with the high resolution iPad screen (background views). Others, I wanted to leave at the same size, but remain at the same relative distance from a particular border (buttons). Some other ones, I left the same size and their position just scaled up with the resolution (info boxes). All in all, that was the most time-consuming part of the process. It also required a few tweaks here and there to support the resolution change correctly.</p>
<p>The other big change was updating the resolution of the 3D views. Fortunately, that was just worked without a single line change. The <a href="http://gamesfromwithin.com/opengl-and-uikit-demo">render target code</a> I&#8217;m using, takes the view dimensions and creates a frame buffer of the correct size. And it&#8217;s not just the dimensions: Remember that the iPad has a different aspect ratio (grumble, grumble), so you need to make sure your perspective and orthographic projections take that into account. </p>
<p>The only other changes I had to make was supporting an upside-down portrait orientation. That was very easy because the frame buffer didn&#8217;t have to change. Make sure you support it both at launch time and during gameplay. If you have a root controller whose view is attached directly to the main window from the start, it&#8217;s as easy as adding this to your controller:</p>
<pre>- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait ||
            interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
</pre>
<p>And make sure you add the supported orientations to your plist.</p>
<p><img src="http://gamesfromwithin.com/wp-content/uploads/2010/05/plist.png" alt="plist.png" border="0" width="491" height="69" /></p>
<p>Finally, before you submit it to the App Store, you&#8217;ll need an iPad-specific icon. The documentation explains how to explicitly list all the icons in the info file, but at the very least, you can provide a file called Icon-72.png that is a 72&#215;72 image and you&#8217;re done.</p>
<h2>Running On The Simulator</h2>
<p>This is one that should be a lot easier than it is. You&#8217;re creating a universal binary with SDK 3.2. Now you want to run it on the simulator. No problem, you run it as usual and you get the iPad simulator. You can debug it and do everything you normally do. </p>
<p>Now you want to run it on the simulator on iPhone mode. It turns out, that&#8217;s not so obvious.</p>
<p>You can&#8217;t just turn the simulator hardware setting to iPhone, because whenever you launch it from XCode it will override that again with the iPad one. Building and running on the 3.1.3 SDK is a no-no because you&#8217;re really running a different build than you&#8217;re going to be submitting (3.2) and all 3.2 SDK features you&#8217;re using are going to result in compile errors.</p>
<p>So after much searching and tweeting, here&#8217;s the solution:</p>
<ul>
<li>Build for 3.2 SDK on the simulator platform.</li>
<li>Change project drop-down to 3.1.3 SDK</li>
<p><img src="http://gamesfromwithin.com/wp-content/uploads/2010/05/sdk_version.png" alt="sdk_version.png" border="0" width="323" height="125" /></p>
<li>Launch with debugger (Cmd + Options + Y). Don&#8217;t build and run!</li>
</ul>
<p>That will launch the simulator on iPhone mode, but still run your 3.2 build. Talk about unintuitive! <a href="#2">[2]</a>. The worst thing is, when you&#8217;re done, you need to switch the project to 3.2 again or you&#8217;ll get tons of compiler errors. That definitely has to go for SDK 4.0.</p>
<p>Here&#8217;s an invaluable tip. Maybe it&#8217;s obvious to long-term Mac users, but it baffled me for a while. The iPad simulator is very well thought out, and it has a 100% and a 50% mode. That makes it possible to use the simulator on screens without very high resolution. Even my external monitor at 1680&#215;1050 can&#8217;t display the iPad simulator at full 1024&#215;768 resolution in portrait mode because of the window borders.</p>
<p>The problem comes in when you want to take a screenshot to add to the App Store or anything else. On the iPhone simulator it was easy, but how do you do that with the iPad since you can&#8217;t fit it on the screen? Cmd + Ctrl + C will take a screenshot <strong>at full resolution</strong> even when running at 50% mode and add it to the clipboard! Switch over to Preview and select New from Clipboard and voila! Full resolution screenshot!</p>
<h2>SDK 3.2 Features</h2>
<p>Chances are that even if you do a simple iPad port, you&#8217;re going to end up using a few 3.2 features. The main one I used in the case of Flower Garden is a UIPopoverController. Here you should follow the steps outlined in the Apple documentation down to a T. But it comes down to this: If a symbol that is defined on 3.2 appears anywhere, even as a member pointer variable in a class, it will compile and run on the iPad fine, but will crash and burn on the iPhone.</p>
<p>So you need to both check that the 3.2 features are available, and you need to &#8220;hide&#8221; the new symbol so it never appears anywhere: Use an id variable and cast it based on the class info. Even casting it directly to the symbol you want will cause a crash.</p>
<pre>Class classPopoverController = NSClassFromString(@"UIPopoverController");
if (classPopoverController)
{
    m_moreGamesPopover = [[classPopoverController alloc] initWithContentViewController:moreGames];
    [m_moreGamesPopover setDelegate:self];
    [m_moreGamesPopover setPopoverContentSize:CGSizeMake(320, moreGamesHeight) animated:NO];
    [m_moreGamesPopover presentPopoverFromRect:m_moreGamesButton.frame inView:self.view
                        permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
</pre>
<p>Not pretty, uh? It works, but I couldn&#8217;t imagine doing this all over the place.</p>
<h2>Gotchas</h2>
<p>In the process of creating a universal app, I found a couple more things to watch out for.</p>
<p>When you submit the new binary through iTunes Connect and it&#8217;s accepted, the application status will change to something like &#8220;Missing screenshot&#8221;. If you go back and edit the app information, you&#8217;ll see there&#8217;s a new set of screenshots you can submit. You&#8217;ll need at least one for your application to enter &#8220;Waiting for Review&#8221; state. And if you have localized descriptions of your app, you&#8217;ll need to do that for every language.</p>
<p>Last, and perhaps most puzzling because I never figured this one out: I was not able to get in-app purchases to work with a test account from a development version of a universal app running on the iPad. I must have tried everything, but whenever I tried purchasing anything, it never brought up the familiar &#8220;sandbox environment&#8221; message. Also, items that hadn&#8217;t been approved yet did not show up in the list of available items. The exact same code worked fine on an iPhone, so that&#8217;s quite puzzling. Is it a major bug on Apple&#8217;s part, or did I miss some obscure &#8220;enable IAPs in debug mode&#8221; checkbox somewhere? It was a bit of a gamble submitting it like that, but fortunately, the approved version on the App Store allows in-app purchases without any problem.</p>
<p>I thought afterwards that maybe that was because the app version on the App Store was no universal, so the Store Kit server was not allowing the iPad version to access the store through the test account. But I tried it again even after it was approved and I had the same problem.</p>
<p>Has anybody managed to use an App Store test account from an iPad on a universal app?</p>
<h2>Conclusion</h2>
<p>All in all, it was a relatively painless process considering it&#8217;s different hardware, with a different resolution, and it&#8217;s the first iteration of the SDK. Was it worth it? I think so. Apart from looking a lot better on an iPad, universal apps get ranked on both iPhone and iPad charts. Flower Garden managed to get all the way up to #14 on the free games chart on the iPad (and around #60 free app overall on the iPad). I&#8217;m sure it got some exposure from being so high up, which in turn helped the iPhone rankings as well.</p>
<p>I can&#8217;t imagine that my next game is going to be iPad-only, but I&#8217;ll certainly have the iPad in mind from the beginning and release it on both platforms. Whether I choose to go universal or separate apps will depend on the game and business decisions, but at least it&#8217;s good to know that it&#8217;s fairly easy to create a universal app.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://gamesfromwithin.com/wp-content/uploads/2010/05/flower_garden_ipad_charts.jpg" alt="flower_garden_ipad_charts.jpg" border="0" width="500" height="389" /></p>
<p><br/><br/></p>
<p><a name="1"></a>[1] Actually, there&#8217;s a pattern that is clear by looking at the hoops we have to jump to do a universal build: Apple was clearly scrambling to get this out the door. As a result, things are buggy, unintuitive, and clunky. Hopefully all that will be fixed for SDK 4.0.</p>
<p><a name="2"></a>[2] See? That confirms point <a href="#1">[1]</a>.</p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps&amp;title=Going%20The%20iPad%20Way%3A%20All%20You%20Wanted%20to%20Know%20About%20Creating%20Universal%20Apps&amp;bodytext=%0AIt%27s%20one%20thing%20to%20go%20on%20record%20saying%20I%20wouldn%27t%20be%20creating%20an%20iPad-specific%20version%20of%20Flower%20Garden%2C%20and%20another%20seeing%20the%20iPhone%20version%20running%20on%20an%20iPad%20with%20all%20the%20ugly%20jaggies%20and%20huge%2C%20pixelated%20text.%20So%20when%20it%20came%20time%20to%20do%20a%20new%20upd" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps&amp;title=Going%20The%20iPad%20Way%3A%20All%20You%20Wanted%20to%20Know%20About%20Creating%20Universal%20Apps&amp;notes=%0AIt%27s%20one%20thing%20to%20go%20on%20record%20saying%20I%20wouldn%27t%20be%20creating%20an%20iPad-specific%20version%20of%20Flower%20Garden%2C%20and%20another%20seeing%20the%20iPhone%20version%20running%20on%20an%20iPad%20with%20all%20the%20ugly%20jaggies%20and%20huge%2C%20pixelated%20text.%20So%20when%20it%20came%20time%20to%20do%20a%20new%20upd" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps&amp;t=Going%20The%20iPad%20Way%3A%20All%20You%20Wanted%20to%20Know%20About%20Creating%20Universal%20Apps" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps&amp;title=Going%20The%20iPad%20Way%3A%20All%20You%20Wanted%20to%20Know%20About%20Creating%20Universal%20Apps" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps&amp;title=Going%20The%20iPad%20Way%3A%20All%20You%20Wanted%20to%20Know%20About%20Creating%20Universal%20Apps" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=Going%20The%20iPad%20Way%3A%20All%20You%20Wanted%20to%20Know%20About%20Creating%20Universal%20Apps&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fgoing-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>GDC 2010: The Best of Both Worlds: Using UIKit with OpenGL</title>
		<link>http://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl</link>
		<comments>http://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl#comments</comments>
		<pubDate>Sat, 13 Mar 2010 18:32:31 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[opengl]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=866</guid>
		<description><![CDATA[
			
				
			
		
Here are the slides for my session at the GDC iPhone Summit, The Best of Both Worlds: Using UIKit With OpenGL.
It was a 30-minute slot, so the material is pretty condensed without the chance to expand on the topics. I&#8217;m giving an extended version of this talk at 360iDev in a few weeks, so I&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p><img class="alignright size-full wp-image-673" src="http://gamesfromwithin.com/wp-content/uploads/2010/03/borg-701632.jpg" alt="borg-701632.jpg" border="0" width="200" height="200"/>Here are the slides for my session at the <a href="http://www.gdconf.com/conference/iphone.html">GDC iPhone Summit</a>, <a href="https://www.cmpevents.com/GD10/a.asp?option=C&#038;V=11&#038;SessID=10541">The Best of Both Worlds: Using UIKit With OpenGL</a>.</p>
<p>It was a 30-minute slot, so the material is pretty condensed without the chance to expand on the topics. I&#8217;m giving an extended version of this talk at <a href="http://www.360idev.com/">360iDev</a> in a few weeks, so I&#8217;ll be able to get into more details then and have a cool sample app that shows off all those concepts.</p>
<p>It was great seeing a bunch of you at my session and at around the iPhone and Indie Summits. It was a great couple of days!</p>
<ul>
<li><a href="http://www.slideshare.net/llopis/the-best-of-both-worlds-mixing-uikit-with-opengl">Presentation slides</a> (<a href="http://gamesfromwithin.com/wp-content/uploads/2010/03/GDC10_uikit_opengl.pdf">pdf format</a>)</li>
<li><a href="http://gamesfromwithin.com/opengl-and-uikit-demo">Sample code</a></li>
</ul>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl&amp;title=GDC%202010%3A%20The%20Best%20of%20Both%20Worlds%3A%20Using%20UIKit%20with%20OpenGL&amp;bodytext=Here%20are%20the%20slides%20for%20my%20session%20at%20the%20GDC%20iPhone%20Summit%2C%20The%20Best%20of%20Both%20Worlds%3A%20Using%20UIKit%20With%20OpenGL.%0A%0AIt%20was%20a%2030-minute%20slot%2C%20so%20the%20material%20is%20pretty%20condensed%20without%20the%20chance%20to%20expand%20on%20the%20topics.%20I%27m%20giving%20an%20extended%20version%20of" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl&amp;title=GDC%202010%3A%20The%20Best%20of%20Both%20Worlds%3A%20Using%20UIKit%20with%20OpenGL&amp;notes=Here%20are%20the%20slides%20for%20my%20session%20at%20the%20GDC%20iPhone%20Summit%2C%20The%20Best%20of%20Both%20Worlds%3A%20Using%20UIKit%20With%20OpenGL.%0A%0AIt%20was%20a%2030-minute%20slot%2C%20so%20the%20material%20is%20pretty%20condensed%20without%20the%20chance%20to%20expand%20on%20the%20topics.%20I%27m%20giving%20an%20extended%20version%20of" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl&amp;t=GDC%202010%3A%20The%20Best%20of%20Both%20Worlds%3A%20Using%20UIKit%20with%20OpenGL" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl&amp;title=GDC%202010%3A%20The%20Best%20of%20Both%20Worlds%3A%20Using%20UIKit%20with%20OpenGL" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl&amp;title=GDC%202010%3A%20The%20Best%20of%20Both%20Worlds%3A%20Using%20UIKit%20with%20OpenGL" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=GDC%202010%3A%20The%20Best%20of%20Both%20Worlds%3A%20Using%20UIKit%20with%20OpenGL&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fgdc-2010-the-best-of-both-worlds-using-uikit-with-opengl&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making A Living (Barely) On The iPhone App Store (aka The Numbers Post)</title>
		<link>http://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store</link>
		<comments>http://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store#comments</comments>
		<pubDate>Fri, 15 Jan 2010 20:04:42 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[flower garden]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=801</guid>
		<description><![CDATA[
			
				
			
		
The App Store is a very hit-driven environment. A few apps sell a large amount of units, and the great majority sell next to nothing. That’s somewhat similar to the music industry, except that the audience for music is much larger, so both the big hits and the small players get more sales. We’ve drooled [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p>The App Store is a very hit-driven environment. A few apps sell a large amount of units, and the great majority sell next to nothing. That’s somewhat similar to the music industry, except that the audience for music is much larger, so both the big hits and the small players get more sales. We’ve drooled over the numbers <a href="http://firemint.com/blog/?p=123">chart</a><a href="http://games.venturebeat.com/2009/07/10/pocket-god-is-a-case-study-of-a-hit-iphone-game/"> toppers</a> sold, we’ve seen sales reports of very <a href="http://toucharcade.com/wp-content/uploads/2009/09/featured.png">successful</a> <a href="http://www.nimblebit.com/2010/01/nimblebit-numbers-2009/">games</a>, and we’ve also seen what happens when <a href="http://www.streamingcolour.com/blog/2009/03/09/the-numbers-post-aka-brutal-honesty/">apps</a> languish at the bottom.</p>
<p>I want to share the sales data for <a href="http://www.snappytouch.com/flowergarden">Flower Garden</a>. Not just the raw data, but a bit of the story behind it, my thoughts, struggles, and why things happened the way they did.</p>
<p>The first thing that you’ll notice is that Flower Garden is a strange in-between app. It’s far from being very successful or being at the top of any chart, but at the same time it probably made more money than 99% of the apps on the App Store. It was also reelased on April 10th, so this represents 10 months of data, an age after which most apps are usually on drip support. So this should be an interesting new data point.</p>
<h2>The Full Monty</h2>
<p>I know that if I put it off, you’re just going to skip to the end to see the sales plot, so let’s get that out of the way. Here it is.</p>
<p style="text-align: center;"><img class="size-full wp-image-816 aligncenter" title="Flower Garden profit" src="http://gamesfromwithin.com/wp-content/uploads/2010/01/Full.png" alt="Full" width="650" height="449" /></p>
<p>The vertical axis is daily profit in US $ (after Apple&#8217;s 30% cut). Flower Garden generated a bit over $21,500 over a period of 10 months. I would hardly consider that an entry-level salary, much less in California, but it’s enough for someone without a family or mortgage to (barely) make a living. I supplemented that with some <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">teaching</a>, <a href="http://gdmag.com/homepage.htm">writing</a>, contracting and consulting, so overall I managed do fine and even save a bit of money last year, all while being totally indie and having full creative control over what I did every day. I&#8217;m not getting rich, but it&#8217;s not a bad life, really.</p>
<p>How many hours of work does Flower Garden represent? It’s really hard to say. It was 6 solid months of work from conception to release, but then there was the fuzzy time spent on marketing, updates, support, new features, etc. I would estimate it was a total of 8 months of full time work, which, at 50 hours per week, makes it 1600 hours. So that&#8217;s a depressing $13.44/hour. At least it’s over minimum wage! <img src='http://gamesfromwithin.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  On the positive side, Flower Garden should continue to sell in the foreseeable future, so that amount will go up a bit over time.</p>
<p>There’s clearly a story behind that graph. It’s not the usual exponential drop off you expect from most (unsuccessful apps) and shows how an aging app can pick up steam on its own after many months on the store, without ever being featured by Apple.</p>
<h2>Launch</h2>
<p>Let’s start from the beginning. Release day!</p>
<p style="text-align: center;"><img class="size-full wp-image-813 aligncenter" title="Flower Garden initial profit" src="http://gamesfromwithin.com/wp-content/uploads/2010/01/Beginning2.png" alt="Beginning2" width="649" height="466" /></p>
<p>After six hard months of work, I submitted Flower Garden to Apple sometime at the beginning of April, and on April 10th I was surprised to see it had been approved. It caught me a bit off guard without my marketing campaign in place, but I announced it high and wide on <a href="http://gamesfromwithin.com/flower-garden-released">this blog</a>, Twitter, Facebook, and I even spammed all my friends with an email. The results are the area marked as (A): About $50-$60 in revenue per day (so about 25-30 sales). Not bad considering that was mostly my friends taking pity on me and people randomly seeing it on the new releases list, but it was far from an auspicious start.</p>
<p>I also contacted all the media sites I knew with a press release and promo codes to entice them to write a review. I was lucky that many reviews appeared over the next couple of weeks, but unfortunately they were all spread out, minimizing the PR effect. The biggest effect was when Flower Garden was simultaneously covered on <a href="http://toucharcade.com/2009/04/16/flower-garden-well-its-not-really-a-game/">TouchArcade</a> and <a href="http://www.macrumors.com/iphone/2009/04/16/flower-garden-for-iphone-is-a-beautifully-designed-app/">MacRumors</a>. That’s what caused the big sales spike (B). From there, it was a standard exponential drop off, until, on the last day of the month, just three weeks after launch, revenue dropped below $100/day again. If that was all there was to it, Flower Garden was a big flop and I should start dusting off my resume.</p>
<h2>Mother’s Day</h2>
<p>I wasn’t ready to throw in the towel yet. I had a couple cards up my sleeve that I was hoping would change things around. After all, May 5th is Mother’s Day in the US. What better time to do some promotion and get Flower Garden noticed?</p>
<p>I decided to run a contest and give away $100 in real flowers to the winner at the same time I put Flower Garden on sale for $1.99 for the week of Mother’s Day. The result? The revenue dip you see in (A).</p>
<p style="text-align: center;"><img class="size-full wp-image-817 aligncenter" title="Flower Garden profit in the middle" src="http://gamesfromwithin.com/wp-content/uploads/2010/01/Middle_long.png" alt="Middle_long" width="650" height="448" /></p>
<p>Mother’s day is probably the small, second spike in that period, but overall, that week was a loss. Lesson learned: Don’t make a sale unless your app is in a visible position (on a top chart somewhere). Flower Garden was nowhere to be seen, so the sale had no effect other than to cut profits by 33%.</p>
<p>I released a couple updates and did the trick updating the release date to get on the new releases list (which no longer works) and I got a couple minor spikes with (B) and (C). Subsequent updates later that summer had almost no effect anymore on sales. The trend was worryingly clear as profits dipped as low as $10/day in mid June (I have no idea what happened that day, but it was the lowest day ever for Flower Garden).</p>
<h2>App Treasures</h2>
<p>In early June we launched <a href="http://apptreasures.com">App Treasures</a>. App Treasures is a label for indie iPhone game developers with top-quality games, and one of the main tools we&#8217;re leveraging is some cross-promotion for our games, both through the web site, and from an in-game view liking to each other’s games. Initially there was no measurable effect, but then <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=313014213&amp;mt=8">Harbor Master</a> was released and shot all the way to the #2 position on the US store and held its position on the top 50 for a while. The results is the area under (D). It definitely brought in some sales to Flower Garden and reversed the downward trend.</p>
<p>Unfortunately all good things come to an end, and referrals from Harbor Master dropped off and its slipped down the charts, and Flower Garden sales continued sinking.</p>
<h2>Facebook and Lite</h2>
<p>At this point I had to face reality. Was it time to give up on Flower Garden and move on to another project? I was ready to do that, but every day I would get several emails from users saying how much they loved Flower Garden, how much happiness it was bringing to their lives, etc. Some of the stories were really touching.</p>
<p>At the same time, every time I would show the game to someone, they usually really liked it. Not liked-it-because-I’m-there, but really, genuinely liked it. Why weren’t more people buying it then? Two problems: First, screenshots were not conveying how cool growing, animated flowers you could touch were, and second, most people didn’t even know Flower Garden existed. It had never been featured by Apple on the App Store, and the audience I was trying to reach didn’t read TouchArcade or other iPhone review sites.</p>
<p>It was at this point that I decided to give it one more try. My goal wasn&#8217;t adding more features as I had done with the updates so far, but to make Flower Garden more visible. I wanted more people to know that Flower Garden existed.</p>
<p>The first thing I did was to add Facebook integration. Not only could you send bouquets through email, but you were able to send them directly to your Facebook friends. The advantage of that approach from my point of view is that all your friends also saw the flowers so for every bouquet sent on Facebook, hopefully dozens or hundreds of people were being exposed to Flower Garden. The result on sales: Not much. Maybe it made the early part of July a little higher than it would have been otherwise, but no noticeable difference.</p>
<p>The second approach was to release a lite version of Flower Garden in early September. I was confident that Flower Garden was a good app, and I was hoping that once people had a chance to try the lite version, they would purchase the full version. Fortunately I was right and the effect on sales was very noticeable, pretty much doubling sales (E), but it never really took off in any significant way, and sales slowly declined over time.</p>
<h2>Second Wind</h2>
<p>You’d think that I would give up at this point, wouldn’t you? And I don&#8217;t say that with pride. I mean, it probably would have been smarter to quit a long time ago. But somehow, every time I was ready to move on , something else would come up that would entice me to try something else with Flower Garden.</p>
<p>This time it was in-app purchases (IAP). <a href="http://developer.apple.com/iphone/program/sdk/inapppurchase.html">Apple had announced IAP</a> back in June. They seemed like a very natural fit for Flower Garden, but given how few units Flower Garden had sold, I would have a very limited audience for IAP. A small percentage of a small number is a tiny number! <img src='http://gamesfromwithin.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />  However, in late October Apple announced that <a href="http://theappleblog.com/2009/10/15/apple-allows-iphone-in-app-purchases-for-free-apps/">IAP were finally allowed from free apps</a> as well. That encouraged me to give Flower Garden one&#8230; last&#8230; try&#8230;</p>
<p>To be totally honest, I wasn’t expecting very much. Even including all the units of the Lite version out there, there just weren’t that many units. Especially not that many people using it on a daily basis (I’m sure a lot of the free ones were downloaded and quickly forgotten). But I thought it would be a good experience and if I only spent a week on it and made $1,000 I could call it even.</p>
<p style="text-align: center;"><img class="size-full wp-image-814 aligncenter" title="Flower Garden profit after IAP" src="http://gamesfromwithin.com/wp-content/uploads/2010/01/End.png" alt="End" width="650" height="448" /></p>
<p>The result was totally unexpected. The Flower Shop opened on December 6th and revenue immediately shot up (A). On December 21st I released a new IAP called Seeds of Winter with 8 new winter-themed flowers, and people loved it and immediately purchased it. Christmas day came and went with somewhat of an increase in sales (C) but nothing really spectacular. Finally, to wrap up the year, there was a big spike on New Year’s Eve (D) (do people send flowers on New Year’s Eve? Really?).</p>
<p>Afterwards revenue flattened out, but at a much higher amount than before. Before IAP, daily revenue was about $50/day. Now it’s more around $180/day. That’s totally beyond any of my expectations!</p>
<p>But hang on, where is the revenue coming from? There are three possible sources: You can purchase Flower Garden, you can make IAP in the full version, and you can also make purchases in the free version. Here’s the breakdown:</p>
<p style="text-align: center;"><img class="size-full wp-image-804 aligncenter" title="Flower Garden IAP profit broken down" src="http://gamesfromwithin.com/wp-content/uploads/2010/01/End_broken_down.png" alt="End_broken_down" width="624" height="416" /></p>
<p>It looks like sales for Flower Garden (blue) continue to be more or less the same, with a slight increase after Christmas. The IAP from the full version of Flower Garden (green) account for most of the extra revenue, especially at the beginning. But it’s very interesting that the purchases coming from Flower Garden Free (orange) are steadily increasing and, as of last week, they became almost as large as the ones from the full version.</p>
<p>That can be explained because more and more people are getting the free version and upgrading it instead of buying the full version (which is exactly what I was hoping for). What’s also really interesting is the downloads of Flower Garden Free.</p>
<p style="text-align: center;"><img class="size-full wp-image-815 aligncenter" title="Flower Garden Free downloads" src="http://gamesfromwithin.com/wp-content/uploads/2010/01/fg_free.png" alt="fg_free" width="650" height="440" /></p>
<p>Flower Garden Free was never a big player. It had the usual big initial spike, but then it settled down at around 100-200 downloads per day (which is very few considering there were 50-60 purchases per day of Flower Garden Full during that period). But, as soon as the in-app Flower Shop was released, downloads started climbing, and on Christmas day they went through the roof (relatively speaking). So it’s no surprise that IAP from Flower Garden Free picked up in these last few weeks.</p>
<h2>The Future</h2>
<p>I have no idea what the future will hold for Flower Garden. This week Apple selected Flower Garden and f<a href="http://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide">eatured it on the App Store as a Staff Favorite</a> worldwide (that period is not show in the sales graphs). I’m also already preparing a new update and some more IAP for Valentine’s Day, so I’m sure there will be more ups and downs in the near future. I&#8217;d certainly like to continue supporting Flower Garden for as long as it&#8217;s profitable.</p>
<p>I’ll follow up this post in a couple of months with the aftermath of the App Store feature and Valentine’s Day. Also, stay tuned for another post with more details of the IAP, what’s successful, purchase patterns, and more.</p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store&amp;title=Making%20A%20Living%20%28Barely%29%20On%20The%20iPhone%20App%20Store%20%28aka%20The%20Numbers%20Post%29&amp;bodytext=The%20App%20Store%20is%20a%20very%20hit-driven%20environment.%20A%20few%20apps%20sell%20a%20large%20amount%20of%20units%2C%20and%20the%20great%20majority%20sell%20next%20to%20nothing.%20That%E2%80%99s%20somewhat%20similar%20to%20the%20music%20industry%2C%20except%20that%20the%20audience%20for%20music%20is%20much%20larger%2C%20so%20both%20the%20big%20" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store&amp;title=Making%20A%20Living%20%28Barely%29%20On%20The%20iPhone%20App%20Store%20%28aka%20The%20Numbers%20Post%29&amp;notes=The%20App%20Store%20is%20a%20very%20hit-driven%20environment.%20A%20few%20apps%20sell%20a%20large%20amount%20of%20units%2C%20and%20the%20great%20majority%20sell%20next%20to%20nothing.%20That%E2%80%99s%20somewhat%20similar%20to%20the%20music%20industry%2C%20except%20that%20the%20audience%20for%20music%20is%20much%20larger%2C%20so%20both%20the%20big%20" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store&amp;t=Making%20A%20Living%20%28Barely%29%20On%20The%20iPhone%20App%20Store%20%28aka%20The%20Numbers%20Post%29" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store&amp;title=Making%20A%20Living%20%28Barely%29%20On%20The%20iPhone%20App%20Store%20%28aka%20The%20Numbers%20Post%29" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store&amp;title=Making%20A%20Living%20%28Barely%29%20On%20The%20iPhone%20App%20Store%20%28aka%20The%20Numbers%20Post%29" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=Making%20A%20Living%20%28Barely%29%20On%20The%20iPhone%20App%20Store%20%28aka%20The%20Numbers%20Post%29&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fmaking-a-living-barely-on-the-iphone-app-store&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/feed</wfw:commentRss>
		<slash:comments>78</slash:comments>
		</item>
		<item>
		<title>All About In-App Purchases Part 2: Selling The Goods</title>
		<link>http://gamesfromwithin.com/in-app-purchases-part-2</link>
		<comments>http://gamesfromwithin.com/in-app-purchases-part-2#comments</comments>
		<pubDate>Fri, 18 Dec 2009 19:17:05 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[in-app purchases]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=750</guid>
		<description><![CDATA[
			
				
			
		
The last entry about in-app purchases left off with the products correctly displayed on the store and ready for purchase. Let&#8217;s push that buy button!
Purchasing a product
The store is fully populated, the items are displayed and, if all goes well, the user presses the buy button. What now?
At this point I check that in-app purchases [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p>The <a href="http://gamesfromwithin.com/in-app-purchases-part-1">last entry about in-app purchases</a> left off with the products correctly displayed on the store and ready for purchase. Let&#8217;s push that buy button!</p>
<h3>Purchasing a product</h3>
<p><img class="alignright size-full wp-image-752" title="iap_1" src="http://gamesfromwithin.com/wp-content/uploads/2009/12/iap_1.jpg" alt="iap_1" width="319" height="309" />The store is fully populated, the items are displayed and, if all goes well, the user presses the buy button. What now?</p>
<p>At this point I check that in-app purchases are enabled and if they aren’t, I put up a message box. Apple says you can also do this earlier, but I figured I’d rather show users what’s available and entice them to buy it. By the time they get that message, they’ll be much more likely to enable them and continue the purchase than if they never saw the store in the first place.</p>
<p>Actually, before I even do that check, I see if the item is currently offered for free. If it is, the code takes an alternative path that doesn’t involve the App Store because apparently you can’t set an in-app purchase to free. Really! Why not? It’s yet something else we need to implement ourselves. Please, Apple, fix that. In the case of free purchases (like the Bonus Seeds included in the full version of Flower Garden) I contact my server directly and download everything from there. If you&#8217;re thinking that a hacker can just set the free flag to true and have access to all your content, it&#8217;s not that easy, because the server checks that the product is really marked as free when it&#8217;s contacted, and if it isn&#8217;t, it declines the transaction. So they have to work a bit harder than that to crack things (more on that next time).</p>
<p>But if the product is not marked as free and in-app purchases are enabled, then you can add the payment to the StoreKit payment queue which is, of course, another asynchronous call. So now we’re back to having to make a decision of what we want the user to do after they attempt to purchase something. Does someone really want to move away from the screen before they complete the purchase? I don’t, so I set another blocking activity screen explaining what’s going on with an activity indicator.</p>
<pre>if ([SKPaymentQueue canMakePayments])
{
    SKPayment* payment = [SKPayment paymentWithProductIdentifier:m_product.m_id];
    SKPaymentQueue* queue = [SKPaymentQueue defaultQueue];
    [queue addPayment:payment];
    [m_progressViewController setText:@"Accessing store" completed:NO];
    [m_progressViewController display:YES animated:YES];
}</pre>
<p>To be able to test the actual purchase, you need to create a test account in iTunes Connect. It’s slightly annoying that you need to explicitly log out from the Settings | Store screen and you can’t do that from the app itself, but it’s not nearly as much of a big deal as not being able to test purchases from the simulator at all. That’s a big fail as far as I’m concerned, and I can’t imagine a single reason why that was done that way (other than lack of time/manpower on Apple’s side).</p>
<h3>Completing the purchase</h3>
<p>You think we might be done by now, but not. Far from it. We’re just getting warmed up.</p>
<p>Now that the payment has entered the queue, you’re going to get a callback notification every time its status changes. That means you&#8217;ll get one right away because it was just added to the queue, another time when the payment is approved by the App Store, or when it fails, or if it’s detected that it was already purchased and this a re-purchase.</p>
<p><img class="alignright size-full wp-image-753" title="iap_2" src="http://gamesfromwithin.com/wp-content/uploads/2009/12/iap_2.jpg" alt="iap_2" width="240" height="360" />While that’s happening, the StoreKit code will bring up those ugly message boxes asking the user if they’re really sure they want to purchase the item for that price, and possibly ask them for their login info. It’s funny that the first time I implemented this part, I thought that it was up to me to put those message boxes up, so they were showing up twice. You don’t have to do anything for that, whether you want to or not. What’s worse, is that each time one of those message boxes comes up, your app gets a message putting it on hold, which usually means the sound is temporarily muted. Looks very unprofessional and I’m surprised Apple forces that on us while they leave everything else so open ended and requiring so much work.</p>
<p>Once the purchase is marked as complete, you can obtain the content for that purchase and make it available in your app. After that step is complete, you can remove the payment from the queue and the transaction is considered complete. In the case of Flower Garden, most purchases involve accessing my server and downloading some data from there for new seeds. Some purchases don’t require any downloading though, and all they do is twiddle a few bits internally.</p>
<p>It&#8217;s important to understand the payment queue well. First of all, it&#8217;s persistent, so once a purchase payment has been added to it, it will be there next time the application starts if it was never removed. It was designed that way to make sure an application can deliver on the product that was purchased even if the app is stopped, crashes, or is interrupted in any way. So initially, a payment is added to the queue meaning that the user has initiated the purchase transaction. At that point, the transaction can fail for multiple reasons: User cancels payment during one of the prompts, wrong user ID, the servers are down, the product was removed from the store, etc. Assuming the purchase is successful, the user account will be charged the cost of the product and the payment will be marked as successful. It&#8217;s at this time that you have to deliver the goods. Only once you&#8217;ve successfully done that you can go ahead and remove the payment from the queue. Otherwise, next time that the app starts, your code should detect a payment there and continue processing it. You really never want to get in a situation that the user pays for something and it&#8217;s never delivered to them.</p>
<p>I&#8217;m happy with how the StoreKit API will keep track of past purchases, and if a user tries to buy the same item again, they&#8217;ll be given the option to redownload it for free. It&#8217;s a great relief not to have to keep track of that ourselves. It will also cut down on customer support emails a huge amount because users can always redownload something if they had to uninstall their app, or somehow, in spite of all our precautions, they bought something but it was never updated in their app. In that case a quick re-download should fix it (just make sure your code is pretty stateless and can deal with re-downloading the same content multiple times).</p>
<p>It gets a bit trickier though. It turns out the payment queue can have more than one payment in it. Why is that? First of all, because the buy process wasn’t blocking the way Apple designed it, a hyperactive user could initiate multiple purchases at once. The other, more realistic situation is that the user initiates a purchase, it’s verified with the App Store, but before you can complete the download, your application is shut down. The Store Kit queue will be restored next time the application starts, but at that point the user could go to the store again and start another purchase.</p>
<p>In any case, you really need to deal with that situation, otherwise you risk losing purchases and angering users (and you really don&#8217;t want to rely on users re-downloading something for free if you can avoid it). This is trickier than it sounds when you’re dealing with downloads from your own server because it might involve multiple downloads, multiple files, etc. So in my case, whenever I get an update of status in the SKPaymentQueue, I add it to my own queue. Then I can process that queue sequentially, one purchase at the time.</p>
<pre>- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction* transaction in transactions)
        [m_transactionQueue addObject:transaction];

    [self processNextTransaction];
}

- (void)processNextTransaction
{
    if (m_processingTransaction)
        return;

    while (m_transactionQueue.count &gt; 0)
    {
        SKPaymentTransaction* transaction = [m_transactionQueue objectAtIndex:0];
        [m_transactionQueue removeObjectAtIndex:0];

        switch (transaction.transactionState)
        {
        case SKPaymentTransactionStatePurchased:
            m_processingTransaction = true;
            [self completeTransaction:transaction];
            return;
        case SKPaymentTransactionStateFailed:
            m_processingTransaction = true;
            [self failedTransaction:transaction];
            return;
        case SKPaymentTransactionStateRestored:
            m_processingTransaction = true;
            [self restoreTransaction:transaction];
            return;
        default: break;
        }
    }
}</pre>
<p>Whenever a transaction is complete, you can flag it as finished and it will be completely removed from the payment queue: [[SKPaymentQueue defaultQueue] finishTransaction:info.m_transaction];</p>
<p><br/></p>
<p>A whole  step I skipped for now is verifying the purchase with your server. I’ll cover that in the next part of this post when I talk about anti-piracy measures.</p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2&amp;title=All%20About%20In-App%20Purchases%20Part%202%3A%20Selling%20The%20Goods&amp;bodytext=The%20last%20entry%20about%20in-app%20purchases%20left%20off%20with%20the%20products%20correctly%20displayed%20on%20the%20store%20and%20ready%20for%20purchase.%20Let%27s%20push%20that%20buy%20button%21%0D%0APurchasing%20a%20product%0D%0AThe%20store%20is%20fully%20populated%2C%20the%20items%20are%20displayed%20and%2C%20if%20all%20goes%20well%2C%20" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2&amp;title=All%20About%20In-App%20Purchases%20Part%202%3A%20Selling%20The%20Goods&amp;notes=The%20last%20entry%20about%20in-app%20purchases%20left%20off%20with%20the%20products%20correctly%20displayed%20on%20the%20store%20and%20ready%20for%20purchase.%20Let%27s%20push%20that%20buy%20button%21%0D%0APurchasing%20a%20product%0D%0AThe%20store%20is%20fully%20populated%2C%20the%20items%20are%20displayed%20and%2C%20if%20all%20goes%20well%2C%20" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2&amp;t=All%20About%20In-App%20Purchases%20Part%202%3A%20Selling%20The%20Goods" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2&amp;title=All%20About%20In-App%20Purchases%20Part%202%3A%20Selling%20The%20Goods" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2&amp;title=All%20About%20In-App%20Purchases%20Part%202%3A%20Selling%20The%20Goods" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=All%20About%20In-App%20Purchases%20Part%202%3A%20Selling%20The%20Goods&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-2&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/in-app-purchases-part-2/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>All About In-App Purchases Part 1: Displaying Store Items</title>
		<link>http://gamesfromwithin.com/in-app-purchases-part-1</link>
		<comments>http://gamesfromwithin.com/in-app-purchases-part-1#comments</comments>
		<pubDate>Thu, 17 Dec 2009 19:05:44 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[in-app purchases]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=737</guid>
		<description><![CDATA[
			
				
			
		
Ever since Apple announced OS 3.0 with in-app purchases, I knew I had implement it in Flower Garden. The concept of in-app purchases fits very well with the idea of a flower shop where virtual gardeners can purchase extra items for their gardens. It was just a matter of justifying the time necessary to implement [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<p>Ever since Apple announced OS 3.0 with in-app purchases, I knew I had implement it in Flower Garden. The concept of in-app purchases fits very well with the idea of a flower shop where virtual gardeners can purchase extra items for their gardens. It was just a matter of justifying the time necessary to implement it. I knew from <a href="http://www.metacritic.com/games/platforms/xbx/mechassault">my previous experience with downloadable content in games</a> that only a small amount of the people who originally purchased the game would be interested in buying additional content. Flower Garden has been <a href="http://www.snappytouch.com/flowergarden_reviews">extremely well received</a>, both by the media and the players, but it never got high-up enough on the charts to be a big seller, so in-app purchases were doomed from the start to be very limited.</p>
<p>The situation improved as soon as Apple announced the availability of in-app purchases in free apps. Flower Garden Free had been out for a few weeks at that point, so that effectively doubled the potential audience.</p>
<p>The final consideration that convinced me to plunge ahead was the realization that while only a small percentage of users would buy extra content, a fraction of those would make multiple purchases, and some people would probably buy every available item. So maybe it would be worthwhile after all.</p>
<p><img class="alignright size-full wp-image-741" title="fg_flowershop2" src="http://gamesfromwithin.com/wp-content/uploads/2009/12/fg_flowershop2.jpg" alt="fg_flowershop2" width="240" height="360" />Having said that, I gave myself one week to completely implement in-app purchases in Flower Garden. That included everything, from implementing the actual purchasing through StoreKit, to server code, and, of course, creating the additional content itself.</p>
<p>For those of you familiar with Flower Garden, the new content I created specifically for in-app purchases was a flower shop offering:</p>
<ul>
<li>An extra garden screen with 12 pots</li>
<li>Liquid plant fertilizer that speeds up plant growth. This is a consumable item with a fixed number of doses and can be repurchased after it’s used up.</li>
</ul>
<p>Additionally, the flower shop in the free version of Flower Garden had these items that would bring it functionality up to par with the full version of Flower Garden:</p>
<ul>
<li>Extra pots in the main garden</li>
<li>Extra common seeds</li>
<li>Set of bonus seeds</li>
</ul>
<p>My initial estimate of one week turned out to be very optimistic, and it ended up taking closer to two and a half weeks. Most of it was spent creating the new content and integrating it smoothly in the game.</p>
<p>In this post and the next few ones, I’ll share my experiences with in-app purchases. From implementation details, tips and tricks, how it might help with piracy, mistakes I made along the way, and even how many sales in-app purchases generated.</p>
<h2>Displaying Store Items</h2>
<p>Apple did a good job documenting the <a href="http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction/Introduction.html">overview of how to implement in-app purchases</a>. Some of the details are missing, but they&#8217;re small enough that I was able to fill in the blanks pretty easily and get things working in a couple of days.</p>
<p>However, I really think the process should have been implemented very differently in Apple’s part. The sequence of actions that needs to be done feels overly complicated. It may be great if someone is trying to do a very customized and integrated store with all sorts of crazy features, but really, in 99% of the cases, developers just want to sell something and be done with it. Forcing us to go through all those steps seems overkill. A simplified higher-level set of helper functions would be a welcome addition to the SDK. For suggestions on how to go about it, look at the SDK for game consoles. They got that part right (or at least much more right than the iPhone SDK).</p>
<h3>Getting the catalog</h3>
<p>The first step towards implementing in-app purchases, is to get a list of all the products you want to sell in your store. It’s a good idea to keep this list off your app and on a web server instead, that way you can add, remove, or edit any products without going through a full app update. That in itself makes in-app purchases very attractive, doesn’t it? You can have a look at the <a href="http://flowers.snappytouch.com/Shop/ShopCatalog.plist">master Flower Garden shop catalog</a>.</p>
<h3>Getting product info</h3>
<p>Step two is to go through each of those products, and get the official product information from the App Store. That involves creating a set with the product ids you want to query, and sending a request.</p>
<p>The code in Flower Garden to query for product ids looks like this:</p>
<pre>NSArray* products = m_appData-&gt;m_shopCatalog.m_products;
NSMutableSet* productIds = [[NSMutableSet alloc] initWithCapacity:32];
for (int i=0; i&lt;[products count]; ++i)
{
    ShopProduct* product = [products objectAtIndex:i];
    if (!product.m_alreadyIncluded)
        [productIds addObject:product.m_id];
}

SKProductsRequest* request = [[SKProductsRequest alloc] initWithProductIdentifiers:productIds];
request.delegate = self;
#ifdef WORK_WITHOUT_APP_STORE
[self productsRequest:request didReceiveResponse:nil];
#else
[request start];
#endif
[productIds release];</pre>
<p>There are a couple interesting things in that code. First of all, notice that before we ask for the product info, we check if the product is already included in the app. That’s because some items, such as the extra pots or the common seeds, already come as part of Flower Garden Full. But at the same time, I wanted to show them in the store and mark them as purchased. So I need to have a parallel path for those items that doesn’t go through the App Store. More on that in a future post.</p>
<p>The other interesting bit is the #ifdef. This one really sucks, so get ready: The simulator can’t make any StoreKit calls. It fails with a nice message box explaining why, but it fails nonetheless. To put it in highly technical terms: That blows! Seriously, that means you’re stuck developing on the device. Turnaround times are about 20-30 seconds, and debugging on the device directly is no fun at all. I’m convinced that alone was part of the reason it took me longer than my initial estimate. So that #ifdef was my attempt to try to get as much done on the simulator as possible. At least I was able to display the products on the flower shop. The actual buying had to be done on the device though. No way around it as far as I know. Why, oh, why, doesn’t Apple let us add a test account on the simulator? Maybe a feature for SDK 4.0?</p>
<h3>Displaying the products</h3>
<p><img class="alignright size-full wp-image-742" title="fg_flowershop3" src="http://gamesfromwithin.com/wp-content/uploads/2009/12/fg_flowershop3.jpg" alt="fg_flowershop3" width="240" height="360" /></p>
<p>Some time after sending the request for info on the products, and assuming we have a valid internet connection and that the App Store is in a good mood (to their credit, Apple’s servers have been very reliable), we’ll get a response. The response will include more information for each of the products we requested, including localized name, description, and price. This is all information taken from the in-app purchases you created in iTunes Connect. And yes, that means that you need to keep multiple sets of data in sync: Your shop catalog and the in-app purchases in iTunes Connect.</p>
<p>Notice that because everything we’ve done so far has been asynchronous (and asynchronous is the name of the game for a lot of the remaining steps as well) it introduces a lot of complexity. What do we do during that time? Do we let the user wander around to other parts of the program? Do we block and make the UI modal? I went with the latter approach for simplicity both coding and in the UI for the user.</p>
<p>At this point you can display them in your shop. In my case I ended up using a very similar interface to the App Store on the iPhone. I figured users are already familiar with that kind of interface, so might as well build on top of that. So that meant the flower shop is a table showing all available products. Clicking on a cell brings up a view with details and a description of each product.</p>
<p>To make my life easier, the only elements that are hardwired on the product page are the icon, the title, and the price/purchase button. The actual description and screenshots is just an embedded web view and part of the product description in the catalog has the correct URL for each project. You can even access <a href="http://flowers.snappytouch.com/Shop/catalog/CourtyardDesc.html">some of them directly here</a>.</p>
<p>So far all this has done for us is let us populate a list of products that are available to be sold. Next entry will cover the details of the actual transaction and a few things to watch out for.</p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1&amp;title=All%20About%20In-App%20Purchases%20Part%201%3A%20Displaying%20Store%20Items&amp;bodytext=Ever%20since%20Apple%20announced%20OS%203.0%20with%20in-app%20purchases%2C%20I%20knew%20I%20had%20implement%20it%20in%20Flower%20Garden.%20The%20concept%20of%20in-app%20purchases%20fits%20very%20well%20with%20the%20idea%20of%20a%20flower%20shop%20where%20virtual%20gardeners%20can%20purchase%20extra%20items%20for%20their%20gardens.%20It%20" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1&amp;title=All%20About%20In-App%20Purchases%20Part%201%3A%20Displaying%20Store%20Items&amp;notes=Ever%20since%20Apple%20announced%20OS%203.0%20with%20in-app%20purchases%2C%20I%20knew%20I%20had%20implement%20it%20in%20Flower%20Garden.%20The%20concept%20of%20in-app%20purchases%20fits%20very%20well%20with%20the%20idea%20of%20a%20flower%20shop%20where%20virtual%20gardeners%20can%20purchase%20extra%20items%20for%20their%20gardens.%20It%20" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1&amp;t=All%20About%20In-App%20Purchases%20Part%201%3A%20Displaying%20Store%20Items" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1&amp;title=All%20About%20In-App%20Purchases%20Part%201%3A%20Displaying%20Store%20Items" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1&amp;title=All%20About%20In-App%20Purchases%20Part%201%3A%20Displaying%20Store%20Items" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=All%20About%20In-App%20Purchases%20Part%201%3A%20Displaying%20Store%20Items&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fin-app-purchases-part-1&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/in-app-purchases-part-1/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Data-Oriented Design (Or Why You Might Be Shooting Yourself in The Foot With OOP)</title>
		<link>http://gamesfromwithin.com/data-oriented-design</link>
		<comments>http://gamesfromwithin.com/data-oriented-design#comments</comments>
		<pubDate>Fri, 04 Dec 2009 19:40:20 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Data-oriented design]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Game tech]]></category>
		<category><![CDATA[game developer magazine]]></category>
		<category><![CDATA[inner product]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=723</guid>
		<description><![CDATA[
			
				
			
		
Picture this: Toward the end of the development cycle, your game crawls, but you don’t see any obvious hotspots in the profiler. The culprit? Random memory access patterns and constant cache misses. In an attempt to improve performance, you try to parallelize parts of the code, but it takes heroic efforts, and, in the end, [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design&amp;source=snappytouch&amp;style=normal&amp;service=bit.ly&amp;service_api=R_185f898b3dec44c3a4de33e8fccadcf7" height="61" width="50" /><br />
			</a>
		</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Picture this: Toward the end of the development cycle, your game crawls, but you don’t see any obvious hotspots in the profiler. The culprit? Random memory access patterns and constant cache misses. In an attempt to improve performance, you try to parallelize parts of the code, but it takes heroic efforts, and, in the end, you barely get much of a speed-up due to all the synchronization you had to add. To top it off, the code is so complex that fixing bugs creates more problems, and the thought of adding new features is discarded right away. Sound familiar?</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">That scenario pretty accurately describes almost every game I’ve been involved with for the last 10 years. The reasons aren’t the programming languages we’re using, nor the development tools, nor even a lack of discipline. In my experience, it’s object- oriented programming (OOP) and the culture that surrounds it that is in large part to blame for those problems. OOP could be hindering your project rather than helping it!</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">It&#8217;s All About Data</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">OOP is so ingrained in the current game development culture that it’s hard to think beyond objects when thinking about a game. After all, we’ve been creating classes representing vehicles, players, and state machines for many years. What are the alternatives? Procedural programming? Functional languages? Exotic programming languages?</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Data-oriented design is a different way to approach program design that addresses all these problems. Procedural programming focuses on procedure calls as its main element, and OOP deals primarily with objects. Notice that the main focus of both approaches is code: plain procedures (or functions) in one case, and grouped code associated with some internal state in the other. Data-oriented design shifts the perspective of programming from objects to the data itself: The type of the data, how it is laid out in memory, and how it will be read and processed in the game.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Programming, by definition, is about transforming data: It’s the act of creating a sequence of machine instructions describing how to process the input data and create some specific output data. A game is nothing more than a program that works at interactive rates, so wouldn’t it make sense for us to concentrate primarily on that data instead of on the code that manipulates it?</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">I’d like to clear up potential confusion and stress that data-oriented design does not imply that something is data- driven. A data-driven game is usually a game that exposes a large amount of functionality outside of code and lets the data determine the behavior of the game. That is an orthogonal concept to data-oriented design, and can be used with any type of programming approach.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Ideal Data</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">If we look at a program from the data point of view, what does the ideal data look like? It depends on the data and how it’s used. In general, the ideal data is in a format that we can use with the least amount of effort. In the best case, the format will be the same we expect as an output, so the processing is limited to just copying that data. Very often, our ideal data layout will be large blocks of contiguous, homogeneous data that we can process sequentially. In any case, the goal is to minimize the amount of transformations, and whenever possible, you should bake your data into this ideal format offline, during your asset-building process.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Because data-oriented design puts data first and foremost, we can architect our whole program around the ideal data format. We won’t always be able to make it exactly ideal (the same way that code is hardly ever by-the-book OOP), but it’s the primary goal to keep in mind. Once we achieve that, most of the problems I mentioned at the beginning of the column tend to melt away (more about that in the next section).</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">When we think about objects, we immediately think of trees— inheritance trees, containment trees, or message-passing trees, and our data is naturally arranged that way. As a result, when we perform an operation on an object, it will usually result in that object in turn accessing other objects further down in the tree. Iterating over a set of objects performing the same operation generates cascading, totally different operations at each object (see Figure 1a).</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">To achieve the best possible data layout, it’s helpful to break down each object into the different components, and group components of the same type together in memory, regardless of what object they came from. This organization results in large blocks of homogeneous data, which allow us to process the data sequentially (see Figure 1b). A key reason why data-oriented design is so powerful is because it works very well on large groups of objects. OOP, by definition, works on a single object. Step back for a minute and think of the last game you worked on: How many places in the code did you have only one of something? One enemy? One vehicle? One pathfinding node? One bullet? One particle? Never! Where there’s one, there are many. OOP ignores that and deals with each object in isolation. Instead, we can make things easy for us and for the hardware and organize our data to deal with the common case of having many items of the same type.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Does this sound like a strange approach? Guess what? You’re probably already doing this in some parts of your code: The particle system! Data-oriented design is turning our whole codebase into a gigantic particle system. Perhaps a name for this approach that would be more familiar to game programmers would have been particle-driven programming.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Advantages of Data-Oriented Design</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">hinking about data first and architecting the program based on that brings along lots of advantages.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Parallelization.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">These days, there’s no way around the fact that we need to deal with multiple cores. Anyone who has tried taking some OOP code and parallelizing it can attest how difficult, error prone, and possibly not very efficient that is. Often you end up adding lots of synchronization primitives to prevent concurrent access to data from multiple threads, and usually a lot of the threads end up idling for quite a while waiting for other threads to complete. As a result, the performance improvement can be quite underwhelming.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">When we apply data-oriented design, parallelization becomes a lot simpler: We have the input data, a small function to process it, and some output data. We can easily take something like that and split it among multiple threads with minimal synchronization between them. We can even take it further and run that code on processors with local memory (like the SPUs on the Cell processor) without having to do anything differently.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Cache utilization.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">In addition to using multiple cores, one of the keys to achieving great performance in modern hardware, with its deep instruction pipelines and slow memory systems with multiple levels of caches, is having cache-friendly memory access. Data-oriented design results in very efficient use of the instruction cache because the same code is executed over and over. Also, if we lay out the data in large, contiguous blocks, we can process the data sequentially, getting nearly perfect data cache usage and great performance. Possible optimizations. When we think of objects or functions, we tend to get stuck optimizing at the function or even the algorithm level; Reordering some function calls, changing the sort method, or even re-writing some C code with assembly.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">That kind of optimization is certainly beneficial, but by thinking about the data first we can step further back and make larger, more important optimizations. Remember that all a game does is transform some data (assets, inputs, state) into some other data (graphics commands, new game states). By keeping in mind that flow of data, we can make higher-level, more intelligent decisions based on how the data is transformed, and how it is used. That kind of optimization can be extremely difficult and time- consuming to implement with more traditional OOP methods.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Modularity.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">So far, all the advantages of data-oriented design have been based around performance: cache utilization, optimizations, and parallelization. There is no doubt that as game programmers, performance is an extremely important goal for us. There is often a conflict between techniques that improve performance and techniques that help readability and ease of development. For example, re-writing some code in assembly language can result in a performance boost, but usually makes the code harder to read and maintain.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Fortunately, data-oriented design is beneficial to both performance and ease of development. When you write code specifically to transform data, you end up with small functions, with very few dependencies on other parts of the code. The codebase ends up being very “flat,” with lots of leaf functions without many dependencies. This level of modularity and lack of dependences makes understanding, replacing, and updating the code much easier.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Testing.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The last major advantage of data-oriented design is ease of testing. As we saw in the June and August Inner Product columns, writing unit tests to check object interactions is not trivial. You need to set up mocks and test things indirectly. Frankly, it’s a bit of a pain. On the other hand, when dealing directly with data, it couldn’t be easier to write unit tests: Create some input data, call the transform function, and check that the output data is what we expect. There’s nothing else to it. This is actually a huge advantage and makes code extremely easy to test, whether you’re doing test-driven development or just writing unit tests after the code.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Drawbacks of Data-Oriented Design</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Data-oriented design is not the silver bullet to all the problems in game development. It does help tremendously writing high-performance code and making programs more readable and easier to maintain, but it does come with a few drawbacks of its own.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The main problem with data-oriented design is that it’s different from what most programmers are used to or learned in school. It requires turning our mental model of the program ninety degrees and changing how we think about it. It takes some practice before it becomes second-nature.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Also, because it’s a different approach, it can be challenging to interface with existing code, written in a more OOP or procedural way. It’s hard to write a single function in isolation, but as long as you can apply data-oriented design to a whole subsystem you should be able to reap a lot of the benefits.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Applying Data-Oriented Design</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Enough of the theory and overview. How do you actually get started with data-oriented design? To start with, just pick a specific area in your code: navigation, animations, collisions, or something else. Later on, when most of your game engine is centered around the data, you can worry about data flow all the way from the start of a frame until the end.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The next step is to clearly identify the data inputs required by the system, and what kind of data it needs to generate. It’s OK to think about it in OOP terms for now, just to help us identify the data. For example, in an animation system, some of the input data is skeletons, base poses, animation data, and current state. The result is not “the code plays animations,” but the data generated by the animations that are currently playing. In this case, our outputs would be a new set of poses and an updated state.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">It’s important to take a step further and classify the input data based on how it is used. Is it read- only, read-write, or write-only? That classification will help guide design decisions about where to store it, and when to process it depending on dependencies with other parts of the program.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">At this point, stop thinking of the data required for a single operation, and think in terms of applying it to dozens or hundreds of entries. We no longer have one skeleton, one base pose, and a current state, and instead we have a block of each of those types with many instances in each of the blocks.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Think very carefully how the data is used during the transformation process from input to output. You might realize that you need to scan a particular field in a structure to perform a pass on the data, and then you need to use the results to do another pass. In that case, it might make more sense to split that initial field into a separate block of memory that can be processed independently, allowing for better cache utilization and potential parallelization. Or maybe you need to vectorize some part of the code, which requires fetching data from different locations to put it in the same vector register. In that case, that data can be stored contiguously so vector operations can be applied directly, without any extra transformations.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Now you should have a very good understanding of your data. Writing the code to transform it is going to be much simpler. It’s like writing code by filling in the blanks. You’ll even be pleasantly surprised to realize that the code is much simpler and smaller than you thought in the first place, compared to what the equivalent OOP code would have been.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">If you think back about most of the topics we’ve covered in this column over the last year, you’ll see that they were all leading toward this type of design. Now it’s the time to be careful about how the data is aligned (Dec 2008 and Jan 2009), to bake data directly into an input format that you can use efficiently (Oct and Nov 2008), or to use non- pointer references between data blocks so they can be easily relocated (Sept 2009).</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Is Thre Room For OOP?</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Does this mean that OOP is useless and you should never apply it in your programs? I’m not quite ready to say that. Thinking in terms of objects is not detrimental when there is only one of each object (a graphics device, a log manager, etc) although in that case you might as well write it with simpler C-style functions and file-level static data. Even in that situation, it’s still important that those objects are designed around transforming data.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Another situation where I still find myself using OOP is GUI systems. Maybe it’s because you’re working with a system that is already designed in an object-oriented way, or maybe it’s because performance and complexity are not crucial factors with GUI code. In any case, I much prefer GUI APIs that are light on inheritance and use containment as much as possible (Cocoa and CocoaTouch are good examples of this). It’s very possible that a data-oriented GUI system could be written for games that would be a pleasure to work with, but I haven’t seen one yet.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Finally, there’s nothing stopping you from still having a mental picture of objects if that’s the way you like to think about the game. It’s just that the enemy entity won’t be all in the same physical location in memory. Instead, it will be split up into smaller subcomponents, each one forming part of a larger data table of similar components.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Data-oriented design is a bit of a departure from traditional programming approaches, but by always thinking about the data and how it needs to be transformed, you’ll be able to reap huge benefits both in terms of performance and ease of development.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Thanks to Mike Acton and Jim Tilander for challenging my ideas over the years and for their feedback on this article.</div>
<p>Picture this: Toward the end of the development cycle, your game crawls, but you don’t see any obvious hotspots in the profiler. The culprit? Random memory access patterns and constant cache misses. In an attempt to improve performance, you try to parallelize parts of the code, but it takes heroic efforts, and, in the end, you barely get much of a speed-up due to all the synchronization you had to add. To top it off, the code is so complex that fixing bugs creates more problems, and the thought of adding new features is discarded right away. Sound familiar?</p>
<p>That scenario pretty accurately describes almost every game I’ve been involved with for the last 10 years. The reasons aren’t the programming languages we’re using, nor the development tools, nor even a lack of discipline. In my experience, it’s object- oriented programming (OOP) and the culture that surrounds it that is in large part to blame for those problems. OOP could be hindering your project rather than helping it!</p>
<h2>It&#8217;s All About Data</h2>
<p>OOP is so ingrained in the current game development culture that it’s hard to think beyond objects when thinking about a game. After all, we’ve been creating classes representing vehicles, players, and state machines for many years. What are the alternatives? Procedural programming? Functional languages? Exotic programming languages?</p>
<p>Data-oriented design is a different way to approach program design that addresses all these problems. Procedural programming focuses on procedure calls as its main element, and OOP deals primarily with objects. Notice that the main focus of both approaches is code: plain procedures (or functions) in one case, and grouped code associated with some internal state in the other. Data-oriented design shifts the perspective of programming from objects to the data itself: The type of the data, how it is laid out in memory, and how it will be read and processed in the game.</p>
<p>Programming, by definition, is about transforming data: It’s the act of creating a sequence of machine instructions describing how to process the input data and create some specific output data. A game is nothing more than a program that works at interactive rates, so wouldn’t it make sense for us to concentrate primarily on that data instead of on the code that manipulates it?</p>
<p>I’d like to clear up potential confusion and stress that data-oriented design does not imply that something is data- driven. A data-driven game is usually a game that exposes a large amount of functionality outside of code and lets the data determine the behavior of the game. That is an orthogonal concept to data-oriented design, and can be used with any type of programming approach.</p>
<h2>Ideal Data</h2>
<div id="attachment_726" class="wp-caption alignright" style="width: 239px"><img class="size-full wp-image-726 " title="oo_design" src="http://gamesfromwithin.com/wp-content/uploads/2009/12/oo_design.png" alt="Call sequence with an object-oriented approach" width="229" height="247" /><p class="wp-caption-text">Figure 1a. Call sequence with an object-oriented approach</p></div>
<p>If we look at a program from the data point of view, what does the ideal data look like? It depends on the data and how it’s used. In general, the ideal data is in a format that we can use with the least amount of effort. In the best case, the format will be the same we expect as an output, so the processing is limited to just copying that data. Very often, our ideal data layout will be large blocks of contiguous, homogeneous data that we can process sequentially. In any case, the goal is to minimize the amount of transformations, and whenever possible, you should bake your data into this ideal format offline, during your asset-building process.</p>
<p>Because data-oriented design puts data first and foremost, we can architect our whole program around the ideal data format. We won’t always be able to make it exactly ideal (the same way that code is hardly ever by-the-book OOP), but it’s the primary goal to keep in mind. Once we achieve that, most of the problems I mentioned at the beginning of the column tend to melt away (more about that in the next section).</p>
<p>When we think about objects, we immediately think of trees— inheritance trees, containment trees, or message-passing trees, and our data is naturally arranged that way. As a result, when we perform an operation on an object, it will usually result in that object in turn accessing other objects further down in the tree. Iterating over a set of objects performing the same operation generates cascading, totally different operations at each object (see Figure 1a).</p>
<div id="attachment_728" class="wp-caption alignright" style="width: 243px"><img class="size-full wp-image-728 " title="do_design" src="http://gamesfromwithin.com/wp-content/uploads/2009/12/do_design1.png" alt="Call sequence with a data-oriented approach" width="233" height="297" /><p class="wp-caption-text">Figure 1b. Call sequence with a data-oriented approach</p></div>
<p>To achieve the best possible data layout, it’s helpful to break down each object into the different components, and group components of the same type together in memory, regardless of what object they came from. This organization results in large blocks of homogeneous data, which allow us to process the data sequentially (see Figure 1b). A key reason why data-oriented design is so powerful is because it works very well on large groups of objects. OOP, by definition, works on a single object. Step back for a minute and think of the last game you worked on: How many places in the code did you have only one of something? One enemy? One vehicle? One pathfinding node? One bullet? One particle? Never! Where there’s one, there are many. OOP ignores that and deals with each object in isolation. Instead, we can make things easy for us and for the hardware and organize our data to deal with the common case of having many items of the same type.</p>
<p>Does this sound like a strange approach? Guess what? You’re probably already doing this in some parts of your code: The particle system! Data-oriented design is turning our whole codebase into a gigantic particle system. Perhaps a name for this approach that would be more familiar to game programmers would have been particle-driven programming.</p>
<h2>Advantages of Data-Oriented Design</h2>
<p>Thinking about data first and architecting the program based on that brings along lots of advantages.</p>
<h3>Parallelization.</h3>
<p>These days, there’s no way around the fact that we need to deal with multiple cores. Anyone who has tried taking some OOP code and parallelizing it can attest how difficult, error prone, and possibly not very efficient that is. Often you end up adding lots of synchronization primitives to prevent concurrent access to data from multiple threads, and usually a lot of the threads end up idling for quite a while waiting for other threads to complete. As a result, the performance improvement can be quite underwhelming.</p>
<p>When we apply data-oriented design, parallelization becomes a lot simpler: We have the input data, a small function to process it, and some output data. We can easily take something like that and split it among multiple threads with minimal synchronization between them. We can even take it further and run that code on processors with local memory (like the SPUs on the Cell processor) without having to do anything differently.</p>
<h3>Cache utilization.</h3>
<p>In addition to using multiple cores, one of the keys to achieving great performance in modern hardware, with its deep instruction pipelines and slow memory systems with multiple levels of caches, is having cache-friendly memory access. Data-oriented design results in very efficient use of the instruction cache because the same code is executed over and over. Also, if we lay out the data in large, contiguous blocks, we can process the data sequentially, getting nearly perfect data cache usage and great performance. Possible optimizations. When we think of objects or functions, we tend to get stuck optimizing at the function or even the algorithm level; Reordering some function calls, changing the sort method, or even re-writing some C code with assembly.</p>
<p>That kind of optimization is certainly beneficial, but by thinking about the data first we can step further back and make larger, more important optimizations. Remember that all a game does is transform some data (assets, inputs, state) into some other data (graphics commands, new game states). By keeping in mind that flow of data, we can make higher-level, more intelligent decisions based on how the data is transformed, and how it is used. That kind of optimization can be extremely difficult and time- consuming to implement with more traditional OOP methods.</p>
<h3>Modularity.</h3>
<p>So far, all the advantages of data-oriented design have been based around performance: cache utilization, optimizations, and parallelization. There is no doubt that as game programmers, performance is an extremely important goal for us. There is often a conflict between techniques that improve performance and techniques that help readability and ease of development. For example, re-writing some code in assembly language can result in a performance boost, but usually makes the code harder to read and maintain.</p>
<p>Fortunately, data-oriented design is beneficial to both performance and ease of development. When you write code specifically to transform data, you end up with small functions, with very few dependencies on other parts of the code. The codebase ends up being very “flat,” with lots of leaf functions without many dependencies. This level of modularity and lack of dependences makes understanding, replacing, and updating the code much easier.</p>
<h3>Testing.</h3>
<p>The last major advantage of data-oriented design is ease of testing. As we saw in the June and August Inner Product columns, writing unit tests to check object interactions is not trivial. You need to set up mocks and test things indirectly. Frankly, it’s a bit of a pain. On the other hand, when dealing directly with data, it couldn’t be easier to write unit tests: Create some input data, call the transform function, and check that the output data is what we expect. There’s nothing else to it. This is actually a huge advantage and makes code extremely easy to test, whether you’re doing test-driven development or just writing unit tests after the code.</p>
<h2>Drawbacks of Data-Oriented Design</h2>
<p>Data-oriented design is not the silver bullet to all the problems in game development. It does help tremendously writing high-performance code and making programs more readable and easier to maintain, but it does come with a few drawbacks of its own.</p>
<p>The main problem with data-oriented design is that it’s different from what most programmers are used to or learned in school. It requires turning our mental model of the program ninety degrees and changing how we think about it. It takes some practice before it becomes second-nature.</p>
<p>Also, because it’s a different approach, it can be challenging to interface with existing code, written in a more OOP or procedural way. It’s hard to write a single function in isolation, but as long as you can apply data-oriented design to a whole subsystem you should be able to reap a lot of the benefits.</p>
<h2>Applying Data-Oriented Design</h2>
<p>Enough of the theory and overview. How do you actually get started with data-oriented design? To start with, just pick a specific area in your code: navigation, animations, collisions, or something else. Later on, when most of your game engine is centered around the data, you can worry about data flow all the way from the start of a frame until the end.</p>
<p>The next step is to clearly identify the data inputs required by the system, and what kind of data it needs to generate. It’s OK to think about it in OOP terms for now, just to help us identify the data. For example, in an animation system, some of the input data is skeletons, base poses, animation data, and current state. The result is not “the code plays animations,” but the data generated by the animations that are currently playing. In this case, our outputs would be a new set of poses and an updated state.</p>
<p>It’s important to take a step further and classify the input data based on how it is used. Is it read- only, read-write, or write-only? That classification will help guide design decisions about where to store it, and when to process it depending on dependencies with other parts of the program.</p>
<p>At this point, stop thinking of the data required for a single operation, and think in terms of applying it to dozens or hundreds of entries. We no longer have one skeleton, one base pose, and a current state, and instead we have a block of each of those types with many instances in each of the blocks.</p>
<p>Think very carefully how the data is used during the transformation process from input to output. You might realize that you need to scan a particular field in a structure to perform a pass on the data, and then you need to use the results to do another pass. In that case, it might make more sense to split that initial field into a separate block of memory that can be processed independently, allowing for better cache utilization and potential parallelization. Or maybe you need to vectorize some part of the code, which requires fetching data from different locations to put it in the same vector register. In that case, that data can be stored contiguously so vector operations can be applied directly, without any extra transformations.</p>
<p>Now you should have a very good understanding of your data. Writing the code to transform it is going to be much simpler. It’s like writing code by filling in the blanks. You’ll even be pleasantly surprised to realize that the code is much simpler and smaller than you thought in the first place, compared to what the equivalent OOP code would have been.</p>
<p>If you think back about most of the topics we’ve covered in this column over the last year, you’ll see that they were all leading toward this type of design. Now it’s the time to be careful about how the data is aligned (Dec 2008 and Jan 2009), to bake data directly into an input format that you can use efficiently (Oct and Nov 2008), or to use non- pointer references between data blocks so they can be easily relocated (Sept 2009).</p>
<h2>Is There Room For OOP?</h2>
<p>Does this mean that OOP is useless and you should never apply it in your programs? I’m not quite ready to say that. Thinking in terms of objects is not detrimental when there is only one of each object (a graphics device, a log manager, etc) although in that case you might as well write it with simpler C-style functions and file-level static data. Even in that situation, it’s still important that those objects are designed around transforming data.</p>
<p>Another situation where I still find myself using OOP is GUI systems. Maybe it’s because you’re working with a system that is already designed in an object-oriented way, or maybe it’s because performance and complexity are not crucial factors with GUI code. In any case, I much prefer GUI APIs that are light on inheritance and use containment as much as possible (Cocoa and CocoaTouch are good examples of this). It’s very possible that a data-oriented GUI system could be written for games that would be a pleasure to work with, but I haven’t seen one yet.</p>
<p>Finally, there’s nothing stopping you from still having a mental picture of objects if that’s the way you like to think about the game. It’s just that the enemy entity won’t be all in the same physical location in memory. Instead, it will be split up into smaller subcomponents, each one forming part of a larger data table of similar components.</p>
<p>Data-oriented design is a bit of a departure from traditional programming approaches, but by always thinking about the data and how it needs to be transformed, you’ll be able to reap huge benefits both in terms of performance and ease of development.</p>
<p><br/><br/></p>
<p>Thanks to <a href="http://www.cellperformance.com/mike_acton">Mike Acton</a> and <a href="http://www.tilander.org/aurora/">Jim Tilander</a> for challenging my ideas over the years and for their feedback on this article.</p>
<p>This article was originally printed in the September 2009 issue of <a href="http://gdmag.com">Game Developer</a>.</p>




	<a rel="nofollow"  href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design&amp;title=Data-Oriented%20Design%20%28Or%20Why%20You%20Might%20Be%20Shooting%20Yourself%20in%20The%20Foot%20With%20OOP%29&amp;bodytext=Picture%20this%3A%20Toward%20the%20end%20of%20the%20development%20cycle%2C%20your%20game%20crawls%2C%20but%20you%20don%E2%80%99t%20see%20any%20obvious%20hotspots%20in%20the%20profiler.%20The%20culprit%3F%20Random%20memory%20access%20patterns%20and%20constant%20cache%20misses.%20In%20an%20attempt%20to%20improve%20performance%2C%20you%20try%20to%20" title="Digg"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://delicious.com/post?url=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design&amp;title=Data-Oriented%20Design%20%28Or%20Why%20You%20Might%20Be%20Shooting%20Yourself%20in%20The%20Foot%20With%20OOP%29&amp;notes=Picture%20this%3A%20Toward%20the%20end%20of%20the%20development%20cycle%2C%20your%20game%20crawls%2C%20but%20you%20don%E2%80%99t%20see%20any%20obvious%20hotspots%20in%20the%20profiler.%20The%20culprit%3F%20Random%20memory%20access%20patterns%20and%20constant%20cache%20misses.%20In%20an%20attempt%20to%20improve%20performance%2C%20you%20try%20to%20" title="del.icio.us"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.facebook.com/share.php?u=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design&amp;t=Data-Oriented%20Design%20%28Or%20Why%20You%20Might%20Be%20Shooting%20Yourself%20in%20The%20Foot%20With%20OOP%29" title="Facebook"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://reddit.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design&amp;title=Data-Oriented%20Design%20%28Or%20Why%20You%20Might%20Be%20Shooting%20Yourself%20in%20The%20Foot%20With%20OOP%29" title="Reddit"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design&amp;title=Data-Oriented%20Design%20%28Or%20Why%20You%20Might%20Be%20Shooting%20Yourself%20in%20The%20Foot%20With%20OOP%29" title="StumbleUpon"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="mailto:?subject=Data-Oriented%20Design%20%28Or%20Why%20You%20Might%20Be%20Shooting%20Yourself%20in%20The%20Foot%20With%20OOP%29&amp;body=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design" title="email"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/email_link.png" title="email" alt="email" class="sociable-hovers" /></a>
	<a rel="nofollow"  href="http://www.printfriendly.com/print?url=http%3A%2F%2Fgamesfromwithin.com%2Fdata-oriented-design&amp;partner=sociable" title="PDF"><img src="http://gamesfromwithin.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/data-oriented-design/feed</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
	</channel>
</rss>
