<?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>Idevblogaday on Games From Within</title><link>https://gamesfromwithin.com/category/idevblogaday/</link><description>Recent content in Idevblogaday on Games From Within</description><generator>Hugo</generator><language>en-us</language><copyright>2004–2026 Noel Llopis</copyright><lastBuildDate>Fri, 16 Dec 2011 00:00:00 +0000</lastBuildDate><atom:link href="https://gamesfromwithin.com/category/idevblogaday/index.xml" rel="self" type="application/rss+xml"/><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>My Next Game</title><link>https://gamesfromwithin.com/my-next-game/</link><pubDate>Sat, 19 Nov 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/my-next-game/</guid><description>&lt;p&gt;&lt;img alt="Stick 2" loading="lazy" src="https://gamesfromwithin.com/my-next-game/images/stick_2.png"&gt;No, this is not an announcement of my next game (I wish). Rather, it&amp;rsquo;s a brain dump of my struggle with the process. It seems that in the game development community we often share the process of making a game and how it did afterwards. But it&amp;rsquo;s rare having some insight into what goes on before the project gets started. Where do ideas come from? Why do we pick one and not another? These are semi-coherent notes about the things I&amp;rsquo;m struggling with right now.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Stick 2" loading="lazy" src="/my-next-game/images/stick_2.png">No, this is not an announcement of my next game (I wish). Rather, it&rsquo;s a brain dump of my struggle with the process. It seems that in the game development community we often share the process of making a game and how it did afterwards. But it&rsquo;s rare having some insight into what goes on before the project gets started. Where do ideas come from? Why do we pick one and not another? These are semi-coherent notes about the things I&rsquo;m struggling with right now.</p>
<h2 id="brewing">Brewing</h2>
<p>A new game for me starts as an idea somewhere, sometime, that got jotted down into my &ldquo;game ideas&rdquo; personal wiki page. I have that page accessible 24 hours a day on my computer, iPhone, or iPad. Only while I&rsquo;m running/cycling or in the shower am I away from that page (and unfortunately, that&rsquo;s the time when most ideas seem to spark). I make a point of not censoring any ideas: If I thought that something would be neat (not just gameplay, but a setting, a visual, a mechanic, or anything), I jot it down.</p>
<p>Over time, I accumulate quite a few ideas. Every so often I review them and I might expand on some and flesh out sub-ideas. Or they might spark different ideas of their own and I jot them down too. I never delete any of them, because I&rsquo;m consciously trying to not censor anything yet. This is purely brainstorming mode. I&rsquo;ve even sent emails to friends about possible game ideas straight out of this list, crappy ideas and all.</p>
<p>During this time I&rsquo;ll rearrange the list. I&rsquo;ll move more likely ideas up, or ones that I&rsquo;m more excited about. That has the effect of a kind of <a href="http://en.wikipedia.org/wiki/Bubble_sort">bubble sort</a>, so the better ideas somehow rise to the top (except for the brilliant ones hidden in the depths somewhere).</p>
<p>This list is particularly useful when I&rsquo;m in the middle of a project and I have what seem brilliant game ideas. Do I put the project aside to do this great idea instead? No. Instead, I add it to the list with all the others. If I&rsquo;m really excited about it, I&rsquo;ll flesh it out as much as I can, but it needs to wait its turn. As you can imagine, after a few days, the idea doesn&rsquo;t seem so shiny anymore, so it was a good thing it didn&rsquo;t derail the current project.</p>
<h2 id="struggling">Struggling</h2>
<p>Eventually the time comes when I need to pick a new project, and this is where the fun and the pain start.</p>
<p>You would think a good approach might be to read the list and start evaluating ideas. In a way, that&rsquo;s what I do, but before I evaluate ideas, I need to some frame of reference to decide what&rsquo;s a worthwhile idea and what isn&rsquo;t.</p>
<p>In the past my criteria for considering a project involved the intersection of three requirements:</p>
<ul>
<li>The game must be interesting for me to work on. I want to learn something new and be excited about what I do. Not interested in cloning something or making a derivative game.</li>
<li>A game I can realistically implement with the resources at my disposal. I&rsquo;m not an artist, so that usually means not having a content-heavy game, and relying on code as much as possible (like the procedural geometry in Flower Garden&ndash;no artist modeled those flowers by hand).</li>
<li>A game that has potential to sell well on the target platforms.</li>
</ul>
<p>Unfortunately, meeting all those three requirements at the same time isn&rsquo;t easy, especially given the astounding number of games already on iOS.</p>
<p>Before I go any further, I need to step back and ask myself a very important question: Why do I want to make this next game? This is a question we indies have the luxury of asking (and answering). I think most big (and small) studios are too busy staying afloat to be able to ask anything like that (besides, the answer is almost always &ldquo;make more money&rdquo; for them).</p>
<p>It turns out the indie life is treating me very well, so making lots money isn&rsquo;t one of the main reasons to make this next game. That means I can safely remove that requirement from my previous list, which grants me a lot more freedom.</p>
<p>I&rsquo;m probably going to spend the next 6 to 10 months working on this project, so it needs to be worthwhile. Does it need to be innovative and break new ground in a way no one has seen before? Does it need to make hard-core FPS players cry to be worth considering? Does it need to be radical, pixelated, mash up 5 different genres, an win the IGF and respect of my peers?</p>
<p>It turns out none of those are the reasons that drive me to make games. In the end, when I look deep down, the reason I want to make games is for the pleasure of taking a vision from the initial idea to something people can play. It&rsquo;s the creativity involved that drives me. I imagine it&rsquo;s the same reason people are driven to write or paint. If along the way, some of those games manage to be innovative, make money, or win an IGF award, that&rsquo;d be fantastic, but in any case, the development process is its own reward.</p>
<p>Given all those factors, I can go down the list of games and evaluate each one. Does it have potential to meet those requirements and be a satisfying project? This might not come as a surprise for those of you involved in creative activities, but this is hands-down, the most difficult time of development for me. As long as I don&rsquo;t have a project picked, my mind is constantly going over this. Anything I read, see, or hear is filtered and analyzed thinking of how it would fit in a game. During this time I&rsquo;m often moody, volatile, and prone to depression if this goes on for too long.</p>
<p>Even though it seems I&rsquo;ll never going to be able to come up with an idea worth doing, eventually something comes along, and the next phase starts.</p>
<h2 id="prototyping">Prototyping</h2>
<p>I&rsquo;ve already <a href="/prototyping-youre-probably-doing-it-wrong/">talked about prototyping</a> <a href="/prototyping-for-fun-and-profit/">at length</a> before. I take the idea I&rsquo;m considering and I try to answer the key questions in the shortest possible time. This is the time to shoot down any bad ideas, or prove why they&rsquo;re not feasible or just boring.</p>
<p>The prototyping phase is a big high for me. It often involves manic activity and I can get a prototype done in a day or two from the initial excitement on the idea. The bad part is that most prototypes prove not to be that great, and they go back to the drawer of game ideas, and I&rsquo;m left scrambling for another idea.</p>
<p>Struggle. Prototype. Discard. Repeat.</p>
<p>I usually repeat this cycle multiple times. Each time around I get more anxious, and the lows and highs are a bit more extreme.</p>
<p>Fortunately, at least so far, eventually I find a prototype that seems worth doing. Something I can see spending the next X months of my life doing. I usually run it by a few friends whose opinion I value highly, and if they&rsquo;re excited about it too, then it becomes an internal green light and I move on to the implementation phase.</p>
<h2 id="tips">Tips</h2>
<p>Apart from asking yourself why your making a game, here are a couple of things worth keeping in mind when picking a new project. They&rsquo;re not new things and I&rsquo;ve heard them before in one form or another, but they&rsquo;re worth reiterating:</p>
<ul>
<li>Don&rsquo;t compete with big companies. They can throw a lot more resources, and, most importantly, lots of marketing behind their titles. Don&rsquo;t try to take Zynga head on. Do your own thing.</li>
<li>Don&rsquo;t chase trends. Take risks. Be different. You&rsquo;re indie and have low overheard. Take advantage of that and do things the big boys would never dare risk $50 million on.</li>
<li>Keep the scope of the project small and focused. It will be bigger than you envision anyway. By being small, you can come up with new ideas faster than big companies.</li>
</ul>
<p>How about you? What&rsquo;s your process for deciding to work on something? Do you struggle until you pick the project? Do you stick with an idea, or do you change and restart?</p>]]></content:encoded></item><item><title>Xcode 4 Trials and Tribulations</title><link>https://gamesfromwithin.com/xcode-4-trials-and-tribulations/</link><pubDate>Thu, 22 Sep 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/xcode-4-trials-and-tribulations/</guid><description>&lt;p&gt;Wether you want it or not, Xcode 4 is around to stay when it comes to iOS development. I&amp;rsquo;ve been happily comfortable with Xcode 3 for quite a while, and my first impressions of Xcode 4 left me completely cold. However, support for Xcode 3 will soon go away, so I need to get ready for the inevitable transition. Maybe I was just having a bad day when I looked at Xcode 4 for the first day. Or maybe my nightmares finally came true and I&amp;rsquo;ll be forced to look for an alternative IDE. Which one is it? Read on to find out.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Wether you want it or not, Xcode 4 is around to stay when it comes to iOS development. I&rsquo;ve been happily comfortable with Xcode 3 for quite a while, and my first impressions of Xcode 4 left me completely cold. However, support for Xcode 3 will soon go away, so I need to get ready for the inevitable transition. Maybe I was just having a bad day when I looked at Xcode 4 for the first day. Or maybe my nightmares finally came true and I&rsquo;ll be forced to look for an alternative IDE. Which one is it? Read on to find out.</p>
<p>To put all the whining and complaining that&rsquo;s about to come in perspective, I want to build some character references first. I&rsquo;ve been programming for 27 years, 13 of those professionally in the games industry, although the non-professional years I probably did just as much coding. I have used everything from emacs + make files to the gamut in IDEs: Turbo C++, Visual Studio, KDevelop, and Xcode 3 among others.</p>
<p>Contrary to popular belief, I&rsquo;m not that picky when it comes to a development environment. Or at least, it doesn&rsquo;t feel that way to me. I want the basics, that&rsquo;s all. Doesn&rsquo;t everybody want this?</p>
<ul>
<li>Have 2-3 source code windows opened side by side.</li>
<li>Build and see the output.</li>
<li>Do everything with keyboard shortcuts.</li>
</ul>
<p>There are lots of other things I want (project configuration, debugging, run tests), but those are the ones I&rsquo;m doing 99% of the time. I never had a problem doing any of those things with past development environments.</p>
<h2 id="the-hit-list">The hit list</h2>
<p>Having more tools and options is great. I love having the option to do advanced operations on my code, but I want to decide when to use those tools, not being bombarded by them. That, in a single sentence, is why Xcode 4, out of the box, is completely unusable for me.</p>
<p>Attempting to do something as simple as type code and build it is extremely frustrating. Xcode will react to me doing that by flashing all sorts of stuff on screen, bring up sidebars with messages, change which source files are displayed, draw squiggles all over my code, and flash alerts overlays. All of that, while not showing me the build output.</p>
<p>Working on Xcode is an extremely noisy (visually) and distracting experience. I understand it&rsquo;s trying help me, but it&rsquo;s failing miserably at it. I&rsquo;m trying to concentrate on what the code does, and I feel I have a parrot yelling stuff from my shoulder and flapping in front of the screen in some misguided attempt to help me code better.</p>
<p>That might work for some people, but not for me. I&rsquo;m the guy who turns off &ldquo;spell check as I type&rdquo; everywhere because I don&rsquo;t want to be taken out of flow while I&rsquo;m typing (I&rsquo;ll do a spell checking pass later on, thank you). I don&rsquo;t have notifications on my mail or Twitter; I check them explicitly when I want to. Now take that kind of annoyances and multiply it times 10 and you start getting an idea of what working on Xcode 4 is like. Xcode 4 feels like it&rsquo;s squarely designed for the texting/ADD generation.</p>
<p>Fortunately, most of it can be remedied and turned into a half-way sane environment.</p>
<p>Here&rsquo;s how to tame the noise in Xcode 4:</p>
<ul>
<li>
<p>Autocomplete is one of the worst offenders. Turn it off! Good autocomplete is awesome, but I&rsquo;d rather ask for it (with a keystroke) than have it bombard me constantly. Not just that, but it&rsquo;s so badly implemented that it will a) put shadows on top of the text I&rsquo;m typing b) replace the text I&rsquo;m typing on the fly so I can&rsquo;t even see what I typed (see screenshot below). Off with it!
<img alt="Autocomplete" loading="lazy" src="/xcode-4-trials-and-tribulations/images/autocomplete.png" title="autocomplete.png"></p>
</li>
<li>
<p>Having the whole screen flash with squiggles on and off while I&rsquo;m typing isn&rsquo;t helping in any way. Xcode is trying to &ldquo;highlight instances of selected symbol&rdquo;, which is a really useful tool, but not while I&rsquo;m typing/thinking! Not just that, but half the time it will add extra squiggles to the screen to make sure I can&rsquo;t even read the symbols themselves. So off with that one too.</p>
<p><img alt="Squiggles" loading="lazy" src="/xcode-4-trials-and-tribulations/images/squiggles.png" title="squiggles.png"></p>
<p>Here&rsquo;s one very frustrating thing: When I turn off the option to automatically highlight instances of the selected symbol from the settings, I lose the ability to do that at all. Yes, you heard that right: I can&rsquo;t (as far as I can tell) press a key and have the IDE highlight all the instances on demand. No sir, that&rsquo;s not the way it was intended.</p>
</li>
<li>
<p>Continuing with the theme of noise and distractions, having a sidebar popup and start showing me errors with my code as I&rsquo;m typing is also definitely NOT helping. Fortunately we can turn off &ldquo;Show live issues&rdquo; in the general settings.</p>
</li>
<li>
<p>One thing that Xcode 4 appeared to have gotten right is the idea of showing multiple source files at the same time. Now many IDEs do that by default these days, so that was a plus. Unfortunately, it&rsquo;s part of the &ldquo;smart&rdquo; assistant. As a general rule, I end up turning off anything with the word &ldquo;smart&rdquo; in it, and this is no exception. The assistant tries to present &ldquo;relevant&rdquo; files to the one I&rsquo;m working on. No, no, no, no! *I* want to decide what to display and what to work on. Just get out of the way and let me do that easily. You can turn off the view to &ldquo;Manual&rdquo;, which helps a huge amount.</p>
</li>
</ul>
<p>Just those changes make Xcode 4 into something that at least I can type into and not get sick at my stomach. We&rsquo;re making progress.</p>
<p>Now I can finally build and&hellip; everything goes wrong. Xcode doesn&rsquo;t show me the build output and it decides to flash a &ldquo;build completed&rdquo; screen overlay in case I looked away in the two seconds it took to build. Seriously? Maybe my attention was drawn into some of the flashing squiggles and I forgot it was building.</p>
<p><img alt="Alert" loading="lazy" src="/xcode-4-trials-and-tribulations/images/alert.png" title="alert.png"></p>
<p>Fortunately for my sanity, it&rsquo;s possible to fix both those things. The alert is easy: Go to behaviors, &ldquo;Build succeeds&rdquo; and turn off &ldquo;Show bezel alert&rdquo; (make sure it&rsquo;s off for all the others while you&rsquo;re there).</p>
<p>The other one is a bit trickier, but it&rsquo;s certainly possible. Set up the &ldquo;Build starts&rdquo; behavior to open a named tab and go to the current log. Like this: <img alt="Behaviors" loading="lazy" src="/xcode-4-trials-and-tribulations/images/behaviors.png" title="behaviors.png"></p>
<p>Now when you build your project, you&rsquo;ll get to see something sane like this. It might initially be as a tab, but you can drag that out and make it into a separate window of its own so it doesn&rsquo;t obscure the source code window: <img alt="Build" loading="lazy" src="/xcode-4-trials-and-tribulations/images/build.png" title="build.png"></p>
<p>You should be able to navigate through any issues found during the build with Cmd + &lsquo;, or, if you like the fancy issue display, press Cmd + 4. Things are so much better when you initiate them on demand rather than when they&rsquo;re forced on you!</p>
<p>Finally, a couple minor UI annoyances that are easily fixed:</p>
<ul>
<li>The toolbar is positively huge. I feel crammed in the high-res 15&quot; MBP (1680 x 1050), so I can&rsquo;t imagine how anyone works with something smaller. In any case, hiding the toolbar helps tremendously. As a bonus, the setting is per window, so your source code windows get the extra real estate, but the build output window keeps the toolbar so you have easy access to changing the target platform.</li>
<li>Line wrap is on by default. Seriously? Off.</li>
</ul>
<h2 id="the-suck-list">The suck list</h2>
<p>If that was everything, I&rsquo;d be happy. It means that even though Xcode 4 ships with retarded defaults, it can be whipped into shape into something usable. Unfortunately, there are a two major things I haven&rsquo;t found a workaround for:</p>
<ul>
<li>
<p>Can&rsquo;t build a single file. Someone at Apple, in their infinite wisdom, decided that building a single file was obsolete with the awesome new feature of &ldquo;show live features&rdquo;. Except that &ldquo;show live features&rdquo; sucks and has to be turned off. Apparently you either take it their way, or the highway, because there isn&rsquo;t an alternative. As with the case of highlighting symbol instances, there isn&rsquo;t a command I can use to &ldquo;show live features&rdquo; on demand.</p>
<p>The alternative is doing a full build. Most of the time that&rsquo;s fine, but whenever you&rsquo;re doing one of those refactorings that breaks half the codebase, then you&rsquo;re really screwed. The only way I can stay focused in a case like that is by cleaning up one file at the time, but this makes it impossible as you keep getting errors from all over the codebase. And as you fix one, the first error in the next build might be in a different file. Very annoying to say the least, especially because this was working and they removed it on purpose. I never file radar bugs (long story), but I made an exception just for this.</p>
</li>
<li>
<p>Build configurations and schemes. Did you notice that when you built the project earlier there was no option to choose debug vs. release or some other configuration? That&rsquo;s another one of those decisions that make you wonder if Apple uses Xcode to manage their own projects (and if they do, what kind of developers or projects they have).</p>
<p>They turned something simple like project configurations that nobody ever complained about, into something byzantine worthy of some of the best efforts from Redmond. This gets the award for &ldquo;most complicated feature nobody needed or wanted&rdquo;. It seems now we have an extra layer of indirection. So you act on a scheme, which then decides which configuration to build and what to do. That&rsquo;s why there are &ldquo;Build for analysis&rdquo; (debug), &ldquo;Build for running&rdquo; (release), &ldquo;Build for testing&rdquo; (WTF?), &ldquo;Build for archiving&rdquo; (distribution?).</p>
<p>After spending some time with it, I&rsquo;m still confused how I would go about running the release configuration, or how to mass-edit all the schemes at once (every target seems to get a different scheme).</p>
<p>The whole schemes thing leaves me completely speechless, and that vein on the side of my forehead is pulsating just from thinking about it, so let&rsquo;s just move on.</p>
</li>
</ul>
<h2 id="the-good">The good</h2>
<p>After you take the time to fix Xcode 4 into something usable, and (somehow) put up with the new broken features, is there something to like?</p>
<p>I had to dig deep, but I found a couple of things that I like better than Xcode 3:</p>
<ul>
<li>Much better project settings UI: Multiple panes, showing multiple values for different configurations, etc. Way better than Xcode 3.</li>
<li>Better semantic analysis. During the build process, Xcode 4 was able to correctly flag some problems in my code that Xcode 3 never warned me about. Mostly to do with constness of parent-scope variable when using blocks.</li>
<li>Better keyboard shortcut support for opening files in different windows (assistant pressing the Option key). I never found a way to open a file in a specific window in Xcode 3 without having to use the mouse.</li>
</ul>
<p>And that&rsquo;s pretty much the whole good list that I was able to find :-|</p>
<h2 id="conclusion">Conclusion</h2>
<p>Xcode has been progressively evolving from version 1 until version 3.2. I have no doubt that&rsquo;s the reason for some of the quirks in the later versions. Xcode 4 seems to be a total re-design and re-implementation, and suffers from the classic <a href="http://en.wikipedia.org/wiki/Second-system_effect">second system effect</a>. It&rsquo;s change for the sake of change, most of the time scrapping useful features and not offering useful alternatives.</p>
<p><img alt="Lawn" loading="lazy" src="/xcode-4-trials-and-tribulations/images/lawn.jpg" title="lawn.jpg"></p>
<p>I&rsquo;m sure I only scrapped the surface of the horrors of Xcode 4 in the day I spent with it. I didn&rsquo;t look very closely at the debugger or the Interface Builder (saving those for another day). I keep hearing about developers with stability problems with Xcode, although I didn&rsquo;t run into any crashes (but I hardly did any real work with it).</p>
<p>Overall, my recommendation is that, if you&rsquo;re comfortably working on Xcode 3, stay as far as possible from Xcode 4. We&rsquo;ll all be forced to move there sooner or later, but in the meanwhile you can continue being productive. Maybe by the time they discontinue Xcode 3, Xcode 4 will have improved a bit.</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>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>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>360iDev: The Conference You Can't Miss</title><link>https://gamesfromwithin.com/360idev-the-conference-you-cant-miss/</link><pubDate>Thu, 28 Oct 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/360idev-the-conference-you-cant-miss/</guid><description>&lt;p&gt;&lt;img alt="360idev.png" loading="lazy" src="https://gamesfromwithin.com/360idev-the-conference-you-cant-miss/images/360idev1.png"&gt;It&amp;rsquo;s no secret that I like a good conference. Actually, I&amp;rsquo;m sure I can find something to enjoy even at a so-so conference. Each field has it&amp;rsquo;s big, ultimate conference: For games it&amp;rsquo;s &lt;a href="http://gdconf.com/"&gt;GDC&lt;/a&gt;, for graphics &lt;a href="http://www.siggraph.org/s2011/"&gt;SIGGRAPH&lt;/a&gt;, and for iPhone development &lt;a href="http://developer.apple.com/wwdc/"&gt;WWDC&lt;/a&gt;. Those big conferences have the big announcements, the big crowds, and the big players. But the smaller conferences always have something a unique to them that the big ones can&amp;rsquo;t compete against.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="360idev.png" loading="lazy" src="/360idev-the-conference-you-cant-miss/images/360idev1.png">It&rsquo;s no secret that I like a good conference. Actually, I&rsquo;m sure I can find something to enjoy even at a so-so conference. Each field has it&rsquo;s big, ultimate conference: For games it&rsquo;s <a href="http://gdconf.com/">GDC</a>, for graphics <a href="http://www.siggraph.org/s2011/">SIGGRAPH</a>, and for iPhone development <a href="http://developer.apple.com/wwdc/">WWDC</a>. Those big conferences have the big announcements, the big crowds, and the big players. But the smaller conferences always have something a unique to them that the big ones can&rsquo;t compete against.</p>
<p>I&rsquo;m going to say this very clearly so it doesn&rsquo;t get lost in the middle of a paragraph.</p>
<p><a href="http://www.360idev.com/">360iDev</a> is the best conference you can go to if you&rsquo;re doing any kind of iOS development.</p>
<p>There. I&rsquo;ve said it. And no, they&rsquo;re not paying me any to say that.</p>
<p>I&rsquo;m clearly not the only one who feels that way either. Just earlier this week <a href="http://twitter.com/#!/weheartgames">Mike Berg</a> wrote <a href="http://weheartgames.com/2010/10/in-the-months-since-360idev-and-why-you-should-go/">a post about how awesome 360iDev is</a>, and we didn&rsquo;t even compare notes. Great minds think alike apparently.</p>
<p>Yes, Apple puts the big show for WWDC. It&rsquo;s a unique experience: the keynote, the crowds, the unveiling of the latest technologies, the sessions, the labs&hellip; But in the end, it&rsquo;s a big show from Apple to woo its developers. You&rsquo;re getting the official message through very polished presentations. Which is fine, but it feels a bit&hellip; too polished. Too streamlined. Too overproduced.</p>
<p>Talk to developers who&rsquo;ve been to WWDC multiple times, and you&rsquo;ll quickly find out that the parts they like best are the labs (access to Apple engineers) and the networking (some with Apple, but mostly with other attendees). That&rsquo;s why <a href="http://macindie.com/2010/06/definitive-wwdc10-parties-list/">keeping track of the parties during WWDC is almost a full-time job</a>!</p>
<h3 id="for-developers-by-developers">For Developers, By Developers</h3>
<p>360iDev on the other hand is a conference for developers by developers. You don&rsquo;t get fed the official party line. Instead, you get to hear how some API really worked (or didn&rsquo;t) in the trenches, how developers had to work around bugs, or, why not, how some technology was a dream to work with. Nothing like hearing it straight from the horse&rsquo;s mouth.</p>
<h3 id="strong-game-development-track">Strong Game Development Track</h3>
<p>There are usually <a href="http://www.360idev.com/schedule">three simultaneous tracks at 360iDev</a>: Business, Sights and Sounds, and Development Tricks. As you can expect, sights and Sounds is usually entirely devoted to games, and there&rsquo;s plenty of game-related info in the other tracks as well.</p>
<p>I&rsquo;m going to be totally honest here: The quality of the sessions varies a lot from one to the other, and they can be somewhat hit or miss. When the presentations are awesome, they&rsquo;re really awesome. And on the average, I&rsquo;d say they&rsquo;re very good. That&rsquo;s the flip side of not having a super-rehearsed, super-polished presentations like WWDC.</p>
<h3 id="hacker-vibe">Hacker Vibe</h3>
<p>You walk into WWDC, and you get a very strong corporate feeling (trying to be developer friendly). The moment you walk into 360iDev, it has a palpable hacker vibe <a href="#1">[1]</a>. The people presenting might not have the most polished slides, but they can do some amazing things on the iPhone. There are even presentations on the internals of the iPhone and what&rsquo;s going on under the hood, something you&rsquo;ll never get from Apple!</p>
<h3 id="game-jam">Game Jam</h3>
<p>As a perfect example of the hacker mentality, the <a href="http://iphonegamejam.com">Game Jam</a> has become a regular feature at 360iDev. On the last night, developers get together in a big rooms, and either flying solo or grouping into teams, they create a <a href="/prototyping-youre-probably-doing-it-wrong/">game prototype</a> in a few hours. The next day at lunch, we have a big gathering and get to demo the games created the previous night to everybody. What a perfect (and exhausting!) last day to the conference!</p>
<h3 id="its-nimble-and-agile">It&rsquo;s Nimble And Agile</h3>
<p>This might not seem like a big deal to some, but it&rsquo;s very important: 360iDev happens twice a year. Technology conferences that happened once a year might have been fine 10-15 years ago, but as the pace of technological advance continues to accelerate, once a year doesn&rsquo;t cut it anymore. Especially if you have to submit talk proposals 6-8 months in advance, they&rsquo;re old news by the time the conference rolls around.</p>
<p>360iDev is much more agile than that. It happens twice a year, and you only need to submit a general overview a few months in advance. Given the content of a lot of the talks, they probably come together just weeks (if not days) before the conference itself. That&rsquo;s part of the reason for the uneven quality of the talks, but it&rsquo;s a price worth paying.</p>
<h3 id="networking">Networking</h3>
<p>360iDev is a small conference. I don&rsquo;t know the official numbers, but I think there are usually around 200-300 attendees. You&rsquo;ll be seeing the same faces all three days, especially the ones that share your same interests and end up going to the same sessions as you do. Even if you&rsquo;re a total introvert, you&rsquo;ll end up meeting a bunch of new, very interesting people, and creating lots of new possibilities for your future.</p>
<p>Even better, the speakers are part of that small number of attendees, and they get to hang out with everybody else. There aren&rsquo;t special VIP parties, or secret off-site invitation-only parties (if they are, they&rsquo;re so secret I missed them). Everybody hangs out during the sessions, at lunch, and the evening festivities. So if there&rsquo;s someone in the speaker list you particularly want to meet, this is your chance.</p>
<p>It&rsquo;s not just other developers either. The iPhone media often comes to the conference as well, so you might get a chance to talk to people from <a href="http://toucharcade.com/">TouchArcade</a> or <a href="http://www.tuaw.com/">TUAW</a>.</p>
<p>360iDev three full days of sessions, one day of tutorials, one night of game jam, three evenings or parties, and one conference full of awesome. And that for a fraction of price of the big conferences. How can you go wrong? <a href="#2">[2]</a></p>
<p>[1] I mean hacker in the <a href="http://en.wikipedia.org/wiki/Hacker_(programmer_subculture)">good sense of the word</a>, not in the &ldquo;cracker&rdquo;, malicious one!</p>
<p>[2] If this doesn&rsquo;t convince <a href="http://twitter.com/gavinbowman">Gavin</a> and <a href="http://twitter.com/#!/tearascal">Craig</a> to come to 360iDev, I don&rsquo;t know what will. Go buy the awesome <a href="http://itunes.apple.com/us/app/linkoidz/id338887297?mt=8&amp;partnerId=30&amp;siteID=aDkhM0mDflg">Linkoidz</a> so they&rsquo;ll be forced to attend :-)</p>
<p><a href="http://itunes.apple.com/us/app/linkoidz/id338887297?mt=8&amp;partnerId=30&amp;siteID=aDkhM0mDflg"><img alt="linkoidz-blog-banner.jpg" loading="lazy" src="/360idev-the-conference-you-cant-miss/images/linkoidz-blog-banner.jpg"></a></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>Casey's Contraptions And The IGF</title><link>https://gamesfromwithin.com/caseys-contraptions-and-the-igf/</link><pubDate>Thu, 21 Oct 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/caseys-contraptions-and-the-igf/</guid><description>&lt;p&gt;&lt;img alt="casey.png" loading="lazy" src="https://gamesfromwithin.com/caseys-contraptions-and-the-igf/images/casey.png"&gt;Today is the day! We finally announced my next game: &lt;a href="http://contraptions.snappytouch.com/"&gt;Casey&amp;rsquo;s Contraptions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is a bit of a different project than some of my past ones. This one is a collaboration with &lt;a href="http://twitter.com/mysterycoconut"&gt;Miguel Ãngel Friginal&lt;/a&gt; from &lt;a href="http://mysterycoconut.com/"&gt;Mystery Coconut&lt;/a&gt;. I&amp;rsquo;m doing the programming, Miguel is doing all the art, and we&amp;rsquo;re both contributing equally to the design and everything else. It has been great having some awesome art to go with the game, but also to collaborate with someone really closely on the game.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="casey.png" loading="lazy" src="/caseys-contraptions-and-the-igf/images/casey.png">Today is the day! We finally announced my next game: <a href="http://contraptions.snappytouch.com/">Casey&rsquo;s Contraptions</a>.</p>
<p>This is a bit of a different project than some of my past ones. This one is a collaboration with <a href="http://twitter.com/mysterycoconut">Miguel Ãngel Friginal</a> from <a href="http://mysterycoconut.com/">Mystery Coconut</a>. I&rsquo;m doing the programming, Miguel is doing all the art, and we&rsquo;re both contributing equally to the design and everything else. It has been great having some awesome art to go with the game, but also to collaborate with someone really closely on the game.</p>
<p>Casey&rsquo;s Contraptions was one of those ideas for a game that I kept wanting to make for quite a while, and now it was finally the right time. It meets the three main requirements that I&rsquo;m looking for in a game project:</p>
<ul>
<li>Something original</li>
<li>Has potential to sell well</li>
<li>It involves a creative activity (instead of something violent or destructive)</li>
</ul>
<p>The idea of games based on mechanical contraptions is not new, but there are surprisingly few games based on it. We are hoping to bring a lot new to the table: Casey himself, unlockable items, interface built from the ground up for multi touch, modern physics simulation, social features, sharing of solutions, and even creation and sharing of new levels. We are <strong>really</strong> excited to be working on this project and we can&rsquo;t wait until it&rsquo;s released.</p>
<p><img alt="MainMenu.jpg" loading="lazy" src="/caseys-contraptions-and-the-igf/images/MainMenu.jpg"></p>
<h3 id="development">Development</h3>
<p>Casey&rsquo;s Contraptions started as a <a href="/prototyping-youre-probably-doing-it-wrong/">prototype</a> back in the summer. After a day or two messing with physics engines and creating some objects, I knew there was something there, so I spent a two more weeks creating an initial version. It wasn&rsquo;t much more than a tech proof-of-concept, but it was clear that there was a game there (even with my horrible stand-in clip art assets).</p>
<p>I sent that built to a couple of friends for initial feedback. It was laughably early, but that&rsquo;s the time when it&rsquo;s possible to really make radical changes to the design. I knew the people I was sending it to a) were used to seeing games at early stages, and b) were not afraid to tell me if something sucked. Actually, I told them to skip the nice parts and just focus on everything that they didn&rsquo;t like. Not surprisingly, that initial feedback was crucial, and really shaped how Casey&rsquo;s Contraptions evolved since then.</p>
<p>Shortly after that, Miguel joined me full time on the game and we dove right into it. For our development, we used a super light-weight agile approach: We have high-level &ldquo;user stories&rdquo;, and two week iterations. Iterations are somewhat flexible (plus minus a few days) and we don&rsquo;t strictly estimate the tasks, just take on as many user stories as we think we can do in that time. The important parts are to always be focused on the most important stories, and to take them to completion each time.</p>
<p>Miguel lives in Seattle and I&rsquo;m in Carlsbad, so we do all of our work remotely. We use Subversion hosted remotely, and we&rsquo;re in constant communication through iChat and email. That allows us to iterate on a piece of art, an item behavior, or a menu item multiple times very quickly. It&rsquo;s not as good as sitting side by side, but I haven&rsquo;t felt like working remotely has gotten in the way at all.</p>
<p>After a busy month and a half, we got to where you see it today, and we submitted the game to the <a href="http://www.igf.com/php-bin/entry2011.php?id=384">Independent Games Festival</a> (IGF).</p>
<p><img alt="Screen1.jpg" loading="lazy" src="/caseys-contraptions-and-the-igf/images/Screen1.jpg"></p>
<h3 id="independent-games-festival">Independent Games Festival</h3>
<p>Some people have asked me why I wanted to submit it to the IGF. I have to be honest and admit that I had never really considered <strong>not</strong> submitting it.</p>
<p>I imagine everybody reading this blog knows about the IGF already. It&rsquo;s the closest thing to the Movie Academy Awards that we have for independent games. There are many reasons why you&rsquo;d want to submit your game. The amount of press and prestige associated with winning or even being nominated as a finalist is huge. The prize money is a nice touch, but it&rsquo;s not really enough to make much of a difference in the game itself (I&rsquo;m talking about the Mobile Category prize). Of course, there are many <a href="http://itunes.apple.com/us/app/tilt-to-live-hd/id391837930?mt=8">other</a> <a href="http://itunes.apple.com/us/app/pocket-frogs/id386644958?mt=8">fantastic</a> <a href="http://itunes.apple.com/us/app/trainyard/id348719156?mt=8">games</a> that are competing at the IGF (a total of almost 400 games!), so it&rsquo;s hard to count on becoming a finalist.</p>
<p>One very real and concrete reason to enter the IGF was to have a very well-defined milestone. It wasn&rsquo;t that different from one of our iterations, except that we had a real customer (the IGF judges) and a non-flexible deadline. That made us really focus our efforts and put in some extra effort in the last couple of weeks to get it in shape for the IGF. Looking back at the game just a couple of weeks ago, it&rsquo;s amazing how far it came in that time.</p>
<p><img alt="igf.gif" loading="lazy" src="/caseys-contraptions-and-the-igf/images/igf.gif">For me personally, the biggest reason to enter the IGF is because it&rsquo;s something I&rsquo;ve always wanted to do. I&rsquo;ve followed the IGF since <a href="http://www.igf.com/1999igfgallery.html">the first one in 1999</a> (which was, coincidentally, the first GDC I attended). Every time I walked through the booths or watched the award ceremony, I wanted to be part of it. So finally, this was my chance to do it. It was a great experience going through the process. Now the next life goal will be to actually make it as a finalist.</p>
<p>Submitting Casey&rsquo;s Contraptions had another, unexpected side effect: It tipped our hand and forced us to announce the game sooner than we were planning on doing. It wasn&rsquo;t until a few days before the submission that we realized the list of IGF games would go public right away. Originally we were planning on announcing the game at <a href="http://www.360idev.com/">360iDev</a> in mid November, but this forced us to move the schedule up somewhat. Hopefully that will be a good thing and will allow us to build some good buzz in the upcoming months all the way until the release. Keep an eye out for a gameplay video and some hands-on previews in the next few weeks.</p>
<p>If you want to keep up to date with Casey&rsquo;s Contraptions development, join the <a href="http://www.facebook.com/pages/Caseys-Contraptions/158351050866139">Facebook group</a>, follow <a href="http://twitter.com/mysterycoconut">Miguel</a> and <a href="http://twitter.com/snappytouch">me</a> on Twitter, or keep an eye on the <a href="http://forums.toucharcade.com/showthread.php?t=70616">Touch Arcade thread</a>.</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>Life In The Top 100 And The Google App Engine</title><link>https://gamesfromwithin.com/life-in-the-top-100-and-the-google-app-engine/</link><pubDate>Thu, 07 Oct 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/life-in-the-top-100-and-the-google-app-engine/</guid><description>&lt;p&gt;A few weeks ago I wrote about &lt;a href="https://gamesfromwithin.com/google-app-engine-as-back-end-for-iphone-apps/"&gt;using the Google App Engine as a back end for Flower Garden&lt;/a&gt;. One of the comments I heard from several people is that the Google App Engine pricing scheme is &amp;ldquo;scary&amp;rdquo; due to its unpredictability. What if your server gets very busy and you find yourself with a huge bill?&lt;/p&gt;
&lt;h3 id="google-app-engine-costs"&gt;Google App Engine Costs&lt;/h3&gt;
&lt;p&gt;At the time I wrote that post, the bandwidth of Flower Garden (and Flower Garden Free) was just under the free bandwidth allowance, so I didn&amp;rsquo;t have to pay anything. However, this last week, after &lt;a href="https://gamesfromwithin.com/communicating-with-players/"&gt;riding the Pocket Frogs rocket&lt;/a&gt;, Flower Garden Free shot up to the #56 overall app in the US. And boy, did that make a difference in server usage!&lt;/p&gt;</description><content:encoded><![CDATA[<p>A few weeks ago I wrote about <a href="/google-app-engine-as-back-end-for-iphone-apps/">using the Google App Engine as a back end for Flower Garden</a>. One of the comments I heard from several people is that the Google App Engine pricing scheme is &ldquo;scary&rdquo; due to its unpredictability. What if your server gets very busy and you find yourself with a huge bill?</p>
<h3 id="google-app-engine-costs">Google App Engine Costs</h3>
<p>At the time I wrote that post, the bandwidth of Flower Garden (and Flower Garden Free) was just under the free bandwidth allowance, so I didn&rsquo;t have to pay anything. However, this last week, after <a href="/communicating-with-players/">riding the Pocket Frogs rocket</a>, Flower Garden Free shot up to the #56 overall app in the US. And boy, did that make a difference in server usage!</p>
<p><img alt="serverload.jpg" loading="lazy" src="/life-in-the-top-100-and-the-google-app-engine/images/serverload.jpg"></p>
<p>That screenshot shows the Google App Engine dashboard with the number of requests per second for a 4 day period. Can you guess when the Pocket Frogs cross-promotion started? It went from an average of 1.5 requests per second, to a peak of about 16. That&rsquo;s a factor of 10 right there.</p>
<p>Let&rsquo;s see what that means in terms of cost. With the Google App Engine, you get charged for different resources you consume: CPU usage, incoming bandwidth, outgoing bandwidth, data storage, and recipients emailed. Of those, the only one that Flower Garden makes any dent on is outgoing bandwidth (mostly the HTML pages and images in the Flower Shop).</p>
<p>For each of those resources, you get a free amount every day. In the case of outgoing bandwidth, we get 1GB before we have to start paying anything. Afterwards, it&rsquo;s $0.12 per GB. The peak day for Flower Garden Free, when it was all the way at #56, it consumed 7.8 GB. Now that it&rsquo;s back down, it&rsquo;s using up at around 2-3 GB of outgoing data every day.</p>
<p>That means, that the busiest day I was charged $0.82 in bandwidth, but the profits for that day were over $1500! I can only hope for days just as busy!</p>
<p><img alt="charges.png" loading="lazy" src="/life-in-the-top-100-and-the-google-app-engine/images/charges.png"></p>
<p>As a reference, these are my Google App Engine charges for the busy week during the promotion. $3.28 for the week? Bring it on! :-)</p>
<h3 id="minimizing-bandwidth">Minimizing Bandwidth</h3>
<p>When I first saw the first day&rsquo;s bandwidth, I was pretty surprised it was taking up that much. I hadn&rsquo;t tried to minimize it first, but 8 GB seemed like a significant amount.</p>
<p>The first thing I did was to forward any requests to the <a href="http://st-flowershop.appspot.com/moregames/index.html">&ldquo;More Games&rdquo;</a> and &ldquo;News&rdquo; section back to the Dreamhost account. After all, if that server goes down, it doesn&rsquo;t really matter, and they can take up significant bandwidth with all the images.</p>
<p>To forward something, I couldn&rsquo;t just do it from the configuration file. Instead, I set a handler for the moregames directory like this:</p>
<pre tabindex="0"><code>- url: /moregames/.*
  script: redirect.py
