<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ios on Games From Within</title><link>https://gamesfromwithin.com/category/ios/</link><description>Recent content in Ios on Games From Within</description><generator>Hugo</generator><language>en-us</language><copyright>2004–2026 Noel Llopis</copyright><lastBuildDate>Fri, 06 Jan 2012 00:00:00 +0000</lastBuildDate><atom:link href="https://gamesfromwithin.com/category/ios/index.xml" rel="self" type="application/rss+xml"/><item><title>Quick Tip: Working With Shaders On iOS</title><link>https://gamesfromwithin.com/quick-tip-working-with-shaders-on-ios/</link><pubDate>Fri, 06 Jan 2012 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/quick-tip-working-with-shaders-on-ios/</guid><description>&lt;p&gt;I&amp;rsquo;m taking a couple of days to upgrade some of my libraries for doing prototyping both in 2D and 3D. One of the many overdue things I wanted to do, was to finally ditch OpenGL ES 1.1 and move to 2.0 exclusively. Yes, even if you&amp;rsquo;re only doing a 2D game, OpenGL ES 2.0 is way worth it.&lt;/p&gt;
&lt;p&gt;There were even a couple of cases during Casey&amp;rsquo;s Contraptions that we wanted a particular effect, and couldn&amp;rsquo;t get it quite right, but it would have been trivial to whip up a shader if we had been using OpenGL ES 2.0. In the end, we had to resort to &lt;a href="https://gamesfromwithin.com/customizable-color-sections-with-opengl-es-1-1/"&gt;texture combiners&lt;/a&gt; (yuck), and it wasn&amp;rsquo;t exactly what we had in mind.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;m taking a couple of days to upgrade some of my libraries for doing prototyping both in 2D and 3D. One of the many overdue things I wanted to do, was to finally ditch OpenGL ES 1.1 and move to 2.0 exclusively. Yes, even if you&rsquo;re only doing a 2D game, OpenGL ES 2.0 is way worth it.</p>
<p>There were even a couple of cases during Casey&rsquo;s Contraptions that we wanted a particular effect, and couldn&rsquo;t get it quite right, but it would have been trivial to whip up a shader if we had been using OpenGL ES 2.0. In the end, we had to resort to <a href="/customizable-color-sections-with-opengl-es-1-1/">texture combiners</a> (yuck), and it wasn&rsquo;t exactly what we had in mind.</p>
<p>OpenGL ES 2.0 requires that you write shaders for any different kind of &ldquo;thing&rdquo; you render, whether it&rsquo;s a simple 2D quad, or a fancy skinned character. I wanted to provide at least a basic 2D rendering shader in my graphics library, but the workflow was a bit awkward.</p>
<p>First of all, shaders on iOS are compiled at runtime <a href="#1">[1]</a>, so we need to access the shader source and compile it. Initially I was thinking of having the shader source files as text in the graphics library, but for the game to access those files, it would have to explicitly add them to its resources so they can be copied during the build phase. That&rsquo;s error prone (I would always forget to do that with every new project) and just plain ugly.</p>
<p>Another possibility would be to include the source text as a string in the library. That would simplify things, but it would mean that:</p>
<ol>
<li>You would lose shader syntax highlighting.</li>
<li>You would need to have the annoying \ at the end of every line.</li>
</ol>
<p>After <a href="https://twitter.com/#!/noel_llopis/status/155072436113649665">asking on Twitter and getting some good suggestions</a>, I decided the easiest way would be to use <a href="http://linuxcommand.org/man_pages/xxd1.html">xxd</a>. It&rsquo;s a shell tool that comes preinstalled in all Macs (and Linux) that takes a file and converts it into a C array that can be included in a program directly.</p>
<p>I liked xxd even better than the old standby of <a href="http://wiki.wxwidgets.org/Embedding_PNG_Images-Bin2c_In_Python">bin2c</a> because it already comes installed, and it generates the whole file, not just an array that then needs to be included from another file. Yes, it would be easy enough to modify, but why bother when you have a perfect tool for the job already?</p>
<p>Now, I can set up a custom rule in Xcode 4 like this:</p>
<p><img alt="Custom rule" loading="lazy" src="/quick-tip-working-with-shaders-on-ios/images/custom_rule1.png"></p>
<p><strong>Update:</strong> The array generated by xxd isn&rsquo;t null-terminated, so we need to add a zero to the array. The easiest way is to use sed. Thanks to <a href="http://twitter.com/#!/SixEchoStudios">SixEcho Studios</a> for the heads up. Also, I updated it to use the varaibles INPUT_FILE_DIR and INPUT_FILE_NAME thanks to <a href="http://twitter.com/#!/mysterycoconut">Miguel&rsquo;s</a> comments.</p>
<p>Now, whenever the shader source changes, it generates a header file like this:</p>
<pre tabindex="0"><code>unsigned char PassThrough_fsh[] = {
  0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x6f,
  0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x44, 0x65, 0x73, 0x74,
  0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
  0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e,
  0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f,
  0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20,
  0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43,
  0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d
,0x00};
unsigned int PassThrough_fsh_len = 91;
</code></pre><p>To compile that shader in the game, all I have to add is two lines:</p>
<pre tabindex="0"><code>#include 
//...
const int fs = ShaderUtils::CompileShader(PassThrough_fsh, GL_FRAGMENT_SHADER);
</code></pre><p>Done! Clean, simple, and minimal cruft.</p>
<p><strong>Update:</strong> I haven&rsquo;t tried it yet because I haven&rsquo;t had the need for any expensive shaders, but I hear really good things about Aras PranckeviÄius GLSL optimizer. In that case, I would add it before the xxd step. You would still use the shader the same way, but it would be optimized and perform faster.</p>
<p>[1] That&rsquo;s a huge mistake and I hope Apple fixes that ASAP. <a href="https://github.com/aras-p/glsl-load-speed">Loading times for any amount of non-trivial shaders adds up really quickly</a>. That&rsquo;s the last thing you want on a mobile device! The OpenGL ES 2.0 standard provides an optional way to load binary shaders, and all that Apple has to do is provide a tool that will compile shaders for the iOS hardware. To be completely future-proof, you they can even mandate that if the binary load fails, you still need to compile from source.</p>]]></content:encoded></item><item><title>iCloud Demystified</title><link>https://gamesfromwithin.com/icloud-demystified/</link><pubDate>Thu, 22 Dec 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/icloud-demystified/</guid><description>&lt;p&gt;Play a game on a device, put it down, pick up another device, and continue playing exactly where you left off. This is the future of games.&lt;/p&gt;
&lt;p&gt;That future is a reality today for some games and apps (Netflix, Kindle), and I&amp;rsquo;m convinced that players will expect that in most games in the next year or so. So obviously, the next bit of new iOS tech I decided to try was iCloud. I would love to turn Flower Garden into that kind of seamless experience, independently of the device you use to access it.&lt;/p&gt;
&lt;p&gt;As a quick spoiler, it turns out I won&amp;rsquo;t be able to make Flower Garden quite so seamless without a lot of extra work. But I learned a lot along the way and I should be able to take a small step in that direction.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Play a game on a device, put it down, pick up another device, and continue playing exactly where you left off. This is the future of games.</p>
<p>That future is a reality today for some games and apps (Netflix, Kindle), and I&rsquo;m convinced that players will expect that in most games in the next year or so. So obviously, the next bit of new iOS tech I decided to try was iCloud. I would love to turn Flower Garden into that kind of seamless experience, independently of the device you use to access it.</p>
<p>As a quick spoiler, it turns out I won&rsquo;t be able to make Flower Garden quite so seamless without a lot of extra work. But I learned a lot along the way and I should be able to take a small step in that direction.</p>
<h2 id="design-considerations">Design considerations</h2>
<p>iCloud promises to be the &ldquo;available from everywhere&rdquo; storage solution that will be a key component towards the scenario of playing on any device at any time. Unfortunately, it&rsquo;s just a component of that whole scenario and still requires quite a bit of work on the part of the developer.</p>
<p>Since I&rsquo;m just retrofitting Flower Garden to work with iCloud, I wanted a simple way to simply replicate the game state on iCloud. Then, whenever you play it from any device, you get the latest state and everything works as expected.</p>
<p>The big problem with that approach is that you can&rsquo;t always count on having an active (or fast enough) internet connection. iPod Touches, iPads, or even iPhone in a plane or a cell tower black spot will make it so your device has no way to communicate with iCloud. So what happens if the player plays without an internet connection, then comes home, grabs another device, plays for a bit with internet connection, and finally launches the original device, this time with internet connection. You&rsquo;ll end up with two conflicting game states. Not fun!</p>
<p><img alt="Whatis icloud" loading="lazy" src="/icloud-demystified/images/whatis_icloud.jpg"></p>
<p>I can think of two different strategies to deal with this situation:</p>
<ul>
<li>Require internet connection to play. Some games do this today. It can be quite frustrating not being able to play your favorite game in the plane, but it does solve the game state conflict problem because they can always communicate with iCloud, so they usually provide seamless multi-device play.</li>
<li>Detect changes on both game states and intelligently solve them. Sounds good in theory, but it&rsquo;s a pain in practice. Unless you have a very simple game state (a percentage completion for example), it means not only do you have to record the state, but you have to record the events that led to that state, and be ready to examine them, compare them, and marge them in the case of a conflict. And the worst part is that even if you put lots of care into it, there will be cases where the merge is not ideal and the player will feel like he lost something in the merge.</li>
</ul>
<p>For Flower Garden, neither solution is particularly attractive. It&rsquo;s the proverbial rock and a hard place. So for the moment I&rsquo;ve decided to implement just a small step in that direction: Sync things that only progress in one direction, without any danger of conflict. That includes purchased IAPs and unlocked seeds. Later on, once that&rsquo;s working solidly without any problems, I can consider adding counts like Fertilizer, Color Dust, or Green Thumb points. That will be a bit trickier because there&rsquo;s still chance for conflict since the count can go up and down, but it&rsquo;s possible to change each amount into two different values that always go up: Earned amount, and spent amount. That way I can always grab the maximum value that I find either local or on iCloud and things should work smoothly. (Update: What I wrote there about separating them in two different values is totally wrong, and any DB programmer worth his salt would be laughing at that. Separating them in two different values won&rsquo;t help at all. That&rsquo;s what I get for doing brain-dump posts on the fly :-)</p>
<p>Apple provides <a href="https://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/iCloud/iCloud.html#//apple_ref/doc/uid/TP40007072-CH5-SW1">two APIs to store data in iCloud</a>: key-value storage and file storage.</p>
<h2 id="key-value-storage">Key Value storage</h2>
<p>Initially, this seems like a great way to go. It&rsquo;s a <a href="https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSUbiquitousKeyValueStore_class/Reference/Reference.html#//apple_ref/occ/cl/NSUbiquitousKeyValueStore">very simple API</a>, and it&rsquo;s very familiar to most iOS programmers because it&rsquo;s just like <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html">NSUserDefaults</a>.</p>
<p>Don&rsquo;t be fooled into thinking you need to store data in strings or one field at the time. You can stuff whatever binary chunk of data you want with NSData, so it&rsquo;s quite versatile.</p>
<p>It does have three pretty big drawbacks thought:</p>
<ul>
<li>
<p><strong>Size</strong>. You can only store up to 64KB of data. That&rsquo;s definitely a big deal if you&rsquo;re planning on storing large data files. Even for Flower Garden, each pot is about 30KB, so I wouldn&rsquo;t be able to save the full garden state this way.</p>
</li>
<li>
<p><strong>Syncing</strong>. The Apple docs say that &ldquo;Keys and values are transferred to and from iCloud at periodic intervals.&rdquo; Ouch! What does that mean? Clearly this is intended for non-crucial data (like settings), so the potential delay isn&rsquo;t a big deal. In my tests, I found that data was often not available when starting the app, but would become available a few seconds later.</p>
</li>
<li>
<p><strong>No way to check state.</strong> When starting the app, there&rsquo;s no way to find out if the values you&rsquo;re reading are up to date. Combined with the slow syncing, it makes it less than idea for important data. On the flip side, <a href="https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSUbiquitousKeyValueStore_class/Reference/Reference.html#//apple_ref/occ/cl/NSUbiquitousKeyValueStore">you can be notified when the data changes</a>, but that means having to deal with changes while the game is running (which I was hoping not to do).</p>
</li>
</ul>
<h2 id="file-storage">File storage</h2>
<p>File storage might be a better option then since it doesn&rsquo;t have any of those drawbacks: there&rsquo;s no size limit, data is synced much more aggressively, and you can check if the data is up-to-date, and wait until it is otherwise.</p>
<p>What&rsquo;s not to like about file storage then? The cumbersome and intrusive API that Apple created around it. If you read the docs, they make it sound like you need to inherit from UIDocument and load all your data through that class. I like to keep things simple and portable, so I&rsquo;d really rather not introduce UIDocument into the file-loading process if I don&rsquo;t have to.</p>
<p>It turns out that <a href="https://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/iCloud/iCloud.html#//apple_ref/doc/uid/TP40007072-CH5-SW1">Apple&rsquo;s docs on the iCloud SDK</a> are quite sparse and lacking details. I was able to put together a demo from those docs and some experimentation, so hopefully this will be useful to other devs as well.</p>
<p>The device has an iCloud storage daemon running, monitoring specific directories for changes. You get the directory assigned to your app by calling <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/URLForUbiquityContainerIdentifier:">URLForUbiquityContainerIdentifier</a>.</p>
<p>To add a new file, the docs recommend first creating the file somewhere else, and then calling <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/setUbiquitous:itemAtURL:destinationURL:error:">NSFileManager:setUbiquitous:itemAtURL:destinationURL:error:</a> to move it to iCloud. Interestingly, I accidentally skipped this step and just wrote to the iCloud directory directly, and the files were stored correctly anyway. Might as well leave it just in case that behavior changes later on, or there&rsquo;s some side effect I didn&rsquo;t notice.</p>
<p>After that, every time you write to the file, the iCloud daemon will detect the changes and push them out to iCloud. This is an important point because a) You don&rsquo;t have explicit control to say &ldquo;start send it now&rdquo; or even &ldquo;This file is ready to be sent to iCloud&rdquo; (that would be my choice), and b) I don&rsquo;t know what it does with partial updates, so I would be very careful about writing to those files and make sure it&rsquo;s an atomic operation (save somewhere else, and them move the file in one operation).</p>
<p>To get the latest version of the files on iCloud, you can check whether they&rsquo;re fully downloaded or not by calling <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html#//apple_ref/occ/instm/NSURL/getResourceValue:forKey:error:">NSURL:getResourceValue:&amp;isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:</a>. If they are up to date, you can move on, otherwise, you can initiate a download of the files by calling <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/startDownloadingUbiquitousItemAtURL:error:">NSFileManager:startDownloadingUbiquitousItemAtURL:error:</a>.</p>
<p>One weird thing is that the startDownloading function doesn&rsquo;t have a callback (that I can see). So I had to set up a timer to check periodically if the files are synced.</p>
<p>Since all the syncing happens at startup, there&rsquo;s no complexity involved with data changing while the app is running. If that&rsquo;s a case you need to handle, you might be better off using UIDocument since it at least detects conflicts. If you do it this way, the latest one will overwrite any past changes.</p>
<p>Also, working this way, it seemed easier to keep the files in Application Support (or Documents), and only move them to/from iCloud when I wanted to. That has the advantage of iCloud not changing things from under you while the game is running, and the fact that, if for some reason the files in iCloud are corrupt, you always have good local files to fall back to.</p>
<h2 id="demo">Demo</h2>
<p><a href="/wp-content/uploads/2011/12/iCloudTest.zip" title="iCloudTest.zip">iCloudTest.zip</a></p>
<p>The demo iCloudTest saves data both with the key value pair, and the file storage system directly like I described above. If you run it from different devices, you&rsquo;ll see that it&rsquo;s amazing how quickly file data gets propagated, but key-value data takes a few more seconds.</p>
<p>The demo project also works in the simulator (there&rsquo;s no iCloud support, so it just uses local files), and it even works with iOS4 (also using local files, and it avoids using any iOS5 symbols while detecting iCloud support).</p>
<h2 id="sharing-data-between-multiple-apps">Sharing Data Between Multiple Apps</h2>
<p>Once you&rsquo;re at this point, sharing data between multiple apps is really straightforward.</p>
<p>First you need to make sure the app IDs of both apps start with the seam Team ID. For some unknown reason lost in the midsts of time, Flower Garden and Flower Garden Free use different prefixes, so that option is out for me. Hopefully most people having been using the Team ID only.</p>
<p>Then you need to decide which type of data you want to share. If you want to share files, you need to add the app ID of the other app to your iCloud entitlement, and then as for the correct app ID (including prefix!) when you call <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/URLForUbiquityContainerIdentifier:">URLForUbiquityContainerIdentifier</a>. If you just want the app&rsquo;s own iCloud data, you can pass NULL as the parameter.</p>
<p>As far as I can tell, each application can only have one set of key-value data. So sharing it between two apps means changing one app to use the app ID of the other app in the com.snappytouch.icloudtest field of the iCloud entitlements file. As long as both apps use the same Team ID prefix, it should work fine without having to do anything else.</p>]]></content:encoded></item><item><title>Trying Out Multisampling On iOS</title><link>https://gamesfromwithin.com/trying-out-multisampling-on-ios/</link><pubDate>Fri, 16 Dec 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/trying-out-multisampling-on-ios/</guid><description>&lt;p&gt;I only recently broke free of iOS3.x for Flower Garden, so I&amp;rsquo;m finally adding all the features I had been itching to add that required higher OS support. I had already added some iOS4+ features, but I was keeping them to a minimum because it&amp;rsquo;s always a huge cause of bugs to target multiple versions of the OS at once.&lt;/p&gt;
&lt;p&gt;One of the first features I looked into adding was &lt;a href="http://en.wikipedia.org/wiki/Multisample_anti-aliasing"&gt;multisample antialiasing (MSAA)&lt;/a&gt; support for OpenGL, which was originally introduced in iOS 4.0. The geometry generated for the petals in Flower Garden is fairly high contrast, and since it&amp;rsquo;s not like the textures were carefully created and laid out by an artist, the result is pretty bad aliasing around the edges. Perfect candidate for multisampling!&lt;/p&gt;</description><content:encoded><![CDATA[<p>I only recently broke free of iOS3.x for Flower Garden, so I&rsquo;m finally adding all the features I had been itching to add that required higher OS support. I had already added some iOS4+ features, but I was keeping them to a minimum because it&rsquo;s always a huge cause of bugs to target multiple versions of the OS at once.</p>
<p>One of the first features I looked into adding was <a href="http://en.wikipedia.org/wiki/Multisample_anti-aliasing">multisample antialiasing (MSAA)</a> support for OpenGL, which was originally introduced in iOS 4.0. The geometry generated for the petals in Flower Garden is fairly high contrast, and since it&rsquo;s not like the textures were carefully created and laid out by an artist, the result is pretty bad aliasing around the edges. Perfect candidate for multisampling!</p>
<p>I based everything on the <a href="http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html#//apple_ref/doc/uid/TP40008793-CH103-SW12">Apple documentation on multisampling</a>. It was very straightforward and it works for both off-screen and view-based render targets. It was also extremely helpful to keep both the ability to use regular and multisampled render targets. That way I can easily run performance and visual comparisons, and, if necessary, I can disable multisampling on a particular device.</p>
<p>The main gotcha was making sure I used the GL_RGBA8_OES color format on the multisampling color buffer (otherwise it won&rsquo;t work, and all you&rsquo;ll get are 1282 &ldquo;invalid operation&rdquo; OpenGL errors). Also, if you&rsquo;re in the same boat as Flower Garden, which uses OpenGL ES 1.1 and the fixed function pipeline, you&rsquo;ll have to add _OES to just about every constant in the documentation.</p>
<h2 id="visual-results">Visual results</h2>
<p>I will let the screenshots speak for themselves.</p>
<p><img alt="Multisample" loading="lazy" src="/trying-out-multisampling-on-ios/images/multisample.png"></p>
<p>In this screenshot you can see the rendering of the pots using off-screen render targets.</p>
<p><img alt="Multisample2" loading="lazy" src="/trying-out-multisampling-on-ios/images/multisample2.png"></p>
<p>Pretty impressive improvement, even if I say so myself! The improvement is even more striking in-game because the animation of the flowers moving in the wind doesn&rsquo;t have jaggies popping in and out.</p>
<p>The improvements are more noticeable on the iPad because the pixels are bigger, and, not surprisingly, less so on retina-display iPhones. But even on the retina displays, jaggies are less noticeable during the flower wind-swaying animations.</p>
<h2 id="performance">Performance</h2>
<p>So, no doubt: They look pretty. But how about performance? Under the hood, the rasterizer is generating four samples for every pixel, and then combining them at the end in a separate step. So you&rsquo;ll get more of a performance hit with complex pixel shaders. <strong>Edit:</strong> My bad. I spaced out and I forgot that MSAA only evaluates the pixel shader once, so performance doesn&rsquo;t depend on pixel shader complexity. Instead, the performance hit probably comes from the extra writes (four per pixel) to the render target, and should be fairly similar between games.</p>
<p>It turns out that Flower Garden is still using OpenGL ES 1.1, which is implemented using shaders at the driver level. Fortunately, even though I&rsquo;m using some texture combiner operations and several input textures, those pixel shaders aren&rsquo;t all that complex.</p>
<p>These are the frames per second I recorded with one particular flower pot on the different devices I have for testing. Notice that the lowest device I have listed is the iPhone 3GS. That&rsquo;s because I have also stopped supporting arm6 CPUs to keep things simpler (and the market share is minimal).</p>
<p><strong>Update:</strong> I was only running the game loop at 30 fps, so the initial performance numbers I had listed are pretty meaningless. Here are the correct numbers running at a max of 60 fps.</p>
<table>
	<thead>
			<tr>
					<th>Device</th>
					<th>Without MSAA</th>
					<th>With MSAA</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>iPhone 3GS</td>
					<td>39 fps (25.6 ms)</td>
					<td>37 fps (27.0 ms)</td>
			</tr>
			<tr>
					<td>iPhone 4</td>
					<td>48 fps (20.8 ms)</td>
					<td>23 fps (43.5 ms)</td>
			</tr>
			<tr>
					<td>iPhone 4S</td>
					<td>60 fps (16.7 ms)</td>
					<td>60 fps (16.7 ms)</td>
			</tr>
			<tr>
					<td>iPad 1</td>
					<td>60 fps (16.7 ms)</td>
					<td>18 fps (55.6 ms)</td>
			</tr>
			<tr>
					<td>iPad 2</td>
					<td>60 fps (16.7 ms)</td>
					<td>60 fps (16.7 ms)</td>
			</tr>
	</tbody>
</table>
<p>Of the devices I tested, MSAA didn&rsquo;t slow down things much on the iPhone 3GS, and the iPhone 4S was maxed out at 60 fps both ways. The iPad 1 was a different story, and performance crashed from 60 fps to 18 fps. Like Rory pointed in the comments, looking at the actual time instead of the fps gives a better insight. Using MSAA adds 38.9 ms to each frame! The iPhone 4 also suffered from a big performance hit due to all the extra pixels in the retina display. I don&rsquo;t care how pretty the flowers are, that&rsquo;s just not acceptable (and no, I&rsquo;m not adding user-tweakable graphics settings like PC games).</p>
<p>I should also add that Flower Garden is hugely CPU bound. It generates all that geometry every frame on the CPU, and that&rsquo;s a lot of vector transforms. So if your game is GPU bound, you&rsquo;re likely to see higher performance hits.</p>
<p>I was initially very surprised to see that the performance on the simulator tanked big time (as in, going from 30 fps to 5 fps). This was news to me, but apparently the iOS simulator runs completely in software, so the quadrupling of pixels brings it to its knees. I&rsquo;m really, really, impressed at how smoothly it usually runs for being in software though. It had me fooled thinking it was using OpenGL under the hood!</p>
<p>As far as memory goes, after an <a href="https://twitter.com/#!/Frogblast/status/144811240177405952">animated discussion on Twitter</a>, it seems that the iPhone does create full buffers for the multisample frame buffers, so there is a significant increase in memory usage. It&rsquo;s not something easy to track because it all happens at the driver level, but it&rsquo;s something to be aware of. Because of this, I might consider turning multisampling off on retina displays, since the improvement is not mind-blowing (and the extra memory is very significant because of the amount of pixels). I&rsquo;ll also probably turn it off in the simulator so I can achieve a decent frame rate during development.</p>
<h2 id="conclusions">Conclusions</h2>
<p>Multisampling only required adding a few lines of code and resulted in an impressive visual improvement and minimal performance impact in some devices. It&rsquo;s a no-brainer on the 3GS and iPad 2. I&rsquo;m wishing I had implemented it earlier!</p>]]></content:encoded></item><item><title>View Controller Notification Changes on iOS5</title><link>https://gamesfromwithin.com/view-controller-notification-changes-on-ios5/</link><pubDate>Fri, 09 Dec 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/view-controller-notification-changes-on-ios5/</guid><description>&lt;p&gt;If you use view controllers in your iOS apps, here&amp;rsquo;s a doozie: The behavior of viewWillAppear/viewDidApear/viewWillDisappear/viewDidDisappear silently changed on iOS5. Depending how your app is organized, this might range from not mattering to being a total disaster.&lt;/p&gt;</description><content:encoded><![CDATA[<p>If you use view controllers in your iOS apps, here&rsquo;s a doozie: The behavior of viewWillAppear/viewDidApear/viewWillDisappear/viewDidDisappear silently changed on iOS5. Depending how your app is organized, this might range from not mattering to being a total disaster.</p>
<p>Pre-iOS5, if you added a view with [self.view addSubview:myView], myView didn&rsquo;t get any notifications. That was weird, but we learned to live with it. Tens (hundreds?) of thousands of developers worked around that and wrote gobs and gobs of code that worked with and counted on that behavior.</p>
<p>Then along comes the iOS5 SDK and someone decided that it would be good to &ldquo;fix&rdquo; that behavior, but doing it silently. By silently I mean no compile-time errors or warnings, but apparently it wasn&rsquo;t deemed worthy of including in the <a href="https://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-5_0/_index.html">iOS5 release notes either</a>. I&rsquo;m sure they thought they were doing us a favor. After all, if someone had a problem with it, it&rsquo;s because they hadn&rsquo;t structured their code correctly.</p>
<p>So now every view you add/remove will get those notifications. Which is fine, except if you had decided to call those by hand yourself. In that case, now they get executed twice, so you may be allocating things twice, making multiple network calls, and just causing general mayhem.</p>
<p>I also noticed that if you call presentModalViewController with a view controller, all the views underneath the modal view controller will get the viewWillDisappear/viewDidDisappear event. In my case this causes total chaos because those events trigger the freeing of some views that the modal view controller will need.</p>
<p>But wait, it gets even better! From what I&rsquo;ve been able to tell, if your app compiled with the iOS5 SDK runs on iOS4, then you don&rsquo;t get those events! That means that now you need to be ready to both deal with receiving them and not receiving them at the same time. Is that useful to anyone (other than devs making iOS5+ apps)?</p>
<p>Fortunately, existing apps compiled with the iOS4 SDK are consistent running both on iOS4 and iOS5 (no view events automatically generated). Phew! Dodged that bullet.</p>
<p>It seems I <a href="/xcode-4-trials-and-tribulations/">complain</a> <a href="/quick-notes-on-lion/">a lot</a> lately, but this seems like another very justified complaint. Wasn&rsquo;t there a way for Apple to add that behavior to new functions without changing the old ones? For example, they could have introduced UIView:addSubview:withNotifications: and eventually deprecated the old ones. Yes, that means that they would have had to duplicate 10-20 functions related to adding/removing views, but they wouldn&rsquo;t have broken half the iOS code out there.</p>
<p>This is probably my fault for relying on viewDidAppear events and calling them myself. I started working around this problem by being super-careful about how and when I call viewDidAppear, but as soon as I realized that iOS4 does it differently, I threw in the towel and went for a different approach. Now, I just implement my own function in the different view controllers and call that instead of viewDidAppear. That way Apple can change those events all they want and it won&rsquo;t affect me anymore.</p>
<p>Of course, all of this only matters if you&rsquo;re making heavy use of view controllers (which unfortunately I am doing in Flower Garden). I&rsquo;ve already said that my future game projects are going to be UIKit-free, so I won&rsquo;t have to deal with this kind of problems again.</p>]]></content:encoded></item><item><title>Duplicating Launchboard Wobble</title><link>https://gamesfromwithin.com/duplicating-launchboard-wobble/</link><pubDate>Fri, 30 Sep 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/duplicating-launchboard-wobble/</guid><description>&lt;p&gt;One of the most requested features for Flower Garden is to be able to move pots around. Not only do players want to group similar flowers or colors together, but they also want to be able to take advantage of the properties of the different gardens. I figured the best thing to do this is by mimicking the wobble on the iPhone launchboard icons when you enter edit mode.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the most requested features for Flower Garden is to be able to move pots around. Not only do players want to group similar flowers or colors together, but they also want to be able to take advantage of the properties of the different gardens. I figured the best thing to do this is by mimicking the wobble on the iPhone launchboard icons when you enter edit mode.</p>
<p>I have to say, I&rsquo;m not a huge fan of the wobble movement, but it does indicate that icons are &ldquo;loose&rdquo; and movable. And since most players are already familiar with that metaphor, and the overhead view of Flower Garden resembles the launchboard quite a bit (not coincidence), I might as well go with it.</p>
<p><img alt="Garden02" loading="lazy" src="/duplicating-launchboard-wobble/images/garden02.jpg"></p>
<p>Each pot is a UIButton with a custom image (<a href="/opengl-and-uikit-demo/">rendered from OpenGL into an off-screen target</a>). So when I enter edit mode, I need to wobble them like the launchboard. Easier said than done.</p>
<p>I searched online and <a href="http://twitter.com/#!/noel_llopis/status/119795265069785088">asked on Twitter</a>, but surprisingly, nobody had done a perfect, reverse-engineering of the wobble movement. Most mentions just do a z rotation on a sine wave, which is not that close of the launchboard animation.</p>
<p>I found that to get closer to the real thing, you need to do that rotation around a random point offset from the center. That&rsquo;s better, but it&rsquo;s still not perfect. There&rsquo;s an additional extra twitch in the original Apple animation. I&rsquo;d love it if someone already reverse-engineered it and has a better model for that animation.</p>
<p>In the meanwhile, I figured I would share the core I&rsquo;m using. It&rsquo;s all very straightforward, except for the part about rotating a UIView around a different point other than the center. I initially thought I could just concatenate transforms, but no matter how you do it, UIKit always interprets the transform around the center.</p>
<p>To be more precise, it interprets the rotation around the anchor point, and that&rsquo;s what you need to modify. The anchor point is defined in units that are a percentage of the layer&rsquo;s size, so by default it&rsquo;s 0.5, 0.5. When you move the anchor point, the layer itself will move, so you need to fix it up by moving the layer&rsquo;s position by the same amount in the opposite direction.</p>
<p>This is what the final code looks like:</p>
<pre tabindex="0"><code>void StartPotWobble(UIButton* button, Random&amp; random)
{
	const Range posOffset(0.10f, 0.2f);
	const float amplitude = random.GetFloat(1,1.5f);
	const Vec2 startCenter(Sign(random.GetFloat(-1,1))*random.GetFloat(posOffset), Sign(random.GetFloat(-1,1))*random.GetFloat(posOffset));
	const Vec2 endCenter(Sign(random.GetFloat(-1,1))*random.GetFloat(posOffset), Sign(random.GetFloat(-1,1))*random.GetFloat(posOffset));

	CGPoint center = button.center;	
	button.layer.anchorPoint = CGPointMake(0.5f + startCenter.x, 0.5f + startCenter.y);
	CGRect bounds = button.bounds;
	button.layer.position = CGPointMake(button.layer.position.x + bounds.size.width*startCenter.x, 
									button.layer.position.y + bounds.size.height*startCenter.y);
	button.transform = CGAffineTransformMakeRotation(-amplitude*DegToRad);
		
	[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationRepeatAutoreverses:YES];
	[UIView setAnimationRepeatCount:FLT_MAX];
	[UIView setAnimationDuration:0.12];
	[UIView setAnimationDelay:random.GetFloat(0,0.09f)];
		button.transform = CGAffineTransformMakeRotation(+amplitude*DegToRad);
	[UIView commitAnimations];
}
	
	
void StopPotWobble(UIButton* button)
{
	[button cancelAllAnimationsRecursively];
	button.transform = CGAffineTransformIdentity;
	CGPoint anchor = button.layer.anchorPoint;
	CGPoint offset = CGPointMake((0.5f - anchor.x)*button.width, (0.5f - anchor.y)*button.height);
	button.layer.anchorPoint = CGPointMake(0.5f, 0.5f);
	button.layer.position = CGPointMake(button.layer.position.x + offset.x, button.layer.position.y + offset.y);
}
</code></pre><p>Ah yes, and I couldn&rsquo;t find a way to loop the animation infinitely (without using the new UIView animation syntax), so FLT_MAX will have to do :-) Any cleaner way?</p>
<p>If someone has an animation that more closely resembles the iPhone launchboard, I&rsquo;d love to hear about it. Let me know and I&rsquo;ll update this post.</p>]]></content:encoded></item><item><title>URL Shorteners In Under Two Minutes</title><link>https://gamesfromwithin.com/url-shorteners-in-under-two-minutes/</link><pubDate>Fri, 26 Aug 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/url-shorteners-in-under-two-minutes/</guid><description>&lt;p&gt;This morning I added the goo.gl URL shortener to Flower Garden, so I thought a quick post with sample code might be helpful for other developers looking to do something similar.&lt;/p&gt;
&lt;p&gt;I use the URL shortener in Flower Garden to send bouquets through SMS. Space is limited in a text message, so the message just contains some text explaining what is it and the URL pointing to the bouquet image. (Yes, I would much rather send them through MMS, but Apple isn&amp;rsquo;t exposing that yet to developers).&lt;/p&gt;
&lt;p&gt;&lt;img alt="Sms" loading="lazy" src="https://gamesfromwithin.com/url-shorteners-in-under-two-minutes/images/sms.png"&gt;&lt;/p&gt;
&lt;p&gt;In this case, the full URL is &lt;a href="http://flowers.snappytouch.com/sms.php?id=949618b4b3c6f3d76e32b45446e238a0"&gt;http://flowers.snappytouch.com/sms.php?id=949618b4b3c6f3d76e32b45446e238a0&lt;/a&gt; which gets thankfully shortened to &lt;a href="http://goo.gl/IV5cq"&gt;http://goo.gl/IV5cq&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This morning I added the goo.gl URL shortener to Flower Garden, so I thought a quick post with sample code might be helpful for other developers looking to do something similar.</p>
<p>I use the URL shortener in Flower Garden to send bouquets through SMS. Space is limited in a text message, so the message just contains some text explaining what is it and the URL pointing to the bouquet image. (Yes, I would much rather send them through MMS, but Apple isn&rsquo;t exposing that yet to developers).</p>
<p><img alt="Sms" loading="lazy" src="/url-shorteners-in-under-two-minutes/images/sms.png"></p>
<p>In this case, the full URL is <a href="http://flowers.snappytouch.com/sms.php?id=949618b4b3c6f3d76e32b45446e238a0">http://flowers.snappytouch.com/sms.php?id=949618b4b3c6f3d76e32b45446e238a0</a> which gets thankfully shortened to <a href="http://goo.gl/IV5cq">http://goo.gl/IV5cq</a>.</p>
<p>Sending bouquets through SMS has been in Flower Garden for several months, but it was using bit.ly before, which is probably the most popular URL shortener out there. I like their web interface and their super-easy to use API, but unfortunately it seems that I hit some mysterious API limit during the Mother&rsquo;s Day Flower Garden promotion. That limit isn&rsquo;t public anywhere, and as far as I can tell, I can&rsquo;t even see it myself through the web interface or through an API query.</p>
<p>Finding out that I reached the API limit was quite shocking, because sending bouquets through SMS isn&rsquo;t a particularly popular feature. Unfortunately I don&rsquo;t have <a href="/analytics-for-ios-games/">good analytics hooked up to that step</a>, but I can&rsquo;t imagine there were more than a few thousand per day.</p>
<p>They were very nice and contacted me instead of shutting down my account since it was just a spike. They also tried to sell me their &ldquo;Enterprise&rdquo; account, but $995/month is a tad too expensive for me. By about $990 probably, so I had to look for other options.</p>
<p>After a very quick research, <a href="http://googlesystem.blogspot.com/2011/01/api-for-google-url-shortener.html">goo.gl</a> was the perfect alternative. Not only is it very fast (and backed up by the giant Google no less), but they have an API limit of 1,000,000 queries/day. If I ever blow that budget, I&rsquo;ll be able to afford the $995/month without a problem :-)</p>
<p>All URL shorteners are very easy to use. You need an API key, and figure out the exact format of the HTTP message you send and the response you get.</p>
<h3 id="googl">goo.gl</h3>
<p><a href="http://goo.gl">Goo.gl</a> has a great <a href="http://code.google.com/apis/urlshortener/v1/getting_started.html">Getting Started Guide</a> that tells you everything you need to know. Get your private API key from <a href="https://code.google.com/apis/console">here</a>, and you&rsquo;re ready to rock.</p>
<p>Drop this in your app and start shortening away. You&rsquo;ll notice I used a synchronous HTTP request, which is usually a big no-no. Here I felt it was justified since the user is blocked waiting for the SMS to be prepared and sent. Besides, goo.gl is very, very fast, so it&rsquo;s never even noticeable.</p>
<pre tabindex="0"><code>const NSString* GooGlAPIURL = @&#34;https://www.googleapis.com/urlshortener/v1/url?key=YOUR_API_KEY_HERE&#34;;

NSString* ShortenURLWithGooGl(NSString* longURL)
{
	NSURL* apiUrl = [NSURL URLWithString:GooGlAPIURL];
	
	NSMutableURLRequest* req = [[NSMutableURLRequest alloc] initWithURL:apiUrl];
	[req setHTTPMethod:@&#34;POST&#34;];
	[req setTimeoutInterval:Timeout];
	[req setValue:@&#34;application/json&#34; forHTTPHeaderField:@&#34;Content-Type&#34;];
	
	NSString* body = [[NSString alloc] initWithFormat:@&#34;{\&#34;longUrl\&#34;: \&#34;%@\&#34;}&#34;, longURL];
	[req setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
	[body release];
	
	NSError* error = [[NSError alloc] init];
	NSHTTPURLResponse* urlResponse = nil;
	NSData* data = [NSURLConnection sendSynchronousRequest:req returningResponse:&amp;urlResponse error:&amp;error];
	[error release];
	if (data == NULL || ([urlResponse statusCode] &lt; 200 &amp;&amp; [urlResponse statusCode] &gt;= 300))
		return NULL;

	NSString* response = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
	NSDictionary* responseDict = [response JSONValue];
	NSString* shortURL = [[responseDict objectForKey:@&#34;id&#34;] retain];
	[response release];
	return shortURL;
}
</code></pre><p>I&rsquo;m using a <a href="https://github.com/stig/json-framework/">JSON framework</a> to parse the answer, but it&rsquo;s so simple I probably wouldn&rsquo;t even have to. I only used it because it&rsquo;s already part of the project because of <a href="https://developers.facebook.com/docs/guides/web/">Facebook Connect</a>.</p>
<h3 id="bitly">bit.ly</h3>
<p>Even though it&rsquo;s not my favorite shortener, I&rsquo;m adding it here for completeness (and because I had the code already written).</p>
<p>The one thing that bit.ly has going for it is that it&rsquo;s even easier to use than goo.gl. No JSON involved, and you don&rsquo;t even need to send a body with your request. As usual, get your API key by <a href="http://bitly.com/a/sign_up">signing up with bit.ly</a>.</p>
<pre tabindex="0"><code>const NSString* BITLYAPIURL = @&#34;http://api.bit.ly/v3/shorten?login=%@&amp;apiKey=%@&amp;format=txt&amp;&#34;;

NSString* ShortenURLWithBitLy(NSString* longURL)
{
	NSString* urlWithoutParams = [NSString stringWithFormat:BITLYAPIURL, LoginName, APIKey];	
	CFStringRef encodedParamCF = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
															 (CFStringRef) longURL, 
															 nil, (CFStringRef) @&#34;&amp;+&#34;, kCFStringEncodingUTF8); 
	NSString* encodedURL = (NSString*)encodedParamCF;
	NSString* parameters = [NSString stringWithFormat:@&#34;longUrl=%@&#34;, [encodedURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
	NSString* finalURL = [urlWithoutParams stringByAppendingString:parameters];
	
	NSURL* url = [NSURL URLWithString:finalURL];
	
	NSMutableURLRequest* req = [[NSMutableURLRequest alloc] initWithURL:url];
	[req setTimeoutInterval:Timeout];
	
	NSHTTPURLResponse* urlResponse = nil;  
	NSData* data = [NSURLConnection sendSynchronousRequest:req returningResponse:&amp;urlResponse error:NULL];
	if (data == NULL || ([urlResponse statusCode] &lt; 200 &amp;&amp; [urlResponse statusCode] &gt;= 300))
		return NULL;

	NSString* response = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
	return response;
}
</code></pre><p>That&rsquo;s it. You should be able to drop in either one of those snippets in your project and spend your time working on the things that really matter in your games.</p>]]></content:encoded></item><item><title>Analytics For iOS Games</title><link>https://gamesfromwithin.com/analytics-for-ios-games/</link><pubDate>Thu, 25 Aug 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/analytics-for-ios-games/</guid><description>&lt;p&gt;Unlike a lot of console and PC games, most mobile and web games keep evolving over time &lt;a href="#1"&gt;[1]&lt;/a&gt;. It&amp;rsquo;s up to a game&amp;rsquo;s designers to ultimately decide how to change and improve the game, but the more data about players&amp;rsquo; habits they have, the more informed a decision they&amp;rsquo;ll be able to make. Having good analytics on iOS games is simply essential these days.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Unlike a lot of console and PC games, most mobile and web games keep evolving over time <a href="#1">[1]</a>. It&rsquo;s up to a game&rsquo;s designers to ultimately decide how to change and improve the game, but the more data about players&rsquo; habits they have, the more informed a decision they&rsquo;ll be able to make. Having good analytics on iOS games is simply essential these days.</p>
<p>Recording particular events as part of the analytics is only part of it. The most important part is how that data is presented to the developer. Having tables with millions of entries does me no good, and as a busy indie developer, I can&rsquo;t afford to spend hours writing scripts to analyze it. I want something that allows me to easily visualize the data and makes sense out of it at a glance.</p>
<p>One possible snagging point about analytics is that Apple was cracking down on some applications with analytics enabled a while back. Specifically, the <a href="https://developer.apple.com/programs/terms/ios/standard/ios_standard_agreement_20110215.pdf">iOS developer agreement</a> states:</p>
<blockquote>
<p>3.3.9 You and Your Applications may not collect user or device data without prior user consent, and then only to provide a service or function that is directly relevant to the use of the Application, or to serve advertising. You may not use analytics software in Your Application to collect and send device data to a third party.</p>
</blockquote>
<p>Where does that leave us? Reading it carefully, it seems that the restrictions are limited to &ldquo;user or device data&rdquo;. I&rsquo;m interpreting that to mean things like UDIDs and emails, not anonymous player usage data (how long did it take to reach level 5, how long are play sessions, etc), so I think we&rsquo;re clear there.</p>
<p>The puzzling thing is that a lot (all?) of the third party analytics libraries do report device information, like what kind of hardware or iOS version is running. That is extremely important information that developers really benefit from knowing, but it seems to go against point 3.3.9. Maybe &ldquo;device data&rdquo; only applies to information about that specific device? (as in, <a href="http://venturebeat.com/2011/08/23/ios-5-udid-privacy/">the UDID that is now going away</a>). I hope so.</p>
<p>Not having analytics isn&rsquo;t really an option. Unless you make a game that you plan to throw on the App Store, never touch again, and hope for the best, you&rsquo;re flying blind without analytics.</p>
<p>What are some of the options we have then?</p>
<h3 id="home-brewed">Home brewed</h3>
<p>If you read this blog regularly, you probably know that I&rsquo;m a <a href="/360idev-cranking-up-floating-point-performance-to-11/">low-level</a>, do-it-myself kind of guy, with <a href="/my-fear-of-middleware/">a deep mistrust and suspicion of middleware</a>. So you would think that I would want to write my own analytics package. After all, how hard can it be? Collect the data you want and ping your server with it. If you get fancy, you can even use a scalable server back end like <a href="http://aws.amazon.com/">AWS</a> or <a href="http://code.google.com/appengine/">GAE</a>. Done.</p>
<p>Not so fast. To do that well, it&rsquo;s a lot more involved than that. You want to batch when you send out the information, and you might want to distinguish between WiFi and 3G connection (to avoid causing extra data usage for players on a limited data plan).</p>
<p>That in itself is not even that bad. The real pain comes in visualizing that data, and that&rsquo;s where you can easily sink in days or weeks, and you would still not have something as good as some of the other alternatives.</p>
<p>The other drawback is that if you have some successful applications, you may be generating Terabytes of data per day. Think about the storage and bandwidth costs for that. Yes, I know that sounds insane, but Playfish reported generating that much analytics data at a <a href="http://www.gdcvault.com/play/1014544/Scaling-Social-Games-What-Game">GDC 2011 talk</a> (<a href="http://www.gdcvault.com/play/1014543/Scaling-Social-Games-What-Game">video for paid GDC Vault members</a>).</p>
<h3 id="flurry">Flurry</h3>
<p><a href="http://www.flurry.com/product/analytics/index.html">Flurry Analytics</a> appears to be the most common analytics package out there among my indie iOS dev friends. It&rsquo;s free and it&rsquo;s easy to integrate. The visualization page is pretty good, and it even offers some fancy features beyond session length and events, such as flow through the application.</p>
<p>So what&rsquo;s not to like? I was never able to make heads or tails of the application flow. When you get at that level, you start needing to spend some serious time making sense of data, which is what I don&rsquo;t have as an indie. The web page to visualize the data is written in Flash, so for those of you using an iPad to check it, it&rsquo;s not a good option. <strong>Update:</strong> Flurry apparently added a Flash-free web page since I last looked at it a few months back. Thanks Charilaos Kalogirou for the tip.</p>
<p>The killer deal for me was bloat. Adding the Flurry analytics library to an app increased the executable size by 500KB. I&rsquo;m sorry, but that&rsquo;s completely unacceptable for me. Memory is tight, and half a MB is very significant. I would rather add another large texture or another music track. And if you think about it, why does it need 500KB to buffer and send some events? That&rsquo;s simply ridiculous.</p>
<h3 id="google-analytics">Google Analytics</h3>
<p>I never actually tried out <a href="http://code.google.com/mobile/analytics/docs/iphone/">Google Analytics</a>. They have an iOS SDK and it integrates quite well into the web page Google Analytics environment. The main drawback I heard from other developers is that it&rsquo;s designed more for web pages rather than for apps and games, so it wasn&rsquo;t a perfect fit.</p>
<p>Anyone who used it want to expand on this in the comments?</p>
<h3 id="localytics">Localytics</h3>
<p><a href="http://www.localytics.com/app-analytics/">Localytics</a> is a relative newcomer to the iOS analytics field, but it was love at first sight for me.</p>
<p>It has the same ease of integration of Flurry, and it provides very similar functionality. Localytics, however, is completely open source, so instead of a black box library, you get the source code and you can add it directly to your game. How much does it increase executable size? 4KB! You have to wonder what the other 496KB were for in the Flurry library.</p>
<p>As a bonus, their visualization web page works great on an iPad, although it can be a bit slow for very large data sets sometimes.</p>
<p>One of their biggest selling points is that they report the analytics in real time, but I really don&rsquo;t care one way or another. Waiting 12 or 24 hours to see the analytics doesn&rsquo;t bother me one bit.</p>
<p>Unlike Flurry, you can only add strings as parameters to events. That works fine if I have a set of discrete options. For example, when someone sends a bouquet in Flower Garden, I can send a &ldquo;bouquet sent&rdquo; event with a parameters that is &ldquo;email&rdquo;, &ldquo;facebook&rdquo;, or &ldquo;sms&rdquo;. As a result, I can see a nice pie chart with the breakdown of how people are sending bouquets. Very useful stuff!</p>
<p>But how about things that don&rsquo;t have discrete options? For example, in Casey&rsquo;s Contraptions, we wanted to see how long players take to solve each level. It turns out you can&rsquo;t have a number as a parameter, but you can easily get around that by discretizing it yourself, which in the end, is easier to visualize. So when we send the LevelXXFinished event, we look at how long the player took to finish it, and we break it down into ranges: under 30s, 30s-1min, 1min-2min, etc.</p>
<p>This is what the report looks like for one of Casey&rsquo;s Contraptions levels:</p>
<p><img alt="Piechart" loading="lazy" src="/analytics-for-ios-games/images/piechart.png"></p>
<p>It looks like a fairly balanced level with the majority of the people spending under 3 minutes to solve it.</p>
<h3 id="random-tips">Random tips</h3>
<p>A couple random things we learned along the way about analytics:</p>
<ul>
<li>Less is more. Start with just a few events and go from there. If you have tons of data, you might never have the time to look at it.</li>
<li>Use analytics during playtesting. One thing is what people tell you, and another thing is what they really do. Since most of our playtesting is done remotely and we can&rsquo;t observe as people play (which is invaluable), we can at least gather some hard data about it.</li>
<li>Turn off analytics reporting in debug mode. Trust me on that one.</li>
</ul>
<p>How about you? What&rsquo;s your favorite analytics package and why?</p>
<p>[1] For example, Flower Garden has been on the App Store for almost two and a half years, and it has changed radically in that time!</p>]]></content:encoded></item><item><title>The Curious Case of Casey and The Clearly Deterministic Contraptions</title><link>https://gamesfromwithin.com/casey-and-the-clearly-deterministic-contraptions/</link><pubDate>Fri, 13 May 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/casey-and-the-clearly-deterministic-contraptions/</guid><description>&lt;p&gt;As we gear up for &lt;a href="http://www.caseyscontraptions.com/"&gt;Casey&amp;rsquo;s Contraptions&lt;/a&gt; launch on May 19th, this is the first post in a series dealing with different aspects of the game. I&amp;rsquo;m planning on covering technical aspects like today, but also design and other parts of development.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Casey 640x100" loading="lazy" src="https://gamesfromwithin.com/casey-and-the-clearly-deterministic-contraptions/images/Casey-640x100.jpg"&gt;&lt;/p&gt;
&lt;p&gt;For those of you who have been living under a rock and haven&amp;rsquo;t seen the Casey&amp;rsquo;s Contraptions video, go watch it now. I&amp;rsquo;ll wait. Or even better, here it is. You don&amp;rsquo;t even have to leave this page:&lt;/p&gt;
&lt;iframe src="http://www.youtube.com/embed/JlqNa9mEqNE" frameborder="0" width="640" height="390"&gt;&lt;/iframe&gt;</description><content:encoded><![CDATA[<p>As we gear up for <a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a> launch on May 19th, this is the first post in a series dealing with different aspects of the game. I&rsquo;m planning on covering technical aspects like today, but also design and other parts of development.</p>
<p><img alt="Casey 640x100" loading="lazy" src="/casey-and-the-clearly-deterministic-contraptions/images/Casey-640x100.jpg"></p>
<p>For those of you who have been living under a rock and haven&rsquo;t seen the Casey&rsquo;s Contraptions video, go watch it now. I&rsquo;ll wait. Or even better, here it is. You don&rsquo;t even have to leave this page:</p>
<iframe src="http://www.youtube.com/embed/JlqNa9mEqNE" frameborder="0" width="640" height="390"></iframe>
<p>The core interaction loop of Casey&rsquo;s Contraptions gameplay is placing some items, pressing the Play button, seeing the simulation, and repeating based on what you learned from seeing the simulation. We designed this loop to be very tight and without any penalty: Running/stopping the simulation is instant, there&rsquo;s no limit on the number of times you run it, and you can even stop the simulation by tapping anywhere on the screen. Even if you painted yourself in a wall by creating a solution that needs a very specific placement of items on the screen, making small changes is very quick and painless.</p>
<p>There&rsquo;s a very important, underlaying assumption in that loop: Running the same simulation multiple times will result in the same behavior. Imagine how frustrating it would be to create a complex chain reaction, just to find out it only works every other time you run it. That would truly deserve a ONE STAR WANT MY MONEY BACK!!</p>
<h3 id="determinism">Determinism</h3>
<p>That&rsquo;s referred to as the game being deterministic: Given the same inputs, it produces the same outputs. It&rsquo;s not the first time I&rsquo;ve had to deal with that. Actually, it seems that I&rsquo;ve had to deal with that in <a href="/back-to-the-future-part-1/">one form</a> <a href="/back-to-the-future-part-2/">or another</a> for all my games in the last 10 years (except for Flower Garden). Most recently, it was a key component of gameplay for the <a href="http://kotaku.com/259968/prototyping-for-fun-and-profit">unreleased game we were working on at Power of Two Games</a>.</p>
<p>To make a game deterministic, you need to remove the obvious sources of &ldquo;accidentally different&rdquo; inputs. That&rsquo;s usually random number generators, and making sure the initial state is truly the same. It&rsquo;s too easy to have some leftover state from the previous simulation that throws things off a little bit.</p>
<p>Another potential source of problems are uninitialized variables. If at some point the simulation depends on an uninitialized variable, different runs will cause different results based on whatever value happened to be in memory at that time.</p>
<p>Once you fix all of those little things, that should be it, right? Same input should create the same output. Not really. We&rsquo;re missing the most crucial input: The timer.</p>
<p>Casey&rsquo;s Contraptions runs at 60 fps on an iPad one, but the timestep isn&rsquo;t set to a fixed 16.667ms. Instead, I use a high-resolution timer to measure how much time has really elapsed since last frame, and I advance the simulation by that much.</p>
<p>The problem is that the timer doesn&rsquo;t always return the exact same amount. It&rsquo;s not super-precise, and it can be slightly affected by other things going on in the device. It won&rsquo;t be off by more than 1/10th of a ms, but that&rsquo;s enough to cause different results and start diverging the simulation.</p>
<h3 id="fixed-timestep">Fixed timestep</h3>
<p>One way to get around this problem is to hardcode the timestep to always be 16.667ms, independently of what it really was. That would fix the determinism problem, but it would add its own drawbacks. If the simulation can&rsquo;t keep up with 60 fps, the game will appear to slow down, which is not the effect we want. Casey&rsquo;s Contraptions includes a level editor to make your own free-form contraptions, and even though we have a cap in the maximum number of items you can add, it&rsquo;s probably possible to add enough of them to start slowing down an iPad 1.</p>
<p><img alt="CaseyDollTruck" loading="lazy" src="/casey-and-the-clearly-deterministic-contraptions/images/CaseyDollTruck.jpg"></p>
<h3 id="recording-timesteps">Recording timesteps</h3>
<p>A tempting solution (and one I&rsquo;m ashamed I even briefly tried), is to record the exact timestep during the first run of the simulation. Then, in subsequent runs when nothing has changed, we use the initially recorded stream of timesteps instead of the real ones from the clock.</p>
<p>Apart from being a clumsy-looking solution (I hate having two modes for doing the same thing), the solution only works in the case of replaying the exact same input. This approach falls apart if you make a change to an item that doesn&rsquo;t affect the simulation until after several seconds have passed. At that point, you&rsquo;re running a new simulation with new timesteps and everything can diverge before the affected object is changed. Bad, idea. Bad.</p>
<h3 id="fixed-simulation-timesteps">Fixed simulation timesteps</h3>
<p>This is the correct solution and it&rsquo;s what we&rsquo;re doing in Casey&rsquo;s Contraptions.</p>
<p>You probably already know that physics simulations are a lot more stable if you take small steps, always of the same size. So you really never want to advance your physics simulation by your frame time. Instead, you want to have a small and fixed simulation step (we&rsquo;re running at 120Hz, but 200 or even 300 are not unheard of). Then, you run the physics simulation as many times as you can fit into your larger timestep. It&rsquo;s also important to keep around the amount of leftover time you haven&rsquo;t simulated, to apply it to the next frame.</p>
<p>The simulation loop code looks something like this:</p>
<pre tabindex="0"><code>	const float timestep = 1.0f/120.0f;
	accumulator += dt;
	while (accumulator &gt;= timestep)
	{
		// Do physics simulation by timestep
		accumulator -= timestep;
	}
</code></pre><p>Once we have this loop in place, our real frame time doesn&rsquo;t matter anymore. The physics simulation will either run for a full step (or multiple steps), or it won&rsquo;t. There&rsquo;s no half-way states. So it doesn&rsquo;t matter if in the first run of the simulation the loop gets executed 3 times in the first frame and 2 times in the second, and in the next simulation is 2 times in the first and 3 in the second. The state of the world will be the same.</p>
<p><a href="http://gafferongames.com/">Glenn Fiedler</a> writes about this kind of simulation loop in much more detail in <a href="http://gafferongames.com/game-physics/fix-your-timestep/">this excellent article</a>.</p>
<h3 id="jitterbug">Jitterbug</h3>
<p>There&rsquo;s still a slight problem with the above loop. Nothing horrible; the simulation is deterministic at this point (assuming everything else is taken care of correctly). But you might notice some annoying jittering as things move around.</p>
<p><img alt="CaseysDollKick" loading="lazy" src="/casey-and-the-clearly-deterministic-contraptions/images/CaseysDollKick1.jpg"></p>
<p>That&rsquo;s because how we&rsquo;re sampling the simulation. We might render a frame after 3 steps of the physics simulation, but another one after 2. So movement isn&rsquo;t going to be very smooth.</p>
<p>To get around it, we need to interpolate the state of the world to match the time at which the frame is rendered. To do that, we need to simulate one timestep in the future, and then interpolate between the previous one and the future one by the percentage amount left in the accumulator.</p>
<p>Something like this:</p>
<pre tabindex="0"><code>	const float timestep = 1.0f/120.0f;
	accumulator += dt;
	while (accumulator &gt;= timestep)
	{
		GameState lastState = gameState;
		// Do physics simulation by timestep
		accumulator -= timestep;
	}

	const float t = accumulator/timestep;
	GamePhysicsUtils::LerpState(interpolatedState, prevState, gameState, t);
</code></pre><p>The interpolation is just the positions and rotations of every item in the world. That&rsquo;s only used for rendering, so no need to worry about velocities or forces (unless those are affecting rendering in a very obvious way too).</p>
<p>This is when it comes really handy to have the game state as a contiguous, relocatable block of memory. You can really easily copy states around without having to worry about allocating any memory or fixing any pointers. Yes, I really like my <a href="/start-pre-allocating-and-stop-worrying/">simple, pre-allocated data</a>.</p>
<p>One added benefit of this approach: If you do it right, you can have extreme slow-motion in your game and everything will be right. Even if you only run one physics simulation loop every 10 rendering frames, the interpolation will take care of making sure everything is super smooth.</p>
<h3 id="odds-and-ends">Odds and ends</h3>
<p>A couple gotchas to watch out for (that&rsquo;s code speak for &ldquo;I didn&rsquo;t think of this and it bit me hard&rdquo;).</p>
<p>If you have any game logic that affects the physical state of your game objects, it needs to be executed in the inner, simulation loop. Anything that deals with visual or audio stuff can go in the regular update loop and only be executed once per frame.</p>
<p>A good example of this was the balloon code. Every frame, I iterate through all existing balloons, and apply some upward force based on buoyancy and other factors. Initially that was done once per frame, after the physics simulation, but that&rsquo;s obviously wrong because it will leave balloons (and everything else) in a different state depending on your frame delta time. I moved it to the inner simulation loop and everything became deterministic again.</p>
<p><img alt="CaseyBalloons" loading="lazy" src="/casey-and-the-clearly-deterministic-contraptions/images/CaseyBalloons.png"></p>
<p>This second gotcha sounds silly, but it was a big deal: Make sure you deal with the situation where you have different numbers of items in the previous game state than in the next game state. For example, if a balloon is destroyed, between the two states, the item count will be different. In my case I don&rsquo;t free any memory, but I was initially making the assumption that I could interpolate based on the index of the items on both states. But since I removed the balloon and pushed all the items behind it forward, the interpolation was totally wrong.</p>
<p>I solved that problem by marking items as invalid, and removing them only after the inner simulation loop was complete. That allowed me to still interpolate in a very straightforward way and not have to worry about missing items.</p>
<h3 id="taking-it-further">Taking it further</h3>
<p>Not only are we relying on this determinism while you play a level of Casey&rsquo;s Contraptions, but also to let you replay solutions from your friends. We simply load their initial layout and run the simulation locally.</p>
<p>[Pause]</p>
<p>Ah, yes, astute reader, you&rsquo;re right to be puzzled about that. How do we make the simulation deterministic across platforms and versions? Good question. Stay tuned.</p>]]></content:encoded></item><item><title>The Business of iPhone and iPad App Development</title><link>https://gamesfromwithin.com/the-business-of-iphone-and-ipad-app-development/</link><pubDate>Mon, 11 Apr 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-business-of-iphone-and-ipad-app-development/</guid><description>&lt;p&gt;&lt;a href="http://amzn.to/eGD2fv"&gt;&lt;img alt="Business cover" loading="lazy" src="https://gamesfromwithin.com/the-business-of-iphone-and-ipad-app-development/images/business_cover.jpg"&gt;&lt;/a&gt;Full disclosure: Apress asked me to review this book and sent me a free copy. I agreed with my usual condition of being able to really say what I thought about the book, good or bad. So here it is.&lt;/p&gt;
&lt;h3 id="tldr"&gt;TL;DR&lt;/h3&gt;
&lt;p&gt;Great book for someone starting out on iOS development. You would be at a severe disadvantage if you don&amp;rsquo;t know about most practices described in the book. Single resource for lots of good practices you&amp;rsquo;d have to pick up from blogs or Twitter otherwise.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="http://amzn.to/eGD2fv"><img alt="Business cover" loading="lazy" src="/the-business-of-iphone-and-ipad-app-development/images/business_cover.jpg"></a>Full disclosure: Apress asked me to review this book and sent me a free copy. I agreed with my usual condition of being able to really say what I thought about the book, good or bad. So here it is.</p>
<h3 id="tldr">TL;DR</h3>
<p>Great book for someone starting out on iOS development. You would be at a severe disadvantage if you don&rsquo;t know about most practices described in the book. Single resource for lots of good practices you&rsquo;d have to pick up from blogs or Twitter otherwise.</p>
<h3 id="in-more-detail">In More Detail&hellip;</h3>
<p>Don&rsquo;t be fooled by the title. <a href="http://amzn.to/eGD2fv">The Business of iPhone and iPad App Development by Dave Wooldridge and Michael Schneider</a> isn&rsquo;t one of your boss&rsquo; stuffy business book. This is a practical, hands on, guide to making a successful iOS app. It assumes you already have an idea and know how to develop it, but it guides you through the steps of focusing the app, designing it so it can be profitable, and releasing it with the best possible chance of becoming a good seller.</p>
<p>You&rsquo;ve probably heard a dozen stories of developers who create a great app, submit it to the App Store, and then wonder why they only sold a dozen copies. This is the book they need to go along with that great app.</p>
<p>The book roughly follows the development timeline of an app, from the initial concept, design, implementation, testing, and release. At each of the stages, it covers any aspects that can have a significant impact in the sales success of the app. Even though you can read the book cover to cover, the chapters are very well defined, so it&rsquo;s easy to jump directly to the part that interests you the most.</p>
<p>With <a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a> almost ready to submit to Apple, I read with particular interest the chapters on creating prerelease buzz and increasing awareness of the app. Lots of good advice there.</p>
<p>Don&rsquo;t expect anything groundbreaking though. If you&rsquo;ve been following this blog for a while, or you&rsquo;ve been hanging out on <a href="http://twitter.com/#!/noel_llopis/ios-gamedevs">Twitter with all the iOS developers</a>, you will know most of what the book has to offer. It might still be worth it for a few pearls of wisdom here and there to fill some blind spot. However, the book should be required reading for any new iOS developer. Easily the best $20 you can spend as far as impact in the final app sales.</p>
<p>I usually have no patience for technical books with filler chapters and sections. This book is very good about getting to the point, although it has a few sections that feel a bit out of place in that they&rsquo;re quite basic and technical (like details of generating provisioning profiles, did we really need that in this book?). All in all, that&rsquo;s a pretty minor point and easy to get around them.</p>
<h3 id="delayed-release">Delayed Release</h3>
<p>Probably my main criticism is that the book doesn&rsquo;t mention one release technique that I consider to be a requirement for any major launch these days: The delayed launch. As the authors mention several times in the last few chapters, once you submit your app, you have no control over when Apple approves it, so you have to play some guessing games.</p>
<p>Instead, you can delay the release of the app once it has been approved, and set it to a known, fixed date in the future (say, a week from approval). At that point, you can really kick in your PR in high gear, contact media outlets, and, most importantly, send them promo codes for your app, even though it&rsquo;s not available for sale yet.</p>
<p>The goal is to have all the PR hit on launch day or shortly after. The more you can make that happen, the more successful any PR efforts will be, and the bigger the initial launch (and hopefully the following sales) will be.</p>
<p>All in all, The Business of iPhone and iPad App Development is an easy recommendation for the new iOS developer. Go read it right now before you even think of shipping another app.</p>
]]></content:encoded></item><item><title>All It Needs Is Love</title><link>https://gamesfromwithin.com/all-it-needs-is-love/</link><pubDate>Fri, 18 Mar 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/all-it-needs-is-love/</guid><description>&lt;p&gt;The App Store today is a different beast from the one in early 2009, when &lt;a href="http://www.wired.com/gadgetlab/2009/02/shoot-is-iphone/"&gt;iShoot ruled the charts&lt;/a&gt;. Look at the top paid games on the App Store today. Actually, don&amp;rsquo;t worry, I did all the leg work for you. Here they are:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Top paid" loading="lazy" src="https://gamesfromwithin.com/all-it-needs-is-love/images/top_paid.png"&gt;&lt;/p&gt;
&lt;p&gt;What can we tell by looking at those games? I see two clear categories: Games with a strong, established IP (Street Fighter, Sonic), or independent games with a huge amount of polish and style.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The App Store today is a different beast from the one in early 2009, when <a href="http://www.wired.com/gadgetlab/2009/02/shoot-is-iphone/">iShoot ruled the charts</a>. Look at the top paid games on the App Store today. Actually, don&rsquo;t worry, I did all the leg work for you. Here they are:</p>
<p><img alt="Top paid" loading="lazy" src="/all-it-needs-is-love/images/top_paid.png"></p>
<p>What can we tell by looking at those games? I see two clear categories: Games with a strong, established IP (Street Fighter, Sonic), or independent games with a huge amount of polish and style.</p>
<h3 id="its-all-about-polish">It&rsquo;s All About Polish</h3>
<p>The love and care developers put into those games shows the moment you start them up. Look at the textures in Tiny Wings, the sound effects in Angry Birds, the feedback animations in Words With Friends, or all the little details in Cut The Rope. All the tiny particle effects, transitions, sounds, and general squish and responsiveness. Every single one of those games is oozing with its own style and contributes to a very enjoyable first (and repeat) experience.</p>
<p>And that is the main point of this post: To make a successful game on the App Store, the main thing you need is love. You can skimp on features, on content, on marketing, on a web site, or even on gameplay balance. All those are things that you can add or improve after shipping, but polish and style are responsible for that crucial first impression. Miss the chance to hit the player with all you&rsquo;ve got the first time they play your game, and that might be a lost sale (and a lost advocate of your game since word of mouth is such a strong force on the App Store).</p>
<p>Not convinced about the difference polish and style makes?</p>
<p>This game is essentially Tiny Wings with just a little bit of polish (and it does have *some* polish).</p>
<iframe title="YouTube video player" src="http://www.youtube.com/embed/uRt3ccRzxOo" frameborder="0" width="480" height="390"></iframe>
<p>And this is Tiny Wings.</p>
<iframe title="YouTube video player" src="http://www.youtube.com/embed/VUnlE4cGgz0" frameborder="0" width="640" height="390"></iframe>
<p>I rest my case.</p>
<h3 id="ship-as-soon-as-possible">Ship As Soon As Possible?</h3>
<p>Traditional game development (especially for consoles) usually goes along these lines: Plan everything, create a game with everything that you want/can fit, ship it once it&rsquo;s done, and hope not to touch it again. On the other hand, in this day of web/Facebook/mobile development the favored approach is to release a product as soon as possible, and then iterate from there.</p>
<p>My preference in the last few years has been more along the shipping as soon as possible lines (even if I haven&rsquo;t always been successful at it). But then I paused and really thought about why and what I would accomplish by shipping early. These are the main reasons I could think about:</p>
<ul>
<li><strong>Getting to market first</strong>. This is a big one in the web world (and maybe even in the hardware world). Even if your product is imperfect, or its UI is less than ideal, getting that initial critical mass of users could be what tips the balance in your favor.</li>
<li><strong>Canceling the project early</strong>. Maybe it takes as long as the first version of a product to realize there isn&rsquo;t demand for it. So it was better to have spent 6 months instead of 3 years before canceling the project.</li>
<li><strong>Focussing your efforts</strong>. An impending ship date will make wonders to keep people on track and focused on what&rsquo;s important to ship a game.</li>
<li><strong>Become profitable as soon as possible.</strong> Even if you make the same amount of money and spend the same amount of time working on a project, if you start bringing in money at the 6 month mark rather than at the 3 year mark, you&rsquo;ll be profitable earlier. And as any RTS fan will tell you, getting extra resources early in the game can put you at a huge advantage.</li>
<li><strong>Changing the product based on early user feedback</strong>. Otherwise you might spend years working on a product that people don&rsquo;t really want, or they would prefer something slightly different.</li>
</ul>
<p>How do those reasons apply to iOS games?</p>
<ul>
<li>As an iOS game, your biggest moment is launch. That&rsquo;s when you can get most momentum and get the word of mouth ball rolling. First impressions matter a lot and a lot of people will make snap decisions about your game in the first few seconds. If it&rsquo;s not looking its best, it doesn&rsquo;t matter if it came earlier than another game. Besides, games, for the most part, aren&rsquo;t providing as much of a service as they&rsquo;re a form of entertainment. Barring brand new genres or whole new platforms, getting to market first doesn&rsquo;t mean much. And even if you&rsquo;re making a brand new genre, chances are it&rsquo;s unique so the clones won&rsquo;t start showing up until after you launch and becomes popular (unless you announce way in advance).</li>
<li>Stopping development on an unsuccessful game earlier rather than later is always a good thing.</li>
<li>Likewise, having a milestone around the corner does wonders for focussing your efforts. That was one of the big benefits we got from <a href="/caseys-contraptions-and-the-igf/">submitting Casey&rsquo;s Contraptions to the IGF</a>.</li>
<li>The last one is tricky. It might seem like a benefit for iOS games as well, but I&rsquo;m going to argue it isn&rsquo;t. Don&rsquo;t get me wrong, I think that testing and user feedback is very valuable. But games ultimately are a form of art[1] and you are the creator. In the end, you need to decide what your game and your vision are like. Feedback will help with usability and balancing issues, but not with what the game is fundamentally. Stick to your vision.</li>
</ul>
<h3 id="my-approach">My Approach</h3>
<p>Looking at those lists, it makes it clear to me that iOS game development is not all about getting a product out of the door as soon as possible. There&rsquo;s no need to create a finished product for your first release. Instead, save every feature and content you can for free updates or even future in-app purchases.</p>
<p>I&rsquo;m convinced that polish and style are one of the most important things an iOS game can have. <a href="/the-importance-of-first-impressions/">It&rsquo;s not the first time I say that</a>. So get the product out as soon as you can, but do not, under any circumstances, cut any polish from your game. Plan on spending a good month or longer after your game is &ldquo;done&rdquo; polishing it. That time will definitely be well spent and will increase the value of your game more than any other month you spent developing it.</p>
<p>What I&rsquo;m suggesting here is actually quite different from what <a href="http://chrishecker.com/Please_Finish_Your_Game">Chris Hecker talked about at last year&rsquo;s GDC</a>. Even though we&rsquo;re both saying &ldquo;take your time and do your game right&rdquo;, he&rsquo;s emphasizing the completeness of the game (in the sense of exploring all its potential), while I&rsquo;m emphasizing the presentation. I think the main reason our messages are so different is the platform we&rsquo;re developing for. On a platform like iOS, I really think you can explore the full potential of a game after it ships without any real drawbacks.</p>
<p>Right now we&rsquo;re in the polish phase in <a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a>. The game has been &ldquo;done&rdquo; for a while, in the sense that we have all the items, lots of levels, you can play through all the puzzles, make your own contraptions, etc. Even though it already has a lot of style and polish, it definitely needs that extra layer of shine to make it really stand out and bring it to the quality of those games in the top 10 list. We can only hope that Casey&rsquo;s Contraptions joins them after we launch!</p>
<p><img alt="Caseys1" loading="lazy" src="/all-it-needs-is-love/images/caseys1.jpg"></p>
<p><img alt="Caseys2" loading="lazy" src="/all-it-needs-is-love/images/caseys2.jpg"></p>
<p> </p>
<p>Interested in keeping up with Casey&rsquo;s Contraptions as we&rsquo;re gearing up for launch? <a href="http://www.facebook.com/contraptions">Join the Facebook page</a>.</p>
<iframe style="border: none; overflow: hidden; width: 450px; height: 80px;" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.facebook.com%2Fcontraptions&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;font&amp;colorscheme=light&amp;height=80" frameborder="0" scrolling="no" width="320" height="240"></iframe>
<p> </p>
<p>[1] Feel free to substitute whatever word you want there that isn&rsquo;t offensive to you: entertainment, interactive media, etc. Games are something *you* create from your imagination, so art seems like the best term to me.</p>]]></content:encoded></item><item><title>Finding the Loose Change</title><link>https://gamesfromwithin.com/finding-the-loose-change/</link><pubDate>Tue, 15 Feb 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/finding-the-loose-change/</guid><description>&lt;p&gt;&lt;em&gt;I&amp;rsquo;m thrilled to present a guest post by&lt;/em&gt; &lt;a href="http://twitter.com/#!/eeen"&gt;&lt;em&gt;Ian Marsh&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, 1/2 of the independent studio (and wildly successful)&lt;/em&gt; &lt;a href="http://nimblebit.com/"&gt;&lt;em&gt;NimbleBit&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. They&amp;rsquo;re the creators of iPhone hits such as Pocket Frogs, Scoops, and Sky Burger, and they recently announced &lt;a href="http://twitter.com/#!/NimbleBit/status/37201707305943040"&gt;they reached 20 million downloads on the App Store&lt;/a&gt;__!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="images/nb_logo128.png"&gt; One of the most important steps on the way to becoming a profitable independent iOS developer is diversifying your revenue stream. Â While business lingo like that makes me throw up a little, all it really means is discovering all the ways you can earn money using the platform. Â New developers sometimes pigeonhole themselves into a single App Store strategy: &amp;ldquo;Sell as many copies at 99 cents as possible&amp;rdquo;. Â More savvy developers mix Â multiple strategies: &amp;ldquo;Paid apps&amp;rdquo;, &amp;ldquo;In-App Purchases&amp;rdquo;, and &amp;ldquo;Advertising&amp;rdquo;. Â I want to make sure all developers know about another additional option often overlooked: LinkShare.&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>I&rsquo;m thrilled to present a guest post by</em> <a href="http://twitter.com/#!/eeen"><em>Ian Marsh</em></a><em>, 1/2 of the independent studio (and wildly successful)</em> <a href="http://nimblebit.com/"><em>NimbleBit</em></a><em>. They&rsquo;re the creators of iPhone hits such as Pocket Frogs, Scoops, and Sky Burger, and they recently announced <a href="http://twitter.com/#!/NimbleBit/status/37201707305943040">they reached 20 million downloads on the App Store</a>__!</em></p>
<p><img loading="lazy" src="images/nb_logo128.png"> One of the most important steps on the way to becoming a profitable independent iOS developer is diversifying your revenue stream. Â While business lingo like that makes me throw up a little, all it really means is discovering all the ways you can earn money using the platform. Â New developers sometimes pigeonhole themselves into a single App Store strategy: &ldquo;Sell as many copies at 99 cents as possible&rdquo;. Â More savvy developers mix Â multiple strategies: &ldquo;Paid apps&rdquo;, &ldquo;In-App Purchases&rdquo;, and &ldquo;Advertising&rdquo;. Â I want to make sure all developers know about another additional option often overlooked: LinkShare.</p>
<p><a href="http://www.linkshare.com/publishers/">LinkShare</a> is a company which pairs publishers with retailers who pay said developers for driving clicks to their sites that result in sales. Â How does this apply to iOS developers? Â Luckily Apple (specifically iTunes) is one of the retailers which uses LinkShare. Â A good FAQ page for the iTunes affiliate program can be found <a href="http://www.apple.com/itunes/affiliates/resources/documentation/frequently-asked-questions.html">here</a>, but the basic gist of it that you earn a 5% commission on items bought on the App Store from your affiliate links. Â As an iOS developer you are probably already using links to your apps (and perhaps others) in lots of places, including &ldquo;More Games&rdquo; screens, twitter, newsletters, banner ads, or your web site. Â Replacing all these existing (and future) links to the App Store with your affiliate links is a great start. Â Retro Dreamer even wrote a <a href="http://retrodreamer.com/blog/2010/07/slight-change-of-plan/">nice quick guide</a> to creating links that work seamlessly in iOS (there are some pros and cons to different link formats).</p>
<p>Now you might think the chances of someone actually buying an app you link to are relatively low, but that&rsquo;s where things get interesting. Â If you read the fine print it turns out affiliates get paid 5% of any purchases made within a 72 hours after following your link. Â Lets say Joe clicks on a link to say, <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=386644958&amp;mt=8&amp;partnerId=30&amp;siteID=0JkCNyaaKoo">Pocket Frogs</a> (our latest free game) which included your affiliate id, which even doesn&rsquo;t result in a paid purchase even if the app is downloaded. Â But perhaps Joe ends up buying Angry Birds ($0.99) an hour later earning you $0.05, or Real Racing 2 ($4.99) that night earning you $0.25, or just maybe the Beatles Box Set ($149.00) the next morning earning you $7.45! Â The cool thing about the iTunes affiliate program is that it gives the affiliate 5% of any and all purchases made through iTunes within 72 hours including ring tones, songs, apps, in-app purchases, movies, tv shows, or rentals.</p>
<p>This of course means you can still earn revenue from linking to free apps, Â which can end up being a powerful thing. Â For example, in Pocket Frogs we run a promotion every week where we offer an in game item for downloading a certain free app (with a LinkShare link of course). Â This not only keeps players checking back, but lets us promote apps we like (like Flower Garden) or even our own. Â Like most other revenue sources LinkShare isn&rsquo;t going to make you a whole lot of money if there aren&rsquo;t that many people clicking your links, but it will certainly grow along with the number of users you have. Â While the majority of revenue generated from Pocket Frogs (which fluctuates between 150k and 200k daily active users) comes from the IAP included in the game, it also generates a healthy amount of revenue from LinkShare (in conjunction with some links inside other apps) as seen below.</p>
<p><img alt="pf_promo.jpg" loading="lazy" src="/finding-the-loose-change/images/pf_promo.jpg"></p>
<p><img alt="pf_promo.jpg" loading="lazy" src="images/PF_LS.png"></p>
<p>The great thing about LinkShare is that it gives you a lot of freedom on how you use it. It doesn&rsquo;t use up any bandwidth or take up CPU cycles, and it doesn&rsquo;t require you to shoehorn 3rd party code into your app. It is as invisible or invasive as you want it to be. So whether you&rsquo;re a new iOS developer just starting out or an experienced dev, you owe it to yourself to take a look at using LinkShare if you&rsquo;re not using it already.</p>
]]></content:encoded></item><item><title>Flower Garden Featured For Valentine's Day!</title><link>https://gamesfromwithin.com/flower-garden-featured-for-valentines-day/</link><pubDate>Thu, 10 Feb 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-featured-for-valentines-day/</guid><description>&lt;p&gt;Two years ago, when I was working on the first release of Flower Garden, Valentine&amp;rsquo;s Day was my target ship date. Unfortunately (or fortunately depending on how you look at it), I missed it and rescheduled it for April. Last year I was eagerly awaiting the Valentine&amp;rsquo;s Day features hoping for a feature by Apple, but Flower Garden wasn&amp;rsquo;t one of the apps to be selected. It was disappointing but understandable given how many newer quality apps are out there.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Two years ago, when I was working on the first release of Flower Garden, Valentine&rsquo;s Day was my target ship date. Unfortunately (or fortunately depending on how you look at it), I missed it and rescheduled it for April. Last year I was eagerly awaiting the Valentine&rsquo;s Day features hoping for a feature by Apple, but Flower Garden wasn&rsquo;t one of the apps to be selected. It was disappointing but understandable given how many newer quality apps are out there.</p>
<p>Fast-forward another year, and this morning I woke up to a very pleasant and unexpected surprise: Flower Garden was featured on the App Store under Apps For Valentine&rsquo;s Day!</p>
<p><img alt="Valentines apple feature" loading="lazy" src="/flower-garden-featured-for-valentines-day/images/valentines_apple_feature.png"></p>
<p>Flower Garden is still going strong, but I wasn&rsquo;t expecting that at all. Thank you, Apple! Not only that, but this feature also appears on the device App Store. Flower Garden was featured twice before by Apple, but never before on a spot that appeared on the device. So that&rsquo;s a first for Flower Garden!</p>
<p><img alt="Valentines apple feature iphone" loading="lazy" src="/flower-garden-featured-for-valentines-day/images/valentines_apple_feature_iphone.png"></p>
<p>To make things more interesting, I had been planning on doing a bit of promotion around Valentine&rsquo;s Day like last year. So a few days ago I <a href="http://www.facebook.com/iphoneflowergarden/posts/165687373479182">released a new update</a>, and included another in-app purchase for the most asked-for feature: More pots in another garden space.</p>
<p><img alt="Secret Garden" loading="lazy" src="/flower-garden-featured-for-valentines-day/images/Secret_Garden.jpg"></p>
<p>Finally, to round things off, I planned on doing a similar promotion to what I did last year around Mother&rsquo;s Day, and I set Flower Garden to be free from today until Valentine&rsquo;s Day to encourage even more people to try it. To get the word out of the price drop, I got some promotion going from <a href="http://itunes.apple.com/us/app/pocket-frogs/id386644958?mt=8">Pocket Frogs</a> and a few other apps encouraging users try out the now free Flower Garden. I&rsquo;m also hoping a few media outlets cover the sale to get the word out as much as possible.</p>
<p><img alt="Pf fg" loading="lazy" src="/flower-garden-featured-for-valentines-day/images/pf_fg.jpg"></p>
<p>As of this moment, Flower Garden is in the top 100 apps in the US and in the top 50 games, so the combination of everything seems to be working. We&rsquo;ll see how things develop over this coming week. Until then, it&rsquo;s going to be an exciting ride.</p>
<p>For the latest news on Flower Garden, join the Facebook page by clicking &ldquo;Like&rdquo;:</p>
<iframe src="http://www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Ffacebook.com%2Fiphoneflowergarden&amp;width=500&amp;colorscheme=light&amp;show_faces=true&amp;stream=true&amp;header=true&amp;height=427" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:427px;" allowtransparency="true"></iframe>
]]></content:encoded></item><item><title>Sleep-Deprived Reflections On The 360iDev Game Jam</title><link>https://gamesfromwithin.com/sleep-deprived-reflections-on-the-360idev-game-jam/</link><pubDate>Fri, 12 Nov 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/sleep-deprived-reflections-on-the-360idev-game-jam/</guid><description>&lt;p&gt;About 48 hours ago, I participated in the &lt;a href="http://gamejam.360idev.com/"&gt;360iDev Game Jam&lt;/a&gt;. I&amp;rsquo;m still recovering from the sleep deprivation and caffeine excesses, but here are some random thoughts about the game jam and why I highly recommend the experience to all developers.&lt;/p&gt;
&lt;p&gt;This was my third 360iDev Game Jam, and it gets better all the time. It&amp;rsquo;s great to see that it has become a 360iDev tradition, and that the number of people participating is going up every time. The last couple of times we had one invited guest to participate remotely (and preside over everybody else in the big &lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/10/owen.jpg"&gt;video&lt;/a&gt; &lt;a href="http://toucharcade.com/wp-content/uploads/2010/04/gamejam52.jpg"&gt;screen&lt;/a&gt;), but this time we opened it up so anybody, anywhere in the world could join us and participate in the updates and discussions through the web site (big thanks for &lt;a href="http://weheartgames.com/"&gt;Mike Berg&lt;/a&gt; for all the excellent work on the web site!).&lt;/p&gt;</description><content:encoded><![CDATA[<p>About 48 hours ago, I participated in the <a href="http://gamejam.360idev.com/">360iDev Game Jam</a>. I&rsquo;m still recovering from the sleep deprivation and caffeine excesses, but here are some random thoughts about the game jam and why I highly recommend the experience to all developers.</p>
<p>This was my third 360iDev Game Jam, and it gets better all the time. It&rsquo;s great to see that it has become a 360iDev tradition, and that the number of people participating is going up every time. The last couple of times we had one invited guest to participate remotely (and preside over everybody else in the big <a href="/wp-content/uploads/2009/10/owen.jpg">video</a> <a href="http://toucharcade.com/wp-content/uploads/2010/04/gamejam52.jpg">screen</a>), but this time we opened it up so anybody, anywhere in the world could join us and participate in the updates and discussions through the web site (big thanks for <a href="http://weheartgames.com/">Mike Berg</a> for all the excellent work on the web site!).</p>
<h3 id="whats-the-point">What&rsquo;s The Point</h3>
<p>Some people don&rsquo;t understand what the point of the game jam is. Other people see the value in it, but disagree with what other people see. The point of a game jam is the same as a jamming music session: To create something while surrounded by other developers and feed off each other&rsquo;s energy and enthusiasm.</p>
<p>In addition to the jamming aspect of it, different people have different goals, and they&rsquo;re all just as good and valuable:</p>
<ul>
<li>Trying a new game idea</li>
<li>Learning a new API or technique</li>
<li>Making a finished product</li>
<li>Starting something new</li>
<li>Being totally experimental</li>
<li>Stretching their comfort zone</li>
</ul>
<p>There were even people using the game jam as a means to make progress in their own game or app they had already started. It&rsquo;s a bit far from the original intent, but why not? It&rsquo;s the jamming part that is the most important.</p>
<p>I was glad to see that most people decided to work the theme (&ldquo;changing the world&rdquo;) in the game somehow. I definitely find that having some constraints helps me focus and be more creative at the same time.</p>
<p>One of the most attractive aspects of a game jam for me is that it&rsquo;s a very focused, but very short effort. Yes, it sounds epic: &ldquo;A full night of pizza, coffee, and coding&hellip;&rdquo; but it&rsquo;s only 8-10 hours. That means the cost of &ldquo;failure&rdquo; is minimal. It&rsquo;s about a work day. That&rsquo;s it. So that means it&rsquo;s possible to try new, risky, experimental things, and, most importantly, be OK if they don&rsquo;t work out. You don&rsquo;t learn by succeeding at everything.</p>
<h3 id="swapping-roles">Swapping Roles</h3>
<p>The last two game jams, I experimented with different kinds of game designs (<a href="/space-in-stereo-iphone-game-jam-postmortem/">heavy use of multi touch</a> and <a href="http://forums.toucharcade.com/showthread.php?t=52183">limited visibility</a>). This time around I&rsquo;m in the middle of a new project (<a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a>), and Miguel and I did about 5-6 <a href="/prototyping-youre-probably-doing-it-wrong/">prototypes</a> earlier this year, so I wasn&rsquo;t itching to do another experimental gameplay prototype.</p>
<p>So instead, <a href="http://twitter.com/mysterycoconut">Miguel</a> and I paired up again, but with a twist: He would do all the programming and I would do all the art. How&rsquo;s that for crazy? Actually, he&rsquo;s in a lot better shape because he&rsquo;s a good programmer in addition to being a great artist. Me, on the other hand, I can barely find my way around in Photoshop to copy and paste images from Google Images, so this was definitely going to be way out of my comfort zone.</p>
<p>As you can expect, <a href="http://gamejam.360idev.com/dueling-planets/">we didn&rsquo;t make as much progress as we had hoped</a>. On the other hand, I never had more fun or learned more new things at a game jam before! It helped a lot that I wasn&rsquo;t just flailing around with Photoshop, but that Miguel was there giving me pointers and showing me what the right way of doing things was. I went from not knowing that there was such a thing as a path tool, to becoming relatively proficient with it over the course of the night. It was like drinking a potion of +5 to Photoshop skills.</p>
<p>Apart from learning a lot, I also developed an even deeper appreciation and admiration of game artists. I knew it wasn&rsquo;t easy stuff and that you needed a lot of talent. What I wasn&rsquo;t quite fully appreciating is how technically involved art creation is! It&rsquo;s very different from traditional painting and drawing, and it&rsquo;s very highly technical. In a way, it&rsquo;s almost like 3D modeling in how it requires mastery of a very complex tool and you need to work on very small parts for a long time.</p>
<p>Here&rsquo;s a screenshot of the game showing all the assets I created during the jam:</p>
<p><img alt="DuelingPlanets_test.jpg" loading="lazy" src="/sleep-deprived-reflections-on-the-360idev-game-jam/images/DuelingPlanets_test.jpg"></p>
<h3 id="lessons-learned">Lessons Learned</h3>
<p>Some random, unsorted, lessons learned from this jam:</p>
<ul>
<li>Come ready with an empty project you can start working on. The jam is not the time when you want to start stripping out old code. I learned that one in <a href="/space-in-stereo-iphone-game-jam-postmortem/">my first game jam</a>, but didn&rsquo;t come prepared with an iPad project (Hint: the iPhone -&gt; iPad automatic conversion sucks&ndash;does anything automatic not suck?).</li>
<li>Everything takes longer than you think. If you think you&rsquo;ll just finish the game by morning, it&rsquo;s probably too big. Choose something smaller.</li>
<li>Learning stuff during the jam is great. Just adjust expectations about what you&rsquo;ll create (we knew this going in, but still caught us by surprise).</li>
<li>Take a moment to interact with the people around you. We&rsquo;re all in a hurry to make something awesome, but take some time to talk to other developers. It&rsquo;s well worth it, and makes the long night more bearable (and energizes you more).</li>
<li>Pizza and coffee is a killer combination. I suspect I might never have to go to sleep if I keep the two in balance ;-b</li>
<li>When wifi sucks, it&rsquo;s hard to take the time to post updates or read other people&rsquo;s updates.</li>
<li>Hotel wifi always sucks.</li>
<li>The jam is not a popularity contest. Sure, it&rsquo;s great to show it off the next day, but make sure you create what you want for yourself and not based on what will demo best the next day.</li>
</ul>
<p>If you haven&rsquo;t done a game jam, you should. I strongly suggest collaborating with at least one other person, and doing it live with a bunch of other developers. The energy is incredible and it will be an experience you&rsquo;ll learn a lot from and will remember for a long time.</p>
<p><em>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>. This will be my last post for iDevBlogADay for a while (need to give those people in the massive waiting list a chance!), but I&rsquo;ll definitely continue posting regularly.</em></p>
]]></content:encoded></item><item><title>The Power Of In-App Purchases</title><link>https://gamesfromwithin.com/the-power-of-in-app-purchases/</link><pubDate>Tue, 09 Nov 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-power-of-in-app-purchases/</guid><description>&lt;p&gt;I finally managed to get through the hotel wifi and upload the slides for this morning&amp;rsquo;s &lt;a href="http://360idev.com"&gt;360iDev&lt;/a&gt; talk: The Power Of In-App Purchases. Thanks everybody who attended for the great questions and feedback!&lt;/p&gt;
&lt;h3 id="session-description"&gt;Session description&lt;/h3&gt;
&lt;p&gt;The common-sense approach to make money on the App Store used to be to do anything to get on the top charts. In-app purchases changed all of that. Good in-app purchases can make your app profitable without being anywhere on the charts, and are the best hope for the independent developer. Come to this session to learn why IAPs can be so effective and how to leverage them effectively: what makes a good IAP, how to increase your user involvement, how to present IAPs in an attractive way, what things attract users, and what things turn them away. We&amp;rsquo;ll go through lots of detailed real-world data from Flower Garden and other games with strong IAPs.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I finally managed to get through the hotel wifi and upload the slides for this morning&rsquo;s <a href="http://360idev.com">360iDev</a> talk: The Power Of In-App Purchases. Thanks everybody who attended for the great questions and feedback!</p>
<h3 id="session-description">Session description</h3>
<p>The common-sense approach to make money on the App Store used to be to do anything to get on the top charts. In-app purchases changed all of that. Good in-app purchases can make your app profitable without being anywhere on the charts, and are the best hope for the independent developer. Come to this session to learn why IAPs can be so effective and how to leverage them effectively: what makes a good IAP, how to increase your user involvement, how to present IAPs in an attractive way, what things attract users, and what things turn them away. We&rsquo;ll go through lots of detailed real-world data from Flower Garden and other games with strong IAPs.</p>
<p><img alt="purchases_vs_users.png" loading="lazy" src="/the-power-of-in-app-purchases/images/purchases_vs_users.png"></p>
<p><strong>Presentation slides:</strong> [<a href="http://www.slideshare.net/llopis/power-iap">Slideshare</a>] [<a href="/wp-content/uploads/2010/11/power_iap.pdf">pdf</a>]</p>
]]></content:encoded></item><item><title>Chronicle Of A Failed Experiment</title><link>https://gamesfromwithin.com/chronicle-of-a-failed-experiment/</link><pubDate>Thu, 04 Nov 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/chronicle-of-a-failed-experiment/</guid><description>&lt;p&gt;In the last year and a half, I&amp;rsquo;ve written about the different things that I&amp;rsquo;ve tried with Flower Garden and their effects on sales. From &lt;a href="https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/"&gt;adding Facebook support, creating a free version&lt;/a&gt;, &lt;a href="https://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/"&gt;adding in-app purchases&lt;/a&gt;, or &lt;a href="https://gamesfromwithin.com/the-power-of-free/"&gt;giving Flower Garden for free for a limited time&lt;/a&gt;. Some strategies worked and some didn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Today I want to share my latest experiment, and how it was a total and complete failure: Adding the option to gift IAP items from within the game.&lt;/p&gt;</description><content:encoded><![CDATA[<p>In the last year and a half, I&rsquo;ve written about the different things that I&rsquo;ve tried with Flower Garden and their effects on sales. From <a href="/making-a-living-barely-on-the-iphone-app-store/">adding Facebook support, creating a free version</a>, <a href="/making-a-living-comfortably-on-the-app-store/">adding in-app purchases</a>, or <a href="/the-power-of-free/">giving Flower Garden for free for a limited time</a>. Some strategies worked and some didn&rsquo;t.</p>
<p>Today I want to share my latest experiment, and how it was a total and complete failure: Adding the option to gift IAP items from within the game.</p>
<p><img alt="gift_this.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/gift_this.png"></p>
<h3 id="promo-codes">Promo Codes</h3>
<p>Before I can talk about how I implemented the &ldquo;Gift This&rdquo; feature, we need to talk about promo codes. Since Flower Garden has so many in-app purchases, I figured it would be very handy to have the ability to give some of them away to people for any reason: They mistakenly downloaded the wrong thing, they bought it in the free version and want to upgrade to the full one, or they supposedly paid for one but they never got it. Whatever the reason, having my own promo codes for in-app purchases was one of the best decisions I could have made. I would highly recommend it if you have IAPs, especially consumables.</p>
<p>The implementation of promo codes was totally straightforward. I have two tables in the Google App Engine: One for active promo codes and one for redeemed ones. The active promo code includes the code itself, the IAP item it refers to, the amount, and whether it&rsquo;s limited to one user or not (if it&rsquo;s limited to one user, the code goes away as soon as it&rsquo;s redeemed, otherwise, any amount of users can redeem it).</p>
<p>Here&rsquo;s an example of a code I just added (yes, feel free to redeem it in the Flower Shop):</p>
<p><img alt="promo_code.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/promo_code.png"></p>
<p>Whenever a promo code is redeemed, I enter that data in the other table. That way not only do I have a log of what codes where redeemed and when, but I can also check and prevent the same device from redeeming the same code multiple times.</p>
<p>Another important reason to keep a redeemed promo code table is that I want promo codes to be as valid as purchasing the IAP directly. That means that if you ever attempt to purchase an item, I check first to see if you&rsquo;ve redeemed a promo code for it, and if so, you can re-download it for free. Same thing when you do a restore purchases (although I believe I haven&rsquo;t gotten around to implementing that part yet :-)</p>
<p>Here&rsquo;s my plea to Apple: <strong>Please, please, please, give us an &ldquo;iTunes Account ID&rdquo; along with the IAP data</strong>. Right now the best we can do is associate a purchase with a device (which is not good enough), or have a whole registration system for users (which is a pain and more time consuming for users). They&rsquo;re already doing this with a Game Center ID, so why not with an iTunes Account?</p>
<h3 id="gift-this">Gift This</h3>
<p>Once the promo code system was in place and field tested for a couple of months, I finally implemented the Gift This functionality. In the Flower Shop, users have the option to buy an item for themselves, or for someone else.</p>
<p>The first time you use the Gift This feature it explains how it works: You purchase the item and then you send it to someone else through email.</p>
<p>Under the hood, it purchases the IAP, contacts the server to generate a new promo code for that item, and then creates an email with the promo code and even a custom URL. Whenever someone receives a gift email, they can just click on the custom link and they immediately receive the item (assuming they have Flower Garden installed, of course).</p>
<p><img alt="gift_email.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/gift_email.png"></p>
<p>One interesting consequence is that to implement this, you need to create one new IAP item for every item you want to gift (especially if they&rsquo;re not consumable). Otherwise, someone couldn&rsquo;t gift an item they had already purchased, or they couldn&rsquo;t gift it more than once. This can add quite a few extra IAPs in your list!</p>
<p>In the case of Flower Garden, I started with the easiest case, and I only implemented gifting for fertilizer purchases (because they&rsquo;re consumable, so I don&rsquo;t have to keep track of who receives them and restoring them).</p>
<h3 id="total-failure">Total Failure</h3>
<p>I really had great hopes for the Gift This feature. I had already envisioned writing a blog post showing IAP revenue going up 20-30% because of that feature. Not quite! It was pretty much a complete flop. The only positive thing I can say about it is that it didn&rsquo;t actually lower regular sales.</p>
<p>See for yourself. In a period of about a month and a half, all the fertilizer gifting in the free and paid versions of Flower Garden amounted to a whopping $191!</p>
<p><img alt="gift_revenue.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/gift_revenue.png"></p>
<p>Definitely not worth the 3-4 days it took me to implement it (and the opportunity cost of not being able to add some other feature or IAP).</p>
<p>Compare it to fertilizer sales during that period of over $7,000:</p>
<p><img alt="fertilizer_revenue.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/fertilizer_revenue.png"></p>
<p>(That&rsquo;s the spike of the new feature plus <a href="/communicating-with-players/">the Pocket Frogs cross promotion</a> if you were wondering about it).</p>
<p>I&rsquo;d love to know how the Gift This feature on the App Store is working out for Apple. I&rsquo;m sure it&rsquo;s doing better than my attempt at it, but I&rsquo;m going to bet it&rsquo;s still a very small percentage compared to regular sales.</p>
<p>Here comes the important question: Why was it a failure? Do people don&rsquo;t like to gift? Was it presented badly? Did most people not know it existed?</p>
<p>There&rsquo;s no way to know for sure, but my current guess is that <strong>people don&rsquo;t like to gift something they don&rsquo;t already own</strong>. Psychologically, there are several too many steps involved: Oh, I want to gift something, look for it in the store, purchase it, and send the email. Not a very fulfilling experience.</p>
<p>On the other hand, gifting something you already own is much more appealing. You have it in front of you, you&rsquo;re proud of it and it looks great. You tap on a button and send it to someone. That is a lot more satisfying. So in the future I&rsquo;ll take that approach and allow people to gift things they already own, even if they had to previously pay for it in some way.</p>
<p>What do you think? Do you have a better theory? How could it have been improved?</p>
<p><em>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>.</em></p>
]]></content:encoded></item><item><title>Games, Resources, And XCode</title><link>https://gamesfromwithin.com/games-resources-and-xcode/</link><pubDate>Thu, 14 Oct 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/games-resources-and-xcode/</guid><description>&lt;p&gt;Up until a few weeks ago, I never had any problems with iPhone game resources. I just added whatever I needed to the XCode project, and it was ready to load from within the game. That simple.&lt;/p&gt;
&lt;p&gt;But that was because of the &lt;a href="http://itunes.apple.com/us/app/flower-garden-free-grow-flowers/id327466677?mt=8&amp;amp;partnerId=30&amp;amp;siteID=aDkhM0mDflg"&gt;kind&lt;/a&gt; of &lt;a href="http://itunes.apple.com/us/app/lorax-garden/id366510234?mt=8&amp;amp;partnerId=30&amp;amp;siteID=aDkhM0mDflg"&gt;games&lt;/a&gt; I was making, which were very light on content, with mostly procedurally generated assets (the consequence of working by myself and being much better at programming than at Photoshop).&lt;/p&gt;</description><content:encoded><![CDATA[<p>Up until a few weeks ago, I never had any problems with iPhone game resources. I just added whatever I needed to the XCode project, and it was ready to load from within the game. That simple.</p>
<p>But that was because of the <a href="http://itunes.apple.com/us/app/flower-garden-free-grow-flowers/id327466677?mt=8&amp;partnerId=30&amp;siteID=aDkhM0mDflg">kind</a> of <a href="http://itunes.apple.com/us/app/lorax-garden/id366510234?mt=8&amp;partnerId=30&amp;siteID=aDkhM0mDflg">games</a> I was making, which were very light on content, with mostly procedurally generated assets (the consequence of working by myself and being much better at programming than at Photoshop).</p>
<p>That game that <a href="http://twitter.com/#!/mysterycoconut">Miguel</a> and I are working on right now is a lot heavier on assets. It has locations, and levels, and the whole shebang. And that&rsquo;s where XCode starts falling short.</p>
<h3 id="explicit-resources">Explicit Resources</h3>
<p><img alt="copy_bundle_resources.png" loading="lazy" src="/games-resources-and-xcode/images/copy_bundle_resources.png">Before, I was adding all my game assets to the Resources folder in XCode. That adds the file to the &ldquo;Copy Bundle Resources&rdquo; step. And as you expect, when you do a build, it checks the date of the existing file, and only copies it if the source file is newer than the destination file.</p>
<p>Personally, I really like this approach. I like to be explicit about what gets included in a game, and I don&rsquo;t mind at all having to add files manually to the project.</p>
<p>Unfortunately, it has one <strong>major</strong> flaw: It collapses all assets at the root of the application directory, ignoring the directory structure where they came from. I have no idea what the rational is for this &ldquo;feature&rdquo;, but someone needs to be taken out to the public town plaza and whipped for that. Actually, make that a double-whipping session if the reason was &ldquo;convenience&rdquo;.</p>
<p>The reason this becomes a big deal now is that we have per-level resources. To keep things sane, we decided to use a directory hierarchy, so Levels/Level00 contains all the files necessary for that level. Same thing with Level01, etc. The problem comes that both those levels have similarly named files: Background.jpg Layout.bin, etc.</p>
<p>Any guesses what happens if you add to XCode two files with the same filename in different paths? Yup. One of them overrides the other. Not a single warning either. Let&rsquo;s make that a triple-serving of whipping, please.</p>
<p>I briefly considered prefixing all the files with the level name (Level00_Background.jpg), but if later I decide to move Level00 to Level05 that&rsquo;s a lot of files to rename, so I would end up having to write scripts, or create a separate file with the level ordering, or just generally waste my time doing something that should have been taken care of by the tool.</p>
<h3 id="folder-references">Folder References</h3>
<p>Even though I had read they had their share of problems, I decided to look a folder references (at Miguel&rsquo;s prompting mostly).</p>
<p>When you add some resources to XCode, you have an option to check &ldquo;Create Folder References for any added folders&rdquo;. That option automatically adds any files in those folders without having to explicitly add them to XCode. So you could add the Levels folder, and then any files you create there will be copied with the game.</p>
<p><img alt="folder_references.png" loading="lazy" src="/games-resources-and-xcode/images/folder_references.png"></p>
<p>I&rsquo;m not a big fan of assets copied automatically, but as a side effect, that step preserves the directory hierarchy each of those files was in. So any files copied this way can be accessed from within the game by using their full directory structure.</p>
<p>I have to ask again: Why are directory structures preserved here but not with explicit resources added to the project? The mind boggles.</p>
<p>But hey, at least it works, right? Not exactly. There are a couple of gotchas.</p>
<p>The big one I had read in <a href="http://majicjungle.com/blog/?p=123">multiple</a> <a href="http://struct.ca/2010/xcode-folder-references/">places</a>, is that XCode doesn&rsquo;t detect any changes to files inside the referenced folder. So you can be making all sorts of changes, building the game, and not seeing anything different. The recommended solution was to add an extra step to the build process that would start by touching the reference folder, forcing a full copy of all assets.</p>
<p>I tested that, I&rsquo;m glad to report that at least in XCode 3.2.4, that&rsquo;s not the case. If you modify any file inside a referenced folder, the file will get copied over correctly during the build process without the need of extra steps.</p>
<p>The bad news is that <strong>all the files</strong> in the referenced folder will be copied. Why oh why??? They clearly know which file changed, why do they feel the need to copy all of the other files? No idea. This is not a big deal early on, but as you start to accumulate dozens and hundreds of megabytes of assets, build times start increasing quite a bit, especially on the device itself.</p>
<p>This is what the copy command looks like for referenced folders:</p>
<pre tabindex="0"><code>CpResource build/Debug-iphonesimulator/Test.app/Levels Levels
cd /Users/noel/Development/Test/trunk/Test
setenv PATH &#34;/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin&#34;
/Developer/Library/PrivateFrameworks/DevToolsCore.framework/Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -Testve-src-symlinks /Users/noel/Development/Test/trunk/Test/Levels /Users/noel/Development/Test/trunk/Test/build/Debug-iphonesimulator/Test.app
</code></pre><p>It&rsquo;s nice touch that it automatically excludes .svn directories though. I was wondering why they use CpResource instead of plain, old cp, but I guess that&rsquo;s to be able to -exclude specific files. Fair enough.</p>
<p>However, what CpResource apparently doesn&rsquo;t do is to process any of the resources in ways that were processed before by XCode. For example, a png file would have been processed by premultiplying it and byte swapping it so loading it in the iPhone would be slightly more efficient. CpResource just does a regular copy and leaves it alone. So if you were relying on that behavior, you need to do it explicitly yourself in your asset baking step.</p>
<h3 id="what-i-really-want">What I Really Want</h3>
<p>For now, I&rsquo;m using folder references for the levels, and explicit references for everything else. That way I keep the data size to a minimum but I get to have the directory hierarchy. Not ideal, but at least it works.</p>
<p>This is what I would really like thought:</p>
<ol>
<li>Easiest: Explicit assets with paths. I really want to just add resources to XCode and have it preserve the directory structure. It&rsquo;s not that hard. If XCode were open source, I would have made that change a long time ago. Can we at least have this as an option?</li>
<li>Second easiest: Folder references that only copy the changed resources. That would also be OK in my book, and I can&rsquo;t believe it would be much harder to implement either.</li>
<li>Best: A remote file system hosted on the Mac during debug build. All file references go out to the host machine and get loaded on the fly. This would allow for fastest build times and loading times would not be that different from a fragmented drive on an old device probably. I know some of you already have something like this. Has anybody made one open source (preferably minimalistic and standalone)? I&rsquo;d love to check it out.</li>
</ol>
<p>Of course, all of this has probably changed already with XCode 4, but I&rsquo;m deathly afraid of installing it while working on a production game. Has anybody tried it yet? Have they fixed anything, or is it even more broken?</p>
<p>To wrap things up, and since <a href="http://twitter.com/#!/mysterycoconut/status/27377955896">Miguel is spilling the beans on Twitter</a>, I&rsquo;ll share a few assets from our current game. Now back to the game because we&rsquo;re submitting it to the Independent Games Festival on Monday. Next Thursday I&rsquo;ll talk about the IGF. Wish us luck!</p>
<p><img alt="clock.png" loading="lazy" src="/games-resources-and-xcode/images/clock.png"></p>
<p><em>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>.</em></p>
]]></content:encoded></item><item><title>Communicating With Players</title><link>https://gamesfromwithin.com/communicating-with-players/</link><pubDate>Thu, 30 Sep 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/communicating-with-players/</guid><description>&lt;p&gt;By now every iOS developer knows that making a great game and putting it on the App Store is only part of the work. In order to get significant sales, it needs to be noticed. You need to spend a significant amount of time in marketing and PR, making sure that blogs cover it, magazines review it, or at least jump-starting it with a group of devoted and vocal forum fans.&lt;/p&gt;</description><content:encoded><![CDATA[<p>By now every iOS developer knows that making a great game and putting it on the App Store is only part of the work. In order to get significant sales, it needs to be noticed. You need to spend a significant amount of time in marketing and PR, making sure that blogs cover it, magazines review it, or at least jump-starting it with a group of devoted and vocal forum fans.</p>
<p>Most often, the advice stops there. So you get your initial sales spike and then sales go way down. What do you do then? Usually, developers release new features and updates. That&rsquo;s great, but how do you get people to notice it. You need to establish some form of communication with your players.</p>
<h3 id="update-messages">Update Messages</h3>
<p>The simplest form of communication is through the &ldquo;What&rsquo;s new&rdquo; section in the update. You can use that section not just to list what features you added and what bugs you fixed, but also to let your players know about other things: plans for the future, other games to try, or even the URL for your Facebook group.</p>
<p>Credit goes to <a href="http://twitter.com/limasky">Igor</a> for bringing up this idea and pointing out the URLs are even clickable in this field (but they aren&rsquo;t in the app description).</p>
<p>Of course, if you&rsquo;re like me and you update your apps only once in a while, this technique isn&rsquo;t as effective. Right now my iPhone tells me I have 67 new updates available. I&rsquo;m clearly not going to be reading through the release notes of each one.</p>
<h3 id="in-game-news">In-Game News</h3>
<p><img alt="fg_promo.jpg" loading="lazy" src="/communicating-with-players/images/fg_promo.jpg">A more direct way of reaching out to your players is to have some sort of in-game news system. At any point you can update a file in your web server with any news, and it is displayed in the game. It can be implemented in many different ways depending on &ldquo;on your face&rdquo; you want to be about it: a pop up that comes up when the user runs the game, a ticker that runs constantly across the bottom of the screen, or, what I did for Flower Garden, a news icon with a badge indicating how many unread items there are, that brings up the news page when you tap it.</p>
<p>Make sure players are able to click on URLs in your news messages so you can direct them to different web pages easily. More on that on a bit.</p>
<h3 id="emails">Emails</h3>
<p>Update messages are only good for players who update their apps (ahem, ahem), and in-game news for active players who&rsquo;re currently launching your apps. For maximum effect, you can send an email newsletter and that way you can also reach users who played the game at some point in the past, but aren&rsquo;t currently playing it now. They&rsquo;re the ones probably most interested in new updates and features, and chances are you can rekindle their interest in the game.</p>
<p>To do this, you should encourage users to register for your mailing list, or collect their emails with their consent in some other way. This was a technique I started using back in December of last year <a href="/making-a-living-barely-on-the-iphone-app-store/">with great success</a>.</p>
<p>I&rsquo;m currently using <a href="http://www.yourmailinglistprovider.com/">Your Mailing List Provider</a> as a means to delivering thousands and thousands of emails <a href="#1">[1]</a>. By the way, <a href="http://ymlp.com/xgemmyyugmgj">don&rsquo;t miss a chance to join the Flower Garden mailing list</a> :-)</p>
<h3 id="facebook">Facebook</h3>
<p>Similar to the mailing list approach, <a href="http://www.facebook.com/iphoneflowergarden">Facebook groups</a> can be a very effective form of communication. An additional benefit is that friends of your players might see them participating in the page and might make them try out your game.</p>
<h3 id="case-study-pocket-frogs-cross-promotion">Case Study: Pocket Frogs Cross-Promotion</h3>
<p>All that is fine in theory. How does it work in practice? I have been using all four forms of communication for a while, and I&rsquo;m definitely seeing good bumps of sales and downloads with each update and each major communication.</p>
<p>Last week, <a href="http://twitter.com/eeen">Ian</a> and <a href="http://twitter.com/NimbleDave">Dave</a> from <a href="http://nimblebit.com/">Nimblebit</a> and I, decided to set up a cross promotion between Pocket Frogs and Flower Garden.</p>
<p><img alt="pf_promo.jpg" loading="lazy" src="/communicating-with-players/images/pf_promo.jpg"></p>
<p>I updated the in-game news and send out an email newsletter coinciding with the latest Flower Garden update telling the players that if they downloaded Pocket Frogs from within Flower Garden, they would be awarded 5 doses of fertilizer. Nimblebit awarded players a flower if they downloaded Flower Garden Free from within Pocket Frogs.</p>
<p>When you have over a million downloads in a week like Pocket Frog did, that kind of player communication is the equivalent of a nuclear cannon. The effects of the cross-promotion were obvious the instant the news went live:</p>
<p><img alt="fgf_chart.png" loading="lazy" src="/communicating-with-players/images/fgf_chart.png"></p>
<p>As you can see, Flower Garden Free made it all the way to the <a href="http://www.topappcharts.com/327466677/app-details-flower-garden-free-grow-flowers-and-send-bouquets.php">number 56 in the iPhone Top Apps chart</a> in the US! The effect even <a href="http://www.topappcharts.com/311265471/app-details-flower-garden-grow-flowers-and-send-bouquets.php">spread to the paid version of Flower Garden</a>:</p>
<p><img alt="fg_charts.png" loading="lazy" src="/communicating-with-players/images/fg_charts.png"></p>
<p>Pocket Frogs at the time was hovering at around #9 on the charts, so it was difficult to have much of an impact on that position without major numbers, but we suspect it might have hovered there a little longer because of the extra downloads from Flower Garden.</p>
<p>Here is what the downloads for Flower Garden Free looked like for the last month. The Pocket Frogs cross-promotion is quite noticeable:</p>
<p><img alt="fg_downloads.png" loading="lazy" src="/communicating-with-players/images/fg_downloads.png"></p>
<p>All those downloads also translated into in-app sales through the Flower Shop. Here are the revenues for that time period:</p>
<p><img alt="fg_revenue.png" loading="lazy" src="/communicating-with-players/images/fg_revenue.png"></p>
<p>One consequence I wasn&rsquo;t expecting, but in retrospect I&rsquo;m not that surprised about, is that the ratings for Flower Garden Free dropped by a whole star (from 4 to 3), with a large percentage of 1-star reviews. That&rsquo;s because a lot of people who wouldn&rsquo;t have downloaded Flower Garden otherwise did it anyway, didn&rsquo;t like it, and deleted it right away.</p>
<p>To wrap things up on a better note, there was yet another side effect of the cross promotion. The Pocket Frogs link was using my LinkShare referral code. Sending all those users to the App Store to download a free game link resulted in about $200 in referral profit for the week.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Communicating with your players is more than just profitable: It&rsquo;s crucial to the sustained success of your games. Make sure you try to engage with them in every way you can, keep them up to date with developments in your game, and don&rsquo;t hesitate to run the occasional cross-promotion, especially with other games that are a good match for your target audience.</p>
<p>[1] If you <a href="http://ymlp.com/psignup_promo">decide to use them</a> and wouldn&rsquo;t mind using my referral code (WQHVUF), I can get a small percentage back.</p>
<p><em>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>.</em></p>
]]></content:encoded></item><item><title>Lag: The Bane Of Touch Screens</title><link>https://gamesfromwithin.com/lag-the-bane-of-touch-screens/</link><pubDate>Thu, 16 Sep 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/lag-the-bane-of-touch-screens/</guid><description>&lt;p&gt;Lag in games is as inevitable as taxes. It&amp;rsquo;s something we can try to minimize, but we always need to live with it. Earlier this week, I noticed that input for my new iPad game was very laggy. Excessively so, to the point it was really detracting from the game, so I decided I had to look into it a bit more.&lt;/p&gt;
&lt;h3 id="lag-in-games"&gt;Lag In Games&lt;/h3&gt;
&lt;p&gt;&lt;img alt="got_lag.png" loading="lazy" src="https://gamesfromwithin.com/lag-the-bane-of-touch-screens/images/got_lag.png"&gt;I&amp;rsquo;m defining lag as the time elapsed between the moment the player performs an input action (press a button, touch the screen, move his finger), until the game provides some feedback for that input (movement, flash behind a button, sound effect).&lt;/p&gt;</description><content:encoded><![CDATA[<p>Lag in games is as inevitable as taxes. It&rsquo;s something we can try to minimize, but we always need to live with it. Earlier this week, I noticed that input for my new iPad game was very laggy. Excessively so, to the point it was really detracting from the game, so I decided I had to look into it a bit more.</p>
<h3 id="lag-in-games">Lag In Games</h3>
<p><img alt="got_lag.png" loading="lazy" src="/lag-the-bane-of-touch-screens/images/got_lag.png">I&rsquo;m defining lag as the time elapsed between the moment the player performs an input action (press a button, touch the screen, move his finger), until the game provides some feedback for that input (movement, flash behind a button, sound effect).</p>
<p>Mick West wrote <a href="http://cowboyprogramming.com/2008/05/27/programming-responsiveness/">a great article on the causes of lag in games</a>, followed up by <a href="http://cowboyprogramming.com/2008/05/30/measuring-responsiveness-in-video-games/">another one in how to measure it</a>. I&rsquo;m going to apply some of that to the lag I was experiencing in my game.</p>
<p>Lag can be introduced in games by many different factors:</p>
<ul>
<li>Delay between gathering input and delivering it to the game.
Delay updating the simulation to reflect new inputs.- Delay rendering simulation state.</li>
<li>Delay displaying the latest rendered state on screen.</li>
</ul>
<p>The new game runs on the iPad and involves moving objects around the screen with your finger. To make sure it wasn&rsquo;t anything weird with the rest of the game code, I wrote <a href="/wp-content/uploads/2010/09/LagTest.zip">a quick (and ugly!) program</a> that draws a square with OpenGL that follows your finger on the screen. When you run the sample, the same lag becomes immediately obvious.</p>
<p>The iPad is a much larger device than the iPhone, and it encourages a physical metaphor even more. As soon as you attempt to move an &ldquo;object&rdquo; on screen, the lag kills that sense of physicality. Instead of moving an object around with your finger, you&rsquo;re dragging it around with a rubber band. It moved the player from applying direct action on screen, to being removed and disassociated with the actions on screen.</p>
<h3 id="loop-structure">Loop Structure</h3>
<p>The place to start looking for lag is in my main loop. The main loop looks something like this:</p>
<pre tabindex="0"><code>	ProcessInput();
	UpdateSimulation();
	RenderWorld();
	PresentRenderBuffer();
</code></pre><p>So I was reading the input correctly before the simulation. Nothing weird there.</p>
<p>Touch input is delivered to the code as events from the OS. Whenever I received those events (outside of the main loop), I queue them, and then process them all whenever the main loop starts in ProcessInput().</p>
<p>The loop runs at 60Hz, so the lag here is at most 16.7 ms (if you&rsquo;re running at 30Hz, then you&rsquo;re looking at a delay up to 33.3ms). Unfortunately, the lag I was seeing in the game was way more than one frame, so there was to be something else.</p>
<h3 id="rendering">Rendering</h3>
<p>For some reason, I thought that iDevices were triple buffered. I ran some tests and fortunately it looks like it&rsquo;s regular double buffering. That means that if I render a frame and call presentRenderBuffer(), the results of that render will be visible on screen at the next vertical sync interval. I&rsquo;m sure there&rsquo;s a slight lag with the iPad screen, but I&rsquo;m willing to be is close to negligible when we&rsquo;re talking about milliseconds, so we&rsquo;ll call that zero.</p>
<h3 id="main-loop-calls">Main Loop Calls</h3>
<p>The game uses CADisplayLink with interval of 1, so the main loop is called once every 16.7 ms (give or take a fraction of ms). I thought that perhaps CADisplayLink wasn&rsquo;t playing well with touch events, so I tried switching to NSTimer, and even to <a href="/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/">my old thread-driven main loop</a>, but none of it seemed to make any difference. Lag was alive and well as always.</p>
<p>That the simulation and rendering in the game are very fast, probably just a few ms. That means the rest of the system has plenty of time to process events. If I had a full main loop, maybe one of the two other approaches would have made a difference.</p>
<p>It looks like the lag source had to be further upstream.</p>
<h3 id="input-processing">Input Processing</h3>
<p>On the dashboard, press and hold on an icon, now move it around the screen. That&rsquo;s the same kind of lag we have in the sample program! That&rsquo;s not encouraging.</p>
<p>A touch screen works as a big matrix of touch sensors. The Apple OS processes that input grid and tries to make sense out of it by figuring out where the touches are. The iOS functions eventually process that grid, and send our programs the familiar touchesBegan, touchesMoved, etc events. That&rsquo;s not easy task by any means. It&rsquo;s certainly not like processing mouse input, which is discrete and very clearly defined. For example, you can put your whole palm down on the screen. Where are the touches exactly?</p>
<p>TouchesBegan is actually a reasonably easy one. That&rsquo;s why you see very little lag associated with that one. Sensors go from having no touch values, to going over a certain threshold. I&rsquo;m sure that as soon as one or two of them cross that threshold, the OS identifies that as a touch and sends up the began event.</p>
<p>TouchesMoved is a lot more problematic. What constitutes a touch moving? You need to detect the area in the sensor grid that is activated, and you need to detect a pattern of movement and find out a new center for it. In order to do that, you&rsquo;ll need several samples and a fair amount of CPU cycles to perform some kind of signal processing on the inputs. That extra CPU usage is probably the reason why some games get choppier as soon as you touch the screen.</p>
<h3 id="measuring-lag">Measuring Lag</h3>
<p>Measuring lag in a game is tricky. You usually can&rsquo;t measure it from within the code, so you need to resort to external means like <a href="http://cowboyprogramming.com/2008/05/30/measuring-responsiveness-in-video-games/">Mick did in his tests</a>.</p>
<p>I decided to do something similar. I pulled out my digital video camera, and started recording my finger moving on the screen. The quality leaves much to be desired, but it&rsquo;s good enough for the job. I can see how far my finger gets from the center of the square, but that&rsquo;s not enough information to quantify the lag. How fast is my finger moving exactly? Fortunately, that&rsquo;s something I can answer in code, so I added that information to the screen <a href="#1">[1]</a>. Now, for a given frame, I can see both how far the finger is from the center of the square and how fast it&rsquo;s going.</p>
<p><img alt="lag_test.jpg" loading="lazy" src="/lag-the-bane-of-touch-screens/images/lag_test.jpg"></p>
<p>The square is 100 pixels wide. When I move my finger at about 500 pixels per second, the center of my finger is on the edge of the square. That makes a rough 100 ms total delay from input until it&rsquo;s rendered. That&rsquo;s a whopping 6 full frames at 60 fps!</p>
<h3 id="what-can-we-do-about-it">What Can We Do About It</h3>
<p>As iOS developers, there isn&rsquo;t much we can do. Make sure your loops are set up correctly to avoid an extra frame delay. Make sure you provide feedback as soon as you can and don&rsquo;t delay it any longer than you have to. Other than that, there&rsquo;s nothing much we can do.</p>
<p>I&rsquo;ve been saying this for a while, but I&rsquo;m a big fan of layers as long as you can get to the underlying layers when you need to. Here&rsquo;s a perfect case where it would be fantastic if Apple gave us raw access to the touch matrix input. Apart from being able to process the input faster (because I know what kind of input to expect for the game), can you imagine the possibilities that would open up? Input wouldn&rsquo;t be limited to touch events, and we could even sense how &ldquo;hard&rdquo; the user is pushing, or the shape of the push.</p>
<p>At the very least, it would be very useful if we had the option to allocate extra CPU cycles to input recognition. I&rsquo;m not doing much in my game while this is going on, so I&rsquo;d happily give the input recognition code 95% of the frame time if it means it can give me those events in half the time.</p>
<p>I&rsquo;m hoping that in a not very far distant, iDevices come with multiple cores, and maybe one of those cores is dedicated to the OS and to do input recognition without affecting the game. Or maybe, since that&rsquo;s such a specialized, data-intensive task, some custom hardware could do the job much faster.</p>
<p>Until then, we&rsquo;ll just have to deal with massive input lag.</p>
<p><strong>How about you? Do you have some technique that can reduce the touch event lag?</strong></p>
<p><a href="/wp-content/uploads/2010/09/LagTest.zip">LagTest source code</a>. Released under the MIT License, yadda, yadda, yadda&hellip;</p>
<p>[1] I actually shrank the OpenGL view to make sure the label wasn&rsquo;t on top if it because I was getting choppier input than usual. Even moving it there caused some choppiness. This is exactly what I saw last year with OpenGL performance dropping when a label is updated every frame!</p>
<p><em>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>.</em></p>
]]></content:encoded></item><item><title>Customizable Color Sections With OpenGL ES 1.1</title><link>https://gamesfromwithin.com/customizable-color-sections-with-opengl-es-1-1/</link><pubDate>Thu, 19 Aug 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/customizable-color-sections-with-opengl-es-1-1/</guid><description>&lt;p&gt;One of the items in my ever-growing list of things to write about, is the rendering techniques I used in Flower Garden. In the end, it would make for a post with lots of pretty pictures, but there&amp;rsquo;s nothing particularly ground-breaking. After all, it&amp;rsquo;s all limited to OpenGL ES 1.1 on the iPhone, which means only two texture units and a two-stage texture combiner. As a result, more interesting ideas keep bubbling up to the top of the list and the poor rendering idea keeps getting passed over.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the items in my ever-growing list of things to write about, is the rendering techniques I used in Flower Garden. In the end, it would make for a post with lots of pretty pictures, but there&rsquo;s nothing particularly ground-breaking. After all, it&rsquo;s all limited to OpenGL ES 1.1 on the iPhone, which means only two texture units and a two-stage texture combiner. As a result, more interesting ideas keep bubbling up to the top of the list and the poor rendering idea keeps getting passed over.</p>
<p>Every so often, something happens that bumps up the priority of one of the items in my list. Maybe it&rsquo;s another related blog post, or a game coming out with something relevant to what I wanted to write about. In this case it was <a href="http://twitter.com/madgarden/status/20999821267">a tweet from Paul Pridham</a> <a href="#1">[1]</a>:</p>
<p><a href="http://twitter.com/madgarden/status/20999821267"><img alt="tweet.png" loading="lazy" src="/customizable-color-sections-with-opengl-es-1-1/images/tweet.png"></a></p>
<p>Customizing colors in a sprite or texture is very frequent in games, from changing player characters into blue and red teams, to creating color variations of an armor piece, to letting the player pick the exact shade for their pet&rsquo;s fur color. Or, in the case of Flower Garden, to change the colors of the petals on the fly.</p>
<p>There are two requirements for this:</p>
<ul>
<li>We want to change colors dynamically.</li>
<li>We only want to affect certain areas of the original texture.</li>
</ul>
<p>That rules out creating texture variations ahead of time, although that might be a valid approach sometimes if you have lots of art resources, don&rsquo;t mind increasing the download size, and you have a fixed number of variation to deal with. It also rules out modulating/blending the texture by a particular color because it would tint all the texture, and we want to limit the effect to particular areas (leave the player&rsquo;s arms their normal color, but change their shirt color).</p>
<p>This is one of those funny cases that it was a lot easier to do many years ago, when we used palletized color modes. You could set all the custom color areas to a particular palette entry, and then update that entry on the fly. Ah, all the <a href="http://ahefner.livejournal.com/11670.html">awesome tricks</a> palettes opened up the door to! I still miss them to this day.</p>
<p><img alt="color.jpg" loading="lazy" src="/customizable-color-sections-with-opengl-es-1-1/images/color.jpg">In modern hardware it&rsquo;s also really easy to do with a shader, but Paul wanted to use it across any iPhone device, and the majority of them are still stuck on OpenGL ES 1.1, so fixed-function pipeline it is.</p>
<p>The simplest approach would be to just render the model twice: First pass renders the texture, and second pass renders the custom color bits (you can render them with a white texture modulated by the global color to get the right color). The main drawbacks are that you&rsquo;re doubling the number of draw calls, and, with 3D objects, it gets a bit tricker because the second pass needs to use the glDepthFunc(GL_EQUAL) depth comparison function.</p>
<p>The better way to do this is using the <a href="http://www.opengl.org/wiki/Texture_Combiners">texture combiners</a>. Texture combiners allow us to perform a limited number of operations to control the final look of a pixel. We can add two textures, or multiply them, or even do a few <a href="http://www.khronos.org/opengles/sdk/1.1/docs/man/glTexEnv.xml">more complex operations</a>. The true power of the combiners is that they can be chained together, so the output from one feeds into the input of another, allowing us to create much more complex operations.</p>
<p>The iPhone 3G is limited two two texture combiner units <a href="#2">[2]</a>, but even two combiners are good to create a good range of effects.</p>
<p>Let&rsquo;s think about what we want to accomplish. We want to leave some parts of the texture completely alone and display the original pixel value. In some other parts of the texture, we want to replace the pixels there with a custom color. Actually even better, we probably want to multiply those pixels by a custom color. That way we can author the part of the texture that is going to change with grayscale details, and our color adds the tint to it.</p>
<p>Let&rsquo;s express it mathematically. Let&rsquo;s make a function M that is 1 for every pixel we want to color, and 0 for the ones where the original texture is supposed to be displayed. Our desired color is c and the texture it t. In that case, the final pixel color (p) is:</p>
<p>p = M*(c*t) + (1 - M)*t</p>
<p><img alt="texture.jpg" loading="lazy" src="/customizable-color-sections-with-opengl-es-1-1/images/texture.jpg"><img alt="mask.jpg" loading="lazy" src="/customizable-color-sections-with-opengl-es-1-1/images/mask.jpg"></p>
<p>We could express that with two combiners: The first one is a modulate (multiply) operation with c and t, and the second one an interpolation operation between the result of the previous combiner and the original texture, based on the function M.</p>
<p>Obviously M is just a mask texture. We can paint it white where we want to color the texture, and black elsewhere. We could even use the alpha channel of the original texture, but there&rsquo;s one big thing to watch out for: If you have your texture as a png and process it through the default iPhone resource operations, the image will be premultiplied for you (whether you want it or not), so your color information will be set to zero everywhere that the alpha channel is zero. Oops. You&rsquo;ll probably want to use the alpha channel to store transparency anyway, so we&rsquo;ll keep the mask separate. If not, make sure you encode the image yourself (as raw or PVRT formats) so it&rsquo;s not premultiplied ahead of time.</p>
<p>Are we ready transfer that formula to the texture combiners? Not quite. Apparently (and this was just trial and error, I haven&rsquo;t seen it documented), the texture assigned to a combiner can only be the one at that stage. If you look at the second combiner, we would need to have the first texture as one of the parameters, in addition to the mask.</p>
<p>So instead, we can reorganize the function above like this:</p>
<p>p = c*(M*t) + (t - M*t)</p>
<p>What did we gain by that? The color is what&rsquo;s going to change dynamically, but the mask and the texture always stay the same. We could precompute the M*t term by simply multiplying the texture and the mask. We can call that new term A. We can do the same thing with the (t - M*t) term, which just means turning black all the pixels in the texture where mask will go. That one will be B. The easiest way to &ldquo;precompute&rdquo; those values is just doing it in Photoshop and exporting it as a new png.</p>
<p><img alt="A.jpg" loading="lazy" src="/customizable-color-sections-with-opengl-es-1-1/images/A.jpg"><img alt="B.jpg" loading="lazy" src="/customizable-color-sections-with-opengl-es-1-1/images/B.jpg"></p>
<p>Our new formula is now:</p>
<p>p = c*A + B</p>
<p>Nice and simple! Now we can really add that to the texture combiners like this:</p>
<pre tabindex="0"><code>// c
glColor4f(m_customColor.r, m_customColor.g, m_customColor.b, 1);

glActiveTexture(GL_TEXTURE0);
// A = M*t (precomputed)
glBindTexture(GL_TEXTURE_2D, m_maskHandle);
glEnable(GL_TEXTURE_2D);
// c*A
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glActiveTexture(GL_TEXTURE1);
// B = t - M*t (precomputed)
glBindTexture(GL_TEXTURE_2D, m_textureHandle);
glEnable(GL_TEXTURE_2D);

// c*A + B
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
</code></pre><p>One more thing to watch out for: Because we&rsquo;re using two textures, you need to have two sets of texture coordinates. In this case, we want them to be the same, so we can just point them to the same set of data:</p>
<pre tabindex="0"><code>glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &amp;vertices[0].u);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &amp;vertices[0].u);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
</code></pre><p>That&rsquo;s it! You can see the results in the included project and play with the register combiners to achieve different operations.</p>
<p>At this point I was going to describe the texture combiner setup I use in Flower Garden to render the petals, but this post ended up taking longer than I had hoped for (I&rsquo;m trying to shoot for an hour per post, but this has taken me already two hours between the code and the the post itself), so I&rsquo;ll save that for another time.</p>
<ul>
<li><a href="/wp-content/uploads/2010/08/CustomColor.zip" title="CustomColor.zip">Demo source code</a>. Released under the MIT license.</li>
</ul>
<p>[1] Paul developed <a href="http://itunes.apple.com/us/app/sword-of-fargoal/id343242870?mt=8">Sword of Fargoal</a>, by far my favorite iPhone RPG. [2] The 3GS allows up to eight I believe.</p>
<p><em>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>.</em></p>
]]></content:encoded></item><item><title>IAP Bundles: More Than Just Good Deals</title><link>https://gamesfromwithin.com/iap-bundles-more-than-just-good-deals/</link><pubDate>Thu, 29 Jul 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/iap-bundles-more-than-just-good-deals/</guid><description>&lt;p&gt;&lt;img alt="fg_bundles.jpg" loading="lazy" src="https://gamesfromwithin.com/iap-bundles-more-than-just-good-deals/images/fg_bundles.jpg"&gt;In-game point bundles are nothing new. Even before the time of in-app purchases, &lt;a href="http://www.zynga.com/"&gt;Zynga&lt;/a&gt; was famous for releasing &lt;a href="http://itunes.apple.com/us/app/mafia-wars-170-reward-points/id311944014?mt=8"&gt;&amp;ldquo;points&amp;rdquo; apps&lt;/a&gt; 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.&lt;/p&gt;
&lt;p&gt;Fast-forward to now, and as more companies are jumping into the bandwagon of &lt;a href="http://itunes.apple.com/us/app/we-rule/id339274852?mt=8"&gt;games that need &amp;ldquo;points&amp;rdquo; to make progress&lt;/a&gt;, we&amp;rsquo;re still bundles. Again, I chucked that up to legacy reasons and doing what worked with the standalone apps.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="fg_bundles.jpg" loading="lazy" src="/iap-bundles-more-than-just-good-deals/images/fg_bundles.jpg">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">&ldquo;points&rdquo; 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 &ldquo;points&rdquo; to make progress</a>, we&rsquo;re still bundles. Again, I chucked that up to legacy reasons and doing what worked with the standalone apps.</p>
<h3 id="discovering-bundles">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: &ldquo;I think we might be underestimating how much people are willing to pay for in-app purchases&rdquo;. 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 alt="werule.png" loading="lazy" src="/iap-bundles-more-than-just-good-deals/images/werule.png"><img alt="wefarm.png" loading="lazy" src="/iap-bundles-more-than-just-good-deals/images/wefarm.png"><img alt="castlecraft.png" loading="lazy" src="/iap-bundles-more-than-just-good-deals/images/castlecraft.png"><img alt="farmville.png" loading="lazy" src="/iap-bundles-more-than-just-good-deals/images/farmville.png"></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 id="bundles-in-flower-garden">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&rsquo;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 alt="fertilizer_sales.png" loading="lazy" src="/iap-bundles-more-than-just-good-deals/images/fertilizer_sales.png"></p>
<p>But now, let&rsquo;s look at that same period by plotting revenue (again, only Flower Garden Free, the full version is very similar but it wasn&rsquo;t easy to combine the two to display them here):</p>
<p><img alt="fertilizer_revenue.png" loading="lazy" src="/iap-bundles-more-than-just-good-deals/images/fertilizer_revenue.png"></p>
<p>Now the two bundles are a lot closer to the single bottle, especially the larger, $5.99 bundle.</p>
<h3 id="more-than-meets-the-eye">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&rsquo;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&rsquo;t even normalize them by the number of sales, it would have to be by the number of daily users, and unfortunately that&rsquo;s not a statistic that I&rsquo;m tracking.</p>
<p>However, I think we can argue two really good points about why bundles are great.</p>
<h4 id="1-more-choice">1. More choice</h4>
<p>Having different levels of bundles give players more choice on how they want to purchase something. From what I&rsquo;ve read about buyer psychology, people love having choices when buying something (just don&rsquo;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&rsquo;s only one.</p>
<h4 id="2-commitment">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&rsquo;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&rsquo;ll be using bundles in the future. Players get a good deal, and you get committed players. It&rsquo;s a win-win situation.</p>
<p><em>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>.</em></p>
]]></content:encoded></item><item><title>Remote Game Editing</title><link>https://gamesfromwithin.com/remote-game-editing/</link><pubDate>Thu, 22 Jul 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/remote-game-editing/</guid><description>&lt;p&gt;I&amp;rsquo;ve long been a fan of minimal game runtimes. Anything that can be done offline or in a separate tool, should be out of the runtime. That leaves the game architecture and code very lean and &lt;a href="https://gamesfromwithin.com/simple-is-beautiful/"&gt;simple&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of the things you potentially give up by keeping the game runtime to a minimum is an &lt;a href="http://www.unrealtechnology.com/features.php?ref=editor"&gt;editor built in the game itself&lt;/a&gt;. But that&amp;rsquo;s one of those things that sounds a lot better than it really is. From a technical point of view, having an editor in the game usually complicates the code a huge amount. All of a sudden you need to deal with objects being created and destroyed randomly (instead of through clearly defined events in the game), and you have to deal with all sorts of crazy inputs and configurations.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve long been a fan of minimal game runtimes. Anything that can be done offline or in a separate tool, should be out of the runtime. That leaves the game architecture and code very lean and <a href="/simple-is-beautiful/">simple</a>.</p>
<p>One of the things you potentially give up by keeping the game runtime to a minimum is an <a href="http://www.unrealtechnology.com/features.php?ref=editor">editor built in the game itself</a>. But that&rsquo;s one of those things that sounds a lot better than it really is. From a technical point of view, having an editor in the game usually complicates the code a huge amount. All of a sudden you need to deal with objects being created and destroyed randomly (instead of through clearly defined events in the game), and you have to deal with all sorts of crazy inputs and configurations.</p>
<p>The worse part though, is having to implement some sort of GUI editing system in every platform. Creating the GUI to run on top of the game is not easy, requiring that you create custom GUI code or try to use some of the OpenGL/DirectX libraries available. And even then, a complex in-game GUI might not be a big deal on a PC, but wait and try to use that interface on a PS3 or iPhone. After all, making games is already complicated and time-consuming enough to waste more time reinventing the widget wheel.</p>
<p>Remote game editing manages to keep a minimal runtime and allow you to quickly create native GUIs that run on a PC. It&rsquo;s the best of both worlds, and although it&rsquo;s not quite a perfect solution, it&rsquo;s the best approach I know.</p>
<h3 id="debug-server">Debug Server</h3>
<p><a href="http://twitter.com/mysterycoconut">Miguel Ãngel Friginal</a> <a href="http://mysterycoconut.com/blog/2010/07/tweak-away/">already covered the basics of the debug server</a>, so I&rsquo;m not going to get in details there.</p>
<p>The idea is that you run a very simple socket server on the game, listening in a particular port. This server implements the basic <a href="http://www.faqs.org/rfcs/rfc854.html">telnet protocol</a>, which pretty much means that it&rsquo;s a line-based, plain-text communication.</p>
<p>The main difference between my debug server and Miguel&rsquo;s (other than mine is written in cross-platform C/C++ instead of ObjC), is that I&rsquo;m not using Lua to execute commands. Using Lua for that purpose is a pretty great idea, but goes against the philosophy of keeping the runtime as lean and mean as possible.</p>
<p>Instead, I register variables with the server by hand. For each variable, I specify its memory address, it&rsquo;s type, any restrictions (such as minimum and maximum values), and a &ldquo;pretty name&rdquo; to display in the client. Sounds like a lot of work, but it&rsquo;s just one line with the help of a template:</p>
<pre tabindex="0"><code>registry.Add(Tweak(&amp;plantOptions.renderGloss, &#34;render/gloss&#34;, &#34;Render gloss&#34;));
registry.Add(Tweak(&amp;BouquetParams::FovY, &#34;bouquet/fov&#34;, &#34;FOV&#34;, Pi/32, Pi/3))
</code></pre><p>And yes, if I were to implement this today, I would probably get rid of the templates and make it all explicit instead (ah, the follies of youth :-)</p>
<pre tabindex="0"><code>TweakUtils::AddBool(registry, &amp;plantOptions.renderGloss, &#34;render/gloss&#34;, &#34;Render gloss&#34;);
TweakUtils::AddFloat(registry, &amp;BouquetParams::FovY, &#34;bouquet/fov&#34;, &#34;FOV&#34;, Pi/32, Pi/3);
</code></pre><p>The debug server itself responds to three simple commands:</p>
<ul>
<li><strong>list</strong>. Lists all the variables registered in the server.</li>
<li><strong>set varname value</strong>. Sets a value.</li>
<li><strong>print varname</strong>. Gets the value for that variable.</li>
</ul>
<p>For example, whenever the server receives a set command, it parses the value, verifies that it&rsquo;s within the acceptable range, and applies it to the variable at the given memory location.</p>
<h3 id="telnet-clients">Telnet Clients</h3>
<p><img alt="telnet.png" loading="lazy" src="/remote-game-editing/images/telnet.png">Because we used the standard telnet protocol, we can start playing with it right away. Launch the game, telnet into the right port, and you can start typing away.</p>
<p>However, most telnet clients leave much to be desired for this. They all rely on the history and cursor manipulation being handled by the shell they assume you&rsquo;re connected to. Here we aren&rsquo;t connected to much of anything, but I&rsquo;d like to be able to push up arrow and get my last command, and be able to move to the beginning of the line or the previous word like I would do in any text editor. The easiest solution I found for that was to use a telnet client prepared for that kind of thing: A MUD client! Just about any will do, but one that works well for me is <a href="http://www.riverdark.net/atlantis/">Atlantis</a>.</p>
<p>So far, we&rsquo;ve implemented the equivalent of a FPS console, but working remotely. And because the code is fully portable, our game can be in just about any platform and we can always access it from our PC. Not just that, but we can even open multiple simultaneous connections to various development devices if you need to run them all at once.</p>
<h3 id="custom-clients">Custom Clients</h3>
<p>Game parameter tweaking is something that is OK through a text-based console, but really comes into its own when you add a GUI. That&rsquo;s exactly what we did at <a href="/tag/power-of-two/">Power of Two Games</a>. We created a generic GUI tool (based on WinForms since we were on Windows at the time), that would connect to the server, ask for a list of variables, and generate a GUI on the fly to represent those variables. Since we knew type and name of each variable, it was really easy to construct the GUI elements on the fly: A slider with a text field for floats and ints, a checkbox for bools, four text fields for vectors, and even a color picker for variables of the type color.</p>
<p>It worked beautifully, and adjusting different values by moving sliders around was fantastic. We quickly ran into two problems through.</p>
<p>The first one is that we added so many different tweaks to the game, that it quickly became unmanageable to find each one we wanted to tweak. So, in the spirit of keeping things as simple as possible (and pushing the complexity onto the client), we decided that the / symbol in a name would separate group name and variable name. That way we could group all related variables together and make everything usable again.</p>
<p>The second problem was realizing that some variables were changing on the runtime without us knowing it on the client. That created weird situations when moving sliders around. We decided that any time a registed variable changes on the server, it should notify any connected clients. That worked fine, but, as you can imagine, it became prohibitively expensive very quickly. To get around that, we added a fourth command: <strong>monitor varname</strong>. This way clients need to explicitly register themselves to receive notifications whenever a variable changes, and the GUI client only did it for the variables currently displayed on the screen.</p>
<p><img alt="tweaker.png" loading="lazy" src="/remote-game-editing/images/tweaker.png"></p>
<p>During this process, it was extremely useful to be able to display a log console to see what kind of traffic there was going back and forth. It helped me track down a few instances of bugs where changing a variable in the client would update it in the server, sending an update back to the client, which would send it again back to the server, getting stuck in an infinite loop.</p>
<p>You don&rsquo;t need to stop at a totally generic tool like this either. You could create a more custom tool, like a level editor, that still communicates with the runtime through this channel.</p>
<h3 id="flower-garden-example">Flower Garden Example</h3>
<p>For Flower Garden, I knew I was going to need a lot of knobs to tweak all those plant DNA parameters, so I initially looked into more traditional GUI libraries that worked on OpenGL. The sad truth is that they all fell way short, even for development purposes. So I decided to grab what I had at hand: My trusty tweaking system from Power of Two Games.</p>
<p>I&rsquo;m glad I did. It saved a lot of time and scaled pretty well to deal with the hundreds of parameters in an individual flower, as well as the miscellaneous tweaks for the game itself (rendering settings, infinite fertilizer, fast-forwarding time, etc).</p>
<p>Unfortunately, there was one very annoying thing: The tweaker GUI was written in .Net. Sure, it would take me a couple of days to re-write it in Cocoa (faster if I actually knew any Cocoa), but as an indie, I never feel I can take two days to do something tangential like that. So instead, I just launched it from VMWare Fusion running Windows XP and&hellip; it worked. Amazingly enough, I&rsquo;m able to connect from the tweaker running in VMWare Fusion to the iPhone running in the simulator. Kind of mind boggling when you stop and think about it. It also connects directly to the iPhone hardware without a problem.</p>
<p>VMWare Fusion uses up a lot of memory, so I briefly looked into running the tweaker client in Mono. Unfortunately Mono for the Mac didn&rsquo;t seem mature enough to handle it, and not only was the rendering of the GUI not refreshing correctly, but events were triggered in a slightly different order than in Windows, causing even more chaos with the variable updates.</p>
<p>Here&rsquo;s a time-lapse video of the creation of a Flower Garden seed from the tweaker:</p>
<h3 id="drawbacks">Drawbacks</h3>
<p>As I mentioned earlier, I love this system and it&rsquo;s better than anything else I&rsquo;ve tried, but it&rsquo;s not without its share of problems.</p>
<p>Tweaking data is great, but once you find that set of values that balances the level to perfection&hellip; then what? You write those numbers down and enter them in code or in the level data file? That gets old fast. Ideally you want a way to automatically write those values back. That&rsquo;s easy if the tool itself is the editor, but if it&rsquo;s just a generic tweaker, it&rsquo;s a bit more difficult.</p>
<p>One thing that helped was adding a Save/Load feature to the tweaker GUI. It would simply write out a large text-based file with all the variables and their current values. Whenever you load one of those, it would attempt to apply those same values to the current registered variables. In the end, I ended up making the Flower Garden offline seed file format match with what the tweaker saved out, so that process went pretty smoothly.</p>
<p>Another problem is if you want lots of real-time (or close to real time) updates from the server. For example, you might want to monitor a bunch of data points and plot them on the client (fps, memory usage, number of collisions per frame, etc). Since those values change every frame, it can quickly overwhelm the simple text channel. For those cases, I created side binary socket channels that can simply send real-time data without any overhead.</p>
<p>Finally, the last drawback is that this tweaking system makes editing variables very easy, but calling functions is not quite as simple. For the most part, I&rsquo;ve learned to live without function calls, but sometimes you really want to do it. You can extend the server to register function pointers and map those to buttons in the client GUI, but that will only work for functions without any parameters. What if you wanted to call any arbitrary function? At that point you might be better off integrating Lua in your server.</p>
<h3 id="future-directions">Future Directions</h3>
<p>This is a topic I&rsquo;ve been interested in for a long time, but the current implementation of the system I&rsquo;m using was written 3-4 years ago. As you all know by now, <a href="/the-always-evolving-coding-style/">my coding style and programming philosophy changes quite a bit over time</a>. If I were to implement a system like this today, I would do it quite differently.</p>
<p>For all I said about keeping the server lean and minimal, it could be even more minimal. Right now the server is receiving text commands, parsing them, validating them, and interpreting them. Instead, I would push all that work on the client, and all the server would receive would be a memory address, and some data to blast at that location. All of that information would be sent in binary (not text) format over a socket channel, so it would be much more efficient too. The only drawback is that we would lose the ability to connect with a simple telnet client, but it would probably be worth it in the long run.</p>
<p><em>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>.</em></p>
]]></content:encoded></item><item><title>The Power of Free (aka The Numbers Post #3)</title><link>https://gamesfromwithin.com/the-power-of-free/</link><pubDate>Thu, 08 Jul 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-power-of-free/</guid><description>&lt;p&gt;It has been two months since &lt;a href="https://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/"&gt;the last &amp;ldquo;numbers post&amp;rdquo;&lt;/a&gt;. It covered the Valentine&amp;rsquo;s Day promotion, spike in sales, and subsequent settling out at a very nice level. Here&amp;rsquo;s a recap of what things looked like at the beginning of May (revenue was about $1500 per week):&lt;/p&gt;
&lt;p&gt;&lt;img alt="fg_before.png" loading="lazy" src="https://gamesfromwithin.com/the-power-of-free/images/fg_before.png"&gt;&lt;/p&gt;
&lt;h3 id="the-plan"&gt;The Plan&lt;/h3&gt;
&lt;p&gt;Mother&amp;rsquo;s Day happens at the beginning of May (in the US and Canada anyway, I&amp;rsquo;m afraid I was too busy in April and I missed Mother&amp;rsquo;s Day in a lot of European countries). I figured it would be the perfect time to do another push.&lt;/p&gt;</description><content:encoded><![CDATA[<p>It has been two months since <a href="/making-a-living-comfortably-on-the-app-store/">the last &ldquo;numbers post&rdquo;</a>. It covered the Valentine&rsquo;s Day promotion, spike in sales, and subsequent settling out at a very nice level. Here&rsquo;s a recap of what things looked like at the beginning of May (revenue was about $1500 per week):</p>
<p><img alt="fg_before.png" loading="lazy" src="/the-power-of-free/images/fg_before.png"></p>
<h3 id="the-plan">The Plan</h3>
<p>Mother&rsquo;s Day happens at the beginning of May (in the US and Canada anyway, I&rsquo;m afraid I was too busy in April and I missed Mother&rsquo;s Day in a lot of European countries). I figured it would be the perfect time to do another push.</p>
<p>If there&rsquo;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&rsquo;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="/">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="/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&rsquo;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&rsquo;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 id="mothers-day">Mother&rsquo;s Day</h3>
<p>On Saturday May 8th, a few minutes past midnight the day before Mother&rsquo;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&rsquo;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&rsquo;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&rsquo;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&rsquo;s Day downloads started going down, but they were still pretty strong the following Sunday. Here&rsquo;s what the download numbers looked like for those 9 days:</p>
<p><img alt="fg_week_downloads.png" loading="lazy" src="/the-power-of-free/images/fg_week_downloads.png"></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><img alt="fg_week_revenue.png" loading="lazy" src="/the-power-of-free/images/fg_week_revenue.png"></p>
<p>Mother&rsquo;s Day went on to become the biggest day in terms of revenue since Flower Garden was launched. Bigger even than Christmas or Valentine&rsquo;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="/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&rsquo;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&rsquo;s also interesting to notice that revenue didn&rsquo;t follow the same drop-off curve as downloads. It wasn&rsquo;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&rsquo;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 id="flipping-the-switch">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="/increase-your-app-ratings-on-the-app-store/">leave positive rating on the App Store</a>. Now it&rsquo;s back up to over 4.5 stars.</p>
<h3 id="aftermath">Aftermath</h3>
<p>Now it&rsquo;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&rsquo;s the revenue since the start of the promotion:</p>
<p><img alt="fg_two_months.png" loading="lazy" src="/the-power-of-free/images/fg_two_months.png"></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><img alt="fg_after2.png" loading="lazy" src="/the-power-of-free/images/fg_after2.png"></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&rsquo;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&rsquo;s a breakdown of where revenue came from in the last month (I&rsquo;m excluding the period where Flower Garden was free to get a more accurate view):</p>
<p><img alt="sales_breakdown.png" loading="lazy" src="/the-power-of-free/images/sales_breakdown.png"></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 id="conclusion">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&rsquo;m trying to decide the pricing scheme for my next game, and even though free plus in-app purchases is very tempting, I&rsquo;m not sure it&rsquo;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><em>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>.</em></p>
]]></content:encoded></item><item><title>Paying Off: The Story Behind Unearthed</title><link>https://gamesfromwithin.com/paying-off-the-story-behind-unearthed/</link><pubDate>Wed, 30 Jun 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/paying-off-the-story-behind-unearthed/</guid><description>&lt;p&gt;&lt;em&gt;Today I have the pleasure to introduce the first-ever guest post in Games From Within, &lt;a href="http://twitter.com/Gyrovation"&gt;Joey Chang&lt;/a&gt;. Like me, Joey worked for many years in the game industry, and finally took the plunge last October to become an &lt;a href="http://www.gyrovation.com/"&gt;independent game developer&lt;/a&gt;. &lt;a href="http://itunes.apple.com/us/app/unearthed/id370826160?mt=8"&gt;Unearthed&lt;/a&gt; is his first iPhone project and it&amp;rsquo;s a very unique free to play, augmented reality (AR) game with an X-Files-like theme.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Joey was kind enough to share the story behind Unearthed, some of the decisions leading up to the final game, and the initial reception and sales numbers. Thanks Joey!&lt;/em&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>Today I have the pleasure to introduce the first-ever guest post in Games From Within, <a href="http://twitter.com/Gyrovation">Joey Chang</a>. Like me, Joey worked for many years in the game industry, and finally took the plunge last October to become an <a href="http://www.gyrovation.com/">independent game developer</a>. <a href="http://itunes.apple.com/us/app/unearthed/id370826160?mt=8">Unearthed</a> is his first iPhone project and it&rsquo;s a very unique free to play, augmented reality (AR) game with an X-Files-like theme.</em></p>
<p><em>Joey was kind enough to share the story behind Unearthed, some of the decisions leading up to the final game, and the initial reception and sales numbers. Thanks Joey!</em></p>
<h3 id="inspiration">Inspiration</h3>
<p>Nine months ago, without warning, a gnome crept into my head. It was an idea inspired from a friend&rsquo;s chance mention of an activity called geocaching, where participants use a GPS to hide and seek containers across the world. Within hours, I had envisioned a global cross between geocaching, the Amazing Race, and online travel agency representatives. The idea didn&rsquo;t look much like the resultant product nine months later, but it formed the most critical ingredient to any venture: the obsession to see it completed.</p>
<p>I spent my evenings for a few short weeks hammering out a design, scoping and cutting features, and beginning a prototype, but it didn&rsquo;t take long for me to admit to the unavoidable truth that such a project would take months working full time or probably 3 to 4 times as many months working nights and weekends. I had to sit and carefully consider the pros and cons of leaving my job to pursue something I desperately wanted to create.</p>
<h3 id="half-hearted-dissent">Half-Hearted Dissent</h3>
<p><img alt="UnearthedPoster.jpg" loading="lazy" src="/paying-off-the-story-behind-unearthed/images/UnearthedPoster.jpg">For two weeks, I debated with my wife and close friends with startup experience. I drafted a list of pros and cons to quitting my job to pursue an iphone project and stared at it for hours. Those of you who have made the leap or considered it may recognize some of the points or have more of your own to add:</p>
<p>Advantages of quitting to work full time on an iphone idea</p>
<ul>
<li>Focus effort, complete project 3-4 times faster</li>
<li>Gain valuable unique experience of running solo</li>
<li>Avoid coding burnout, alienating loved ones, loss of sanity</li>
<li>Resume padding</li>
</ul>
<p>Advantages of keeping day job while working on iphone idea</p>
<ul>
<li>Steady income in a scary economy</li>
<li>Not having to job search in a scary economy</li>
<li>Peace of mind (in a scary economy)</li>
</ul>
<p>You can see where a large portion of the dissenting argument forms its basis. After two weeks of listening to unanimous encouragement (bordering on persistent nagging) to quit my job, two weeks of trying my best to convince myself why I should not quit my job, I did what my gut knew from day one was going to be best for me. I marched to my boss&rsquo;s room and quit my job. Ok, I had maybe two false starts where I turned around and went back to my seat.</p>
<h3 id="the-project-unearthed">The Project Unearthed</h3>
<p>Over the next 8 months, scoping and an inclination to appeal to a casual segment evolved the project into a global paranormal investigation titled Unearthed. I tried my best to figure how to maximize the success of the product, and compiled a list of all the ways I could imagine increasing the product&rsquo;s exposure:</p>
<ul>
<li>Banner ads</li>
<li>Spamming blogs and websites to review my product</li>
<li>Spamming friends on facebook</li>
<li>Writing a blog</li>
<li>Viral app features</li>
</ul>
<p>I had trouble justifying the cost to pay for banner ads, and I had too much urgency to implement the product to devote time to a blog, so I focused on occasionally talking about the app on facebook, compiling a list of potential blog candidates for the day the app released, and devising viral features.</p>
<p><img alt="Screen1.jpg" loading="lazy" src="/paying-off-the-story-behind-unearthed/images/Screen13.jpg">Apart from typical facebook posting and email-a-friend features, I decided to employ a &ldquo;refer-an-agent&rdquo; feature which would enable users to invite others to join their network, essentially a grouping of users that correlated with how effectively their app could process scanned creature data. The larger the network, the more credit users would receive for uploading data, and the better they would perform in leaderboards and achievements. The approach was an &ldquo;everybody wins&rdquo; style where anytime any user in the network gained a referral, every single person in the network would benefit from the growth of the network. The hope was that this feature would gain a viral quality.</p>
<p>Friends placed immense pressure to release the product as soon as humanly possible under the theory that doing so would reveal the 70% of my design that was wrong, so I divided Unearthed into three releases. The app itself has three game modes, each incrementally accessible as a given region &ldquo;levels up&rdquo; from users&rsquo; data uploads. I would have time to release the latter modes while the first mode of the game, the most casual mode where users look around where they stand and scan for anomalies, was being played.</p>
<h3 id="in-app-purchases-and-ads">In App Purchases and Ads</h3>
<p><img alt="Screen0.jpg" loading="lazy" src="/paying-off-the-story-behind-unearthed/images/Screen0.jpg">Considering the App Store was flooded with free apps and that I had no name in the industry to immediately convince users to immediately pay for my app, I concluded that the most likely approach for success was to release a free app with In App Purchases. This appeared to be the best way to get as many users to at least try the app and decide how much they wanted to spend to access more functionality. Initially, I offered the following items:</p>
<ul>
<li>All content, present and future ($5.99)</li>
<li>Scanner upgrades level 2-3 ($1.99)</li>
<li>Scanner upgrades level 4-5 ($1.99)</li>
<li>Bounty Mode (coming soon) ($1.99)</li>
<li>Blitz Mode (coming soon) ($1.99)</li>
</ul>
<p>However, I hit a snag with Apple&rsquo;s terms which did not permit me to even mention any features that were not yet implemented. The first item was intended to be a bulk pricing investment in the forthcoming completion of the app, and the &lsquo;coming soon&rsquo; items were just client-side displays to tease of the future modes (not actually registered products in the IAP servers). Because I had to remove them, I revised my IAP content to the following:</p>
<ul>
<li>Scanner upgrades level 2 ($.99)</li>
<li>Scanner upgrades level 3 ($.99)</li>
<li>Scanner upgrades level 4 ($.99)</li>
<li>Scanner upgrades level 5 ($.99)</li>
<li>Scanner upgrades 2-5 ($2.99)</li>
</ul>
<p>The app essentially gives users access to all features of the game, but with a lowly basic scanner that doesn&rsquo;t boast the speed, range, and creature clearance levels of a fully boosted scanner.</p>
<p>I added Greystripe&rsquo;s ad system as a means to offset the cost I might incur from using Google App Engine as my server solution. Considering the large amount of rank tracking required by my app, I estimated the revenue from ads to break even with the cost of using App Engine.</p>
<h3 id="release-and-reception">Release and Reception</h3>
<p>The app was approved in the early afternoon of June 21st, a Monday. Excited, I quickly moved up the release date and it hit the stores later that afternoon. One week later, the sales are dismal, with about 400 total downloads and only a handful of purchases.</p>
<p><img alt="UnearthedWeek1.jpg" loading="lazy" src="/paying-off-the-story-behind-unearthed/images/UnearthedWeek1.jpg"></p>
<p>I considered possible contributors to this could be the following (in order of impact):</p>
<ul>
<li>Requiring 3GS</li>
<li>Releasing 4 days before the iPhone 4 (dropping off New Releases)</li>
<li>Requiring OS 3.1.3 (instead of 3.1)</li>
<li>Releasing the app in the late afternoon (dropping off New Releases faster)</li>
</ul>
<p>Without knowing the specifics on the sales of the 3GS versus the 3G and the iPod Touch, the fraction of 3GS users able to even see my app in the store might be a small fraction. Unnecessarily releasing under an OS that prevented users from installing unless they went back to iTunes to update their OS was likely a dealbreaker for browsing users (quickly remedied but days later). And considering how many of the 1.5 million users would be browsing the App Store for free apps Thursday, releasing a few days too early may have been the biggest avoidable mistake yet.</p>
<h3 id="moving-forward">Moving Forward</h3>
<p>As uninspiring as it was getting only a few hundred downloads and enough revenue for lunch, I had heard that word of mouth was a powerful vehicle, possibly the best vehicle, for an unknown developer, so my plan is to continue giving it more time and implement the GPS-enabled Bounty Mode which will take considerably less time, possibly a short 1-2 months. One week is certainly not a large enough measure of success, and already I&rsquo;ve received a few responses from blogs willing to write reviews, so I&rsquo;m hopeful of seeing the userbase grow and eagerly anticipating the next big server issue. In the coming weeks, there will definitely be no &ldquo;sitting back while the cash rolls in&rdquo;, as I recently had the blessing/curse of another inspiring must-create iPad app revelation and am sweating bullets designing and scoping while scheduling in work on Unearthed, all the while keeping a grave eye on the lifeline of my business.</p>
<p>Looking back at the struggling decision I made to quit my job, I&rsquo;m reminded of some advice that was given to me beforehand. &ldquo;Quitting your job will be the hardest decision, but it will make you feel great.&rdquo; And like an enormous burden lifted from me, it did. And to this day, with earned lunch money in hand, it continues to.</p>
]]></content:encoded></item><item><title>Increase Your App Ratings On The App Store</title><link>https://gamesfromwithin.com/increase-your-app-ratings-on-the-app-store/</link><pubDate>Mon, 14 Jun 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/increase-your-app-ratings-on-the-app-store/</guid><description>&lt;p&gt;Every iPhone developer fears the one-star-on-uninstall rating. I understand Apple&amp;rsquo;s reasoning for adding the prompt for rating on uninstall, but since that&amp;rsquo;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&amp;rsquo;s quite unfair from the developer point of view.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Every iPhone developer fears the one-star-on-uninstall rating. I understand Apple&rsquo;s reasoning for adding the prompt for rating on uninstall, but since that&rsquo;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&rsquo;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&rsquo;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&rsquo;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&amp;story_fbid=130406023644468&amp;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&rsquo;t new</a>, and I&rsquo;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&rsquo;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 alt="fg_prompt.jpg" loading="lazy" src="/increase-your-app-ratings-on-the-app-store/images/fg_prompt.jpg"></p>
<h3 id="dont-be-annoying">Don&rsquo;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&rsquo;t nag.</p>
<p>For quite a few versions, I&rsquo;ve had a review button in the &ldquo;Feedback&rdquo; 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&rsquo;s an example of a feedback prompt that is <strong>too</strong> 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&rsquo;t gotten a single complaint about it being annoyed yet&ndash;keeping my fingers crossed).</p>
<h3 id="disrupt-the-user-as-little-as-possible">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&rsquo;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&rsquo;t like your app probably won&rsquo;t be around in two days, so they&rsquo;ll never see the prompt.</p>
<p>Second, choose a good time to ask. Please, don&rsquo;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&rsquo;t ask me in the middle of a level or when I&rsquo;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 &ldquo;good&rdquo; moment. Maybe only ask them to rate the app if they actually beat the level. They&rsquo;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&rsquo;t send bouquets in Flower Garden). In that case, I will ask at startup or at some other, non-ideal point.</p>
<h3 id="make-rating-the-app-as-easy-as-possible">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&rsquo;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 &ldquo;Rate now&rdquo; 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 id="prompt-at-every-update">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&rsquo;t have to write any custom code at every release. Also, make sure to respect the &ldquo;Don&rsquo;t ask anymore&rdquo; option if the user selected that in a previous update.</p>
<h3 id="source-code">Source code</h3>
<p>Here&rsquo;s the <a href="/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 tabindex="0"><code>	bool ShouldAskForReview();
	bool ShouldAskForReviewAtLaunch();
	void AskForReview();
</code></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 id="results">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><img alt="fg_itunes_ratings.png" loading="lazy" src="/increase-your-app-ratings-on-the-app-store/images/fg_itunes_ratings.png"></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 &ldquo;I love this app!&rdquo; reviews without much more substance. (I&rsquo;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&rsquo;s a very small percentage.</li>
</ul>
<p>Overall, it was a very small time investment and the results show it was definitely worth it. I&rsquo;ll be using this approach in my future projects (unless future iOS versions take care of it automatically somehow).</p>
<p>[1] Apple, can we fix that? How about a REST API for leaving ratings and reviews? Pretty please?</p>
]]></content:encoded></item><item><title>Flower Garden Selected As An Apple Staff Favorite Across Europe</title><link>https://gamesfromwithin.com/flower-garden-selected-as-an-apple-staff-favorite-across-europe/</link><pubDate>Fri, 14 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-selected-as-an-apple-staff-favorite-across-europe/</guid><description>&lt;p&gt;&lt;img alt="fg_europe.jpg" loading="lazy" src="https://gamesfromwithin.com/flower-garden-selected-as-an-apple-staff-favorite-across-europe/images/fg_europe.jpg"&gt;Right on the heels of the Mother&amp;rsquo;s Day promotion, &lt;a href="http://bit.ly/fg_gfw"&gt;Flower Garden&lt;/a&gt; just got its &lt;a href="https://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/"&gt;second&lt;/a&gt; ever App Store feature. This time it was selected as a Staff Favorite across most of Europe (UK, Spain, Ireland, Denmark, Finland, Greece, Netherlands, Norway, Portugal, Switzerland, and Sweden!).&lt;/p&gt;
&lt;p&gt;And if you haven&amp;rsquo;t picked up your &lt;strong&gt;free&lt;/strong&gt; copy of Flower Garden, make sure to do it now. It will probably go back to full price after this weekend.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="fg_europe.jpg" loading="lazy" src="/flower-garden-selected-as-an-apple-staff-favorite-across-europe/images/fg_europe.jpg">Right on the heels of the Mother&rsquo;s Day promotion, <a href="http://bit.ly/fg_gfw">Flower Garden</a> just got its <a href="/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/">second</a> ever App Store feature. This time it was selected as a Staff Favorite across most of Europe (UK, Spain, Ireland, Denmark, Finland, Greece, Netherlands, Norway, Portugal, Switzerland, and Sweden!).</p>
<p>And if you haven&rsquo;t picked up your <strong>free</strong> copy of Flower Garden, make sure to do it now. It will probably go back to full price after this weekend.</p>
<p>Gracias! Obrigado! Grazie! Î£Î±Ï‚ ÎµÏ…Ï‡Î±ÏÎ¹ÏƒÏ„ÏŽ! Tak!</p>
]]></content:encoded></item><item><title>Making A Living (Comfortably) On The App Store (aka The Numbers Post #2)</title><link>https://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/</link><pubDate>Fri, 14 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/</guid><description>&lt;p&gt;A few months ago, I wrote &lt;a href="https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/"&gt;a post analyzing how Flower Garden had done since it was released&lt;/a&gt;. 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.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A few months ago, I wrote <a href="/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 id="recap-and-overview">Recap and Overview</h2>
<p>Here&rsquo;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><img alt="Full" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/Full.png" title="Flower Garden profit"></p>
<p>And here is how things look now. This plot includes the previous data so it&rsquo;s easier to contrast before and after. The area in blue is the new data since the last post.</p>
<p><img alt="fg_total.png" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/fg_total.png"></p>
<p>Just glancing at that chart makes it clear that that the increase around Christmas wasn&rsquo;t a fluke. It actually wasn&rsquo;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&rsquo;s look at the new data in more detail.</p>
<p><img alt="fg_recent.png" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/fg_recent.png"></p>
<p>At a glance, there are three, very different sections.</p>
<h2 id="the-feature">The Feature</h2>
<p>The first one starts with a significant increase in sales (A), and is in large part due to <a href="/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&rsquo;s a nice spike, but it&rsquo;s nothing like the x10 spikes other developers have seen with App Store features. That&rsquo;s because the Staff Favorite slot, even though it&rsquo;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&rsquo;m in the minority, so the effect on sales is greatly reduced.</p>
<p>That spike is also in part due to <a href="/making-a-living-barely-on-the-iphone-app-store/">my last &ldquo;numbers post&rdquo;</a>, which happened right at the same time (not completely accidentally). The page attracted about 15,000 views in a few days, so I&rsquo;m sure a few of them translated in people checking out Flower Garden out of curiosity.</p>
<h2 id="valentines-day">Valentine&rsquo;s Day</h2>
<p>The second spike isn&rsquo;t hard to guess: It&rsquo;s the weekend of February 14th, Valentine&rsquo;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="/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&rsquo;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&amp;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&rsquo;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&rsquo;s Day had higher profit than the initial release spike back in April of last year!</p>
<h2 id="winding-down">Winding Down</h2>
<p>Of course, everything that goes up, must eventually come down. So the weeks following Valentine&rsquo;s Day profits went rapidly down. It was at the very end of April that I started working on <a href="/dr-seuss-lorax-garden-up-the-charts/">Lorax Garden</a>, so for that period of time I wasn&rsquo;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 id="flower-garden-free">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><img alt="fg_free.png" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/fg_free.png"></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&rsquo;s Day (caused by word of mouth, lots of sent bouquets, and the <a href="http://bit.ly/iPhoneValentine">Valentine&rsquo;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&rsquo;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><img alt="iap_profit.png" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/iap_profit.png"></p>
<h2 id="the-future">The Future</h2>
<p>The data for this post stops at May 5th. That&rsquo;s because on May 6th I released a new set of seeds and <a href="/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/">gave Flower Garden away for free as part of the Mother&rsquo;s Day promotion</a>. As soon as the dust settles from that, I&rsquo;ll write a third post detailing how it turned out.</p>
]]></content:encoded></item><item><title>Going The iPad Way: All You Wanted to Know About Creating Universal Apps</title><link>https://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/</link><pubDate>Mon, 10 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/</guid><description>&lt;p&gt;&lt;img alt="flower_garden_ipad.jpg" loading="lazy" src="https://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/flower_garden_ipad.jpg"&gt; It&amp;rsquo;s one thing to go on record saying &lt;a href="https://gamesfromwithin.com/figuring-out-the-ipad/"&gt;I wouldn&amp;rsquo;t be creating an iPad-specific version of Flower Garden&lt;/a&gt;, 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&amp;rsquo;s &lt;a href="http://bit.ly/fg_gfw"&gt;now available on the App Store&lt;/a&gt;, so go get it and check it out!&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="flower_garden_ipad.jpg" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/flower_garden_ipad.jpg"> It&rsquo;s one thing to go on record saying <a href="/figuring-out-the-ipad/">I wouldn&rsquo;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&rsquo;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&rsquo;t that much documentation on how to go about making a universal iPhone/iPad version. There&rsquo;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&rsquo;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="/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&rsquo;re using just OpenGL or just UIKit, the conversion to a universal app will be significantly faster.</p>
<h2 id="universal-project">Universal Project</h2>
<p>The first thing you need to do is understand what&rsquo;s going on with all the SDK versions. At this time, the latest iPhone OS version is 3.1.3, but you&rsquo;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&rsquo;s a very similar situation to when we were <a href="/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&ndash;that&rsquo;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&rsquo;ll see an entry called &ldquo;Upgrade Current Target For iPad&rdquo;. 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&hellip; 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&rsquo;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="/from-full-to-lite-in-under-an-hour/">free and a paid version</a> for example.</p>
<p>Besides, I&rsquo;m uncomfortable with automated &ldquo;smart&rdquo; tools that do things behind my back without me knowing exactly what&rsquo;s going on, so I upgraded by hand by looking at the diffs of what the upgrade command did. It turns out it&rsquo;s extremely simple.</p>
<ol>
<li>Under the project properties, set your base SDK to 3.2.</li>
<li>Set Architectures to &ldquo;Optimized (arm6, arm7)&rdquo;</li>
<li>Uncheck &ldquo;Build Active Architectures Only&rdquo;
<img alt="proejct_settings_1.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/proejct_settings_1.png">5. In the Deployment section, set it to SDK 3.1.3 (or whatever 3.X you want to target)
<img alt="project_settings_2.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/project_settings_21.png"></li>
</ol>
<p>That&rsquo;s it, really. That&rsquo;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&rsquo;re near the 20MB limit). In the case of Flower Garden, the combined executable is 3.4MB, so that&rsquo;s not a big deal.</p>
<h2 id="ipad-functionality">iPad Functionality</h2>
<p>What about that new xib file that the upgrade process creates? You don&rsquo;t really need it. It&rsquo;s there in case you want to have a different set of xibs for each platform, and it&rsquo;s hooked up to the info file so the app knows to load it at startup.</p>
<p><img alt="ib.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/ib.png">For the universal version of Flower Garden, I wasn&rsquo;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="/opengl-and-uikit-demo/">render target code</a> I&rsquo;m using, takes the view dimensions and creates a frame buffer of the correct size. And it&rsquo;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&rsquo;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&rsquo;s as easy as adding this to your controller:</p>
<pre tabindex="0"><code>- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait ||
            interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
</code></pre><p>And make sure you add the supported orientations to your plist.</p>
<p><img alt="plist.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/plist.png"></p>
<p>Finally, before you submit it to the App Store, you&rsquo;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 72x72 image and you&rsquo;re done.</p>
<h2 id="running-on-the-simulator">Running On The Simulator</h2>
<p>This is one that should be a lot easier than it is. You&rsquo;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&rsquo;s not so obvious.</p>
<p>You can&rsquo;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&rsquo;re really running a different build than you&rsquo;re going to be submitting (3.2) and all 3.2 SDK features you&rsquo;re using are going to result in compile errors.</p>
<p>So after much searching and tweeting, here&rsquo;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
<img alt="sdk_version.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/sdk_version.png">- Launch with debugger (Cmd + Options + Y). Don&rsquo;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&rsquo;re done, you need to switch the project to 3.2 again or you&rsquo;ll get tons of compiler errors. That definitely has to go for SDK 4.0.</p>
<p>Here&rsquo;s an invaluable tip. Maybe it&rsquo;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 1680x1050 can&rsquo;t display the iPad simulator at full 1024x768 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&rsquo;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 id="sdk-32-features">SDK 3.2 Features</h2>
<p>Chances are that even if you do a simple iPad port, you&rsquo;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 &ldquo;hide&rdquo; 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 tabindex="0"><code>Class classPopoverController = NSClassFromString(@&#34;UIPopoverController&#34;);
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];
}
</code></pre><p>Not pretty, uh? It works, but I couldn&rsquo;t imagine doing this all over the place.</p>
<h2 id="gotchas">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&rsquo;s accepted, the application status will change to something like &ldquo;Missing screenshot&rdquo;. If you go back and edit the app information, you&rsquo;ll see there&rsquo;s a new set of screenshots you can submit. You&rsquo;ll need at least one for your application to enter &ldquo;Waiting for Review&rdquo; state. And if you have localized descriptions of your app, you&rsquo;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 &ldquo;sandbox environment&rdquo; message. Also, items that hadn&rsquo;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&rsquo;s quite puzzling. Is it a major bug on Apple&rsquo;s part, or did I miss some obscure &ldquo;enable IAPs in debug mode&rdquo; 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 id="conclusion">Conclusion</h2>
<p>All in all, it was a relatively painless process considering it&rsquo;s different hardware, with a different resolution, and it&rsquo;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&rsquo;m sure it got some exposure from being so high up, which in turn helped the iPhone rankings as well.</p>
<p>I can&rsquo;t imagine that my next game is going to be iPad-only, but I&rsquo;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&rsquo;s good to know that it&rsquo;s fairly easy to create a universal app.</p>
<p><img alt="flower_garden_ipad_charts.jpg" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/flower_garden_ipad_charts.jpg"></p>
<p>[1] Actually, there&rsquo;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>[2] See? That confirms point <a href="#1">[1]</a>.</p>
]]></content:encoded></item><item><title>Flower Garden Is Free This Weekend To Celebrate Mother's Day!</title><link>https://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/</link><pubDate>Sat, 08 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/</guid><description>&lt;p&gt;&lt;img alt="Icon-128x128.png" loading="lazy" src="https://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/images/Icon-128x128.png"&gt;&lt;img alt="flower_shop.jpg" loading="lazy" src="https://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/images/flower_shop.jpg"&gt;Since this Sunday is Mother&amp;rsquo;s Day (in the US at least), I&amp;rsquo;m making &lt;a href="http://freeappcalendar.com/details.php?id=159"&gt;Flower Garden &lt;strong&gt;FREE&lt;/strong&gt; for the weekend&lt;/a&gt;. Yes, that&amp;rsquo;s right, completely free!&lt;/p&gt;
&lt;p&gt;Am I going crazy? Giving away the fruit of my labor for so many months? The App Store will do that to people, but this is a bit more sane. The idea is to encourage many more people to try it out. I&amp;rsquo;m actually hoping some of them will like it so much, they&amp;rsquo;ll buy a few of the in-app purchases from the Flower Shop. And even if they don&amp;rsquo;t, hopefully they&amp;rsquo;ll spread the (good) word about Flower Garden and they might also sign up for the mailing list. And in this business, expanding your user base is a great strategy that can be leveraged for future projects.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Icon-128x128.png" loading="lazy" src="/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/images/Icon-128x128.png"><img alt="flower_shop.jpg" loading="lazy" src="/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/images/flower_shop.jpg">Since this Sunday is Mother&rsquo;s Day (in the US at least), I&rsquo;m making <a href="http://freeappcalendar.com/details.php?id=159">Flower Garden <strong>FREE</strong> for the weekend</a>. Yes, that&rsquo;s right, completely free!</p>
<p>Am I going crazy? Giving away the fruit of my labor for so many months? The App Store will do that to people, but this is a bit more sane. The idea is to encourage many more people to try it out. I&rsquo;m actually hoping some of them will like it so much, they&rsquo;ll buy a few of the in-app purchases from the Flower Shop. And even if they don&rsquo;t, hopefully they&rsquo;ll spread the (good) word about Flower Garden and they might also sign up for the mailing list. And in this business, expanding your user base is a great strategy that can be leveraged for future projects.</p>
<p>The idea of giving away a free app isn&rsquo;t anything new. There are whole sites like <a href="http://freeappcalendar.com">FreeAppCalendar</a> dedicated to doing exactly that, and other developers, like <a href="http://nimblebit.com">NimbleBit</a> have been doing that on and off very successfully to reach a wider audience with their games.</p>
<p>How will it work out? I don&rsquo;t know yet, but Flower Garden is quickly going up the charts even early on Saturday. It&rsquo;s currently in the top 50 free apps in Japan, and about to get in the top 10 kids games in the US, so it&rsquo;s looking good.</p>
<p>If you haven&rsquo;t picked it up yet, this is the time. And if you have, make sure you tell your friends and family to download it and check it out before it goes back to the regular price. I&rsquo;ll report back on the results of this promotion in a few days.</p>
]]></content:encoded></item><item><title>Dr. Seuss Lorax Garden Up The Charts</title><link>https://gamesfromwithin.com/dr-seuss-lorax-garden-up-the-charts/</link><pubDate>Sun, 02 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/dr-seuss-lorax-garden-up-the-charts/</guid><description>&lt;p&gt;&lt;img alt="LoraxGarden.jpg" loading="lazy" src="https://gamesfromwithin.com/dr-seuss-lorax-garden-up-the-charts/images/LoraxGarden.jpg"&gt;If you follow this blog regularly you&amp;rsquo;ve probably noticed that there&amp;rsquo;s been a kind of blackout period. I hardly posted during the last couple of months. What happened? &lt;a href="http://bit.ly/iphoneloraxgarden"&gt;Lorax Garden&lt;/a&gt; is what happened.&lt;/p&gt;
&lt;p&gt;In late February I agreed to collaborate with &lt;a href="http://www.oceanhousemedia.com/products/"&gt;Oceanhouse Media&lt;/a&gt; on a game project. They had the &lt;a href="http://www.oceanhousemedia.com/products/drseuss/"&gt;Dr. Seuss license&lt;/a&gt; and I had &lt;a href="http://www.snappytouch.com/flowergarden/"&gt;the flowers&lt;/a&gt;. Perfect match for a Lorax-themed game! And so the &lt;a href="http://bit.ly/iphoneloraxgarden"&gt;Lorax Garden&lt;/a&gt; was born.&lt;/p&gt;
&lt;p&gt;I was originally hoping to write some entries here on the progress of the game as I worked on it, but I quickly realized that I wouldn&amp;rsquo;t have any spare time for anything other than the project. We wanted to have the Lorax Garden (and &lt;a href="http://bit.ly/iphonelorax"&gt;the Lorax book app&lt;/a&gt;) on the App Store by &lt;a href="http://www.earthday.org/earthday2010"&gt;Earth Day&lt;/a&gt; (April 20th), so that left us with a very aggressive 5-week schedule (and GDC somewhere in the middle!). Fortunately, we managed to hit our deadline, and you can see the results today by yourself by &lt;a href="http://bit.ly/iphoneloraxgarden"&gt;downloading it from the App Store&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="LoraxGarden.jpg" loading="lazy" src="/dr-seuss-lorax-garden-up-the-charts/images/LoraxGarden.jpg">If you follow this blog regularly you&rsquo;ve probably noticed that there&rsquo;s been a kind of blackout period. I hardly posted during the last couple of months. What happened? <a href="http://bit.ly/iphoneloraxgarden">Lorax Garden</a> is what happened.</p>
<p>In late February I agreed to collaborate with <a href="http://www.oceanhousemedia.com/products/">Oceanhouse Media</a> on a game project. They had the <a href="http://www.oceanhousemedia.com/products/drseuss/">Dr. Seuss license</a> and I had <a href="http://www.snappytouch.com/flowergarden/">the flowers</a>. Perfect match for a Lorax-themed game! And so the <a href="http://bit.ly/iphoneloraxgarden">Lorax Garden</a> was born.</p>
<p>I was originally hoping to write some entries here on the progress of the game as I worked on it, but I quickly realized that I wouldn&rsquo;t have any spare time for anything other than the project. We wanted to have the Lorax Garden (and <a href="http://bit.ly/iphonelorax">the Lorax book app</a>) on the App Store by <a href="http://www.earthday.org/earthday2010">Earth Day</a> (April 20th), so that left us with a very aggressive 5-week schedule (and GDC somewhere in the middle!). Fortunately, we managed to hit our deadline, and you can see the results today by yourself by <a href="http://bit.ly/iphoneloraxgarden">downloading it from the App Store</a>.</p>
<p>It was very interesting starting a totally new project from the existing Flower Garden codebase. I had to add some new flower-tech to make flowers more Seussian (curvy, uneven) and make Truffula Trees. Lorax Garden has a definite game structure and progression, so all the game code was completely new. It even has a flower-growing minigame to earn extra care hearts. All that had to be created by ripping out Flower Garden code and writing new one. It was a pleasure to see how easy it was to reuse all the flower-tech code that was well isolated and tested from the beginning though.</p>
<p><img alt="LoraxGardenScreenshot.jpg" loading="lazy" src="/dr-seuss-lorax-garden-up-the-charts/images/LoraxGardenScreenshot.jpg"></p>
<p>The Lorax Garden is currently featured by Apple on the App Store, and <a href="http://bit.ly/iphoneloraxgarden">it&rsquo;s on sale for $0.99</a> (down from the regular price of $2.99). All of that combined with a strong launch and mentions on <a href="http://www.usatoday.com/tech/columnist/jinnygudmundsen/2010-04-29-kid-apps-ipad_N.htm">USA Today</a> and <a href="http://appmodo.com/18108/lorax-garden-app-review-bring-the-trees-back/">other media outlets</a> have brought it up to the #39 (edit: #37!) paid app overall in the US App Store charts. A fantastic result, and with any luck it will continue climbing for another day or two.</p>
<p><img alt="LoraxGardenFeatured.png" loading="lazy" src="/dr-seuss-lorax-garden-up-the-charts/images/LoraxGardenFeatured.png"></p>
]]></content:encoded></item><item><title>OpenGL And UIKit Demo</title><link>https://gamesfromwithin.com/opengl-and-uikit-demo/</link><pubDate>Sat, 10 Apr 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/opengl-and-uikit-demo/</guid><description>&lt;p&gt;&lt;img alt="uikit_demo.png" loading="lazy" src="https://gamesfromwithin.com/opengl-and-uikit-demo/images/uikit_demo.png"&gt;This coming Monday I&amp;rsquo;ll be giving a presentation at &lt;a href="http://360idev.com"&gt;360iDev&lt;/a&gt; titled &amp;ldquo;All You Wanted To Know About Mixing OpenGL with UIKit (And More)&amp;rdquo;. It&amp;rsquo;s an extended version of &lt;a href="https://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/"&gt;my talk&lt;/a&gt; at this year&amp;rsquo;s &lt;a href="http://www.gdconf.com/conference/iphone.html"&gt;GDC iPhone Summit&lt;/a&gt;. It&amp;rsquo;s going to be 1h 20min long instead of just half an hour.&lt;/p&gt;
&lt;p&gt;The main difference is that I&amp;rsquo;m going to go in detail about each of the different cases of mixing OpenGL and UIKit, and what better way to do that than with a live demo. I&amp;rsquo;ll be switching back and forth between Keynote and XCode and going over the details, which is where a lot of the tricky parts are.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="uikit_demo.png" loading="lazy" src="/opengl-and-uikit-demo/images/uikit_demo.png">This coming Monday I&rsquo;ll be giving a presentation at <a href="http://360idev.com">360iDev</a> titled &ldquo;All You Wanted To Know About Mixing OpenGL with UIKit (And More)&rdquo;. It&rsquo;s an extended version of <a href="/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/">my talk</a> at this year&rsquo;s <a href="http://www.gdconf.com/conference/iphone.html">GDC iPhone Summit</a>. It&rsquo;s going to be 1h 20min long instead of just half an hour.</p>
<p>The main difference is that I&rsquo;m going to go in detail about each of the different cases of mixing OpenGL and UIKit, and what better way to do that than with a live demo. I&rsquo;ll be switching back and forth between Keynote and XCode and going over the details, which is where a lot of the tricky parts are.</p>
<p><a href="/wp-content/uploads/2010/04/OpenGLUIKit.zip" title="OpenGLUIKit.zip">Here is the source code for the demo</a>. That way you can look at it now and come to the session prepared with more questions, or ready to discuss what works and what doesn&rsquo;t work for you. I love to have interactive sessions, so definitely come ready to ask questions.</p>
<p>If you&rsquo;re not coming to 360iDev&hellip; shame on you! It&rsquo;s the best iPhone conference around. You&rsquo;ll be missing not just my session, but tons of other great talks, and the <a href="http://iphonegamejam.com">iPhone Game Jam</a> (sponsored by <a href="http://toucharcade.com">TouchArcade</a> this year). If you can&rsquo;t make it this time, make a note on your calendar for next time!</p>
<ul>
<li><a href="/wp-content/uploads/2010/04/OpenGLUIKit.zip" title="OpenGLUIKit.zip">Demo source code</a>. Released under the MIT license.</li>
</ul>
]]></content:encoded></item><item><title>GDC 2010: The Best of Both Worlds: Using UIKit with OpenGL</title><link>https://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/</link><pubDate>Sat, 13 Mar 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/</guid><description>&lt;p&gt;&lt;img alt="borg-701632.jpg" loading="lazy" src="https://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/images/borg-701632.jpg"&gt;Here are the slides for my session at the &lt;a href="http://www.gdconf.com/conference/iphone.html"&gt;GDC iPhone Summit&lt;/a&gt;, &lt;a href="https://www.cmpevents.com/GD10/a.asp?option=C&amp;amp;V=11&amp;amp;SessID=10541"&gt;The Best of Both Worlds: Using UIKit With OpenGL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It was a 30-minute slot, so the material is pretty condensed without the chance to expand on the topics. I&amp;rsquo;m giving an extended version of this talk at &lt;a href="http://www.360idev.com/"&gt;360iDev&lt;/a&gt; in a few weeks, so I&amp;rsquo;ll be able to get into more details then and have a cool sample app that shows off all those concepts.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="borg-701632.jpg" loading="lazy" src="/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/images/borg-701632.jpg">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&amp;V=11&amp;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&rsquo;m giving an extended version of this talk at <a href="http://www.360idev.com/">360iDev</a> in a few weeks, so I&rsquo;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="/wp-content/uploads/2010/03/GDC10_uikit_opengl.pdf">pdf format</a>)</li>
<li><a href="/opengl-and-uikit-demo/">Sample code</a></li>
</ul>
]]></content:encoded></item><item><title>Flower Garden a Finalist for The 2010 Pocket Gamer Awards for Most Innovative Game!</title><link>https://gamesfromwithin.com/flower-garden-a-finalist-for-the-2010-pocket-gamer-awards-for-most-innovative-game/</link><pubDate>Wed, 03 Mar 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-a-finalist-for-the-2010-pocket-gamer-awards-for-most-innovative-game/</guid><description>&lt;p&gt;&lt;a href="http://www.pocketgamer.co.uk/r/Various/Pocket%20Gamer%20Awards/feature.asp?c=17875"&gt;&lt;img alt="10AF654B-A6A5-4C29-BE46-D58B3A09BAEA.jpg" loading="lazy" src="https://gamesfromwithin.com/flower-garden-a-finalist-for-the-2010-pocket-gamer-awards-for-most-innovative-game/images/10AF654B-A6A5-4C29-BE46-D58B3A09BAEA.jpg"&gt;&lt;/a&gt;Pocket Gamer just announced the finalists for the &lt;a href="http://www.pocketgamer.co.uk/r/Various/Pocket%20Gamer%20Awards/feature.asp?c=17875"&gt;2010 Pocket Gamer Awards&lt;/a&gt;. I was thrilled to see that Flower Garden has been selected as a finalist for the Most Innovative iPhone Game award.&lt;/p&gt;
&lt;p&gt;On a personal level, this nomination means quite a bit for me. Flower Garden has gotten &lt;a href="http://fingergaming.com/2009/04/24/review-flower-garden/"&gt;some&lt;/a&gt; &lt;a href="http://theportablegamer.com/2009/04/iphone-review-flower-garden/"&gt;great&lt;/a&gt; &lt;a href="http://www.pocketgamer.co.uk/r/iPhone/Flower+Garden/review.asp?c=12825"&gt;reviews&lt;/a&gt;, and some incredible user feedback, and it was even featured as an &lt;a href="https://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/"&gt;Apple Staff Favorite on the App Store&lt;/a&gt;, but it had never been up for an award of this importance.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="http://www.pocketgamer.co.uk/r/Various/Pocket%20Gamer%20Awards/feature.asp?c=17875"><img alt="10AF654B-A6A5-4C29-BE46-D58B3A09BAEA.jpg" loading="lazy" src="/flower-garden-a-finalist-for-the-2010-pocket-gamer-awards-for-most-innovative-game/images/10AF654B-A6A5-4C29-BE46-D58B3A09BAEA.jpg"></a>Pocket Gamer just announced the finalists for the <a href="http://www.pocketgamer.co.uk/r/Various/Pocket%20Gamer%20Awards/feature.asp?c=17875">2010 Pocket Gamer Awards</a>. I was thrilled to see that Flower Garden has been selected as a finalist for the Most Innovative iPhone Game award.</p>
<p>On a personal level, this nomination means quite a bit for me. Flower Garden has gotten <a href="http://fingergaming.com/2009/04/24/review-flower-garden/">some</a> <a href="http://theportablegamer.com/2009/04/iphone-review-flower-garden/">great</a> <a href="http://www.pocketgamer.co.uk/r/iPhone/Flower+Garden/review.asp?c=12825">reviews</a>, and some incredible user feedback, and it was even featured as an <a href="/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/">Apple Staff Favorite on the App Store</a>, but it had never been up for an award of this importance.</p>
<p>It&rsquo;s also the category that it was nominated for. It makes me really proud that it was nominated for Most Innovative Game, because one of my original goals was to create something unique and original.</p>
<p>Finally, these awards are particularly meaningful because they&rsquo;re not based on popularity, sales, or voting, which are bound to bias awards towards best-selling titles. Instead, these finalists were hand-picked by the editors of Pocket Gamer. With the crazy amount of good apps out there, it really is an honor that they selected Flower Garden as one of the top 5 for 2009.</p>
<p>Thank you, Pocket Gamer!</p>
]]></content:encoded></item><item><title>Figuring Out The iPad</title><link>https://gamesfromwithin.com/figuring-out-the-ipad/</link><pubDate>Thu, 28 Jan 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/figuring-out-the-ipad/</guid><description>&lt;p&gt;Everybody was buzzing with excitement yesterday morning. A flurry of Twitter comments scrolled by all throughout the morning and the afternoon. You could taste the &lt;a href="http://www.apple.com/ipad/"&gt;iPad&lt;/a&gt; in the air (OK, almost).&lt;/p&gt;
&lt;p&gt;Shortly after the &lt;a href="http://events.apple.com.edgesuite.net/1001q3f8hhr/event/index.html"&gt;unveiling&lt;/a&gt;, people divided themselves in to two camps: &lt;a href="http://gizmodo.com/5458382/8-things-that-suck-about-the-ipad"&gt;the iPad haters&lt;/a&gt;, and &lt;a href="http://iphonedevelopment.blogspot.com/2010/01/gizmodo-knows-about-sucking-apparently.html"&gt;the iPad defenders&lt;/a&gt;. Each of them was intent in convincing the other camp that their view is the right one. Just like most of the pointless human conflict over the last two thousand years minus the bloody wars part.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Everybody was buzzing with excitement yesterday morning. A flurry of Twitter comments scrolled by all throughout the morning and the afternoon. You could taste the <a href="http://www.apple.com/ipad/">iPad</a> in the air (OK, almost).</p>
<p>Shortly after the <a href="http://events.apple.com.edgesuite.net/1001q3f8hhr/event/index.html">unveiling</a>, people divided themselves in to two camps: <a href="http://gizmodo.com/5458382/8-things-that-suck-about-the-ipad">the iPad haters</a>, and <a href="http://iphonedevelopment.blogspot.com/2010/01/gizmodo-knows-about-sucking-apparently.html">the iPad defenders</a>. Each of them was intent in convincing the other camp that their view is the right one. Just like most of the pointless human conflict over the last two thousand years minus the bloody wars part.</p>
<p>Of course, I felt the same way. As a consumer, I was very disappointed by the lack of video camera and the non-widescreen form factor. But I stepped back and realized that the iPad is here, and it is what it is. All the wishing and convincing in the world isn&rsquo;t going to make a difference. The platform is here to stay, and with Apple&rsquo;s genius behind it, I&rsquo;m sure it&rsquo;s going to be anywhere from &ldquo;moderately successful&rdquo; to &ldquo;a huge success&rdquo;.</p>
<p>The only question to answer as a developer is, how can I make the most out of the iPad? And for that, we need to understand what the iPad is.</p>
<p><img alt="apple-ipad-5.jpg" loading="lazy" src="/figuring-out-the-ipad/images/apple-ipad-5.jpg"></p>
<p>There&rsquo;s been a lot of talk on the <a href="http://www.apple.com/ipad/specs/">iPad specs</a>: 1024x768 resolution, a custom <a href="http://www.engadget.com/2010/01/28/apples-a4-is-an-arm-based-system-on-a-chip-a-la-tegra-2/">A4 chipset</a> including a CPU and a modern GPU, etc. But those are just dry facts about the hardware. They will be crucial things to keep in mind to develop for the iPad, but they don&rsquo;t help us that much understanding it.</p>
<p>Some people are claiming <a href="http://mactipspodcast.com/ipad1/">the iPad is a large iPod Touch</a>, but I think that nothing could be further from the truth.</p>
<p>Precisely because the iPad is larger, it&rsquo;s not a device you&rsquo;re going to carry in your pocket. It&rsquo;s something that&rsquo;s going to be laying on your desk, or piled on top of a few books on the coffee table. And that changes everything.</p>
<p>Whereas on the iPhone/iPod Touch users could use an app for a few seconds or minutes during the day, the iPad is going to encourage longer sessions, just once or twice a day. The kind of apps, and in particular the kind of games that are going to be well suited to the iPad are going to be much more than a higher-resolution iPhone game. For the most part, they&rsquo;re going to be totally different genres.</p>
<p>For example, <a href="http://itunes.apple.com/us/app/civilization-revolution/id324563544?mt=8">Civilization</a> never made much sense for me on the iPhone, but it now becomes a perfect iPad game. On the other hand, <a href="http://itunes.apple.com/us/app/flower-garden-free-grow-flowers/id327466677?mt=8">Flower Garden</a>, was designed from the beginning to have multiple, short sessions throughout the day, so it will make very little sense as an iPad game. I suppose that makes me one of the first developers going on record saying I&rsquo;m not going to port my existing iPhone app to the iPad :-)</p>
<p>The differences with the iPod Touch go beyond how frequently people use it. For example, games controlled by tilt are going to be restricted to a more hard core audience. Someone who really wants to sit down and spin the iPad around like a driving wheel controlling a car. Casual users will be less likely to grab the iPad and play a quick game of <a href="http://itunes.apple.com/us/app/scoops-ice-cream-fun-for-everyone/id291591378?mt=8">Scoops</a> or <a href="http://itunes.apple.com/us/app/doodle-jump-be-warned-insanely/id307727765?mt=8">Doodle Jump</a> because it&rsquo;s going to feel like a bigger deal than slightly tilting the iPhone in your hand.</p>
<p>The target demographic for the iPad is very different than the iPhone and iPod Touch. It will appeal mostly to people in their 30s and older, whereas the iPod Touch is really spreading on the younger demographic of middle and even elementary school. That will also radically change the kind of apps and games people will play on the iPad.</p>
<p>So it&rsquo;s clear that the iPad is not a large iPod Touch, and it doesn&rsquo;t pretend to replace it. That&rsquo;s a key point. Instead of replacing it, us as developers should think about it as complementing the iPhone and iPod Touch. The kind of experience I expect from the ideal iPad application is one that lets me access the same data set or game state I was using with my iPhone during the day. Maybe I&rsquo;ll put up with the iPhone interface to play some Civilization while I&rsquo;m commuting to work, but I expect to come back home, sit down on the couch, pick up my iPad and continue the same game with a much better interface. So we&rsquo;re going to see a trend towards more apps and games that store all their state in the server, and let you access it from any device.</p>
<p>The older demographic, deeper games, and server integration, combined with a higher-resolution screen is going to make people expect a more polished experience, and development costs are going to increase significantly. It&rsquo;s definitely a new challenge in a market that&rsquo;s ever changing, and whoever figures it out will have a good chance to have an early iPad hit in their hands.</p>
]]></content:encoded></item><item><title>Making A Living (Barely) On The iPhone App Store (aka The Numbers Post)</title><link>https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/</link><pubDate>Fri, 15 Jan 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/</guid><description>&lt;p&gt;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&amp;rsquo;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&amp;rsquo;ve drooled over the numbers &lt;a href="http://firemint.com/blog/?p=123"&gt;chart&lt;/a&gt; &lt;a href="http://games.venturebeat.com/2009/07/10/pocket-god-is-a-case-study-of-a-hit-iphone-game/"&gt;toppers&lt;/a&gt; sold, I&amp;rsquo;ve seen sales reports of very &lt;a href="http://toucharcade.com/wp-content/uploads/2009/09/featured.png"&gt;successful&lt;/a&gt; &lt;a href="http://www.nimblebit.com/2010/01/nimblebit-numbers-2009/"&gt;games&lt;/a&gt;, and we&amp;rsquo;ve also seen what happens when &lt;a href="http://www.streamingcolour.com/blog/2009/03/09/the-numbers-post-aka-brutal-honesty/"&gt;apps&lt;/a&gt; languish at the bottom.&lt;/p&gt;</description><content:encoded><![CDATA[<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&rsquo;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&rsquo;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, I&rsquo;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&rsquo;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&rsquo;ll notice is that Flower Garden is a strange in-between app. It&rsquo;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 relelased 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 id="the-full-monty">The Full Monty</h2>
<p>I know that if I put it off, you&rsquo;re just going to skip to the end to see the sales plot, so let&rsquo;s get that out of the way. Here it is.</p>
<p><img alt="Full" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/Full.png" title="Flower Garden profit"></p>
<p>The vertical axis is daily profit in US $ (after Apple&rsquo;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&rsquo;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&rsquo;m not getting rich, but it&rsquo;s not a bad life, really.</p>
<p>How many hours of work does Flower Garden represent? It&rsquo;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&rsquo;s a depressing $13.44/hour. At least it&rsquo;s over minimum wage! :-) 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&rsquo;s clearly a story behind that graph. It&rsquo;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 id="launch">Launch</h2>
<p>Let&rsquo;s start from the beginning. Release day!</p>
<p><img alt="Beginning2" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/Beginning2.png" title="Flower Garden initial profit"></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="/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&rsquo;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 id="mothers-day">Mother&rsquo;s Day</h2>
<p>I wasn&rsquo;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&rsquo;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&rsquo;s Day. The result? The revenue dip you see in (A).</p>
<p><img alt="Middle_long" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/Middle_long.png" title="Flower Garden profit in the middle"></p>
<p>Mother&rsquo;s day is probably the small, second spike in that period, but overall, that week was a loss. Lesson learned: Don&rsquo;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 id="app-treasures">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&rsquo;re leveraging is some cross-promotion for our games, both through the web site, and from an in-game view liking to each other&rsquo;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 id="facebook-and-lite">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&rsquo;m-there, but really, genuinely liked it. Why weren&rsquo;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&rsquo;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&rsquo;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&rsquo;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 id="second-wind">Second Wind</h2>
<p>You&rsquo;d think that I would give up at this point, wouldn&rsquo;t you? And I don&rsquo;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! :-( 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&hellip; last&hellip; try&hellip;</p>
<p>To be totally honest, I wasn&rsquo;t expecting very much. Even including all the units of the Lite version out there, there just weren&rsquo;t that many units. Especially not that many people using it on a daily basis (I&rsquo;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><img alt="End" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/End.png" title="Flower Garden profit after IAP"></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&rsquo;s Eve (D) (do people send flowers on New Year&rsquo;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&rsquo;s more around $180/day. That&rsquo;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&rsquo;s the breakdown:</p>
<p><img alt="End_broken_down" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/End_broken_down.png" title="Flower Garden IAP profit broken down"></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&rsquo;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&rsquo;s also really interesting is the downloads of Flower Garden Free.</p>
<p><img alt="fg_free" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/fg_free.png" title="Flower Garden Free downloads"></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&rsquo;s no surprise that IAP from Flower Garden Free picked up in these last few weeks.</p>
<h2 id="the-future">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="/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&rsquo;m also already preparing a new update and some more IAP for Valentine&rsquo;s Day, so I&rsquo;m sure there will be more ups and downs in the near future. I&rsquo;d certainly like to continue supporting Flower Garden for as long as it&rsquo;s profitable.</p>
<p>I&rsquo;ll follow up this post in a couple of months with the aftermath of the App Store feature and Valentine&rsquo;s Day. Also, stay tuned for another post with more details of the IAP, what&rsquo;s successful, purchase patterns, and more.</p>
]]></content:encoded></item><item><title>Flower Garden Now An Apple Staff Favorite On The App Store Worldwide!</title><link>https://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/</link><pubDate>Tue, 12 Jan 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/</guid><description>&lt;p&gt;Aparently Santa came to town a little later this year. Or maybe it was the &lt;a href="http://en.wikipedia.org/wiki/Biblical_Magi#Traditions"&gt;Reyes Magos&lt;/a&gt; (also bit late). In either case, I woke up this morning to find a very nice present waiting for me at my &lt;a href="http://twitter.com/MKripalani/status/7660447268"&gt;computer&lt;/a&gt;: Apple featured Flower Garden as an Apple Staff Favorite! Apparently this is in all App Stores worldwide too (I have confirmations for &lt;a href="http://twitter.com/OwenGoss/status/7668421503"&gt;Canada&lt;/a&gt; and &lt;a href="http://www.facebook.com/photo.php?pid=3204730&amp;amp;id=74897183702&amp;amp;comments&amp;amp;ref=mf"&gt;Thailand&lt;/a&gt;, so I imagine it applies to other territories as well).&lt;/p&gt;</description><content:encoded><![CDATA[<p>Aparently Santa came to town a little later this year. Or maybe it was the <a href="http://en.wikipedia.org/wiki/Biblical_Magi#Traditions">Reyes Magos</a> (also bit late). In either case, I woke up this morning to find a very nice present waiting for me at my <a href="http://twitter.com/MKripalani/status/7660447268">computer</a>: Apple featured Flower Garden as an Apple Staff Favorite! Apparently this is in all App Stores worldwide too (I have confirmations for <a href="http://twitter.com/OwenGoss/status/7668421503">Canada</a> and <a href="http://www.facebook.com/photo.php?pid=3204730&amp;id=74897183702&amp;comments&amp;ref=mf">Thailand</a>, so I imagine it applies to other territories as well).</p>
<p><img alt="fg_appstore_feature" loading="lazy" src="/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/images/fg_appstore_feature.jpg" title="fg_appstore_feature"></p>
<p>This is the first time Flower Garden has received any kind of &ldquo;Apple love&rdquo;, so it&rsquo;s particularly exciting, especially considering that Flower Garden was released all the way back in April. I imagine the recent update, which included the Flower Shop with in-app purchases, must have caught someone&rsquo;s eye.</p>
<p>The only downside is that the featuring might throw off the sales data I was collecting to show the effect on sales that in-app purchases and the holiday season had. But I&rsquo;m not really complaining. That&rsquo;s a very nice reason to have the data thrown off :-) Thank you Apple!</p>
]]></content:encoded></item><item><title>All About In-App Purchases Part 4: iTunes Connect</title><link>https://gamesfromwithin.com/in-app-purchases-part-4/</link><pubDate>Tue, 29 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/in-app-purchases-part-4/</guid><description>&lt;p&gt;Weâ€™re used to going through t&lt;a href="https://gamesfromwithin.com/at-the-mercy-of-apples-whim/"&gt;he approval process for binaries&lt;/a&gt;, but in-app purchases are a bit different. Hereâ€™s some of what I learned going through this for &lt;a href="http://www.facebook.com/iphoneflowergarden"&gt;Flower Garden&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="purchase-states"&gt;Purchase States&lt;/h2&gt;
&lt;p&gt;When you first create an in-app purchase in iTunes Connect, it is listed as â€œPending Developer Approvalâ€. This means that if you ask for info on that product id with a SKProductsRequest, youâ€™ll get the info for the item only on development builds, not in distributions builds.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Weâ€™re used to going through t<a href="/at-the-mercy-of-apples-whim/">he approval process for binaries</a>, but in-app purchases are a bit different. Hereâ€™s some of what I learned going through this for <a href="http://www.facebook.com/iphoneflowergarden">Flower Garden</a>.</p>
<h2 id="purchase-states">Purchase States</h2>
<p>When you first create an in-app purchase in iTunes Connect, it is listed as â€œPending Developer Approvalâ€. This means that if you ask for info on that product id with a SKProductsRequest, youâ€™ll get the info for the item only on development builds, not in distributions builds.</p>
<p>Once your in-app purchase item is ready, you need to upload a screenshot of it working in the app, and approve it yourself. At that point it enters the queue to be approved by Apple. Once an item has been approved by Apple (marked as Ready for Sale), it will appear both in development and distribution builds.</p>
<p>This behavior is very convenient because you can add in-app purchases normally for development, and not worry about them showing up for all your existing users until theyâ€™re done. Just make sure to keep around a distribution build of your app to test what the end user sees.</p>
<p>In addition to that, you can flag items as available for sale or not. That way you have the added flexibility of temporarily removing an item from sale, or making it available at a later time.</p>
<p><img alt="itunesconnect" loading="lazy" src="/in-app-purchases-part-4/images/itunesconnect.jpg" title="itunesconnect"></p>
<h2 id="approval-process">Approval Process</h2>
<p>The first time you submit any in-app purchases, youâ€™ll probably do it along with a binary update (since you need to code in <a href="/in-app-purchases-part-1/">support for displaying</a> and <a href="/in-app-purchases-part-2/">allowing the purchases of items</a>). Youâ€™ll have an option to mark the items to be approved along with the binary, so everything will become available on the App Store at the same time. In that case, the approval process is just like for a regular binary update (it seems to be averaging a week lately).</p>
<p>You can also submit in-app purchase items by themselves, without an app binary update. I did this for the Seeds of Winter pack in Flower Garden. Somehow, I was expecting a turnaround time of a day or two. After all, I figured they would look at the provided screenshot and approve it. Unfortunately, that wasnâ€™t the case. In this particular situation, approval took almost a week, and Iâ€™m not sure it was because of the normal process, or because I emailed Apple asking what the procedure was to submit a product by itself (the product was approved within an hour of me getting a response from them saying they would look into it).</p>
<p>I was monitoring iTunes Connect pretty obsessively at the time it was approved (because it was right before my two-week break for the holidays) and I saw that the Seeds of Winter pack went from â€œWaiting for Reviewâ€ to â€œIn Reviewâ€ to â€œApproved for Saleâ€ in a matter of two minutes. That was one quick check! (Iâ€™m not complaining though).</p>
<p>Whatâ€™s even more interesting is that I didnâ€™t know that an item wouldnâ€™t appear on a distribution build unless it was approved by Apple, so I had added an extra layer on <a href="http://flowers.snappytouch.com/Shop/ShopCatalog.plist">the shop catalog file on my server</a> that allowed me to prevent an item from showing up on the Flower Shop until I turned it on myself. And since that check wasnâ€™t turned on, it means that Apple approved the in-app purchase by looking at the provided screenshot, without running it in the app.</p>
<p>This shouldnâ€™t be too surprising. After all, Iâ€™m not even sure what the point is for in-app purchase approvals. For content that comes from the server, I can change it at any time, so the only thing they can approve is the name and description provided in iTunes Connect. I suppose the screenshot is fine for that, but I would also expect really speedy approval times. After all, not having to wait for lengthy approval processes is one of the big draws for in-app purchases.</p>
<p>I did learn one important lesson from going through this process. Next time I submit a binary prepared for more in-app purchases, Iâ€™m going to create stand-ins for all possible in-app purchases Iâ€™m considering and submit them for approval at the same time as the app binary, but marked as not ready for sale. That way they will all be approved at once, and I can take my time creating the final version for those items and making them available instantly whenever I want.</p>
<h2 id="purchasing-items">Purchasing Items</h2>
<p>The same way that non-Apple approved items only show up in development builds, the only accounts that can purchase any items on development builds are test accounts using the sandbox environment. These are accounts you create on iTunes Connect and allow you to purchase items in your programs without spending real money (otherwise Iâ€™d be in trouble considering how many times I ended up purchasing items during the development of the Flower Shop!). Conversely, distribution builds only work with non-test accounts and non-sandbox environment.</p>
<p>One thing that threw me off was that I started getting support requests from people who had trouble logging in with their account to make in-app purchases. They claimed they were being asked about this â€œsandbox environmentâ€. That threw me in a panic for a second, because I thought that everybody was somehow accessing the sandbox environment and nobody could make any purchases (because they had full iTunes accounts). It turns out, thatâ€™s a problem that happens with jailbroken phones with a particular app installed. Itâ€™s <a href="http://www.facebook.com/l.php?u=http%3A%2F%2Fbit.ly%2F70C1Zw&amp;h=92bfb053b357f0588362e316b88d9f32">nicely documented here</a> so Iâ€™ve been pointing people in that direction.</p>
<p>Finally, I believe thereâ€™s no provision in iTunes Connect to deal with different binary versions, but thatâ€™s something thatâ€™s very important to handle. If I release a new binary with some new feature built into the app, and an in-app purchase to unlock it, I donâ€™t want people with an earlier version purchasing it and getting mad that itâ€™s not working. Ideally this should be an option in iTunes Connect, but in the meanwhile, I build a version check into <a href="http://flowers.snappytouch.com/Shop/ShopCatalog.plist">the shop catalog itself</a>. That way only apps with that version or higher can even display a particular item. Or I can even take it a step further and display the item but notify the user that they need to update the app before the purchase it.</p>
]]></content:encoded></item><item><title>All About In-App Purchases Part 3: Anti-Piracy Measures</title><link>https://gamesfromwithin.com/in-app-purchases-part-3/</link><pubDate>Mon, 21 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/in-app-purchases-part-3/</guid><description>&lt;p&gt;One of the big advantages of in-app purchases for some people is that it makes pirating content more difficult. For me it wasnâ€™t much of an issue because a) Most of the people who enjoy Flower Garden arenâ€™t the ones checking out the app warez sites, and b) I know better than to waste my time trying to prevent piracy &lt;a href="#1"&gt;[1]&lt;/a&gt;. Besides, I always roll my eyes whenever I hear that 90% or some other large percentage of the users are using a pirated copy, so the developer lost all that money. News flash: 99% of those users using a cracked version wouldnâ€™t have bought your product anyway, so you can rest a bit easier at night.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the big advantages of in-app purchases for some people is that it makes pirating content more difficult. For me it wasnâ€™t much of an issue because a) Most of the people who enjoy Flower Garden arenâ€™t the ones checking out the app warez sites, and b) I know better than to waste my time trying to prevent piracy <a href="#1">[1]</a>. Besides, I always roll my eyes whenever I hear that 90% or some other large percentage of the users are using a pirated copy, so the developer lost all that money. News flash: 99% of those users using a cracked version wouldnâ€™t have bought your product anyway, so you can rest a bit easier at night.</p>
<p>Even so, I decided to take a few extra steps that at least will make things a bit more difficult to crack and keep things more secure. I could have gone way beyond this, but I donâ€™t think that would have been worth my time.</p>
<h3 id="verify-the-purchase">Verify the purchase</h3>
<p><img alt="fg_pirate" loading="lazy" src="/in-app-purchases-part-3/images/fg_pirate.jpg" title="fg_pirate">Right now, you can download programs that will automatically crack an app by extracting its data and resigning it so it works on any jailbroken phone. Thereâ€™s no doubt that even if you implement in-app purchases just like I described in <a href="/in-app-purchases-part-1/">earlier</a> <a href="/in-app-purchases-part-2/">posts</a>, crackers will have to analyze the code and do some steps by hand, so that might be enough to slow down the pace of cracked apps.Â Even so, an experienced cracker wonâ€™t take long to crack your in-app purchases unless you take some extra steps. All they have to do is find the function that you call in response to getting the go ahead from the App Store and theyâ€™ll gain access to all content.</p>
<p>The first thing you should do is to verify that the purchase happened correctly. To do that, once you get the notification in your app that the payment was complete, you send the receipt to your server, and have your server verify it in turn with the App Store. Since crackers donâ€™t have access to your server (if they do youâ€™re in more trouble than a few cracked apps), that step is secure. If your app was cracked and the user didnâ€™t pay for the purchase, the App Store will fail the verification of the receipt and you donâ€™t have to deliver the content.</p>
<p>How do you check that the receipt is valid? First of all, you need to send the receipt of the purchase to your server. I send it along with some other info, like the userâ€™s UDID, what product was purchased, etc so I can keep general usage statistics. The relevant bits of code are the following:</p>
<pre tabindex="0"><code>NSString* receiptString = [self createEncodedString:transaction.transactionReceipt];
//...
[postBody appendData:[[NSString stringWithFormat:@&#34;\r\n--%@\r\n&#34;, boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[@&#34;Content-Disposition: form-data; name=\&#34;receipt\&#34;\r\n\r\n&#34; dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[receiptString dataUsingEncoding:NSUTF8StringEncoding]];
//...
[req setHTTPBody:postBody];
</code></pre><p>The createEncodedString function takes some arbitrary data and creates a <a href="http://en.wikipedia.org/wiki/Base64">base64 encoding</a>. Thatâ€™s one of the parts that is not particularly well documented in the SDK documentation.</p>
<pre tabindex="0"><code>- (NSString*) createEncodedString:(NSData*)data
{
    static char table[] = &#34;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=&#34;;

    const int size = ((data.length + 2)/3)*4;
    uint8_t output[size];

    const uint8_t* input = (const uint8_t*)[data bytes];
    for (int i = 0; i &lt; data.length; i += 3)
    {
        int value = 0;
        for (int j = i; j &lt; (i + 3); j++)
        {
            value &lt;&lt;= 8;
            if (j &lt; data.length)
                value |= (0xFF &amp; input[j]);
        }

        const int index = (i / 3) * 4;
        output[index + 0] =  table[(value &gt;&gt; 18) &amp; 0x3F];
        output[index + 1] =  table[(value &gt;&gt; 12) &amp; 0x3F];
        output[index + 2] = (i + 1) &lt; data.length ? table[(value &gt;&gt; 6)  &amp; 0x3F] : &#39;=&#39;;
        output[index + 3] = (i + 2) &lt; data.length ? table[(value &gt;&gt; 0)  &amp; 0x3F] : &#39;=&#39;;
    }    

    return  [[NSString alloc] initWithBytes:output length:size encoding:NSASCIIStringEncoding];
}
</code></pre><p>That just sends the receipt to my server. Once the server receives that request, it needs to verify the data with the App Store. The exact format of the App Store request is, again, not well documented. It turns out it needs to be sent as anonymous data in a POST request. After some trial and error, this is the php code Iâ€™m using in my server to verify the receipt:</p>
<pre tabindex="0"><code>function isReceiptValid($purchase)
{
	$data = array (&#39;receipt-data&#39; =&gt; $purchase-&gt;receipt );
	$encodedData = json_encode($data);

	$url = &#34;https://buy.itunes.apple.com/verifyReceipt&#34;;

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $encodedData);
	$encodedResponse = curl_exec($ch);
	curl_close($ch);

	if ($encodedResponse == false)
	{
		logError($purchase, &#34;Payment could not be verified (no response data).&#34;);
		return false;
	}

	$response = json_decode($encodedResponse);
	if ($response-&gt;{&#39;status&#39;} != 0)
	{
		logError($purchase, &#34;Payment could not be verified (status != 0).&#34;);
		return false;
	}

	$purchase-&gt;storeReceipt = $response-&gt;{&#39;receipt&#39;};
	return true;
}
</code></pre><p>If things check out, the server returns a valid code, and you can go ahead and make the content available to the user. Otherwise, it means the user is trying to pass up a fake purchase as valid and you can deal with it any way you want.</p>
<h3 id="get-content-from-the-server">Get content from the server</h3>
<p>Of course, if the content is already embedded in the app itself, the cracker can bypass both the App Store purchase and the receipt verification through your server, and just access the content directly. If you want a better chance of not being cracked, have your server deliver the content. That way, if the receipt doesnâ€™t check out, you never transfer the content.</p>
<p>In the case of Flower Garden, all seed packets are downloaded from the server, but the other purchases (extra pots, extra fertilizer) are just changing a few internal variables, so they would be a lot easier to crack.</p>
<p>One of the easiest ways that crackers can get around this verification is by buying the content once and saving the receipt that comes with it. Then, cracked versions can pass that receipt to your server, theyâ€™ll be validated as correctly, and theyâ€™ll be able to download the content.Â So, as an added precaution, you might want to keep track how many times a certain purchase is re-downloaded, especially from different UDIDs. I canâ€™t imagine a legitimate reason for a user to download the same purchase more than 20-30 times from different devices, so denying the purchase at that point in the server seems justified.</p>
<h3 id="save-those-receipts">Save those receipts</h3>
<p>The last step I to make cracking more difficult was to save the receipt itself to disk along with the content that was downloaded. Then, periodically, the game can pick one of those receipts, and verify with the server that itâ€™s still valid. If itâ€™s ever reported as an invalid receipt, the game deletes the content for that purchase. This is not as draconian as it sounds, because even if itâ€™s ever triggered for a legitimate user (and I have no idea how that could be other than data corruption), they can always re-purchase it again for free (and they would want to do that to fix their data corruption anyway).</p>
<p>To be able to delete things easily and cleanly, I keep each downloaded in-app purchase on a separate directory. So itâ€™s very easy to delete the whole directory without having to access files everywhere. The hardest thing is making sure the game deals with the missing data and that nothing is referencing it. Iâ€™ll touch on that on a future part of this article.</p>
<p>Keeping purchases in separate directories also makes it easier to reset all purchases. Thatâ€™s something I didnâ€™t originally include in Flower Garden, but I should have. Sometimes, data can get corrupted or maybe a bug occurs because of some combination of purchases (hopefully not, but you never know!). Allowing the user to reset the purchases and re-download them allows them to fix those problems without having to reinstall the app and lose their progress.</p>
<p>[1] I know from first hand experience that one dedicated teenager with all the time in his hands can spend inordinate amounts of time bypassing the most elaborate anti-piracy schemes. The harder it is, the more of a challenge it becomes, and the more fun it is. To this day, I still remember the thrill of finally bypassing the copy protection of <a href="http://tacgr.emuunlim.com/downloads/filedetail.php?recid=3">1943 on the Amstrad CPC</a> after two days of non-stop hacking, which included several loops XORing all the available memory (including the currently executing code), and messages from the developers taunting me!</p>
]]></content:encoded></item><item><title>All About In-App Purchases Part 2: Selling The Goods</title><link>https://gamesfromwithin.com/in-app-purchases-part-2/</link><pubDate>Fri, 18 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/in-app-purchases-part-2/</guid><description>&lt;p&gt;The &lt;a href="https://gamesfromwithin.com/in-app-purchases-part-1/"&gt;last entry about in-app purchases&lt;/a&gt; left off with the products correctly displayed on the store and ready for purchase. Let&amp;rsquo;s push that buy button!&lt;/p&gt;
&lt;h3 id="purchasing-a-product"&gt;Purchasing a product&lt;/h3&gt;
&lt;p&gt;&lt;img alt="iap_1" loading="lazy" src="https://gamesfromwithin.com/in-app-purchases-part-2/images/iap_1.jpg" title="iap_1"&gt;The store is fully populated, the items are displayed and, if all goes well, the user presses the buy button. What now?&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The <a href="/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&rsquo;s push that buy button!</p>
<h3 id="purchasing-a-product">Purchasing a product</h3>
<p><img alt="iap_1" loading="lazy" src="/in-app-purchases-part-2/images/iap_1.jpg" title="iap_1">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&rsquo;re thinking that a hacker can just set the free flag to true and have access to all your content, it&rsquo;s not that easy, because the server checks that the product is really marked as free when it&rsquo;s contacted, and if it isn&rsquo;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 tabindex="0"><code>if ([SKPaymentQueue canMakePayments])
{
    SKPayment* payment = [SKPayment paymentWithProductIdentifier:m_product.m_id];
    SKPaymentQueue* queue = [SKPaymentQueue defaultQueue];
    [queue addPayment:payment];
    [m_progressViewController setText:@&#34;Accessing store&#34; completed:NO];
    [m_progressViewController display:YES animated:YES];
}
</code></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 id="completing-the-purchase">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&rsquo;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 alt="iap_2" loading="lazy" src="/in-app-purchases-part-2/images/iap_2.jpg" title="iap_2">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&rsquo;s important to understand the payment queue well. First of all, it&rsquo;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&rsquo;s at this time that you have to deliver the goods. Only once you&rsquo;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&rsquo;s never delivered to them.</p>
<p>I&rsquo;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&rsquo;ll be given the option to redownload it for free. It&rsquo;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&rsquo;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 tabindex="0"><code>- (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;
        }
    }
}
</code></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>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>
]]></content:encoded></item><item><title>All About In-App Purchases Part 1: Displaying Store Items</title><link>https://gamesfromwithin.com/in-app-purchases-part-1/</link><pubDate>Thu, 17 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/in-app-purchases-part-1/</guid><description>&lt;p&gt;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 &lt;a href="http://www.metacritic.com/games/platforms/xbx/mechassault"&gt;my previous experience with downloadable content in games&lt;/a&gt; that only a small amount of the people who originally purchased the game would be interested in buying additional content. Flower Garden has been &lt;a href="http://www.snappytouch.com/flowergarden_reviews"&gt;extremely well received&lt;/a&gt;, 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.&lt;/p&gt;</description><content:encoded><![CDATA[<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 alt="fg_flowershop2" loading="lazy" src="/in-app-purchases-part-1/images/fg_flowershop2.jpg" title="fg_flowershop2">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 id="displaying-store-items">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&rsquo;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 id="getting-the-catalog">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 id="getting-product-info">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 tabindex="0"><code>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];
</code></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 id="displaying-the-products">Displaying the products</h3>
<p><img alt="fg_flowershop3" loading="lazy" src="/in-app-purchases-part-1/images/fg_flowershop3.jpg" title="fg_flowershop3"></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>
]]></content:encoded></item><item><title>Two Day iPhone OpenGL Class Coming to The Bay Area</title><link>https://gamesfromwithin.com/two-day-iphone-opengl-class-coming-to-the-bay-area/</link><pubDate>Sun, 18 Oct 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/two-day-iphone-opengl-class-coming-to-the-bay-area/</guid><description>&lt;p&gt;&lt;img alt="cars" loading="lazy" src="https://gamesfromwithin.com/two-day-iphone-opengl-class-coming-to-the-bay-area/images/cars.png" title="cars"&gt;After the success of the OpenGL class in Denver, we&amp;rsquo;re bringing the &lt;a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/"&gt;iPhone OpenGL class&lt;/a&gt; to the Bay Area. It will be held November 19th and 20th in &lt;a href="http://maps.google.com/maps?q=10950+North+Blaney+Avenue+Cupertino,+CA+95014&amp;amp;oe=utf-8&amp;amp;client=firefox-a&amp;amp;ie=UTF8&amp;amp;gl=us&amp;amp;ei=imnbSoj4OYakMfvskN8H&amp;amp;ved=0CA0Q8gEwAA&amp;amp;hq=&amp;amp;hnear=10950+N+Blaney+Ave,+Cupertino,+Santa+Clara,+California+95014&amp;amp;ll=37.334072,-122.02362&amp;amp;spn=0.026377,0.043731&amp;amp;z=15"&gt;Cupertino&lt;/a&gt;, right next to Apple&amp;rsquo;s headquarters at Infinite Loop.&lt;/p&gt;
&lt;p&gt;The class is aimed at iPhone developers without previous OpenGL or 3D graphics experience. As part of the class, we&amp;rsquo;ll create both 2D and 3D OpenGL applications, and we&amp;rsquo;ll cover a broad range of topics, start with the basics of setting up OpenGL and rendering triangles on screen, to multitexturing and point sprites in the last day. This is definitely a hands-on class, so you&amp;rsquo;ll need to bring your laptop and be ready to do some coding.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="cars" loading="lazy" src="/two-day-iphone-opengl-class-coming-to-the-bay-area/images/cars.png" title="cars">After the success of the OpenGL class in Denver, we&rsquo;re bringing the <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">iPhone OpenGL class</a> to the Bay Area. It will be held November 19th and 20th in <a href="http://maps.google.com/maps?q=10950+North+Blaney+Avenue+Cupertino,+CA+95014&amp;oe=utf-8&amp;client=firefox-a&amp;ie=UTF8&amp;gl=us&amp;ei=imnbSoj4OYakMfvskN8H&amp;ved=0CA0Q8gEwAA&amp;hq=&amp;hnear=10950+N+Blaney+Ave,+Cupertino,+Santa+Clara,+California+95014&amp;ll=37.334072,-122.02362&amp;spn=0.026377,0.043731&amp;z=15">Cupertino</a>, right next to Apple&rsquo;s headquarters at Infinite Loop.</p>
<p>The class is aimed at iPhone developers without previous OpenGL or 3D graphics experience. As part of the class, we&rsquo;ll create both 2D and 3D OpenGL applications, and we&rsquo;ll cover a broad range of topics, start with the basics of setting up OpenGL and rendering triangles on screen, to multitexturing and point sprites in the last day. This is definitely a hands-on class, so you&rsquo;ll need to bring your laptop and be ready to do some coding.</p>
<p>Check out the <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">Mobile Orchard page for discounts and registration details</a>. Feel free to <a href="/contact/">contact me</a> if you have any questions.</p>
<p>Hope to see you there!</p>
]]></content:encoded></item><item><title>Space in Stereo iPhone Game Jam Postmortem</title><link>https://gamesfromwithin.com/space-in-stereo-iphone-game-jam-postmortem/</link><pubDate>Mon, 05 Oct 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/space-in-stereo-iphone-game-jam-postmortem/</guid><description>&lt;p&gt;A week ago, I sent out a &lt;a href="http://twitter.com/SnappyTouch/status/4409865477"&gt;quick tweet&lt;/a&gt; asking if anyone would be interested in doing an iPhone Game Jam at the &lt;a href="http://www.360idev.com/"&gt;360iDev conference&lt;/a&gt;. The response was &lt;a href="http://twitter.com/%23search?q=jam%2520360idev"&gt;immediate and hugely positive&lt;/a&gt;, so, with the help of the organizers of 360iDev, we put together an informal &lt;a href="http://iphonegamejam.com/"&gt;iPhone Game Jam&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The idea was to get together Tuesday evening, starting at around 7PM, and to code all night and have an iPhone game (or at least a prototype) done by morning. About 25 showed up, working on about &lt;a href="http://iphonegamejam.com/index.php?title=Projects"&gt;a dozen projects&lt;/a&gt;. Participants were welcome to group into teams or work solo. There were no restrictions as far as themes or technology. The only rules were that you had to finish something by morning (no leaving something that was 5% of a game) and you had to start the game from scratch (no finishing a game you had started a while ago).&lt;/p&gt;</description><content:encoded><![CDATA[<p>A week ago, I sent out a <a href="http://twitter.com/SnappyTouch/status/4409865477">quick tweet</a> asking if anyone would be interested in doing an iPhone Game Jam at the <a href="http://www.360idev.com/">360iDev conference</a>. The response was <a href="http://twitter.com/%23search?q=jam%2520360idev">immediate and hugely positive</a>, so, with the help of the organizers of 360iDev, we put together an informal <a href="http://iphonegamejam.com/">iPhone Game Jam</a>.</p>
<p>The idea was to get together Tuesday evening, starting at around 7PM, and to code all night and have an iPhone game (or at least a prototype) done by morning. About 25 showed up, working on about <a href="http://iphonegamejam.com/index.php?title=Projects">a dozen projects</a>. Participants were welcome to group into teams or work solo. There were no restrictions as far as themes or technology. The only rules were that you had to finish something by morning (no leaving something that was 5% of a game) and you had to start the game from scratch (no finishing a game you had started a while ago).</p>
<p><img alt="space" loading="lazy" src="/space-in-stereo-iphone-game-jam-postmortem/images/space.jpg" title="space"></p>
<p>The reason behind doing a game jam is to be able to quickly create game prototypes and decide if theyâ€™re worth pursuing further or not. Much better to spend a few hours one night and then throwing it away, than spending several months with multiple people involved. Also, the heavy time constraints often help participants by focusing them in the ultimate goal and forcing them to adopt creative solutions. Being all together in one large room added a lot of energy and made it possible to work really focused for many hours without a huge amount of caffeine (although the large amounts of coffee provided by <a href="http://twitter.com/javahead">Jay</a> really helped!). In the end, we even ended up getting <a href="http://www.youtube.com/watch?v=KCYsZqp573o">a late-night fiddle serenade</a> by <a href="http://www.philhassey.com/blog/">Phil Hassey</a>. Try that at home by yourself! <a href="http://www.streamingcolour.com/blog/">Owen Goss</a> liked the idea so much, he decided to jam with use remotely through video conferencing!</p>
<p>One specific thing that I wanted to avoid with the game jam was the idea of giving any sort of prices at the end. I really wanted to keep the jam as an environment where people would be free to experiment and fail. If people were thinking of potential prices at the end, they would be a lot less willing to go out on a limb and try different things.</p>
<p>My goal going into the jam was to experiment with game mechanics that relied heavily on multi touch. I felt that very few games made good use of multi touch (aside from pinching) and that it had the potential to create something very different from the single-touch based game that weâ€™re used to from mice for the last 20 years. The flip side of it is that a multi-touch game was much riskier and unknown. Could something that multiple simultaneous touches be fun, or would it be frustrating? Would your fingers get in the way and clutter the screen, or would it be a new experience? In the back of my mind, I was definitely drawing inspiration from the fantastic game <a href="http://click.linksynergy.com/fs-bin/stat?id=aDkhM0mDflg&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;RD_PARM1=http%25253A%25252F%25252Fitunes.apple.com%25252FWebObjects%25252FMZStore.woa%25252Fwa%25252FviewSoftware%25253Fid%25253D315613006%252526mt%25253D8%252526uo%25253D6%252526partnerId%25253D30">Bug Bugs</a>, by <a href="http://igloo-games.com/">Igloo Games</a>.</p>
<p>I did all the coding myself, but I teamed up with <a href="http://twitter.com/veiledgames">Evan McMahon</a> from <a href="http://veiledgames.com/">Veiled Games</a> and he did all the awesome art in the prototype.</p>
<p><img alt="Owen Goss joining the iPhone Game Jam remotely" loading="lazy" src="/space-in-stereo-iphone-game-jam-postmortem/images/owen.jpg" title="owen"></p>
<p><em>Owen Goss joining the iPhone Game Jam remotely</em></p>
<h2 id="what-went-right">What Went Right</h2>
<h3 id="started-with-an-idea"><strong>Started with an idea</strong></h3>
<p>I went into the jam with the idea of experimenting with multi-touch game mechanics. I also had in mind a setting that would be a good backdrop to those mechanics: You control a large, round spaceship in interstellar travel. As you travel between the stars, you need to collect different resources to power your ship and provide all necessary materials. Each type of resource goes in a different bay (which are located along the outer rim), so with two fingers you rotate the ship to move the collecting bay forward, and with the other hand you drag the different resources you encounter. Some resources arenâ€™t useful, so you need to flick them away so they donâ€™t hit the ship. Finally, other resources need to be combined before they can be processed, so you first need to bring them together, and then drag them to the ship.</p>
<p>You only have 10-12 hours to build a game, so if I didnâ€™t have an idea going into the jam, I would have wasted precious time trying to figure out what to do while I could have been working on the game.</p>
<p>At the same time, I didnâ€™t have the idea fully fleshed out and set in stone. I definitely let things change based on what I saw as I was implementing it. So itâ€™s good to strike a flexible medium between having an idea and letting it evolve during the jam.</p>
<h3 id="used-familiar-tools"><strong>Used familiar tools</strong></h3>
<p>Just the day before, <a href="http://criticalthoughtgames.com/">David Whatley</a> raved about how great <a href="http://cocos2d.org/">Cocos2d</a> was for prototyping, and that same day, my friend <a href="http://hiddenelephant.com/blog/">Serban</a> gave <a href="http://hiddenelephant.com/blog/2009/10/01/360idev-introduction-to-2d-game-programming-using-cocos2d/">a presentation on using Cocos2d</a>. Iâ€™m <a href="http://twitter.com/SnappyTouch/status/4480633461">on record</a> saying that I canâ€™t stand to work with Cocos2d because it imposes a particular (totally backwards) architecture on you, and I canâ€™t ever see myself shipping a game with it, but I can see the value in using it for prototyping.</p>
<p>The point of this jam (for me anyway) wasnâ€™t to learn some new tech, but to experiment with gameplay. So I really considered it, but in the end, I decided to work with something I was familiar with, and used my (very small) codebase using straight OpenGL. Iâ€™m very glad that I did because I never felt that working at that level got in the way (other than one frustrating moment related to the first point in â€œwhat went wrongâ€),</p>
<h3 id="didnât-worry-about-performance"><strong>Didnâ€™t worry about performance</strong></h3>
<p>This is a hard one for me! The last <a href="../../../../../gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone">two</a> <a href="../../../../../360idev-cranking-up-floating-point-performance-to-11">talks</a> Iâ€™ve given are all about performance on the iPhone, but even thinking about performance here would have been a waste of time and resources. Sure, the game had to be fast enough to run on the actual device because playing a game on the phone is a very different experience than playing it on the simulator. Besides, a game like this requiring lots of multi-touch was impossible to play on the simulator.</p>
<p>But at the same time, I didnâ€™t have to submit it to the App Store come morning, so I decided that as long as it ran on my 3GS, I didnâ€™t care about anything else. That meant it could be very suboptimal and be a total memory hog. I didnâ€™t care! I wasnâ€™t even releasing resources!</p>
<p>The result, it played perfectly fine on my phone, and I spent zero time trying to optimize it or taking a longer route because of performance or memory reasons. On the other hand, just the tiny, single level I created is about 12MB, so itâ€™s clearly very bloated.</p>
<h3 id="teaming-up"><strong>Teaming up</strong></h3>
<p>As I mentioned earlier, I teamed up with Evan McMahon to create the art for the game. He wasnâ€™t at the conference, so we organized everything through IM and <a href="http://www.getdropbox.com/">Dropbox</a>. The experience was great because not only did he create some awesome-looking art, but he really motivated me along the way. We played off each otherâ€™s energy and came up with new ideas because of the collaboration.</p>
<p>Going solo would have been OK because I was surrounded by a room full of like-minded developers hacking away at their games, so that would have helped keep up the energy levels, but it wouldnâ€™t have had nearly as much of an effect as working directly with someone else. My only regret is that Evan wasnâ€™t there with me.</p>
<p><img alt="ScreenWithButton" loading="lazy" src="/space-in-stereo-iphone-game-jam-postmortem/images/ScreenWithButton.jpg" title="ScreenWithButton"></p>
<p>What about the art itself? Was it a waste of time to add it to the game? After all, it didnâ€™t help me make a better decision about the multi-touch game mechanics, did it? It wasnâ€™t a waste of time at all for me. First of all, it took just as long adding some nice art than it took to add stand-in art because there wasnâ€™t anything special about it. But most importantly, there is a feedback loop between the look of the game and the gameplay and feel of the game. So seeing the art in the game definitely changed how I felt about it and the decisions I made about it during the night.</p>
<h2 id="what-went-wrong"><strong>What Went Wrong</strong></h2>
<h3 id="didnât-have-a-project-ready"><strong>Didnâ€™t have a project ready</strong></h3>
<p>This just goes to show my lack of experience with super-rapid prototyping. I didnâ€™t have a project ready to get started with the prototyping. I originally created a blank OpenGL project from XCode, and quickly realized I would be missing all the set up for sound, the view controller structure, and even some of the default touch-handling. So I grabbed one of my current projects in development, stripped it of everything game specific, and turned it into the project for the game jam. Not a big deal, except that it took me a good 20-30 minutes to go through this, and in the process I deleted a couple crucial lines that gave me lots of problems with OpenGL for the next 30 minutes. Doh!</p>
<p>Next time: Come prepared with a blank project, ready to go.</p>
<h3 id="running-up-against-technical-stuff"><strong>Running up against technical stuff</strong></h3>
<p>I went with OpenGL instead of Cocos2d on purpose to avoid having to deal with learning technical stuff sleep deprived in the middle of the jam. Unfortunately, it turns out my understanding of the multi touch event API wasnâ€™t up to snuff to handle 5 simultaneous touches, starting, moving, and ending, each of them affecting a different object (or different parts of the same object). During the jam I wasnâ€™t writing unit tests either, so that made for a pretty confusing time until I stepped back for a second, hit the documentation and Appleâ€™s touch sample program, and tried to gain a better understanding of what was going on. Hint: Apparently looking at the touches in the UIEvent* parameter passed to touchesBegan is not a good idea, and you need to look at the ones passed in NSSet*.</p>
<h3 id="not-enough-time"><strong>Not enough time!</strong></h3>
<p>I certainly didnâ€™t get as far in the prototype as I had hoped I would. Thereâ€™s only one type of resource (ice chunks) and the control mechanics need to be improved quite a bit.</p>
<p>Is it possible that if I had used Cocos2d I would have gotten more done of the prototype? Yes, itâ€™s possible, although I wonâ€™t know until I try it. Is it possible that half way through the prototype I would have encountered something that Cocos2d couldnâ€™t do and I was left stranded? Yes, thatâ€™s also possible. And thatâ€™s a big reason why I donâ€™t like framework-y type of APIs, and instead I would rather have a toolkit type of API so I can call into it and do the work myself whenever I want instead.</p>
<p>In any case, this is the flip side of â€œusing familiar toolsâ€. I will definitely experiment with Cocos2d in the future and consider it for another game jam if Iâ€™m familiar enough with it and I feel it speeds up development.</p>
<p><img alt="Everybody still going strong late at night (but not quite so perky anymore)" loading="lazy" src="/space-in-stereo-iphone-game-jam-postmortem/images/gamejam.jpg" title="gamejam"></p>
<p><em>Everybody still going strong late at night (but not quite so perky anymore)</em></p>
<h2 id="conclusions"><strong>Conclusions</strong></h2>
<p>I think Space in Stereo has potential, but right now itâ€™s too early to tell if itâ€™s any good. The basic mechanic is there, but itâ€™s not fun by any stretch of the imagination. I already learned a bunch about it though, including that some things werenâ€™t nearly as much fun as I was hoping would be. For example, rotating the space station with two fingers&hellip; well, sucks. The better control scheme is to move the space station by dragging around the middle, and rotating it by dragging a finger around the edge in a circular motion. That was also what everybody was instinctively doing when they were trying out the game.</p>
<p>The game is just at the point that spending another 4-5 hours on it would answer a lot of questions about how fun it can be. Iâ€™m definitely planning on spending that time and then making a decision. If I decide not to go ahead with it, itâ€™s not a big deal. Great games come out of making a lot of different prototypes and throwing away all the so-so ones along the way.</p>
<p>As far as the Game Jam itself, it can only be described in one word: Awesome. It was everything I was hoping for and more. I canâ€™t stress enough how much it helped to have everybody else around you and being so focused for that period of time. I had heard much about game jams, but I had never actually participated in one. After this one Iâ€™m sold. I canâ€™t wait until the next one!</p>
<p><em>Gameplay footage of Space in Stereo</em></p>]]></content:encoded></item><item><title>360iDev: Cranking Up Floating Point Performance To 11</title><link>https://gamesfromwithin.com/360idev-cranking-up-floating-point-performance-to-11/</link><pubDate>Tue, 29 Sep 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/360idev-cranking-up-floating-point-performance-to-11/</guid><description>&lt;p&gt;&lt;img alt="360iDev_speaker" loading="lazy" src="https://gamesfromwithin.com/360idev-cranking-up-floating-point-performance-to-11/images/360iDev_speaker.png" title="360iDev_speaker"&gt;Here are the slides and the source code for my talk this afternoon at 360iDev in Denver. Thanks to everyone who came to the talk. I was surprised to see so much interest on this topic, so that was great.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Session description:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The iPhone has a very powerful engine under that shiny hood when it comes to floating-point computations. This is something that surprises a lot of programmers because by default, things can slow down a lot whenever any floating point numbers are involved. This session will explain the secrets to unlocking maximum performance for floating point calculations, from the mysteries of Thumb mode, to harnessing the full power of the forgotten vector floating point unit. Stay away from this session if he thought of reading or even (gasp!) writing assembly code scares you.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="360iDev_speaker" loading="lazy" src="/360idev-cranking-up-floating-point-performance-to-11/images/360iDev_speaker.png" title="360iDev_speaker">Here are the slides and the source code for my talk this afternoon at 360iDev in Denver. Thanks to everyone who came to the talk. I was surprised to see so much interest on this topic, so that was great.</p>
<p><strong>Session description:</strong></p>
<p>The iPhone has a very powerful engine under that shiny hood when it comes to floating-point computations. This is something that surprises a lot of programmers because by default, things can slow down a lot whenever any floating point numbers are involved. This session will explain the secrets to unlocking maximum performance for floating point calculations, from the mysteries of Thumb mode, to harnessing the full power of the forgotten vector floating point unit. Stay away from this session if he thought of reading or even (gasp!) writing assembly code scares you.</p>
<ul>
<li><a href="http://www.slideshare.net/llopis/cranking-floating-point-performance-to-11-on-the-iphone-2111775">Presentation slides</a> (<a href="/wp-content/uploads/2009/09/iPhoneFP.pdf.zip">pdf format</a>)</li>
<li><a href="/wp-content/uploads/2009/09/vfpperf.zip">Sample project</a></li>
</ul>
]]></content:encoded></item><item><title>GDC Austin 2009: Squeezing Every Drop Of Performance Out Of The iPhone</title><link>https://gamesfromwithin.com/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/</link><pubDate>Wed, 16 Sep 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/</guid><description>&lt;p&gt;&lt;img alt="austin" loading="lazy" src="https://gamesfromwithin.com/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/images/austin.jpg" title="austin"&gt;I just put up &lt;a href="http://www.slideshare.net/llopis/squeezing-every-drop-of-performance-out-of-the-iphone"&gt;the slides for my talk&lt;/a&gt; this morning at GDC Austin: &lt;a href="https://www.cmpevents.com/GDAU09/a.asp?option=C&amp;amp;V=11&amp;amp;SessID=9869"&gt;Squeezing Every Drop Of Performance Out Of The iPhone.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks for everyone who attended the session and for the great feedback so far. If you&amp;rsquo;re going to be in China next month, I&amp;rsquo;ll be giving a very similar talk at &lt;a href="http://www.gdcchina.com/"&gt;GDC China&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Session description:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This session will describe the iPhone performance optimization lessons learned through many hours of tuning. We&amp;rsquo;ll start with an overview of the performance analysis tools available on the iPhone SDK to help you narrow down your performance bottlenecks. Then we&amp;rsquo;ll cover the best way to set up your render loops, rendering best practices, how to deal with the limited memory, or even how to drop down to assembly to use the forgotten vector floating point unit.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="austin" loading="lazy" src="/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/images/austin.jpg" title="austin">I just put up <a href="http://www.slideshare.net/llopis/squeezing-every-drop-of-performance-out-of-the-iphone">the slides for my talk</a> this morning at GDC Austin: <a href="https://www.cmpevents.com/GDAU09/a.asp?option=C&amp;V=11&amp;SessID=9869">Squeezing Every Drop Of Performance Out Of The iPhone.</a></p>
<p>Thanks for everyone who attended the session and for the great feedback so far. If you&rsquo;re going to be in China next month, I&rsquo;ll be giving a very similar talk at <a href="http://www.gdcchina.com/">GDC China</a>.</p>
<p><strong>Session description:</strong></p>
<p>This session will describe the iPhone performance optimization lessons learned through many hours of tuning. We&rsquo;ll start with an overview of the performance analysis tools available on the iPhone SDK to help you narrow down your performance bottlenecks. Then we&rsquo;ll cover the best way to set up your render loops, rendering best practices, how to deal with the limited memory, or even how to drop down to assembly to use the forgotten vector floating point unit.</p>
<p><a href="https://www.cmpevents.com/GDAU09/a.asp?option=C&amp;V=11&amp;SessID=9869">Presentation slides</a> (<a href="/wp-content/uploads/2009/09/iPhone_performance.pdf">pdf format</a>)</p>
]]></content:encoded></item><item><title>From Full to Lite in Under An Hour</title><link>https://gamesfromwithin.com/from-full-to-lite-in-under-an-hour/</link><pubDate>Mon, 14 Sep 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/from-full-to-lite-in-under-an-hour/</guid><description>&lt;p&gt;&lt;img alt="Icon_lite_rounded" loading="lazy" src="https://gamesfromwithin.com/from-full-to-lite-in-under-an-hour/images/Icon_lite_rounded.png" title="Icon_lite_rounded"&gt;A bit over a month ago &lt;a href="#1"&gt;[1]&lt;/a&gt;, I decided it was time to create a &lt;a href="http://itunes.com/apps/flowergardenlite"&gt;&amp;ldquo;lite&amp;rdquo; version of Flower Garden&lt;/a&gt; &lt;a href="#2"&gt;[2]&lt;/a&gt;. I really thought it was going to be a pretty easy task: Disable a few pots, remove some seeds, and repackage it. Sounds simple enough. But before that, I had to decide how to structure the project for the lite version.&lt;/p&gt;
&lt;h3&gt;&lt;/h3&gt;</description><content:encoded><![CDATA[<p><img alt="Icon_lite_rounded" loading="lazy" src="/from-full-to-lite-in-under-an-hour/images/Icon_lite_rounded.png" title="Icon_lite_rounded">A bit over a month ago <a href="#1">[1]</a>, I decided it was time to create a <a href="http://itunes.com/apps/flowergardenlite">&ldquo;lite&rdquo; version of Flower Garden</a> <a href="#2">[2]</a>. I really thought it was going to be a pretty easy task: Disable a few pots, remove some seeds, and repackage it. Sounds simple enough. But before that, I had to decide how to structure the project for the lite version.</p>
<h3></h3>
<p>#defining The Problem</p>
<p>The first approach that came to mind was to use #ifdefs. Hopefully, if I did things well, it wouldn&rsquo;t require too many of them. As soon as I gave it some more thinking, it was clear this was a pretty flawed approach.</p>
<p>I like to be able to create a build with zero human interaction: Press a button, wait, and the build is ready. I don&rsquo;t want to have to do any manual (read, error-prone) steps. So I couldn&rsquo;t just have an #ifdef that I turned on and off depending on whether I was building the lite version or the full one. I can get around that by creating a new configuration in XCode, except that it wouldn&rsquo;t be one, it would be one for every existing configuration I already have: Debug, Release, Distribution Ad Hoc, and Distribution App Store. So this would make a total of 8 configurations. That&rsquo;s rather ugly!</p>
<p>In case the explosion of configurations wasn&rsquo;t ugly enough, there was one other, even bigger problem: An #ifdef wouldn&rsquo;t allow me to change the assets included in each version of Flower Garden, and, most importantly, I couldn&rsquo;t change the Info.plist file to have a different bundle id (although maybe I could change the Info.plist for each of the new configurations and point it to the new one).</p>
<p>Not an attractive option. So how else can we do it?</p>
<h3 id="new-xcode-project">New XCode Project</h3>
<p>The idea is straightforward: Make a copy of the existing project for the full version of the game, and change it in any way you want: Remove resources, add new ones, change Info.plist, etc. You can still share common source files and define a preprocessor macro LITE in the new project to #ifdef parts of the code.</p>
<p>This approach sounds more promising, until you realize that changes made to one project don&rsquo;t carry over to the other one. So if you&rsquo;re done developing the full version, and you create the lite version at the very end, maybe that won&rsquo;t be a problem (although, how can you be sure you&rsquo;re done?) And making changes to two separate projects is never fun.</p>
<p>You could improve things a bit by starting out the lite version as a branch in source control. That way, changes made to one of the branches can (hopefully) be merged back into the main line or another branch (have fun merging xcodeproj files). I think it&rsquo;s because I&rsquo;ve had the displeasure of working in projects that went totally overboard branching, that just the word branch makes me recoil in disgust. Yes, this method might work, but it seemed cumbersome and error prone.</p>
<p>Any other solutions?</p>
<h3 id="stay-on-target">Stay On Target</h3>
<p>It turns out I kept thinking in terms of a solution I could have implemented in Visual Studio (that&rsquo;s what I get for spending so many years working with it). But fortunately we&rsquo;re not in Windows-land anymore. This is XCode, and XCode totally rocks.</p>
<p>XCode&rsquo;s build system, once you wrap your head around it, is much more flexible and natural than Visual Studio&rsquo;s. It&rsquo;s much more like a make file (and I say that in a good way&ndash;I do like make files!). You have files, and then you have targets. And there&rsquo;s nothing that says a file can&rsquo;t be in multiple targets (and the file only appears in the project once). Once you have multiple target, whenever you add a new file you have the option to add it to both targets the same time if you want. Perfect!</p>
<p>My Flower Garden project contains about 15 targets: 7 &ldquo;engine&rdquo; libraries, 7 test executables for each of the libraries, and one main executable target for the game itself. So the (now obvious) solution, was to simply create a new target for the lite version, in that same project, with the same files. It turns out this solution had all the advantages of the previous approaches with none of the drawbacks.</p>
<h3 id="lite-target-details">Lite Target Details</h3>
<p><img alt="targets" loading="lazy" src="/from-full-to-lite-in-under-an-hour/images/targets.png" title="targets">Once I landed on the target idea, it really was quite straightforward to create the Lite version by following a few, simple steps:</p>
<ul>
<li>Make a duplicate of the target for the full version. Just right click on the full target, and select duplicate.</li>
<li>Rename new target to something else (Flower Garden Lite&ndash;I&rsquo;m highly imaginative when it comes to naming things like this! :-)</li>
<li>Make a duplicate of your Info.plist (InfoLite.plist)</li>
<li>Change the info.plist file setting for the lite target to point to InfoLite.plist</li>
<li>Edit InfoLite.plist to have a different bundle identifier and maybe a different bundle display name (the name that&rsquo;s going to show up under the icon on the iPhone).</li>
<li>Add a compiler define to the lite target called LITE or something like that. That way you can #ifdef a few parts of the code depending on the version you&rsquo;re compiling.</li>
</ul>
<p>And that&rsquo;s almost it. There&rsquo;s one more trick that made my life a lot easier. It turns out that you will definitely want to change not just some code, but some assets depending on which version you&rsquo;re using. So maybe you&rsquo;ll have a Wall.png texture in the full version, but you&rsquo;ll want to have a different version of that texture in the Lite version. I started out creating a new file called WallLite.png, but then it quickly cascaded into a bunch of code changes loading either Wall.png or WallLite.png depending on the version and it was ugly and time consuming.</p>
<p>A much better approach is to rely on the resource copy step of XCode. By default, XCode will grab the resources in your project and copy them all in the same folder, flattening the hierarchy completely. This can be a pain if you have resources with the same name organized in different folders because they will clash. But here we can use it to our advantage to supply different versions of the resource for the full and lite versions.</p>
<p>Just create a Lite directory and put any variations of your resources there. Then, in the Resources Copy step of the target, remove the resources you&rsquo;re replacing and add the ones from the Lite directory. Whenever you build, XCode will put those new resources in the same place where the full resources were and your code won&rsquo;t have to change one bit. This trick works even with xib files, which is great because I had to modify one of them to reduce the number of pots in the garden screen.</p>
<p>Once you have that set up, the rest is just a matter of deciding what functionality goes in the lite version and how it is presented. It can be as simple or as complex as you want.</p>
<p>In the case of Flower Garden, it was very straightforward. I limited the number of pots to two, and the number of different seeds to three. So I just had to change a few resources and add a couple of #ifdefs with the number of total pots and seeds. I also removed the resources that weren&rsquo;t used in the lite version (the seed data for all the unavailable seeds for example).</p>
<p>Flower Garden lite was finally approved and it has been available on the App Store for a few days. So far it has been downloaded several thousand times, it has been very well received, and has definitely bumped up the sales of the full version. Definitely a few hours well spent!</p>
<p>[1] The lite version took a couple of hours to create and a month to approve by Apple.</p>
<p>[2] It was something I wanted to have created from the beginning, but my hands were tied because email bouquets were being sent through my server and I had a maximum number of emails I was allowed to send per day because of spam limits. Fortunately, as soon as the 3.0 OS was released, apps were able to use in-app email and that restriction went away.</p>]]></content:encoded></item><item><title>At The Mercy of Apple's Whim</title><link>https://gamesfromwithin.com/at-the-mercy-of-apples-whim/</link><pubDate>Tue, 01 Sep 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/at-the-mercy-of-apples-whim/</guid><description>&lt;p&gt;We&amp;rsquo;ve known for a long time that Apple are king-makers when it comes to bringing up an app through the ranks of the App Store. A nice feature on the front page, and boom, guaranteed sales for at least a week. We&amp;rsquo;ve all complained at the randomness of it all, but we&amp;rsquo;ve all wished to be there. It&amp;rsquo;s random, but at least it&amp;rsquo;s something positive, so it&amp;rsquo;s a bit like winning the lottery.&lt;/p&gt;</description><content:encoded><![CDATA[<p>We&rsquo;ve known for a long time that Apple are king-makers when it comes to bringing up an app through the ranks of the App Store. A nice feature on the front page, and boom, guaranteed sales for at least a week. We&rsquo;ve all complained at the randomness of it all, but we&rsquo;ve all wished to be there. It&rsquo;s random, but at least it&rsquo;s something positive, so it&rsquo;s a bit like winning the lottery.</p>
<p>There&rsquo;s a darker side to Apple&rsquo;s randomness. Something developers have been complaining for quite a while and it&rsquo;s just getting worse: The approval process.</p>
<p>This is nothing new though. For a while developers have been reporting random rejections by Apple. Some of them extremely <a href="http://hiddenelephant.com/blog/2009/05/15/ridiculous-app-store-rejection/">unfair</a> and <a href="http://neverodd.wordpress.com/2009/02/23/apple-slays-the-dragon/">illogical</a>.</p>
<p>A few months ago, if you got hit with one of those random rejects, it was annoying, but it was bearable. Usually a resubmit would get approved in under a week, so it was possible to fix whatever random thing Apple flagged down (or show them that it wasn&rsquo;t an issue), and resubmit without wasting too much time.</p>
<p>Now things are different. Supposedly 95% of apps are approved (or rejected) under 14 days (although my <a href="http://bit.ly/iphoneapprovaltime">informal and biased survey</a> shows <a href="http://bit.ly/iphoneapprovalresults">very different percentages</a>). A mistake from Apple rejecting an app doesn&rsquo;t cost you a week anymore, but perhaps as much as an extra 3-4 weeks! That&rsquo;s a big deal for a company that&rsquo;s trying to time the release of a product.</p>
<p>So far, I had been one of the lucky developers and I never got a rejection from Apple with Flower Garden. Actually, updates were usually approved withing 7 days <strong>to the hour</strong> (very suspicious, isn&rsquo;t it?). But my luck ran out and I joined the group of developers hit hard by random and unfair updates.</p>
<p>Two days ago, Flower Garden 1.7, which had been in review for 24 days was rejected with the following explanation from Apple:</p>
<blockquote>
<p>Dear Noel,</p>
<p>Thank you for submitting Flower Garden to the App Store. We&rsquo;ve reviewed Flower Garden and determined that we cannot post this version of your iPhone application to the App Store because your application contains pricing information in the application, located in the &ldquo;More Games&rdquo; page. Providing specific pricing information in this location may lead to user confusion because of pricing differences in countries. It would be appropriate to remove pricing information from your application.</p>
<p>Once these modifications have been made please upload a new binary using iTunes Connect</p>
<p>Regards,</p>
<p>iPhone Developer Program</p>
</blockquote>
<p>I was completely floored when I read that email. So apparently displaying a web page with prices for other apps is not allowed unless you localize that based on the language settings of the iPhone. How many apps are doing that? I doubt many (any?) are doing it. I can certainly bring up piles and piles of other games that are showing non-localized prices. But precedence is clearly not an argument with Apple. Even previous versions of Flower Garden had that exact same view with prices and it wasn&rsquo;t a problem! Random reviewer strikes again.</p>
<p>But wait, there&rsquo;s more. The prices are shown on a web page fed through my server. I made that change in 30 seconds and emailed them back, hoping they could simply re-test that functionality and approve it on the spot. No, that would be too easy! I had to resubmit a new binary and start the approval process again! I just gave them the change to cut back their work to a fraction of the time (supposedly they had tested other things that they&rsquo;ll have to re-test because they have no way of knowing I didn&rsquo;t change/update anything else). Sigh! I resubmitted it and I&rsquo;m hoping for a quick approval, but somehow I&rsquo;m ready for another 24-day wait.</p>
<p>So this morning I was excited to receive another email from Apple, I open it and&hellip;</p>
<blockquote>
<p>Hello Noel,</p>
<p>Flower Garden Lite cannot be posted because it is a feature-limited version. Free or &ldquo;Lite&rdquo; versions are acceptable, however the application must be a fully functional app and cannot reference features that are not implemented or up-sell to the full version.</p>
<p>Users can view unlockable seeds on the &ldquo;Seeds&rdquo; tab but cannot access them in the Lite version of the application. Please refer to the attached screenshot for an example.</p>
<p>Please upload a new binary and correct metadata using iTunes Connect .</p>
<p>Regards,</p>
<p>iPhone Developer Program</p>
</blockquote>
<p>and they attached the following screenshot:</p>
<p><a href="/wp-content/uploads/2009/09/IMG_0014.PNG"><img alt="IMG_0014" loading="lazy" src="/at-the-mercy-of-apples-whim/images/IMG_0014.PNG" title="IMG_0014"></a></p>
<p>Users can be unlockable seeds but can&rsquo;t unlock them? If you follow the included tutorial (2 messages) you unlock the first one. Another message tells them that growing the second seed unlocks the last one. Did they read that, or did they see a locked seed and had a knee-jerk reaction?</p>
<p>I replied to their email right away and explained how to unlock them. I&rsquo;m afraid I&rsquo;ll get an email back tomorrow asking me to resubmit and throwing Flower Garden Lite at the back of the queue. I hope not, but I&rsquo;m prepared for the worst.</p>
<p>It might just be slightly annoying for hobbyist developers, but all of this is making the App Store very difficult to build a reliable, sustainable business around it. The lack of visibility, random approval process, unpredictability, and lack of direct contact make it impossible to have a reliable process or combine release dates with other events such as PR or marketing campaigns. At this point, I would even consider a &ldquo;professional&rdquo; iPhone developer account that costs $1K per year and gives you a direct contact in Apple and better visibility and predictability with the approval process. Otherwise, if things continue this way, I&rsquo;m afraid that professional developers will only put up with this for so long and are soon going to consider the iPhone as a secondary platform and they&rsquo;ll move on to other pastures like the PSP Mini or new opportunities that come up.</p>
]]></content:encoded></item><item><title>iSimulate: A Great Add-On For The iPhone Simulator</title><link>https://gamesfromwithin.com/isimulate-a-great-add-on-for-the-iphone-simulator/</link><pubDate>Fri, 28 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/isimulate-a-great-add-on-for-the-iphone-simulator/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/08/isimulate.png"&gt;&lt;img alt="isimulate" loading="lazy" src="https://gamesfromwithin.com/isimulate-a-great-add-on-for-the-iphone-simulator/images/isimulate.png" title="isimulate"&gt;&lt;/a&gt;I just had a chance to check out &lt;a href="http://www.vimov.com/isimulate/"&gt;iSimulate&lt;/a&gt;, a tool for iPhone developers created by &lt;a href="http://www.vimov.com/"&gt;Vimov&lt;/a&gt;. iSimulate is intended to complement the current iPhone simulator by adding most of the features a real iPhone has. In the spirit of full disclosure, Vimov sent me a promo code to try it out for free, but I only accepted it with the condition I could write my unfiltered impressions. So here we go.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/isimulate.png"><img alt="isimulate" loading="lazy" src="/isimulate-a-great-add-on-for-the-iphone-simulator/images/isimulate.png" title="isimulate"></a>I just had a chance to check out <a href="http://www.vimov.com/isimulate/">iSimulate</a>, a tool for iPhone developers created by <a href="http://www.vimov.com/">Vimov</a>. iSimulate is intended to complement the current iPhone simulator by adding most of the features a real iPhone has. In the spirit of full disclosure, Vimov sent me a promo code to try it out for free, but I only accepted it with the condition I could write my unfiltered impressions. So here we go.</p>
<p>iSimulate consists of two different parts: <a href="http://click.linksynergy.com/fs-bin/stat?id=aDkhM0mDflg&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;u1=gfw_isimulate&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252FWebObjects%252FMZStore.woa%252Fwa%252FviewSoftware%253Fid%253D306908756%2526mt%253D8%2526uo%253D6%2526partnerId%253D30">The iPhone app</a>, which you need to purchase through the App Store, and a static library that you link with your program. Once your app is using the library, launching the iSimulate iPhone app lets you connect your device to your app and forward accelerometer, touch, and GPS events. In other words, most of the things the simulator doesn&rsquo;t do natively.</p>
<p>iSimulate definitely passed my picky installation requirements with flying colors. I was afraid the installation would hook up with existing framework libraries, add new configurations, and in general mess up my system. Fortunately, hooking up the iSimulate library couldn&rsquo;t be easier: Copy the provided .a library anywhere you want, link with it in your app (don&rsquo;t forget the -ObjC linker flag), make sure you&rsquo;re using the Core framework, and you&rsquo;re good to go. That simple. That&rsquo;s how I want external libraries to work.</p>
<p>You don&rsquo;t even need to initialize anything. Just launch your app in the simulator, launch iSimulate on the iPhone and it detects your program running and lets you connect to it. The iPhone app itself even looks very pretty and polished. The overall package is definitely very professional-looking.</p>
<p>From there, any touch on the device is forwarded to the simulator. So you can finally do off-center multi touches, or two touches that happen at different times, or even 5-touch events (the max the iPhone support). The other big one is being able to tilt or shake your device and see the game react correctly on the simulator, which is would have been very handy when writing the accelerometer code to move flowers around in <a href="http://snappytouch.com/flowergarden">Flower Garden</a>, but would almost be necessary when you&rsquo;re making heavy use of accelerometer input for games like <a href="http://click.linksynergy.com/fs-bin/stat?id=aDkhM0mDflg&amp;u1=gfw_skyburger&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252FWebObjects%252FMZStore.woa%252Fwa%252FviewSoftware%253Fid%253D311972587%2526mt%253D8%2526uo%253D6%2526partnerId%253D30">Sky Burger</a>. Finally, it also claims to give you location information, but I didn&rsquo;t have an app I could easily test it with.</p>
<p><a href="/wp-content/uploads/2009/08/fg_accelerometer.jpg"><img alt="Flowers affected by gravity on the simulator" loading="lazy" src="/isimulate-a-great-add-on-for-the-iphone-simulator/images/fg_accelerometer.jpg" title="fg_accelerometer"></a></p>
<p><em>Flowers affected by gravity on the simulator</em></p>
<p>Another situation where iSimulate is a life savior is when trying to capture a video of your game. If you rely on multi touch or accelerometer features, then your only options are to either hack in something yourself, or dig out a physical video camera and record it the old-fashioned way (which is surprisingly time consuming and creates less-than-ideal results). With iSimulate you can still use a <a href="http://store.shinywhitebox.com/home/home.html">desktop video capture software</a> on the simulator and create a top-quality in a fraction of the time.</p>
<p>Not everything is perfect though. I thought the forwarding of touch events would be incredibly useful, until I realize I have no idea what I&rsquo;m about to tap because the program is running on the simulator, not on the device. So I&rsquo;m just making a guess about where my finger is going to land. It&rsquo;s not even like a mouse cursor that you see where it&rsquo;s going and then you click. You&rsquo;re literally tapping blind hoping you touch what you wanted. That works with a static UI, but if you have moving elements you need to touch, you&rsquo;re totally out of luck. I wonder if they could extend iSimulate to capture the image from the simulator and forward it to the iPhone. Even if they only refreshed the image a few times per second, that would be enough to make touch input a lot more friendly.</p>
<p>There&rsquo;s another big problem with touch input though. From their docs page, iSimulate works great with OpenGL apps, but doesn&rsquo;t work with the following UIKit controls: Keyboard, UIScrollView (including MKMapView), UIPickerView and UITableView. Wow! Apart from the keyboard one (no big deal, we have a real keyboard attached) the other ones are pretty major. I&rsquo;m sure they have a good reason why, but I can&rsquo;t imagine what that might be from my knowledge of how the touch even system works (anybody from Vimov care to comment on that?). Heck, I&rsquo;d even be willing to add some extra code to my app to hook directly into iSimulate input events if it means it would work with those classes. Apart from that, I found one case in Flower Garden where iSimulate failed: Touching the bouquet tag to bring up the editing mode. It&rsquo;s weird, it would let me touch-drag it to move it, but it wouldn&rsquo;t go into editing mode.</p>
<p>The accelerometer input worked flawlessly, but here iSimulate has some competition from <a href="http://code.google.com/p/accelerometer-simulator/wiki/Home">Accelerometer Simulator</a>, an open-source app plus library to forward accelerometer data from the device to the app. It&rsquo;s not nearly as slick as iSimulate, but it&rsquo;s free, so that migth be a more attractive solution for some people.</p>
<p>Overall, is iSimulate worth the $32 price tag (it&rsquo;s $15.99 at the moment)? I would say yes if you&rsquo;re developing OpenGL iPhone games with heavy use of multi touch and accelerometer input and you&rsquo;re planning on making money from them. In that case, you&rsquo;re better off spending an hour of your time polishing the game (or taking a break from programming) and buying iSimulate. However, if you&rsquo;re using UIKit objects or you just need accelerometer input, then you might be better off just using Accelerometer Simulator. If Vimov can fix the UIKit input and display the output of the simulator on the device, iSimulate would become an indispensable tool in every programmer&rsquo;s toolbox.</p>
]]></content:encoded></item><item><title>Early Bird Registration Ending For Denver OpenGL Class And 360iDev</title><link>https://gamesfromwithin.com/early-bird-registration-ending-for-denver-opengl-class-and-360idev/</link><pubDate>Thu, 27 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/early-bird-registration-ending-for-denver-opengl-class-and-360idev/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/08/OpenGL_iPhone.png"&gt;&lt;img alt="OpenGL_iPhone" loading="lazy" src="https://gamesfromwithin.com/early-bird-registration-ending-for-denver-opengl-class-and-360idev/images/OpenGL_iPhone.png" title="OpenGL_iPhone"&gt;&lt;/a&gt;For those of you still on the fence about attending my &lt;a href="http://www.mobileorchard.com/opengl"&gt;iPhone OpenGL class&lt;/a&gt; in Denver, you should sign up before this Sunday if you want to get the super-combo deal. Right now you get a total combined discount of over $300 if you sign up both for the OpenGL class and the &lt;a href="http://www.360idev.com/"&gt;360iDev conference&lt;/a&gt;. If you&amp;rsquo;re only interested in the OpenGL class, the early-bird registration ends next Friday, September 4th.&lt;/p&gt;
&lt;p&gt;Obviously I&amp;rsquo;m biased when I say the class is going to be awesome (which it is), but I can also say with total honesty that 360iDev is an incredible conference. It&amp;rsquo;s very different from &lt;a href="http://developer.apple.com/WWDC/"&gt;WWDC&lt;/a&gt;, but that&amp;rsquo;s what makes it so great: It has top-quality &lt;a href="http://www.360idev.com/sessionsschedules"&gt;content&lt;/a&gt; and &lt;a href="http://www.360idev.com/denver-2009-speakers"&gt;speakers&lt;/a&gt;, but it&amp;rsquo;s small and intimate, so you get to meet and hang out with all the other speakers and participants. It was at the first 360iDev conference back in March that I met &lt;a href="http://twitter.com/kshepherd"&gt;Keith&lt;/a&gt; and &lt;a href="http://twitter.com/owengoss"&gt;Owen&lt;/a&gt; (among &lt;a href="http://twitter.com/serban"&gt;many&lt;/a&gt; &lt;a href="http://twitter.com/byteclub"&gt;other&lt;/a&gt; &lt;a href="http://twitter.com/jasoncitron"&gt;cool&lt;/a&gt; &lt;a href="http://twitter.com/chews"&gt;developers&lt;/a&gt;) in person for the first time and that&amp;rsquo;s how &lt;a href="http://apptreasures.com"&gt;App Treasures&lt;/a&gt; was born.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/OpenGL_iPhone.png"><img alt="OpenGL_iPhone" loading="lazy" src="/early-bird-registration-ending-for-denver-opengl-class-and-360idev/images/OpenGL_iPhone.png" title="OpenGL_iPhone"></a>For those of you still on the fence about attending my <a href="http://www.mobileorchard.com/opengl">iPhone OpenGL class</a> in Denver, you should sign up before this Sunday if you want to get the super-combo deal. Right now you get a total combined discount of over $300 if you sign up both for the OpenGL class and the <a href="http://www.360idev.com/">360iDev conference</a>. If you&rsquo;re only interested in the OpenGL class, the early-bird registration ends next Friday, September 4th.</p>
<p>Obviously I&rsquo;m biased when I say the class is going to be awesome (which it is), but I can also say with total honesty that 360iDev is an incredible conference. It&rsquo;s very different from <a href="http://developer.apple.com/WWDC/">WWDC</a>, but that&rsquo;s what makes it so great: It has top-quality <a href="http://www.360idev.com/sessionsschedules">content</a> and <a href="http://www.360idev.com/denver-2009-speakers">speakers</a>, but it&rsquo;s small and intimate, so you get to meet and hang out with all the other speakers and participants. It was at the first 360iDev conference back in March that I met <a href="http://twitter.com/kshepherd">Keith</a> and <a href="http://twitter.com/owengoss">Owen</a> (among <a href="http://twitter.com/serban">many</a> <a href="http://twitter.com/byteclub">other</a> <a href="http://twitter.com/jasoncitron">cool</a> <a href="http://twitter.com/chews">developers</a>) in person for the first time and that&rsquo;s how <a href="http://apptreasures.com">App Treasures</a> was born.</p>
<p>So if you&rsquo;re on the fence, I hope you give it a try. See you in Denver!</p>
]]></content:encoded></item><item><title>Getting Started With Shaders On The iPhone 3GS</title><link>https://gamesfromwithin.com/getting-started-writing-shaders-on-the-iphone-3gs/</link><pubDate>Mon, 24 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/getting-started-writing-shaders-on-the-iphone-3gs/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/08/shader.jpg"&gt;&lt;img alt="shader" loading="lazy" src="https://gamesfromwithin.com/getting-started-writing-shaders-on-the-iphone-3gs/images/shader.jpg" title="shader"&gt;&lt;/a&gt;I just wrote &lt;a href="http://www.mobileorchard.com/getting-started-with-opengl-es-20-on-the-iphone-3gs"&gt;an article for Mobile Orchard&lt;/a&gt; on how to get started with OpenGL ES 2.0 on the iPhone 3GS. It goes over all the steps necessary to set up a barebones project that renders a quad on screen using a vertex and a fragment shader. It&amp;rsquo;s not the most stunning thing ever visually, but I think it makes for a good starting point for OpenGL ES 2.0 projects.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/shader.jpg"><img alt="shader" loading="lazy" src="/getting-started-writing-shaders-on-the-iphone-3gs/images/shader.jpg" title="shader"></a>I just wrote <a href="http://www.mobileorchard.com/getting-started-with-opengl-es-20-on-the-iphone-3gs">an article for Mobile Orchard</a> on how to get started with OpenGL ES 2.0 on the iPhone 3GS. It goes over all the steps necessary to set up a barebones project that renders a quad on screen using a vertex and a fragment shader. It&rsquo;s not the most stunning thing ever visually, but I think it makes for a good starting point for OpenGL ES 2.0 projects.</p>
]]></content:encoded></item><item><title>Handling App Store and LinkShare Links</title><link>https://gamesfromwithin.com/handling-app-store-and-linkshare-links/</link><pubDate>Sat, 15 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/handling-app-store-and-linkshare-links/</guid><description>&lt;p&gt;One of the perks of being part of the &lt;a href="http://apptreasures.com"&gt;App Treasures label&lt;/a&gt; is that we get some nice cross-promotion with an in-game view to display other titles in the label. This list is, of course, stored in our server and pulled in through a standard UIWebView. It links to other pages with details for each of our games, and a link to buy it directly from the App Store. Everything is really straightforward, except for the App Store link.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the perks of being part of the <a href="http://apptreasures.com">App Treasures label</a> is that we get some nice cross-promotion with an in-game view to display other titles in the label. This list is, of course, stored in our server and pulled in through a standard UIWebView. It links to other pages with details for each of our games, and a link to buy it directly from the App Store. Everything is really straightforward, except for the App Store link.</p>
<p><a href="/wp-content/uploads/2009/08/AppTreasuresWebView.jpg"><img alt="AppTreasuresWebView" loading="lazy" src="/handling-app-store-and-linkshare-links/images/AppTreasuresWebView.jpg" title="AppTreasuresWebView"></a></p>
<p>By default, the UIWebView will try to open the App Store link itself, which results in an error. What we want to do instead is intercept the request and launch it directly with an NSURLConnection so the call can be redirected to the iPhone App Store app. The best place to implement this is in the <code>-[UIWebViewDelegate webView:shouldStartLoadWithRequest:navigationType:]</code> method:</p>
<pre tabindex="0"><code>- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
    if ([[[request URL] host] isEqualToString:@&#34;phobos.apple.com&#34;])
    {
        NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[request URL]] delegate:self startImmediately:YES];
        [conn release];
        return NO;
    }
    return YES;
}
</code></pre><p>While we&rsquo;re in the topic of links, I also recently added some <a href="http://www.linkshare.com/">LinkShare</a> links to my apps. The 5% kickback for each purchase is nice, but the tracking capabilities it gives you is the real reason I wanted to use it. The way LinkShare works is by providing a custom URL that contains your referral ID to allow LinkShare to track the transaction. Unfortunately, unlike the Amazon referral program for example, LinkShare is a third party company and is not tied directly into the App Store. That means the links they provide go through click.linksynergy.com and then are redirected to the App Store. The result is that trying to follow one of those links from your app will result in Safari coming up, opening up a new page, shutting down, and then opening the App Store app. Not pretty!</p>
<p>Fortunately, there&rsquo;s a workaround. Just like we did with the App Store links, we can open the LinkShare link directly with a NSURLConnection instead of letting Safari handle it. Then, once the link resolves to the forwarded one, we can open it directly with the App Store app:</p>
<pre tabindex="0"><code>- (IBAction)buyItNow
{
    NSString* link = @&#34;http://click.linksynergy.com/fs-bin/click?........&#34;;
    NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:link]] delegate:self startImmediately:YES];
    [conn release];Â Â  Â 
}

- (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)response
{
    m_iTunesURL = [response URL];
    return request;
}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
    [[UIApplication sharedApplication] openURL:m_iTunesURL];
}
</code></pre><p>Voila! The user goes directly to the App Store page, there are no annoying Safari transitions, and you still get the referral bonus.</p>
<p>Incidentally, most of this is already documented in an <a href="https://developer.apple.com/iphone/library/qa/qa2008/qa1629.html">Apple Technical Q&amp;A note</a>, but it&rsquo;s kind of hidden away and I think most people don&rsquo;t know about it.</p>
<p>If you&rsquo;re using LinkShare, you should also check out <a href="http://www.mobileorchard.com/connecting-click-throughs-to-app-sales/">this post at Mobile Orchard</a>. One of the things I learned there was the use of the &amp;u1 parameter, which allows you to tag links with arbitrary information so you can track where purchases came from. Knowing where people are buying your app from is extremely helpful to know how to maximize sales!</p>
<p>[Edit: <a href="http://twitter.com/c99koder/status/3335554765">Sam Steele</a> pointed me to the <a href="http://github.com/c99koder/lastfm-iphone/blob/8f1630ed32e68e27042afc7d5abcb6846844963e/Classes/UIApplication+openURLWithWarning.m">source code for the Last.fm app</a> which handles all the URL redirects. Thanks!]</p>
]]></content:encoded></item><item><title>Environment Mapping Demo With OpenGL ES 1.1</title><link>https://gamesfromwithin.com/environment-mapping-demo-with-opengl-es-1-1/</link><pubDate>Sat, 01 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/environment-mapping-demo-with-opengl-es-1-1/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/08/Car.jpg"&gt;&lt;img alt="Car" loading="lazy" src="https://gamesfromwithin.com/environment-mapping-demo-with-opengl-es-1-1/images/Car.jpg" title="Car"&gt;&lt;/a&gt;I just finished creating a graphics demo for a chapter I&amp;rsquo;m writing for the book &lt;a href="http://www.amazon.com/iPhone-Advanced-Projects-Joachim-Bondo/dp/1430224037"&gt;iPhone Advanced Projects&lt;/a&gt; edited by Dave Mark. In the chapter I go over a few different lighting techniques and go in detail on how to do masked environment mapping on an iPhone 3G with OpenGL ES 1.1.&lt;/p&gt;
&lt;p&gt;The demo ended up looking pretty good, so I decided to upload a quick video showing the different lighting modes:&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/Car.jpg"><img alt="Car" loading="lazy" src="/environment-mapping-demo-with-opengl-es-1-1/images/Car.jpg" title="Car"></a>I just finished creating a graphics demo for a chapter I&rsquo;m writing for the book <a href="http://www.amazon.com/iPhone-Advanced-Projects-Joachim-Bondo/dp/1430224037">iPhone Advanced Projects</a> edited by Dave Mark. In the chapter I go over a few different lighting techniques and go in detail on how to do masked environment mapping on an iPhone 3G with OpenGL ES 1.1.</p>
<p>The demo ended up looking pretty good, so I decided to upload a quick video showing the different lighting modes:</p>
<ul>
<li>Diffuse texture only</li>
<li>Diffuse texture plus ambient and diffuse lighting</li>
<li>Diffuse texture plus ambient, diffuse, and specular lighting (as usually, per-vertex lighting looks pretty bad, even though this is a relatively high-poly model)</li>
<li>Fully reflective environment map (using the normal environment map technique)</li>
<li>Environment map added to the diffuse texture and lighting</li>
<li>Environment map with a reflection mask plus diffuse texture and lighting (two passes on an iPhone 3G&ndash;or one pass if you&rsquo;re not using the diffuse alpha channel)</li>
</ul>
<p>The chapter in the book will go in detail into each of those techniques, building up to the last one. Full source code will be included as well.</p>
<p>Some of these techniques will also be covered in my upcoming <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">Two Day iPhone OpenGL Class</a> organized in collaboration with <a href="http://www.mobileorchard.com/">Mobile Orchard</a>.</p>
]]></content:encoded></item><item><title>Targeting 2.x With 3.0 Features. Trouble Ahead.</title><link>https://gamesfromwithin.com/targeting-2-x-with-3-0-features-trouble-ahead/</link><pubDate>Fri, 31 Jul 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/targeting-2-x-with-3-0-features-trouble-ahead/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/07/iPhone-SDK-for-iPhone-OS-3-0-Beta-2-Released-Download-Here-2.png"&gt;&lt;img alt="iPhone-SDK-for-iPhone-OS-3-0-Beta-2-Released-Download-Here-2" loading="lazy" src="https://gamesfromwithin.com/targeting-2-x-with-3-0-features-trouble-ahead/images/iPhone-SDK-for-iPhone-OS-3-0-Beta-2-Released-Download-Here-2.png" title="iPhone-SDK-for-iPhone-OS-3-0-Beta-2-Released-Download-Here-2"&gt;&lt;/a&gt;As far as Apple goes, OS 2.x doesn&amp;rsquo;t exist anymore. That much was clear from WWDC when we asked their engineers any questions about it. And as cool as 3.0 is, with all the &lt;a href="http://www.apple.com/iphone/softwareupdate/"&gt;new nifty features&lt;/a&gt;, the reality is that there&amp;rsquo;s still a good percentage of (mostly iPod Touch) users out there still on 2.2. We can have our cake and eat it too by targeting 2.x and still using a few select 3.0 features. But it&amp;rsquo;s more complicated than Apple made it out to be. Trouble is looming just under the surface.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/07/iPhone-SDK-for-iPhone-OS-3-0-Beta-2-Released-Download-Here-2.png"><img alt="iPhone-SDK-for-iPhone-OS-3-0-Beta-2-Released-Download-Here-2" loading="lazy" src="/targeting-2-x-with-3-0-features-trouble-ahead/images/iPhone-SDK-for-iPhone-OS-3-0-Beta-2-Released-Download-Here-2.png" title="iPhone-SDK-for-iPhone-OS-3-0-Beta-2-Released-Download-Here-2"></a>As far as Apple goes, OS 2.x doesn&rsquo;t exist anymore. That much was clear from WWDC when we asked their engineers any questions about it. And as cool as 3.0 is, with all the <a href="http://www.apple.com/iphone/softwareupdate/">new nifty features</a>, the reality is that there&rsquo;s still a good percentage of (mostly iPod Touch) users out there still on 2.2. We can have our cake and eat it too by targeting 2.x and still using a few select 3.0 features. But it&rsquo;s more complicated than Apple made it out to be. Trouble is looming just under the surface.</p>
<h2 id="trouble-with-versions">Trouble With Versions</h2>
<p>When you install the 3.0 SDK and create a new project, it will be automatically set up to build only for 3.0. To target earlier versions while still having access to 3.0 features, you need to take a few extra step. These steps are described in detail in the readme of the <a href="http://developer.apple.com/iphone/library/samplecode/MailComposer/index.html">MailComposer sample</a> (iPhone dev account required). My friend <a href="http://hiddenelephant.com/blog/">Serban</a> also <a href="http://hiddenelephant.com/blog/2009/06/12/targeting-iphone-2x-on-snow-leopard-with-xcode-32/">wrote about how to do it when you add Snow Leopard to the mix</a>.</p>
<p>The required steps are:</p>
<ul>
<li>Under project properties, set up the Base SDK setting to be OS 3.0</li>
</ul>
<p><a href="/wp-content/uploads/2009/07/step1.png"><img alt="step1" loading="lazy" src="/targeting-2-x-with-3-0-features-trouble-ahead/images/step1.png" title="step1"></a></p>
<ul>
<li>Also in project properties, change the iPhone OS Deployment Target to OS 2.2 (or whichever version you want to target).</li>
</ul>
<p><a href="/wp-content/uploads/2009/07/step2.png"><img alt="step2" loading="lazy" src="/targeting-2-x-with-3-0-features-trouble-ahead/images/step2.png" title="step2"></a></p>
<ul>
<li>Go to target properties, and add a 3.0 library with the features you need. Make sure you set its type to Weak instead of Required.</li>
</ul>
<p><a href="/wp-content/uploads/2009/07/step4.png"><img alt="step4" loading="lazy" src="/targeting-2-x-with-3-0-features-trouble-ahead/images/step4.png" title="step4"></a></p>
<ul>
<li>In your code, check that a feature is available before using it. For example, you can do this check to see if the in-app mail functionality is available:</li>
</ul>
<pre tabindex="0"><code>Class mailClass = (NSClassFromString(@&#34;MFMailComposeViewController&#34;));
 return (mailClass != nil &amp;&amp; [mailClass canSendMail]);
</code></pre><ul>
<li>Make sure you set your app to build with the 3.0 SDK and off you go.</li>
</ul>
<p><a href="/wp-content/uploads/2009/07/step3.png"><img alt="step3" loading="lazy" src="/targeting-2-x-with-3-0-features-trouble-ahead/images/step3.png" title="step3"></a></p>
<p>If all goes well, it should run under 2.x and 3.0. If all goes well&hellip;</p>
<h2 id="trouble-with-libraries">Trouble With Libraries</h2>
<p>If that was the end of the story, then we would all be happy and I wouldn&rsquo;t have to write this entry. And for a while I really thought that was everything I had to do to get Flower Garden to use 3.0 features and still work on 2.x devices. Everything compiled fine, but when I went to run it on a 2.2 device, it crashed.</p>
<p>Looking at the crash logs, it was crashing inside a static library that used Objective C and UIKit. Digging further, it seemed that function calls were being sent to the wrong place. What was going on?</p>
<p>At this point I realized the root of this problem was the linker flags I was using. As soon as I started using the 3.0 SDK, I had to add the -all_load linker flag in order to be able to use the static library. I believe this loads all the symbols used by the libraries and links with them at link time. Without it, the library code would crash at runtime as soon as it was executed</p>
<p>The -all_load flag seems fine, except that the 2.x and 3.x versions of the SDK have different libraries and resolve symbols to different locations. So by doing -all_load, we&rsquo;re linking against the location of the 3.0 version and trying to run it on 2.x. Bad idea.</p>
<p>I thought long and hard on how to get around this. I came up with all sorts of crazy schemes, and after a couple frustrating days, I gave up. Then, all of a sudden, I realized that it had an embarrassingly simple solution: Don&rsquo;t use a library! I&rsquo;m not kidding. Just move the files in XCode directly into your main game target and you&rsquo;re done. No -all_load and everything works fine.</p>
<p>Yes, I&rsquo;m still embarrassed for not figuring that out after 30 seconds&hellip;</p>
<h2 id="trouble-with-compilers">Trouble With Compilers</h2>
<p>So all happy with that discovery, I rebuild and run the app and&hellip; crash again!</p>
<p>The call stack this time looked like this:</p>
<pre tabindex="0"><code>Thread 0 Crashed:
0Â Â  dyldÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  Â Â Â  Â 0x2fe01060 dyld_fatal_error + 0
1Â Â  dyldÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  Â Â Â  Â 0x2fe07ca8 dyld::bindLazySymbol(mach_header const*, unsigned long*) + 484
2Â Â  dyldÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  Â Â Â  Â 0x2fe15eb4 stub_binding_helper_interface + 12
</code></pre><p>What was going on in there? Some Googling and searching in the iPhone forum later, I learned that SDK 3.0 uses a different version of GCC (4.2 instead of 4.0). That means it will try to use some runtime functions that are not available with earlier versions. In particular, my crash was related to subtracting two uint64_t variables. Re-writing the code by casting the values to uint32_t before doing the operation fixed the problem. There&rsquo;s an ugly &ldquo;solution&rdquo; for you!</p>
<p>So how do you know if something will work on 2.0? I don&rsquo;t have a good answer for that other than test it as much as you can. Does someone have a better solution?</p>
<p>The good news is that, after I made those fixes, Flower Garden was happily running on 2.2 and 3.0. Now I can finally roll out in-app email without giving up on 2.x devices and cutting my potential customer base (or depriving current users of future updates).</p>
<h2 id="open-questions">Open Questions</h2>
<p>Going through this answered a few questions, but also created a few new ones. Maybe someone here will know the answer or will be able to point me in the right direction.</p>
<ul>
<li>Does anyone know how to <strong>debug</strong> your OS 3.0 app on the simulator set to 2.2? Whenever I launch it from the debugger, the simulator gets set to 3.0. Even if I set it to 2.2, I wonder if it will behave the same as a 2.2 device.</li>
<li>I&rsquo;ve heard rumours about somehow, packing two versions of the app in the same executable (kind of like the universal MacOS executables with both a PowerPC and an Intel version). Has anyone done something like that with the iPhone? Any docs on that?</li>
</ul>
]]></content:encoded></item><item><title>Balancing Flowers</title><link>https://gamesfromwithin.com/balancing-flowers/</link><pubDate>Wed, 29 Jul 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/balancing-flowers/</guid><description>&lt;p&gt;I feel bad for the &lt;a href="http://www.designer-notes.com/"&gt;designers&lt;/a&gt; of games like Civilization or Supreme Commander. And I don&amp;rsquo;t even want to think about World of Warcraft. I thought it was tricky to balance the different flowers in &lt;a href="http://snappytouch.com/flowergarden"&gt;Flower Garden&lt;/a&gt;, so I can only imagine the amount of time and effort than went into tweaking all the properties of the many dozens of units in those games to balance them just right.&lt;/p&gt;
&lt;p&gt;At first, things sounded simple enough: Create 20 different seeds, with varied looks and properties. I had &lt;a href="http://www.facebook.com/video/video.php?v=79362357780"&gt;a really cool tool to tweak the flower DNA in real time&lt;/a&gt; (more on that another day), so how hard could it be?&lt;/p&gt;</description><content:encoded><![CDATA[<p>I feel bad for the <a href="http://www.designer-notes.com/">designers</a> of games like Civilization or Supreme Commander. And I don&rsquo;t even want to think about World of Warcraft. I thought it was tricky to balance the different flowers in <a href="http://snappytouch.com/flowergarden">Flower Garden</a>, so I can only imagine the amount of time and effort than went into tweaking all the properties of the many dozens of units in those games to balance them just right.</p>
<p>At first, things sounded simple enough: Create 20 different seeds, with varied looks and properties. I had <a href="http://www.facebook.com/video/video.php?v=79362357780">a really cool tool to tweak the flower DNA in real time</a> (more on that another day), so how hard could it be?</p>
<p>The main properties I had to balance were amount of care required (as in, how often you had to water them before they would go dry) and how long the flower took to grow. The first few flowers came along just fine, but after the fifth or sixth seed, they all started blurring together. Did I have a fast-growing flower that needed a lot of care already? To get around this, I started writing all the seeds I had done so far and their characteristics in a text file so I could refer to them easily.</p>
<p>After a few more seeds, I knew I was in trouble again. Reading through all the flowers was a pain, but now I was starting to forget what they looked like. Did I already have an orange flower with a few, large petals? How about a small white one with lots of rounded petals and glossy leaves? The text file didn&rsquo;t cut it anymore, I had to go graphical. So I created a document with a picture of each flower along with all its relevant information (name, growth time, and amount of care).</p>
<p>This helped a lot, but it eventually became inadequate when I started creating the unlock conditions and balancing and the different seeds in order of difficulty. I just wasn&rsquo;t able to look at a list of 20 entries, each of them with 3 key elements (care, duration, and unlock condition) and keep it all in my head to make intelligent decisions based on it.</p>
<p>I&rsquo;m a very visually-oriented person. Whenever I can, I try to solve problem visually instead of memorizing lists or plugging equations. In particular, I love to take a multi-dimensional problem and visualize it along its main axes. So I took the next logical step to help me make sense of all that data and created a seed chart.</p>
<p><a href="/wp-content/uploads/2009/07/FlowerSequence.jpg"><img alt="FlowerSequence_s" loading="lazy" src="/balancing-flowers/images/FlowerSequence_s.jpg" title="FlowerSequence_s"></a></p>
<p>This seed chart is a two-dimensional arrangement of all the common seeds in the game, along with their picture and the key information we had before (there are another dozen bonus seeds that aren&rsquo;t listed in this chart). The horizontal axis indicates how much care a plant needs. Specifically, it shows how many segments in the water meter before it dries out (and each segment is 3 hours). The vertical axis indicates the growth duration for the plant in real time. Instead of making it a straight, linear scale, I decided to go with regions, which is how they are presented in the game (&ldquo;Instant&rdquo;, &ldquo;A few hours&rdquo;, &ldquo;Overnight&rdquo;, &ldquo;A few days&rdquo;, &ldquo;About a week&rdquo;, and &ldquo;Quite a while!&rdquo;). Within the region, they&rsquo;re roughly ordered by duration (shorter towards the top, longer towards the bottom).</p>
<p>Now it was really easy to see at a glance the key characteristics for each seed, see where I had clusters, and where I had empty spaces that no seeds were currently using. As a bonus, I was able to come up with a rough ordering indicating the level of difficulty for each seed. The further down and to the right a seed was, the more difficult it was to grow.</p>
<p>That allowed me to block out some regions (dotted red lines) indicating difficulty ratings, which are listed in the game in the seed information as &ldquo;Piece of cake&rdquo;, &ldquo;Easy&rdquo;, &ldquo;Moderate&rdquo;, &ldquo;Hard&rdquo;, or &ldquo;Experts only&rdquo;. Notice how the lines separating the regions are not parallel (even though the vertical axis is kind of logarithmic). That&rsquo;s because moving along the horizontal axis increases difficulty a lot faster than moving down the vertical axis. So even a relatively complex relationship like that can be observed at a glance from the chart.</p>
<p>Another great benefit of the seed chart is that I was able to draw paths between seeds, showing the unlocking relationships between them. Before it was hard to see these relationships in text, but now it was very visual, and I could make sure that easier flowers unlocked the path to harder ones as long as the unlock relationship flowed roughly from the top left to the bottom right.</p>
<p>As a side effect, the chart allowed me to learn even more things about the data than I had expected. For example, I was able to see which colors I had used so far, and which colors I still needed to use. One really interesting thing I noticed is that colors were clustering around specific areas. Red colors seemed to be mostly in the harder flowers. Yellow colors were predominant with the dry plants, and blue colors with the wetter ones. I thought that was pretty neat, so I tweaked a few seeds here and there to make that color connection even stronger.</p>
<p>The lesson learned here is that the old saying applies even more in this age of information: One picture is worth one mega of words.</p>
]]></content:encoded></item><item><title>Teaching a Two-Day OpenGL iPhone Class. Register Now!</title><link>https://gamesfromwithin.com/teaching-a-two-day-opengl-iphone-class-register-now/</link><pubDate>Thu, 23 Jul 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/teaching-a-two-day-opengl-iphone-class-register-now/</guid><description>&lt;p&gt;&lt;img alt="opengl" loading="lazy" src="https://gamesfromwithin.com/teaching-a-two-day-opengl-iphone-class-register-now/images/opengl.jpg" title="opengl"&gt;I&amp;rsquo;m excited to announce the &lt;a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/"&gt;intensive, two-day class on OpenGL for the iPhone&lt;/a&gt; that I&amp;rsquo;ll be teaching. The class will be held September 26th-27th, in Denver, right before the &lt;a href="http://www.360idev.com/"&gt;360iDev conference&lt;/a&gt;, and it&amp;rsquo;s part of the &lt;a href="http://www.mobileorchard.com/"&gt;Mobile Orchard Workshops&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The class is aimed at iPhone developers without previous OpenGL experience. It&amp;rsquo;s going to be very hands-on, and you&amp;rsquo;ll create both 2D and 3D applications during the weekend. You&amp;rsquo;ll learn all the basics: cameras, transforms, and how to draw meshes, but we&amp;rsquo;ll also cover some more advanced topics such as lighting, multitexturing, point sprites, and even render targets. Most importantly, you&amp;rsquo;ll walk away with a solid understanding of the basis, which will allow you to continue learning OpenGL and advanced computer graphics on your own from the docs, samples, or even browsing the API directly.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="opengl" loading="lazy" src="/teaching-a-two-day-opengl-iphone-class-register-now/images/opengl.jpg" title="opengl">I&rsquo;m excited to announce the <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">intensive, two-day class on OpenGL for the iPhone</a> that I&rsquo;ll be teaching. The class will be held September 26th-27th, in Denver, right before the <a href="http://www.360idev.com/">360iDev conference</a>, and it&rsquo;s part of the <a href="http://www.mobileorchard.com/">Mobile Orchard Workshops</a>.</p>
<p>The class is aimed at iPhone developers without previous OpenGL experience. It&rsquo;s going to be very hands-on, and you&rsquo;ll create both 2D and 3D applications during the weekend. You&rsquo;ll learn all the basics: cameras, transforms, and how to draw meshes, but we&rsquo;ll also cover some more advanced topics such as lighting, multitexturing, point sprites, and even render targets. Most importantly, you&rsquo;ll walk away with a solid understanding of the basis, which will allow you to continue learning OpenGL and advanced computer graphics on your own from the docs, samples, or even browsing the API directly.</p>
<p>The main requirement for the class is that you&rsquo;re familiar with the iPhone development environment and that you have basic knowledge of the C language. Beyond that, to the the most out of the course, you should be familiar with the basics of linear algebra (vector, matrices, and dot products). Anything else, we&rsquo;ll cover it all during the class.</p>
<p>Registration is now open, and you can get some great discounts by registering early and attending the 360iDev conference. For more details, check <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">the official announcement page</a>.</p>
<p>Hope to see some of you there!</p>
]]></content:encoded></item><item><title>Flower Garden Coverage and Interview on Spanish TV</title><link>https://gamesfromwithin.com/flower-garden-coverage-and-interview-on-spanish-tv/</link><pubDate>Tue, 21 Jul 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-coverage-and-interview-on-spanish-tv/</guid><description>&lt;p&gt;A couple of weeks ago I gave a presentation about iPhone development at &lt;a href="http://gamelab.es"&gt;Gamelab&lt;/a&gt;, the main game development conference in Spain (yes, it was my first technical presentation in Spanish!). Afterwards I was interviewed by &lt;a href="http://www.rtve.es/television/trasla2/zoom-net/"&gt;Zoom Net&lt;/a&gt;, a popular TV show about games and technology. Yesterday they aired the episode with my interview and I was pleasantly surprised to see they turned it into a &lt;a href="http://www.rtve.es/mediateca/videos/20090721/zoom-net-fifa-wii-sports-resort-juegos-para-moviles-20-07-2009/548164.shtml"&gt;full 4-minute section covering Flower Garden&lt;/a&gt;. Coverage starts at 8m 40s from the start (and, obviously, it&amp;rsquo;s in Spanish).&lt;/p&gt;</description><content:encoded><![CDATA[<p>A couple of weeks ago I gave a presentation about iPhone development at <a href="http://gamelab.es">Gamelab</a>, the main game development conference in Spain (yes, it was my first technical presentation in Spanish!). Afterwards I was interviewed by <a href="http://www.rtve.es/television/trasla2/zoom-net/">Zoom Net</a>, a popular TV show about games and technology. Yesterday they aired the episode with my interview and I was pleasantly surprised to see they turned it into a <a href="http://www.rtve.es/mediateca/videos/20090721/zoom-net-fifa-wii-sports-resort-juegos-para-moviles-20-07-2009/548164.shtml">full 4-minute section covering Flower Garden</a>. Coverage starts at 8m 40s from the start (and, obviously, it&rsquo;s in Spanish).</p>
<p><a href="http://www.rtve.es/mediateca/videos/20090721/zoom-net-fifa-wii-sports-resort-juegos-para-moviles-20-07-2009/548164.shtml"><img alt="noel_tv" loading="lazy" src="/flower-garden-coverage-and-interview-on-spanish-tv/images/noel_tv.jpg" title="noel_tv"></a></p>
<p>Notice the other iPhone games that flash at the start of the Flower Garden section: <a href="http://imangistudios.com/harbormaster/index.html">Harbor Master</a>, <a href="http://veiledgames.com/?page=upthere">Up There</a>, and <a href="http://imangistudios.com/littleredsled/index.html">Little Red Sled</a>, all <a href="http://apptreasures.com/">App Treasures</a> games! The video also starts with coverage of Fifa 10, so we&rsquo;re in pretty good company :-)</p>
]]></content:encoded></item><item><title>A Huge Leap Forward: Graphics on The iPhone 3G S</title><link>https://gamesfromwithin.com/a-huge-leap-forward-graphics-on-the-iphone-3g-s/</link><pubDate>Sat, 20 Jun 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/a-huge-leap-forward-graphics-on-the-iphone-3g-s/</guid><description>&lt;p&gt;I just wrote an article over at &lt;a href="http://www.mobileorchard.com"&gt;Mobile Orchard&lt;/a&gt; about &lt;a href="http://www.mobileorchard.com/a-huge-leap-forward-graphics-on-the-iphone-3gs"&gt;the new graphics capabilities on the new iPhone 3G S&lt;/a&gt;. Check it out to find out the details, and what those new features might mean for us developers.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I just wrote an article over at <a href="http://www.mobileorchard.com">Mobile Orchard</a> about <a href="http://www.mobileorchard.com/a-huge-leap-forward-graphics-on-the-iphone-3gs">the new graphics capabilities on the new iPhone 3G S</a>. Check it out to find out the details, and what those new features might mean for us developers.</p>
]]></content:encoded></item><item><title>Unveiling The App Treasures Indie iPhone Game Label</title><link>https://gamesfromwithin.com/unveiling-the-app-treasures-indie-iphone-game-label/</link><pubDate>Fri, 05 Jun 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/unveiling-the-app-treasures-indie-iphone-game-label/</guid><description>&lt;p&gt;&lt;img alt="apptreasureslogo_withcompanylogos" loading="lazy" src="https://gamesfromwithin.com/unveiling-the-app-treasures-indie-iphone-game-label/images/apptreasureslogo_withcompanylogos.png" title="apptreasureslogo_withcompanylogos"&gt;&lt;/p&gt;
&lt;p&gt;Today we finally unveiled a project we had been working on for a couple of months: The &lt;a href="http://apptreasures.com"&gt;App Treasures&lt;/a&gt; label.&lt;/p&gt;
&lt;p&gt;Only indie games that we consider to be really fun, polished, and of high quality are part of the label. We hope that when players enjoy one of our games, they can turn to the other App Treasures games and find something they like.&lt;/p&gt;
&lt;p&gt;With the App Store dominated more every day by big developers and publishers, this is a way for small indie developers to stand our ground. With App Treasures we establish a strong brand, share resources, and get more visibility in the App Store and in the eyes of the users. The same benefits we would get with a publisher, but without giving up our independence, creative freedom, or a percentage of the profits.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="apptreasureslogo_withcompanylogos" loading="lazy" src="/unveiling-the-app-treasures-indie-iphone-game-label/images/apptreasureslogo_withcompanylogos.png" title="apptreasureslogo_withcompanylogos"></p>
<p>Today we finally unveiled a project we had been working on for a couple of months: The <a href="http://apptreasures.com">App Treasures</a> label.</p>
<p>Only indie games that we consider to be really fun, polished, and of high quality are part of the label. We hope that when players enjoy one of our games, they can turn to the other App Treasures games and find something they like.</p>
<p>With the App Store dominated more every day by big developers and publishers, this is a way for small indie developers to stand our ground. With App Treasures we establish a strong brand, share resources, and get more visibility in the App Store and in the eyes of the users. The same benefits we would get with a publisher, but without giving up our independence, creative freedom, or a percentage of the profits.</p>
<p>The current App Treasures members are:</p>
<ul>
<li><a href="http://www.theblimppilots.com/">The Blimp Pilots</a> (Koi Pond, Distant Shore)</li>
<li><a href="http://www.imangistudios.com/">Imangi Studios</a> (Imangi, Word Squares, Little Red Sled)</li>
<li><a href="http://www.snappytouch.com/">Snappy Touch</a> (Flower Garden)</li>
<li><a href="http://www.streamingcolour.com/">Streaming Colour Studios</a> (Dapple)</li>
<li><a href="http://www.veiledgames.com/">Veiled Games</a> (Up There, Payday Roulette)</li>
</ul>
<p>You can read more details in <a href="http://www.appcraver.com/interview-with-app-treasures/">this interview I did for App Craver</a>. Mobile Orchard also published <a href="http://www.mobileorchard.com/app-treasures-indie-iphone-game-developers-school-of-fish/">a really good piece</a> with some interesting views and conclusions on App Treasures.</p>
<p>Oh, and don&rsquo;t forget to <a href="http://twitter.com/apptreasures">follow App Treasures on Twitter</a> to keep up with the latest news.</p>
]]></content:encoded></item><item><title>Virtual Memory Paging Is The Lazy Man's Caching Scheme</title><link>https://gamesfromwithin.com/virtual-memory-paging-is-the-lazy-mans-caching-scheme/</link><pubDate>Fri, 22 May 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/virtual-memory-paging-is-the-lazy-mans-caching-scheme/</guid><description>&lt;p&gt;One of the unintended side effects of &lt;a href="https://gamesfromwithin.com/i-want-my-memory-apple/"&gt;my previous post on the horrible memory situation on the iPhone&lt;/a&gt;, was that &lt;a href="https://gamesfromwithin.com/i-want-my-memory-apple/"&gt;some people pointed out&lt;/a&gt; it was possible to &lt;a href="https://devforums.apple.com/message/49187#49187"&gt;hook up a disk storage back end to the iPhone&amp;rsquo;s virtual memory system&lt;/a&gt;. That&amp;rsquo;s quite ironic because I think of it as compounding the already dismal situation rather than a solution or a even a stopgap measure.&lt;/p&gt;
&lt;p&gt;As far as I&amp;rsquo;m concerned, virtual memory paging is the lazy man&amp;rsquo;s caching scheme. There, I&amp;rsquo;ve said it. Now let me qualify it a bit and justify why I feel that way.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the unintended side effects of <a href="/i-want-my-memory-apple/">my previous post on the horrible memory situation on the iPhone</a>, was that <a href="/i-want-my-memory-apple/">some people pointed out</a> it was possible to <a href="https://devforums.apple.com/message/49187#49187">hook up a disk storage back end to the iPhone&rsquo;s virtual memory system</a>. That&rsquo;s quite ironic because I think of it as compounding the already dismal situation rather than a solution or a even a stopgap measure.</p>
<p>As far as I&rsquo;m concerned, virtual memory paging is the lazy man&rsquo;s caching scheme. There, I&rsquo;ve said it. Now let me qualify it a bit and justify why I feel that way.</p>
<p>A lot of applications, and especially games, can&rsquo;t keep in memory every bit of data they need for their execution. There&rsquo;s just too much data and not enough RAM to keep all the levels, all the textures, all the characters, and all the movies. Even the thought of keeping everything in memory is ridiculous. Instead, games are architected to strike a balance between memory usage and responsive interfaces. Usually that means loading levels, or parts of levels on demand, and keeping them in memory while they can be needed. Some other times it means loading levels of detail for textures, meshes, and animations depending on the player position.Â The point is, nobody knows as well as the game itself what needs to be in memory, what can be unloaded, and when the best time to do it is.</p>
<p>A different approach would be to ignore thinking about managing memory as a scarce resource and use as much of it as we need. If we ever go over the amount of available physical memory, the virtual memory system will kick in and page out memory to disk to make room for the memory we&rsquo;ve requested. But there lies the problem: The virtual memory system is a lower-level system that knows absolutely nothing about our game or application. It can only make guesses about what memory is OK to evict and when it&rsquo;s a good time to do it. If you&rsquo;re unlucky it will choose to page out memory when you need performance the most, and it might evict a page that you&rsquo;re about to use in a few milliseconds. If that happens, you can kiss your performance bye-bye.</p>
<p>Because of that, virtual memory paging will always do a much worse job than we could have done ourselves. But hey, it takes no effort or thinking on the part of the programmers, hence the &ldquo;lazy man&rsquo;s caching scheme&rdquo; I was referring to earlier.</p>
<p>However, virtual memory paging is sometimes a necessary evil. The assumption running through the previous three paragraphs is that we, as programmers of the game, can always manage the physical memory so our game runs efficiently on it. That is true for certain platforms, usually with fixed hardware specs, and ones with minimal or no background processes running. Game consoles are perfect examples of this: We know how much RAM we have to start, we know how much the system needs, how much video memory there is, and we can deal with the rest ourselves. We&rsquo;ll decide what to load and when to load it.</p>
<p>On something like a modern PC (whether it&rsquo;s Windows, Mac, Linux, or any other flavor), we have none of those guarantees. We don&rsquo;t know how much memory we&rsquo;re going to encounter when we run our game, and, what&rsquo;s even worse, we have no idea how that available memory is going to change during the execution of the program <a href="#1">[1]</a>. In a situation like that, we can plan for some minimum memory requirements, but we&rsquo;re going to need that virtual memory paging to bail us out of tricky low-memory situations. It might sound like a good idea, but that&rsquo;s one of the main reasons why PC games are often choppy and with inconsistent frame rates (buggy drivers being the other main reason).</p>
<p>Finally coming back to the iPhone, how does virtual memory paging fit there? There&rsquo;s no doubt that it would help because it would reduce the number of crashes due to programs unexpectedly running out of memory. But at the same time, it would cause most games and apps to be choppy and unresponsive, especially when it&rsquo;s just launched. But the iPhone is mostly a fixed spec platform, with minimal background processes <a href="#2">[2]</a>, so we can always do better than the dumb virtual memory system. Maybe that&rsquo;s not a big deal if you&rsquo;re writing an app that interfaces with a web site and writes data to a database, but it&rsquo;s crucial to be able to write responsible games, which are considered near real-time apps.</p>
<p>On the iPhone there should be no need for virtual memory paging (not to mention that it would probably drain the battery a lot faster). Instead of solving the memory problem by throwing more and more complex systems at it, what we really need is a guaranteed amount of memory for our app to run and we can take care of the rest. But Apple needs to take the first step and set that memory aside.</p>
<p>We&rsquo;re waiting, Apple.</p>
<p>[1] We could go totally hard core and allocate the memory we need and then mark it as not swappable by the virtual memory system. That wouldn&rsquo;t do any good because if other processes start requesting memory and they run out, the virtual memory system will swap out other pages (and possibly cause other processes to thrash) and kill our performance as well. So things are pretty much out of our hands as soon as virtual memory paging comes into play.</p>
<p>[2] There are a lot of background processes, but they should be relatively well-behaved. None of them should be pulling in massive amounts of data while the game is running.</p>
]]></content:encoded></item><item><title>Where'd That Memory Go?</title><link>https://gamesfromwithin.com/whered-that-memory-go/</link><pubDate>Fri, 15 May 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/whered-that-memory-go/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/i-want-my-memory-apple/"&gt;My re&lt;img alt="iphone_memory" loading="lazy" src="https://gamesfromwithin.com/whered-that-memory-go/images/iphone_memory.jpg" title="iphone_memory"&gt;cent rant&lt;/a&gt; about the dismal situation of memory in the iPhone quickly became quite popular. Most people were either unaware of the situation, or completely agreed that it was a major stumbling block for any app that tries to make good use of the hardware.&lt;/p&gt;
&lt;p&gt;As a response to that post, some people suggested some intriguing ways to increase the available memory on the iPhone. I&amp;rsquo;ve been experimenting with that a bit, but I don&amp;rsquo;t have any conclusive solutions yet. Right now it&amp;rsquo;s all totally unreliable hacks. Hopefully in a followup post I can present some solutions.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/i-want-my-memory-apple/">My re<img alt="iphone_memory" loading="lazy" src="/whered-that-memory-go/images/iphone_memory.jpg" title="iphone_memory">cent rant</a> about the dismal situation of memory in the iPhone quickly became quite popular. Most people were either unaware of the situation, or completely agreed that it was a major stumbling block for any app that tries to make good use of the hardware.</p>
<p>As a response to that post, some people suggested some intriguing ways to increase the available memory on the iPhone. I&rsquo;ve been experimenting with that a bit, but I don&rsquo;t have any conclusive solutions yet. Right now it&rsquo;s all totally unreliable hacks. Hopefully in a followup post I can present some solutions.</p>
<p>In the meanwhile, I wanted to talk about a piece of the puzzle, which is keeping track of the memory status on the iPhone. How much memory is available? How much memory does the program use? We need to be able to answer those questions accurately in order to do anything about memory. Unfortunately, there doesn&rsquo;t appear to be a good answer even for this!</p>
<h2 id="finding-total-memory">Finding Total Memory</h2>
<p>Let&rsquo;s start with the easy part: Finding the overall memory on the device. Right now all iPhones and iPod Touch models have 128MB RAM, so it&rsquo;s kind of pointless, but it&rsquo;s interesting anyway. To accomplish that we need to dig into some of the low-level functions that query hardware capabilities. In particular, the function sysctl() reports both physical memory and user memory.</p>
<pre tabindex="0"><code>    int mem;
Â    int mib[2];
   Â mib[0] = CTL_HW;
   Â mib[1] = HW_PHYSMEM;
   Â size_t length = sizeof(mem);
   Â sysctl(mib, 2, &amp;mem, &amp;length, NULL, 0);
   Â NSLog(@&#34;Physical memory: %.2fMB&#34;, mem/1024.0f/1024.0f);

    mib[1] = HW_USERMEM;
   Â length = sizeof(mem);
   Â sysctl(mib, 2, &amp;mem, &amp;length, NULL, 0);
   Â NSLog(@&#34;User memory: %.2fMB&#34;, mem/1024.0f/1024.0f);
</code></pre><p>The output of that code is:</p>
<pre tabindex="0"><code>Physical memory: 116.00MB
User memory: 91.30MB
</code></pre><p>Interesting. Physical memory is not quite reported as 128MB. That&rsquo;s probably because the video memory takes up 12MB of the total. The kernel apparently uses 24.7MB, which is not unreasonable if that was all the memory used by the OS. Unfortunately, that&rsquo;s only for the kernel. The different processes and apps are going to use up more than that. A LOT more than that.</p>
<p>Incidentally, sysctl() is a pretty rocking function. It will give you all sorts of cool information, such as CPU and bus frequency (412MHz and 103MHz respectively for my iPhone 3G), cache sizes, and whether a vector unit is present (it claims it isn&rsquo;t, so it must not be referring to the vfp).</p>
<h2 id="finding-available-memory">Finding Available Memory</h2>
<p>As cool a function as it is, sysctl() only returns static information about the hardware. If we want to find information about the current status of the memory, we need to look elsewhere.</p>
<p>As far as I can tell, the best function to get this information host_statistics() with HOST_VM_INFO_COUNT to get virtual memory statistics. Querying that function fills out the following structure:</p>
<pre tabindex="0"><code>struct vm_statistics {
    natural_t	free_count;		/* # of pages free */
    natural_t	active_count;		/* # of pages active */
    natural_t	inactive_count;		/* # of pages inactive */
    natural_t	wire_count;		/* # of pages wired down */
    natural_t	zero_fill_count;	/* # of zero fill pages */
    natural_t	reactivations;		/* # of pages reactivated */
    natural_t	pageins;		/* # of pageins */
    natural_t	pageouts;		/* # of pageouts */
    natural_t	faults;			/* # of faults */
    natural_t	cow_faults;		/* # of copy-on-writes */
    natural_t	lookups;		/* object cache lookups */
    natural_t	hits;			/* object cache hits */

    /* added for rev1 */
    natural_t	purgeable_count;	/* # of pages purgeable */
    natural_t	purges;			/* # of pages purged */

    /* added for rev2 */
   Â /*
     * NB: speculative pages are already accounted for in &#34;free_count&#34;,
     * so &#34;speculative_count&#34; is the number of &#34;free&#34; pages that are
     * used to hold data that was read speculatively from disk but
     * haven&#39;t actually been used by anyone so far.
     */
    natural_t	speculative_count;	/* # of pages speculative */
};
</code></pre><p>Lots of good info there! (at least for a hardware geek like me). The most interesting one is free_count. That number combined with the page size (which is defined in the handy global variable vm_page_size&ndash;which is unsurprisingly 4K on the iPhone) should give us the amount of available memory, right? Right?</p>
<p>Kind of. Unfortunately virtual memory is managed at many different levels. The OS will keep some pages on reserve to use on a rainy day. So it&rsquo;s possible that there is more memory available than reported in this function. It will however give you a good minimal bound on the amount of free memory. You can count on that amount for sure.</p>
<p>This function puts it together to return the amount of available memory in KB:</p>
<pre tabindex="0"><code>int getAvailableMemoryInKB()
{
    vm_statistics_data_t vmStats;
    mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
    kern_return_t kernReturn = host_statistics(mach_host_self(),
                             HOST_VM_INFO, (host_info_t)&amp;vmStats, &amp;infoCount);
    if(kernReturn != KERN_SUCCESS)
   Â     return -1;
    return (vm_page_size * vmStats.free_count) / 1024;
}
</code></pre><p>To check that available memory roughly matches what I do in the app, I allocate a 1MB block, run it again and&hellip; surprise! I get the same amount of memory available. Apparently the OS is waiting to actually set those memory pages aside until you really need them (I hate it when machines try to out-think me). So to really get them to count as allocated, we need to write to every page of the memory we just allocated. The easiest way is just go bzero(mem, 1024*1024);. Running the function again correctly shows that the available memory has gone down by 1MB.</p>
<h2 id="not-making-sense-of-used-and-total-memory">(Not) Making Sense Of Used and Total Memory</h2>
<p>An old habit I picked up during <a href="http://www.ecs.umass.edu/ece">my engineering days</a> is to always confirm my calculations through a different path. If the total amount of memory reported by the virtual memory system matched up with the total amount of memory reported by sysctl() I would leave this happy and be able to sleep soundly tonight.</p>
<p>The total amount of virtual memory is calculated by adding together the free, used, wired, and inactive pages. It should come up to be roughly around 91MB. The answer: 89MB. OK, close enough, right? Not really.</p>
<p>Here&rsquo;s the biggest mystery so far: If I malloc a chunk of memory (and write to it to have it marked as not available), host_statistics() correctly shows that those pages are not available anymore, but they don&rsquo;t show up as used, wired, or anything else!!! So simply adding free, used, wired, and inactive reports a totally bogus number that doesn&rsquo;t take into account allocations from your program. What&rsquo;s going on there? Obviously I&rsquo;m misunderstanding something, so maybe someone with more knowledge of kernel and vm features can help me out. Otherwise I won&rsquo;t be getting much sleep I&rsquo;m afraid :-)</p>
<p>Just to prove that I&rsquo;m not crazy, here&rsquo;s a code snippet and its output:</p>
<pre tabindex="0"><code>- (void)updateStatus
{
	vm_statistics_data_t vmStats;
	mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
	host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&amp;vmStats, &amp;infoCount);

	const int totalPages = vmStats.wire_count + vmStats.active_count +
                               vmStats.inactive_count + vmStats.free_count;
	const int availablePages = vmStats.free_count;
	const int activePages = vmStats.active_count;
	const int wiredPages = vmStats.wire_count;
	const int purgeablePages = vmStats.purgeable_count;

	NSMutableString* txt = [[NSMutableString alloc] initWithCapacity:512];
	[txt appendFormat:@&#34;Total: %d (%.2fMB)&#34;, totalPages, pagesToMB(totalPages)];
	[txt appendFormat:@&#34;nAvailable: %d (%.2fMB)&#34;, availablePages, pagesToMB(availablePages)];
	[txt appendFormat:@&#34;nActive: %d (%.2fMB)&#34;, activePages, pagesToMB(activePages)];
	[txt appendFormat:@&#34;nWired: %d (%.2fMB)&#34;, wiredPages, pagesToMB(wiredPages)];
	[txt appendFormat:@&#34;nPurgeable: %d (%.2fMB)&#34;, purgeablePages, pagesToMB(purgeablePages)];

	NSLog(txt);
	[txt release];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self updateStatus];
    const int sizeInBytes = 1024*1024;
    int* mem = (int*)malloc(sizeInBytes);
    bzero(mem, sizeInBytes);
   Â [self updateStatus];
}
</code></pre><p>And the output is:</p>
<pre tabindex="0"><code>Total: 22128 (86.44MB)
Available: 8124 (31.73MB)
Active: 6361 (24.85MB)
Wired: 6408 (25.03MB)
Purgeable: 359 (1.40MB)

Total: 21880 (85.47MB)
Available: 7888 (30.81MB)
Active: 6344 (24.78MB)
Wired: 6412 (25.05MB)
Purgeable: 359 (1.40MB)
</code></pre><p>Notice how the available pages go down by about 1MB but everything else stays about the same?</p>
<p>While we&rsquo;re at it, does someone know of a better, lower-level way to allocate memory than malloc()? I&rsquo;d like to just allocate memory pages directly. I looked into vm_allocate() but I wasn&rsquo;t able to get the correct port rights. Anyone?</p>
<p><strong>Update:</strong> Thanks to Colin for pointing out that <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/mmap.2.html">mmap</a> is the low-level memory allocation function I was looking for. You can allocate pages directly without going through malloc. Perfect!</p>
<h2 id="next-up">Next Up&hellip;</h2>
<p>This is a stepping stone towards the memory experiments I&rsquo;m running. In the next day or so I should be able to report some good ways to clear up as much memory as possible for our apps.</p>
]]></content:encoded></item><item><title>I Want My Memory, Apple!</title><link>https://gamesfromwithin.com/i-want-my-memory-apple/</link><pubDate>Thu, 07 May 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/i-want-my-memory-apple/</guid><description>&lt;p&gt;I love developing for the iPhone. It&amp;rsquo;s a really fun machine. Small enough to allow very small teams to &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301387274&amp;amp;mt=8"&gt;create&lt;/a&gt; &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311972587&amp;amp;mt=8"&gt;great&lt;/a&gt; &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=285820845&amp;amp;mt=8"&gt;apps&lt;/a&gt;, but at the same time powerful enough that you can do some &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=314297798&amp;amp;mt=8"&gt;really&lt;/a&gt; &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=299093633&amp;amp;mt=8"&gt;impressive&lt;/a&gt; &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=306811786&amp;amp;mt=8"&gt;games&lt;/a&gt;. The tools are great, the iteration time is great. It&amp;rsquo;s was a pleasure all around developing &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311265471&amp;amp;mt=8"&gt;Flower Garden&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Except when it comes to memory, that is.&lt;/p&gt;
&lt;p&gt;I really like most of the design calls that Apple made designing the software for the iPhone: Using C and Objective C (instead of Javascript or web-only apps), building it on top of a Unix-like core, and even providing OpenGL (although I would love to have lower-level access to the graphics hardware).&lt;/p&gt;</description><content:encoded><![CDATA[<p>I love developing for the iPhone. It&rsquo;s a really fun machine. Small enough to allow very small teams to <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301387274&amp;mt=8">create</a> <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311972587&amp;mt=8">great</a> <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=285820845&amp;mt=8">apps</a>, but at the same time powerful enough that you can do some <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=314297798&amp;mt=8">really</a> <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=299093633&amp;mt=8">impressive</a> <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=306811786&amp;mt=8">games</a>. The tools are great, the iteration time is great. It&rsquo;s was a pleasure all around developing <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311265471&amp;mt=8">Flower Garden</a>.</p>
<p>Except when it comes to memory, that is.</p>
<p>I really like most of the design calls that Apple made designing the software for the iPhone: Using C and Objective C (instead of Javascript or web-only apps), building it on top of a Unix-like core, and even providing OpenGL (although I would love to have lower-level access to the graphics hardware).</p>
<p>Developing for the iPhone is a mix of PC and game console development. One one side, it&rsquo;s a fairly open platform with standard APIs (like PCs), and on the other, it has (almost) fixed hardware <a href="#1">[1]</a> and a regulated distribution channel (like game consoles). I would even argue that the iPhone borrows the best of both worlds. When it comes to memory, however, the iPhone adopted the <strong>worst</strong> of both worlds. I feel that Apple completely dropped the ball there. Completely.</p>
<p>On a PC (whether it&rsquo;s Windows, Mac, Linux, or whatever), you can&rsquo;t count on having a fixed amount of memory. When your program runs, it can be running in a machine with RAM to spare, or in one with barely enough to run the OS. Or maybe it&rsquo;s running on a machine with enough RAM but there are fifty other programs running and there&rsquo;s no memory left for your program.</p>
<p>Fortunately (or unfortunately depending on your point of view), virtual memory allows the operating system to write memory pages back to disk and free up space for your program. Yes, it can cause the program to halt and crawl while memory is being paged out, but it will run. Definitely not an ideal solution for semi-real time applications like games. That&rsquo;s one of the main causes for choppy, underperforming PC games, but it has worked for many years and will do in a pinch.</p>
<p><img alt="prod_103276" loading="lazy" src="/i-want-my-memory-apple/images/prod_103276.jpg" title="prod_103276">On consoles on the other hand, you have a fixed amount of RAM from the start. You know what that amount is, and you can plan for it. In this latest generation of consoles, you still need to give up part of that precious memory to some other processes for user interface and network updates, but even that amount is known ahead of time. You can plan for it, and make your game fit in the memory that you have left.</p>
<p>The iPhone memory situation is&hellip; a mess. It&rsquo;s like a console in that you have a fixed amount of RAM: 128 MB (although I&rsquo;m sure Apple doesn&rsquo;t want developers thinking about it so they can roll out iPhones with more memory without affecting existing programs). Because it has a fixed amount of RAM, the iPhone doesn&rsquo;t provide virtual memory swapping <a href="#2">[2]</a>. So far so good. But here&rsquo;s the kicker: Unlike a game console, the iPhone makes no guarantees about how much memory your application has available when it runs.</p>
<p>Let me say that again: You&rsquo;re dealing with a fixed-memory environment and you have no way of knowing how much memory will be available to you. Did that sink in yet?</p>
<p>So how are you supposed to deal with that? Apple wants us to be able to dynamically load and unload anything in our programs in response to low-memory warning events. That might work well if you&rsquo;re loading web pages and just need to unload some cached ones, but that&rsquo;s far from ideal for games. What are you going to do? Unload part of the level? Get rid of some sounds? Not every game can do that, and even if you could, it would add a huge amount of complexity to something that should be pretty simple.</p>
<p>You can&rsquo;t even plan on using a fixed minimum amount of memory. From my experiments on my iPhone 3G, it seems that it&rsquo;s relatively safe to use between 15 to 18MB. Any more than that, and you start getting low memory warnings, and unless you program does something about it, the OS will promptly terminate you. On an iPod Touch, since it&rsquo;s not running as many background services, you usually have more memory available. I learned that the hard way, because I developed most of Flower Garden on an iPod Touch, only to find out that it was too slow and running out of memory on the iPhone 3G.</p>
<p>And this is out of a total of 128MB. Where did the rest of the memory go? Come on, even with phone, GPS, and music processes in the background, where did the rest of the memory go? Probably the worse culprits are the mail program and Safari, which are left in memory even after you exit back to the springboard (Bad design decision, no cookie!).</p>
<p>And what exactly does it mean &ldquo;to do something about it&rdquo; when you get a low-memory warning? You&rsquo;re supposed to free up as much memory as you can, but is it enough? Who knows! Maybe you free up one megabyte but the OS still decides that you&rsquo;re taking too much memory and it will kill you anyway. It seems like the worst memory handling scheme ever designed.</p>
<p>As an extreme situation, I have seen as little as 3.5MB available when starting my own program! What are you supposed to do in that case? Most games will just crash back to the springboard. Want to test this? Launch Safari, load 10-15 heavy web pages, quit, and then launch your favorite game. A crash is almost guaranteed. For my next project, I&rsquo;ll be tempted to respond to a low-memory warning by killing the Safari and Mail processes. That will free up some memory!</p>
<p><img alt="fg_seeds" loading="lazy" src="/i-want-my-memory-apple/images/fg_seeds.png" title="fg_seeds">To make matters worse, I had the bright idea of <a href="/remixing-opengl-and-uikit/">combining OpenGL and UIKit</a> for Flower Garden. Some things worked really well, like being able to quickly create some screens with Interface Builder and take advantage of all of Apple&rsquo;s UI widgets and fonts. Creating the seeds screen or the settings panel was a breeze with UIKit. However, UIKit uses an undetermined amount of memory behind the scenes, which makes all attempts at staying below a certain memory threshold pure black magic. In particular, drawing images to a context apparently causes mysterious caching of bitmaps taking huge performance hits and memory chunks over which we have no control. And game programmers don&rsquo;t like to feel they have no control over what&rsquo;s happening!</p>
<p>Another consequence of such a horrible memory situation is that game developers aren&rsquo;t able to make full use of the resources available. If we&rsquo;re aiming for 15MB, but have to drop back to 5-8MB, most developers are not going to try to write a game that uses 30 or 40MB (which <em>might</em> be available). What a shame!</p>
<p>I&rsquo;ve said before that the iPhone very closely resembles the great <a href="http://en.wikipedia.org/wiki/Dreamcast">Sega Dreamcast</a> (which is my favorite game console of all time). The Dreamcast only had 16MB of main RAM and 8MB of video RAM, but the best games on the iPhone, still pale in comparison to the best Dreamcast games. Why? Mostly because of the memory situation. If we had a guaranteed 16MB of RAM and the possibility of using all the extra free memory, iPhone games would look very, very differently.</p>
<p><strong>My plea to Apple:</strong> Please, give us some minimum memory guarantees for OS3.0! That, more than anything else, will make the biggest difference in the look and reliability of future games.</p>
<p>[1] There are slight differences between iPhone 2G, 3G, iPod Touch 1st and 2nd gen (especially the latter, which has a faster CPU and faster file system).</p>
<p>[2] It has virtual memory in the sense that there&rsquo;s a paging system with virtual addressing (so two memory pages far apart in real memory could be made to seem to be continuous), but there is no automatic paging in and out of memory pages to/from disk.</p>
]]></content:encoded></item><item><title>April San Diego iPhone Developers Meet Up</title><link>https://gamesfromwithin.com/april-san-diego-iphone-developers-meet-up/</link><pubDate>Thu, 16 Apr 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/april-san-diego-iphone-developers-meet-up/</guid><description>&lt;p&gt;Come join us for the next iPhone developers meet-up. This should be an interesting one with lots of things to share after GDC and the launch of several local apps (&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311972587&amp;amp;mt=8"&gt;Sky Burger&lt;/a&gt;, &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=310314279&amp;amp;mt=8"&gt;Appy Newz&lt;/a&gt;, &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311265471&amp;amp;mt=8"&gt;Flower Garden&lt;/a&gt; and more!).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: April Wednesday 22nd at 7:30PM until whenever &lt;strong&gt;Where:&lt;/strong&gt; &lt;a href="http://tinyurl.com/bcmkwj"&gt;Oâ€™Sullivanâ€™s Pub in Carlsbad&lt;/a&gt; (home of the &lt;a href="http://www.appyentertainment.com/"&gt;Appy Entertainment Secret World Headquarters&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Appy is being a great host again and providing some munchies. You&amp;rsquo;re responsible for your own drinks though :-)&lt;/p&gt;</description><content:encoded><![CDATA[<p>Come join us for the next iPhone developers meet-up. This should be an interesting one with lots of things to share after GDC and the launch of several local apps (<a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311972587&amp;mt=8">Sky Burger</a>, <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=310314279&amp;mt=8">Appy Newz</a>, <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311265471&amp;mt=8">Flower Garden</a> and more!).</p>
<p><strong>When</strong>: April Wednesday 22nd at 7:30PM until whenever <strong>Where:</strong> <a href="http://tinyurl.com/bcmkwj">Oâ€™Sullivanâ€™s Pub in Carlsbad</a> (home of the <a href="http://www.appyentertainment.com/">Appy Entertainment Secret World Headquarters</a>)</p>
<p>Appy is being a great host again and providing some munchies. You&rsquo;re responsible for your own drinks though :-)</p>
<p>Hope to see you there!</p>
]]></content:encoded></item><item><title>Interview at The Mobile Orchard Podcast</title><link>https://gamesfromwithin.com/interview-at-the-mobile-orchard-podcast/</link><pubDate>Mon, 13 Apr 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/interview-at-the-mobile-orchard-podcast/</guid><description>&lt;p&gt;The &lt;a href="http://www.mobileorchard.com/interview-with-consolepc-game-developer-turned-iphone-indie-noel-llopis/"&gt;latest podcast from Mobile Orchard&lt;/a&gt; covers my interview describing my experience as an indie iPhone developer and how Flower Garden was developed. I was particularly pleased when Dan Grigsby invited me to do the interview because the &lt;a href="http://www.mobileorchard.com/category/podcast/"&gt;Mobile Orchard podcast&lt;/a&gt; is one of the two podcasts I listen regularly (the other one being &lt;a href="http://www.ted.com/index.php/talks"&gt;TED Talks&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The interview topics range from high-level topics like business aspects of iPhone development, down to the nitty-gritty of how the procedural flowers were created, or how I had to use assembly language to take advantage of the vector floating point processor on the iPhone to do all the heavy lifting for matrix transforms.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The <a href="http://www.mobileorchard.com/interview-with-consolepc-game-developer-turned-iphone-indie-noel-llopis/">latest podcast from Mobile Orchard</a> covers my interview describing my experience as an indie iPhone developer and how Flower Garden was developed. I was particularly pleased when Dan Grigsby invited me to do the interview because the <a href="http://www.mobileorchard.com/category/podcast/">Mobile Orchard podcast</a> is one of the two podcasts I listen regularly (the other one being <a href="http://www.ted.com/index.php/talks">TED Talks</a>).</p>
<p>The interview topics range from high-level topics like business aspects of iPhone development, down to the nitty-gritty of how the procedural flowers were created, or how I had to use assembly language to take advantage of the vector floating point processor on the iPhone to do all the heavy lifting for matrix transforms.</p>
]]></content:encoded></item><item><title>Flower Garden Released!</title><link>https://gamesfromwithin.com/flower-garden-released/</link><pubDate>Sat, 11 Apr 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-released/</guid><description>&lt;p&gt;&lt;a href="http://snappytouch.com/flowergarden"&gt;&lt;/a&gt;&lt;a href="http://snappytouch.com/flowergarden"&gt;&lt;img alt="fg_icon_rounded_s" loading="lazy" src="https://gamesfromwithin.com/flower-garden-released/images/fg_icon_rounded_s.png" title="fg_icon_rounded_s"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://snappytouch.com/flowergarden"&gt;Flower Garden&lt;/a&gt; was finally approved and it&amp;rsquo;s available right now! This is what I&amp;rsquo;ve been pouring my heart and soul for the last six months. You can &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311265471&amp;amp;mt=8"&gt;buy it directly from the App Store&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you like it and would like to help out, here are some of the things you can do to promote it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go back to iTunes and write a fair review&lt;/li&gt;
&lt;li&gt;Grow flowers and send bouquets to your friends&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="http://www.facebook.com/group.php?gid=89055267811"&gt;Flower Garden group on Facebook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tell all your friends how great it is :-)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks everybody for all the encouragement and support along the way. I hope you enjoy playing it as much as I enjoyed creating it.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="http://snappytouch.com/flowergarden"></a><a href="http://snappytouch.com/flowergarden"><img alt="fg_icon_rounded_s" loading="lazy" src="/flower-garden-released/images/fg_icon_rounded_s.png" title="fg_icon_rounded_s"></a></p>
<p><a href="http://snappytouch.com/flowergarden">Flower Garden</a> was finally approved and it&rsquo;s available right now! This is what I&rsquo;ve been pouring my heart and soul for the last six months. You can <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311265471&amp;mt=8">buy it directly from the App Store</a>.</p>
<p>If you like it and would like to help out, here are some of the things you can do to promote it:</p>
<ul>
<li>Go back to iTunes and write a fair review</li>
<li>Grow flowers and send bouquets to your friends</li>
<li>Join the <a href="http://www.facebook.com/group.php?gid=89055267811">Flower Garden group on Facebook</a></li>
<li>Tell all your friends how great it is :-)</li>
</ul>
<p>Thanks everybody for all the encouragement and support along the way. I hope you enjoy playing it as much as I enjoyed creating it.</p>
<p>And don&rsquo;t worry, this is just the beginning. I have lots of updates planned, so keep an eye out for lots of fun new features!</p>
]]></content:encoded></item><item><title>Flower Garden: In Review</title><link>https://gamesfromwithin.com/flower-garden-in-review/</link><pubDate>Thu, 09 Apr 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-in-review/</guid><description>&lt;p&gt;&lt;img alt="review1" loading="lazy" src="https://gamesfromwithin.com/flower-garden-in-review/images/review1.png" title="review1"&gt;&lt;/p&gt;
&lt;p&gt;With all the excitement last week with GDC and the last push for Flower Garden, I completely forgot to announce that I submitted Flower Garden to Apple last Friday. It&amp;rsquo;s currently listed &amp;ldquo;In Review&amp;rdquo; and hopefully, if all goes well, will be available on the App Store either this weekend or early next week. Keeping my fingers crossed!&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="review1" loading="lazy" src="/flower-garden-in-review/images/review1.png" title="review1"></p>
<p>With all the excitement last week with GDC and the last push for Flower Garden, I completely forgot to announce that I submitted Flower Garden to Apple last Friday. It&rsquo;s currently listed &ldquo;In Review&rdquo; and hopefully, if all goes well, will be available on the App Store either this weekend or early next week. Keeping my fingers crossed!</p>
]]></content:encoded></item><item><title>GDC 2009: iPhone Development: Exploring The New Frontier</title><link>https://gamesfromwithin.com/gdc-2009-iphone-development-exploring-the-new-frontier/</link><pubDate>Wed, 08 Apr 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-2009-iphone-development-exploring-the-new-frontier/</guid><description>&lt;p&gt;Things have been so busy ever since I got back from GDC that I never got a chance to upload the slides for my GDC presentation. So here they are. You can &lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/04/gdc09_llopis_iphone.key"&gt;download the Keynote file directly from here&lt;/a&gt;, or &lt;a href="http://www.slideshare.net/llopis/gdc-2009-iphone-development-exploring-the-new-frontier"&gt;view it online&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The presentation went very well. The room was *completely* packed, with every seat taken and people standing along the walls. In retrospect I shouldn&amp;rsquo;t be surprised because it was the only iPhone presentation in the main GDC conference. Clearly there is a huge amount of interest in the platform. I&amp;rsquo;m already pushing to have a lot more iPhone content for next year, so you can all look forward to that.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Things have been so busy ever since I got back from GDC that I never got a chance to upload the slides for my GDC presentation. So here they are. You can <a href="/wp-content/uploads/2009/04/gdc09_llopis_iphone.key">download the Keynote file directly from here</a>, or <a href="http://www.slideshare.net/llopis/gdc-2009-iphone-development-exploring-the-new-frontier">view it online</a>.</p>
<p>The presentation went very well. The room was *completely* packed, with every seat taken and people standing along the walls. In retrospect I shouldn&rsquo;t be surprised because it was the only iPhone presentation in the main GDC conference. Clearly there is a huge amount of interest in the platform. I&rsquo;m already pushing to have a lot more iPhone content for next year, so you can all look forward to that.</p>
<p>Because it was the only iPhone presentation in the main GDC, I had to keep it very high-level and focused on the question of &ldquo;what can you expect if you switch to develop games on the iPhone&rdquo;? Not like I can really answer that, but at least I can share what my experience was. Hopefully next year I can really dive into some juicy tech topics.</p>
<p>In the meanwhile, if you&rsquo;re dying for some more technical content, go check out my latest column in <a href="http://gdmag.com/homepage.htm">Game Developer Magazine</a> dealing with multi-touch input devices with the lessons I learned from Flower Garden.</p>
<p><a href="/wp-content/uploads/2009/04/gdc09_llopis_iphone.key"><img alt="pres" loading="lazy" src="/gdc-2009-iphone-development-exploring-the-new-frontier/images/pres.jpg" title="pres"></a></p>
<p><strong>Update</strong>: <a href="http://sites.google.com/a/aribraginsky.com/gdc09/">Ari Braginsky</a> recorded the audio of the session (<a href="http://sites.google.com/a/aribraginsky.com/gdc09/audio/20090326-3-iPhoneDevelopment-ExploringtheNewFrontier-NoelLlopis-Part1of2.wma?attredirects=0">part 1</a> and <a href="http://sites.google.com/a/aribraginsky.com/gdc09/audio/20090326-3-iPhoneDevelopment-ExploringtheNewFrontier-NoelLlopis-Part2of2.wma?attredirects=0">part 2</a>), so if you want, you can follow along with the slides. Thanks Ari! I believe that the synced audio and slides will be available through the GDC web site for registered attendees too.</p>
]]></content:encoded></item><item><title>The Importance Of First Impressions</title><link>https://gamesfromwithin.com/the-importance-of-first-impressions/</link><pubDate>Mon, 23 Mar 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-importance-of-first-impressions/</guid><description>&lt;p&gt;A few weeks ago, I set as my drop-dead, better-be-done-or-I-kill-myself date for Flower Garden to be March 20th. The date getting closer allowed me to focus and put a huge, hard effort. Since I got back from &lt;a href="http://www.360idev.com/"&gt;360iDev&lt;/a&gt;, I&amp;rsquo;ve been working between 18 and 20 hours per day. Yes, that&amp;rsquo;s pretty crazy, but it actually didn&amp;rsquo;t feel like a strain because a) I love doing this and b) I can do it from the comfort of my own home. But that&amp;rsquo;s the topic for another post.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A few weeks ago, I set as my drop-dead, better-be-done-or-I-kill-myself date for Flower Garden to be March 20th. The date getting closer allowed me to focus and put a huge, hard effort. Since I got back from <a href="http://www.360idev.com/">360iDev</a>, I&rsquo;ve been working between 18 and 20 hours per day. Yes, that&rsquo;s pretty crazy, but it actually didn&rsquo;t feel like a strain because a) I love doing this and b) I can do it from the comfort of my own home. But that&rsquo;s the topic for another post.</p>
<p>The point is that as March 20th approached, I was slaying bugs left and right. Flower Garden went through two rounds of beta testing and it had some great feedback. All the crash bugs and top priority tasks were done and taken care of a few days before the deadline. Things were looking good for a submission to Apple on the expected date! Yay!</p>
<p><img alt="fg" loading="lazy" src="/the-importance-of-first-impressions/images/fg.png" title="fg">Then, with just a day to go, I decided to step back a second. Something had been nagging at me for a bit and I had to be honest with myself. Yes, all the crashing bugs and major features were taken care of. But how come my <a href="http://trac.edgewall.org/">issue tracking system</a> still had 50 entries in it marked as &ldquo;Final release&rdquo;? It wasn&rsquo;t a big deal. Those were all marked as &ldquo;low priority&rdquo; or &ldquo;trivial&rdquo;. And that&rsquo;s the great thing about the iPhone, I can submit the application and then start pushing out updates as I get to the little stuff. Right? Right?</p>
<p>This wasn&rsquo;t a case of taking <a href="http://goldenboat.wordpress.com/2009/02/25/the-old-yeller-method-of-game-development/">Old Yeller behind the shed</a>. The app was looking good. Really good. And it wasn&rsquo;t just a puppy, but a fully grown, beautiful app. It&rsquo;s just that it was a bit&hellip; slow and rough around the edges.</p>
<p>This is were things got really tough for me. On one hand, I was ready to ship this baby. I have been working on it for almost six months (where did time go??) and a lot of people were loving it. But when I allowed myself to give it one hard look, I realized that the experience I was hoping for wasn&rsquo;t there. Yes, the functionality was there, but not the experience. With a tool that gets a job done, maybe that&rsquo;s not a huge deal. But Flower Garden is all about the experience.</p>
<p>I tried to rationalize it by thinking how I could get all those little, low priority things done in an update right away: Improving the performance of the rendering, making the transitions more responsive, adding those subtle animations and sounds, making load times shorter&hellip; In short, it was missing the key ingredient to a successful experience: polish. I could always add that polish later, but what about all the people who bought it right away? What kind of impression were they going to get? In a <a href="http://apple20.blogs.fortune.cnn.com/2009/03/05/apples-app-store-25000-apps-and-counting/">saturated market</a> like the iPhone App Store, and especially with a title aimed at a casual audience, first impressions are everything. If people don&rsquo;t fall in love with your product right away, you might not get a second chance.</p>
<p>So it was with a very heavy heart that I decided to slip my target date. I really needed one more week to get to the point that Flower Garden could be the experience I had envisioned. And of course, to make it twice as hard, this coming week it&rsquo;s <a href="http://gdconf.com">GDC</a>, so that means that the release date is pushed out two weeks.</p>
<p>Coming from the console world, where updating your game is a rare opportunity and you better get everything right for the big release,I was really counting on releasing frequent updates. Does it mean that updates are useless in the App Store? That we shouldn&rsquo;t take advantage of them? Not at all. I realized that I was looking at them the wrong way. Updates are supposed to provide bug fixes and new functionality. They are <strong>not</strong> a crutch for sloppy development and an excuse to release products before they&rsquo;re ready.</p>
<p>Now I have regrouped. Reassessed where I&rsquo;m at, and prepared the final plan of attack. If all goes well, I will be submitting Flower Garden to the App Store the last week of Mark/beginning of April. When exactly? When it&rsquo;s ready. Lesson learned.</p>
]]></content:encoded></item><item><title>iPhone Developer Program Gotchas (or what I learned the hard way)</title><link>https://gamesfromwithin.com/iphone-developer-program-gotchas/</link><pubDate>Wed, 11 Mar 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/iphone-developer-program-gotchas/</guid><description>&lt;p&gt;One of the most confusing parts of iPhone development is dealing with the &lt;a href="http://developer.apple.com/iphone/manage/overview/index.action"&gt;iPhone Developer Program&lt;/a&gt; side of things. You know, all that fun stuff with certificates, devices, provisioning profiles, distribution profiles, etc. Oh, the hours of &amp;ldquo;fun&amp;rdquo; you can spend with that.&lt;/p&gt;
&lt;p&gt;Last night was particularly frustrating because I had just called it &amp;ldquo;beta&amp;rdquo; on Flower Garden and celebrated with the requisite victory dance, when the fun of sending out the beta build started. What I thought would be a ten-minute task, turned into a long nightmare and I didn&amp;rsquo;t get the build out until 1AM.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the most confusing parts of iPhone development is dealing with the <a href="http://developer.apple.com/iphone/manage/overview/index.action">iPhone Developer Program</a> side of things. You know, all that fun stuff with certificates, devices, provisioning profiles, distribution profiles, etc. Oh, the hours of &ldquo;fun&rdquo; you can spend with that.</p>
<p>Last night was particularly frustrating because I had just called it &ldquo;beta&rdquo; on Flower Garden and celebrated with the requisite victory dance, when the fun of sending out the beta build started. What I thought would be a ten-minute task, turned into a long nightmare and I didn&rsquo;t get the build out until 1AM.</p>
<p><img alt="dilbert" loading="lazy" src="/iphone-developer-program-gotchas/images/dilbert.gif" title="dilbert"></p>
<p>This is not the first time I run into issues with provisioning profiles and distribution in general. It&rsquo;s a very finicky process, and other developers are going through the same pains. <a href="http://www.markj.net/">Mark Johnson</a> suggested I collected all the gotchas I&rsquo;ve learned into a single place so it can serve as a form of reference. That&rsquo;s a great idea, because the process is so byzantine that I will have forgotten most of them next time I need to do another big submission.</p>
<p>This is not a &ldquo;how to&rdquo; document on preparing your builds for ad-hoc or App Store distribution. Apple has the basic flow documented in their site, and other people have also <a href="http://furbo.org/2008/08/06/beta-testing-on-iphone-20/">talked about the process</a>. This is intended to be more of an appendix explaining details, clarifying assumptions, and correcting things that are just plain wrong.</p>
<p>To make this more comprehensive, I&rsquo;d like to open it up to other people&rsquo;s experiences, not just mine. If you have gone through some pains with the iPhone Developer Program (and who hasn&rsquo;t?) and found a way to deal with them, please post in the comments and I&rsquo;ll update this page to reflect it.</p>
<h2 id="iphone-developer-program">iPhone Developer Program</h2>
<p><strong>1. App identifier is case sensitive.</strong> This is the string you need to enter when you create an app ID through the developer web site, and the one you need to set in your Info.plist. My usual development id is com.snappytouch.* so I can use it for anything I do. But in preparation for sending out the beta build, I created one just for Flower Garden: com.snappytouch.flowergarden. I thought that everything on the build side of things would be fine because my default app ID was: com.snappytouch.${PRODUCT_NAME:identifier}. Unfortunately, this failed to create a working build without any helpful errors. After much hair-pulling, I figured that was because my app is called &ldquo;FlowerGarden&rdquo; not &ldquo;flowergarden&rdquo;. Changing the app ID in XCode to com.snappytouch.flowergarden fixed that.</p>
<p><strong>2. Easy UDIDs.</strong> Forget about asking your testers to go to iTunes and get the UDID from there. Instead, tell them to get <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=291822093&amp;mt=8">BetaHelper</a> and email you all the information directly. Easy and no typing errors!</p>
<p><strong>3. Bulk device upload.</strong> I got a great response to the call for beta testers for Flower Garden, so I was left with about 30 new device UDIDs to enter in the developer web site. Entering them one at a time with a slow-as-molasses interface isn&rsquo;t my idea of fun so I decided to use the bulk upload option. Unfortunately the format isn&rsquo;t described exactly anywhere, and the errors displayed if the format doesn&rsquo;t match exactly are meaningless.</p>
<p>The exact format is:</p>
<pre tabindex="0"><code>Device ID	Device Name
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	Whatever name here
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	Lalalala
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	Whatever
</code></pre><p>So, tab separated, not comma separated. First column is the device ID (40 digits). Second is the name, no quotes around it. First line is ignored. Here&rsquo;s the killer: You cannot have any blank lines after the last entry. And the error message if you do is simply a &ldquo;Bad format&rdquo;. Come on Apple, throw us a bone over here! One last thing: You can&rsquo;t upload a device ID that is already in your database. Really annoying. Still, beats cut and pasting all those IDs by hand.</p>
<p><strong>4. <a href="http://www.markj.net/iphone-ad-hoc-distribution-windows-mac/">Ad-hoc zip file for Windows users</a>.</strong> Apparently it can&rsquo;t be created with the Compress option in finder because it puts extra files. I used zip from the command line and it worked correctly. (Thanks to <a href="http://www.markj.net/">Mark Johnson</a> for that one).</p>
<p><strong>5. App Store zip file has to be created through Finder with Compress</strong>. I heard that on Twitter somewhere, but needs confirmation. Anyone?</p>
<p><strong>6. Adding provisioning profiles.</strong> Forget about dragging them on XCode and manage them manually. Check out <a href="/adding-new-development-devices/">my earlier entry about it</a>.</p>
<p><strong>7. Set correct provisioning profile everywhere.</strong> And I mean everywhere. You need to do it both in the Info for the target and the info for the project itself. Yes, both dialog boxes look identical and have 99% the same information, but the provisioning profile setting is different apparently. Fail to set it in both places, and your app won&rsquo;t load in the device.</p>
<p>I&rsquo;m sure there are a lot more. If you&rsquo;ve found some of your own, leave a comment and I&rsquo;ll update the list.</p>
]]></content:encoded></item><item><title>Becoming Indie: 360iDev Presentation</title><link>https://gamesfromwithin.com/becoming-indie-360idev-presentation/</link><pubDate>Tue, 03 Mar 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/becoming-indie-360idev-presentation/</guid><description>&lt;p&gt;&lt;img alt="360|iDev" loading="lazy" src="https://gamesfromwithin.com/becoming-indie-360idev-presentation/images/8u2n8y.png" title="360|iDev"&gt;Here are the slides for the 360iDev presentation I gave a few minutes ago. They&amp;rsquo;re in Keynote format. Thanks everybody for coming and all the questions at the end. It was lots of fun!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Session description:&lt;/strong&gt; This session will cover the experiences of a professional game developer, used to 200+ person teams, multi-million dollar budgets, and 3+ year schedules, who left all that behind to become a one-person indie company developing exclusively for the iPhone. It will explain how things are different and how some things are very much the same, and will show specific examples of graphics technology, development environment, and asset pipeline. I will be using my current iPhone project, Flower Garden, as an example. The audience will learn what the transition is like and what to expect going indie making games for the iPhone.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="360|iDev" loading="lazy" src="/becoming-indie-360idev-presentation/images/8u2n8y.png" title="360|iDev">Here are the slides for the 360iDev presentation I gave a few minutes ago. They&rsquo;re in Keynote format. Thanks everybody for coming and all the questions at the end. It was lots of fun!</p>
<p><strong>Session description:</strong> This session will cover the experiences of a professional game developer, used to 200+ person teams, multi-million dollar budgets, and 3+ year schedules, who left all that behind to become a one-person indie company developing exclusively for the iPhone. It will explain how things are different and how some things are very much the same, and will show specific examples of graphics technology, development environment, and asset pipeline. I will be using my current iPhone project, Flower Garden, as an example. The audience will learn what the transition is like and what to expect going indie making games for the iPhone.</p>
<p><a href="/wp-content/uploads/2009/03/becomingindiekey.zip">BecomingIndie.key.zip</a></p>
]]></content:encoded></item><item><title>Adding New Development Devices</title><link>https://gamesfromwithin.com/adding-new-development-devices/</link><pubDate>Sat, 28 Feb 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/adding-new-development-devices/</guid><description>&lt;p&gt;Today I join the ranks of proud iPhone owners (maybe not so much &lt;a href="http://blog.wired.com/gadgets/2009/02/why-the-iphone.html"&gt;in Japan&lt;/a&gt; though). Yes, it an extra expense I can barely afford, but my previous cell phone contract was pretty much over and it made sense. So far I had been doing all my development on an iPod Touch, but I could really use a real iPhone for beta testing Flower Garden with all the reports of &lt;a href="http://toucharcade.com/2008/11/23/2nd-generation-ipod-touch-faster-than-iphone/"&gt;significant performance differences&lt;/a&gt; between the iPod Touch 2nd gen and iPhone. Besides, with &lt;a href="http://www.360conferences.com/360iDev/?"&gt;360iDev&lt;/a&gt; and &lt;a href="http://gdconf.com/"&gt;GDC&lt;/a&gt; coming up, being able to have constant internet access for email and &lt;a href="http://twitter.com/SnappyTouch"&gt;Twitter&lt;/a&gt; is a huge bonus.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Today I join the ranks of proud iPhone owners (maybe not so much <a href="http://blog.wired.com/gadgets/2009/02/why-the-iphone.html">in Japan</a> though). Yes, it an extra expense I can barely afford, but my previous cell phone contract was pretty much over and it made sense. So far I had been doing all my development on an iPod Touch, but I could really use a real iPhone for beta testing Flower Garden with all the reports of <a href="http://toucharcade.com/2008/11/23/2nd-generation-ipod-touch-faster-than-iphone/">significant performance differences</a> between the iPod Touch 2nd gen and iPhone. Besides, with <a href="http://www.360conferences.com/360iDev/?">360iDev</a> and <a href="http://gdconf.com/">GDC</a> coming up, being able to have constant internet access for email and <a href="http://twitter.com/SnappyTouch">Twitter</a> is a huge bonus.</p>
<p>Or maybe I just had gadget envy. Whatever.</p>
<p>But I&rsquo;m not writing to rub in what a cool gadget I have now. I had a couple interesting experiences adding new devices to XCode and I figured I would share them with other iPhone devs.</p>
<h2 id="sdk-and-firmware-compatibility">SDK and firmware compatibility</h2>
<p>This is something I noticed a few weeks ago, but I was able to confirm it with my new iPhone. Each new version of the iPhone SDK warns you to upgrade your device firmware to that version before you attempt to run any programs on it with the new SDK. I always took that literally, but I realized it&rsquo;s not as restrictive as it sounds.</p>
<p>With each version of the SDK, you have the option to target your build to that version or any of the previous ones. I discovered quite by accident that is perfectly fine to use a certain SDK (like 2.2.1) to build for an earlier version (2.0) and run it on a device with older firmware matching that version. It really makes a lot of sense, because otherwise the only way you could test your app on older firmware would be by reinstalling an old SDK. So maybe this is old news to most people, but it was certainly nice to first upgrade the SDK, and only later the firmware to minimize potential for problems.</p>
<h2 id="updating-provisioning-profile">Updating provisioning profile</h2>
<p>So with my new shiny iPhone in hand (actually, it was a $99 refurbished model, but it shines like new and has that new car smell&hellip; oh wait), I set to run Flower Garden on it. The process involved the following steps:</p>
<ul>
<li>Add a new device with the UDID of my iPhone to the Apple Developer Program account. I made the mistake of having to type it manually from iTunes&ndash;didn&rsquo;t realize that XCode allows you to copy and paste it, doh!. Check.</li>
<li>Add the new device to the development provisioning profile I was using. Check.</li>
<li>Download the updated provisioning profile and add it to XCode and my iPhone. Since the iPhone was plugged, all I had to do was drag it onto XCode. Check.</li>
<li>Clean all, build, run. And&hellip;.</li>
</ul>
<p>Yeah, you guessed it, I got an error. Otherwise I wouldn&rsquo;t be writing this if it had behaved as expected, would I? The error kindly informed me that the provisioning profile I was using to build the app wasn&rsquo;t available on my device. But I could see it in the organizer window of XCode. I double checked it was the correct one and that Flower Garden was being built with that one. Check. Check.</p>
<p>What was going on?</p>
<p>Here&rsquo;s the fun part, which took me a few minutes of digging through the docs. When I added the updated provisioning profile, XCode decided that it was a different one from the one I was trying to replace. But, here&rsquo;s the kicker, they both had the same name and description. So XCode was still building my app with the old one, but it was the new one that was installed on the iPhone.</p>
<p>I discovered this by going to the source. XCode stores all the provisioning profiles in the folder ~/Library/MobileDevice/Provisioning Profiles. You can&rsquo;t tell much of anything by looking at the filenames since they&rsquo;re a bunch of UIDS, but you can crack the files open with a good text editor and you&rsquo;ll see they&rsquo;re a mix of text and binary data. From there, you can see which file corresponds to which profile by looking at the text between the <Name> tags. All I had to do was delete the two development provisioning profiles, re-add the new one to XCode and the iPhone and I was back in business.</p>
<p>I had heard so many horror stories of upgrades to 2.2.1 that I was afraid I was hitting one of those. Fortunately it was quite simple. Next time I&rsquo;ll know where to look right away.</p>
<p>Now it&rsquo;s back to work for me. I still need to finish the slides for 360iDev and then I need to fix a couple of things in Flower Garden and get it ready for the first round of beta testing. Sleep? What&rsquo;s that?</p>
]]></content:encoded></item><item><title>Presenting at GDC 2009 on iPhone Development</title><link>https://gamesfromwithin.com/presenting-at-gdc-2009-on-iphone-development/</link><pubDate>Tue, 17 Feb 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/presenting-at-gdc-2009-on-iphone-development/</guid><description>&lt;p&gt;&lt;img alt="gdc09" loading="lazy" src="https://gamesfromwithin.com/presenting-at-gdc-2009-on-iphone-development/images/gdc09.jpg" title="gdc09"&gt;It seems like GDC was just the other day, but GDC 2009 is around the corner! And this year, I&amp;rsquo;m going to be giving a presentation titled &lt;a href="https://www.cmpevents.com/GD09/a.asp?option=C&amp;amp;V=11&amp;amp;SessID=9150"&gt;iPhone Development: Exploring The New Frontier&lt;/a&gt; I&amp;rsquo;m sorry about reverting to the cliched format of having a colon in the presentation title. It was too hard to resist :-).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll be sharing my experiences transitioning from traditional AAA console game development, with teams of 100+ people, multi-million budgets, and several years of development, to indie iPhone development. There are a surprising amount of things that carry over from &amp;ldquo;big game development&amp;rdquo;, and quite a few that are totally different. I&amp;rsquo;ll go into what&amp;rsquo;s involved making games for the iPhone, and what game developers can expect when making the transition.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="gdc09" loading="lazy" src="/presenting-at-gdc-2009-on-iphone-development/images/gdc09.jpg" title="gdc09">It seems like GDC was just the other day, but GDC 2009 is around the corner! And this year, I&rsquo;m going to be giving a presentation titled <a href="https://www.cmpevents.com/GD09/a.asp?option=C&amp;V=11&amp;SessID=9150">iPhone Development: Exploring The New Frontier</a> I&rsquo;m sorry about reverting to the cliched format of having a colon in the presentation title. It was too hard to resist :-).</p>
<p>I&rsquo;ll be sharing my experiences transitioning from traditional AAA console game development, with teams of 100+ people, multi-million budgets, and several years of development, to indie iPhone development. There are a surprising amount of things that carry over from &ldquo;big game development&rdquo;, and quite a few that are totally different. I&rsquo;ll go into what&rsquo;s involved making games for the iPhone, and what game developers can expect when making the transition.</p>
<p>Apart from my talk, I&rsquo;m particularly excited about this year&rsquo;s GDC. It seems that the amount of content on indie game development and iPhone game development has shot through the roof. On Monday and Tuesday we&rsquo;re treated to not just one, but two great summits: The <a href="http://www.gdconf.com/conference/igs.html">Independent Games Summit</a> and <a href="http://www.gdconf.com/conference/gdcmobile.html">GDC Mobile</a>! Last year, the Independent Games Summit was the best part of the show. Meeting all the other indie game developers out there and hearing their experiences was great. This year I&rsquo;m hoping for more of the same plus all the iPhone-specific content.</p>
<p>Of course, the main conference is packed with great content too, but I haven&rsquo;t had time to go through all of it and pick the sessions I want to attend yet. Too busy wrapping up my current project.</p>
<p>So if you see me around the show, stop by and say hi. I&rsquo;m always glad to meet other fellow developers, and it&rsquo;s always nice to put a face with a name for those of you that I know know through Twitter or online blogs.</p>
]]></content:encoded></item><item><title>Last Objective-C Annoyance: Fixed!</title><link>https://gamesfromwithin.com/last-objective-c-annoyance-fixed/</link><pubDate>Tue, 10 Feb 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/last-objective-c-annoyance-fixed/</guid><description>&lt;p&gt;I&amp;rsquo;ve gone on and on before about &lt;a href="https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-objective-c/"&gt;how much I like Objective-C&lt;/a&gt; and especially, how well it plays with C++. Mixing the two is a pleasure, and it&amp;rsquo;s often hard to remember where one stops and the other one starts. So much so that sometimes I catch myself calling C++ member functions like this [self myFunction:param];. Oops.&lt;/p&gt;
&lt;p&gt;It is true that Objective-C can be a bit more verbose than plain C++, but it more than makes up for it with named parameters (which increase readability a huge amount), and not having to duplicate many things between header and implementation files.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve gone on and on before about <a href="/iphone-from-a-game-developers-perspective-objective-c/">how much I like Objective-C</a> and especially, how well it plays with C++. Mixing the two is a pleasure, and it&rsquo;s often hard to remember where one stops and the other one starts. So much so that sometimes I catch myself calling C++ member functions like this [self myFunction:param];. Oops.</p>
<p>It is true that Objective-C can be a bit more verbose than plain C++, but it more than makes up for it with named parameters (which increase readability a huge amount), and not having to duplicate many things between header and implementation files.</p>
<p>Yet, even though I like Objective-C so much, there was one last, really annoying feature that was preventing perfect interop between C++ and Objective-C. Something so simple, yet so fundamental, that it really got in the way. Something that wouldn&rsquo;t allow me to write something as simple as this:</p>
<pre tabindex="0"><code>@interface MyView : UIView
{
Â Â Â  // ...
Â Â Â  SingleTouchEvent m_singleTouchEvent;
}
</code></pre><p>SingleTouchEvent is a custom C++ class. There&rsquo;s nothing wrong with that right? There shouldn&rsquo;t. But if you try and compile it, you&rsquo;ll get this warning:</p>
<pre tabindex="0"><code>warning: type `SingleTouchEvent&#39; has a user-defined constructor
warning: C++ constructors and destructors will not be invoked for Objective-C fields
</code></pre><p>Some of you might be saying, no big deal, you can dynamically allocate objects and have their constructors called as usual. That&rsquo;s true, but I hate allocating objects on the heap just because of something like this. My preference is always to make them member variables if I can. It&rsquo;s faster, more efficient, less error prone, and easier to read. Needless to say, this was bugging the hell out of me.</p>
<p>I looked all over the build options in case there was some setting I could toggle to enable C++ constructors to be called, but no luck. I did a bit more research, and lo and behold, it turns out there is a custom setting you can pass directly to gcc to do exactly that! It&rsquo;s nowhere in the XCode settings GUI, so you have to enter it by hand. Go to Project | Info, and in the Custom Settings section, enter the following: GCC_OBJC_CALL_CXX_CDTORS = YES</p>
<p><img alt="setting" loading="lazy" src="/last-objective-c-annoyance-fixed/images/setting.png" title="setting"></p>
<p>With that setting enabled, Objective-C and C++ now play together better than ever!</p>
<p>Without any barriers to writing new code in Objective-C, I expect it will slowly (or maybe not so slowly) replace C++ as my main language of choice for future projects.</p>
]]></content:encoded></item><item><title>San Diego iPhone Developers Gathering This Wednesday</title><link>https://gamesfromwithin.com/san-diego-iphone-developers-gathering-this-wednesday/</link><pubDate>Tue, 10 Feb 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/san-diego-iphone-developers-gathering-this-wednesday/</guid><description>&lt;p&gt;We had so much fun the first time, that we decided to do it again. Last time we had a great turnout and we had a great time comparing ninja UIKit techniques, giving exclusive worldwide previews of apps in the works, and sharing voodoo spells to to make your app show up in the front page of the App Store (amazing what a few beers will do).&lt;/p&gt;
&lt;p&gt;So we&amp;rsquo;re back at it again. Anybody involved in iPhone development or interested in learning more about it is welcome to come.&lt;/p&gt;</description><content:encoded><![CDATA[<p>We had so much fun the first time, that we decided to do it again. Last time we had a great turnout and we had a great time comparing ninja UIKit techniques, giving exclusive worldwide previews of apps in the works, and sharing voodoo spells to to make your app show up in the front page of the App Store (amazing what a few beers will do).</p>
<p>So we&rsquo;re back at it again. Anybody involved in iPhone development or interested in learning more about it is welcome to come.</p>
<p>When: Wednesday Feb 11th from 8PM until whenever. Where <a href="http://tinyurl.com/bcmkwj">O&rsquo;Sullivan&rsquo;s Pub in Carlsbad</a> (home of the <a href="http://www.appyentertainment.com/">Appy Entertainment Secret World Headquarters</a>)</p>
<p>If you&rsquo;re interested, you might also want to join the <a href="http://groups.google.com/group/san-diego-iphone-developers">San Diego iPhone Developers group</a> to keep up to date with any future announcements.</p>
<p>See you all there!</p>
]]></content:encoded></item><item><title>Remixing OpenGL and UIKit</title><link>https://gamesfromwithin.com/remixing-opengl-and-uikit/</link><pubDate>Fri, 30 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/remixing-opengl-and-uikit/</guid><description>&lt;p&gt;Yesterday I wrote about &lt;a href="https://gamesfromwithin.com/using-multiple-opengl-views-and-uikit/"&gt;OpenGL views&lt;/a&gt;, and how they can be integrated into a complex UI with multiple view controllers. There&amp;rsquo;s another interesting aspect of integrating OpenGL and UIKit, and that&amp;rsquo;s moving images back and forth between the two systems. In both cases, the key enabler is the CGContext class.&lt;/p&gt;
&lt;h2 id="from-uikit-to-opengl"&gt;From UIKit to OpenGL&lt;/h2&gt;
&lt;p&gt;This is definitely the most common way of sharing image data. Loading an image from disk in almost any format is extremely easy with Cocoa Touch. In fact, it couldn&amp;rsquo;t get any easier:&lt;/p&gt;</description><content:encoded><![CDATA[<p>Yesterday I wrote about <a href="/using-multiple-opengl-views-and-uikit/">OpenGL views</a>, and how they can be integrated into a complex UI with multiple view controllers. There&rsquo;s another interesting aspect of integrating OpenGL and UIKit, and that&rsquo;s moving images back and forth between the two systems. In both cases, the key enabler is the CGContext class.</p>
<h2 id="from-uikit-to-opengl">From UIKit to OpenGL</h2>
<p>This is definitely the most common way of sharing image data. Loading an image from disk in almost any format is extremely easy with Cocoa Touch. In fact, it couldn&rsquo;t get any easier:</p>
<pre tabindex="0"><code>UIImage* image = [UIImage imageNamed:filename];
</code></pre><p>After being used to image libraries like <a href="http://openil.sourceforge.net/">DevIL</a>, it&rsquo;s quite a relief to be able to load a file with a single line of code and no chance of screwing anything up. So it makes a lot of sense to use this as a starting point for loading OpenGL textures. So far we have a UIImage. How do we get from there to a texture?</p>
<p>All we have to do is create a CGContext with the appropriate parameters, and draw the image onto it:</p>
<pre tabindex="0"><code>byte* textureData = (byte *)malloc(m_width * m_height * 4);
CGContext* textureContext = CGBitmapContextCreate(textureData, m_width, m_height, 8, m_width * 4, 
Â Â Â Â Â Â Â Â Â Â Â  CGImageGetColorSpace(image), kCGImageAlphaPremultipliedLast);
CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (CGFloat)m_width, (CGFloat)m_height), image);
CGContextRelease(textureContext);
</code></pre><p>At that point, we&rsquo;ll have the image information, fully uncompressed in RGBA format in textureData. Creating an OpenGL texture from that is done like we always do:</p>
<pre tabindex="0"><code>glGenTextures(1, &amp;m_handle);
glBindTexture(GL_TEXTURE_2D, m_handle);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
</code></pre><p>And we&rsquo;re done.</p>
<p>A word of advice: This is a quick way to load textures and get started, but it&rsquo;s not the ideal way I would recommend for a shipping product. This code is doing a lot of work behind the scenes: loading the file, decompressing the image into an RGBA array, allocating memory, copying it over to OpenGL, and, if you set the option, generating mipmaps. All of this at load time. Ouch! If you have more than a handful of textures, that&rsquo;s going to be a pretty noticeable delay while loading.</p>
<p>Instead, it would be much more efficient to perform all the work offline, and prepare the image into the final format that you want to use with OpenGL. Then you can load that data directly into memory and call glTextImage2D on it directly. Not as good as having direct access to video memory and loading it there directly, but that&rsquo;s as good as it&rsquo;s going to get on the iPhone. Fortunately Apple provides a command-line tool called texturetool that does exactly that, including generating mipmaps.</p>
<p>Another use of transferring image data from UIKit to OpenGL beyond loading textures is to use the beautiful and full-featured font rendering in UIKit in OpenGL applications. To do that, we render a string into the CGContext:</p>
<pre tabindex="0"><code>CGColorSpaceRefÂ Â Â  colorSpace = CGColorSpaceCreateDeviceGray();
int sizeInBytes = height*width;
void* data = malloc(sizeInBytes);
memset(data, 0, sizeInBytes);
CGContextRef context = CGBitmapContextCreate(data, width, height, 8, width, colorSpace, kCGImageAlphaNone);
CGColorSpaceRelease(colorSpace);
CGContextSetGrayFillColor(context, grayColor, 1.0);
CGContextTranslateCTM(context, 0.0, height);
CGContextScaleCTM(context, 1.0, -1.0);
UIGraphicsPushContext(context);
Â Â Â  [txt drawInRect:CGRectMake(destRect.left, destRect.bottom, destRect.Width(), destRect.Height()) withFont:font 
Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];
UIGraphicsPopContext();
</code></pre><p>There are a couple things that are a bit different about this. First of all, notice that we&rsquo;re using a gray color space. That&rsquo;s because we&rsquo;re rendering the text into a grayscale, alpha-only texture. Otherwise, a full RGBA texture would be a waste. Then there&rsquo;s all the transform stuff thrown in the middle. That&rsquo;s because the coordinate system for OpenGL is flipped with respect to UIKit, so we need to inverse the y.</p>
<p>Finally, we can create a new texture from that data, or update an existing texture:</p>
<pre tabindex="0"><code>glBindTexture(GL_TEXTURE_2D, m_handle);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, m_width, m_height, GL_ALPHA, GL_UNSIGNED_BYTE, data);
</code></pre><h2 id="from-opengl-to-uikit">From OpenGL to UIKit</h2>
<p>This is definitely the more uncommon way of transferring image data. You would use this when saving something rendered with OpenGL back to disk (like game screenshots), or even when using OpenGL-rendered images on UIKit user interface elements, like I&rsquo;m doing in my project.</p>
<p>The process is very similar to the one we just went over, but backwards, with a CGContext as the middleman.</p>
<p>We first start by rendering whatever image we want. You can do this from the back buffer, or from a different render target. I don&rsquo;t know that it makes a difference in performance either way (these are not fast operations, so don&rsquo;t try to do them every frame!). Then you capture the pixels from the image you just rendered into a plain array:</p>
<pre tabindex="0"><code>unsigned char buffer[width*(height+30)*4];
glReadPixels(0,0,width,height,GL_RGBA,GL_UNSIGNED_BYTE, &amp;buffer);
</code></pre><p>By the way, notice the total awesomeness of the array declaration with non-constant variables. Thank you <a href="http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html">C99</a> (and gcc). Of course, that might not be the best thing to do with large images, since you might blow the stack size, but that&rsquo;s another issue.</p>
<p>Anyway, once you have those pixels, you need to go through the slightly convoluted CGContext again to put it in a format that can be consumed directly by UIImage like this:</p>
<pre tabindex="0"><code>CGImageRef iref = CGImageCreate(width,height,8,32,width*4,CGColorSpaceCreateDeviceRGB(),
Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  kCGBitmapByteOrderDefault,ref,NULL, true, kCGRenderingIntentDefault);
uint32_t* pixels = (uint32_t *)malloc(imageSize);
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width*4, CGImageGetColorSpace(iref), 
Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  Â Â Â  kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);
CGContextTranslateCTM(context, 0.0, height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(0.0, 0.0, width, height), iref);Â Â Â  
CGImageRef outputRef = CGBitmapContextCreateImage(context);
UIImage* image = [[UIImage alloc] initWithCGImage:outputRef];
free(pixels);
</code></pre><p>Again, we do the same flip of the y axis to avoid having inverted images.</p>
<p>Here the trickiest part was getting the color spaces correct. Apparently, even though it looks very flexible, the actual combinations supported in CGBitmapContextCreate <a href="http://developer.apple.com/qa/qa2001/qa1037.html">are pretty limited</a>. I kept getting errors because I kept passing an alpha channel combination that it didn&rsquo;t like.</p>
<p>At this point, you&rsquo;ll have the OpenGL image loaded an a UIImage, and you can do anything you want with it: Slap it on a button, save it to disk, or anything that strikes your fancy.</p>
]]></content:encoded></item><item><title>Using Multiple OpenGL Views And UIKit</title><link>https://gamesfromwithin.com/using-multiple-opengl-views-and-uikit/</link><pubDate>Fri, 30 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/using-multiple-opengl-views-and-uikit/</guid><description>&lt;p&gt;The iPhone includes OpenGL ES for graphics rendering (thank you Apple for not coming up with a custom API!). Specifically, it uses &lt;a href="http://www.khronos.org/opengles/sdk/1.1/docs/man/"&gt;OpenGL ES 1.1&lt;/a&gt; plus a few extensions. It&amp;rsquo;s all very familiar and standard, except for the actual setup, which requires some integration with the iPhone UI.&lt;/p&gt;
&lt;p&gt;The now gone CrashLander sample, in spite of some atrocious code, was the best example on how to get a simple, OpenGL app on the iPhone. It covered the basics: creating an OpenGL frame buffer, loading some textures, drawing some polys, and presenting the result to the screen. It was very useful because it was a very small and concise and it made for a great starting point for any OpenGL-based app.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The iPhone includes OpenGL ES for graphics rendering (thank you Apple for not coming up with a custom API!). Specifically, it uses <a href="http://www.khronos.org/opengles/sdk/1.1/docs/man/">OpenGL ES 1.1</a> plus a few extensions. It&rsquo;s all very familiar and standard, except for the actual setup, which requires some integration with the iPhone UI.</p>
<p>The now gone CrashLander sample, in spite of some atrocious code, was the best example on how to get a simple, OpenGL app on the iPhone. It covered the basics: creating an OpenGL frame buffer, loading some textures, drawing some polys, and presenting the result to the screen. It was very useful because it was a very small and concise and it made for a great starting point for any OpenGL-based app.</p>
<p>Unfortunately, because it was so basic, it didn&rsquo;t show how OpenGL can play with the rest of UIKit user interface. Instead, it took the approach from many games of taking control of the full screen and viewing it a a single resource. That&rsquo;s fine as long as you&rsquo;re making those kind of games, but I found myself having to mix OpenGL and UIKit quite a bit in my current project. And eventually, I even had to use multiple OpenGL views in different parts of the app.</p>
<h2 id="single-opengl-view">Single OpenGL View</h2>
<p>To render with OpenGL to a view, you have to first set the class-static method +layerClass so it creates the right type of layer. Specifically, we need a CAEAGLLayer:</p>
<pre tabindex="0"><code>+ (Class)layerClass
{
Â Â Â  return [CAEAGLLayer class];
}
</code></pre><p>You can create a view of that type in code, or you can lay it out on the Interface Builder. I actually like the Interface Builder quite a bit, so that&rsquo;s how I end up creating all of mine.</p>
<p>Then, you need to create an OpenGL context:</p>
<pre tabindex="0"><code>Â Â Â  m_eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
Â Â Â  [EAGLContext setCurrentContext:m_eaglContext];
</code></pre><p>Finally, you need to create a valid frame buffer object from the CAEAGLLayer from the view you just created:</p>
<pre tabindex="0"><code>Â Â Â  glGenFramebuffersOES(1, &amp;buffer.m_frameBufferHandle);
Â Â Â  glGenRenderbuffersOES(1, &amp;buffer.m_colorBufferHandle);
Â Â Â  glGenRenderbuffersOES(1, &amp;buffer.m_depthBufferHandle);

Â Â Â  glBindRenderbufferOES(GL_RENDERBUFFER_OES, buffer.m_colorBufferHandle);
Â Â Â  [m_eaglContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:drawable];
Â Â Â  glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &amp;buffer.m_width);
Â Â Â  glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &amp;buffer.m_height);

Â Â Â  glBindRenderbufferOES(GL_RENDERBUFFER_OES, buffer.m_depthBufferHandle);
Â Â Â  glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, buffer.m_width, buffer.m_height);
Â Â Â  glBindRenderbufferOES(GL_RENDERBUFFER_OES, buffer.m_colorBufferHandle);

Â Â Â  glBindFramebufferOES(GL_FRAMEBUFFER_OES, buffer.m_frameBufferHandle);
Â Â Â  glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, buffer.m_colorBufferHandle);Â 
Â Â Â  glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, buffer.m_depthBufferHandle)
</code></pre><p>It&rsquo;s all pretty standard frame buffer OpenGL stuff. The renderBufferStorage:fromDrawable function is the one that actually allocates buffer storage for that particular view.</p>
<p>After that, you&rsquo;re home free and you can use OpenGL the way you&rsquo;ve always done. The only difference is that to present, you call this functions instead:</p>
<pre tabindex="0"><code>Â Â Â  [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER_OES];
</code></pre><p>Done.</p>
<h2 id="integrating-opengl-and-uikit">Integrating OpenGL and UIKit</h2>
<p>After you have the basic OpenGL app set up, you can treat it as a full-screen, exclusive resource and do all your output through it. That works fine for a lot of games, but there are a lot of games and apps that benefit from using some amount of UIKit functionality. After all, UIKit is a great UI API, and it seems like a shame to reinvent it all if it&rsquo;s not necessary.</p>
<p>The good news is that OpenGL rendering is happen in a view, so you can do everything you can do with views: Animate it, do fancy transitions, add them to nav bars or tab bars, etc. The bad news is that, unless you&rsquo;re careful, performance will suffer.</p>
<p>Apple has some best practices on what to do with OpenGL views, but it comes down to avoid doing transforms on them (instead, use the transforms in OpenGL), and avoid putting other UIKit elements on top of it, especially transparent ones. Although, I seem to be able to get away with small buttons and such without affecting the frame rate, so that&rsquo;s always a plus.</p>
<p>So having realized that, now you can make your application transition between the OpenGL view, and other views. Maybe you have a table view with settings, or some sort of UIKit dialog box, or a high-score table. You can safely do all of that with UIKit (and add your own graphics and custom rendering if you want to give it a totally different look).</p>
<p>One thing to watch out for: Whenever your OpenGL view isn&rsquo;t visible, make sure to stop doing frame updates (for simulation and rendering). Otherwise, the rest of the UI is going to be very unresponsive (and you might not find that out until you run it on the device, because the simulator is very fast). The UIViewController viewWillAppear and viewDidDisappear functions are perfect to find out when you should start and stop frame updates.</p>
<h2 id="multiple-views">Multiple Views</h2>
<p>Things get more complicated when you want to have multiple views with OpenGL rendering. I don&rsquo;t mean multiple viewports in the same screen, but multiple views in the sense of multiple UIViews. My current project, for example, has different views connected with a UITabBarController. Some of the are custom UIViews and some of them are OpenGL views.</p>
<p>My first thought was to try to have different OpenGL contexts for each view, but that would complicate things because I wanted to share the same textures and other resources. I know there&rsquo;s a shared groups option, but that was definitely not the way to go.</p>
<p>The best solution I found was to use multiple frame buffers, binding each of them to the correct OpenGL view. That way, when I switch views, I switch frame buffers and everything works correctly.</p>
<p>On the -viewDidLoad function for each view controller with an OpenGL view, I call the function listed above to create a new frame buffer bound to that view, and it returns an index. Then, in the -viewWillAppear function, I set the frame buffer corresponding to that index:</p>
<pre tabindex="0"><code>Â Â Â  const FrameBuffer&amp; buffer = m_frameBuffers[bufferIndex];
Â Â Â  glBindFramebufferOES(GL_FRAMEBUFFER_OES, buffer.m_frameBufferHandle);Â Â Â 
Â Â Â  glBindRenderbufferOES(GL_RENDERBUFFER_OES, buffer.m_colorBufferHandle);
Â Â Â  glViewport(....);
</code></pre><p>That&rsquo;s it. Now you can switch between different OpenGL views and UIKit views without any problems. Just make sure to only render the visible views! That can be trickier than it sounds because the viewWillAppear and viewDidDisappear functions only get called for views that were layed out in the Interface Builder. If you added them by hand, you need to call those methods yourself (why??!?!). So keep tabs on that, otherwise everything will slow down to a halt.</p>
<h2 id="and-to-wrap-it-up">And To Wrap It Up&hellip;</h2>
<p>You thought I had forgotten about the promise to slowly unveil art from my current project, uh? Fear not, here comes the next teaser. This is an actually screenshot taken a minute ago. Incidentally, this is not one of the views using OpenGL. We&rsquo;ll have to save those for another day :-)</p>
<p><img alt="screenshot" loading="lazy" src="/using-multiple-opengl-views-and-uikit/images/screenshot.jpg" title="screenshot"></p>
]]></content:encoded></item><item><title>Tea Time! 1.1 Update Gets Its Way</title><link>https://gamesfromwithin.com/tea-time-11-update-gets-its-way/</link><pubDate>Tue, 27 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/tea-time-11-update-gets-its-way/</guid><description>&lt;p&gt;&lt;img alt="bug" loading="lazy" src="https://gamesfromwithin.com/tea-time-11-update-gets-its-way/images/bug.jpg" title="bug"&gt;Last Friday, I decided to fix a bug in Tea Time!. Not so much a bug in Tea Time! actually, but a bug in Apple&amp;rsquo;s UIPickerView control that showed up when subclassing it. It turns out that it was possible to scroll the picker wheel &lt;em&gt;just so&lt;/em&gt;, and one of the rows would come up blank (see screenshot). As far as I could tell, the UIPickerView class was unhappy that I was pre-allocating all the views I was going to show in the picker and handing them out whenever they were requested. So I had to allocate them on the fly or reuse the one in reusingView:&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="bug" loading="lazy" src="/tea-time-11-update-gets-its-way/images/bug.jpg" title="bug">Last Friday, I decided to fix a bug in Tea Time!. Not so much a bug in Tea Time! actually, but a bug in Apple&rsquo;s UIPickerView control that showed up when subclassing it. It turns out that it was possible to scroll the picker wheel <em>just so</em>, and one of the rows would come up blank (see screenshot). As far as I could tell, the UIPickerView class was unhappy that I was pre-allocating all the views I was going to show in the picker and handing them out whenever they were requested. So I had to allocate them on the fly or reuse the one in reusingView:</p>
<pre tabindex="0"><code>- (UIView *)pickerView:(UIPickerView *)pickerView
        viewForRow:(NSInteger)row forComponent:(NSInteger)component
        reusingView:(UIView *)view;
</code></pre><p>Once I did that, the bug mysteriously went away. Ah, the joys of dealing with code you have no source to.</p>
<p>So being the tinkerer that I am, I couldn&rsquo;t just stop there, and I spent an hour fixing something else that was annoying me to no end: When you start Tea Time! there&rsquo;s always a &ldquo;click&rdquo; sound that the picker plays because I&rsquo;m selecting the last used tea configuration during initialization.</p>
<p>I looked high and low how to fix that, but there seemed to be no way to do it. Nothing in the published SDK information that I could see. But digging through the header file for UIPickerView, I saw this:</p>
<pre tabindex="0"><code>@protocol UIPickerViewDataSource, UIPickerViewDelegate;

UIKIT_EXTERN_CLASS @interface UIPickerView : UIView &lt;NSCoding&gt;
{
Â //... snip....
Â  @package
Â Â Â  struct {
Â Â Â Â Â Â Â  unsigned int needsLayout:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToNumberOfComponentsInPickerView:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToNumberOfRowsInComponent:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToDidSelectRow:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToViewForRow:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToTitleForRow:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToWidthForComponent:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToRowHeightForComponent:1;
Â Â Â Â Â Â Â  unsigned int showsSelectionBar:1;
Â Â Â Â Â Â Â  unsigned int allowsMultipleSelection:1;
Â Â Â Â Â Â Â  unsigned int allowSelectingCells:1;
Â Â Â Â Â Â Â  unsigned int soundsDisabled:1;
Â Â Â  } _pickerViewFlags;
}
</code></pre><p>See that last flag? soundsDisabled. Sounds promising, doesn&rsquo;t it? Unfortunately _pickerViewFlags has @package protection, which means I can&rsquo;t get to it. Or so the theory goes.</p>
<p>Objective C is surprisingly &ldquo;good&rdquo; about letting you get under the hood and bypass protection levels. So I tried accessing those flags with NSObject function setValueForKey, but the stubborn picker would refuse to let me have access and throw an exception instead. Now he was starting to really annoy me. After all, I&rsquo;m supposed to be working on my other project, not hacking this little app.</p>
<p>I couldn&rsquo;t stop though. It&rsquo;s not in my nature.</p>
<p>Oh yeah, Objective C is refusing to give me access to those flags? Fine. I&rsquo;ll resort to the hackiest or hacks. But I <strong>will</strong> turn that damn bit off! An object is just a block of memory really, and each member variable is located at a fixed offset from the start of the object. See where this is going? Are you horrified enough? Yup. In the debugger I saw that _pickerViewFlags was exactly 16 bytes from the start UIViewPicker. So I grabbed the pointer to the picker, moved forward to the _pickerViewFlags variable, and stomped the soundsDisabledBit. Mwahahahaha! That will teach you, annoying picker!</p>
<p>Compile, run, and&hellip;. &ldquo;click&rdquo;. WTF!?!?!? I went in the debugger and checked that I was changing the right bits. Everything was fine. Except that, somehow, the picker was ignoring that. Defeated, I gave up in disgust.</p>
<p>It was that evening when I saw a tweet from <a href="http://twitter.com/jeff_lamarche">@jeff_lamarche</a> about accessing an undocumented function to turn off the sounds in the clicker. Nice timing! He pointed me to <a href="http://iphonedevelopment.blogspot.com/2008/10/you-shouldnt-but-you-will.html">his blog post</a> about how to get a listing of all the undocumented SDK functions and how to access them from your programs. I couldn&rsquo;t believe that there was a function to do exactly what I wanted, but Apple wasn&rsquo;t exposing it. And for something so simple too!!</p>
<p>It was as simple as</p>
<pre tabindex="0"><code>@interface CustomPicker(hidden)
- (void)setSoundsEnabled:(BOOL)isEnabled;
@end
</code></pre><p>followed by</p>
<pre tabindex="0"><code>Â Â Â  [m_picker setSoundsEnabled:NO];
Â Â Â  [m_picker selectRow:settings.m_teaType inComponent:0 animated:NO];
Â Â Â  [m_picker selectRow:settings.m_teaStrength inComponent:1 animated:NO];
Â Â Â  [m_picker selectRow:settings.m_teaFormat inComponent:2 animated:NO];
Â Â Â  [m_picker setSoundsEnabled:YES];
</code></pre><p>Finally! I had defeated UIPickerView!</p>
<p>Now the catch is, you&rsquo;re not supposed to use undocumented SDK functions. Apparently that&rsquo;s grounds for getting your app rejected by Apple and having to resubmit. But I figured I had nothing to lose, and it might be an interesting learning lesson. After all, how exactly does Apple check for undocumented functionality? Do they scan the submitted executable against a set of forbidden entry points? I couldn&rsquo;t imagine that&rsquo;s a manual process. But on the other hand, there are reports of other apps getting onto the App Store using undocumented SDK features.</p>
<p>I figured, what the heck, it was a tiny little thing that wasn&rsquo;t going to hurt anyone. Might as well try it.</p>
<p><img alt="teatime" loading="lazy" src="/tea-time-11-update-gets-its-way/images/teatime.png" title="teatime">I went ahead submitted the update last Friday, and today (Tuesday) I got the official email with the approval of my new version. Not a bad turnaround time since I imagine they don&rsquo;t work weekends. It even just <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8">made it to the App Store</a> as I was writing this. Shweet!</p>
<p>I&rsquo;m still left wondering how Apple tries to monitor undocumented SDK usage. Did they not bother with my app since it was so small? Is it really a manual process? (I feel bad for the person in charge of that just thinking about it). Did they catch it and realized it was totally harmless and let it through? Only Apple knows I&rsquo;m afraid. They really should make their process both more transparent and more consistent and fair for everybody.</p>
<p>But hey, I&rsquo;m not complaining. No more annoying click at startup :-)</p>
]]></content:encoded></item><item><title>Speaking at iPhone Conference And A Teaser</title><link>https://gamesfromwithin.com/speaking-at-iphone-conference-and-a-teaser/</link><pubDate>Wed, 21 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/speaking-at-iphone-conference-and-a-teaser/</guid><description>&lt;p&gt;&lt;img alt="360|iDev" loading="lazy" src="https://gamesfromwithin.com/speaking-at-iphone-conference-and-a-teaser/images/8u2n8y.png" title="360|iDev"&gt;I missed the &lt;a href="http://developer.apple.com/events/iphone/techtalks/"&gt;iPhone Tech Talk World Tour&lt;/a&gt; last Fall. At the time it wasn&amp;rsquo;t a big deal because I was still soaking in all the information from the iPhone SDK docs. Now, on the other hand, I&amp;rsquo;m at the point that I&amp;rsquo;m getting into more advanced stuff, either not covered in the docs, or that it&amp;rsquo;s just plain tricky. For example, I spent all day today trying to coerce my app into sending an email with an image attachment&amp;ndash;in the end I either kind of succeeded, or I bypassed the problem, depending how you look at it. But that&amp;rsquo;s another story for another day.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="360|iDev" loading="lazy" src="/speaking-at-iphone-conference-and-a-teaser/images/8u2n8y.png" title="360|iDev">I missed the <a href="http://developer.apple.com/events/iphone/techtalks/">iPhone Tech Talk World Tour</a> last Fall. At the time it wasn&rsquo;t a big deal because I was still soaking in all the information from the iPhone SDK docs. Now, on the other hand, I&rsquo;m at the point that I&rsquo;m getting into more advanced stuff, either not covered in the docs, or that it&rsquo;s just plain tricky. For example, I spent all day today trying to coerce my app into sending an email with an image attachment&ndash;in the end I either kind of succeeded, or I bypassed the problem, depending how you look at it. But that&rsquo;s another story for another day.</p>
<p>So last week, I was excited to learn there was a new iPhone development conferenceÂ  called <a href="http://www.360conferences.com/360iDev/">360|iDev</a> (not the greatest conference name&ndash;sounds too much like an Xbox development conference). It looks like a very hands-on, for developers by developers kind of conference, instead of half-marketing, half-development like Apple&rsquo;s offerings (Yes, we&rsquo;re already on board, you don&rsquo;t have to sell us on how cool the iPhone is. We know. We&rsquo;ve banked our life and savings on it actually). The lineup of speakers looks really promising (including <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=291176027&amp;mt=8">Urban Tycoon</a> author, <a href="http://www.mikehuntington.com/">Mike Huntington</a>).</p>
<p>What really excites me the most is meeting the other attendees though. It looks like it&rsquo;s not going to be a huge conference (hundreds instead of thousands or tens of thousands like <a href="http://gdconf.com">GDC</a>), and we&rsquo;re all staying at the same hotel, so there should be plenty of opportunities to meet people, chat, trade tips, and compare horror stories over beers.</p>
<p>I actually liked the idea so much, that I decided to jump in and submit a session proposal, and the organizers very kindly accepted it (which is great because otherwise I might not have been able to have afforded going :-)). I&rsquo;ll be talking about my experience going from a AAA console development environment, to a single-person iPhone development team. Both the obvious differences, the not so obvious similarities, and how a single person can really deliver a top-notch iPhone game.</p>
<p>I encourage everybody to have a look at the <a href="http://www.360conferences.com/360iDev/">360|iDev</a> site and register if you haven&rsquo;t already. It&rsquo;s not very expensive (especially if you buy the ticker sooner, rather than later), and it&rsquo;s going to be a blast. It&rsquo;s in San Jose in early March, a couple of weeks before GDC, so no conflicts for game developers there. Also, if you&rsquo;re interested in speaking, check out their <a href="http://www.360conferences.com/360iDev/2008/12/360idev-whats-this-is-all-about-and.html">call for speakers</a> while they&rsquo;re still accepting new submissions. I hope to see some of you there!</p>
<p>On a totally different note, a couple of weeks ago, Evan at <a href="http://www.veiledgames.com/">Veiled Games</a> (<a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=299876012&amp;mt=8">Up There</a>), which is one of my favorite indie iPhone developers, promised to put <a href="http://www.veiledgames.com/blog/?p=319">a daily image with a teaser of their upcoming project</a>. This was soon picked up by Gavin at <a href="http://www.antairgames.com/blog/2009/01/10/weekly-update-14/">Antair Games</a>, who is <a href="http://www.antairgames.com/blog/2009/01/10/weekly-update-14/">letting us peek under the covers</a> of what&rsquo;s coming up after <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298155609&amp;mt=8">Sneezies</a>.</p>
<p>I figured it would be fun to follow their steps, but don&rsquo;t hold your breath of a daily update. Maybe weekly if you&rsquo;re lucky. Maybe.</p>
<p>So here&rsquo;s this week&rsquo;s teaser. Draw whatever conclusions you want from it :-)</p>
<p><img alt="gnome" loading="lazy" src="/speaking-at-iphone-conference-and-a-teaser/images/gnome.jpg" title="gnome"></p>
]]></content:encoded></item><item><title>Status: Pending Contract :-(</title><link>https://gamesfromwithin.com/status-pending-contract/</link><pubDate>Tue, 13 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/status-pending-contract/</guid><description>&lt;p&gt;&lt;img alt="pending" loading="lazy" src="https://gamesfromwithin.com/status-pending-contract/images/pending.jpg" title="pending"&gt; Based on all the horror stories I had read from other developers, I really thought I got out easy submitting Tea Time! It only took a week and a half to approve, there were no complications, and I was able to change to a company status half way through.&lt;/p&gt;
&lt;p&gt;I guess I really got out too easy and Apple had to remedy that. Today I found that Tea Time! shows up in the App Store listings, but it&amp;rsquo;s unavailable when you try to buy it. When I looked in the app management site, much to my surprise, Tea Time! was listed as &amp;ldquo;Pending Contract&amp;rdquo;.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="pending" loading="lazy" src="/status-pending-contract/images/pending.jpg" title="pending"> Based on all the horror stories I had read from other developers, I really thought I got out easy submitting Tea Time! It only took a week and a half to approve, there were no complications, and I was able to change to a company status half way through.</p>
<p>I guess I really got out too easy and Apple had to remedy that. Today I found that Tea Time! shows up in the App Store listings, but it&rsquo;s unavailable when you try to buy it. When I looked in the app management site, much to my surprise, Tea Time! was listed as &ldquo;Pending Contract&rdquo;.</p>
<p>What I thought was a relatively fast switch from individual to a company status, just propagated through their database and cancelled my previous contract. So I had to enter all the banking and tax information (exactly the same as before) and wait for the bureaucracy to approve it. So it looks like Tea Time! is going to be out of commission for a few days (or weeks or months?).</p>
<p>It really blows because it will kill whatever little momentum it had. Boy am I glad I went through this now and not with my other project!</p>
]]></content:encoded></item><item><title>Tea Time! Back Up</title><link>https://gamesfromwithin.com/tea-time-back-up/</link><pubDate>Tue, 13 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/tea-time-back-up/</guid><description>&lt;p&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;amp;mt=8"&gt;&lt;img alt="snappy" loading="lazy" src="https://gamesfromwithin.com/tea-time-back-up/images/snappy.jpg" title="Tea Time!"&gt;&lt;/a&gt;I was just pleasantly surprised to see that my new sales contract as &lt;a href="http://www.snappytouch.com/"&gt;Snappy Touch&lt;/a&gt; for the App Store was approved and that &lt;a href="http://www.snappytouch.com/teatime"&gt;Tea Time!&lt;/a&gt; is once again &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;amp;mt=8"&gt;available for sale&lt;/a&gt;. I was fearing it would be gone for days, but the blackout only lasted about a day. Not too bad.&lt;/p&gt;
&lt;p&gt;The only difference is that now it&amp;rsquo;s listed with Snappy Touch being the seller instead of my name. Will this be the end of the App Store saga? Let&amp;rsquo;s hope so.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8"><img alt="snappy" loading="lazy" src="/tea-time-back-up/images/snappy.jpg" title="Tea Time!"></a>I was just pleasantly surprised to see that my new sales contract as <a href="http://www.snappytouch.com/">Snappy Touch</a> for the App Store was approved and that <a href="http://www.snappytouch.com/teatime">Tea Time!</a> is once again <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8">available for sale</a>. I was fearing it would be gone for days, but the blackout only lasted about a day. Not too bad.</p>
<p>The only difference is that now it&rsquo;s listed with Snappy Touch being the seller instead of my name. Will this be the end of the App Store saga? Let&rsquo;s hope so.</p>
<p>In the meanwhile, a sales update for those of you curious about it: In the first three days, Tea Time! sold 83 units. On one hand, that&rsquo;s more than I expect (although I suspect that half of those are people following this blog and my announcement on Facebook). But on the other hand, it&rsquo;s nothing if you&rsquo;re trying to make a profit from it, even if it just took a couple of days to put together.</p>
<p>Granted, this is an extreme example. It has gotten exactly <strong>zero</strong> marketing of any kind, and it&rsquo;s aimed at a very specific audience. I&rsquo;m sure if a place like <a href="http://www.republicoftea.com/">Republic of Tea</a> or <a href="http://www.adagio.com">Adagio Tea</a> advertised it in their catalogs, sales would go way up. But it gives you a base line of what you can expect in the worst case.</p>
]]></content:encoded></item><item><title>The "One Day" iPhone App Experiment</title><link>https://gamesfromwithin.com/the-one-day-iphone-app-experiment/</link><pubDate>Mon, 12 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-one-day-iphone-app-experiment/</guid><description>&lt;p&gt;I&amp;rsquo;ve been working full time on an iPhone app for the last three months. Realistically, I still have another month ahead of me. Four months is nothing compared to projects for current game consoles, but it&amp;rsquo;s pretty long for an iPhone app. It&amp;rsquo;s not like I&amp;rsquo;m slacking off (I swear that playing &lt;a href="%20http://www.worldofwarcraft.com"&gt;WoW&lt;/a&gt; has nothing to do with it!), but it&amp;rsquo;s a relatively complex project for an iPhone, involving 3D graphics, procedural geometry generation, custom user interface, and network access among other things. Definitely not your everyday, quick iPhone app.&lt;/p&gt;
&lt;p&gt;&lt;img alt="teatimeitunesicon" loading="lazy" src="https://gamesfromwithin.com/the-one-day-iphone-app-experiment/images/teatimeitunesicon.png" title="teatimeitunesicon"&gt;A couple of weeks ago, I decided to take a few days off from my project to enjoy the holidays with friends and family. Of course, I couldn&amp;rsquo;t stop thinking about the project. Soon my thoughts turned to how much more I had to go, and how some parts of the development process were still unknown to me, like the Apple submission process, or making a build for distribution on the App Store.&lt;/p&gt;
&lt;p&gt;At that point, inspiration struck, and I decided to use one day during the holidays to write a quick, one-day app. That way it wouldn&amp;rsquo;t take any time away from my project and I would learn a lot from it. And maybe, just maybe, I would make a buck or two in the process.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve been working full time on an iPhone app for the last three months. Realistically, I still have another month ahead of me. Four months is nothing compared to projects for current game consoles, but it&rsquo;s pretty long for an iPhone app. It&rsquo;s not like I&rsquo;m slacking off (I swear that playing <a href="%20http://www.worldofwarcraft.com">WoW</a> has nothing to do with it!), but it&rsquo;s a relatively complex project for an iPhone, involving 3D graphics, procedural geometry generation, custom user interface, and network access among other things. Definitely not your everyday, quick iPhone app.</p>
<p><img alt="teatimeitunesicon" loading="lazy" src="/the-one-day-iphone-app-experiment/images/teatimeitunesicon.png" title="teatimeitunesicon">A couple of weeks ago, I decided to take a few days off from my project to enjoy the holidays with friends and family. Of course, I couldn&rsquo;t stop thinking about the project. Soon my thoughts turned to how much more I had to go, and how some parts of the development process were still unknown to me, like the Apple submission process, or making a build for distribution on the App Store.</p>
<p>At that point, inspiration struck, and I decided to use one day during the holidays to write a quick, one-day app. That way it wouldn&rsquo;t take any time away from my project and I would learn a lot from it. And maybe, just maybe, I would make a buck or two in the process.</p>
<p>The app itself was a very simple <a href="http://www.snappytouch.com/teatime">tea timer</a>, inspired by tea maker machines: Enter the type of tea you want, the strength, and whether it&rsquo;s loose leaves or in a bag, and it starts a timer with the correct steeping time for that particular tea. This was such a simple app, that it ended being exactly the way I had visualized the first time I thought about it.</p>
<h2 id="coding-the-app">Coding The App</h2>
<p>Just coding the app itself was an interesting learning experience. Up until that point, I had spent most of my time on the OpenGL side of the iPhone. Tea Time! on the other hand, was 100% Cocoa Touch, so that was a nice change of pace.</p>
<p>Why did it take me a day? It&rsquo;s such a trivial app that I should be able to throw it together in a few hours, right? Not quite. I had to deal with all the little quirks of Cocoa Touch, and get around the crippled functionality that Apple exposes in their API (while their own apps use a different API).</p>
<p>For example, it was a bit of a letdown to see I couldn&rsquo;t add images to the picker control. But my disappointment was immediately replaced with excitement when I saw how easy it was to subclass it and display whatever you wanted in it. Unfortunately, the excitement gave way to annoyance trying to work around some of the bugs Apple still has on the picker control.</p>
<p>It&rsquo;s <strong>really</strong> frustrating not having access to the same API Apple uses internally. I wanted to be able to turn off the iPhone while the timer was counting down, and have the device turn back on when the timer ends, just like the built-in alarm. Oh no, can&rsquo;t do. Apparently that&rsquo;s reserved for Apple. Fortunately, the longest you&rsquo;re going to steep a cup of tea is 6-7 minutes, so I just disabled the power-saving feature of the iPhone so it doesn&rsquo;t go to sleep while it&rsquo;s counting down.</p>
<p>Even for such a simple application, getting a polished user interface in place takes some effort and time. The <a href="http://developer.apple.com/tools/interfacebuilder.html">Interface Builder</a> allows me to throw a user interface together in a snap just to get the basic functionality up and running. Later, I can come back and tweak it until I&rsquo;m happy with it. Surprisingly, there are lots of things that the Interface Builder doesn&rsquo;t allow you to do, so a lot of controls have extra code to tweak some of their parameters (increasing the target area of the info button on the top right corner, or setting the background images for he start/stop buttons, which require a special stretching pattern). Looking on the bright side, it&rsquo;s very easy to combine a layout from the Interface Builder with custom code, which is a very important lesson for content-creation tools of any kind (and one that a lot of game tools get wrong!).</p>
<p>The rest of the coding time went into all the little things we don&rsquo;t usually think about: Saving preferences, remembering the last used combination of parameters, getting the right splash screen, etc. All in all, the coding was about a day&rsquo;s worth of work.</p>
<h2 id="creating-the-content">Creating The Content</h2>
<p>There&rsquo;s more to an app than code and a nice GUI layout, especially if you don&rsquo;t want it to look like a boring spreadsheet: Graphics and sounds. In my first pass, while I was coding the basic functionality, I just grabbed whatever images I found through <a href="http://images.google.com/images?hl=en&amp;q=tea+cup&amp;btnG=Search+Images&amp;gbv=2">Google Images</a> and threw them in. Then, once the app was pretty much finished, I set to replace them.</p>
<p><img alt="Tea cup" loading="lazy" src="/the-one-day-iphone-app-experiment/images/tea_cup_1.jpg" title="tea_cup_1"></p>
<p><em>Original photo of my tea cup that became the icon for Tea Time!</em></p>
<p>That&rsquo;s harder than it sounds because I&rsquo;m not a graphic designer. I&rsquo;m semi-proficient at <a href="http://www.gimp.org/">the Gimp</a>, but that&rsquo;s about it. I do quite a bit of photography and I love tea though, so I decided to take pictures of the tea I was preparing at home. The main icon of for Tea Time! is just my tea mug with the tea I was having that morning.</p>
<p>The images had to be processed in the Gimp quite a bit. Tweaked colors and brightness, removed background objects, and even altered to fit the constraints of the GUI. For example, the little cups in the picker are the same picture that was then carefully colorized in the Gimp to match different tea types.</p>
<p>For the alarm sound, I was hoping to be able to play the system alarm sounds that come with the iPhone. But again, Apple lets us down by not giving us access to those (Why not???). So I hit a couple web sites with free sounds, selected a few that I liked, and tweaked them with <a href="http://audacity.sourceforge.net/">Audacity</a> to get the right length and sampling rate.</p>
<p>It was a really fun process getting all the content ready. I really enjoyed it and it was a nice break from coding, but it sucked almost another full day of work. So my &ldquo;one day&rdquo; app, was already almost up to two days. But at least I was done now. Right?</p>
<h2 id="submitting-the-app">Submitting The App</h2>
<p>I had done ad-hoc builds before, but I hadn&rsquo;t prepared one for submission to the App Store. So I had to figure that out: Create a new distribution certificate, create a new configuration in XCode, test it&hellip; Not too bad.</p>
<p>Then I had to sign up for iTunes Connect and agree to a bunch of legalese non-sense. It was all done online and really quick, so that wasn&rsquo;t a problem either. Finally I was ready to submit the app and be done with it. I had to write up a description, figure out the categories it would be listed under, take screenshots, and prepare a high-res cover art. I get all that ready, I fill out the submission form, and press submit. Done!</p>
<p>Oh wait, I get a message about not being able to get paid until I get a contract in place. What? Apparently when I signed up for iPhone development that only covered free applications, but I needed to set up a new contract in place with Apple if I was going to sell anything. So I had to enter bank ids, account numbers, tax information, and everything else. Once all that information was in place, my contract was in &ldquo;Reviewing&rdquo; state, and a couple days later it was approved without any hitches. Be warned that if you&rsquo;re not in the US, apparently you have to mail a physical form to them before they approve the contract, so the process is likely to be much longer.</p>
<p>Along with the price (a very obvious $0.99), I had to set the &ldquo;Availability date&rdquo; for the app. I had read horror stories of developers who finally had their app approved, just to find it buried ten pages into the &ldquo;New Releases&rdquo; list in iTunes. The guys over at <a href="http://www.veiledgames.com/blog/?p=183">Veiled Games</a>, explained how the release date is a combination of when the app is approved and the availability date you set. So I set the availability date to two weeks in the future and was ready to tweak it if necessary.</p>
<p>Are we done yet? Not quite. The submission page wanted a URL for a web page describing the app, and I didn&rsquo;t have anything ready. I didn&rsquo;t want to just point to a page in this blog, and I had been thinking that I should set up a company as a real legal entity for doing iPhone development and consulting. Fortunately, I had gone through this process before with Power of Two Games, so it was relatively easy and painless, especially since this was a single-member LLC. So the rest of the day was spent coming up with a company name (Snappy Touch), registering the domain (<a href="http://www.snappytouch.com">http://snappytouch.com</a>), registering the LLC (in the state of Oregon no less because it&rsquo;s a lot cheaper than California), installing Wordpress in the new domain, and setting up a <a href="http://www.snappytouch.com/teatime">basic page describing Tea Time!</a>.</p>
<p>Finally done! Total time: Three days.</p>
<h2 id="waiting-and-waiting">Waiting And Waiting</h2>
<p>But Tea Time! wasn&rsquo;t on the App Store yet. It had just entered the review process. Now I had to wait for Apple to approve it (or reject it so I can fix it). I heard from other developers that the usual wait time was about two weeks, but between this coinciding with the new year, and Apple getting swamped with submissions for the holidays, I figured I would be more like three or four weeks. Glad nothing was riding on this app getting out quickly.</p>
<p>A few days later, when I was checking out the info for Tea Timer! in the Apple submission site, while it was still in review, I was shocked to see it was listed as requiring SDK 2.2. That made no sense! I made a point to develop it for SDK 2.0 so every iPhone and iPod Touch user could buy it. I made really sure I selected SDK 2.0 when I created the iTunes distribution build. What gives? Apparently just building against SDK 2.0 wasn&rsquo;t enough. I actually had to change the project settings to set SDK 2.0 as the default. That&rsquo;s a sneaky one!</p>
<p>So what to do? I rejected my own binary and uploaded a new, updated one. This one was correctly listed as requiring SDK 2.0. I wasn&rsquo;t too happy at having to do that because I&rsquo;m sure it put me back to the end of the line, but this is exactly the kind of thing I was hoping to learn with Tea Time! in a no-pressure situation.</p>
<p>Waiting is no fun, so I made things a bit more interesting. Since I had gone to the trouble of creating a legal company, I decided to change my Apple Developer account to be a company instead of an individual. That way the company information would show up correctly in iTunes whenever Tea Time! was available. I figured this would be a matter of checking off a checkbox in my account settings, but apparently not. I had to email the Apple Developer Connection support with the request, wait a few days for an answer, and then provide some legal proof that the company existed (like the articles of incorporation). Once I emailed those, they initiated the conversion process, during which time I was locked out of my account for three days.Â  What does it take to change one bit in my account record??? Fortunately I had nothing else better to do than wait by this time, and it wasn&rsquo;t impeding any work on my other project.</p>
<h2 id="finally">Finally!</h2>
<p>The very next day after getting changed over as a company status, I got the much-awaited email from Apple announcing that Tea Time! was approved. That was just a week and a half after my initial submission. That was fast, especially considering I re-submitted the binary half way through. I reset my availability date to that day, and within a couple of hours, <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8">there it was, in the App Store</a>. Mission accomplished!</p>
<p>Now, I get to learn about the sales reports, and, if I ever sell enough units, getting payments from Apple. They won&rsquo;t make a payment until you accumulate at least $250 in profit from a single territory, so I&rsquo;m not holding my breath for that one :-)</p>
<p>The &ldquo;one day&rdquo; app really took three days of work plus a week and a half of waiting. All in all, two weeks from idea to the moment it was available on the App Store. The process could be faster, but it wasn&rsquo;t too bad. The experience was a lot of fun, and I certainly learned a lot from my mistakes and what things to watch out for next time, when it really counts.</p>]]></content:encoded></item><item><title>Tea Time! Available on The App Store Now!</title><link>https://gamesfromwithin.com/first-iphone-app-available-on-the-app-store-now/</link><pubDate>Fri, 09 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/first-iphone-app-available-on-the-app-store-now/</guid><description>&lt;p&gt;My first iPhone app, &lt;a href="http://www.snappytouch.com/teatime"&gt;Tea Time!&lt;/a&gt;, just hit the &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;amp;mt=8"&gt;App Store&lt;/a&gt; today! Tea lovers of the world: Go get it now.&lt;/p&gt;
&lt;p&gt;What am I doing writing a little app like that? Don&amp;rsquo;t worry, that&amp;rsquo;s not what I&amp;rsquo;ve been doing for the last few months :-) It was an experiment to see how quick I could put a simple app together and getting the experience of going through the whole cycle with the App Store. Tomorrow I&amp;rsquo;ll write an entry with all that I&amp;rsquo;ve learned so far.&lt;/p&gt;</description><content:encoded><![CDATA[<p>My first iPhone app, <a href="http://www.snappytouch.com/teatime">Tea Time!</a>, just hit the <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8">App Store</a> today! Tea lovers of the world: Go get it now.</p>
<p>What am I doing writing a little app like that? Don&rsquo;t worry, that&rsquo;s not what I&rsquo;ve been doing for the last few months :-) It was an experiment to see how quick I could put a simple app together and getting the experience of going through the whole cycle with the App Store. Tomorrow I&rsquo;ll write an entry with all that I&rsquo;ve learned so far.</p>
<p>Enjoy your tea!</p>
]]></content:encoded></item><item><title>San Diego iPhone Developer Gathering Next Week</title><link>https://gamesfromwithin.com/san-diego-iphone-developer-gathering-next-week/</link><pubDate>Thu, 08 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/san-diego-iphone-developer-gathering-next-week/</guid><description>&lt;p&gt;Are you doing iPhone development? Are you in the San Diego area? Come meet a bunch of local iPhone developers next week. It will be an informal gathering, just to get to know each other, trade war stories, and bitch about the App Store over &lt;a href="http://www.karlstrauss.com/PAGES/Locations/Menu/Start.htm#5"&gt;pizza&lt;/a&gt; and &lt;a href="http://www.karlstrauss.com/PAGES/Beer/Start_Beer.htm"&gt;beers&lt;/a&gt;. Feel free to invite anybody interested as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: Wednesday January 14th from 7PM until whenever &lt;strong&gt;Where&lt;/strong&gt;: &lt;a href="http://maps.google.com/maps?q=9675+Scranton+Rd,+San+Diego,+CA&amp;amp;oe=utf-8&amp;amp;client=firefox-a&amp;amp;ie=UTF8&amp;amp;split=0&amp;amp;ll=32.899552,-117.196655&amp;amp;spn=0.055562,0.092525&amp;amp;z=14&amp;amp;iwloc=addr"&gt;Karl Strauss Brewery in Mira Mesa&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hope to see you all there!&lt;/p&gt;</description><content:encoded><![CDATA[<p>Are you doing iPhone development? Are you in the San Diego area? Come meet a bunch of local iPhone developers next week. It will be an informal gathering, just to get to know each other, trade war stories, and bitch about the App Store over <a href="http://www.karlstrauss.com/PAGES/Locations/Menu/Start.htm#5">pizza</a> and <a href="http://www.karlstrauss.com/PAGES/Beer/Start_Beer.htm">beers</a>. Feel free to invite anybody interested as well.</p>
<p><strong>When</strong>: Wednesday January 14th from 7PM until whenever <strong>Where</strong>: <a href="http://maps.google.com/maps?q=9675+Scranton+Rd,+San+Diego,+CA&amp;oe=utf-8&amp;client=firefox-a&amp;ie=UTF8&amp;split=0&amp;ll=32.899552,-117.196655&amp;spn=0.055562,0.092525&amp;z=14&amp;iwloc=addr">Karl Strauss Brewery in Mira Mesa</a></p>
<p>Hope to see you all there!</p>
]]></content:encoded></item><item><title>Break That Thumb For Best iPhone Performance</title><link>https://gamesfromwithin.com/break-that-thumb-for-best-iphone-performance/</link><pubDate>Mon, 05 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/break-that-thumb-for-best-iphone-performance/</guid><description>&lt;p&gt;I haven&amp;rsquo;t started doing any real performance optimizations on my iPhone app yet. I pretty much ported it from the original PC version, saw that it was running rather slow (2-3 fps) so I changed the number of elements on the screen until it was an &amp;ldquo;acceptable&amp;rdquo; 15 fps and left it there until I had time to come back and optimize things towards the end.&lt;/p&gt;
&lt;p&gt;I even ran it through some of the iPhone performance gathering tools and saw that it was spending half the time in the simulation and half the time rendering. A bit surprising, but it&amp;rsquo;s not like I had much to compare it against since this was my first performance-intensive iPhone app.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I haven&rsquo;t started doing any real performance optimizations on my iPhone app yet. I pretty much ported it from the original PC version, saw that it was running rather slow (2-3 fps) so I changed the number of elements on the screen until it was an &ldquo;acceptable&rdquo; 15 fps and left it there until I had time to come back and optimize things towards the end.</p>
<p>I even ran it through some of the iPhone performance gathering tools and saw that it was spending half the time in the simulation and half the time rendering. A bit surprising, but it&rsquo;s not like I had much to compare it against since this was my first performance-intensive iPhone app.</p>
<p>That was until this morning. Prompted by some of the comments in my previous post, I did a quick search about the iPhone floating-point performance. I had heard conflicting information on it: does it have hardware floating-point support? do you have to use fixed-point numbers for best performance? Apple is very tight-lipped about the specific hardware specs of the iPhone, which seems very strange to those of us coming from a console background. But people have been able to determine that the CPU is a 32-bit RISC <a href="http://www.arm.com/products/CPUs/ARM1176.html">ARM1176JZF</a>. The good news is that it have a full floating-point unit, so we can continue writing math and physics code the way we do in most platforms.</p>
<p>The ARM CPU also has <a href="http://www.arm.com/products/CPUs/archi-thumb.html">an architecture extension called the Thumb</a>. It seems to be a special set of 16-bit bitcodes that claim to improve performance. I image the performance increase comes from a smaller code footprint and faster code fetching and processing. As a bonus, you also get a smaller memory footprint, so it seems like a win for a lot of mobile platforms. XCode comes with the option to generate Thumb code turned on by default.</p>
<p>But, and this is a <strong>huge</strong> but, it seems that floating point operations cause the program to switch back and form between Thumb mode and regular 32-bit mode. I would be interesting to look at the assembly generated, but I haven&rsquo;t had time to do that yet. So the more floating-point calculations you do, the less of performance gain you&rsquo;ll get from Thumb optimizations. Or, in the extreme, you might even get a performance degradation.</p>
<p>Most 3D games are very floating-point intenstive, and my app is no different, so I decided to turn off Thumb code generation on a whim. The results:</p>
<ul>
<li>Thumb code generation ON (default): 15 fps</li>
<li>Thumb code generation OFF: 39 fps</li>
</ul>
<p>Whoa!!! That&rsquo;s a saving of 41 ms per frame! That has to be the optimization with most bang for the time spent on it that I&rsquo;ve ever done. This also probably means that my app is now totally render-bound, which is good news. I&rsquo;m sure I can optimize tons of stuff there</p>
<p>So if you&rsquo;re doing any kind of a 3D game, <em>turn off Thumb code generation</em>. Now!</p>
<p><em>Edit:</em> I realized I never explained how to turn the Thumb code generation off! Oops. Go to your project settings, add a new User-Defined setting called: GCC_THUMB_SUPPORT and set it to NO. That simple (but surprisingly there wasn&rsquo;t an already existing setting to check it on and off).</p>
<p><img alt="thumb" loading="lazy" src="/break-that-thumb-for-best-iphone-performance/images/thumb.png" title="thumb"></p>
]]></content:encoded></item><item><title>iPhone from A Game Developer's Perspective: The iPhone API</title><link>https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-the-iphone-api/</link><pubDate>Mon, 05 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-the-iphone-api/</guid><description>&lt;p&gt;Apple is very aware that a crucial aspect to the success of a new platform is getting developers on board. Requiring a Mac for all iPhone development isn&amp;rsquo;t a good start. That&amp;rsquo;s the first barrier of entry for a lot of developers, like me, who came from a Linux or Windows background. Strike one. Objective C, even though I have come to like it, isn&amp;rsquo;t exactly a hot, popular language (although &lt;a href="http://www.google.com/trends?q=%22objective+C%22"&gt;that&amp;rsquo;s changing a bit&lt;/a&gt;). Strike two. Fortunately, Apple doesn&amp;rsquo;t strike out and gets everything else right. They provide a top-notch development environment, tools, and great APIs.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t worry, I&amp;rsquo;m not going to get into the details of the iPhone API. You can get all that and more from &lt;a href="http://developer.apple.com/iphone/index.action"&gt;Apple&amp;rsquo;s iPhone development&lt;/a&gt; web site. I&amp;rsquo;m just going to talk about my experience starting with a new set of APIs and how they hold up in the process of a full project development.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Apple is very aware that a crucial aspect to the success of a new platform is getting developers on board. Requiring a Mac for all iPhone development isn&rsquo;t a good start. That&rsquo;s the first barrier of entry for a lot of developers, like me, who came from a Linux or Windows background. Strike one. Objective C, even though I have come to like it, isn&rsquo;t exactly a hot, popular language (although <a href="http://www.google.com/trends?q=%22objective+C%22">that&rsquo;s changing a bit</a>). Strike two. Fortunately, Apple doesn&rsquo;t strike out and gets everything else right. They provide a top-notch development environment, tools, and great APIs.</p>
<p>Don&rsquo;t worry, I&rsquo;m not going to get into the details of the iPhone API. You can get all that and more from <a href="http://developer.apple.com/iphone/index.action">Apple&rsquo;s iPhone development</a> web site. I&rsquo;m just going to talk about my experience starting with a new set of APIs and how they hold up in the process of a full project development.</p>
<h2 id="starting-out">Starting Out</h2>
<p>Apple has done a great job holding the hand of developers new to the iPhone. As soon as you sign up for iPhone development, you&rsquo;ll have access to several &ldquo;Getting Started&rdquo; documents and videos. Some of the videos are a bit on the fluffy, advertising side (&ldquo;look at our new platform, it&rsquo;s sooo cool!&rdquo;), but they&rsquo;re not a bad intro anyway. The docs on the other hand are pure gold. They&rsquo;re a perfect introduction but with a fair amount of detail as well. They cover everything, from UI, to graphics and sound, to platform-specific features such as the accelerometer. I still find myself referring back to those every so often.</p>
<p>When the &ldquo;Getting Started&rdquo; docs aren&rsquo;t enough, you have a full reference of all the classes and APIs at your fingertips, both online and through the XCode help system. I found the quality of the class reference to be pretty good. Usually, when something isn&rsquo;t clear from the function name, the help is good at clarifying things.</p>
<p>I have to admit that I&rsquo;m not a read-the-manual-first kind of guy. So while all those documents are great, and I use them a lot now, that&rsquo;s not how I started out. Apple provides a bunch of sample code, covering all the major APIs, so I just downloaded the ones I was interested in, compiled them and fired them up. Then I used the docs to answer my questions about what the code was doing. The Crash Landing project was a perfect example of how to get started with games. I must have spent a whole day just pouring over that code the day I got my hands on the SDK.</p>
<p>Keep in mind that while Apple does a great job of getting the experienced developer up and running on the iPhone, they&rsquo;re certainly not catering to new programmers. It&rsquo;s a shame because the iPhone is such a fun, little platform, that I could see lots of kids wanting to jump in and getting their first real programming experience there. I hope that books and other resources pop up with that audience in mind.</p>
<h2 id="low-level-stuff">Low Level Stuff</h2>
<p>Things will look very familiar at the bottom of the API chain. Most of the low-level functionality can be accessed through pretty standard POSIX libraries: thread, file IO, sockets, etc,Â  all in straight C. My code ported over to using this libraries without having to make a single change.</p>
<p>As game developers, the first thing that we worry about is how are we going to do graphics. Fortunately, the iPhone includes an OpenGL implementation, so that&rsquo;s very familiar territory. Specifically, it&rsquo;s <a href="http://www.khronos.org/opengles/1_X/">OpenGL ES 1.1</a> with a few extensions thrown in. The <a href="http://toucharcade.com/2008/07/07/under-the-hood-the-iphones-gaming-mettle/">hardware itself</a> is a fixed-function PowerVR chip with hardware vertex processing and texture combiners. Very 1999 :-) All of that makes writing 3D graphics app on the iPhone a breeze, even if <a href="http://www.glbenchmark.com/phonedetails.jsp?benchmark=pro&amp;D=Apple%20iPhone&amp;testgroup=lowlevel">performance isn&rsquo;t top notch</a>. At least they didn&rsquo;t throw yet another proprietary API at us.</p>
<p>Surprisingly, the online help falls short with OpenGL. There are actually hardly any docs on that, and they mostly cover a couple functions to interface with their view system. I guess they figured you can just go to the internet and <a href="http://www.khronos.org/opengles/sdk/1.1/docs/man/">read all about it there</a>, but I would have expected them to integrate them with the rest of the references at least.</p>
<p>OpenGL meshes relatively well with the user interface libraries, in the sense that you can render to almost any surface and combine it with other user interface elements. Unfortunately, it seems that putting any user interface views on top of OpenGL causes pretty major performance hits, so the integration isn&rsquo;t perfect.</p>
<p>I haven&rsquo;t used it yet, but Apple also provides the <a href="http://connect.creativelabs.com/openal/default.aspx">Open AL API</a> for 3D sound. Again, props to Apple for sticking to an existing API.</p>
<h2 id="cocoa-touch">Cocoa Touch</h2>
<p>This is where the real fun starts. At least for me, this is all new territory. Mac programmers should be a lot more familiar with it. Cocoa Touch are the libraries for all the high-level user interface and accessing device-specific features. Since the iPhone is such an interface-centric device, this is where a lot of your time is going to be spent. The exception is if you decide to make a game that is 100% OpenGL, user interface and all. In that case, you&rsquo;ll only be using this layer to access a few things, like touch inputs and accelerometer readings.</p>
<p>My impression coming to Cocoa Touch from an MFC/WTL/.Net background and no Cocoa experience was a breath of fresh air. Sure, the interface on the iPhone is simpler than the horrible monstrosities you can create with MFC, so maybe that&rsquo;s why the API seems simpler. But whatever the reason, it just makes sense. You have one window, views, and view controllers. Once you get how they relate, the rest just comes together. I find myself guessing how things should be and getting it right most of the time. That tells me they&rsquo;re doing something right (for the record, I never manage to guess anything with the .Net framework and it&rsquo;s always a struggle).</p>
<p>When something isn&rsquo;t obvious, you can look it up in the extensive online help, or just crack open the header file and look at what properties each class exposes. The class hierarchy isn&rsquo;t too crazy, and each level adds a manageable number of functions.</p>
<p>It&rsquo;s also really easy to extend controls and create your own versions to have special behaviors or even draw them in different ways. To me it was always a pain to create custom controls in MFC with their own rendering, but here it&rsquo;s a breeze.</p>
<p>I also really like how a lot of controls don&rsquo;t own your data, or even keep a copy that you need to refresh, but simply ask you for it when they need it. For example the picker (which you can quickly guess it&rsquo;s called UIPickerView) will ask a delegate how many columns and rows to display and what data or views to render in each of them. Nice and simple.</p>
<p>We&rsquo;re done with the fan boy raving. Not everything is perfect and some things are downright annoying.</p>
<p>Initialization of views and view controllers can be a bit weird. Sometimes the initFromNib gets called, sometimes it&rsquo;s the viewDidLoad, sometimes it&rsquo;s none of those and I have to hook up the loadView function, and sometimes I just have to make one myself. All depending on how the particular view gets created. Annoying.</p>
<p>Then there are some bugs and weird behaviors that you have to put up with. Because Apple doesn&rsquo;t provide the full source code, you can&rsquo;t just fix them or copy them and make your own version. Some controls are pretty elaborate so writing them from scratch is quite time consuming. For example, the segment control behaves as a toggle if you only have two segments, but as a button if you have more than two. There is a boolean variable that allows you to turn the toggle behavior off, but, guess what, it&rsquo;s protected. So to make such a simple change, you need to create your own class and extend the UISegmentedControl. Doh!</p>
<p>Sometimes you&rsquo;re not even so lucky. Looking at the header file for the UIPickerView class I noticed there was a flag to turn off the sound it makes when rotating the wheels. But it was marked as private (as @package actually), so I couldn&rsquo;t do a thing about it. Double doh!</p>
<p>And it&rsquo;s more than a flag here or there. Maybe you&rsquo;d like to change the background of the picker, or the way the selection works? Out of luck. That&rsquo;s all neatly wrapped up inside the picker class itself and you have no access to it. If you want to make a change, you need to reimplement it all from scratch. Hopefully Apple will continue refining the API and exposing more functionality where needed.</p>
<p>All of this leads me to my number one complaint about the Cocoa Touch API. It&rsquo;s something that annoys me profoundly and I can&rsquo;t believe Apple is doing. <em>The API you have exposed to you is different than the one Apple uses internally</em>. Why oh, why?? It violates everything I hold true and sacred about library and API design. I understand their wish to keep thing simple and clean, and to provide good documentation to everything is there. They managed to do those things admirably well. But why not provide whatever API calls they consider to be &ldquo;expert&rdquo; without documentation and a big warning saying you&rsquo;re on your own? Why???</p>
<p>But wait, it gets better. Apple has been actively rejecting apps from the App Store from people who went to the trouble of reverse engineering the libraries and calling undocumented functionality from them. What is up with that? Is it Apple&rsquo;s way of ensuring future compatibility? Then how are their own apps going to work when changes happen since they&rsquo;re obviously using a bunch of undocumented features. Not only that, but <a href="http://technologyexpert.blogspot.com/2008/12/app-store-incorrectly-rejects-app-over.html">they get it wrong sometimes</a>!</p>
<p>I thought this was as bad as it was going to get, but wait, there&rsquo;s more. Apple is playing favorites. So if you&rsquo;re a big company and have two Os in your name (and your name doesn&rsquo;t start with M) then you get to <a href="http://arstechnica.com/news.ars/post/20081126-google-admits-to-using-undocumented-api-in-google-mobile-app.html">use their undocumented APIs</a> without getting rejected. How totally annoying is that?</p>
<h2 id="all-in-all">All In All&hellip;</h2>
<p>Apart from the questionable decisions of what to expose in the API and a few stray bugs, the iPhone has a great set of APIs to develop for. I found it really easy to get into them and became productive in no time. If only they would expose the full functionality, it would be an almost perfect setup.</p>]]></content:encoded></item><item><title>2009: The Year of The Indie Developer?</title><link>https://gamesfromwithin.com/2009-the-year-of-the-indie-developer/</link><pubDate>Thu, 01 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/2009-the-year-of-the-indie-developer/</guid><description>&lt;p&gt;A few days ago I went out to lunch with some friends and they brought up an interesting thought: Will 2009 be the year of the indie developer?&lt;/p&gt;
&lt;p&gt;I loved the sound of that! I&amp;rsquo;ve been an indie developer for a year and a half, and I&amp;rsquo;m seeing &lt;a href="http://appyentertainment.com/"&gt;more&lt;/a&gt; &lt;a href="http://www.torpexgames.com/index.php"&gt;and&lt;/a&gt; &lt;a href="http://2dboy.com/"&gt;more&lt;/a&gt; people taking tha route. I think indie development is necessary for a healthy game development industry. Where else are people going to try weird ideas, experimental development techniques, an commercially unproven designs? I think it&amp;rsquo;s a sign of maturity that we&amp;rsquo;re seeing a need filled by independent development next to the Maddens and Worlds of Warcraft and other chart-toppers.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A few days ago I went out to lunch with some friends and they brought up an interesting thought: Will 2009 be the year of the indie developer?</p>
<p>I loved the sound of that! I&rsquo;ve been an indie developer for a year and a half, and I&rsquo;m seeing <a href="http://appyentertainment.com/">more</a> <a href="http://www.torpexgames.com/index.php">and</a> <a href="http://2dboy.com/">more</a> people taking tha route. I think indie development is necessary for a healthy game development industry. Where else are people going to try weird ideas, experimental development techniques, an commercially unproven designs? I think it&rsquo;s a sign of maturity that we&rsquo;re seeing a need filled by independent development next to the Maddens and Worlds of Warcraft and other chart-toppers.</p>
<p>I think 2008 will go down as the year that indie games made it to the big time: <a href="http://braid-game.com/">Braid</a>, <a href="http://www.torpexgames.com/games.php">Schizoid</a>, and <a href="http://www.worldofgoo.com/">World of Goo</a> are just the top of the iceberg. It showed that it was possible to become an indie developer and make a living from it. 2009 has to be the year that indie development really explodes, right? The trend is certainly there. I&rsquo;m constantly hearing about people or even whole teams leaving <a href="http://www.ea.com/">large</a> <a href="http://www.activision.com/index.html">development</a> <a href="http://www.ubi.com/">houses</a> and starting their own, small companies. These developers are not trying to become the next EA, but they want to keep things small, creative, and, above all, fun.</p>
<p>If the only path for indie game development were downloadable console games on XBLA and PSN, the future wouldn&rsquo;t look so bright. I used to be really excited about those platforms, but the restrictive zeal of Microsoft and Sony, the dingy royalty deal on XBLA, plus the high-development costs required for most games in those platforms, makes them very difficult to develop for and make any money from them. More and more, I&rsquo;m hearing of donwloadable console titles with budgets around a million dollars. A million dollars!! That&rsquo;s &ldquo;just&rdquo; a tad bit out of my indie pocket range.</p>
<p>Fortunately there are other paths. We have the usual PC market, which seems to be on its way to being abandoned by the major players but leaves a void for indies. <a href="http://www.bit-blot.com/aquaria/">Some</a> <a href="http://www.wolfire.com/lugaru">guys</a> seem to be doing well there, especially if you consider the Mac and Linux markets in addition to Windows.</p>
<p>Then there&rsquo;s Nintendo&rsquo;s <a href="http://www.nintendo.com/wii/wiiware">WiiWare</a>, which seems surprisingly much more open than the Xbox360 or PS3. I don&rsquo;t have any friends who are personally developing for WiiWare, but I hear the barriers of access are not insurmountable. I&rsquo;d love to see some sales numbers though. Nintendo certainly has the name to attract players and developers. Maybe they need to open up their DS development a bit too. <a href="http://www.bobsgame.com">Bob would like that</a> for sure!</p>
<p>And then we have our last, best hope for indie game development: The iPhone <a href="#note1">[1]</a>.</p>
<p>The iPhone seems to hit all the right marks: Hardware advanced enough that you can develop really interesting and good-looking games, yet simple enough that one or two people can create a top title. Very open (<a href="http://developer.apple.com/iphone">the SDK and tools are available for free</a> to anyone!!) but with a very clear <a href="http://www.apple.com/iphone/appstore/">distribution channel</a>.</p>
<p>Given the low prices of games (between $0.99 and $10) on the iPhone, not only is it possible to make great games with a team of two people, but actually having larger teams can make development much less profitable. I can&rsquo;t imagine how EA or Maxis are making any money from their iPhone games if they put even just 10 or 20 people to work on them for a few months.</p>
<p>In order for indies to succeed in the app store, it&rsquo;s important that we get enough visibility. Right now, the big money is on the top lists that Apple publishes which are unfortunately out of reach for most of us. A trend I&rsquo;ve noticed lately is that big publishers are starting to elbow out indies out of the <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewCustomPage?name=pageiTunes2008_Apps">Top Ten charts</a>. I hope that&rsquo;s not a trend that continues much further.</p>
<p>I&rsquo;m glad to see that the app store has related links when you browse a product, and also a variety of independent web sites that are appearing trying to sort the iWheat from the iChaff. It&rsquo;s a start, but we need more initiatives along those lines. In the meanwhile, support your indie iPhone developers. Or at least go out of your way to learn a bit more about them. If you haven&rsquo;t seen it already, check out the <a href="http://www.newyearappblowout.com/">New Year&rsquo;s App Blowout Sale</a> and pick up <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298155609&amp;mt=8">Sneezies</a>, <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=299876012&amp;mt=8">Up There</a>, and <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=294789951&amp;mt=8">Mouse House</a>. All three totally adorable, very polished games.</p>
<p>Happy New Year 2009 to everybody! I&rsquo;m sure this year will bring a lot of surprises and interesting developments.</p>
<p>[1]Yes, I shamelessly stole that line from <a href="http://babylon5.warnerbros.com/">my favorite sci-fi show</a>.</p>]]></content:encoded></item><item><title>iPhone from A Game Developer's Perspective: Objective C</title><link>https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-objective-c/</link><pubDate>Tue, 30 Dec 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-objective-c/</guid><description>&lt;p&gt;I have a feeling I don&amp;rsquo;t fit the profile for the average iPhone developer. I bet a lot of them come from Mac or Web development backgrounds. On the other hand, I come from over the years of professional game development on consoles and PCs, which gives me a different perspective on things. When I hear developers complaining about Apple&amp;rsquo;s approval process to put something on the App Store, I can&amp;rsquo;t help but laugh and wish they had a taste of submitting an Xbox or PS3 game for approval. Now, that&amp;rsquo;s a real bitch! On the other hand, long-time Mac developers will be throwing around all these API names and classes like everybody learned them in kindergarden.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve only been doing iPhone development for a few months, so I don&amp;rsquo;t claim to know everything. But they have been some intensive couple of months, that&amp;rsquo;s for sure. This is my attempt to share my experiences, and hopefully encourage more game developers to take the leap and consider this really fun little machine.&lt;/p&gt;
&lt;p&gt;As I explained in a previous post, I was a Mac-virgin. Sure, I had used one here and there, but never as my primary platform. Not only was I able to get up to speed and functional in a matter of days, but I totally love it and switched to it as my main computer. So, with that out of the way, how about the iPhone development itself? Over the next few days (or weeks, depending how busy I get), I&amp;rsquo;ll try and cover the major areas of iPhone development that I&amp;rsquo;ve experienced so far.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s get the most obvious one out of the way: &lt;a href="http://en.wikipedia.org/wiki/Objective_C"&gt;Objective C&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I have a feeling I don&rsquo;t fit the profile for the average iPhone developer. I bet a lot of them come from Mac or Web development backgrounds. On the other hand, I come from over the years of professional game development on consoles and PCs, which gives me a different perspective on things. When I hear developers complaining about Apple&rsquo;s approval process to put something on the App Store, I can&rsquo;t help but laugh and wish they had a taste of submitting an Xbox or PS3 game for approval. Now, that&rsquo;s a real bitch! On the other hand, long-time Mac developers will be throwing around all these API names and classes like everybody learned them in kindergarden.</p>
<p>I&rsquo;ve only been doing iPhone development for a few months, so I don&rsquo;t claim to know everything. But they have been some intensive couple of months, that&rsquo;s for sure. This is my attempt to share my experiences, and hopefully encourage more game developers to take the leap and consider this really fun little machine.</p>
<p>As I explained in a previous post, I was a Mac-virgin. Sure, I had used one here and there, but never as my primary platform. Not only was I able to get up to speed and functional in a matter of days, but I totally love it and switched to it as my main computer. So, with that out of the way, how about the iPhone development itself? Over the next few days (or weeks, depending how busy I get), I&rsquo;ll try and cover the major areas of iPhone development that I&rsquo;ve experienced so far.</p>
<p>Let&rsquo;s get the most obvious one out of the way: <a href="http://en.wikipedia.org/wiki/Objective_C">Objective C</a>.</p>
<p>Somehow, its very mention seems to fill people with fear. When other programmers hear I&rsquo;m doing iPhone development, they lower their voice, they get closer, and ask &ldquo;Do you _have_ to write it in Objective C?&rdquo; I think the main reason people are scare of it is because it&rsquo;s not very well known. It&rsquo;s not a sexy newcomer that the web is buzzing about like Rails, or a language with the backup of corporate giants like C# or Java. Objective C has been around since the early 80s, which is pretty amazing because it feels very modern in a lot of its features. Frankly, I&rsquo;m surprised that Microsoft chose to create C# instead of adopting/extending Objective C (or maybe I&rsquo;m not <strong>that</strong> surprised coming from Microsoft&ndash;OK, that was the last dig at MS and C# for today. Promise).</p>
<p>I had never used Objective C before I started doing iPhone development, but it was a breeze to get up to speed coming from a strong C and C++ background. The most important thing is that the interop between Objective C and C/C++ is nearly flawless. It&rsquo;s a pleasure to call Objective C functions from C++ and the other way around. So much so that the lines get all blurred between what is what. Take that C#! (oops, so much for my promise).</p>
<p>Objective C is organized like C++, with header files and implementation files. That&rsquo;s both good and bad. Good because it&rsquo;s familiar, it gives you a good separation between the public interface of a class and its implementation, and allows for fast build times. But it&rsquo;s bad because there is some annoying duplication between both files. Fortunately, Objective C gets this one right (again), and allows you to keep the header file to purely the public interface of the class. That means I can declare all the private member functions in the implementation file, which keeps duplication to a minimum.</p>
<p>A word of warning: You&rsquo;ll probably have to change all your .cpp files to be .mm so they compile as Objective C and you can freely include any Objective C headers. Also note that Objective C files are usually .m which only parses C header files. If you need to call C++ files you need to make them .mm, or you&rsquo;ll get some really bizarre errors.</p>
<p>If you&rsquo;re really a died-in-the-wool C++ fanatic, you can isolate yourself from all the Objective C stuff by writing a few wrappers that interface with the operating system. If not, you can go with the flow and embrace it and use it when it&rsquo;s needed.</p>
<p>Assuming you&rsquo;re willing to look at Objective C, how is it coming from a C++ game programming background? At first glance it&rsquo;s a bit ugly. I admit it. It looks like it&rsquo;s full of - and + and [[square:brackets] everywhere]. But it&rsquo;s very superficial. Objective C is a superset of C++, which means they introduced a different way to create Objective C classes (as opposed to C++ classes). The worst thing about the brackets, which are used for sending messages to objects, is that typing them is cumbersome. I often find myself having to move back to the beginning of the line to add new brackets as I&rsquo;m making new function calls.</p>
<p>Internally things are much more dynamic than C++, and instead of member function calls they&rsquo;re really messages that get passed around. That makes it easier to deal with null objects or objects that might or might not implement specific interfaces. I don&rsquo;t know if you can add new message handlers on the fly, but I suspect you could (although why you&rsquo;d want to do it other than for geek achievement points is beyond me&ndash;I&rsquo;ve certainly never felt the need to do it).</p>
<p>One of the features that I&rsquo;m using quite a bit are properties. You can declare member variables as properties, tag them with what kind of access is permitted (read-only, read-write, whether you want to take ownership or not, whether it&rsquo;s an atomic assignment, etc), and all the code is automatically provided for you. Nice time saver.</p>
<p>Protocols are also a nice, clean way to provide interfaces. Certainly much better than the madness of C++! It makes working with objects that implement certain interfaces very easy. It&rsquo;s also really easy to pass &ldquo;pointers&rdquo; to specific member variables through the use of selectors.</p>
<p>Enough with the raving. What&rsquo;s not to like? Only a couple of things, really. Or at least so far. Ask me again in a year and I&rsquo;ll probably have a laundry list of complaints. I doubt it will ever reach my level annoyance with C++ though. That&rsquo;s pretty much impossible.</p>
<p>My biggest complaint about Objective C is that, get this, C++ constructors for member variables in Objective C classes are not called. Yup. You read that right! I&rsquo;m sure there&rsquo;s a good reason, but it does suck. Fortunately most of the Objective C code is high level classes, so it&rsquo;s OK to new the C++ classes I need to work with. Still, it&rsquo;s annoying. I also wish that Objective C played better with namespaces, but that&rsquo;s a relatively small complaint.</p>
<p>This might sound like a strong statement, but if I were to design my ideal development language today, it would be pretty darn close to Objective C.</p>
<p>Something I still don&rsquo;t know much about: Performance. I haven&rsquo;t been doing much profiling on the iPhone yet, and all my performance-sensitive parts are written in C++. Still, I&rsquo;d be curious to see how much overhead Objective C adds on top of C++. I suspect that a fair bit given the message-passing architecture and the more dynamic nature of the language.</p>
<p>Someone asked me what am I using for unit testing with Objective C. Hmm&hellip; errr&hellip; I&rsquo;m not doing any unit testing in Objective C. There I said it :-) Not yet anyway. I&rsquo;m sure I will as soon as I start using more of it. Most of the Objective C code is high-level code interfacing with the iPhone API, so I haven&rsquo;t felt much the need to use TDD with it. If anybody has some recommended Objective C unit-testing frameworks that are lightweight and minimalistic, I&rsquo;d love to hear it.</p>
<p>If you&rsquo;re interested in learning Objective C, <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/ObjC.pdf">this document</a> was the best resource I found to learn Objective C. It&rsquo;s simple enough that you can use it to get up to speed, but detailed enough that I still refer to it from time to time. I haven&rsquo;t felt the need for any books or any other tutorials.</p>
<p>Coming up next: The iPhone API, Xcode, and more goodies.</p>]]></content:encoded></item><item><title>Stranger in a Mac Land</title><link>https://gamesfromwithin.com/stranger-in-a-mac-land/</link><pubDate>Mon, 08 Dec 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/stranger-in-a-mac-land/</guid><description>&lt;p&gt;I&amp;rsquo;ve worked with many operating systems over the years: from the humble CP/M, to early versions of DOS, toÂ  Windows 3.0 (if you can even call that an OS), along with many different versions of Linux since 1993, a smattering of VMS, and, of course, all the recent flavors of Windows. But somehow, I always managed to avoid Apple operating systems.&lt;/p&gt;
&lt;p&gt;Starting iPhone development was a bit of a change since it required me to work exclusively under OSX and use a new IDE (XCode). I had talked to people who found the change very cumbersome and found the new environment got in their way, so I approached it with a bit of trepidation.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve worked with many operating systems over the years: from the humble CP/M, to early versions of DOS, toÂ  Windows 3.0 (if you can even call that an OS), along with many different versions of Linux since 1993, a smattering of VMS, and, of course, all the recent flavors of Windows. But somehow, I always managed to avoid Apple operating systems.</p>
<p>Starting iPhone development was a bit of a change since it required me to work exclusively under OSX and use a new IDE (XCode). I had talked to people who found the change very cumbersome and found the new environment got in their way, so I approached it with a bit of trepidation.</p>
<h2 id="its-an-os-x-world">It&rsquo;s An OS X World</h2>
<p>With my new Macbook Pro under my arm (actually, it wasn&rsquo;t new, I bought it used off Craigslist because I couldn&rsquo;t afford a new one), I embarked on an adventure to this strange, new world of OS X development.</p>
<p>Some background is necessary here: I&quot;m a minimalistic, no frills kind of guy when it comes to my preferences when working with computers (although now that I think about it, it probably applies to most other things in my life as well). The first thing I do with a new install of Windows is turn off all the GUI animations (don&rsquo;t get me started on the <a href="http://www.microsoft.com/windowsxp/using/helpandsupport/learnmore/crawford_september03.mspx">search puppy dog</a>!!), most of the sounds, all the auto-complete and auto-spellcheck features, and automatic upgrades. When I want the computer to do something, I&rsquo;ll tell it to do so. Otherwise I want it to be quiet and responsive.</p>
<p>My ideal Visual Studio setup is also pretty similar: No fancy web startup page, no animations, no autocompletions by default (unless I press CTRL-Space), out with all the toolbars, just give me two text windows side by side and control everything from keyboard shortcuts (which I&rsquo;m still using the ones from Visual C++ 6.0).</p>
<p>Needless to say, I was afraid of clashing with Mac OSX&rsquo;s environment. I had a suspicious that it was full of eye candy, GUI frills, and required a mouse for everything. Not a good match.</p>
<p>There wasn&rsquo;t as much of a learning curve as some getting-used-to. There are some Mac quirkiness that I just don&rsquo;t get: The disembodied menu on the top of the screen, the lack of change of mouse cursor when you can resize a window, or not being able to automatically restore a file to its original location from the recycle bin.</p>
<p>But those are all relatively small things that don&rsquo;t overshadow the fact that I just love this new environment. I used to like the Windows fonts, but after a week of using a Mac, I can&rsquo;t go back to those tiny, jaggedy Windows fonts. Handling of multiple monitors is perfectly integrated and works like a charm. In general, things Just Work (TM).</p>
<p>Then there are the things that I love from my time in Linux that I can&rsquo;t live without: Multiple desktops with Spaces, a decent command line shell, or being able to tweak settings directly in low-level config files.</p>
<p>And the thing that has changed how I work the most: <a href="http://www.apple.com/macosx/features/300.html#spotlight">Spotlight</a>. No need for icons everywhere, or &ldquo;Start | Programs&rdquo; or anything. Just start typing what you want and there it is. It&rsquo;s like the return of the command line on steroids. Between Spotlight, <a href="http://www.mozilla.com/en-US/firefox/features/#location-bar">Firefox smart locaton bar</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/2888">GMarks</a>, and <a href="http://labs.mozilla.com/projects/ubiquity/">Ubiquity</a>, I feel right at home. Now combine them all somehow and I&rsquo;ll be in heaven!</p>
<h2 id="but-wait-what-about-windows">But Wait, What About Windows?</h2>
<p>I ended up falling in love with OS X so much, that I quickly moved to it as my primary environment at home for everything. Frankly, these days, it&rsquo;s pretty easy for me to change environments since most of what I do is online. Just give me Firefox (or a good browser) and I&rsquo;m there: GMail, Google Calendar, Google Reader, Google Docs (hmm&hellip; I sense a theme here), and a Wiki cover most of what I do on a daily basis.</p>
<p>For the rest of the apps, almost everything I need runs under OS X: good media visualizer (Preview), photograph organizer (<a href="http://www.adobe.com/products/photoshoplightroom/">Lightroom</a>), image editor (<a href="http://www.gimp.org/">The Gimp</a>/<a href="http://www.adobe.com/products/photoshop/photoshop/">Photoshop</a>), audio editor (<a href="http://audacity.sourceforge.net/">Audacity</a>), music player (iTunes), and a few more odds and ends. OS X comes with some great utilities out of the box too, like Grab, Preview, or Activity Monitor.</p>
<p>Unfortunately, there are still a couple of things that I can only run under Windows. The main thing are games unfortunately, so I need to keep my Windows box around just for that. Although I just started playing <a href="http://en.wikipedia.org/wiki/Crack_cocaine">World of Warcraft</a> and it runs great on my Mac. Thanks Blizzard! Apart from that, every so often I need to do something in Visual Studio, or run some application I wrote in .Net. For that, I go about it in two different ways.</p>
<p>I can run it on the Windows box itself. Instead of keeping two sets of keyboards and mice (or a switch box), I used <a href="http://synergy2.sourceforge.net/">Synergy</a> for a while. It was pretty cool being able to move the mouse cursor from one screen on the Mac to the screen on Windows and continue working there, and that might be a great solution if you&rsquo;re working 50-50 on both platforms. In my case, it was more like 90-10 at the time (more like 99.9 to 0.1 now), so it felt a bit of a waste to have a full monitor dedicated to Windows. Instead, I decided to use Remote Desktop to control my Windows computer from the Mac. Amazingly enough, Microsoft wrote a <a href="http://www.microsoft.com/mac/products/remote-desktop/default.mspx">Remote Desktop app for OS X</a> that works like a charm, much better than some of the VNC programs I tried.</p>
<p>Whenever I don&rsquo;t need to run something that is performance critical, I reach for <a href="http://www.vmware.com/products/fusion/">Fusion</a>. I&rsquo;ve tried many products in the past that claim to run programs for another platform in your own computer: Wine, CrossOver Office, earlier versions of VMWare, but they&rsquo;re always plagued by problems and incompatibilities. VMWare Fusion really surprised me by running anything I threw at it flawlessly, including Quicken (yes, I need to switch to <a href="http://www.mint.com/">Mint</a> or <a href="http://www.buxfer.com/">Buxfer</a>) and some hardware-accelerated 3D programs (those were a bit chuggy though, but they worked). And the coolest feature ever: Unity&ndash;I can run Windows apps in a window of their own directly on the Mac desktop. Totally awesome! On top of all that, I can have multiple snapshots, restore earlier states, and I can even run other operating systems like different versions of Linux. A geek&rsquo;s true dream!</p>
<p>Some people will claim that I have drunk from the Apple kool-aid, and to a certain extent, they&rsquo;re right. But I&rsquo;d like to think I was swayed by many good reasons having to do with using the computer and being more productive, rather than Apple&rsquo;s brainwashy, lifestyle marketing message. That and the smooth feel of the Macbook against the palm of my hands, its sleek profile, and sexy design. :-)</p>
<p>What about XCode and development? That&rsquo;s another story for another day.</p>
]]></content:encoded></item><item><title>Brave New iPhone World</title><link>https://gamesfromwithin.com/brave-new-iphone-world/</link><pubDate>Fri, 14 Nov 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/brave-new-iphone-world/</guid><description>&lt;p&gt;I know that things have been very quiet over here for the last few weeks. Lots of stuff happening and it&amp;rsquo;s hard to find time to write sometimes. But now I should be getting back into the swing of things and updating Games from Within more regularly.&lt;/p&gt;
&lt;p&gt;The big news is that we decided to call it quits on &lt;a href="http://powerof2games.com"&gt;Power of Two Games&lt;/a&gt;. It was an amazing experience and I learned a huge amount. I&amp;rsquo;m sure we&amp;rsquo;ll write a postmortem with some of the gems we learned along the way sometime soon. Unlike most postmortems, we really don&amp;rsquo;t have any office politics, bosses to suck up to, or publishers to keep happy, we&amp;rsquo;ll be able to be brutally honest.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I know that things have been very quiet over here for the last few weeks. Lots of stuff happening and it&rsquo;s hard to find time to write sometimes. But now I should be getting back into the swing of things and updating Games from Within more regularly.</p>
<p>The big news is that we decided to call it quits on <a href="http://powerof2games.com">Power of Two Games</a>. It was an amazing experience and I learned a huge amount. I&rsquo;m sure we&rsquo;ll write a postmortem with some of the gems we learned along the way sometime soon. Unlike most postmortems, we really don&rsquo;t have any office politics, bosses to suck up to, or publishers to keep happy, we&rsquo;ll be able to be brutally honest.</p>
<p>Against my better judgement, especially with the current horrible economy, I&rsquo;m still burning the indie development candle. This time by myself and on the iPhone. I&rsquo;ll get into many more details in the future, but so far iPhone development has been surprisingly fun and smooth.</p>
<p>One of the most attractive things about iPhone development is the short projects. Some of the top selling iPhone applications were written in just a week or two. The game/toy I&rsquo;m working on is a bit more involved than a <a href="http://www.maniacworld.com/iPhone-Fart-App-Banned.html">fart generator</a> or a <a href="www.maniacworld.com/iPhone-Fart-App-Banned.html">rotary dial</a>, so I expect it will take me a total of three months. Still, much better than trying to make a game for XBLA or PSN!</p>
<p>Another big plus of iPhone development is the approval process. Yes, Apple needs to approve the application, but the process is infinitely simpler than trying to certify your PS3 or 360 game. I haven&rsquo;t gone through that myself yet, but that&rsquo;s what I keep hearing from other developers.</p>
<p>And then you have the App Store. Ah, the App Store. A captive audience of impulse-buyers with their credit cards already in the system because of iTunes. Genius. The cut that Apple takes is very reasonable, just 30%. Let&rsquo;s hope they keep it that way and don&rsquo;t pull <a href="http://kotaku.com/359668/microsoft-cuts-indie-royalties-in-half">the Microsoft move</a> on us!</p>
<p>So, what&rsquo;s not to like? That everybody and their grandmother is writing iPhone apps and throwing them on the App Store on the hopes of making a quick buck. And the worst thing is that it&rsquo;s actually working. So people keep gambling with crappy apps hoping to become the next <a href="http://www.hottrix.com/software/">iBeer</a> or <a href="http://www.theblimppilots.com/The_Blimp_Pilots/Koi_Pond.html">Koi Pond</a>. As a result, the App Store is flooded with stuff, most of it horrible, some OK, a few good, and a very few great apps. Right now the App Store interface isn&rsquo;t ideal for discovering new, high-quality games and applications, and most of the exposure is limited to the Top Seller lists. I&rsquo;m hoping in the next few months they move towards something more along the lines of Amazon.</p>
<p>And speaking of interfaces, whose retarded idea was it to only be able to access the App Store from within iTunes? I like Apple, and I&rsquo;m totally digging Mac OS X (more on that later), but I hate having to use a slow, bloated application to do something that amounts to browsing a few web pages. Besides, you&rsquo;d think they would hook more people by making it more accessible. Oh well. That&rsquo;s not changing any time soon.</p>
<p>Stay tuned for more updates on my iPhone development adventures and maybe, just maybe, an early glimpse of the game :-)</p>
]]></content:encoded></item></channel></rss>