</code></pre><p>And the redirect script is very simple:</p>
<pre tabindex="0"><code>import os
import sys
import logging
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

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

def main():
	run_wsgi_app(application)

if __name__ == &#34;__main__&#34;:
	main()
</code></pre><p>Another thing you can do is to turn on <a href="http://code.google.com/appengine/docs/python/config/appconfig.html#Static_File_Handlers">explicit caching of files in the app.yaml</a> file for your Google App Engine app. I don&rsquo;t know how much that helps with data requested from within an iPhone app, but it can&rsquo;t hurt.</p>
<p>Finally, I made some changes to Flower Garden. I never had bandwidth minimization in mind, so for example, I was happily requesting updated news and other data at the beginning of every session. I wised up a bit and now it only requests that data at most once every few hours or days.</p>
<p>In case you&rsquo;re ever getting close to using up your quotas, I learned that you can <a href="http://code.google.com/appengine/docs/quotas.html">query them at runtime</a>. I haven&rsquo;t done anything about it yet, but I suppose I could start forwarding image fetches to a backup server whenever I get close to the limit. But for that, I&rsquo;ll have to sell many more units of Flower Garden!</p>
<h3 id="google-app-engine-shortcomings">Google App Engine Shortcomings</h3>
<p>Overall, I&rsquo;m very happy with the Google App Engine. But it&rsquo;s not all a bed of roses over here. I think the Google App Engine excels at scaling under heavy load, but surprisingly, it doesn&rsquo;t have anything close to 100% uptime. I&rsquo;m going to say it probably doesn&rsquo;t even have 95% uptime! With such a massive system and all the redundancy underneath, I&rsquo;m surprised they can&rsquo;t have better uptime. Supposedly <a href="http://code.google.com/status/appengine">their status page</a> makes you think everything is perfect, but it&rsquo;s really far from it.</p>
<p>Apart from downtime, people are also reporting <a href="http://groups.google.com/group/google-appengine/browse_frm/thread/f8dd1f332ab32909#">severe latency issues sometimes</a>, and I&rsquo;ve seen some errors like that in my log every so often. Chalk it up to being a beta I suppose. I imagine it&rsquo;s only going to get better with time.</p>
<p>I would still use the Google App Engine for any new game I&rsquo;ll release in the future, whether it has big or small backend needs. If nothing else, the ease of development and testing beats every alternative for me.</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>My Standing Desk Experiment</title><link>https://gamesfromwithin.com/my-standing-desk-experiment/</link><pubDate>Fri, 24 Sep 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/my-standing-desk-experiment/</guid><description>&lt;p&gt;I&amp;rsquo;m not sure where I first heard about standing desks. It was probably about a year ago in some online article, but it didn&amp;rsquo;t have much of an impact at the time. Since then, the benefits of standing (or rather, the dangers of sitting down for prolonged periods of time) has been appearing &lt;a href="http://opinionator.blogs.nytimes.com/2010/02/23/stand-up-while-you-read-this/?em"&gt;in the news&lt;/a&gt; &lt;a href="http://www.usatoday.com/news/health/2010-01-20-sitting-death_N.htm"&gt;more often&lt;/a&gt;. Some people even went as far as setting up &lt;a href="http://lifehacker.com/171537/coolest-workspace-contest--the-treadputer"&gt;treadmill desks&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Initially I dismissed it for me because I&amp;rsquo;m reasonably active: I either run or bike 5 or 6 days per week, and the rest of the days I go for a walk around the neighborhood. It was the combination of &lt;a href="http://press.psprings.co.uk/bjsm/january/sm67702.pdf"&gt;increased studies&lt;/a&gt; on the effects of sitting, some people in &lt;a href="http://twitter.com/castano"&gt;my&lt;/a&gt; &lt;a href="http://twitter.com/eeen"&gt;social&lt;/a&gt; &lt;a href="http://twitter.com/ClickNothing"&gt;circle&lt;/a&gt; finally making the jump and raving about it, and me developing some problems in a hamstring that finally made me consider it more seriously. And trust me, if you&amp;rsquo;re a cyclist or a runner, the last thing you want to have is hamstring problems.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;m not sure where I first heard about standing desks. It was probably about a year ago in some online article, but it didn&rsquo;t have much of an impact at the time. Since then, the benefits of standing (or rather, the dangers of sitting down for prolonged periods of time) has been appearing <a href="http://opinionator.blogs.nytimes.com/2010/02/23/stand-up-while-you-read-this/?em">in the news</a> <a href="http://www.usatoday.com/news/health/2010-01-20-sitting-death_N.htm">more often</a>. Some people even went as far as setting up <a href="http://lifehacker.com/171537/coolest-workspace-contest--the-treadputer">treadmill desks</a>!</p>
<p>Initially I dismissed it for me because I&rsquo;m reasonably active: I either run or bike 5 or 6 days per week, and the rest of the days I go for a walk around the neighborhood. It was the combination of <a href="http://press.psprings.co.uk/bjsm/january/sm67702.pdf">increased studies</a> on the effects of sitting, some people in <a href="http://twitter.com/castano">my</a> <a href="http://twitter.com/eeen">social</a> <a href="http://twitter.com/ClickNothing">circle</a> finally making the jump and raving about it, and me developing some problems in a hamstring that finally made me consider it more seriously. And trust me, if you&rsquo;re a cyclist or a runner, the last thing you want to have is hamstring problems.</p>
<p>It turns out that my 5-mile morning runs weren&rsquo;t making me immune to the dangers of sitting. It&rsquo;s not how much exercise you get per day, but how long do you sit on a chair continuously. And no, buying an fancy, expensive chair might help with your back, but it&rsquo;s not going to do one bit of good with all the other problems.</p>
<p>One of the many advantages of working from home is that I can try weird things that would be much more difficult in a regular workplace. I also have a track history of liking to experiment on myself <a href="#1">[1]</a>, so it didn&rsquo;t take much convincing to give this a try.</p>
<p>After some initial research, it appeared that the way to go was an adjustable-height desk. That way you can work standing, but you still have the flexibility to sit down whenever you need to. I also found out that apparently this is not all that uncommon in Europe. The only drawback is that adjustable standing desks are not easily available here in the US, and the ones that are out there are aimed at offices and big companies, with matching eye-popping price tags. Even though <a href="/the-power-of-free/">Flower Garden continues to do well</a>, I wasn&rsquo;t quite ready to plop down several thousand dollars on something I might end up hating.</p>
<p><img alt="standing_1.jpg" loading="lazy" src="/my-standing-desk-experiment/images/standing_1.jpg">So I decided to start cheap and work my way up from the bottom. First I had to decide if I even liked this whole working-while-standing thing. I wasn&rsquo;t even sure I would be able to type! I thought about raising my desk with cinder blocks, but I would have to raise a lot and would make it very unstable. So instead, I created four stacks of books on top of my desk and put a board on top. Then I was able to put the keyboard, computer, and monitor on the board and give that a try.</p>
<p>Let me tell you: It was weird.</p>
<p>At first I didn&rsquo;t know how to type. My fingers were constantly off to the side. It turns out my initial height was too low. You really want to have the keyboard at a height that puts a 90 degree bend on your elbows. That&rsquo;s what they say about the sitting position, but somehow I can manage to have less. However, standing, I really needed that height.</p>
<p>Even once I adjust the height, the first day was kind of rough. After an hour, I was definitely feeling it in my feet. I think I did half a day the first day and I felt totally exhausted. All that running wasn&rsquo;t helping that much standing at my desk apparently.</p>
<p>Fortunately things got better very quickly. In a few days, I was able to work for hours without much problem. I would find myself constantly shifting my weight between my feet and moving around a little bit. I was definitely liking that whole standing thing.</p>
<p><img alt="standing_2.jpg" loading="lazy" src="/my-standing-desk-experiment/images/standing_2.jpg">At this point I decided that the stack of books was too annoying, but I wasn&rsquo;t quite ready for an expensive desk. So I picked up a <a href="http://www.ikea.com/us/en/catalog/products/60141484">Fredrik Ikea</a> desk from Craigslist for $50. The nice thing about this desk is that it can be assembled so the top of the desk is almost at any height. You can&rsquo;t change it on the fly, but at least it serves as a standing desk.</p>
<p>Finally I was able to work standing and be comfortable at the same time now that I had space for more than a mug along with the keyboard. The extra shelves on the desk were also very handy (one over the table top and one underneath).</p>
<p>After spending a couple of weeks with the desk, I decided that I definitely liked standing and it was something I wanted to continue doing long term. I felt more focused while standing, and my productivity was up. An unexpected side benefit was that when someone else comes into the room, they can walk right up to the desk and we can look at the monitor together, or look at some papers, much more easily than if it was a sitting desk.</p>
<p>However, it was also clear that I needed to switch things up a bit. Spending the whole day standing continued to be pretty tough on my feet, and it even made it so I didn&rsquo;t want to work any longer than I had to. I really had to combine the standing with some hours of sitting down, which is probably a healthier thing to do anyway.</p>
<p>At this point I had two options: I could go full out and get a motorized adjustable desk, or I could get an adjustable draft chair which are tall enough to sit comfortably at a standing-height desk. Since I already had a nice office chair, and the Ikea desk was a bit wobbly set up like that, I decided to spend the money on the motorized desk.</p>
<p>Again, after a bunch of research, it seemed that one of the best options was to order a (very appropriately named), <a href="http://www.geekdesk.com/">GeekDesk</a> online. They have them in two sizes, Classic and Mini. It turns out I wanted something more in the middle (around 60&quot; wide), so I ended up ordering the Mini frame and a <a href="http://www.ikea.com/us/en/catalog/products/50106773">desk top from Ikea for $80</a>. It wasn&rsquo;t cheap, but it was way cheaper than the alternatives and all the reviews and experiences I read were very positive.</p>
<p>It arrived very quickly and it was a breeze to assemble. I did have a scary moment that it looked like one of the wheels didn&rsquo;t fit in the metal opening, but I eventually managed to coerce it. Hopefully this kind of manufacturing problems aren&rsquo;t common.</p>
<p><img alt="x2_277d29f.jpeg" loading="lazy" src="/my-standing-desk-experiment/images/x2_277d29f.jpeg"><img alt="x2_277d225.jpeg" loading="lazy" src="/my-standing-desk-experiment/images/x2_277d225.jpeg"></p>
<p>I can only describe the final setup with one word: Awesome. The desk isn&rsquo;t wobbly at all, and it takes just a few seconds to change heights with the push of a button. Not just that, but I can fine tune the height at any moment in tiny increments. And in the sitting position, I can put it low enough to make typing very comfortable (most desks are set up too high to type really comfortably for me).</p>
<p>My daily work routine has settled into working standing in the mornings, sitting for an hour or so after lunch, standing all afternoon, and then sitting in the evening I have have to do some work. With the wonderful weather here in Southern California, I&rsquo;ll often take my sitting work time outside in the back patio in the shade. So all in all, I probably spend one or two hours sitting down at the desk.</p>
<p>Yes, it was a significant amount of money, but it&rsquo;s something I&rsquo;m using every day and it improves both my productivity and my health. Definitely worth it.</p>
<p>Standing desks have one downside though. This situation happens embarrassingly often. Good thing I work home alone!</p>
<p>[1] A few years ago I gave polyphasic sleep a try. It was actually really great for gaining extra hours, but eventually I gave it up because I was constantly out of sync with the rest of the world. I&rsquo;d do it again if I were spending months <a href="http://www.imdb.com/title/tt0084787/">alone in a research station in the Antarctica</a>.</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>Google App Engine As Back End For iPhone Apps</title><link>https://gamesfromwithin.com/google-app-engine-as-back-end-for-iphone-apps/</link><pubDate>Thu, 09 Sep 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/google-app-engine-as-back-end-for-iphone-apps/</guid><description>&lt;p&gt;As soon as a game involves servers, there&amp;rsquo;s no such a thing anymore as &amp;ldquo;ship and forget&amp;rdquo;. Flower Garden put this in evidence about a month ago when I started getting complaints from users that the Flower Shop kept going down. Sometimes they weren&amp;rsquo;t even getting the items they were purchasing! (fortunately they can always do a free re-download, but they don&amp;rsquo;t always know that).&lt;/p&gt;
&lt;p&gt;Flower Garden was using a shared Dreamhost server to upload bouquets, host in-game news, and, most importantly, to serve the Flower Shop (which involves hosting the static shop files, redeeming promo codes, recording transactions, verifying receipts with Apple&amp;rsquo;s server, and delivering purchased content). All the Flower Shop functionality was implement in PHP and using a mySQL database.&lt;/p&gt;</description><content:encoded><![CDATA[<p>As soon as a game involves servers, there&rsquo;s no such a thing anymore as &ldquo;ship and forget&rdquo;. Flower Garden put this in evidence about a month ago when I started getting complaints from users that the Flower Shop kept going down. Sometimes they weren&rsquo;t even getting the items they were purchasing! (fortunately they can always do a free re-download, but they don&rsquo;t always know that).</p>
<p>Flower Garden was using a shared Dreamhost server to upload bouquets, host in-game news, and, most importantly, to serve the Flower Shop (which involves hosting the static shop files, redeeming promo codes, recording transactions, verifying receipts with Apple&rsquo;s server, and delivering purchased content). All the Flower Shop functionality was implement in PHP and using a mySQL database.</p>
<p>After some stressful sorting through the logs, it looked like the server was running out of memory and killing PHP processes. Dreamhost&rsquo;s technical support didn&rsquo;t help much and just claimed that I was simply something that happened and they would be happy to sell me a virtual private server. I was surprised to hear it was using up a lot of memory, and certainly nothing I could see with the tools available to me showed that. I certainly hadn&rsquo;t done any changes in a while and traffic was constant. Doing some Googling at the time brought up lots of other angry Dreamhost users in a similar situation, so I suspected server configuration problems.</p>
<p>Whatever the case, I couldn&rsquo;t let it be that way and I had to fix it somehow. I briefly considered a virtual private server, or even a dedicated host in some highly <a href="http://www.slicehost.com/">recommended</a> <a href="http://www.linode.com/">providers</a>. But in the end, the simplicity, scalability, and affordability of the Google App Engine won me over.</p>
<p>Now that Flower Garden has been using the Google App Engine for several weeks, I still think it&rsquo;s fantastic. I wish someone had whacked me on the head when I started writing server code and forced me to use it. Hopefully this post will be more pleasant than a hit to the head and will still have a similar (good) effect.</p>
<h3 id="google-app-engine-overview">Google App Engine Overview</h3>
<p><img alt="appengine_lowres.gif" loading="lazy" src="/google-app-engine-as-back-end-for-iphone-apps/images/appengine_lowres.gif">Even though I was pretty much completely new to the Google App Engine (I had looked into it briefly before the launch of Flower Garden but dismissed it because they couldn&rsquo;t support the amount of email traffic I needed), it took me two days to port over everything. Actually flipping the switch from the old system to the new one took a while longer, but that required more courage than work. More on that later.</p>
<p>This is not a Google App Engine tutorial. Instead, it&rsquo;s going to be an overview of what it can do and why you should consider it as a backend for your iPhone app instead of using a shared or even dedicated server.</p>
<p>The first shock (at least for me) when looking into the Google App Engine is that you can&rsquo;t run PHP. You&rsquo;re limited to Java or Python. It turns out Python is my go-to scripting language, so I was thrilled at the idea. PHP is fine, but Python is a whole class above.</p>
<p>Next, it took a bit of adjusting to the fact that the environment to run anything on the Google App Engine has to be carefully controlled. You need to create a configuration file indicating the entry points and their handlers. Fortunately, all of that is well covered in the <a href="http://code.google.com/appengine/docs/python/overview.html">extensive online documentation</a>.</p>
<p>This is what the Flower Garden config file looks like, indicating both static files and several execution entry points:</p>
<pre tabindex="0"><code>application: st-flowershop
version: 1
runtime: python
api_version: 1

handlers:
- url: /catalog
  static_dir: catalog

- url: /emailassets
  static_dir: emailassets

- url: /news
  static_dir: news

- url: /moregames
  static_dir: moregames

- url: /.*
  script: purchase.py
</code></pre><p>If you hit one of the URLs listed as static_dir, you get those files directly (like the <a href="http://st-flowershop.appspot.com/news/news.html">in-game news</a>). Anything else is handled by the Python script purchase.py. Google even provides the <a href="http://code.google.com/appengine/docs/python/tools/webapp/">webapp framework</a> that easily allows you to connect different parts of the script to handle different requests and easily get to the input parameters.</p>
<p>Once you&rsquo;re past that and you have the requisite &ldquo;Hello World&rdquo; up and running, then it&rsquo;s all fun and games.</p>
<p>One of the great features of the Google App Engine is that it comes with a fully-featured, local environment. This environment is installed automatically with the Google App Engine SDK, and there&rsquo;s nothing to configure. It&rsquo;s certainly nothing like setting up Apache + mySQL + PHP in your dev station! That way, you can do all your work locally, and only update the servers when you&rsquo;re confident everything is working.</p>
<p>Beyond this, the only other thing that is different from what you may be used to is the datastore. They provide a query language called <a href="http://code.google.com/appengine/docs/python/datastore/">GQL</a>, which is not exactly SQL, but it&rsquo;s very similar. Close enough that I had no trouble porting over my very simple queries anyway.</p>
<p>Adding data to a data store couldn&rsquo;t be simpler. For example, to add a promo code, I need the following class definition:</p>
<pre tabindex="0"><code>class PromoCode(db.Model):
	code = db.StringProperty()
	productid = db.StringProperty()
	amount = db.IntegerProperty(default=1)
	singleuse = db.BooleanProperty(default=True)
	enabled = db.BooleanProperty(default=True)
</code></pre><p>And then I can add it this way:</p>
<pre tabindex="0"><code>	promocode = PromoCode()
	# fill it up here
	promocode.put()
</code></pre><p>How do I check if a promocode is valid? I can use the SQL-like syntax, or something even simpler:</p>
<pre tabindex="0"><code>	q = PromoCode.all()
	q.filter(&#34;code =&#34;, code)
	return q.get()
</code></pre><p>Once you know that, you can go to town with your Python programs.</p>
<h3 id="google-app-engine-advantages">Google App Engine Advantages</h3>
<p><strong>Scalability</strong> This was the big reason that forced me to move away from Dreamhost. I have no way of testing how scalable it really is, but I&rsquo;m going to take Google&rsquo;s word for it. They know a tiny little bit about scalability. And besides, Flower Garden is nothing compared to other apps (it serves about 1.5 requests per second on average).</p>
<p>Since I don&rsquo;t know how things are implemented under the hood in the Google App Engine, I don&rsquo;t have a good feel for performance best practices. So I&rsquo;m hoping that my very simple queries (add to the end of a table, or see if a record is present) are just fine. If not, I can do some tuning down the line (and I won&rsquo;t have to wait for any approval to make the code go live!).</p>
<p><strong>Local environment</strong> The local environment is simply great. It makes developing a pleasure. You can add any test data you want to the local datastore through a web interface without affecting the live server. Probably my favorite feature is the console: Since the server is running locally, you can print out any debug info in the server code and you can see it live as you perform some action. That saved me hours of debugging compared to doing it on a remote server with php!</p>
<p><strong>Server synching</strong> In the past, I&rsquo;ve synced my server scripts through ftp and I kept meaning to write an automated script to do that. In this case, Google provides a script (and a GUI tool) to do the actual synching with the servers, which is great. It even waits a few seconds until it can verify that the new version is live on the server.</p>
<p><strong>Python</strong> I&rsquo;m not a big Java fan (although I used it a bit way back in the day when it first came out), but I do love Python. For a program with some complexity like this, it&rsquo;s definitely a much better choice than PHP.</p>
<p><strong>Real-time stats</strong> The Google App Engine web console displays real-time stats of access to your site. You see it expressed in requests per second and you can visualize it in the past few hours, days, or even month. You also have access to all the logs, and you can filter by type of log message (debug, info, warning, error).</p>
<p><strong>Price</strong> This is one category where the Google App Engine definitely shines. Every day you&rsquo;re given a free quota of bandwidth, disk usage, and CPU usage. If you stay under that quota you don&rsquo;t pay anything. If you go over, you pay per unit as you go (at very reasonable prices). You can even set a maximum cap on daily spending so you don&rsquo;t encounter any nasty surprises at the end of the month.</p>
<p>So far, Flower Garden has been hovering right at the edge of the outgoing bandwidth free quota (the rest of the metrics it doesn&rsquo;t even come close). So even if traffic were to double, expenses would be very reasonable.</p>
<h3 id="development-tricks">Development Tricks</h3>
<p>Along the way, I figured out a couple of interesting tricks that helped me during development.</p>
<p><strong>Bypass the App store for testing</strong> For me, few things are more annoying than doing development in the actual device. Iteration is slow and stepping with the debugger is mostly impossible (seems to depend on the mood of the debugger that day). So I try to do the bulk of the development on the simulator and just test on the device when things are ready.</p>
<p>Unfortunately, the device can&rsquo;t access the App Store, which makes testing all the server functionality dealing with the App Store painful. What I did was to add a define that, when present, the program bypasses the App Store but still functions as usual.</p>
<p><strong>Local server</strong> During development, you want to be using your local server. In my case, I set it up so that Debug versions of the code access the local server, but Release and Distribution ones access the live one.</p>
<p>There is one problem: The Google App Engine server, by default, binds itself to localhost, not to the IP address of your network card. That meant I was able to hit it from the simulator just fine accessing http://localhost:8080, but not from the device. In order to access the development server from the device, I had to explicitly tell the server to bind itself to another address like this:</p>
<pre tabindex="0"><code>dev_appserver.py --address 192.168.1.150 FlowerShop
</code></pre><p>Now I can access the server at 192.168.1.150:8080 from both the simulator and any device.</p>
<p><strong>Switching servers</strong> Porting the code took just a couple of days. Making the switch on the live server was a lot scarier though. I couldn&rsquo;t wait for a new update to be released because that seems to take over a week these days, so I forwarded requests from the old server to the new one.</p>
<p>I did it one system every day, avoiding weekends which is when there&rsquo;s the most traffic. News was easy, and so was the web view with more games. But I ran into a snag with promo codes and Flower Shop purchases.</p>
<p>Initially, I was just redirecting requests in .htaccess this way:</p>
<pre tabindex="0"><code>Redirect permanent /Shop/catalog http://st-flowershop.appspot.com/catalog
Redirect 301 /Shop/catalog http://st-flowershop.appspot.com/catalog
</code></pre><p>As I learned the hard way, POST variables aren&rsquo;t preserved in a redirect of that kind (I guess to avoid state being changed in multiple servers). I tried a bunch of things, but in the end, I wrote a quick php script that gathered all POST variables and re-posted them to the new request. A bit ugly, but it did the trick:</p>
<pre tabindex="0"><code>&lt;?php
function PostRequest($url, $_data) {

    $data = array();    
    while(list($n,$v) = each($_data)){
        $data[] = &#34;$n=&#34; . urlencode($v);
    }    
    $data = implode(&#39;&amp;&#39;, $data);
    // format --&gt; test1=a&amp;test2=b etc.

    $url = parse_url($url);
    if ($url[&#39;scheme&#39;] != &#39;http&#39;) { 
        die(&#39;Only HTTP request are supported !&#39;);
    }

    $host = $url[&#39;host&#39;];
    $path = $url[&#39;path&#39;];

    $fp = fsockopen($host, 80);

    fputs($fp, &#34;POST $path HTTP/1.1\r\n&#34;);
    fputs($fp, &#34;Host: $host\r\n&#34;);
    fputs($fp, &#34;Content-type: application/x-www-form-urlencoded\r\n&#34;);
    fputs($fp, &#34;Content-length: &#34;. strlen($data) .&#34;\r\n&#34;);
    fputs($fp, &#34;Connection: close\r\n\r\n&#34;);
    fputs($fp, $data);

    $result = &#39;&#39;; 
    while(!feof($fp)) {
        $result .= fgets($fp, 128);
    }
    fclose($fp);

    $result = explode(&#34;\r\n\r\n&#34;, $result, 2);
    $header = isset($result[0]) ? $result[0] : &#39;&#39;;
    $content = isset($result[1]) ? $result[1] : &#39;&#39;;
    return $content;
}

print PostRequest(&#34;http://st-flowershop.appspot.com/purchase&#34;, $_POST);
?&gt;
</code></pre><h3 id="conclusion">Conclusion</h3>
<p>I hope this post is enough to at least make you interested in checking out the Google App Engine and help you get over a couple of the initial hurdles. I&rsquo;ll definitely be using it in any future projects.</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>Reconsidering Version Control</title><link>https://gamesfromwithin.com/reconsidering-version-control/</link><pubDate>Thu, 02 Sep 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/reconsidering-version-control/</guid><description>&lt;p&gt;Ever since I turned indie, version control just hasn&amp;rsquo;t been much of an issue. Gone are the days of hundreds of multi-GB files that changed multiple times per day. With small teams of one or two plus a few collaborators, Subversion hosted remotely worked fine. Of course, all the cool kids these days are going on about how their distributed version control systems solve world hunger, but I&amp;rsquo;ve been mostly ignoring it because I have better things to do with my time (like writing games &lt;a href="#1"&gt;[1]&lt;/a&gt;).&lt;/p&gt;</description><content:encoded><![CDATA[<p>Ever since I turned indie, version control just hasn&rsquo;t been much of an issue. Gone are the days of hundreds of multi-GB files that changed multiple times per day. With small teams of one or two plus a few collaborators, Subversion hosted remotely worked fine. Of course, all the cool kids these days are going on about how their distributed version control systems solve world hunger, but I&rsquo;ve been mostly ignoring it because I have better things to do with my time (like writing games <a href="#1">[1]</a>).</p>
<p>Yesterday things changed a bit. As a result of <a href="/growing-indie-style/">last week&rsquo;s &ldquo;growing&rdquo; post</a>, <a href="http://twitter.com/mrfreire">Manuel Freire</a> is going to join me to help with <a href="http://www.snappytouch.com/flowergarden">Flower Garden</a> development. That makes two of us banging on the same codebase, and from two different time zones, so we don&rsquo;t get the benefit of being in the same closet as it was the case with <a href="/tag/power-of-two/">Power of Two Games</a>. Since I was in my get-things-done mindset, I figured I would just set up a new svn repository for the project, move over the Flower Garden data, give us both access to it, and move on.</p>
<p>But no, it couldn&rsquo;t be that easy. Can you guess what the first words out of his mouth were when I asked him about version control? &ldquo;Oh, I love Git!&rdquo;</p>
<p>That was the last straw. I had to do a mini-research session on version control systems, so I spent a couple of hours looking into it. If we were going to move over to something, now would be the time to do it.</p>
<h3 id="git-and-mercurial">Git and Mercurial</h3>
<p>Git and Mercurial both look great. I was debating which one to go with until I realized that they&rsquo;re both two flavors of the same thing, so it comes down more to personal preferences and tastes. <a href="http://importantshock.wordpress.com/2008/08/07/git-vs-mercurial/">This is best description</a> I found on the differences between Git and Mercurial. When it comes to computers, I&rsquo;m totally a MacGyver guy (actually, that might be true when it comes to anything now that I think about it), so that made my decision easier.</p>
<p>The big feature everybody keeps talking about for distributed version systems is effortless branching. That&rsquo;s great, but I really have no intention of branching much. I haven&rsquo;t created a single branch in the last four years, and I don&rsquo;t expect to start doing that now. Next.</p>
<p>The other big feature is working disconnected from the network. That&rsquo;s something I could use, but considering I&rsquo;m only offline a handful of times a year, it really isn&rsquo;t enough of an incentive to switch to a whole new system.</p>
<p>Git sounds like a great tool for large, distributed, open-source projects with hundreds of contributors, but frankly, I couldn&rsquo;t find anything else that was worth mentioning for a small project and a handful of people. I feel like someone is trying to sell me a Porsche when my beat-up Hyundai is still perfectly functional for driving to the grocery store once a week. Am I missing something obvious?</p>
<h3 id="hosting">Hosting</h3>
<p>Hosting the actual repository was part of the consideration. This is for a private project, so all open-source sites are out. Ideally I wanted to host it just like I do with Subversion in Dreamhost, but the instruction page on how to install <a href="http://wiki.dreamhost.com/Git">Git</a> and <a href="http://wiki.dreamhost.com/Mercurial">Mercurial</a> are enough to put most people off. Clearly, there&rsquo;s a steep learning curve there.</p>
<p><img alt="server-rack.jpg" loading="lazy" src="/reconsidering-version-control/images/server-rack.jpg">So <a href="http://twitter.com/SnappyTouch/status/22671257092">I asked on Twitter for recommendations</a>. I&rsquo;ve learned that Git and Mercurial users are definitely very vocal and are always willing to help someone join their ranks. Within minutes I had all the suggestions listed below:</p>
<ul>
<li><a href="http://github.com/">Github</a> (Git)</li>
<li><a href="http://repositoryhosting.com/">Repositoryhosting.com</a> (Git, Hg, SVN)</li>
<li><a href="http://bitbucket.org/">Bitbucket</a> (Hg)</li>
<li><a href="http://www.fogcreek.com/kiln/">Klin</a> (Hg)</li>
<li><a href="http://codaset.com/">CodaSet</a> (Git)</li>
<li><a href="http://www.assembla.com/">Assembla</a> (Git, SVN)</li>
<li><a href="http://unfuddle.com/">Unfuddle</a> (Git, SVN)</li>
<li><a href="http://beanstalkapp.com/">Beanstalkapp.com</a> (Git, SVN)</li>
<li><a href="http://sourcerepo.com/">SourceRepo</a> (Git, Hg, SVN)</li>
<li><a href="https://www.dropbox.com/home">Plain Dropbox</a> (Git I guess)</li>
<li>Self-hosting (<a href="http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way">gitosis</a> for managing Git)</li>
</ul>
<p>Prices varied a lot. From the $25/month/user of Kiln, to the $6/month of RepositoryHosting (gets you unlimited users and 2GB of storage). The Snappy Touch repository is already over 2GB, so it would end up being a bit more expensive than that, but not too bad.</p>
<p>Of those, Github was definitely the most recommended. I was starting to feel Git might not be the one for me, so I looked a bit more into RepositoryHosting because they had Subversion support. It turns out they also provide Trac, which is a great tool, although <a href="/indie-project-management-for-one-tools/">I already have that set up myself</a>.</p>
<h3 id="wish-list">Wish List</h3>
<p><strong>Binary files</strong></p>
<p>The one thing I really want in a version control system is good large binary file handling. I check in everything under version control, source code, assets, raw assets, and even built executables for each version. I want to be able to throw multiple GB psd files in the repository and have it work correctly (meaning fast, and using the least amount of space possible).</p>
<p><a href="http://www.perforce.com/">Perforce</a> did an OK job with that. Git and Mercurial apparently are both horrible at it. So is Subversion, but at least it&rsquo;s a tool I already know and I don&rsquo;t have to spend time learning the ins and outs of how to optimize the Git database or how to make backups, or cull unused trees.</p>
<p><strong>GUI</strong></p>
<p>I love my command-line tools. I live in Terminal for a good part of the day, and having a real shell is one of the things that makes my life so much more pleasant under Mac OS than under Windows. But there are some things for which a GUI tool is a really useful addition, and version control is one of them.</p>
<p>On the Mac, I&rsquo;ve been using <a href="http://versionsapp.com/">Versions</a> as a client for Subversion and it does everything I want. It&rsquo;s fast, handles multiple repositories, lets me browse history, diff changes, etc. From my brief search and other people&rsquo;s comments, there&rsquo;s nothing quite like that for Git or Mercurial yet. That&rsquo;s a pretty big, gaping hole.</p>
<p><strong>Low-level access</strong></p>
<p>Looking at all those hosting providers, I realized how much I want to have low-level access to the database. I want to be able to back it up myself, and run svnadmin when I want to. A lot of those hosting sites looked really pretty, but you were very limited in what you could do.</p>
<h3 id="coming-to-a-decision">Coming To A Decision</h3>
<p>If this were a thriller, you&rsquo;d be disappointed. I&rsquo;m afraid there are no plot twists and you can already guess the conclusion.</p>
<p>In the end, since neither Git nor Hg are built to address my biggest need (large binary files), I&rsquo;ll stick with svn. It might be old, it might not be cool, but it serves my needs, I already know how to use it, I have the tools, I can admin it and fix a problem. I can concentrate on what matters instead: Writing games.</p>
<p>I decided to continue hosting it myself on Dreamhost. I can easily have one repository for every major project. However, by default, Dreamhost creates svn repositories using htaccess security and HTTP protocol. That&rsquo;s OK, except that none of the actual data is encrypted as it would be if I were using ssh. I could use HTTPS, but then I would have to set up a certificate and pay for a fixed IP address, so instead I found an alternate way to have a secure connection.</p>
<p>All Subversion repositories live in a user account (svnuser). I create a new user group for every repository, and change all the files in the repository to belong to that group. Make sure you also set the <a href="http://tldp.org/LDP/intro-linux/html/sect_04_01.html#sect_04_01_06">SGID bit</a> so any files created in that directory still belong to the group. Then I can create a new shell user for every collaborator, and add him to the groups of the repositories I&rsquo;d like him to have access to. At that point, he&rsquo;ll be able to access the repository as svh+ssh://username@hostname.com/home/svnuser/repository. All safe and secure.</p>
<h3 id="bonus-svn-fu">Bonus SVN-Fu</h3>
<p>Here&rsquo;s something that I learned yesterday while I was moving repositories around. It&rsquo;s probably common knowledge for seasoned SVN admins, but it was new to me.</p>
<p>I had a repository that included a bunch of my projects. What I wanted was to create a new repository that still had all the history, but only for the FlowerGarden part of the tree. I knew about svnadmin dump for transferring whole repositories, but I didn&rsquo;t know there was a very simple way to <a href="http://svnbook.red-bean.com/en/1.5/svn.reposadmin.maint.html#svn.reposadmin.maint.filtering">only transfer part of it</a>.</p>
<p>First you need to dump it as usual:</p>
<pre tabindex="0"><code>svnadmin dump repository &gt; repos-dumpfile
</code></pre><p>Now, it turns out you can process the dump file before adding it back to another repository. So we can do:</p>
<pre tabindex="0"><code>svndumpfilter include FlowerGarden --drop-empty-revs --renumber-revs &lt; repos-dumpfile &gt; fg-dumpfile
</code></pre><p>Finally, you can add the resulting dump file into a fresh repository and have all the history for that project and only that project:</p>
<pre tabindex="0"><code>svnadmin create flowergarden
svnadmin load --ignore-uuid flowergarden &lt; fg-dumpfile
</code></pre><p>Amazingly, for a repository that was over 2GB, that only took a few minutes. Go Subversion!</p>
<p>[1] Or reading. Or going for a walk. Heck, even sleeping would be a better use of my time than futzing around with a new tool.[2]</p>
<p>[2] And yes, I realize I sound like a grumpy old man. Getting there apparently. Now get off my lawn.</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>Growing, Indie Style</title><link>https://gamesfromwithin.com/growing-indie-style/</link><pubDate>Thu, 26 Aug 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/growing-indie-style/</guid><description>&lt;p&gt;The media have covered to death both sides of the coin: The stories of developers &lt;a href="http://bits.blogs.nytimes.com/2010/06/25/doodle-jump-reaches-five-million-downloads/"&gt;striking&lt;/a&gt; &lt;a href="http://tech.fortune.cnn.com/2010/02/11/meet-the-guys-behind-pocket-god/"&gt;it&lt;/a&gt; &lt;a href="http://thenextweb.com/mobile/2010/08/13/angry-birds-sells-6-5-million-copies-shoots-for-100-million-paid-downloads/"&gt;big&lt;/a&gt;, and how the great majority of indies don&amp;rsquo;t recoup their costs. A few days ago, &lt;a href="http://pocketcyclone.com/"&gt;Markus&lt;/a&gt; &lt;a href="http://pocketcyclone.com/2010/08/24/indie-devs-dirty-little-secret/"&gt;looked at indie iPhone development&lt;/a&gt; and how there is a middle-ground group of developers that are able to make make a living at it without going broke but without getting that big hit. Let&amp;rsquo;s call them the &lt;em&gt;developer&amp;rsquo;s middle class&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Markus suggested that about 20% of developers fall in that middle class, but my gut feeling, when it comes to iPhones and games, is that it&amp;rsquo;s more like 5-10%. But it&amp;rsquo;s just a made up number based on personal observation anyway. It would be very interesting to conduct some sort of survey (or analyze the App Store data), but I fear the results would get muddled up due to the differences between full time indies, hobbyists, and big companies.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The media have covered to death both sides of the coin: The stories of developers <a href="http://bits.blogs.nytimes.com/2010/06/25/doodle-jump-reaches-five-million-downloads/">striking</a> <a href="http://tech.fortune.cnn.com/2010/02/11/meet-the-guys-behind-pocket-god/">it</a> <a href="http://thenextweb.com/mobile/2010/08/13/angry-birds-sells-6-5-million-copies-shoots-for-100-million-paid-downloads/">big</a>, and how the great majority of indies don&rsquo;t recoup their costs. A few days ago, <a href="http://pocketcyclone.com/">Markus</a> <a href="http://pocketcyclone.com/2010/08/24/indie-devs-dirty-little-secret/">looked at indie iPhone development</a> and how there is a middle-ground group of developers that are able to make make a living at it without going broke but without getting that big hit. Let&rsquo;s call them the <em>developer&rsquo;s middle class</em>.</p>
<p>Markus suggested that about 20% of developers fall in that middle class, but my gut feeling, when it comes to iPhones and games, is that it&rsquo;s more like 5-10%. But it&rsquo;s just a made up number based on personal observation anyway. It would be very interesting to conduct some sort of survey (or analyze the App Store data), but I fear the results would get muddled up due to the differences between full time indies, hobbyists, and big companies.</p>
<p>Snappy Touch falls squarely in the <em>developer&rsquo;s middle class</em>. I&rsquo;ve been very lucky and <a href="/the-power-of-free/">Flower Garden&rsquo;s sales</a> have been remarkably stable, hovering at around $2,000 per week (and spiking up during promotions and new updates).</p>
<p>For the 90% of developers that don&rsquo;t make their money back, their choices are limited to either stopping, or digging deeper in their pockets (or somebody else&rsquo;s pockets) and try again. For the 0.1% that hit it out of the park, they bring in so much money they can pretty much choose to do anything they want without risking the company.</p>
<p>For us middle-class developers, things are tougher. We have two choices:</p>
<ul>
<li>The first course of action is plodding along doing what we&rsquo;re doing, making a reasonable living and putting some money aside. We can build our personal and business nest egg, and then a bit more. And we can love every minute of it.</li>
<li>Choice number two is to take any spare money and reinvest it in the company. And in the case of iPhone development, that can only mean getting more people involved creating the games.</li>
</ul>
<p><img alt="time-vs-money.jpg" loading="lazy" src="/growing-indie-style/images/time-vs-money.jpg">The first choice is nice and safe. We can keep doing what we love, making a living from it, and even saving some money. Assuming the App Store doesn&rsquo;t collapse overnight, we might be able to pull that off for a few more years. But it has a horrible hidden cost: The opportunity cost.</p>
<p>Most long-term, successful apps will require a fair amount of updates. New content keeps users interested, and they also expect support for new hardware (iPad, iPhone 4, etc). All the time I spend creating updates for Flower Garden is time I don&rsquo;t spend making a new game. At the top of my list of hundreds of game ideas, I have four or five that I know will be successful, but the bottleneck from making them happen is my bandwidth. I can only do so much by myself.</p>
<p>That&rsquo;s why I&rsquo;ve decided that Snappy Touch needs to grow. Mind you, I&rsquo;m not talking big corporation, I don&rsquo;t ever want to even get to 20 people. But I would love to eventually be able to have a small team working on a new project and a few other developers maintaining and updating existing projects. I envision it happening mostly as distributed development and not in a traditional office setting.</p>
<p>The problem is how to start. Going from one to two people is probably the hardest step in growing a company. It&rsquo;s a 100% increase! That&rsquo;s probably another reason why successful startups often have three people involved from the start: Adding a fourth person is &ldquo;only&rdquo; a 33% increase in size, which seems more manageable.</p>
<p>Adding another person is also scary from a money point of view. It&rsquo;s going from saving just a bit of money, to potentially spending it all so that maybe we can produce more games and make more money in the end. That&rsquo;s a lesson I learned very clearly in <a href="http://download.cnet.com/DopeWars-Palm/3000-2099_4-10029311.html">Dope Wars</a>: You need money to make money. To get crazy scores in that game, you had to take a huge loan out from the start (and then be really lucky). Except that in this case there&rsquo;re no loans (I&rsquo;m totally self-funded). And it&rsquo;s also not a game, it&rsquo;s real life.</p>
<p>Having said all of that, I&rsquo;m going to turn this post into a recruiting tool (which is great because it self-selects the target audience to people who read this blog or <a href="http://twitter.com/snappyTouch">follow me on Twitter</a>).</p>
<h3 id="position-description">Position Description</h3>
<p><em>[Edit: Thanks for the overwhelming response! I already have enough candidates and the tricky part is selecting just one! I&rsquo;ll post again whenever a similar opportunity opens up. Thanks!]</em></p>
<p>I&rsquo;m looking for an programmer intern/part-time entry level position. Later on, if things work out, it could become a full-time position. I&rsquo;m looking for someone who can dive into the Flower Garden source code and quickly be able to start maintaining it and adding features. I&rsquo;ll definitely remain involved with the project, but I&rsquo;ll be mostly setting the direction and working on the harder bits. I expect us to be in contact on a daily basis, and set up a quick iChat call once or twice a week (or if you&rsquo;re local we can work half a day a week together).</p>
<p><strong>Requirements</strong></p>
<ul>
<li>Very familiar with iPhone development (you should have some apps under your belt).</li>
<li>Very familiar with Objective C and the UIKit framework</li>
<li>Good knowledge of C (and a tiny bit of C++)</li>
<li>Available to work 10-20 hours per week. This is very flexible.</li>
<li>Bonus points for knowing Python or having used the Google App Engine.</li>
<li>I&rsquo;d prefer someone who can work for several months (and maybe longer term).</li>
<li>Local to San Diego would be great, but not a requirement as long as we can voice chat easily.</li>
</ul>
<p>Compensation is hourly and based on experience, but remember this is an intern/entry level position. Possible bonuses based on performance and sales. Sounds like something you&rsquo;d be interested in? <a href="/contact/">Drop me a note and convince me you&rsquo;re the right person for the job.</a>.</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>Prototyping: You're (Probably) Doing It Wrong</title><link>https://gamesfromwithin.com/prototyping-youre-probably-doing-it-wrong/</link><pubDate>Thu, 12 Aug 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/prototyping-youre-probably-doing-it-wrong/</guid><description>&lt;p&gt;You&amp;rsquo;re not alone, I was also doing prototyping wrong until a few years ago. There are probably many different ways of prototyping games correctly, and maybe your way works great for you. In that case, a more accurate title for this post could have been &amp;ldquo;Prototyping: I Was Doing It Wrong&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;A good game prototype is something fast/cheap that allows you to answer a specific question about your game. The key points there are &lt;em&gt;fast/cheap&lt;/em&gt; and &lt;em&gt;specific question&lt;/em&gt;. It&amp;rsquo;s not a level of a game, it&amp;rsquo;s not a &amp;ldquo;vertical slice&amp;rdquo;, and it&amp;rsquo;s certainly not an engine for the game.&lt;/p&gt;</description><content:encoded><![CDATA[<p>You&rsquo;re not alone, I was also doing prototyping wrong until a few years ago. There are probably many different ways of prototyping games correctly, and maybe your way works great for you. In that case, a more accurate title for this post could have been &ldquo;Prototyping: I Was Doing It Wrong&rdquo;.</p>
<p>A good game prototype is something fast/cheap that allows you to answer a specific question about your game. The key points there are <em>fast/cheap</em> and <em>specific question</em>. It&rsquo;s not a level of a game, it&rsquo;s not a &ldquo;vertical slice&rdquo;, and it&rsquo;s certainly not an engine for the game.</p>
<p><a href="http://chrishecker.com/Homepage">Chris Hecker</a> and <a href="http://www.slackworks.com/%7Ecog/">Chaim Gingold</a> gave one of the <a href="http://www.d6.com/users/checker/gdc06-AdvancedPrototyping.ppt">best presentations on the subject of rapid prototyping</a>. It was hugely influential for me, and it made me re-think the way I do prototypes. If you get a chance, find the audio for the presentation, it&rsquo;s definitely worth it.</p>
<h3 id="mistake-1-going-with-the-first-idea">Mistake #1: Going With The First Idea</h3>
<p><img alt="proto_2.jpg" loading="lazy" src="/prototyping-youre-probably-doing-it-wrong/images/proto_2.jpg">Every company I&rsquo;ve ever worked at has done this mistake. The team hashes out a bunch of ideas, and somehow they pick one (or create it by committee). Maybe they&rsquo;ll create a prototype to show something about the game, or maybe they&rsquo;ll dive straight and start writing a design document and developing technology. If you&rsquo;re lucky, or you have an extremely talented game director, the game that comes out of the other end might be fantastic. In most cases, it&rsquo;s just a so-so idea and the team only realizes it when the first level comes together, years later, at around alpha time. At this point the choice is canning a project after spending millions of dollars, or patching it up to try to salvage something. Neither idea is particularly appealing.</p>
<p>Creating a prototype for a game you know you&rsquo;ve already committed to is pointless. It&rsquo;s nothing more than an exercise to keep management happy. Frankly, I even made that same mistake at Power of Two, when <a href="/prototyping-for-fun-and-profit/">we prototyped the game idea we had in mind</a> and immediately moved on into pre-production (and yes, later we realized we had to change things to make it more interesting).</p>
<p>What I do now is to force myself to prototype several of my top ideas before committing to any one project. I have a page (actually, a <a href="http://trac.edgewall.org/">wiki</a> page) with every game idea or thought I have. That page has way over a hundred entries, and every so often I cull and reorganize it, bringing up the most promising ideas towards the top. Whenever I&rsquo;m in prototyping mode, I start grabbing them from the top and prototype them.</p>
<p><img alt="proto_1.jpg" loading="lazy" src="/prototyping-youre-probably-doing-it-wrong/images/proto_1.jpg">With a good prototype it&rsquo;s easy to see if an idea is worthwhile. If it&rsquo;s not, I discard it and move on to the next one. If it has potential but it&rsquo;s just so-so, I either choose to continue just a bit longer (to ask another, better question) or I shelve it back in the list of potential game ideas. Maybe at some later time, things might click in or I might have a new inspiration and the game idea might become a lot stronger.</p>
<p>Also, often times, after doing one prototype and deciding against it, a new idea will come up. Usually a variation on the original prototype or something directly sparked from it, so I&rsquo;ll find myself jumping to that idea instead of one of the ones I had saved in my list.</p>
<p>Eventually, one idea will click and you&rsquo;ll know that&rsquo;s &ldquo;the one&rdquo;. If you&rsquo;re lucky (or unlucky) enough to have that happen with the first one you try, I still recommend doing a few more prototypes. If nothing else, you might be prototyping future projects, so it&rsquo;s certainly not wasted time. For my current project, I went through eight prototypes before finding &ldquo;the one&rdquo; (several of them were a collaboration with <a href="http://twitter.com/mysterycoconut">Miguel</a>). Eight to ten prototypes per project is roughly what I&rsquo;m hearing from other indies with this approach.</p>
<h3 id="mistake-2-not-having-a-good-question">Mistake #2: Not having a good question</h3>
<p>A good prototype attempts to answer a question about the game. But not all questions are created equal. First of all, a question needs to be relevant and crucial to the project. &ldquo;Can I have a pretty settings screen?&rdquo; isn&rsquo;t a particularly difficult question to answer, so it doesn&rsquo;t deserve its own prototype. &ldquo;Can I control little planes by drawing smooth lines on the screen?&rdquo; is a much bigger unknown (before Flight Control anyway, today you can just download the game and immediately answer yes).</p>
<p><img alt="proto_3.jpg" loading="lazy" src="/prototyping-youre-probably-doing-it-wrong/images/proto_3.jpg">Also, a good question is concise and can be answered in a fairly unambiguous way. &ldquo;Is this game awesome?&rdquo; isn&rsquo;t a good question because &ldquo;awesome&rdquo; is very vague. A better question might be &ldquo;Can I come up with a tilt control scheme that is responsive and feels good?&rdquo;. Feels good is a very subjective question, but it&rsquo;s concrete enough that people can answer that pretty easily after playing your prototype for a bit.</p>
<p>Even though most questions are about game design, they can also be about any other aspect of the game. Maybe you&rsquo;re doing something tricky with technology and you want to make sure it&rsquo;s feasible. If not, there&rsquo;s no point in even starting. It&rsquo;s more uncommon to think of prototyping art, but it&rsquo;s also a very valid approach: &ldquo;Will this art style allow foreground objects to stand out enough?&rdquo; &ldquo;Will the lighting approach allow the player to see important features in enough detail?&rdquo;. Often you can do these art &ldquo;prototypes&rdquo; directly in Photoshop or a 3D modeling package.</p>
<p>In the case of Flower Garden, the main unknown was the technology behind the procedural flowers. So I created a prototype to answer the question &ldquo;Can I create compelling procedural flowers that grow in real-time and the user can interact with them?&rdquo;. The prototype had several parts to answer that question: the geometry generation, the animation, the simulation, and the rendering. There isn&rsquo;t anything else particularly ground-breaking in the rest of the Flower Garden code, so as soon as I was able to answer &ldquo;yes&rdquo; to that question, I green-lighted the project and started production on it.</p>
<p>For larger projects, you might have several major, outstanding questions, so you&rsquo;ll need to do multiple prototypes. Unless they&rsquo;re very closely related, I find it easier to keep them separate instead of building on top of the same prototype.</p>
<p>Without a good question, it&rsquo;s too easy for a prototype to go on for a long time. You feel you&rsquo;re making progress because new things are added, but you have no real sense of when to stop or when it&rsquo;s done. You really have to focus on the question, ignore everything else, and be merciless in your approach.</p>
<h3 id="mistake-3-taking-too-long">Mistake #3: Taking too long</h3>
<p><img alt="proto_4.jpg" loading="lazy" src="/prototyping-youre-probably-doing-it-wrong/images/proto_41.jpg">One of the key concepts in the definition of a prototype was that it has to be fast/cheap (which are two sides of the same coin). What&rsquo;s fast enough? It depends on the length of the project itself. It&rsquo;s not the same thing to do a prototype for a two-month iPhone game, than for a three-year console game. Also, a larger, more expensive project probably has more complex questions to answer with a prototype than a simple iPhone game.</p>
<p>In my case, I shoot for one-day prototypes. If you already have the tech to create games with, one day allows you to focus 100% on answering the question. By the end of the day, or even before, I have a pretty good idea how the game is going to work out. My shortest prototype ever was a 2-hour one. I thought it was going to be longer, but I managed to complete everything to answer the question in two hours (for the record, I didn&rsquo;t can that idea, but I shelved it for a possible future project).</p>
<p><a href="http://iphonegamejam.com/index.php?title=Main_Page">Game</a> <a href="http://indiegamejam.com/">jams</a> are a great way to get over the mental block of doing quick prototypes. There you are focused on making the game on a very short time, surrounded by people trying to do the same thing. I can&rsquo;t think of a more fun way to prototype than that!</p>
<p>Also, think beyond programming. Is there a faster way you can answer the prototype question? Maybe you can use the modding capabilities of an existing game, or even do a mockup with paper moving pieces around. Don&rsquo;t fall in the trap of thinking you have to code a prototype if something simpler and faster will do.</p>
<p>If you find that a day is not enough, take a step back and really ask yourself why you need more time. Were you getting side-tracked on things that were irrelevant to the prototype (menus, tech, art, etc)? Are you asking a question that the prototype can&rsquo;t answer? Do you have the game idea clearly defined in your head?</p>
<h3 id="mistake-4-building-a-system-not-a-game">Mistake #4: Building a system, not a game</h3>
<p><img alt="proto_5.jpg" loading="lazy" src="/prototyping-youre-probably-doing-it-wrong/images/proto_5.jpg">When you&rsquo;re making a prototype, if you ever find yourself working on something that isn&rsquo;t directly moving your forward, stop right there. As programmers, we have a tendency to try to generalize our code, and make it elegant and be able to handle every situation. We find that an itch terribly hard not scratch, but we need to learn how. It took me many years to realize that it&rsquo;s not about the code, it&rsquo;s about the game you ship in the end.</p>
<p>Don&rsquo;t write an elegant game component system, skip the editor completely and hardwire the state in code, avoid the data-driven, self-parsing, XML craziness, and just code the damned thing.</p>
<p>When you&rsquo;re prototyping, it&rsquo;s a race to answer the main prototype question. Everything is expendable. Don&rsquo;t even worry about memory leaks, hardwired numbers, or how you load resources. Just get stuff on the screen as quickly as you can.</p>
<p>And don&rsquo;t ever, ever, use the argument &ldquo;if we take some extra time and do this the <em>right</em> way, we can reuse it in the game&rdquo;. EVER.</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 Const Nazi</title><link>https://gamesfromwithin.com/the-const-nazi/</link><pubDate>Thu, 15 Jul 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-const-nazi/</guid><description>&lt;p&gt;Anybody who worked with me or saw any of my code, would know right away why they call me the Const Nazi. That&amp;rsquo;s because in my coding style, I make use of the keyword &lt;em&gt;const&lt;/em&gt; everywhere. But instead of going on about how &lt;em&gt;const&lt;/em&gt; is so great, I&amp;rsquo;m going to let Hitler tell us how he really feels about it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;No Flash? Try the &lt;a href="https://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi.mov"&gt;QuickTime video version&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Let me get one thing out of the way to stop all the trigger-happy, const-bashing, would-be-commenters: &lt;em&gt;const&lt;/em&gt; doesn&amp;rsquo;t make any guarantees that values don&amp;rsquo;t change.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Anybody who worked with me or saw any of my code, would know right away why they call me the Const Nazi. That&rsquo;s because in my coding style, I make use of the keyword <em>const</em> everywhere. But instead of going on about how <em>const</em> is so great, I&rsquo;m going to let Hitler tell us how he really feels about it.</p>
<p><em>No Flash? Try the <a href="/wp-content/uploads/2010/07/const_nazi.mov">QuickTime video version</a>.</em></p>
<p>Let me get one thing out of the way to stop all the trigger-happy, const-bashing, would-be-commenters: <em>const</em> doesn&rsquo;t make any guarantees that values don&rsquo;t change.</p>
<p>You can change a <em>const</em> variable by casting the constness away, or referencing it through a pointer, but you really had to go out of your way to do that. If it helped with that, const would solve (or improve) the memory aliasing problem like Hitler pointed out. It doesn&rsquo;t, so const is pretty weak as far as promises go. It just says &ldquo;I, the programmer, promise not to change this value on purpose (unless I&rsquo;m truly desperate)&rdquo;. Still, even a promise like that goes a long way helping with readability and maintenance.</p>
<p>With that out of the way, what exactly do I mean by using <em>const</em> everywhere?</p>
<h3 id="const-non-value-function-parameters">Const non-value function parameters</h3>
<p>Any reference or pointer function parameters that are pointing to data that will not be modified by the function should be declared as <em>const</em>. If you&rsquo;re going to use <em>const</em> just for one thing, this is the one to use. It&rsquo;s invaluable glancing at a function signature and seeing which parameters are inputs and which ones are outputs.</p>
<pre tabindex="0"><code>void Detach(PhysicsObject&amp; physObj, int attachmentIndex, const HandleManager&amp; mgr);
</code></pre><p>Marking those parameters as <em>const</em> also serves as a warning sign in case a programmer in the future tries to modify one of them. Imagine the disaster if the calling code assumes data never changes, but the function suddenly starts modifying that data! <em>const</em> won&rsquo;t prevent that from happening, but will remind the programmer that he&rsquo;s changing the &ldquo;contract&rdquo; and needs to revisit all calling code and check assumptions.</p>
<h3 id="const-local-variables">Const local variables</h3>
<p>This is a very important use of <em>const</em> and one of the ones hardly anyone follows. If I declare a local (stack) variable and its value never changes after initialization, I always declare it <em>const</em>. That way, whenever I see that variable used later in the code, I know that its value hasn&rsquo;t changed.</p>
<pre tabindex="0"><code>const Vec2 newPos = AttachmentUtils::ApplySnap(physObj, unsnappedPos);
const Vec2 deltaPos = newPos - physObj.center;
physObj.center = newPos;
</code></pre><p>This is one of the reasons why I did a 180 on the ternary C operator (?). I used to hate it and find it cryptic and unreadable, but now I find it compact and elegant and it fulfills my <em>const</em> fetish very well.</p>
<p>Imagine you have a function that is going to work in one of two objects and you need to compute the index to the object to work on. You could do it this way:</p>
<pre tabindex="0"><code>int index;
if (some condition)
	index = 0;
else
	index = 2;

DoSomethingWithIndex();
</code></pre><p>Not only does that take several lines not to do much, but index isn&rsquo;t <em>const</em> (argh!). So every time I see index anywhere later on in that function, I&rsquo;m going to have to spend the extra mental power to make sure nothing has changed (and, with my current coding style, I would assume it has changed).</p>
<p>Instead, we can simply do this:</p>
<pre tabindex="0"><code>const int index = (some condition) ? 0 : 2;
DoSomethingWithIndex();
</code></pre><p>Ahhhh&hellip; So much better!</p>
<h3 id="const-member-variables">Const member variables</h3>
<p>This one doesn&rsquo;t really apply to me anymore because I don&rsquo;t use classes and member variables. But if you do, I strongly encourage you do mark every possible member function as <em>const</em> whenever you can.</p>
<p>The only downside is that sometimes you&rsquo;ll have some internal bit of data that is really not changing the &ldquo;logical&rdquo; state of an object, but it&rsquo;s still modifying a variable (usually some caching or logging data). In that case, you&rsquo;ll have to resort to the mutable keyword.</p>
<h3 id="const-value-function-parameters">Const value function parameters</h3>
<p><img alt="const_nazi.jpg" loading="lazy" src="/the-const-nazi/images/const_nazi.jpg">Apparently I&rsquo;m not a total Const Nazi because this is one possible use of <em>const</em> that I choose to skip (even though I tried it for a while because of <a href="http://cnicholson.net/">Charles</a>).</p>
<p>Marking a value function parameter as <em>const</em> doesn&rsquo;t make any difference from the calling code point of view, but it serves the same purpose as marking local stack variables as <em>const</em> in the implementation of the function. You&rsquo;re just saying &ldquo;I&rsquo;m not going to modify that parameter in this function&rdquo; so it makes the code easier to understand.</p>
<p>I&rsquo;m actually all for this, but the only reason I&rsquo;m not doing it is because C/C++ makes it a pain. Marking parameters as <em>const</em> in the function declaration adds extra verbosity and doesn&rsquo;t help the person browsing the functions at all. You could actually put the <em>const</em> only in the function definition and it will work, but at that point the declaration and the definition are different, so you can&rsquo;t copy and paste them or use other automated tools or scripts.</p>
<p>The concept of <em>const</em> is one of the things I miss the most when programming other languages like C#. I don&rsquo;t understand why they didn&rsquo;t add it to the language. On something like Python or Perl I can understand because they&rsquo;re supposed to be so free form, but C#? (Edit: How about that? <a href="http://msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx">Apparently C# has const</a>. It was either added in the last few years or I completely missed it before). It also really bugs me that Objective C or the Apple API doesn&rsquo;t make any use of <em>const</em>.</p>
<p>Frankly, if it were up to me, I would change the C/C++ language to make every variable <em>const</em> by default and adding the <em>nonconst</em> or <em>changeable</em> (or take over <em>mutable</em>) keyword for the ones you want to modify. It would make life much more pleasant.</p>
<p>But then again, that&rsquo;s why the call me the Const Nazi.</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>The Always-Evolving Coding Style</title><link>https://gamesfromwithin.com/the-always-evolving-coding-style/</link><pubDate>Fri, 25 Jun 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-always-evolving-coding-style/</guid><description>&lt;p&gt;&lt;em&gt;This is my first entry into &lt;a href="http://twitter.com/#search?q=%23idevblogaday"&gt;#iDevBlogADay&lt;/a&gt;. It all &lt;a href="http://twitter.com/mysterycoconut/status/16871555420"&gt;started very innocently with a suggestion from Miguel&lt;/a&gt;, but the ball got rolling pretty quickly. The idea is to have one independent iPhone game developer write a blog entry each day of the week. At first we thought we would be hard-pressed to get 7 developers, but it&amp;rsquo;s starting to seem we might have multiples per day!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Check out the new sidebar with all the #iDevBlogADay blogs. We&amp;rsquo;re also putting together a &lt;a href="feed://pipes.yahoo.com/pipes/pipe.run?_id=52b65f0bbfca4cc92db78d0b0408cac6&amp;amp;_render=rss"&gt;common RSS feed&lt;/a&gt; if you want to subscribe to that instead.&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>This is my first entry into <a href="http://twitter.com/#search?q=%23idevblogaday">#iDevBlogADay</a>. It all <a href="http://twitter.com/mysterycoconut/status/16871555420">started very innocently with a suggestion from Miguel</a>, but the ball got rolling pretty quickly. The idea is to have one independent iPhone game developer write a blog entry each day of the week. At first we thought we would be hard-pressed to get 7 developers, but it&rsquo;s starting to seem we might have multiples per day!</em></p>
<p>Check out the new sidebar with all the #iDevBlogADay blogs. We&rsquo;re also putting together a <a href="feed://pipes.yahoo.com/pipes/pipe.run?_id=52b65f0bbfca4cc92db78d0b0408cac6&amp;_render=rss">common RSS feed</a> if you want to subscribe to that instead.</p>
<p>Writing is addictive, so don&rsquo;t be surprised if this once-a-week minimum turns into multiple-times-a-week.</p>
<p> </p>
<p><img alt="matrix.jpg" loading="lazy" src="/the-always-evolving-coding-style/images/matrix.jpg">Every developer who&rsquo;s been working on a team for a while is able to tell the author of a piece of code just by looking at it. Sometimes it&rsquo;s even fun to do a forensic investigation and figure out not just the original author, but who else modified the source code afterwards.</p>
<p>What I find interesting is that I can do the same thing with my own code&hellip; as it changes over time. Every new language I learn, every book I read, every bit of code I see, every open-source project I browse, every pair-programming session, every conversation with a fellow developer leaves a mark behind. It slightly changes how I think of things, and realigns my values and priorities as a programmer. And those new values translate into different ways to write code, different architectures, and different coding styles.</p>
<p>It never happens overnight. I can&rsquo;t recall a single case where I changed my values in a short period of time, causing dramatic changes to my coding style. Instead, it&rsquo;s the accumulation of lots of little changes here and there that slowly shifts things around. It&rsquo;s like the movement of the Earth&rsquo;s magnetic pole: very slow, but changes radically over time (although maybe just a tad bit faster).</p>
<h3 id="why-talk-about-coding-styles">Why Talk About Coding Styles</h3>
<p>Coding style in itself is purely a personal thing, and therefore, very uninteresting to talk about. However, in its current form, my coding style goes against the grain of most general modern &ldquo;good practices&rdquo;. A few weeks ago I released <a href="/opengl-and-uikit-demo/">some sample source code</a> and it caused a bit of a stir because it was so unconventional. That&rsquo;s when I realized it might be worth talking about it after all (along with <a href="http://twitter.com/GeorgeSealy/status/15800523038">George bugging me about it</a>), and especially the reasons why it is the way it is.</p>
<p>Before I even start, I want to stress that I&rsquo;m not advocating this approach for everybody, and I&rsquo;m certainly not saying it&rsquo;s the perfect way to go. I know that in a couple of years from now, I&rsquo;ll look back at the code I&rsquo;m writing today and it will feel quaint and obsolete, just like the code I wrote during <a href="/office-tools-for-starving-startups/">Power of Two Games</a> looks today. All I&rsquo;m saying is that this is the style that fits <strong>me</strong> best <strong>today</strong>.</p>
<h3 id="motivation">Motivation</h3>
<p>This is my current situation which shapes my thinking and coding style:</p>
<ul>
<li>All my code is written in C and C++ (except for a bit of ObjC and assembly).</li>
<li>It&rsquo;s all for real-time games on iPhone, PCs, or modern consoles, so performance and resource management are very important.</li>
<li>I always try to write important code through <a href="/backwards-is-forward-making-better-games-with-test-driven-development/">Test-Driven Development</a>.</li>
<li>I&rsquo;m the only programmer (and only designer).</li>
<li>Build times in my codebase are very fast.</li>
</ul>
<p>And above all, <a href="/simple-is-beautiful/">I love simplicity</a>. I try to achieve simplicity by considering every bit of code and thinking whether it&rsquo;s absolutely necessary. I get rid of anything that&rsquo;s not essential, or that&rsquo;s not benefitting the project by at least two or three times as much as it&rsquo;s complicating it.</p>
<h3 id="how-i-write-today">How I Write Today</h3>
<p>So, what does my code look like these days? Something like this (this is taken from a prototype I wrote with <a href="http://twitter.com/mysterycoconut">Miguel</a> of <a href="http://mysterycoconut.com/">Mystery Coconut</a> fame):</p>
<pre tabindex="0"><code>namespace DiverMode
{
    enum Enum
    {
        Normal,
        Shocked,
        Inmune,
    };
}

struct DiverState
{
    DiverState()
        : mode(DiverMode::Normal)
        , pos(0,0)
        , dir(0)
        , o2(1)
        , boostTime(0)
        , timeLeftInShock(0)
        , timeLeftImmune(0)
    {}

    DiverMode::Enum mode;
    Vec2 pos;
    float dir;
    float o2;

    float boostTime;
    float timeLeftInShock;
    float timeLeftImmune;
};

namespace DiverUtils
{
    void Update(float dt, const Vec2&amp; tiltInput, GameState&amp; state);
    void Shock(DiverState&amp; diver);
    void StartSprint(DiverState&amp; diver);
    void StopSprint(DiverState&amp; diver);
}
</code></pre><p>The first thing that stands out is that I&rsquo;m using a struct and putting related functions in a namespace. It may seem that&rsquo;s just a convoluted way of writing a class with member functions, but there&rsquo;s more to it than that.</p>
<p>By keeping the data in a struct instead of a class, I&rsquo;m gaining several advantages:</p>
<ul>
<li>I&rsquo;m showing all the data there is and how big it is. Nothing is hidden.</li>
<li>I&rsquo;m making it clear that it&rsquo;s free of pointers and temporary variables.</li>
<li>I&rsquo;m allowing this data to be placed anywhere in memory.</li>
</ul>
<p>The fact that the functions are part of a namespace is not really defensible; it&rsquo;s pure personal preference. It would have been no different than if I had prefixed them with DriverUtils_ or anything else, I just think it looks clearner. I do prefer the functions to be separate and not member functions though. It makes it easier to organize functions that work on multiple bits of data at once. Otherwise you&rsquo;re stuck deciding whether to make them members of one structure or another. It also makes it easier to break up data structures into separate structures later on and minimize the amount of changes to the code.</p>
<p>Probably one of the biggest influences on me starting down this path was the famous article by Scott Meyers <a href="http://www.drdobbs.com/184401197;jsessionid=Z3IAXBFRBPX03QE1GHRSKHWATMY32JVN">How Non Member Functions Improve Encapsulation</a>. I remember being shocked the first time I read it (after having read religiously <a href="http://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876/?tag=gamesfromwith-20">Effective C++</a> and <a href="http://www.amazon.com/More-Effective-Improve-Programs-Designs/dp/020163371X/?tag=gamesfromwith-20">More Effective C++</a>). That reasoning combined with all the other changes over the years, eventually led to my current approach.</p>
<p>Since everything is in a structure and everything is public, there&rsquo;s very little built-in defenses against misuse and screw-ups. That&rsquo;s fine because that&rsquo;s not a priority for me. Right now I&rsquo;m the only programmer, and if I work with someone else, I expect them to have a similar level of experience than me. Some codebases written with a defensive programming approach have an amazing amount of code (and therefore complexity) dedicated to babysitting programmers. No thanks. I do make extensive use of asserts and unit tests to allow me to quickly make large refactorings though.</p>
<p>Another thing to note that might not be immediately obvious from the example above is that all functions are very simple and shallow. They take a set of input parameters, and maybe an output parameter or just a return value. They simply transform the input data into the output data, without making extensive calls to other functions in turn. That&rsquo;s one of the basic approaches of <a href="/data-oriented-design/">data-oriented design</a>.</p>
<p>Because everything is laid out in memory in a very simple and clear way, it means that serialization is a piece of cake. I can fwrite and fread data and have instant, free serialization (you only need to do some extra work if you change formats and try to support older ones). Not only that, but it&rsquo;s great for saving the game state in memory and restoring it later (which I&rsquo;m using heavily in my current project). All it takes is this line of code:</p>
<pre tabindex="0"><code>oldGameState = currentGameState
</code></pre><p>This style is a dream come true for Test-Driven Development (TDD). No more worrying about mocks, and test injections, or anything like that. Give the function some input data, and see what the output is. Done! That simple.</p>
<p>One final aspect of this code that might be surprising to some is how concrete it is. This is not some generic game entity that hold some generic components, with connections defined in XML and bound together through templates. It&rsquo;s a dumb, <a href="http://en.wikipedia.org/wiki/Plain_old_data_structure">POD</a> Diver structure. Diver as in the guy going swimming underwater. This prototype had fish as well, and there was a Fish structure, and a large array of sequential, homogeneous Fish data. The main loop wasn&rsquo;t generic at all either: It was a sequence of UpdateDivers(), UpdateFish(), etc. Rendering was done in the same, explicit way, making it extra simple to minimize render calls and state changes. When you work with a system like this, you never, ever want to go back to a generic one where you have very little idea about the order in which things get updated or rendered.</p>
<h3 id="beyond-the-sample">Beyond The Sample</h3>
<p>To be fair, this sample code is very, very simple. The update function for a reasonable game element is probably larger than a few lines of code and will need to do a significant amount of work (check path nodes, cast rays, respond to collisions, etc). In that case, if it makes sense, the data contained in the structure can be split up. Or maybe the first update function generates some different output data that gets fed into later functions. For example, we can update all the different game entities, and as an output, get a list of ray cast operations they want to perform, do them all in a later step, and then feed the results back to the entities either later this frame or next frame if we don&rsquo;t mind the added latency.</p>
<p>There&rsquo;s also the question of code reuse. It&rsquo;s very easy to reuse some low level functions, but what happens when you want to apply the same operation to a Diver and to a Fish? Since they&rsquo;re not using inheritance, you can&rsquo;t use polymorphism. I&rsquo;ll cover that in a later blog post, but the quick preview is that you extract any common data that both structs have and work on that data in a homogeneous way.</p>
<p> </p>
<p>What do you think of this approach? In which ways do you think it falls short, and in which ways do you like it better than your current style?</p>
]]></content:encoded></item></channel></rss>