<?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>Posts on Games From Within</title><link>https://gamesfromwithin.com/posts/</link><description>Recent content in Posts on Games From Within</description><generator>Hugo</generator><language>en-us</language><copyright>2004–2026 Noel Llopis</copyright><lastBuildDate>Wed, 23 May 2018 00:00:00 +0000</lastBuildDate><atom:link href="https://gamesfromwithin.com/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Dealing Cards</title><link>https://gamesfromwithin.com/dealing-cards/</link><pubDate>Wed, 23 May 2018 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/dealing-cards/</guid><description>&lt;p&gt;Most of my games and prototypes lately are very board gamey and almost always involve dealing random &amp;ldquo;cards&amp;rdquo; to create a hand of cards. For example, in &lt;a href="http://subterfuge-game.com/"&gt;Subterfuge&lt;/a&gt; players have the choice of one of three specialists every few hours, which is similar to dealing 3 random cards and having the player pick one.&lt;/p&gt;
&lt;p&gt;You would think that dealing cards at random would be trivially easy to implement. You would also be wrong.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Deal" loading="lazy" src="https://gamesfromwithin.com/dealing-cards/images/deal.png"&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p>Most of my games and prototypes lately are very board gamey and almost always involve dealing random &ldquo;cards&rdquo; to create a hand of cards. For example, in <a href="http://subterfuge-game.com/">Subterfuge</a> players have the choice of one of three specialists every few hours, which is similar to dealing 3 random cards and having the player pick one.</p>
<p>You would think that dealing cards at random would be trivially easy to implement. You would also be wrong.</p>
<p><img alt="Deal" loading="lazy" src="/dealing-cards/images/deal.png"></p>
<h3 id="truly-random">Truly Random</h3>
<p>Always the eternal optimist (and devout follower of the <a href="https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it">YAGNI principle</a>), I start by implementing dealing cards by simply picking randomly among the types of cards available. Something along these lines:</p>
<pre tabindex="0"><code>for (int i=0; i&lt;HandSize; ++i)
    hand[i] = Random_GetInt(0, CardType::COUNT-1);
</code></pre><p>The best part of this approach is that it&rsquo;s simple. The bad part is&hellip; everything else.</p>
<p>Maybe that works for your game, and if so, congratulations, you can stop now and move on with the rest of the game. Unfortunately, this doesn&rsquo;t cut it for most card games. The player might get a hand all of the same card. Or maybe never get a card type that she really needs. Most of the time, an algorithm like this will frustrate players quite a bit and get in the way of the enjoyment of the game.</p>
<h3 id="deck-of-cards">Deck of Cards</h3>
<p>The next approach I usually try is to simply copy physical games and build an actual deck. Remember that we&rsquo;re talking about internal structures, so this doesn&rsquo;t mean that the concept of a deck is exposed to the player at all. As far as they know, they&rsquo;re just getting cards at &ldquo;random&rdquo;.</p>
<p><img alt="Deck" loading="lazy" src="/dealing-cards/images/deck-1.jpg"></p>
<p>In this case, you create an array of card types, shuffle it, and give cards from the top to the player.</p>
<pre tabindex="0"><code>const int cardsPerType = 3;
for (int i=0; i&lt;CardType::COUNT; ++i)
    for (int j=0; j&lt;cardsPerType; ++j)
        Deck_Add(deck, i);

Deck_Shuffle(deck);

for (int i=0; i&lt;HandSize; ++i)
    hand[i] = deck[i];
</code></pre><p>This is quite an improvement over our first approach. To start with, we&rsquo;re guaranteed never to get more than a certain amount of cards of each type in the deck. That will prevent ridiculous hands of all cards of the same type that make the game unplayable.</p>
<p>It also allows us to vary the amount of cards of each type in the deck. That way we can make some cards more rare than others, or even enforce unique cards by only adding one of each of those types.</p>
<p>You may argue that this approach is perfect since this is how &ldquo;true&rdquo; (meaning &ldquo;physical) card games are designed most of the time. While that is true, physical card games often involve just randomly shuffling a deck because the alternative would be very time consuming (or might need a third-party who isn&rsquo;t playing to set up the deck). Because of that, most games need to be able to deal with very uneven distribution of cards, which might be too limiting for your designs.</p>
<p>A lot of games games will benefit of having a more controlled deck, and since we&rsquo;re running on a computer, we can afford to do a lot more than just shuffle cards together. We can take advantage of the digital medium and do things we couldn&rsquo;t easily do with physical cards.</p>
<h3 id="aside-shuffling-a-deck">Aside: Shuffling a Deck</h3>
<p>Shuffling a deck might seem like a trivial algorithm, but as usual the details can get a bit tricky.</p>
<p>If you wanted to get very physical, you could try to simulate real riffle shuffling of a deck: randomly split the deck into more-or-less equal parts, and interleave them with each other with some randomness. Then you&rsquo;d have to run it <a href="https://www.math.hmc.edu/funfacts/ffiles/20002.4-6.shtml">several times</a> and even so I think you&rsquo;d get very suspect results.</p>
<p><img alt="Shuffling" loading="lazy" src="/dealing-cards/images/shuffling.gif"></p>
<p>A simplified algorithm is to randomly grab two cards in the deck and swap their positions. Is that good enough? How many times do you need to run that loop in order to get a proper (i.e. fully randomized) shuffle? I haven&rsquo;t analyzed that algorithm, but I get the feeling it would have to be done many times in order to get something acceptable (especially considering the not-very-random nature of computer &ldquo;random&rdquo; number generators).</p>
<p>The best and simplest approach I have found to shuffle a deck is the following: assign a random number to each card in the deck, then sort the cards based on that random number. It&rsquo;s easy to understand how a single sort will shuffle the deck properly and works the same for any number of cards (and runs in O(n log n) if we want to get pedantic about it).</p>
<h3 id="multiple-decks">Multiple Decks</h3>
<p>One way to have more control over the deck composition is to have multiple decks. We don&rsquo;t need to communicate to the player that there are in fact multiple decks, this is something that happens under the hood.</p>
<p>This is the approach we took in Subterfuge. Players are presented with a choice of 3 specialists every X hours. Initially those specialists were completely random, but the results were very underwhelming. <a href="https://blog.subterfuge-game.com/post/104851367166/luck-in-subterfuge">The approach we ended up settling on</a> involved classifying each specialist as being in the categories of attack, defense, or other. The game prepares 3 decks, one of each category with 3 of each of the specialists in each category. Additionally, we make sure that we never have 2 of the same specialist in a row.</p>
<p>When it comes time to generate 3 &ldquo;random&rdquo; specialists for the players to choose from, we pick the top one from each of the decks.</p>
<h3 id="blocks">Blocks</h3>
<p>In my current prototype, the player has a hand of 4-5 &ldquo;cards&rdquo;, and as soon as they use one, a new one is drawn and their hand refilled. Cards can be roughly classified in 6 different categories, and it&rsquo;s important that the player gets access to one of those categories within a few turns.</p>
<p>I wanted to come up with an approach that guaranteed access to tiles of all categories, but without making the pattern too obvious. For example, I didn&rsquo;t want to have the deck be one card of each category.</p>
<p>The solution I can up with was to break up the deck in blocks of 10 cards. Within each of those blocks, I can make some guarantees about its composition. This approach was inspired by the composition of boosters in collectable card games like Magic: The Gathering, or even in the way the deck is prepared in <a href="https://boardgamegeek.com/boardgame/30549/pandemic">Pandemic</a>.</p>
<p><img alt="Boosters" loading="lazy" src="/dealing-cards/images/boosters.jpg"></p>
<p>The way I implemented it, each block of 10 cards will contain one card of each category, plus 4 other random cards (as long as they are not already in the block). Then all the cards in the block are shuffled and added to the deck. This results in apparently &ldquo;random&rdquo; draws without feeling predictable, and yet players are never left without a key resource they may need.</p>
<p>This kind of enforced structure can also add some depth to the game. Expert players might notice this pattern (or read this, which is a lot easier) and use it to their advantage when they&rsquo;re trying to make decisions based on what cards might appear in future terms.</p>
<p>Any of you out there use a different method for creating random-but-not-quite-random draws in your games?</p>]]></content:encoded></item><item><title>Sometimes You Have To Let Go</title><link>https://gamesfromwithin.com/sometimes-you-have-to-let-go/</link><pubDate>Thu, 15 Mar 2018 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/sometimes-you-have-to-let-go/</guid><description>&lt;p&gt;As a game developer, working on a project for years just to have it cancelled can be devastating. I&amp;rsquo;ve been lucky enough that it has never happened to me, but it&amp;rsquo;s an occurrence all to common in the games industry. However, having to cancel your own game after years of work is even harder. So it is with a heavy heart that I announce that I&amp;rsquo;m stopping development on Lasting Legacy.&lt;/p&gt;</description><content:encoded><![CDATA[<p>As a game developer, working on a project for years just to have it cancelled can be devastating. I&rsquo;ve been lucky enough that it has never happened to me, but it&rsquo;s an occurrence all to common in the games industry. However, having to cancel your own game after years of work is even harder. So it is with a heavy heart that I announce that I&rsquo;m stopping development on Lasting Legacy.</p>
<p>When we started work on Lasting Legacy, I envisioned it as a quick 9-10 month project (that&rsquo;s quick for me, but I know it&rsquo;s long for other devs). As we worked on it, it felt like the game was interesting and rich enough to spend a little longer and flesh it out to its full potential. Maybe spend a total of a year and a half on it.</p>
<p>Now it&rsquo;s been two full years since we started. We&rsquo;ve had a playable game almost from the start, but when I have an honest look at it, it&rsquo;s still far from launch. We still need lots more content, game balancing, polishing, different game modes, porting to different platforms, creating videos, and all the marketing. It&rsquo;s that pesky last 20% that takes 80% of the time&ndash;OK, maybe not 80% but at least another 12 months. All of that is definitely doable, but it would bring the project to a full 3 years (at least!), or a total of 6 man-years.</p>
<p><img alt="Calendar" loading="lazy" src="/sometimes-you-have-to-let-go/images/calendar.jpg"></p>
<p>The problem with that is that, for Lasting Legacy to be financially successful, it would have to sell a lot of copies. A lot more than I can realistic expect it to sell. Let&rsquo;s reeeeeally stretch the meaning of &ldquo;successful&rdquo; and say that the goal is that we should each make $50K per year. That&rsquo;s a total of $300K after the cut from the stores, or about $430K in sales. At $15 per sale, that&rsquo;s almost 30K sales, and <a href="http://steamspy.com/year/">most Steam games don&rsquo;t come even close to that number</a>.</p>
<p>So we had a choice: We could focus really hard on the marketing aspect to make sure we hit that many sales, or we could stop development altogether, cut our loses, and move on to something else. The problem with focusing on marketing is that it would add even more time, making it necessary to sell even more copies to break even. It would also mean spending months doing work that I really dislike (making trailers, doing a Kickstarter, promoting the game, chasing reviewers and streamers&hellip;).</p>
<p>Would it be worth doing that marketing push? Was I really willing to bet that Lasting Legacy would be a big seller? If I&rsquo;m honest, I think that Lasting Legacy has the potential to be a very good, original game, but I don&rsquo;t think it&rsquo;s a game that lots of people want (or if they do, I wasn&rsquo;t able to connect with that audience). I&rsquo;m fine making games that don&rsquo;t sell very much, but at least I want to enjoy the work that I&rsquo;m doing. So in the end, I&rsquo;d rather stop working on Lasting Legacy and move on to other projects that I can enjoy and can be potentially more profitable.</p>
<p>Fortunately the time I spent on Lasting Legacy wasn&rsquo;t completely wasted: Apart from developing some new tech that I didn&rsquo;t have when I started (<a href="/using-sqlite-to-organize-design-data/">SQLite to organize data</a>, or on-the-fly font rendering for example), I continued to <a href="/isomorphism-as-a-game-design-tool/">grow as a designer</a>, and I hope a lot of what I learned will carry over to my future projects.</p>
<p>Some people will take away from this that Lasting Legacy failed because we didn&rsquo;t do market research to see if there was demand for it, or tailor it to the tastes of gamers. I disagree. My goal from the start was not to maximize profits, it was to make a game I found interesting and getting compensated for my time. The failure of Lasting Legacy was that we were just too slow. If we had managed to make the game in a year like we originally planned, just selling 5-6K units would have been enough to cover our time.</p>
<p>So what&rsquo;s next for me? I&rsquo;ve taken the lessons learned to heart and decided to make a game by myself in 6 months. That&rsquo;s a hard deadline. I&rsquo;m drawing inspiration from <a href="http://www.smestorp.com/">Michael Brough</a> and <a href="http://www.tinytouchtales.com/">Arnold Rauers</a>, both of them excellent game designers who make small games that start with major artificial constraints and they design around them. The constraint I picked is to make a simulation game in a very small grid (single screen, around 6x6). So far I&rsquo;ve been doing some prototypes and I&rsquo;m pretty happy how it&rsquo;s coming along. If all goes well I&rsquo;ll announce it soon and release it in a few months.</p>
<p>As part of this shift towards making smaller games, I&rsquo;m going to create a mailing list for my games in general, not for each game individually. If you&rsquo;d like to keep up to date, please sign up for my mailing list and I&rsquo;ll make sure you&rsquo;re the first ones to know about my upcoming games.</p>
<p>Subscribe to my mailing list</p>
<p>Wish me luck!</p>]]></content:encoded></item><item><title>Lasting Legacy Rulebook</title><link>https://gamesfromwithin.com/lasting-legacy-rulebook/</link><pubDate>Tue, 31 Oct 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/lasting-legacy-rulebook/</guid><description>&lt;p&gt;There&amp;rsquo;s nothing like writing down all the rules for a game to keep yourself honest. You can quickly see if complexity is spiraling out of control, and, most importantly, you get to see if your expectations of the design match the reality of the game.&lt;/p&gt;
&lt;p&gt;So I decided to write a &amp;ldquo;rulebook&amp;rdquo; for Lasting Legacy. I put rulebook in quotes because Lasting Legacy isn&amp;rsquo;t 100% a board game. There&amp;rsquo;s a light simulation component behind the scenes that is opaque to the player, but everything else can be treated like a board game. I figured it would be a good exercise for me, and maybe a good reference for early testers so they know what&amp;rsquo;s going on without a fancy tutorial.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Family tree" loading="lazy" src="https://gamesfromwithin.com/lasting-legacy-rulebook/images/family_tree.png"&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m happy with the final result. It&amp;rsquo;s about three pages of generously-spaced rules without any images, which beats a lot of board games out there.&lt;/p&gt;
&lt;p&gt;A word of caution: This is not trying to be a funny, engaging rulebook. It&amp;rsquo;s a dry, to the point, description of &lt;strong&gt;all&lt;/strong&gt; the rules in the game, arranged in the best way to understand all the concepts in a single read. It&amp;rsquo;s also not a &amp;ldquo;How to play&amp;rdquo; document. I think that could be another interesting exercise for down the line, where I just focus on the bare minimum to get a player playing.&lt;/p&gt;</description><content:encoded><![CDATA[<p>There&rsquo;s nothing like writing down all the rules for a game to keep yourself honest. You can quickly see if complexity is spiraling out of control, and, most importantly, you get to see if your expectations of the design match the reality of the game.</p>
<p>So I decided to write a &ldquo;rulebook&rdquo; for Lasting Legacy. I put rulebook in quotes because Lasting Legacy isn&rsquo;t 100% a board game. There&rsquo;s a light simulation component behind the scenes that is opaque to the player, but everything else can be treated like a board game. I figured it would be a good exercise for me, and maybe a good reference for early testers so they know what&rsquo;s going on without a fancy tutorial.</p>
<p><img alt="Family tree" loading="lazy" src="/lasting-legacy-rulebook/images/family_tree.png"></p>
<p>I&rsquo;m happy with the final result. It&rsquo;s about three pages of generously-spaced rules without any images, which beats a lot of board games out there.</p>
<p>A word of caution: This is not trying to be a funny, engaging rulebook. It&rsquo;s a dry, to the point, description of <strong>all</strong> the rules in the game, arranged in the best way to understand all the concepts in a single read. It&rsquo;s also not a &ldquo;How to play&rdquo; document. I think that could be another interesting exercise for down the line, where I just focus on the bare minimum to get a player playing.</p>
<h2 id="lasting-legacy-rulebook">Lasting Legacy Rulebook</h2>
<h3 id="1-overview">1. Overview</h3>
<h4 id="goal">Goal</h4>
<p>Gain the highest <img loading="lazy" src="/lasting-legacy-rulebook/images/LegacyIcon.png"><strong>Legacy</strong> possible.</p>
<p><img alt="Legacy" loading="lazy" src="/lasting-legacy-rulebook/images/legacy-1.png"></p>
<h4 id="setting">Setting</h4>
<p>Guide a European family around the 19th century through several generations. Socialize and find suitable marriage partners to grow you family, so you can earn <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong>, <img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong>, and ultimately, <img loading="lazy" src="/lasting-legacy-rulebook/images/LegacyIcon.png"><strong>Legacy</strong>.</p>
<p><img alt="Family" loading="lazy" src="/lasting-legacy-rulebook/images/family-1.png"></p>
<h3 id="2-concepts">2. Concepts</h3>
<p>Note: Any numbers shown here are just the defaults. There are always effects in the game that can modify those numbers up or down.</p>
<h4 id="family-members">Family members</h4>
<p>People in the family tree are called family members. Family members under 14 years old are considered children. They&rsquo;re represented with round frames and don&rsquo;t have any special abilities. Once they become adults they can choose between one or more occupations, depending on their education level. Adult family members will have children based on their age and fertility.</p>
<p><img alt="Family members" loading="lazy" src="/lasting-legacy-rulebook/images/family_members.png"></p>
<p>The head of the family, indicated with a special frame, defines which family members can be used at any given time. Only the head of the family, their spouse, and people under them (children and heirs) are enabled. Other family members are disabled and can&rsquo;t be used.</p>
<p><img alt="Head explained" loading="lazy" src="/lasting-legacy-rulebook/images/head_explained.png"></p>
<h4 id="occupations">Occupations</h4>
<p>Every adult member can have an occupation. The clothes and items people have represents their occupation. Occupations can be passive or active:</p>
<ul>
<li>Passive occupations have a permanent effect on the game. All the current effects are shown in the effect window.</li>
<li>Active occupations provide you with a potential action you can perform by clicking on the occupation button.</li>
</ul>
<p>Some occupations require a minimum education to appear as a choice. Occupations come in 4 rarities: common, uncommon, rare, and unique. Unique occupations will appear at most once per game. Occupations also could have one or more time periods during which they can appear: early, middle, or late in the game.</p>
<p><img alt="Occupation" loading="lazy" src="/lasting-legacy-rulebook/images/occupation-3.png"></p>
<h4 id="personality">Personality</h4>
<p>Every adult family member and friend has personality traits that consists of a series of likes and dislikes.</p>
<p><img alt="Likes" loading="lazy" src="/lasting-legacy-rulebook/images/likes-1.png"></p>
<h4 id="friends">Friends</h4>
<p>Your family friends are shown along the bottom of the screen, in oval frames. The smiley face shows their friendship level towards the family. Each year friendships drop a fixed amount. When the friendship level for a friend drops to 0, the face turns blue, and the following year that friend leaves.</p>
<p><img alt="Friends" loading="lazy" src="/lasting-legacy-rulebook/images/friends-1.png"></p>
<p>Friends can join your family through marriage. The heart in the friend&rsquo;s frame represents how much they love someone in your family. Love is determined by many factors, including personality match, sexual preference, age similarity, and friendship amount. If that love level is above a certain threshold, it means they&rsquo;re in love with someone and they&rsquo;re willing to marry that person (see section 3: Proposing and Accepting Proposals).</p>
<h4 id="gold">Gold</h4>
<p><img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong> is one of the primary resources in the game. It can be earned through actions and effects of people. Additionally, you may have a recurring <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong> income (shown in the green arrow), and a recurring <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong> payment (shown in the red arrow) that happen every year.</p>
<p><img alt="Gold" loading="lazy" src="/lasting-legacy-rulebook/images/gold-1.png"></p>
<p>You can spend more <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong> than you have, automatically taking a loan. Every year your <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong> is negative, your family pays 10% of that negative amount in interest payments. 200 <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong> is the debt limit. If you ever owe more that amount, the game ends in bankruptcy.</p>
<h4 id="prestige">Prestige</h4>
<p><img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> is the other primary resource of the game. It represents your social standing, and the more <img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> you have, the more friend slots you have available. You always have at least one friend slot. For every 10 <img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> you accumulate, you gain an additional friend slot up to a maximum of 10. Beyond that, you can accumulate more <img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> but you won&rsquo;t gain any more slots.</p>
<p><img alt="Friends" loading="lazy" src="/lasting-legacy-rulebook/images/friends.png"></p>
<p>If at any point you gain a friend but you have no empty slots available, the friend with the lowest friendship leaves and the new one takes its place.</p>
<p><img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> can also be spent to do actions that are usually associated with negative social implications. Friends can leave you if your <img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> falls and you lose a slot occupied by a friend.</p>
<p>Unlike <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong>, <img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> can&rsquo;t even go below zero. However, you can still use actions that would cause your <img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> to go to zero. If you do, the person who did the action will be disowned by the family and won&rsquo;t be part of the active family anymore.</p>
<h4 id="health">Health</h4>
<p>People normally are healthy. Sometimes they will become sick due to a variety of reasons. From there, each year they can either become healthy, stay sick, or turn terminally ill. Once someone is terminally ill, unless something is done about it, they will die the following year.</p>
<p><img alt="Health" loading="lazy" src="/lasting-legacy-rulebook/images/health-1.png"></p>
<h4 id="heir">Heir</h4>
<p>A yellow line in the tree indicates the next heir to the head of the family, which is the preferred child of the current head of the family. Whenever a family member does an action that&rsquo;s related to one of those traits, their parents will change their opinion of that person, either in a positive or negative way.</p>
<p><img alt="Heir" loading="lazy" src="/lasting-legacy-rulebook/images/heir.png"></p>
<p>You can see the current opinion of someone by selecting them and looking at the smiley faces over each of their children. The more filled in that face is, the higher the parent&rsquo;s opinion of that child is.</p>
<p>When the head of the family dies, the current heir becomes the new head of the family. The new head of the family also presents you with a new family goal due to their tastes and whims. This goal will let you gain <img loading="lazy" src="/lasting-legacy-rulebook/images/LegacyIcon.png"><strong>Legacy</strong> by doing certain things during their time as head of the family.</p>
<h4 id="heirlooms">Heirlooms</h4>
<p>Heirlooms will give you <img loading="lazy" src="/lasting-legacy-rulebook/images/LegacyIcon.png"><strong>Legacy</strong> based on different criteria. You start the game with one random family heirloom in your collection.</p>
<p><img alt="Heirloom" loading="lazy" src="/lasting-legacy-rulebook/images/heirloom-1.png"></p>
<h4 id="events">Events</h4>
<p>Every 30 to 70 years, an event will happen which will affect how things normally work. You will be notified 10 years before the event becomes active.</p>
<h4 id="countries">Countries</h4>
<p>The majority of the people you&rsquo;ll encounter during a playthrough come from the country you are playing in. You might encounter a few friends that come from neighboring countries. If you manage to add those friends to your family, that country will be unlocked and available for a future playthrough.</p>
<p>Countries add variety in the form of starting conditions, tweaked rules, and some unique occupations to those countries among other things.</p>
<h3 id="3-how-to-play">3. How to play</h3>
<p>Each turn, take one of the following actions. Each action will move the year forward one year.</p>
<h4 id="socialize">Socialize</h4>
<p>Gain one friend. The new friend&rsquo;s age and education level is influenced by the person who socialized.</p>
<p><img alt="Socialize" loading="lazy" src="/lasting-legacy-rulebook/images/socialize-1.png"></p>
<h4 id="visit-friend">Visit Friend</h4>
<p>Restore one friend&rsquo;s friendship level to the maximum.</p>
<p><img alt="Visit" loading="lazy" src="/lasting-legacy-rulebook/images/visit-2.png"></p>
<h4 id="propose-in-marriage">Propose in marriage</h4>
<p>Men in the family can propose in marriage to friends. When you click on the propose in marriage button, only the friends who are willing to accept will be highlighted. Click on one of them to marry them.</p>
<p><img alt="Propose" loading="lazy" src="/lasting-legacy-rulebook/images/propose.png"></p>
<p>Women will sometimes have a dowry made out of <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong> and/or <img loading="lazy" src="/lasting-legacy-rulebook/images/PrestigeIcon.png"><strong>Prestige</strong> associated with them. When you marry a woman with a dowry, those resources are added to the family resources. On the other hand, women from the family will sometimes have to offer a dowry in order to marry a man. In that case, those resources will be taken away from the family resources.</p>
<h4 id="accept-marriage-proposal">Accept marriage proposal</h4>
<p>People in the family can receive marriage proposals from friends (indicated by the hearts above their heads). These proposals are only available for one year. If you accept it, they&rsquo;ll be married right away. Otherwise, the friend will feel rejected and their friendship will drop more than usual.</p>
<p><img alt="Choose proposal" loading="lazy" src="/lasting-legacy-rulebook/images/choose_proposal.png"></p>
<h4 id="choose-an-occupation">Choose an occupation</h4>
<p>When a family member becomes an adult, they can choose an occupation (indicated by the question marks above their heads and their lack of occupation item and clothes).</p>
<p>If you don&rsquo;t choose an occupation, they will pick one of the available ones after 5 years.</p>
<p><img alt="Choose occupation" loading="lazy" src="/lasting-legacy-rulebook/images/choose_occupation.png"></p>
<h4 id="use-occupation-action">Use occupation action</h4>
<p>You can click on the occupation action of any active family member to perform that action. Occupation actions are unique to each occupation. Sick people can&rsquo;t do any occupation actions.</p>
<p><img alt="Action" loading="lazy" src="/lasting-legacy-rulebook/images/action-1.png"></p>
<p>You can also use the occupation action of a friend. That&rsquo;s like asking them for a huge favor, so they&rsquo;ll do the action, but then leave.</p>
<h4 id="restore-heirloom">Restore heirloom</h4>
<p>Whenever someone in your family over the age of 50 dies, they will leave a family heirloom in the attic. Each heirloom in the attic has a cost associated with restoring it. You need to restore an heirloom to add it to your heirloom collection so it generates <img loading="lazy" src="/lasting-legacy-rulebook/images/LegacyIcon.png"><strong>Legacy</strong>.</p>
<h4 id="pass">Pass</h4>
<p>When there&rsquo;s nothing else better to do, you can pass the turn and earn 5 <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong>.</p>
<p><img alt="Pass" loading="lazy" src="/lasting-legacy-rulebook/images/pass-1.png"></p>
<h3 id="4-end-of-game">4. End of game</h3>
<p>The game will end when one of these conditions is true:</p>
<ul>
<li>You run out of time and the war starts. The year display will always tell you how many years you have remaining.</li>
<li>You reach your <img loading="lazy" src="/lasting-legacy-rulebook/images/GoldIcon.png"><strong>Gold</strong> debt limit.</li>
<li>The head of the family dies without an heir.</li>
</ul>
<p>The amount of <img loading="lazy" src="/lasting-legacy-rulebook/images/LegacyIcon.png"><strong>Legacy</strong> you have at the end of the game is your final score.</p>]]></content:encoded></item><item><title>Isomorphism As a Game Design Tool</title><link>https://gamesfromwithin.com/isomorphism-as-a-game-design-tool/</link><pubDate>Thu, 13 Jul 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/isomorphism-as-a-game-design-tool/</guid><description>&lt;p&gt;In the early stages of developing a game, once I have the idea and &lt;a href="https://gamesfromwithin.com/the-feelings-of-lasting-legacy/"&gt;the feelings&lt;/a&gt; of the game down solid, my approach is to throw everything I can think of at the game and see what sticks.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bubblegum" loading="lazy" src="https://gamesfromwithin.com/isomorphism-as-a-game-design-tool/images/bubblegum.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;My early-in-development creative process.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t usually bother fleshing individual ideas out in design documents because it usually takes just as long for me to implement those things and see them in the game instead. And who would want to read about an idea when you can see how it works in the game directly?&lt;/p&gt;
&lt;p&gt;During this phase I need to generate lots of different ideas because only some of them are going to stick. The more varied the better, so I like to approach my idea generation from different angles. The two most common approaches are starting from the theme, and starting from the mechanics&lt;/p&gt;
&lt;p&gt;For example, in &lt;a href="http://lastinglegacygame.com/"&gt;Lasting Legacy&lt;/a&gt;, we quickly came up with occupations like Family Doctor or Ball Organizer from the theme, and figured out what useful things they could do in the game (heal people, and attract new friends respectively).&lt;/p&gt;
&lt;p&gt;We also came up with several occupations starting from a mechanics point of view. For example, we knew we wanted someone to increase the income of other people, so we came up with the Savvy Businessman occupation.&lt;/p&gt;
&lt;p&gt;This time around I also used a third approach to generate ideas: Isomorphism.&lt;/p&gt;</description><content:encoded><![CDATA[<p>In the early stages of developing a game, once I have the idea and <a href="/the-feelings-of-lasting-legacy/">the feelings</a> of the game down solid, my approach is to throw everything I can think of at the game and see what sticks.</p>
<p><img alt="Bubblegum" loading="lazy" src="/isomorphism-as-a-game-design-tool/images/bubblegum.png"></p>
<p><em>My early-in-development creative process.</em></p>
<p>I don&rsquo;t usually bother fleshing individual ideas out in design documents because it usually takes just as long for me to implement those things and see them in the game instead. And who would want to read about an idea when you can see how it works in the game directly?</p>
<p>During this phase I need to generate lots of different ideas because only some of them are going to stick. The more varied the better, so I like to approach my idea generation from different angles. The two most common approaches are starting from the theme, and starting from the mechanics</p>
<p>For example, in <a href="http://lastinglegacygame.com/">Lasting Legacy</a>, we quickly came up with occupations like Family Doctor or Ball Organizer from the theme, and figured out what useful things they could do in the game (heal people, and attract new friends respectively).</p>
<p>We also came up with several occupations starting from a mechanics point of view. For example, we knew we wanted someone to increase the income of other people, so we came up with the Savvy Businessman occupation.</p>
<p>This time around I also used a third approach to generate ideas: Isomorphism.</p>
<p><a href="https://en.wikipedia.org/wiki/Isomorphism">Isomorphism</a> is a word that comes from the greek composed of &ldquo;isos&rdquo; (same) and &ldquo;morphe&rdquo; (shape) and it means that two concepts are equal. This concept is very useful in mathematics. Imagine you have a very tough problem that you don&rsquo;t know how to solve. Instead of having to go through the very difficult task of trying to solve that problem, you could instead show that it maps exactly (is isomorphic) to another problem you have already solved.</p>
<p>How does that help us with game design? If we can determine that our game, or at least parts of our game, map to parts of other games, we can look to see if the mechanics of those games can apply to ours.</p>
<p>I didn&rsquo;t set out to design the Lasting Legacy this way, but it turns out there is a close correspondence between a lot of concepts in Lasting Legacy and Magic: The Gathering. That&rsquo;s really good news because not only is Magic a great game, but it has been in active development for 25 years and it has explored a lot of different mechanics. So being able to draw parallels and tap into those ideas is a great resource and a very different angle of attack to a tough problem.</p>
<p>The mapping between Magic and Lasting Legacy goes something like this:</p>
<ul>
<li>Hand of cards = Friends</li>
<li>Permanents = Active family tree</li>
<li>Graveyard = Dead and inactive family members</li>
<li>Library = Upcoming friends</li>
</ul>
<p><img alt="Mapping" loading="lazy" src="/isomorphism-as-a-game-design-tool/images/Mapping.jpg"></p>
<p>I want to highlight that we&rsquo;re talking about looking at concepts from another game, mapping them to our game, and then applying them, not using them straight. Those concepts couldn&rsquo;t be used as it is, or wouldn&rsquo;t make any sense, without the mapping from game to game. For example, in Magic: The Gathering, the player has a hand of cards but Lasting Legacy doesn&rsquo;t, so the idea of discarding a card to achieve something doesn&rsquo;t apply. Once we establish the mapping between the hand of cards and available friends, we could use the idea of dismissing a friend for similar purposes.</p>
<p>These are are some of the mechanics that we were able to map and apply to Lasting Legacy.</p>
<p><strong>Bringing cards back from graveyard.</strong> Reanimating creatures has been a staple of black decks in Magic from the beginning. Thematically we could revive a dead family member, but that doesn&rsquo;t fit very well with the more realistic approach of Lasting Legacy. Instead, we created a Genealogy Researcher, who can become the same occupation as a dead family ancestor.</p>
<p><img alt="Animatedead" loading="lazy" src="/isomorphism-as-a-game-design-tool/images/animatedead.jpg"></p>
<p><strong>Looking at cards from the top of the deck.</strong> Deck searching and manipulation is a very common blue Mechanic in Magic, but Lasting Legacy doesn&rsquo;t really have the concept of a deck of cards, so we can&rsquo;t do a lot of that. We can, however, look at the &ldquo;top&rdquo; X friends that would come up and pick one, which is exactly what the Dashing Socialite does. It&rsquo;s a very useful occupation because it gives you a degree of filtering of your friends and reduces <a href="/luck-in-games/">randomness</a>.</p>
<p><img alt="Impulse" loading="lazy" src="/isomorphism-as-a-game-design-tool/images/impulse.jpg"></p>
<p><strong>Enter the battlefield effects.</strong> In Magic, many creatures have an effect that is triggered whenever they &ldquo;enter the battlefield&rdquo; (meaning, enter in play). This is a very useful tool, and we adopted it in Lasting Legacy. It gives you another reason to bring someone into the family, even if it&rsquo;s not for their occupation or even to extend the main family branch. For example, the Charismatic Musician increases your prestige whenever he enters the family.</p>
<p><img alt="Auramancer" loading="lazy" src="/isomorphism-as-a-game-design-tool/images/auramancer.jpg"></p>
<p><strong>Blinking.</strong> Several cards in Magic allow players to &ldquo;blink&rdquo; permanents. That means those permanents go away and immediately enter into play again. That&rsquo;s very useful to protect those permanents or re-triggering their enter the battlefield effects. We haven&rsquo;t added this to Lasting Legacy yet, but it&rsquo;s definitely towards the top of the lit of possibilities, especially if we end up with many other occupations that have effects when they join the family. This mechanic might make for an interesting subtheme for an expansion down the line.</p>
<p><img alt="Blink" loading="lazy" src="/isomorphism-as-a-game-design-tool/images/blink.jpg"></p>
<p> </p>
<p>There are many more mechanics that could be mapped to Lasting Legacy, but these are some of the most interesting ones we&rsquo;ve done so far. If we end up making expansions, I&rsquo;m sure we&rsquo;ll revisit this topic as a source of new ideas and mechanics.</p>]]></content:encoded></item><item><title>Lasting Legacy Dev Update #3: UI Improvements</title><link>https://gamesfromwithin.com/lasting-legacy-dev-update-3-ui-improvements/</link><pubDate>Tue, 13 Jun 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/lasting-legacy-dev-update-3-ui-improvements/</guid><description>&lt;p&gt;Here&amp;rsquo;s a new video showing the UI improvements and how the characters feel more alive.&lt;/p&gt;
&lt;iframe width="700" height="394" src="https://www.youtube.com/embed/8Jvn3Ln0TCM" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Apologies for the less than ideal sound and video quality. We&amp;rsquo;re working on fixing that for next time.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Here&rsquo;s a new video showing the UI improvements and how the characters feel more alive.</p>
<iframe width="700" height="394" src="https://www.youtube.com/embed/8Jvn3Ln0TCM" frameborder="0" allowfullscreen></iframe>
<p>Apologies for the less than ideal sound and video quality. We&rsquo;re working on fixing that for next time.</p>
]]></content:encoded></item><item><title>Using SQLite to Organize Design Data</title><link>https://gamesfromwithin.com/using-sqlite-to-organize-design-data/</link><pubDate>Tue, 16 May 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/using-sqlite-to-organize-design-data/</guid><description>&lt;p&gt;I haven&amp;rsquo;t written purely about tech in a long time, but this is a particularly interesting intersection of tech and game design, so I thought I would share it with everybody. Be warned though: This is one of those posts that&amp;rsquo;s just about the thought process I went through for something and the solution I reached. I&amp;rsquo;m most definitely &lt;strong&gt;not&lt;/strong&gt; advocating this solution for everybody. Think about it and pick the solution that works for you the best.&lt;/p&gt;
&lt;p&gt;By now you&amp;rsquo;ve probably heard of &lt;a href="http://lastinglegacygame.com/"&gt;Lasting Legacy&lt;/a&gt;: you&amp;rsquo;re managing a family around the 19th century through several generations, socializing, choosing good marrying prospects, and helping family members pick an occupation. Ah, occupations&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Tutor" loading="lazy" src="https://gamesfromwithin.com/using-sqlite-to-organize-design-data/images/tutor.png"&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p>I haven&rsquo;t written purely about tech in a long time, but this is a particularly interesting intersection of tech and game design, so I thought I would share it with everybody. Be warned though: This is one of those posts that&rsquo;s just about the thought process I went through for something and the solution I reached. I&rsquo;m most definitely <strong>not</strong> advocating this solution for everybody. Think about it and pick the solution that works for you the best.</p>
<p>By now you&rsquo;ve probably heard of <a href="http://lastinglegacygame.com/">Lasting Legacy</a>: you&rsquo;re managing a family around the 19th century through several generations, socializing, choosing good marrying prospects, and helping family members pick an occupation. Ah, occupations&hellip;</p>
<p><img alt="Tutor" loading="lazy" src="/using-sqlite-to-organize-design-data/images/tutor.png"></p>
<h3 id="occupations">Occupations</h3>
<p>Occupations and the life and blood of the game. It&rsquo;s what gives the player lots of new actions and effects that can be combined in lots of different ways to achieve lots of powerful effects. The only downside of occupations is that&hellip; there are a lot of them! Right now we have about 50 and that&rsquo;s just some really basic stuff. I expect the game will ship with about 100 occupations, and possibly more once we add country-specific ones.</p>
<p>50 doesn&rsquo;t sound too bad you say. Sure, but each occupation has a lot of data that goes along with it: a name, whether it has an action or not, text for the action,text for the log, costs, whether it&rsquo;s inherited&hellip; Hang on, let me tell you <strong>exactly</strong> what an occupation has:</p>
<pre tabindex="0"><code>struct OccupationInfo
{
     Occupation::Enum occupation;
     Rarity::Enum rarity;
     const char* maleName;
     const char* femaleName;
     const char* description;
     const char* logEntry;
     IconSpriteId::Enum spriteId;
     uint32_t periodFlags;
     int goldIncome;
     bool incomeMultiplied;
     int prestigeIncome;
     int legacyIncome;
     bool action;
     int goldCost;
     int prestigeCost;
     bool educationRequired;
     int targetCount;
     bool pickable;
     bool destructive;
     bool inherited;
     Occupation::Enum childrenOccupation;
     int personLike;
     uint32_t tags;
     AccessoryType::Enum maleAccessories[MaxAccessories];
     AccessoryType::Enum femaleAccessories[MaxAccessories];
     int maleAccessoriesCount;
     int femaleAccessoriesCount;
};
</code></pre><p>How do we set all that data for 50 different occupations? Back when I was working for big game companies I&rsquo;m sure that someone&rsquo;s job would have been to create a GUI tool to let designers enter those values. Then someone else would create a fancy XML format that could be exported from the tool. Then, if we were lucky, someone else would take that XML and crunch it during the asset conversion process into something binary that could be read directly into memory. Probably someone else would work on tech that would let you hot load new data while the game was running. Sweet!</p>
<p>Except that now I&rsquo;m a lowly indie developer and I don&rsquo;t have time for any of that stuff that doesn&rsquo;t actually make the game better. Fortunately, I also don&rsquo;t have a team of 50 designers to deal with, so my solution is this:</p>
<pre tabindex="0"><code>{
	OccupationInfo&amp; info = OccupationInfos[Occupation::Banker];
	info = OccupationInfo(Occupation::Banker, &#34;Town Banker&#34;, IconSpriteId::Banker);
	strcpy(info.description, &#34;Gain 100 gold. Income decreases by 1.&#34;);
	info.logEntry = &#34;%s %s gained %d gold.&#34;;
	info.tags = OccupationTags::Gold;
}
{
	OccupationInfo&amp; info = OccupationInfos[Occupation::Poisoner];
	info = OccupationInfo(Occupation::Poisoner, &#34;Cunning Poisoner&#34;, IconSpriteId::Poisoner);
	strcpy(info.description, &#34;Kill another family member.&#34;);
	info.logEntry = &#34;%s %s poisoned %s %s.&#34;;
	info.cost = 500;
	info.tags = OccupationTags::Danger;
	info.rarity = Rarity::Uncommon;
}
{
	OccupationInfo&amp; info = OccupationInfos[Occupation::Tutor];
	info = OccupationInfo(Occupation::Tutor, &#34;Private Tutor&#34;, IconSpriteId::Tutor);
	strcpy(info.description, &#34;Another adult family member leaves their occupation and becomes educated.&#34;);
	info.logEntry = &#34;%s %s sent %s %s to school.&#34;;
	info.educationRequired = true;
	info.tags = OccupationTags::Social;
}
</code></pre><p>&ldquo;Oh the horror! Hardcoded data!&rdquo; shriek all new CS students as they recoil from the screen.</p>
<p>But it really isn&rsquo;t that bad. Actually, it&rsquo;s pretty great: I don&rsquo;t have any exporting/importing to do, I don&rsquo;t have to load anything at runtime, and the compiler does a lot of checking for me. True, I can&rsquo;t change it on the fly, but I don&rsquo;t really need to when rebuilding the whole game takes about a second.</p>
<p>Unfortunately the problem is that we have 50 of those initialization blocks. Hopefully a lot more by the time we ship. They&rsquo;re perfectly fine to work on each of them in isolation, but I&rsquo;m not able to get a big picture. Have I created a similar one to this new one I&rsquo;m thinking about? How much do other similar occupations cost? Can I get all the Social occupations together so I can compare them? How many rare occupations do we have in the late period? I can&rsquo;t answer those questions very well by looking at that code. I needed something else.</p>
<h3 id="global-view">Global View</h3>
<p>Using some kind of text file wouldn&rsquo;t help any. It would be a matter of changing that into an ini or an XML file, which would be much more painful without any of the benefits.</p>
<p>I started setting up a Google Spreadsheet, which is something we did for the specialists in <a href="http://subterfuge-game.com/">Subterfuge</a>. Spreadsheets have some nice capabilities like doing data validation on cells (for example, to enter enums), or letting you sort records based on some criteria. In Subterfuge the spreadsheet method worked reasonably well because we didn&rsquo;t have as many specialists and each of them had less data, so the spreadsheet was pretty manageable. Here we just had too much data for each occupation and the spreadsheet was getting unwieldy.</p>
<p>Miguel mentioned SQLite, but I wasn&rsquo;t too keen on linking with some extra library and loading that data at runtime. It also sounded like total overkill to have a full relational database for what amounts to a single table. Then I realized how wrong I totally was.</p>
<p>People have written GUI tools for SQLite that let you create, edit, and browse databases very easily. For example, we&rsquo;re using <a href="http://sqlitebrowser.org/">DB Browser for SQLite</a> and I think there are better ones out there (although maybe not free ones). Our main table looks something like this:</p>
<p><img alt="Table" loading="lazy" src="/using-sqlite-to-organize-design-data/images/table.png"></p>
<p>And the data itself like this:</p>
<p><img alt="Data" loading="lazy" src="/using-sqlite-to-organize-design-data/images/data.png"></p>
<p>It looks like a spreadsheet until you realize that you can very easily search any field and you can even create &ldquo;views&rdquo; with more complex queries ahead of time. So now I can quickly see how many rare occupations we have in the late period with a single click. Very sweet! It definitely gives me that global view I was hoping for.</p>
<p>How about loading this data from the database at runtime? I doubt it would be a big deal, but it&rsquo;s still something I&rsquo;m not crazy about. Fortunately, it&rsquo;s super easy to extract the data from SQLite. We have this in our make file:</p>
<pre tabindex="0"><code>@sqlite3 -header -csv $(DB_SRC) &#39;SELECT * FROM Occupations&#39; &gt; $(DB_CSV)
</code></pre><p>And that spits out a nice comma-separated file with all the data. Still, loading csv files at runtime isn&rsquo;t much of an improvement, so we do a bit more processing. Initially I started converting the csv file into an ini file (since we already have an ini-reader library), but then I realized there was no point in doing that. Unlike Subterfuge, I&rsquo;ll never want to have different versions of the game data around and load them based on different rules versions. We just want one true version. What&rsquo;s the easiest way to put that data in the game? C code!</p>
<p>So with a simple Python script, I convert that csv file into a C file that looks an awful lot like the one we started with, except that this time it&rsquo;s completely derived from the contents of the database. One of the great benefits of this is that we can let the compiler do a lot of the checking instead of having to do it in the script or (gasp) at runtime. For example, some occupations force their children to have a particular occupation (King -&gt; Prince). I don&rsquo;t even have any code that checks that the occupation you enter there is valid. We just generate code like this:</p>
<pre tabindex="0"><code>info.childrenOccupation = Occupation::XXXXX;
</code></pre><p>If XXXXX doesn&rsquo;t happen to be a valid Occupation enum, you get a build error until you fix it. And again, since the whole turnaround time between editing the database and building the game can be a second or two, it&rsquo;s really no big deal at all.</p>
<h3 id="constants">Constants</h3>
<p>I left one small detail: Constants. Look at some of the first code I put up early on:</p>
<pre tabindex="0"><code>strcpy(info.description, &#34;Gain 100 gold. Income decreases by 1.&#34;);
</code></pre><p>What&rsquo;s wrong with that? Yup, you got it. Somewhere else in the code, I have some constants like this:</p>
<pre tabindex="0"><code>const int BankerReward = 100;
const int BankerIncomePenalty = 1;
</code></pre><p>Now every time I change how much money the Banker gives, I need to change the string and the constant (let&rsquo;s not even talk about localized strings yet).</p>
<p>So instead now I use global string replacement while we&rsquo;re generating the C code. The string on the database is this:</p>
<pre tabindex="0"><code>Gain [[BankerReward]] gold. Income decreases by [[BankerIncomePenalty]].
</code></pre><p>Whenever we load the csv file, we look for any substrings with the pattern [[&hellip;]] and we try to match them from a header file with constants that we&rsquo;ve loaded. If we find them, we replace them with their values, and if we don&rsquo;t, we spit out an error and stop because clearly someone wanted to have a string replaced there and probably mistyped it.</p>
<p>Does all of that sound complicated? Not really. When I said earlier that the Python script was simple, I wasn&rsquo;t kidding. This is the bulk of it, including the constant replacement (just a couple helper functions are missing):</p>
<pre tabindex="0"><code>def main():
	dir = os.path.dirname(os.path.realpath(__file__))
	baseDir = dir + &#34;/../LastingLegacy/AssetsRaw/&#34;
	reader = csv.DictReader(open(baseDir + &#39;db/occupations.csv&#39;, &#39;rU&#39;))

	sourceCodeDir = baseDir + &#34;../src/&#34;
	globalVariables = readGlobalVars(sourceCodeDir)
	pattern = re.compile(r&#39;\b(&#39; + &#39;|&#39;.join(globalVariables.keys()) + r&#39;)\b&#39;)

	Rarities = {&#39;C&#39;: &#39;Rarity::Common&#39; , &#39;U&#39;: &#39;Rarity::Uncommon&#39;, &#39;R&#39;: &#39;Rarity::Rare&#39;, &#39;Q&#39;: &#39;Rarity::Unique&#39;}
	Periods = {&#39;E&#39;: &#39;Period::Early&#39; , &#39;M&#39;: &#39;Period::Middle&#39;, &#39;L&#39;: &#39;Period::Late&#39;}

	defFile = open(sourceCodeDir + &#34;Occupations.inc&#34;, &#39;w&#39;)
	for entry in reader:
		type = entry[&#39;id&#39;]
		defFile.write(&#39;{\nOccupationInfo&amp; info = OccupationInfos[Occupation::&#39; + type + &#39;];\n&#39;)
		defFile.write(&#39;info.occupation = Occupation::&#39; + type + &#39;;\n&#39;)
		defFile.write(&#39;info.spriteId = IconSpriteId::&#39; + type + &#39;;\n&#39;)
		defFile.write(&#39;info.maleName = &#34;&#39; + entry[&#39;maleName&#39;] + &#39;&#34;;\n&#39;)
		if entry[&#39;femaleName&#39;]:
			defFile.write(&#39;info.femaleName = &#34;&#39; + entry[&#39;femaleName&#39;] + &#39;&#34;;\n&#39;)
		else:
			defFile.write(&#39;info.femaleName = info.maleName;\n&#39;)
		
		description = multipleReplace(entry[&#39;description&#39;], globalVariables)
		defFile.write(&#39;info.description = &#34;&#39; + description +&#39;&#34;;\n&#39;)
		
		defFile.write(&#39;info.logEntry = &#34;&#39; + entry[&#39;logEntry&#39;] + &#39;&#34;;\n&#39;)
		WriteOptionalBool(defFile, entry, &#39;educationRequired&#39;, type)
		WriteOptionalKey(defFile, entry, &#39;goldCost&#39;, type)
		WriteOptionalKey(defFile, entry, &#39;prestigeCost&#39;, type)
		WriteOptionalKey(defFile, entry, &#39;goldIncome&#39;, type)
		WriteOptionalKey(defFile, entry, &#39;prestigeIncome&#39;, type)
		WriteOptionalKey(defFile, entry, &#39;legacyIncome&#39;, type)
		WriteOptionalBool(defFile, entry, &#39;incomeMultiplied&#39;, type)
		WriteOptionalBool(defFile, entry, &#39;action&#39;, type)
		WriteEnum(defFile, entry, &#39;rarity&#39;, Rarities, type)
		WritePeriodFlags(defFile, entry, &#39;periods&#39;, Periods, type)
		WriteOptionalKey(defFile, entry, &#39;targetCount&#39;, type)
		WriteOptionalBool(defFile, entry, &#39;destructive&#39;, type)
		WriteOptionalBool(defFile, entry, &#39;pickable&#39;, type)
		WriteOptionalBool(defFile, entry, &#39;inherited&#39;, type)
		if entry[&#39;childrenOccupation&#39;]:
			defFile.write(&#34;info.childrenOccupation = Occupation::&#34; + entry[&#39;childrenOccupation&#39;] + &#34;;\n&#34;)
		WriteOptionalKey(defFile, entry, &#39;personLike&#39;, type)
		WriteOptionalTags(defFile, entry, &#39;tags&#39;, type)
		WriteOptionalAccessories(defFile, entry, &#39;maleAccessories&#39;, type)
		WriteOptionalAccessories(defFile, entry, &#39;femaleAccessories&#39;, type)

		defFile.write(&#39;}\n&#39;)

	defFile.close()	
</code></pre><p><a href="/wp-content/uploads/2017/05/generateoccupations.py_.zip">Here&rsquo;s the full script</a> in case anyone is interested in the details.</p>
<p>Boom! Done!</p>
<p>Ship it.</p>]]></content:encoded></item><item><title>Lasting Legacy Dev Update #2: Head of the Family and Legacy</title><link>https://gamesfromwithin.com/lasting-legacy-dev-update-2-head-of-the-family-and-legacy/</link><pubDate>Tue, 18 Apr 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/lasting-legacy-dev-update-2-head-of-the-family-and-legacy/</guid><description>&lt;p&gt;This week&amp;rsquo;s video covers the concept of &lt;em&gt;head of the family&lt;/em&gt; and what exactly is &lt;em&gt;legacy&lt;/em&gt; and how to obtain it. We&amp;rsquo;re also continuing the same family as last time. Will Fanni become the heir, or will childless Peter bring the lineage to an end?&lt;/p&gt;
&lt;iframe width="700" height="394" src="https://www.youtube.com/embed/6sWt5WMrmG0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;I managed to keep things shorter than last time, so this one is only 12 minutes. For those of you who prefer text updates, don&amp;rsquo;t worry, we&amp;rsquo;ll have one of those next week.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This week&rsquo;s video covers the concept of <em>head of the family</em> and what exactly is <em>legacy</em> and how to obtain it. We&rsquo;re also continuing the same family as last time. Will Fanni become the heir, or will childless Peter bring the lineage to an end?</p>
<iframe width="700" height="394" src="https://www.youtube.com/embed/6sWt5WMrmG0" frameborder="0" allowfullscreen></iframe>
<p>I managed to keep things shorter than last time, so this one is only 12 minutes. For those of you who prefer text updates, don&rsquo;t worry, we&rsquo;ll have one of those next week.</p>
]]></content:encoded></item><item><title>Lasting Legacy Dev Update #1</title><link>https://gamesfromwithin.com/lasting-legacy-dev-update-1/</link><pubDate>Wed, 12 Apr 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/lasting-legacy-dev-update-1/</guid><description>&lt;p&gt;Here&amp;rsquo;s the first video dev update for Lasting Legacy. We go over the basic gameplay.&lt;/p&gt;
&lt;iframe width="700" height="394" src="https://www.youtube.com/embed/IBp5LCF4nt4" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;It&amp;rsquo;s a whopping 19 minutes long, so I may have overdone it a bit! I&amp;rsquo;ll try to keep it shorter for future updates.&lt;/p&gt;
&lt;p&gt;Since this is the first time we&amp;rsquo;re doing this, any feedback is appreciated. Would you like to see more of these in the future? What should the focus be? Any technical issues I should improve?&lt;/p&gt;</description><content:encoded><![CDATA[<p>Here&rsquo;s the first video dev update for Lasting Legacy. We go over the basic gameplay.</p>
<iframe width="700" height="394" src="https://www.youtube.com/embed/IBp5LCF4nt4" frameborder="0" allowfullscreen></iframe>
<p>It&rsquo;s a whopping 19 minutes long, so I may have overdone it a bit! I&rsquo;ll try to keep it shorter for future updates.</p>
<p>Since this is the first time we&rsquo;re doing this, any feedback is appreciated. Would you like to see more of these in the future? What should the focus be? Any technical issues I should improve?</p>
]]></content:encoded></item><item><title>What Kind of Game is Lasting Legacy?</title><link>https://gamesfromwithin.com/what-kind-of-game-is-lasting-legacy/</link><pubDate>Thu, 23 Mar 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/what-kind-of-game-is-lasting-legacy/</guid><description>&lt;p&gt;You&amp;rsquo;ve read the &lt;a href="https://gamesfromwithin.com/announcing-lasting-legacy/"&gt;&lt;em&gt;Lasting Legacy&lt;/em&gt; announcement&lt;/a&gt;, seen some of the art, got an idea about the setting for the game, and you even know about &lt;a href="https://gamesfromwithin.com/the-feelings-of-lasting-legacy/"&gt;the feelings we want players to experience&lt;/a&gt;. But what kind of game is &lt;em&gt;Lasting Legacy&lt;/em&gt; exactly?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Lasting Legacy&lt;/em&gt; is a fairly unique game, so it doesn&amp;rsquo;t quite fit in any predetermined genre. The closest category would be single-player, turn-based simulation, although the simulation part in Lasting Legacy is very light (unlike something like &lt;em&gt;Sim City&lt;/em&gt; or &lt;em&gt;The Sims&lt;/em&gt;), and in that respect it&amp;rsquo;s more like a board game. So it&amp;rsquo;s more accurate to say that &lt;em&gt;Lasting Legacy&lt;/em&gt; is a blend of simulation games and board games.&lt;/p&gt;
&lt;p&gt;Intrigued? You&amp;rsquo;re in the right place. Read on.&lt;/p&gt;</description><content:encoded><![CDATA[<p>You&rsquo;ve read the <a href="/announcing-lasting-legacy/"><em>Lasting Legacy</em> announcement</a>, seen some of the art, got an idea about the setting for the game, and you even know about <a href="/the-feelings-of-lasting-legacy/">the feelings we want players to experience</a>. But what kind of game is <em>Lasting Legacy</em> exactly?</p>
<p><em>Lasting Legacy</em> is a fairly unique game, so it doesn&rsquo;t quite fit in any predetermined genre. The closest category would be single-player, turn-based simulation, although the simulation part in Lasting Legacy is very light (unlike something like <em>Sim City</em> or <em>The Sims</em>), and in that respect it&rsquo;s more like a board game. So it&rsquo;s more accurate to say that <em>Lasting Legacy</em> is a blend of simulation games and board games.</p>
<p>Intrigued? You&rsquo;re in the right place. Read on.</p>
<h3 id="what-do-you-do-in-lasting-legacy">What Do You Do in <em>Lasting Legacy</em>?</h3>
<p>The description of the game says that you manage a family for about 200 years and build a lasting legacy. Every action you perform moves the time forward one year, and actions are performed directly on individual people.</p>
<p>There are some common, general actions available:</p>
<ul>
<li>Socialize, which helps you find more friends.</li>
<li>Visit a friend, to increase that friendship.</li>
<li>Propose in marriage or accept a marriage proposal.</li>
<li>Pick an occupation for someone who recently became an adult.</li>
</ul>
<p>Those actions allow you to tend to the family and continue growing the family tree. The meat of the game comes from each person having an occupation, and that occupation provides either a special action, or an ongoing effect.</p>
<p>For example, having a Doctor in the family gives you an action to heal a sick person.</p>
<p><img alt="Doctor" loading="lazy" src="/what-kind-of-game-is-lasting-legacy/images/Doctor-1.png"></p>
<p>On the other hand, a Moneylender in the family gives you the ongoing effect of not having maximum debt anymore (time to run those credit cards!).</p>
<p><img alt="Moneylender" loading="lazy" src="/what-kind-of-game-is-lasting-legacy/images/moneylender-1.png"></p>
<p>The ultimate goal of the game is to achieve the highest <em>legacy</em> possible each time you play. You gain <em>legacy</em> in one of two ways:</p>
<ol>
<li>By acquiring heirlooms from deceased family members that give you <em>legacy</em> for different reasons (for example, number of people in your family with a particular occupation).</li>
<li>By meeting the whims of some important family members. For example, someone in the family might have a thing for big weddings, so you&rsquo;ll gain <em>legacy</em> for every big wedding you have while they&rsquo;re around.</li>
</ol>
<p>Sounds simple enough, but in order to do those things, you&rsquo;ll have to balance the maintenance of your family (social needs, marriages, children, sickness), acquiring gold and prestige, and, to top it all, dealing with the rising military tension in your country. War is inevitable, but you may be able to deflate military tension and push off the start of the war (which brings the end of the game).</p>
<h3 id="game-mechanics">Game Mechanics</h3>
<p>Stepping back and looking at the game from a high-level point of view, there are two major mechanics that appear:</p>
<ol>
<li><strong>Tableau building.</strong> The family tree is your tableau, because it represents the powers and actions that are available to you. A lot of card games have a similar mechanic (<em><a href="https://www.boardgamegeek.com/boardgame/28143/race-galaxy">Race for the Galaxy</a></em> is one of the best and most famous ones), but in <em>Lasting Legacy</em> the tableau has a twist: It&rsquo;s dynamic. People can only make a contribution while they&rsquo;re alive, so your tableau will change as decades go by, and you&rsquo;ll have to adapt your strategy and plan ahead to take full advantage of it.</li>
<li><strong>Hand management.</strong> Your friends are a very similar resource to a hand of cards in most games. You may be able to bring them into play as part of your family, or maybe you can do their action once and discard them. This hand of cards is also very dynamic and it changes with the friendship levels and your family prestige.</li>
</ol>
<p>Those two mechanics are very common in card and board games. That&rsquo;s not surprising since <em>Lasting Legacy</em> has strong board game influences. However, <em>Lasting Legacy</em> is not a board game, and it would be very difficult to make a straight translation into a physical game. There&rsquo;s a light simulation under the hood that makes people do things by themselves: have children, propose in marriage, pick occupations (unless you pick them for them), etc. Hopefully it&rsquo;s a good blend borrowing the best of both the digital and the physical worlds.</p>
<p> </p>
<p><strong>Want to find out more about <em>Lasting Legacy</em> as we announce it? Make sure you sign up for our <a href="http://lastinglegacygame.com">mailing list</a> and/or join the <a href="https://www.facebook.com/lastinglegacygame/">Facebook page</a>.</strong></p>]]></content:encoded></item><item><title>The Feelings of Lasting Legacy</title><link>https://gamesfromwithin.com/the-feelings-of-lasting-legacy/</link><pubDate>Fri, 27 Jan 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-feelings-of-lasting-legacy/</guid><description>&lt;p&gt;When I start working on a game, one of the first things I decide is how will the game make the player feel. Different designers have different ways of driving and focusing the design of their games: some will use a short elevator pitch, some will use key pieces of art, some will let the mechanics dictate the rest. I prefer to use the way I want players to feel to anchor the design, and I flesh out the rest of the game around it.&lt;/p&gt;
&lt;p&gt;Once you have defined that feel, you can run every single design decision by it. Every game feature should support those feelings in some way, if not, they&amp;rsquo;re a good candidate to cut. And if some contradict them directly, you can veto them right away and not go down that path any further.&lt;/p&gt;</description><content:encoded><![CDATA[<p>When I start working on a game, one of the first things I decide is how will the game make the player feel. Different designers have different ways of driving and focusing the design of their games: some will use a short elevator pitch, some will use key pieces of art, some will let the mechanics dictate the rest. I prefer to use the way I want players to feel to anchor the design, and I flesh out the rest of the game around it.</p>
<p>Once you have defined that feel, you can run every single design decision by it. Every game feature should support those feelings in some way, if not, they&rsquo;re a good candidate to cut. And if some contradict them directly, you can veto them right away and not go down that path any further.</p>
<p>For Lasting Legacy, we have two main feelings we want to evoke in players:</p>
<p><img alt="960" loading="lazy" src="/the-feelings-of-lasting-legacy/images/960-1.jpg"></p>
<h3 id="1-experiencing-the-drama-of-complex-family-stories">1. Experiencing the drama of complex family stories.</h3>
<p>A playthrough of Lasting Legacy lasts about 20-30 minutes and the game is intended to be played over many times (more details on this for a later post). Each of those playthroughs is completely different, and the player experiences an entirely different story of a family through the generations. The combination of the player&rsquo;s actions and the behaviors of the game characters should create funny, memorable, and sometimes bizarre situations.</p>
<p>For example, this is a recount of something that happened in just one of the generations of one of my recent plays of the game:</p>
<blockquote>
<p>The Novak family was pennyless and without any income. Mr. and Ms. Novak spent all their effort into trying to gain prestige and money to secure a place in society. They had two children, Jakab and Andrea. Jakab, unfortunately, ended up being the Town Gossipmonger and never held any real jobs. Andrea managed to become a Baker, but the income was meager.</p>
<p>Things started looking up when Andrea, caught the eye of Mr. Kende, a handsome, rich friend of the family. They were quickly married and the family felt the relief as they had access to Mr. Kende&rsquo;s fortune. The parents approved very strongly of this union and made sure that Andrea would become the heir of the family.</p>
<p>Years passed, and even though the disappointing Jakab was married and provided numerous grandchildren to Mr. Novak, Andrea and Mr. Kende didn&rsquo;t have any children of their own yet. This was a grave cause of concern for her parents, who even encouraged them to see an herbalist to increase their fertility. A few more years passed and at this point it was clear that there would be no children out of that marriage. Something had to be done or the dynasty would end right there.</p>
<p>Jakab started spreading rumors about how Mr. Kende had come by his fortune through shady means, hoping to hurt his reputation and have his parents choose him as the new heir. His attempt failed, ended up being further distanced from his parents, and Andrea was still the sole heir.</p>
<p>Mr. and Ms. Novak died after some time, and Andrea and Mr. Kende, still childless, became the new head of the family. It looked like the dynasty would end here, but that&rsquo;s when they became acquainted with Ms. Bognar, the orphanage director. She was able to facilitate the adoption of Henrietta, an adorable 6 year-old girl who would become the hope of the family&rsquo;s future for years to come.</p>
</blockquote>
<p>We want to be able to let players share their most memorable stories, but we haven&rsquo;t fleshed out exactly how we&rsquo;re going to do that. As you can see from the previous paragraphs, it&rsquo;s not a trivial matter. One possibility is to export some kind of autogenerated scrapbook that players can annotate if they want to, but there are many other ways we can go wit this (Any great ideas? Let us know in the comments).</p>
<p><img alt="Alurencombo" loading="lazy" src="/the-feelings-of-lasting-legacy/images/alurencombo-1.png"></p>
<h3 id="2-feeling-smart-for-discovering-combinations-of-occupations-that-create-really-powerful-outcomes">2. Feeling smart for discovering combinations of occupations that create really powerful outcomes.</h3>
<p>The explicit goal of Lasting Legacy is to score as many points as possible (i.e. build the largest legacy). In order to do that, players will acquire gold, prestige, and eventually turn it into legacy through different means. To get really high scores, players will have to carefully combine the actions and abilities from the different members of their family and their friends. The more outrageous the combination, the bigger the score.</p>
<p>This is an example of the kind of thinking that goes behind finding combinations of powers:</p>
<blockquote>
<p>The current head of the family likes prestige and will give 1 legacy for every 10 prestige the family earns. You have a Philantropic Benefactor in your family that gives you 5 prestige for every 50 gold you &ldquo;donate&rdquo;, but gold is running low. However, you also have access to a Ruthless Negotiator, who reduces all action costs by half, so each Philanthropic Benefactor activation gives you 5 prestige for 25 gold. This works for a few years, but you&rsquo;re almost out of money.</p>
<p>Then you notice that one of your friends is a Radical Anarchist, whose power is to get rid of all debt but he goes to jail. So you bring him to the family, rack up the debt to the maximum with the Philanthropic Benefactor, and finally send off the Radical Anarchist to erase all the debt. As a result, you gained a large amount of legacy, greatly increased your prestige, and didn&rsquo;t spend much gold in the process.</p>
</blockquote>
<p>This is very similar to the kind of combination of powers you find in games like Magic: The Gathering (<a href="/most-influential-games-on-me/">a huge influence on me in general</a>), and also reminiscent of the specialists powers in <a href="http://subterfuge-game.com/">Subterfuge</a>.</p>
<p>Those two goals are orthogonal. I could see some players enjoying one but not caring about the other, so we&rsquo;re making the game that can be enjoyable even if you just care about one of those aspects. We&rsquo;re making sure that both kinds of players can enjoy the game to the fullest. Someone who mostly cares about the stories, can just focus on growing the family and dealing with the emerging drama. On the other hand, someone who cares about maximizing their score also need to maintain the family going because it means playing longer and scoring more points, but they can ignore the in-game meaning of the actions they&rsquo;re taking and just visualize it in terms of how big of a legacy they&rsquo;re creating.</p>
<p>We hope that once players have played through the game many times and they become really good at it, that they ignore the explicit game goals and make their own constraints. The game becomes more of a toy at that point (unconstrained play) which is an aspect I love in games (we did that with <a href="http://shared.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a> as well). For example, the player may want to decide to play through a family in extreme poverty that never earns any gold, or a family that is all made out of criminals and low-life characters, or maybe just try to breed the most extreme physical characteristics possible. We hope there&rsquo;s a lot of room for exploration and enjoyment beyond just getting high scores.</p>]]></content:encoded></item><item><title>Announcing: Lasting Legacy</title><link>https://gamesfromwithin.com/announcing-lasting-legacy/</link><pubDate>Wed, 18 Jan 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/announcing-lasting-legacy/</guid><description>&lt;p&gt;Today I can finally announce the game &lt;a href="https://twitter.com/mysterycoconut"&gt;Miguel&lt;/a&gt; and I have been working on for a while: &lt;a href="http://lastinglegacygame.com/"&gt;&lt;em&gt;Lasting Legacy&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lastinglegacygame.com/"&gt;&lt;img alt="Logo" loading="lazy" src="https://gamesfromwithin.com/announcing-lasting-legacy/images/logo.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can read more about &lt;a href="http://lastinglegacygame.com/"&gt;&lt;em&gt;Lasting Legacy&lt;/em&gt; in the official web site&lt;/a&gt;. There isn&amp;rsquo;t a lot of information yet, but we wanted to announce it now so we can talk openly about it until release. We&amp;rsquo;ll definitely be revealing more information here over the upcoming weeks.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Today I can finally announce the game <a href="https://twitter.com/mysterycoconut">Miguel</a> and I have been working on for a while: <a href="http://lastinglegacygame.com/"><em>Lasting Legacy</em></a>.</p>
<p><a href="http://lastinglegacygame.com/"><img alt="Logo" loading="lazy" src="/announcing-lasting-legacy/images/logo.png"></a></p>
<p>You can read more about <a href="http://lastinglegacygame.com/"><em>Lasting Legacy</em> in the official web site</a>. There isn&rsquo;t a lot of information yet, but we wanted to announce it now so we can talk openly about it until release. We&rsquo;ll definitely be revealing more information here over the upcoming weeks.</p>
<h3 id="platforms">Platforms</h3>
<p>The first thing that might surprise some people is that we&rsquo;re going to release <em>Lasting Legacy</em> for Windows and Mac first (hopefully through Steam). This is a departure from all of my games as an independent developer, but I feel that PC is a better fit than mobile for <em>Lasting Legacy</em>. Also, I know Steam is flooded with new game releases, but it&rsquo;s not quite the mad house that mobile is these days, especially for a game that follows the old &ldquo;pay-once play-forever&rdquo; approach.</p>
<p>It won&rsquo;t be difficult to make a tablet/phone version later, so assuming it&rsquo;s moderately successful, we&rsquo;re likely to make an iOS version afterwards (Android is such a horrible development environment for native C games, that it probably won&rsquo;t be worth our time). And I suppose there&rsquo;s always the possibility of a console version if the opportunity presents itself.</p>
<h3 id="goals">Goals</h3>
<p>Why are we making <em>Lasting Legacy</em>? There are several high-level goals I had for my next project.</p>
<ol>
<li>
<p><strong>Shorter development.</strong> When I look back at the development times of the games I released over the years, I see a disturbing trend.</p>
<p><img alt="Screen Shot 2017 01 16 at 2 58 26 PM" loading="lazy" src="/announcing-lasting-legacy/images/Screen-Shot-2017-01-16-at-2.58.26-PM.png"></p>
<p>I really didn&rsquo;t want my next project to take nearly as long as Subterfuge did. Part of it meant tackling a game with a smaller scope, and part of it meant making it single player. My hope is that <em>Lasting Legacy</em> takes us less than 18 months from start to launch. Let&rsquo;s see if we can make it.</p>
</li>
<li>
<p><strong>Potential for wide appeal.</strong> The nature of Subterfuge meant that it was always a very niche product. We went into it knowing that and we successfully created a game that a very small percentage of people really love. This time I wanted to change things and wanted to create a game that had potential for wide appeal. It doesn&rsquo;t mean that it&rsquo;s going to be a clone of existing games or that we&rsquo;re going to dumb down anything. It just means that more people might like it, and some will hopefully love it as much as the devoted Subterfuge fans.</p>
<p>So far, in the extremely tiny, non-statistically meaningful sample of our close families, my wife, who is definitely not a video gamer, really likes the idea of the game and is interested to hear more about it (which is more than I can say for any of my projects since Flower Garden).</p>
</li>
<li>
<p><strong>Low money investment.</strong> Maybe it&rsquo;s not quite the <a href="https://medium.com/@morganjaffit/indipocalypse-or-the-birth-of-triple-i-eba64292cd7a#.jx9iu02qy">Indipocalypse</a> but there&rsquo;s no doubt it&rsquo;s a lot harder to make money from selling independent, original games than it was 5 years ago. Because of that, I don&rsquo;t feel comfortable investing a large amount of money into a project that might or might not end up being financially successful. That means picking a game that we can do almost completely between the two of us, minimizing the amount of contracting we have to do, and the scope of <em>Lasting Legacy</em> is perfect for that.</p>
</li>
</ol>
<h3 id="roadmap">Roadmap</h3>
<p>We still have a lot of work to do ahead of us.</p>
<ul>
<li><strong>Steam Greenlight.</strong> Once we have a lot more content in the game, we&rsquo;ll be able to create a video for the game and get it on Steam through the Greenlight process.</li>
<li><strong>Early access.</strong> Once we&rsquo;re on Steam, we&rsquo;ll have a period of Early Access. Because the <em>Lasting Legacy</em> is highly replayable, it&rsquo;s going to be a good candidate for Early Access. That time is also really going to help us fine tune the balance of the game and take player feedback into account for the final release.</li>
<li><strong>Release.</strong> When will this be? Once the game is done (but it better be this year!!).</li>
</ul>
<p>Want to help us make <em>Lasting Legacy</em> a success? Make sure you sign up for the <a href="http://lastinglegacygame.com">mailing list</a> and/or join the <a href="https://www.facebook.com/lastinglegacygame/">Facebook page</a>. Apart from progress updates, we&rsquo;ll announce when the game is on Greenlight so you can help vote us through it. Once we hit Early Access, we&rsquo;d love it if you can play the game and send us your feedback.</p>]]></content:encoded></item><item><title>Game Development Income</title><link>https://gamesfromwithin.com/game-development-income/</link><pubDate>Mon, 02 Jan 2017 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/game-development-income/</guid><description>&lt;p&gt;Inspired by &lt;a href="https://twitter.com/GreyAlien"&gt;Jake Birkett&lt;/a&gt;&amp;rsquo;s &lt;a href="https://twitter.com/GreyAlien/status/815949620727709696"&gt;game dev income chart&lt;/a&gt;, I decided to dig out my own data and make a similar chart. I figured it would be a good way to start the year looking at a retrospective of my time as an independent developer.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Game income2" loading="lazy" src="https://gamesfromwithin.com/game-development-income/images/game_income2.png"&gt;&lt;/p&gt;
&lt;p&gt;Some interesting observations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I made zero income in my first two years as as independent developer! I was supplementing my income writing a column for Game Developer Magazine, teaching classes, and doing some contracting. I even started interviewing thinking I would have to give up the indie life and go back to work for a company. I always tell new game developers to be ready not to make any money for a while for this reason.&lt;/li&gt;
&lt;li&gt;Flower Garden seems to have a reasonable tail in spite of minimal updates. Every so often I feel a bit guilty for not doing more with it, but even if I wanted to spend time on it, I can&amp;rsquo;t think of anything that would increase sales.&lt;/li&gt;
&lt;li&gt;Subterfuge is a blip in the radar. But what&amp;rsquo;s even worse, Subterfuge took 3.5 years to make, whereas Flower Garden was around 2 years (including all updates).&lt;/li&gt;
&lt;li&gt;The US tax system isn&amp;rsquo;t really set up for people with really spikey income like this.&lt;/li&gt;
&lt;li&gt;I need to make games more quickly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s to releasing a game in 2017 that is visible on that chart!&lt;/p&gt;</description><content:encoded><![CDATA[<p>Inspired by <a href="https://twitter.com/GreyAlien">Jake Birkett</a>&rsquo;s <a href="https://twitter.com/GreyAlien/status/815949620727709696">game dev income chart</a>, I decided to dig out my own data and make a similar chart. I figured it would be a good way to start the year looking at a retrospective of my time as an independent developer.</p>
<p><img alt="Game income2" loading="lazy" src="/game-development-income/images/game_income2.png"></p>
<p>Some interesting observations:</p>
<ul>
<li>I made zero income in my first two years as as independent developer! I was supplementing my income writing a column for Game Developer Magazine, teaching classes, and doing some contracting. I even started interviewing thinking I would have to give up the indie life and go back to work for a company. I always tell new game developers to be ready not to make any money for a while for this reason.</li>
<li>Flower Garden seems to have a reasonable tail in spite of minimal updates. Every so often I feel a bit guilty for not doing more with it, but even if I wanted to spend time on it, I can&rsquo;t think of anything that would increase sales.</li>
<li>Subterfuge is a blip in the radar. But what&rsquo;s even worse, Subterfuge took 3.5 years to make, whereas Flower Garden was around 2 years (including all updates).</li>
<li>The US tax system isn&rsquo;t really set up for people with really spikey income like this.</li>
<li>I need to make games more quickly.</li>
</ul>
<p>Here&rsquo;s to releasing a game in 2017 that is visible on that chart!</p>
]]></content:encoded></item><item><title>Most Influential Games (on Me)</title><link>https://gamesfromwithin.com/most-influential-games-on-me/</link><pubDate>Wed, 28 Dec 2016 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/most-influential-games-on-me/</guid><description>&lt;p&gt;I&amp;rsquo;ve been wanting to write about the project that I&amp;rsquo;m working on at the moment, but unfortunately we haven&amp;rsquo;t been able to announce it this year, so that will have to wait until January. I could do one of those year retrospective lists, but to be honest, I haven&amp;rsquo;t played enough digital or physical games from 2016 to be very interesting or representative.&lt;/p&gt;
&lt;p&gt;Instead, I&amp;rsquo;m going to try something a bit different. I want to highlight the games that have had the most influence on me as a game maker. Not the best games, not the most memorable games, not the most impressive games, but the ones that have directly influenced me and the games I&amp;rsquo;ve made.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve been wanting to write about the project that I&rsquo;m working on at the moment, but unfortunately we haven&rsquo;t been able to announce it this year, so that will have to wait until January. I could do one of those year retrospective lists, but to be honest, I haven&rsquo;t played enough digital or physical games from 2016 to be very interesting or representative.</p>
<p>Instead, I&rsquo;m going to try something a bit different. I want to highlight the games that have had the most influence on me as a game maker. Not the best games, not the most memorable games, not the most impressive games, but the ones that have directly influenced me and the games I&rsquo;ve made.</p>
<p>It was actually really hard coming up with this list. I initially had games that I absolutely love as a player and I spent many hours playing them. When I started fleshing things out, I realized they didn&rsquo;t directly influence me as a designer, so I ended up cutting them, even though it was really hard to do that (anyone who knows me will wonder why <a href="https://en.wikipedia.org/wiki/Fallout_(video_game)">Fallout</a> or <a href="https://en.wikipedia.org/wiki/Master_of_Orion">Master of Orion</a> are missing from this list).</p>
<h2 id="sorcery-1985">Sorcery (1985)</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/YI0TKuWh2TA" frameborder="0" allowfullscreen></iframe>
<p>This game single-handedly set me in the course of making games. I saw Sorcery at a friend&rsquo;s house, and I knew I had to make my own games, even before I owned a computer. I was blown away with everything about it: The sense of exploration and adventure, the atmosphere, the graphics, and the gameplay. I even dared replay this game recently and it mostly stands the test of time (although the tunnels over water are as frustrating as always).</p>
<h2 id="the-hobbit-1982">The Hobbit (1982)</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/SZsyv5aKw4U" frameborder="0" allowfullscreen></iframe>
<p>This is the oldest game in the list, but I actually didn&rsquo;t discover until later. The Hobbit, along with other text adventures, changed my preconceptions of what games could do. I felt I was free to walk around and interact with the world in any way I wanted in a way that graphic adventure games wouldn&rsquo;t let me.</p>
<p>I also learned the power of text in games, and how some good paragraphs of text can be much more evocative than graphics.</p>
<p>All of this led to the first serious game I completed: <a href="http://computeremuzone.com/ficha.php?id=695">La mÃ¡quina del tiempo</a> (which was an adaptation of H.G. Well&rsquo;s <a href="https://en.wikipedia.org/wiki/The_Time_Machine">The Time Machine</a>).</p>
<h2 id="macadam-bumper-1985">Macadam Bumper (1985)</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/SOE6zr8qRbQ" frameborder="0" allowfullscreen></iframe>
<p>This was the first game I played that allowed me to create my own levels (I suppose that in another world I should have played the earlier <a href="https://en.wikipedia.org/wiki/Pinball_Construction_Set">Pinball Construction Set</a>). For a budding game creator, this was a dream come true. I remember spending many afternoons with my cousin making our own version of a pinball table at the local arcade. I didn&rsquo;t play it much beyond that, but the seed of games with built-in level creation had been planted.</p>
<p>Casey&rsquo;s Contraptions is clearly the game I created that was most directly influenced by Macadam Bumper.</p>
<h2 id="sim-city-1989">Sim City (1989)</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/A54blk-ojA4" frameborder="0" allowfullscreen></iframe>
<p>The idea of a game being a simulation you can interact with was completely new to me, and I was instantly drawn to Sim City (even with the horrendous initial graphics). Later versions became much prettier and refined, but the basic idea remained the same. As a game designer, simulations are probably my favorite genre, and I&rsquo;m planning on exploring them more in the future.</p>
<h2 id="magic-the-gathering-1994">Magic: The Gathering (1994)</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/SPitPk-qiaA" frameborder="0" allowfullscreen></iframe>
<p>Another love at first sight. So many ideas from this game were new to me! Customization, card interactions, expandability&hellip; I also saw first hand how a game can grow beyond being a game that you play and &ldquo;finish&rdquo; to a full hobby that becomes part of your life. I&rsquo;ve taken some breaks from the game over the years, but even today I&rsquo;m playing it quite actively.</p>
<p>In spite of its flaws, I consider it one of the best and deepest games I&rsquo;ve ever played.</p>
<p>There&rsquo;s a lot I could write about Magic, but I&rsquo;m going to save it for another (or multiple) posts down the line.</p>
<h2 id="braid-2008">Braid (2008)</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/OqIKs_nRCLg" frameborder="0" allowfullscreen></iframe>
<p><a href="http://braid-game.com/">Braid</a> (along with <a href="https://worldofgoo.com/">World of Goo</a>) really showed me how an independent developer can make not just similar, but better and different games than traditional companies. This was particularly relevant to me at the time since it was around the time I had quit my full-time job to go independent and make games with a friend.</p>
<p>Playing through Braid and listening to <a href="https://www.youtube.com/watch?v=gwsi7TEQxKc">Jon&rsquo;s</a> <a href="https://www.youtube.com/watch?v=d0m0jIzJfiQ">talks</a> also opened my eyes to the idea of deliberate design. In Braid everything has a reason to be where it is. Every puzzle explores a slightly different consequence of the rules of the game (<a href="http://gamedesignreviews.com/reviews/braid-understanding-difficulty/">even when they&rsquo;re not very player friendly</a>). That&rsquo;s an important idea I&rsquo;ve tried to carry with me since then, and it definitely had an impact in <a href="http://subterfuge-game.com/">Subterfuge</a>.</p>
<h2 id="binding-of-isaac-2011">Binding of Isaac (2011)</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/c5PLC6nmOO4" frameborder="0" allowfullscreen></iframe>
<p>Binding of Isaac is a bit of an odd duck in this list. I&rsquo;m usually not a big fan of games that rely on speed and reflexes, yet Binding of Isaac is very much a twitch game. It&rsquo;s also a game that was not love at first sight. I played it for a bit and put it down. I even remember asking on Twitter what&rsquo;s so good about it. Fortunately some friends convinced me to give it another try, thinking about it less as an arcade game and more as the rogue-like it really is. At that point everything clicked in and I was hooked.</p>
<p>It was my first and strongest experience with rogue-like games (sorry <a href="http://www.spelunkyworld.com/">Spelunky</a>, I tried but never really got into you). I fell in love with the idea of games that can be completed relatively quickly, but are intended to be replayed over and over as things change from play to play.</p>
<h2 id="observations">Observations</h2>
<p>I had no idea what list I was going to come up with when I started writing this, so it&rsquo;s quite interesting to see the date distribution. There are more games from the 80s in this list than any other decade. That&rsquo;s to be expected since that was my first contact with games and that&rsquo;s when I had the strongest influences.</p>
<p>What&rsquo;s more interesting is that all decades since then are represented. I consider myself to be pretty jaded with respect to games (and movies and books), so it takes a lot for me to take notice of something and get excited about it. So I&rsquo;m really glad to see that there are standout games recently that wow me with something new and awesome.</p>
<p>Another interesting point is that there are no Japanese games in this list. Most game developers I know (especially in the US), grew up with Nintendo and Sega consoles and playing lots of Japanese games there. On the other hand, I never played more than 5 minutes of a Mario, Zelda, or Castlevania game! Instead, I grew up on Jet Set Willy, Roland in Time, and Dizzy. Whether you want it or not, that definitely changes the way I see and interpret games today (it never happened, but maybe I&rsquo;ll revisit the idea in the future).</p>
<p>At one point I was even going to use that source of uniqueness to make a game based around my love of the old games I grew up with. The idea was to present something familiar but that would be different to most people that had a different gaming background than me.</p>
<p>Finally, the game I&rsquo;m currently working on (which I hope we can announce any day now) has very clear influences from games on this list:</p>
<ul>
<li>Strong game element interactions and combinations(Magic: The Gathering).</li>
<li>Some simulation elements (Sim City).</li>
<li>Deliberate design (Braid).</li>
<li>Rogue-like structure (Binding of Isaac).</li>
</ul>
<p>Hopefully next post I can finally talk about this super-duper secret project.</p>
<p>Happy new year!</p>]]></content:encoded></item><item><title>Best Board Games of 2015</title><link>https://gamesfromwithin.com/best-board-games-of-2015/</link><pubDate>Tue, 19 Jan 2016 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/best-board-games-of-2015/</guid><description>&lt;p&gt;My tastes in board games are always evolving and changing, and 2015 was a very different year that marked a turning point for me. Looking at my play statistics, it&amp;rsquo;s clear that something changed: I played fewer games than in previous years, and, most importantly, I played many fewer new games than other years.&lt;/p&gt;
&lt;p&gt;2015 was the year when I started focusing on playing more often the games I loved, and stopped chasing after trying all the hot new games.&lt;/p&gt;
&lt;p&gt;Towards the end of 2014 it dawned on me that most new board games I was playing were ranging from bad to just OK, and only a selected few made it into the good or very good category. So why was I spending so much time and energy playing new games? It&amp;rsquo;s not like I had played the old ones too much and was done with them. As a matter of fact, I was frustrated with how little I was playing them, and how, if I only play a game once every six months or a year, I&amp;rsquo;m basically starting over from scratch. So I was always playing games at a very superficial level, without being able to get deeper into them. Not to mention it&amp;rsquo;s a pleasure to pull out a game and not have to worry about reading or explaining the rules!&lt;/p&gt;
&lt;p&gt;2015 was the year of depth for me.&lt;/p&gt;
&lt;p&gt;Of course depth comes at the cost of breath, so when it comes time to make a best-of list for 2015, I don&amp;rsquo;t have nearly as many different games to draw on as other years. Because of that, I&amp;rsquo;ll limit my list to just 3 games.&lt;/p&gt;</description><content:encoded><![CDATA[<p>My tastes in board games are always evolving and changing, and 2015 was a very different year that marked a turning point for me. Looking at my play statistics, it&rsquo;s clear that something changed: I played fewer games than in previous years, and, most importantly, I played many fewer new games than other years.</p>
<p>2015 was the year when I started focusing on playing more often the games I loved, and stopped chasing after trying all the hot new games.</p>
<p>Towards the end of 2014 it dawned on me that most new board games I was playing were ranging from bad to just OK, and only a selected few made it into the good or very good category. So why was I spending so much time and energy playing new games? It&rsquo;s not like I had played the old ones too much and was done with them. As a matter of fact, I was frustrated with how little I was playing them, and how, if I only play a game once every six months or a year, I&rsquo;m basically starting over from scratch. So I was always playing games at a very superficial level, without being able to get deeper into them. Not to mention it&rsquo;s a pleasure to pull out a game and not have to worry about reading or explaining the rules!</p>
<p>2015 was the year of depth for me.</p>
<p>Of course depth comes at the cost of breath, so when it comes time to make a best-of list for 2015, I don&rsquo;t have nearly as many different games to draw on as other years. Because of that, I&rsquo;ll limit my list to just 3 games.</p>
<h2 id="honorable-mention-magic-the-gathering">Honorable mention: <a href="http://magic.wizards.com/">Magic: The Gathering</a></h2>
<p><img alt="Cardart H0njz9txi1" loading="lazy" src="/best-board-games-of-2015/images/cardart_H0njz9txi1.jpg"></p>
<p>Magic: the Gathering and I go a long way back. I&rsquo;ve played Magic on and off for over 20 years and it&rsquo;s irrevocably intertwined with a lot of the different stages of my life. It has also strongly influenced me as a game designer.</p>
<p>But why list Magic as one of the best games of this year? Because I started playing seriously it again and it&rsquo;s an amazing game, in every way better than it was in 1995. Standard competitive play is constantly evolving and adapting, and booster draft is very balanced, fun, and skill-intensive. Wizards of the Coast did an amazing job with the Khans of Tarkir, Fate Reforged, Dragons of Tarkir, and Origins sets, and even though Battle for Zendikar was a big let down, I have my hopes up for Shadows Over Innistrad.</p>
<h2 id="3-the-gallerist">3. <a href="https://www.boardgamegeek.com/boardgame/125153/gallerist">The Gallerist</a></h2>
<p><img alt="Pic2503200" loading="lazy" src="/best-board-games-of-2015/images/pic2503200.png"></p>
<p>Even though I&rsquo;m moving away from complex games, one of my favorite games of 2015 was The Gallerist by Vital Lacerda. Kanban, by the same author, snuck in <a href="/noels-best-board-games-of-all-time-2014-edition/">my top games of all time list</a> that I created last year, and I like the Gallerist better. The theme is quite unique, the mechanics fresh and different, and you&rsquo;re hardly ever locked out of a particular action, which is something I find very frustrating in games. The game feels like a giant puzzle with lots of gears where you need to figure out how to make the most money before the end.</p>
<p>To top it off, <a href="http://amyshamansky.com/">my wife Amy</a> had a painting accepted in the abstract paintings category, so it&rsquo;s really cool to play a game with a piece of her art in it.</p>
<h2 id="2-grand-austria-hotel">2. <a href="https://www.boardgamegeek.com/boardgame/182874/grand-austria-hotel">Grand Austria Hotel</a></h2>
<p><img alt="Pic2648647 md" loading="lazy" src="/best-board-games-of-2015/images/pic2648647_md.jpg"></p>
<p>I love it when a neat theme meets good design into a very cohesive game. That&rsquo;s exactly what happened in Grand Austria Hotel, and somehow, it manages to go beyond the usual resource-conversion-to-points-engine to something fairly unique and interesting. Two warnings with this game though: 1) It can be a bit brain-burning towards the end with all the bonus actions, and 2) I would avoid playing this at full player count. There&rsquo;s a fair amount of downtime, and the board state would probably change too much between turns. It worked great at two players and I suspect it would be good with three as well.</p>
<h2 id="1-pandemic-legacy">1. <a href="https://www.boardgamegeek.com/boardgame/161936/pandemic-legacy-season-1">Pandemic Legacy</a></h2>
<p><img alt="PandemicLegacy red" loading="lazy" src="/best-board-games-of-2015/images/PandemicLegacy-red.jpg"></p>
<p>(Spoiler free) And the #1 game for 2015 is&hellip; Pandemic Legacy! But&hellip; this is not the glowing review you may be expecting of the game that rocketed up the BGG rankings and was the first game to displace the Twilight Struggle from the top spot in many years.</p>
<p>I love <a href="https://www.boardgamegeek.com/boardgame/30549/pandemic">Pandemic</a> and I love <a href="https://www.boardgamegeek.com/boardgameexpansion/40849/pandemic-brink">the</a> <a href="https://www.boardgamegeek.com/boardgameexpansion/137136/pandemic-lab">Pandemic</a> <a href="https://www.boardgamegeek.com/boardgameexpansion/137136/pandemic-lab">expansions</a>. My wife and I play it frequently and it&rsquo;s always a fun experience, teetering between success and world collapse. We can play it over and over. None of this should be a surprise since <a href="/noels-best-board-games-of-all-time-2014-edition/">Pandemic was #6 of my all-time games list from last year</a>.</p>
<p>How about Pandemic Legacy? Frankly, if I have to choose, I&rsquo;ll pick regular Pandemic. Pandemic Legacy is a nice little distraction. It&rsquo;s a sequence of games where the rules keep changing a bit, sometimes half way through a game. If I didn&rsquo;t already know and love Pandemic, I might even find it annoying. We&rsquo;re only about half way through the campaign, but I feel that nothing we do has a meaningful impact in the overall storyline. Things are going to happen independently of what you do, and you&rsquo;re just going to reveal the next card in the legacy deck.</p>
<p>Still, is Pandemic Legacy fun? Yes, but because it&rsquo;s Pandemic. It&rsquo;s good enough to take the #1 spot for 2015 for me. But plain Pandemic is better and it&rsquo;s the place you should start if you haven&rsquo;t already.</p>
<p>How about you? Any interesting picks for you top board games of 2015?</p>]]></content:encoded></item><item><title>State of the Blog</title><link>https://gamesfromwithin.com/state-of-the-blog/</link><pubDate>Fri, 08 Jan 2016 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/state-of-the-blog/</guid><description>&lt;p&gt;When was the last time I wrote something in this blog? It was a while ago. Hmm&amp;hellip; Let me check.&lt;/p&gt;
&lt;p&gt;Yikes! It was over a year ago! That&amp;rsquo;s probably the longest gap ever in the history of this blog. What happened? And most importantly for the two of you still reading, what&amp;rsquo;s going to happen over here?&lt;/p&gt;</description><content:encoded><![CDATA[<p>When was the last time I wrote something in this blog? It was a while ago. Hmm&hellip; Let me check.</p>
<p>Yikes! It was over a year ago! That&rsquo;s probably the longest gap ever in the history of this blog. What happened? And most importantly for the two of you still reading, what&rsquo;s going to happen over here?</p>
<p><a href="http://subterfuge-game.com/">Subterfuge</a> happened mostly. It was a long project that ran much longer than we expected. This last year I was focused on getting Subterfuge out the door. The little bit of writing energy I had went into writing for the <a href="http://blog.subterfuge-game.com/">Subterfuge development blog</a>.</p>
<p>For those of you who missed it, here are some of the highlights of the stuff I wrote focused on game design. Also check it all out because <a href="https://twitter.com/roncarmel">Ron</a> wrote a bunch of good stuff as well:</p>
<ul>
<li>
<p><a href="http://blog.subterfuge-game.com/post/103045873286/a-board-game-at-heart">A Board Game At Heart</a>. Where I explain how Subterfuge is more like a board game without any of the physical manifestations of a physical board game.</p>
</li>
<li>
<p><a href="http://blog.subterfuge-game.com/post/104851367166/luck-in-subterfuge">Luck in Subterfuge</a>. Applying one of my favorite topics to Subterfuge.</p>
</li>
<li>
<p><a href="http://blog.subterfuge-game.com/post/107423560776/balancing-different-paths-to-victory">Balancing Different Paths to Victory</a>. Balancing a competitive, multiplayer game was tricky and new for me. Lots of lessons learned.</p>
</li>
<li>
<p><a href="http://blog.subterfuge-game.com/post/108840831561/emergent-depth">Emergent Depth</a>. Why simplicity and depth are not mutually exclusive.</p>
</li>
<li>
<p><a href="http://blog.subterfuge-game.com/post/110177431691/depth-first-design">Depth-First Design</a>. More on how we first designed Subterfuge for depth.</p>
</li>
<li>
<p><a href="http://blog.subterfuge-game.com/post/112147930751/gaming-the-game">Gaming the Game</a>. The pains of a multiplayer, competitive game. And that was even before launch!</p>
</li>
<li>
<p><a href="http://blog.subterfuge-game.com/post/113436513776/cycling-and-subterfuge">Cycling and Subterfuge</a>. One of the least popular posts, but one of my favorites, highlighting how Subterfuge and road cycling have several similar dynamics.</p>
</li>
</ul>
<p>OK, so I was busy. You get it. What&rsquo;s going to happen over here in the future? To be honest, it wasn&rsquo;t an easy decision.</p>
<p>I considered stopping writing new entries in the blog and just leaving it up as an archive. Interesting game design conversations happen over at <a href="https://twitter.com/noel_llopis">Twitter</a> fairly frequently and so I have a reduced impulse to write here. Unfortunately those conversations are a) hard to follow b) quickly lost. So if what I write gets split up in a bunch of small tweets, it would be an overall loss.</p>
<p>At the other extreme, I considered getting back on a regular schedule and writing one article every week while back in the days of <a href="http://idevblogaday.com">#idevblogaday</a>. It&rsquo;s tempting, but I didn&rsquo;t like the pressure to have something written by a particular day. Nor did I like to feel that I had to come up with a significant, polished article.</p>
<p>So instead I&rsquo;ll take a middle road: I&rsquo;ll write relatively short posts in a relatively frequent schedule. How&rsquo;s that for vague? :-)</p>
<p>As for the content of the posts, it will all be centered around game design (probably not much pure programming anymore) and hopefully cover all the phases of my next project. I&rsquo;m also curious about possibly doing some streaming, but I have to find some content that fits well with that medium.</p>
<p>If you have some topics you&rsquo;d like me to cover, make sure to let me know on the comments or on <a href="https://twitter.com/noel_llopis">Twitter</a>.</p>
<p>Happy 2016 everybody!</p>]]></content:encoded></item><item><title>Noel's Best Board Games of All Time - 2014 Edition</title><link>https://gamesfromwithin.com/noels-best-board-games-of-all-time-2014-edition/</link><pubDate>Sun, 04 Jan 2015 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/noels-best-board-games-of-all-time-2014-edition/</guid><description>&lt;p&gt;There is no doubt that my game tastes are changing over time. Last year I was very much in love with point-salad games, and now I&amp;rsquo;m craving games with interesting player interactions or economic systems. This list is my attempt at capturing my top 20 favorite games at the end of 2014. It should be very interesting to compare it with the 2015 edition and see what has changed.&lt;/p&gt;
&lt;p&gt;This list was inspired by &lt;a href="https://boardgamegeek.com/geeklist/182599/casualgods-3rd-annual-top-20-games-all-time"&gt;Casualgod&amp;rsquo;s 3rd Annual Top 20 Games of All Time&lt;/a&gt;. David and I have a lot of overlapping tastes, so if you like what you see here, make sure you check out his list as well.&lt;/p&gt;</description><content:encoded><![CDATA[<p>There is no doubt that my game tastes are changing over time. Last year I was very much in love with point-salad games, and now I&rsquo;m craving games with interesting player interactions or economic systems. This list is my attempt at capturing my top 20 favorite games at the end of 2014. It should be very interesting to compare it with the 2015 edition and see what has changed.</p>
<p>This list was inspired by <a href="https://boardgamegeek.com/geeklist/182599/casualgods-3rd-annual-top-20-games-all-time">Casualgod&rsquo;s 3rd Annual Top 20 Games of All Time</a>. David and I have a lot of overlapping tastes, so if you like what you see here, make sure you check out his list as well.</p>
<h2 id="20-arkham-horror"><a href="https://boardgamegeek.com/boardgame/15987/arkham-horror">20. Arkham Horror</a></h2>
<p><img alt="Ah" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/ah1.jpg"></p>
<p>I make no claims this is a good game. However, this game is an amazing experience. The cooperative aspect is very important, and it&rsquo;s definitely a game that you get better the more you play.</p>
<p>Our first few games were way too long (3-4 hours), but once we got the rules down, now we can knock a game out in 2 hours or less.</p>
<p>The expansions add a lot of much-welcome variety. My favorite way of playing with them is to focus on each expansion, by just using about half the cards from the base game, and the rest from the expansion. That way each expansion shines to the maximum, with a lot of encounters being directly relevant to the theme of the game. Mixing them all just dilutes the experience and makes it a worse game than just plain base game.</p>
<h2 id="19-keyflower"><a href="https://boardgamegeek.com/boardgame/122515/keyflower">19. Keyflower</a></h2>
<p><img alt="Keyflower" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/keyflower3.jpg"></p>
<p>The rating for Keyflower could change quite a bit (up or down) simply because I haven&rsquo;t played it enough. My plays of it have been great, and I&rsquo;m looking forward to playing it a lot more.</p>
<p>The mix of bidding on tiles and using them at the same time is brilliant. Knowing some of the winter tiles ahead of times let&rsquo;s you plan more strategically for the end of game scoring. At least for the first few plays, this is probably best with 3 players, otherwise it&rsquo;s too many villages to keep track of.</p>
<h2 id="18-kanban-automotive-revolution"><a href="https://boardgamegeek.com/boardgame/109276/kanban-automotive-revolution">18. Kanban: Automotive Revolution</a></h2>
<p><img alt="Kanban" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/kanban.jpg"></p>
<p>This is the only entry in this list for a 2014 game, and it wasn&rsquo;t even part of the original list when I first put it together. However, a couple more plays quickly shot this up the ranks. I wouldn&rsquo;t be surprised to see this higher up in next year&rsquo;s list.</p>
<p>Kanban is a complex game, and on the surface like the kind of games I&rsquo;ve been getting away from recently. I don&rsquo;t like games that are complex for complexity sake (like Madeira), but Kanban pulls it all together and makes it work very well.</p>
<p>There are a lot of things going on on the board, but each department is quite simple. The complexity comes in how to put together all the actions in the most efficient way. I&rsquo;m four plays into this game and still learning new games.</p>
<p>Also, each play is quite different given the meeting goals and end of game bonus. Variability between games is a theme that will appear over and over in this list.</p>
<h2 id="17-notre-dame"><a href="https://boardgamegeek.com/boardgame/25554/notre-dame">17. Notre Dame</a></h2>
<p><img alt="Notredame" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/notredame.jpg"></p>
<p>One of my favorite Feld games (Castles of Burgundy barely missed the list). It plays in about an hour, the card drafting adds a nice limitation on your actions and keeps you very interested in what your neighbors are doing.</p>
<p>The extra cards in the mini-expansion make the game much better since it&rsquo;s more varied from game to game.</p>
<h2 id="16-the-palaces-of-carrara"><a href="https://boardgamegeek.com/boardgame/129948/palaces-carrara">16. The Palaces of Carrara</a></h2>
<p><img alt="Carrara" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/carrara.jpg"></p>
<p>I have to admit that my first play of this was underwhelming, but repeated plays quickly turned it around, and eventually pushed it all the way to #16.</p>
<p>Variability in this game is huge and no two games are alike. You have to re-evaluate everything depending on the scoring cards that come up for each game. Sometimes you build wide, sometimes you go tall, sometimes you focus on some buildings, or cities, or&hellip; The resource market is very simple and interesting, and the bits are great too.</p>
<p>Word of advice: Ignore the basic game. Sure, play with the basic goals once, but with the rest of the advanced rules (not moving the wheel, upgrading buildings, 8-point buildings, etc). I didn&rsquo;t and I almost missed out on this gem of a game.</p>
<h2 id="15-in-the-year-of-the-dragon"><a href="https://boardgamegeek.com/boardgame/31594/year-dragon">15. In the Year of the Dragon</a></h2>
<p><img alt="Ityotd" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/ityotd.jpg"></p>
<p>This is my other Feld on the top 20, and not surprisingly, it&rsquo;s from the same period as Notre Dame. It&rsquo;s still pretty focused, and quite different than most other games: You see all the disasters ahead of time, it&rsquo;s a matter of planning around them, maximizing scoring opportunities, and fighting everybody else who is trying to do the same thing. Deliciously tight and it plays great with 5 (and also great at lower player counts).</p>
<h2 id="14-race-for-the-galaxy"><a href="https://boardgamegeek.com/boardgame/28143/race-galaxy">14. Race for the Galaxy</a></h2>
<p><img alt="Rftg" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/rftg.jpg"></p>
<p>Yet another game that is hugely variable from play to play. Here you have some control (through Exploring) but ultimately it comes down to what you find and how you use it.</p>
<p>This is one of the rare games that has simultaneous action selection that I actually like, probably because other people&rsquo;s choices can only benefit you, and never negate your whole turn (unless you tried to get really cute).</p>
<p>I haven&rsquo;t even started playing with the expansions, or with any of the alternate lines. Looking forward to many more plays of this.</p>
<h2 id="13-santiago"><a href="https://boardgamegeek.com/boardgame/8125/santiago">13. Santiago</a></h2>
<p><img alt="Santiago" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/santiago.jpg"></p>
<p>Santiago was a total surprise. Yes, I had read very good comments from my Geekbuddies, but I really wasn&rsquo;t expecting it would be that good.</p>
<p>Santiago embodies everything I&rsquo;m looking for in games these days: - Strong player interaction (you&rsquo;re competing but still need to rely on other people) - Short playtimes - Simple ruleset</p>
<p>The result is an amazing game that some people describe as vicious, but I choose to think as self-interested. You&rsquo;re in it to win, and other players will have to make it worth your while if they want you to do something in particular. It&rsquo;s great that the game can be won through smart bidding, being a hard negotiator as the Overseer, or just by saving up lots of money and being opportunistic.</p>
<h2 id="12-the-great-zimbabwe"><a href="https://boardgamegeek.com/boardgame/111341/great-zimbabwe">12. The Great Zimbabwe</a></h2>
<p><img alt="Zimbabwe" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/zimbabwe.jpg"></p>
<p>This is a very unique race game (the same way that Race for the Galaxy is a race) where you can change the ending line in exchange for some advantages. It features the kind of player interaction I like, where you&rsquo;re competing with people, but at the same time using each other&rsquo;s resources in a positive way.</p>
<p>Each game is very different depending on the map layout and which gods come out. The only downside is how suddenly the ending can arrive, and how it can be spotted a turn or two in advance and there&rsquo;s nothing that can be done to stop it.</p>
<p>My favorite player count for this is probably 3 or 4.</p>
<h2 id="11-troyes"><a href="https://boardgamegeek.com/boardgame/73439/troyes">11. Troyes</a></h2>
<p><img alt="Troyes" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/troyes.jpg"></p>
<p>I never made a top-20 list last year, but I think this would have ended up much higher on last year&rsquo;s edition. Unfortunately I only played it twice on 2014, so I&rsquo;m not surprised it slid down a bit. Maybe next year it&rsquo;ll go back up.</p>
<p>I love dice as inputs, coupled with dice-manipulation mechanics, and this game is all about that.</p>
<p>Extremely varied gameplay is again present here: Only a few cards come up in each game, that those completely determine how the game is played (along with the event cards). No two games are alike, although that sometimes can be a bad thing (I introduced a friend to this game and we ended up with punishing events and cards that didn&rsquo;t combine very well with each other).</p>
<p>I was a bit disappointed with the expansion, so those of you looking for it, I&rsquo;d say skip it and save all that money.</p>
<h2 id="10-ra"><a href="https://boardgamegeek.com/boardgame/12/ra">10. Ra</a></h2>
<p><img alt="Ra" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/ra.jpg"></p>
<p>By now this list has quite a few games with bidding mechanisms (and there will be more further down). Ra is the purest of them all in that it&rsquo;s only about bidding.</p>
<p>It&rsquo;s another one of those games with a very simple ruleset that I love (with a slightly complicated end-game scoring, but it&rsquo;s easy enough with the player mats).</p>
<p>The thing that makes Ra stand out is that the bidding is very &ldquo;chunky&rdquo;. You have four tiles and you can bid one of them. That&rsquo;s all. Sure, it makes valuing things easier than Medici, but that&rsquo;s not a bad thing.</p>
<h2 id="9-lord-of-the-rings-the-card-game"><a href="https://boardgamegeek.com/boardgame/77423/lord-rings-card-game">9. Lord of the Rings: The Card Game</a></h2>
<p><img alt="Lotr" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/lotr.jpg"></p>
<p>It&rsquo;s not surprisingly that an LCG is very variable, but I&rsquo;m always amazed at how completely different each scenario makes this game feel. And by that I don&rsquo;t mean that one scenario is more combat heavy and another one more questing heavy. It&rsquo;s that the new rules and events for each scenario change the game completely, and at the same time make it so extremely thematic. For example, in Journey Down the Anduin, at one point you get on a boat and you&rsquo;re not attacked by the enemies in the engaging area, but you draw an extra card during the encounter phase (because you&rsquo;re traveling so quickly).</p>
<p>I haven&rsquo;t tried this solo yet (which I hear is brutally hard), but it&rsquo;s great fun with two players. Some scenarios are extremely hard though (I&rsquo;m looking at you, The Hobbit!), and most of them encourage you to tweak your decks in different ways.</p>
<h2 id="8-glen-more"><a href="https://boardgamegeek.com/boardgame/66362/glen-more">8. Glen More</a></h2>
<p><img alt="Glenmore" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/glenmore.jpg"></p>
<p>I love the jump-ahead mechanic in this game. There&rsquo;s always a great tension between getting something before other people, and still getting the other tiles you want along the way. The end-of-game penalty for having larger towns makes it even more interesting.</p>
<p>The tile-laying part of the game is very interesting too, because you have some restrictions (roads and river) and only the tiles next to a tile you lay down are activated, so you need to plan very carefully.</p>
<p>All in all, it combines short play time, and extremely meaningful and difficult decisions. Oh and it plays great with two as well.</p>
<h2 id="7-hansa-teutonica"><a href="https://boardgamegeek.com/boardgame/43015/hansa-teutonica">7. Hansa Teutonica</a></h2>
<p><img alt="Hansa" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/hansa.jpg"></p>
<p>For the longest time I kept reading about Hansa Teutonica as the poster child of boring, dry euros, as well as having a reputation for being extremely aggressive.</p>
<p>I don&rsquo;t mind my euros dry, but I typically don&rsquo;t like them aggressive. However, it turns out this was love at first sight for me. From the first play, I enjoyed every minute of this game. I didn&rsquo;t see the play as aggressive, but more of a blocking play that you get a benefit when someone moves you out of the way.</p>
<p>Unlike many other games in this list, this doesn&rsquo;t have much (any?) variability from game to game, but because there are so many ways to approach it, it can still feel quite different.</p>
<p>I&rsquo;m looking forward to many more plays and trying some of the expansion maps as well.</p>
<h2 id="6-pandemic"><a href="https://boardgamegeek.com/boardgame/30549/pandemic">6. Pandemic</a></h2>
<p><img alt="Pandemic" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/pandemic.jpg"></p>
<p>My highest-rated cooperative game. There may be some nostalgia in here, but I would pick this one above all other coops.</p>
<p>Cooperative games have strong random elements, and sometimes things are stacked in such a way that no matter what you do, you will fail. That&rsquo;s the nature of the game. Pandemic has that problem as well, but play time is short enough that it doesn&rsquo;t matter. You pick up the cards and do it again.</p>
<p>I love that the infection is driven by a deck of cards because you have a lot of information about what is likely to come up soon (since the discard pile is shuffled and put on top after every epidemic). That&rsquo;s something that was sorely missing from Pandemic The Cure (the dice version of Pandemic).</p>
<p>Finally, in case things start feeling too samey, the expansions add a lot of variability (I didn&rsquo;t like my first play of In The Lab, but I suspect it has a very steep learning curve).</p>
<h2 id="5-kingdom-builder"><a href="https://boardgamegeek.com/boardgame/107529/kingdom-builder">5. Kingdom Builder</a></h2>
<p><img alt="Kb" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/kb.jpg"></p>
<p>This game is the definition of variability from game to game. The rules themselves are just a couple of mechanics on how to put settlements on the board, and the scoring is mostly down to the cards that are drawn at the beginning of each game.</p>
<p>This was another one of those games that the first play felt a bit underwhelming. I thought the game was playing me, rather than me the game. It wasn&rsquo;t until the second game that I realized it was about positioning myself to accomplish what I want to do, rather than trying to select different terrain cards. It&rsquo;s also really interesting how you have very different goals early in the game (minimize terrain adjacencies so you can move to other places on the board), than you do late in the game (touch as many terrain types as possible so you can put your pieces anywhere you want).</p>
<p>Yes, you can get some ridiculously broken power/scoring combos, but again, games are quick. Have a laugh and play it again.</p>
<h2 id="4-homesteaders"><a href="https://boardgamegeek.com/boardgame/26566/homesteaders">4. Homesteaders</a></h2>
<p><img alt="Homesteaders" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/homesteaders.jpg"></p>
<p>Short, tense, and every decision is extremely meaningful. There are only 10 rounds to the whole game, and you won&rsquo;t even get a building in each round. You can go hugely in debt, and yet (hopefully) everything kind of comes together at the end.</p>
<p>It certainly fits with me liking bidding games, but it might initially stand out as a game with very little apparent variability from game to game. Rahdo even dismissed it because it didn&rsquo;t vary enough. Let me tell you something: This game is so tight, that minor changes will throw off your long-term plans in no time. I recently started a game where I had decided I was going to go for the Church and in-game points, but the way the bidding tiles came out, and the way Amy was bidding against me, I was forced to change plans and go for a resource/dudes strategy. So much for lack of variability!</p>
<p>It plays fantastic with any player count. The only downside is that a lot of buildings are available right from the start, so it&rsquo;s a bit overwhelming for new players. Well worth a small time investment to learn this fantastic game though.</p>
<h2 id="3-age-of-steam"><a href="https://boardgamegeek.com/boardgame/4098/age-steam">3. Age of Steam</a></h2>
<p><img alt="Aos" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/aos.jpg"></p>
<p>I&rsquo;ve tried a lot of train/route-building games, and Age of Steam comes out clearly on top (I need to play more <a href="https://www.boardgamegeek.com/boardgame/27833/steam">Steam</a> to decide between the two though).`</p>
<p>The auctions for player order/bonus are extremely interesting an unforgiving. The roles themselves are very well thought out so even if you don&rsquo;t get first place, you can still snatch first build or first move.</p>
<p>The route building and delivery aspect are always very fun and satisfying, the only downside is the randomness of where new goods appear on the board (yes, you see where they&rsquo;ll appear, but you don&rsquo;t know when, which makes all the difference in the world). Players can also find themselves in a downward spiral that takes them out of the game completely, but that&rsquo;s part of the experience of the game (although I agree that a 2-3 hour game where you&rsquo;re out of contention for half of it is not very fun, experience or no experience, so don&rsquo;t let that happen).</p>
<p>Finally, the variety of maps for Age of Steam out there make this game infinitely replayable. It&rsquo;s not jut a different distribution of mountains and rivers, it&rsquo;s that most maps radically change a few rules and transform the experience into something completely different.</p>
<h2 id="2-dominion"><a href="https://boardgamegeek.com/boardgame/36218/dominion">2. Dominion</a></h2>
<p><img alt="Dominion" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/dominion.jpg"></p>
<p>Speaking of variability, here&rsquo;s Donald X&rsquo;s other hugely variable game. Dominion was the first deck builder. I&rsquo;ve played a bunch since then, and I keep coming back to this one: it plays quickly, works great with any player count (but best with just 2 or 3), and it&rsquo;s always completely different.</p>
<p>Just like Troyes, some games are going to be more amazing than others depending on the combinations that come up, but it&rsquo;s always really fun looking at that new set of cards and figuring out a path to victory.</p>
<h2 id="1-brass-and-age-of-industry"><a href="https://boardgamegeek.com/boardgame/28720/brass">1. Brass and Age of Industry</a></h2>
<p><img alt="Aoi" loading="lazy" src="/noels-best-board-games-of-all-time-2014-edition/images/aoi.jpg"></p>
<p>I&rsquo;m giving my #1 game of all time award to both <a href="https://boardgamegeek.com/boardgame/65901/age-industry">Age of Industry</a> and <a href="https://boardgamegeek.com/boardgame/28720/brass">Brass</a>. It might feel like I&rsquo;m cheating, but I really consider Brass as a particular Age of Industry map with some funky rules thrown in. The fact is, both games feel very similar (with card drawing being the main difference).</p>
<p>I might give Brass the edge as a best game, but Age of Industry wins because of the different maps available and the different experiences it provides. I go back and forth between which one I like better, but I have them both rated as 10 (my only two 10 ratings on BGG).</p>
<p>They have the exact kind of player interaction that I love, where players are jockeying for position, using each other resources, and yet trying to out-do each other. I love that player order is determined by how much you spend in a turn, which gives you very interesting control over your turn.</p>
<p>I also consider Brass to be game that can be best played online: each turn is fairly long and meaty, and there are at most 16 turns in a 4-player game (most likely you&rsquo;ll have a couple of them back to back, so more like 14). As opposed to games that are 100+ turns long, and in each turn you&rsquo;re just clicking OK to something. I&rsquo;m always up for <a href="http://brass.orderofthehammer.com/index.php">a game of Brass online</a>, so if anyone is interested, let me know me and let&rsquo;s play.</p>
<p> </p>
<p><em><a href="https://boardgamegeek.com/geeklist/183750/noels-top-20-games-all-time-2014-edition">This list first appeared on BGG</a></em></p>]]></content:encoded></item><item><title>Best Board Games of 2013</title><link>https://gamesfromwithin.com/best-board-games-of-2013/</link><pubDate>Sun, 12 Jan 2014 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/best-board-games-of-2013/</guid><description>&lt;p&gt;Looking back, 2013 continued my trend of diving deeper in board games, both playing and designing them. It&amp;rsquo;s no coincidence that &lt;a href="http://subterfuge-game.com/"&gt;Subterfuge&lt;/a&gt;, the game I&amp;rsquo;m working on with &lt;a href="http://twitter.com/roncarmel"&gt;Ron Carmel&lt;/a&gt;, has very strong board game influences. I&amp;rsquo;ll talk more in a future post about the design part, what kind of games I tried making and which ones I&amp;rsquo;m still working on. This post will focus on the best games I played that came out on 2013.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Looking back, 2013 continued my trend of diving deeper in board games, both playing and designing them. It&rsquo;s no coincidence that <a href="http://subterfuge-game.com/">Subterfuge</a>, the game I&rsquo;m working on with <a href="http://twitter.com/roncarmel">Ron Carmel</a>, has very strong board game influences. I&rsquo;ll talk more in a future post about the design part, what kind of games I tried making and which ones I&rsquo;m still working on. This post will focus on the best games I played that came out on 2013.</p>
<p>I try to <a href="http://www.boardgamegeek.com/plays/bymonth/user/llopis/subtype/boardgame">log every board game play</a>, so I can see that <a href="http://friendless.servegame.org/dynamic/tabbed/llopis/2#pbmever">I logged 674 different plays during the course of the year, and 246 of those were games new to me</a>. I didn&rsquo;t invent a time-expanding machine, so the time for that has come straight from TV, movies, and video games. After realizing that we were spending just about every evening playing board games, my wife an I cancelled our Netflix subscription and never looked back. I also only played a handful of PC and iOS games during the whole year.</p>
<p>Another good portion of those games were due to going to local game days, and to two board game conventions: <a href="http://originsgamefair.com/">Origins</a> and <a href="http://boardgamegeek.com/bggcon">BGGCon</a>.</p>
<p>Having played that many games, I figured it would be interesting to write a best-of list for the year. For this one, I wanted to focus exclusive on games that came out on 2013. I played 43 games that came out on 2013, and of those, these are my favorites.</p>
<h1 id="5-nations"><a href="http://www.boardgamegeek.com/boardgame/126042/nations">5. Nations</a></h1>
<p>I absolutely love Civilization and <a href="http://en.wikipedia.org/wiki/Master_of_Orion_II:_Battle_at_Antares">Civ-like</a> games. Unfortunately, for the most part, those work best on a computer due to the long play time, and the large amount of parts, pieces, and interconnecting systems. I&rsquo;ve tried playing some board game versions (<a href="http://www.boardgamegeek.com/boardgame/25613/through-the-ages-a-story-of-civilization">Through the Ages</a>, <a href="http://www.boardgamegeek.com/boardgame/40765/clash-of-cultures">Clash of Cultures</a>) and while they weren&rsquo;t bad, I would probably rather play the computer version of Civilization.</p>
<p>Nations is finally the first civilization board game that works really well for me. It has a reasonable play time (under 2 hours for 4 players), interesting player interaction without direct conflict, and a great power curve. One of the key things design aspects that allows this game to work so well is that they did away with the map (just like Through the Ages), so players can focus exclusively on advancing their civilization rather than exploring the map.</p>
<p><img alt="Nations" loading="lazy" src="/best-board-games-of-2013/images/nations.jpg"></p>
<h1 id="4-bora-bora"><a href="http://www.boardgamegeek.com/boardgame/127060/bora-bora">4. Bora Bora</a></h1>
<p>It&rsquo;s no secret that I like a lot of <a href="http://www.boardgamegeek.com/boardgamedesigner/4958/stefan-feld">Stefan Feld</a> games. I particularly like some of his earlier games (<a href="http://www.boardgamegeek.com/boardgame/31594/in-the-year-of-the-dragon">In The Year of the Dragon</a>, <a href="http://www.boardgamegeek.com/boardgame/25554/notre-dame">Notre Dame</a>), but I also like some of his recent ones (<a href="http://www.boardgamegeek.com/boardgame/84876/the-castles-of-burgundy">Castles of Burgundy</a>). Some critics dismiss a lot of his designs as &ldquo;point salads&rdquo;, but I do like my veggies! Seriously, there are badly done point salads, where the things you do have little significance beyond getting you some points (<a href="http://www.boardgamegeek.com/boardgame/102680/trajan">Trajan</a> fell in that category for me), and well-done points salads like Bora Bora, where you&rsquo;re showered with points, but you&rsquo;re also opening up new paths and possibilities with each new action. Bora Bora hits all the right buttons for me: interweaving of effects on the board, different strategies, and the sense of building something. It&rsquo;s a tad long with 4 players, but it plays great with 2 or 3.</p>
<p><img alt="Bora bora board game" loading="lazy" src="/best-board-games-of-2013/images/bora-bora-board-game.jpg"></p>
<h1 id="3-spyrium"><a href="http://www.boardgamegeek.com/boardgame/137269/spyrium">3. Spyrium</a></h1>
<p>While Bora Bora is a game that hits you with its colorful game board, fancy player boards, and loads of chits, Spyrium stands in stark contrast and it manages to do with very few components: A deck of cards, a few tokens, and a minimal (almost unnecessary) central board. Spyrium is a amazing piece of design because it manages to have a very rich and deep gameplay with minimalistic components.</p>
<p>In spite of having so few components, Spyrium has a huge amount of variability between games. Apart from the variations from the actions other players take, there&rsquo;s the order in which cards will come up, the order of events for each round, and even the tokens that go on the cards themselves (which is an extra layer of variability for those cards since it changes their cost or effect).</p>
<p>The key mechanic of adding or removing workers for money or the card is very innovative and fresh. It&rsquo;s also a game that plays well, but very differently, at different player counts. So playing with 4 people after learning the game with 2 will cause you to re-learn everything you thought you knew about it.</p>
<p><img alt="Spyrium" loading="lazy" src="/best-board-games-of-2013/images/Spyrium.jpg"></p>
<h1 id="2-prosperity"><a href="http://www.boardgamegeek.com/boardgame/145203/prosperity">2. Prosperity</a></h1>
<p>Prosperity was co-designed by <a href="http://www.boardgamegeek.com/boardgamedesigner/2/reiner-knizia">Reiner Knizia</a> and <a href="http://www.boardgamegeek.com/boardgamedesigner/7448/sebastian-bleasdale">Sebastian Bleasdale</a>. While Dr. Knizia is the big name there, I&rsquo;m a particular fan of Bleasdale&rsquo;s earlier design, <a href="http://www.boardgamegeek.com/boardgame/122515/keyflower">Keyflower</a>. In spite of that, I was afraid this game was going to be a too-abstract tile-laying game not to my tastes.</p>
<p>Boy was I wrong! Prosperity was my surprise game of the show at BGG Con (and I played a lot of games at the con). It hits the perfect level of abstractness that you feel you&rsquo;re in charge of a city, but without degenerating in a sea of details that bog the game down. It manages to hit that magical middle-weight game category, that packs a lot of very interesting decisions in a playing time of an hour or less.</p>
<p><img alt="Prosperity" loading="lazy" src="/best-board-games-of-2013/images/prosperity.jpg"></p>
<h1 id="1-bruxelles-1893"><a href="http://www.boardgamegeek.com/boardgame/144592/bruxelles-1893">1. Bruxelles 1893</a></h1>
<p>Unlike other simpler games, Bruxelles 1893 presents the player with a myriad of choices. It falls a bit in the camp of a Feldian point-salad game, but where each action and choice is very interconnected to the rest of the actions and the state in the board. You want to do action A, but if you do action B before, then A will be a lot more efficient. But of course, if you do C, then B will be even more powerful. Those kind of tough choices elevate this game to the top of my 2014 games.</p>
<p>Bruxelles 1893 is by new designer <a href="http://www.boardgamegeek.com/boardgamedesigner/69130/etienne-espreman">Etienne Espreman</a>, but with some involvement by <a href="http://www.boardgamegeek.com/boardgamedesigner/38335/sebastien-dujardin">SÃ©bastien Dujardin</a>, who designed my favorite board game, <a href="http://www.boardgamegeek.com/boardgame/73439/troyes">Troyes</a>.</p>
<p><img alt="Bruxelles" loading="lazy" src="/best-board-games-of-2013/images/bruxelles.jpg"></p>
<p> </p>
<p>Maybe even more interesting than looking at the list itself, is to look at what those games have in common. I have fairly varied tastes in games, but all the games in this list have some strong common elements:</p>
<ul>
<li>Tough, interesting choices</li>
<li>Themes that appeal to me (no generic fantasy or zombies)</li>
<li>They play well with 2 players</li>
<li>Some player interaction, but no direct player confrontation and screwage</li>
<li>Play times under 2 hours</li>
</ul>
<p>Some of my other favorite games for this year that didn&rsquo;t quite make it in the top 5 were:</p>
<ul>
<li><a href="http://boardgamegeek.com/boardgame/119506">Freedom: The Underground Railroad</a>: A cooperative game (a weakness of mine) with a very strong history theme.</li>
<li><a href="http://www.boardgamegeek.com/boardgame/144415/nauticus">Nauticus</a>: By wonder duo Michael Kiesling and Wolfgang Kramer. I wasn&rsquo;t impressed with their other 2013 release, Coal Baron, but Nauticus is a perfect middle-weight game with possibilities for clever play.</li>
<li><a href="http://www.boardgamegeek.com/boardgame/131357/coup">Coup</a>: Technically this is a 2012 release, but it became much more widely available in 2013. It&rsquo;s an amazing, quick, social game of bluffing and deduction. . The love child of Resistance and Love Letter.</li>
<li><a href="http://www.boardgamegeek.com/boardgame/136280/la-boca">La Boca</a>: A unique spacial game that forces players to collaborate to build something they can only see from their side. You really have to experience to understand it.</li>
<li><a href="http://www.boardgamegeek.com/boardgame/143986/cv">CV</a>: A quirky dice-rolling game with delightful art where you build the life of your character. It&rsquo;s mostly luck-driven, but it ends up with very memorable stories.</li>
</ul>
<p>I didn&rsquo;t play every board game released on 2013 (or even close), so take my list with a grain of salt. As a reference, these are the other games I played that didn&rsquo;t make the cut: <a href="http://boardgamegeek.com/boardgame/137408">Amerigo</a>, <a href="http://boardgamegeek.com/boardgame/143741">Bang! The Dice Game</a>, <a href="http://boardgamegeek.com/boardgame/140933">Blueprints</a>, <a href="http://boardgamegeek.com/boardgame/137237">Bremerhaven</a>, <a href="http://boardgamegeek.com/boardgame/136888">Bruges</a>, <a href="http://boardgamegeek.com/boardgame/136440">Canterbury</a>, <a href="http://boardgamegeek.com/boardgame/102794">Caverna: The Cave Farmers</a>, <a href="http://boardgamegeek.com/boardgame/124052">Cinque Terre</a>, <a href="http://boardgamegeek.com/boardgame/143515">Coal Baron</a>, <a href="http://boardgamegeek.com/boardgame/124361">Concordia</a>, <a href="http://boardgamegeek.com/boardgame/142451">Cornish Smuggler</a>, <a href="http://boardgamegeek.com/boardgame/140603">Francis Drake</a>, <a href="http://boardgamegeek.com/boardgame/27574">Island Fortress</a>, <a href="http://boardgamegeek.com/boardgame/52461">Legacy: The Testament of Duke de Crecy</a>, <a href="http://boardgamegeek.com/boardgame/126000">Letnisko</a>, <a href="http://boardgamegeek.com/boardgame/140620">Lewis &amp; Clark</a>, <a href="http://boardgamegeek.com/boardgame/130912">The Lord of the Rings Dice Building Game</a>, <a href="http://boardgamegeek.com/boardgame/121122">The Lost Dutchman</a>, <a href="http://boardgamegeek.com/boardgame/131891">Lost Legends</a>, <a href="http://boardgamegeek.com/boardgame/147624">Mount Everest</a>, <a href="http://boardgamegeek.com/boardgame/71906">NÃ¡ufragos</a>, <a href="http://boardgamegeek.com/boardgame/102148">NOIR: Deductive Mystery Game</a>, <a href="http://boardgamegeek.com/boardgame/146094">Plunder</a>, <a href="http://boardgamegeek.com/boardgame/143519">Quantum</a>, <a href="http://boardgamegeek.com/boardgame/109764">Quarantine</a>, <a href="http://boardgamegeek.com/boardgame/119591">Rialto</a>, <a href="http://boardgamegeek.com/boardgame/144344">Rococo</a>, <a href="http://boardgamegeek.com/boardgame/144733">Russian Railroads</a>, <a href="http://boardgamegeek.com/boardgame/121615">Shadows over the Empire</a>, <a href="http://boardgamegeek.com/boardgame/132407">Stone &amp; Relic</a>, <a href="http://boardgamegeek.com/boardgame/133473">Sushi Go!</a>, <a href="http://boardgamegeek.com/boardgame/137238">Time &rsquo;n&rsquo; Space</a>, <a href="http://boardgamegeek.com/boardgame/137397">Via Appia</a>, <a href="http://boardgamegeek.com/boardgame/128621">Viticulture</a>.</p>]]></content:encoded></item><item><title>Luck In Games</title><link>https://gamesfromwithin.com/luck-in-games/</link><pubDate>Tue, 06 Aug 2013 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/luck-in-games/</guid><description>&lt;p&gt;The amount and type of luck involved in a game has a profound impact on the feel of that game. Some games have no luck whatsoever, and all the variation comes from what the opponent does (chess), some of them are all about luck with not much else (roulette), and most of them fall somewhere in between, creating a wide spectrum of possible experiences.&lt;/p&gt;
&lt;p&gt;We don&amp;rsquo;t talk much about the role of luck in video games, probably because it&amp;rsquo;s hidden away under the black box of the computer simulation, but just like with board games, it can have have a large impact in the type of experience the video game provides.&lt;/p&gt;
&lt;p&gt;Thinking about luck in these terms was crucial for the game I&amp;rsquo;m working on (still unannounced!). We made some crucial decisions thinking about how luck was part of the game and kind what kind of experience it created for the player. I&amp;rsquo;m hoping this post helps people with similar design challenges.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The amount and type of luck involved in a game has a profound impact on the feel of that game. Some games have no luck whatsoever, and all the variation comes from what the opponent does (chess), some of them are all about luck with not much else (roulette), and most of them fall somewhere in between, creating a wide spectrum of possible experiences.</p>
<p>We don&rsquo;t talk much about the role of luck in video games, probably because it&rsquo;s hidden away under the black box of the computer simulation, but just like with board games, it can have have a large impact in the type of experience the video game provides.</p>
<p>Thinking about luck in these terms was crucial for the game I&rsquo;m working on (still unannounced!). We made some crucial decisions thinking about how luck was part of the game and kind what kind of experience it created for the player. I&rsquo;m hoping this post helps people with similar design challenges.</p>
<p>This post should apply to any kind of game in general (board or video games). Next time, I&rsquo;ll be focusing especially on luck in video games using this as a launching point for a deeper look. Also, I&rsquo;m limiting the definition of luck to random effects built into the game system itself, and not due just to player interaction.</p>
<h2 id="no-luck-games">No-Luck Games</h2>
<p>In games with no luck, players rely completely on their skill to win. In that way, they&rsquo;re closer to sports. Games become an intense, straight competition, pitting players&rsquo; brains against each other. Right there it shows how luck (or in this case, the absence of luck) creates a very specific feel to a game.</p>
<p>Good examples of games without any luck are classics such as Chess or Go. There are also plenty of modern board games with no luck, like <a href="http://www.boardgamegeek.com/boardgame/3076/puerto-rico">Puerto Rico</a>, <a href="http://www.boardgamegeek.com/boardgame/18602/caylus">Caylus</a> (they both have a minimal amount of luck in the initial tile order), or <a href="http://www.boardgamegeek.com/boardgame/2655/hive">Hive</a>.</p>
<p>It&rsquo;s interesting that a lot of abstract games tend to have no luck, and the more thematic a game gets, the more they seem to rely on luck.</p>
<h2 id="are-you-feeling-lucky">Are You Feeling Lucky?</h2>
<p>Having some amount of luck in a game can be very beneficial for most kinds of board games. It accomplishes many things:</p>
<ol>
<li>Keeps things varied from game to game</li>
<li>Keeps players feeling they have a chance to win even if they&rsquo;re not currently ahead</li>
<li>Removes pressure from winning players (&ldquo;If someone beats me, it&rsquo;s because they had a lucky streak&rdquo;)</li>
<li>Makes players who didn&rsquo;t win feel they stand a chance next time they play (&ldquo;next time I&rsquo;ll catch a break and I can win!&rdquo;)</li>
</ol>
<p>Points 2, 3, and 4 all encourage more people to play the game and feel they&rsquo;re competitive at it, even if they didn&rsquo;t win (and even if they&rsquo;re not really competitive). One of the best examples of this is poker: Everybody feels they can do great at poker, if only they get good cards. In reality, this is not true in the long term, but poker introduces plenty of luck that it really is true in the short term.</p>
<p>A consequence of all those points is that having some amount of luck allows players of different skills to participate in the same game and enjoy it equally. For games that rely on having multiple people looking to play it, it can be a big factor.</p>
<h2 id="types-of-luck">Types of luck</h2>
<p>For games that choose to add some luck element, there&rsquo;s a whole range of amounts and types of lucks they can use for different effects. Unfortunately, it&rsquo;s also possible to mix the wrong type of luck with a given game feature and create a frustrating experience instead of an enjoyable one.</p>
<ul>
<li>Post-action luck. This is luck introduced after the player has made a decision and executed an action. It can be in the form of flipping a coin to see if you unlock a chest, or rolling a dice to see if your armies invade a territory.</li>
<li>Pre-action luck. Pre-action luck consists of the random events that happen before the player performs an action. The player is able to take them into account and make a decision based on them.</li>
<li>Hidden information. Hidden information is the third kind of luck. I was a bit hesitant to include it as its own category first, but it seemed different enough from the other two to warrant being listed on its own. Hidden information refers to things that are known only to some players and will affect other players or the game scoring.</li>
</ul>
<p><img alt="Dice troyes" loading="lazy" src="/luck-in-games/images/dice-troyes.jpg"></p>
<h2 id="post-action-luck">Post-action luck</h2>
<p>OK, I&rsquo;m going to say it: I&rsquo;m not a fan of post-action luck. The player has already made its action and the outcome is random (even if it&rsquo;s based on a probability curve the player is aware of, like <a href="http://anydice.com/program/e6">rolling 3 six-sided dice</a>). Since it doesn&rsquo;t add to the choices the player has, it&rsquo;s mostly uninteresting. This is the kind of luck that can add a bit of spice to an otherwise boring game, it doesn&rsquo;t do much to make the game more interesting.</p>
<p>When used incorrectly, this kind of luck is extremely frustrating. The player can feel they chose the &ldquo;best&rdquo; action, but they rolled double 1s and their move backfired on them. Sure, there was some tension knowing that could happen, but was it really fun? Maybe the first time or two, but probably not long term.</p>
<p>While I typically really don&rsquo;t like this kind of luck in my games, there are some situations in which even I will add it can add some interest to the game.</p>
<p>The first case is when the player can choose to perform one action or another, being aware of the different probability curves for both actions. For example, you can roll a single die and deal that damage to an enemy, or you can roll two dice, but if you roll two 1s, your character gets hit instead. In a situation like that, even though it&rsquo;s still post-action luck, the player was presented with a meaningful decision ahead of time and had to weight the risks and rewards of both options.</p>
<p>The second case where post-action luck can work is when the action is repeated many times over the course of a game. That way, the outcome of each individual action in themselves is not game-breaking, and all the actions will eventually add up to the average over the course of the game. Luck in this case introduces a bit of noise and slight excitement without affecting things much.</p>
<p>This is a good situation to combine with the ability for players to slowly change their probability curves over the course of the game. That way, they can increase their chances of success for an action as the game progresses, presenting the player with a way to feel more powerful. This is often used in RPGs and video games.</p>
<p>Having some kind of post-action luck that affects the outcome of an action can also give players hope that they can do something, even if those chances are small. Otherwise, without any luck involved, they would see the situation is hopeless and lose interest in the game. At the same time, having that luck element makes predicting every possible outcome nearly impossible, so it encourages players to make a decision without spending a long time figuring out an ideal outcome.</p>
<p>Finally, another situation where post-action luck isn&rsquo;t always a bad thing is in very short games. I love <a href="http://www.boardgamegeek.com/boardgame/70323/king-of-tokyo">King of Tokyo</a> even though it&rsquo;s a complete dice fest with lots of post-action luck. Even if you get some really bad dice rolls, a game maybe only lasts 10-15 minutes, so it didn&rsquo;t feel like a complete waste of time. On the other hand, losing a 4-hour game to a dice roll can be extremely infuriating.</p>
<p>The dark side of post-action luck is the human addition to random rewards, which is the reason why gambling or slot machines are so popular. Games can exploit that human quirk to their advantage and hook players in a game that would otherwise not be very interesting or fun.</p>
<p>A very meta post-action luck is buying &ldquo;booster packs&rdquo; of collectable card games (like Magic The Gathering). Purchasing the cards is the action, and the luck happens when you open it and see which random cards were in the pack. As most ex-Magic The Gathering players can attest, this can be extremely addictive.</p>
<h2 id="pre-action-luck">Pre-action luck</h2>
<p>This type of luck can add just as much randomness as post-action luck, but creates a very different feel for the game. Since the random event happens before the player action, even if you didn&rsquo;t get the ideal outcome you were hoping for, you can choose to do the best action given your situation.</p>
<p>To illustrate the difference, consider power-ups in a first-person shooter. You open the door to one room and there&rsquo;s a mysterious gift package power-up. You have no idea what it is, you pick it up andâ€¦ it turns out it was health. Maybe that&rsquo;s great because you were low in health. Or maybe you were maxed out and it was useless. That&rsquo;s post-action luck.</p>
<p>Alternatively, imagine you open that door and you see 3 power-ups side by side. You see what they&rsquo;re going to give you (health, ammo, or a new weapon). As soon as you take one, the others go away. Maybe neither one of them is exactly the ideal, but you can make a decision and pick the best one for your situation. That&rsquo;s pre-action luck.</p>
<p>In board games, <a href="http://www.boardgamegeek.com/boardgamedesigner/4958/stefan-feld">Stefan Feld</a> is the master of pre-action luck. A lot of his games involve some kind of luck mechanism that limits your actions. For example, in <a href="http://www.boardgamegeek.com/boardgame/84876/the-castles-of-burgundy">The Castles of Burgundy</a> or <a href="http://www.boardgamegeek.com/boardgame/127060/bora-bora">Bora Bora</a>, you roll dice, and the numbers on those dice determine which actions you can take.</p>
<p>Without going that far, just about any games that involves drawing cards from a deck and having a &ldquo;hand&rdquo; of cards uses pre-action luck. The cards you&rsquo;re dealt are the pre-action luck, and then you have to do the best you can with those cards.</p>
<p>An extreme type of pre-action luck is initial game layout. That happens only a single time during the game, and before players make any actions, so it has the potential to affect the full course of the game. Even players who are adamantly opposed to luck in games, are often willing to accept game setup randomness because it can be fully taken into account during the game without any surprises.</p>
<p>Pre-action luck isn&rsquo;t as common in games as post-action luck, but it could be used just about anywhere that post-action luck is used. Consider the classic situation of a character attack some monsters and rolling a set of dice that determine whether he hits and how much damage it does. We could change that into pre-action luck by having players roll the dice (either all at once or separately), and having the dice restrict the options of what they can do. For example, low rolls on one dice could indicate that they can only do an attack close to the ground, while high rolls means they can attack flying enemies. Then the player can choose which of those actions to take, or maybe he can instead take a defensive stance or run away.</p>
<p>The main downside of pre-action luck is that it can extend every player action. The more it&rsquo;s used, and the more possible choices it presents to the player, the longer the game might take, so it&rsquo;s best to save it for times where the decisions really matter. If not, either post-action luck or no luck at all, might be better choices.</p>
<p><img alt="Shipyard" loading="lazy" src="/luck-in-games/images/shipyard.jpg"></p>
<h2 id="hidden-information">Hidden information</h2>
<p>The most common example in board games is hidden end of game bonuses. For example, in <a href="http://boardgamegeek.com/boardgame/55600/shipyard">Shipyard</a> players get a set of goals that will score them points at the end of the game. There are two reasons for these goals: By giving each player different goals, it encourages players to focus on different aspects of the game instead of fighting over the same set of &ldquo;optimal&rdquo; actions. It also encourages players to pay attention to what other players are doing, and potentially try to anticipate or even block other players from getting too far ahead in their goals.</p>
<p>An even more interesting case is the game <a href="http://www.boardgamegeek.com/boardgame/73439/troyes">Troyes</a> (one of my favorites!). Not only does each player get a set of end-of-game goals to get extra points, but all players, not just the player holding them, will be scored based on those goals. That makes paying attention to other players and trying to guess what they&rsquo;re doing even more important.</p>
<p>At the extreme end of hidden information there are games like <a href="http://www.boardgamegeek.com/boardgame/91312/discworld-ankh-morpork">Discworld: Ankh-Morpork</a>, in which each player gets a hidden winning condition. Players go about doing their actions until someone announces at the beginning of their turn that they have won the game, and they reveal their hidden victory condition card.</p>
<p>The higher the importance of the hidden information, the more casual and random the game becomes (and so, the shorter the game should be ideally).</p>
<p>I started writing this thinking it would be a quick entry about luck in games, but now it&rsquo;s grown into something pretty large, and I didn&rsquo;t even get a chance to touch on luck in video games. I&rsquo;ll look into that next time.</p>
<p><strong>Related reading</strong> These are a couple of great writeups/presentations on the same topic:</p>
<ul>
<li><a href="http://boardgamegeek.com/blogpost/15046/2-types-of-luck">Types of Luck by Antti Karjalainen</a></li>
<li><a href="http://twvideo01.ubm-us.net/o1/vault/gdccanada09/slides/RobertGutscheraLuckSkillAndHI_GDCV050109.pptx">Luck, Skill, and Hidden Information by Robert Gutschera</a></li>
</ul>]]></content:encoded></item><item><title>Board Games: My New (Old) Love</title><link>https://gamesfromwithin.com/board-games-my-new-old-love/</link><pubDate>Mon, 01 Jul 2013 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/board-games-my-new-old-love/</guid><description>&lt;p&gt;It feels like I&amp;rsquo;ve been making and playing video games all my life. It turns out I&amp;rsquo;ve been playing board games even longer.&lt;/p&gt;</description><content:encoded><![CDATA[<p>It feels like I&rsquo;ve been making and playing video games all my life. It turns out I&rsquo;ve been playing board games even longer.</p>
<p>I&rsquo;ve always loved board games, but being an only child, it was always challenging to find people to play with. My dad was often willing to play, and I would often pull out <a href="http://www.boardgamegeek.com/boardgame/10293/en-busca-del-imperio-cobra">some of my favorites</a> when friends came over. But it never felt like I could get enough.</p>
<p>It was no big surprise then, that as soon as I saw games on a computer I fell in love heads over heels. My first thought was &ldquo;Wow! I can play games with the computer without having to depend on other people being here&rdquo;. Imagine that! It didn&rsquo;t matter that the games were uniformly horrible, hardly responsive, chunky, and monochrome. It was nirvana for me.</p>
<p>My second thought after seeing a video game was &ldquo;I want to make those!&rdquo; And that&rsquo;s what I&rsquo;ve been doing pretty much constantly since that day almost 30 years ago.</p>
<p>During that time board games took a back seat. My love was still there, but I was too busy with video games to consider them as serious entertainment. At times I&rsquo;m sure I even thought that video games were a step up from board games; the next logical step in evolution.</p>
<p>That phase of my life lasted until grad school. That&rsquo;s when a good friend of mine introduced me to this new little game that had just come out a couple of years before called Magic The Gathering. You&rsquo;d think that grad school wouldn&rsquo;t be the best time to get hooked on a game like that, and you&rsquo;d be right. It was an amazing ride for several years (from <a href="http://www.wizards.com/magic/tcg/productarticle.aspx?x=mtg/tcg/fallenempires/productinfo">Fallen Empires</a> until <a href="http://www.wizards.com/magic/tcg/productarticle.aspx?x=mtg/tcg/exodus/productinfo">Exodus</a> for those of you keeping track). I realized how much I loved the physical and social aspect of board and card games, and how it was mostly missing from video games. At the time I was playing a lot of Warcraft and Quake 1 online, but the experience was nothing like playing Magic across the table from another person.</p>
<p>After my Magic phase, I tried some of the flourishing &ldquo;euro&rdquo; games that were just coming out at the time, but I was mostly absorbed back in video games again. Steam and iOS were taking up all my gaming time for a few years.</p>
<p>Then, last year, everything changed. <a href="https://twitter.com/mysterycoconut">Miguel</a> came to visit with a car trunk full of board games. Literally! Not only did I have an absolute blast playing board games all week, but so did Amy, my wife. We were instantly hooked. Now all my gaming time is dedicated to board games, and I have hardly touched some kind of video game in the last year.</p>
<h2 id="why-i-love-board-games">Why I Love Board Games</h2>
<p>My love of board games comes from many different reasons.</p>
<p><strong>Physical aspect</strong>. I love the convenience of digital distribution of books, music, and video games. But at the same time, I&rsquo;m tired of manipulating pixels on the screen for all my activities (both work and entrainment). Touch screens are a small step in the right direction, but they still feel very artificial. When it comes down to it, nothing beats the feel of some wood pieces as you move them around the table. There are already too many screens and digital bits in my life.</p>
<p><img alt="Keyflower" loading="lazy" src="/board-games-my-new-old-love/images/keyflower.jpg"></p>
<p><strong>Social aspect</strong>. Video games are mostly solitary experiences. Even multiplayer games, you&rsquo;re usually not facing the people you play with, unless it&rsquo;s with one of my favorite patterns: local multiplayer games, which are not extremely popular (and it&rsquo;s hard to have the right people to play with around). On the other hand, most board games are inherently social. Not only I get to spend lots of extra time with my wife and friends, but I also get to meet lots of new people at conventions and game days.</p>
<p><strong>Variety of experiences</strong>. I didn&rsquo;t quite realize what a huge variety of experiences board games offer. Just a few games off the top of my head that offer a huge range of different experiences: <a href="http://www.boardgamegeek.com/boardgame/30549/pandemic">Pandemic</a>, <a href="http://www.boardgamegeek.com/boardgame/84876/the-castles-of-burgundy">Castles of Burgundy</a>, <a href="http://www.boardgamegeek.com/boardgame/113294/escape-the-curse-of-the-temple">Escape</a>, <a href="http://www.boardgamegeek.com/boardgame/3076/puerto-rico">Puerto Rico</a>, <a href="http://www.boardgamegeek.com/boardgame/21763/mr-jack">Mr. Jack</a>, <a href="http://www.boardgamegeek.com/boardgame/15987/arkham-horror">Arkham Horror</a>, or <a href="http://www.boardgamegeek.com/boardgame/39856/dixit">Dixit</a>. And that&rsquo;s only games in my collection, which is limited to my own tastes and doesn&rsquo;t include war games or much <a href="http://boardgamegeek.com/wiki/page/Ameritrash">Ameritrash</a>. Video games probably offer an even wider range of experiences because a computer can be so versatile, but the board game landscape feels more varied and healthy. That might be due to video games being mass market, while board games are still trying to get there. I suspect that&rsquo;s a topic for a future post.</p>
<p><img alt="Arkham horror intro" loading="lazy" src="/board-games-my-new-old-love/images/arkham-horror-intro.jpg"></p>
<p><strong>Learning new games</strong>. I love learning new games. You could even say I&rsquo;m addicted to it. I love to see how things fit together, how the game plays out, and trying to figure out a good strategy. Generally, I&rsquo;m much happier playing 20 new games 5 times than playing a single game 100 times. With video games, since the game is the running the simulation, not me, there&rsquo;s a lot less to learn. There&rsquo;s also something about tutorials that are an absolute chore and I dread learning a game through them.</p>
<p><strong>Replaying games</strong>. At the same time, I love replaying games I already know how to play. This is something that often doesn&rsquo;t happen with video games. A lot of them are intended to make more progress every time you play, culminating in some climax at the end, after 10-20 hours of play. After that, you can play it again, but I usually move on to some other game. One recent notable exception is one of my all-time favorite games: <a href="http://bindingofisaac.wikia.com/wiki/The_Binding_of_Isaac_Wiki">The Binding of Isaac</a>, which forces you to replay it over and over.</p>
<p><strong>They&rsquo;re for me</strong>. I feel I&rsquo;m squarely in the target audience for a good portion of board games being released. I&rsquo;m eagerly anticipating releases later on this year, and I can&rsquo;t wait to read about the new Essen announcements. Most video games, on the other hand, with a few notable exceptions, leave me completely cold appealing mostly to adolescent power fantasies. A quick glance at the top sellers on the App Store or even most console titles, and it&rsquo;s clear that I don&rsquo;t belong there.</p>
<p><img alt="Burgundy box" loading="lazy" src="/board-games-my-new-old-love/images/burgundy-box.jpg"></p>
<h2 id="fun-new-world">Fun New World</h2>
<p>I love the experience of taking a field I didn&rsquo;t know much about, and diving right in. I&rsquo;ve been fully immersing myself in the world of board games. Every day <a href="http://boardgamegeek.com/plays/bydate/user/llopis/subtype/boardgame">I play one or more board games</a>, and I go to a full-day gaming events once or twice a month. Sometimes it feels like drinking from the proverbial firehose. I&rsquo;m constantly learning about new gameplay mechanics, the art of finely balancing a game, game evolution and trends, or even the works of specific designers and how they changed over time.</p>
<p>During a period like this, I tend to grow creatively a huge amount. Being exposed to something new causes all sorts of new associations result in a constant stream of new ideas. Some of them are related directly to board games, but a lot of them spill over into video games and even other parts of my life.</p>
<p>So what&rsquo;s next for me? I&rsquo;m not giving up making video games any time soon, don&rsquo;t worry. I love making games in any format, and my goal is to continue making a living making games for different platforms. Board games are like another platform, but one with some strong challenges and constraints.</p>
<p>Of the video games I&rsquo;m working on, one of them has very heavy board game influences in its design. I have no doubt that it would be completely different had I not rediscovered board games recently. We&rsquo;re hoping to announce the game and talk more about it soon.</p>
<p>In addition to that, I&rsquo;m, of course, dabbling on the side with board game ideas. Unfortunately there&rsquo;s virtually no money in physical board games, so it&rsquo;s just purely a hobby, but it&rsquo;s a really fun one. And who knows, I might be able to make a digital version of one of those board games if I end up with a good design.</p>
<p>In the meanwhile, I expect to write quite a bit here about board games, and especially of the cross over between board and video games and what we can learn from each of them to make better games. You can also <a href="http://boardgamegeek.com/user/llopis">find me regularly on BGG</a>.</p>]]></content:encoded></item><item><title>Why Am I Making Games?</title><link>https://gamesfromwithin.com/why-am-i-making-games/</link><pubDate>Fri, 03 May 2013 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/why-am-i-making-games/</guid><description>&lt;p&gt;A couple of weeks ago I posted &lt;a href="https://gamesfromwithin.com/why-are-you-making-games/"&gt;my GDC micro-talk titled &lt;em&gt;Why are you making games?&lt;/em&gt;&lt;/a&gt;. From the feedback I got, it seems that it resonated with a lot of people, and it also made some people stop and ask themselves that question (along with a few sleepless nights).&lt;/p&gt;
&lt;p&gt;However, the question I was asked over and over was why am &lt;strong&gt;I&lt;/strong&gt; making games? What are my answers to that question? As I said before, there are no right or wrong answers. Everybody needs to find their own answers, so in that respect, my answers don&amp;rsquo;t really matter.&lt;/p&gt;
&lt;p&gt;On the other hand, since what I write here is purely personal, and a lot of people are curious about it, I figured I would give it a shot and answers those questions publicly.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A couple of weeks ago I posted <a href="/why-are-you-making-games/">my GDC micro-talk titled <em>Why are you making games?</em></a>. From the feedback I got, it seems that it resonated with a lot of people, and it also made some people stop and ask themselves that question (along with a few sleepless nights).</p>
<p>However, the question I was asked over and over was why am <strong>I</strong> making games? What are my answers to that question? As I said before, there are no right or wrong answers. Everybody needs to find their own answers, so in that respect, my answers don&rsquo;t really matter.</p>
<p>On the other hand, since what I write here is purely personal, and a lot of people are curious about it, I figured I would give it a shot and answers those questions publicly.</p>
<p>Another thing I also want to stress is that these are not even permanent answers for me. These are my answers for the projects I&rsquo;m working on right now. Whenever it&rsquo;s time to start a new project, I will ask myself this question again and probably come up with different answers. That, I think, it&rsquo;s key to be able to focus on some aspects at the expense of others, instead of always compromising and trying to achieve a bit of everything.</p>
<h2 id="why-i-am-not-making-games">Why I Am Not Making Games</h2>
<p>You thought I was going to get right away to the reasons why I was making games? No, it&rsquo;s not that easy. I need to start with the reasons I thought I was making games, but turns out I discarded (for this time around).</p>
<h3 id="innovationawards">Innovation/awards</h3>
<p>I&rsquo;ve always felt an urge to innovate and create something original. Something that would be worthy of getting some awards and recognition. Even back in the <a href="/tag/power-of-two/">Power of Two Games days</a>, <a href="https://twitter.com/c_nich">Charles</a> and I (half) joked that if we won an IGF award, we would eat a whole cheesecake from <a href="http://www.estreetcafe.com">E Street</a>. Unfortunately (or fortunately, depending from your point of view), that never happened, and the cheesecake remained safe behind the glass. Flower Garden was pretty innovative (even to this day, there aren&rsquo;t many similar games&ndash;if you can even call it a game). Casey&rsquo;s Contraptions had some original aspects, but its main strength was in polish of execution.</p>
<p><img alt="Cheesecake" loading="lazy" src="/why-am-i-making-games/images/cheesecake.jpg"></p>
<p>For this time around, I decided that this was not going to be one of the main reasons behind me making games though. I&rsquo;m sure I&rsquo;ll come back to this one very soon though.</p>
<h3 id="money">Money</h3>
<p>It&rsquo;s hard not to think about money when one of your main target platforms is iOS. I know they&rsquo;re mostly the exception, but looking at the huge financial success of some indie developers, or the revenue of some of the games on the Top Grossing chart, it&rsquo;s only natural to want a slice of that pie.</p>
<p>Since free-to-play is one of the most profitable approaches on the App Store, I originally started out some of my designs by trying to do &ldquo;free-to-play done right&rdquo;. I was going to show the world how you can make a free-to-play game, treat players as human beings, not play any psychological tricks, not make the game suck on purpose, and still make a boatload of money.</p>
<p><img alt="Wq money woman" loading="lazy" src="/why-am-i-making-games/images/wq-money-woman.jpg"></p>
<p>Along the way, two things happened:</p>
<ol>
<li>It&rsquo;s a lot harder to design a game that does all those things than to write it out in a neat, little sentence like I just did.</li>
<li><a href="https://twitter.com/checker">Chris</a> called me on it. He asked the really pointed question of &ldquo;if you don&rsquo;t need the money, why focus your design around that idea when there are so many interesting design aspects out there to explore?&rdquo; He was totally right! At this moment, I don&rsquo;t have the financial pressure to ship a game, so why limit my game artificially like this?</li>
</ol>
<p>Those two things, combined with the fact that I hate most games in the Top Grossing chart of the App Store, means that I should not even try making a game aimed at that audience.</p>
<p>Since money eventually runs out, I will have to consider money more seriously in future projects. Even so, I will probably go the route of making more personal, niche games that appeal to a small percentage of people, rather than try to go after a pure mass-market approach.</p>
<h3 id="expressing-something">Expressing something</h3>
<p>I fall in the camp of people who believe that games are (or can be) art. That&rsquo;s especially true of indie games, which carry the strong creative touch of an individual or a small team. Starting from something you want to express. For this one time, I was going to put that aside and focus on other aspects.</p>
<h2 id="why-i-am-making-games">Why I Am Making Games</h2>
<p>After removing all those reasons (and lots more that I didn&rsquo;t talk about), why am I making games? Or rather, why am I making the games I&rsquo;m currently making? It turns out, the reasons for these game are mostly selfish.</p>
<h3 id="enjoy-the-development">Enjoy the development</h3>
<p>I wanted to make a game where I would enjoy the actual development as much as possible. This is a lot more constrictive than it may seem at first glance, and it means many things:</p>
<ul>
<li>I wanted to avoid games with large components that are uninteresting to design and implement (in-game stores, credits, managing users, etc).</li>
<li>I need to be exploring new concepts (to me) and trying new things to really enjoy the development process, so the game needs to be substantially different from other games that I made in the past: no growing virtual plants, or creating physics puzzles to share with friends.</li>
<li>The focus of the game should be on the design itself, not some technology. Even though most of my past experience comes from programming, I&rsquo;m only interested in design these days. Programming is just a means to quickly convert my ideas into something the computer can do, but I&rsquo;m not interested in programming for the sake of programming (as anyone who looks at my code can attest to).</li>
</ul>
<h3 id="create-something-ill-be-proud-of-afterwards">Create something I&rsquo;ll be proud of afterwards</h3>
<p>This is an easy one. It doesn&rsquo;t matter how much money the game makes, but I wanted it to be something I can be proud of afterwards. Interestingly, the &ldquo;innovation/awards&rdquo; point is a subset of this reason, but this point is more general, and I can be proud of the games I make for many reasons.</p>
<p>You would think that this point should go without saying, and nobody should be making games they&rsquo;re not proud of. Unfortunately, just a glance at the App Store will quickly convince anyone that&rsquo;s not the case.</p>
<h3 id="one-more-thingâ">One more thingâ€¦</h3>
<p>Indie game development can be a pretty solitaire affair, but that&rsquo;s not something that bothered me too much (maybe growing up an only child had something to do with that). I never needed someone else to keep me motivated in or committed to a project.</p>
<p>I am currently working on not one, but two different projects at once. Soon I&rsquo;ll be able to start talking about them in detail. Both of those projects are collaborations with other people. After working on them for a few months, I have come to realize that working with the right people can be really invigorating: Bouncing ideas back and forth and see them grow into something bigger than they started, or just pushing and motivating each other has become completely invaluable for me. I&rsquo;m hoping to be able to continue working and collaborating with amazing people in my future projects.</p>]]></content:encoded></item><item><title>Why Are You Making Games?</title><link>https://gamesfromwithin.com/why-are-you-making-games/</link><pubDate>Mon, 01 Apr 2013 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/why-are-you-making-games/</guid><description>&lt;p&gt;&lt;em&gt;This is a written version of my 5-minute talk from the Indie Soapbox session at this year&amp;rsquo;s GDC.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Why are you making games? No, I don&amp;rsquo;t mean &amp;ldquo;why are &lt;em&gt;you&lt;/em&gt; making games?&amp;rdquo;. Also, I don&amp;rsquo;t mean &amp;ldquo;why are you making &lt;em&gt;games&lt;/em&gt;?&amp;rdquo;. And I certainly don&amp;rsquo;t mean &amp;ldquo;&lt;em&gt;why (on earth)&lt;/em&gt; are you making games?&amp;rdquo;. I mean the question in the purest, most abstract sense. Just &amp;ldquo;why are you making games?&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;This was a key question for me last year, I spent a lot of time thinking about it, and I thought other people might benefit from asking themselves the same question. To see where I&amp;rsquo;m coming from, let&amp;rsquo;s do a quick flash back.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s late 2011. Miguel and I finished working on Casey&amp;rsquo;s Contraptions and my daughter was born. I took a couple months completely off from work (new dads will understand why), and then, right at the turn of the new year, I decided to start working again. The plan was to prototype a few of the juiciest ideas, pick one that really stood out, and make a new game in a few months. How hard could it be, right?&lt;/p&gt;
&lt;p&gt;Right?&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>This is a written version of my 5-minute talk from the Indie Soapbox session at this year&rsquo;s GDC.</em></p>
<p>Why are you making games? No, I don&rsquo;t mean &ldquo;why are <em>you</em> making games?&rdquo;. Also, I don&rsquo;t mean &ldquo;why are you making <em>games</em>?&rdquo;. And I certainly don&rsquo;t mean &ldquo;<em>why (on earth)</em> are you making games?&rdquo;. I mean the question in the purest, most abstract sense. Just &ldquo;why are you making games?&rdquo;.</p>
<p>This was a key question for me last year, I spent a lot of time thinking about it, and I thought other people might benefit from asking themselves the same question. To see where I&rsquo;m coming from, let&rsquo;s do a quick flash back.</p>
<p>It&rsquo;s late 2011. Miguel and I finished working on Casey&rsquo;s Contraptions and my daughter was born. I took a couple months completely off from work (new dads will understand why), and then, right at the turn of the new year, I decided to start working again. The plan was to prototype a few of the juiciest ideas, pick one that really stood out, and make a new game in a few months. How hard could it be, right?</p>
<p>Right?</p>
<p>It turns out it was a lot harder than I ever imagined. I was confident in my list of hundreds of game ideas that I had been adding to over the years. I picked one idea, made a quick prototype in a day or two, and decided that I wasn&rsquo;t as excited about that idea as I thought. So I picked another one, and another prototype that didn&rsquo;t go anywhere. Then another, then another, and then another. This went on for months.</p>
<p>By the time I realized that my prototype icons weren&rsquo;t fitting in a single page on my development iPad, I started worrying that something was wrong. Prototyping is great, it allows you to find the truly great ideas and all of that, but I wasn&rsquo;t any closer to a game idea I wanted to make than when I started.</p>
<p><img alt="Prototypes" loading="lazy" src="/why-are-you-making-games/images/prototypes.jpg"></p>
<p>At this point, I even started prototyping game ideas I knew I was <em>not</em> going to make, just to remove any pressure on me, as well as to get it out of my system how much I hated those game genres. It was an interesting effort, but, as you can imagine, it didn&rsquo;t lead to any shipped games.</p>
<p>I did, however, help me start figuring out what was going on. I realized that the prototypes I was creating were dissatisfying because my intentions were unclear. I wanted too many conflicting things out of this next game, and that was pulling the game in all kinds of opposite directions.</p>
<p>I wanted to make a unique a different game, yet at the same time I wanted it to reach a huge audience. I wanted to ride the wave of financially successful iOS games, but I didn&rsquo;t want to sell my soul with freemium-based games, and instead, I was going to make a &ldquo;good&rdquo; freemium game. I wanted to make something innovative, but I wanted to do it in just 6-9 months. I wanted it all, and I wanted it yesterday. Bad combination.</p>
<p>That&rsquo;s when I sat down and asked myself point blank &ldquo;why am I making games?&rdquo;. Or at least the more concrete version &ldquo;why am I making my next game?&rdquo;. That&rsquo;s a surprisingly hard question to answer really honestly. I had to peel away a bunch of layers until I found the answers to my question.</p>
<p>My specific answers don&rsquo;t matter because there isn&rsquo;t a right and wrong answer. Any answer is good as long as it&rsquo;s honest, from the bottom of your heart. There are as many valid answers as game developers out there. Some people make games because they want to be famous, others because they want to make money, others because it&rsquo;s the only thing they know how to do, others because they want to win awards, others because they want to reach as many people as possible, others because they want to tell stories, etc, etc.</p>
<p>It&rsquo;s actually amazing it took me this long to ask and confront this question. When you&rsquo;re working on a game company things are different, and you don&rsquo;t need to do that level of introspection. But once you go indie, it becomes really important. Even though I&rsquo;ve now been indie for 6 years, I&rsquo;ve been going in automatic pilot all this time, kind of skirting around this issue and winging it. I see a lot of indie developers out there doing the same thing, with greater or lesser success, but still conflicted internally about what they&rsquo;re doing.</p>
<p>Once you have the answer to your question, you can use it to guide you in any big decisions related to game development, and even in life in general. Which projects to tackle, or even what features to add to your game, will often be easy to decide if you keep your goals in mind.</p>
<p>For me, within two weeks of answering the question, I had settled on not just one, but two different projects that I was super-excited about. Both projects are still moving along and I hope to start sharing information about them soon.</p>
<p>So I encourage anybody reading this to make some quiet time in the next few days, and pose yourself the question &ldquo;why am I making games&rdquo;. Once you find your answer, not only will it help you with future decisions, but it will make you more satisfied with them.</p>]]></content:encoded></item><item><title>Porting My Game Code To Mac OS</title><link>https://gamesfromwithin.com/porting-my-game-code-to-mac-os/</link><pubDate>Thu, 05 Jul 2012 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/porting-my-game-code-to-mac-os/</guid><description>&lt;p&gt;I&amp;rsquo;m still working on prototypes. I&amp;rsquo;ve spent the last six months going through different game ideas and working on prototype after prototype. Along the way I&amp;rsquo;ve made over 20 different prototypes on iPad or iPhone. I&amp;rsquo;m sure a lot of those prototypes would have made decent iOS games, but I wasn&amp;rsquo;t particularly excited to develop them all the way and take them to completion. I&amp;rsquo;m looking for something that&amp;rsquo;s both very interesting to develop and something I can proudly point to after it ships.&lt;/p&gt;
&lt;p&gt;Right now I have a couple of game ideas in hand that I&amp;rsquo;m pretty excited about. I prototyped one of those, but I quickly realized it might be a game better suited for desktops rather than iOS, so I decided to write my next prototype for that game on the Mac. Maybe another day I&amp;rsquo;ll write a post about prototypes, but what I want to write about today is my experience moving over my prototyping code to the Mac.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;m still working on prototypes. I&rsquo;ve spent the last six months going through different game ideas and working on prototype after prototype. Along the way I&rsquo;ve made over 20 different prototypes on iPad or iPhone. I&rsquo;m sure a lot of those prototypes would have made decent iOS games, but I wasn&rsquo;t particularly excited to develop them all the way and take them to completion. I&rsquo;m looking for something that&rsquo;s both very interesting to develop and something I can proudly point to after it ships.</p>
<p>Right now I have a couple of game ideas in hand that I&rsquo;m pretty excited about. I prototyped one of those, but I quickly realized it might be a game better suited for desktops rather than iOS, so I decided to write my next prototype for that game on the Mac. Maybe another day I&rsquo;ll write a post about prototypes, but what I want to write about today is my experience moving over my prototyping code to the Mac.</p>
<p>I&rsquo;ve been working on MacOS since 2007, when I switched because of iPhone development. <a href="/quick-notes-on-lion/">For the most part</a>, I&rsquo;ve been loving it as an OS, but I never actually targeted it as a platform in my development. I figured it wouldn&rsquo;t be very hard at all to compile my simple C/C++ + OpenGL code that I use as the basis for all my iOS games on MacOS. After all, that code started on Windows and DirectX, and porting it to iOS was pretty quick and easy. On top of that, I can use Xcode 4 for Mac, just like iOS (<a href="/xcode-4-trials-and-tribulations/">I&rsquo;m not sure that counts as a plus</a> though). How card can it possibly be?</p>
<p>The answer is, not hard at all, as long as you&rsquo;re aware of a couple gotchas along the way.</p>
<h2 id="xcode-project">Xcode project</h2>
<p>I figured I would start from scratch, so I created a new Xcode project targeting MacOS. First surprise was that, unlike iOS, there wasn&rsquo;t a template to create an OpenGL application. Instead, I need to create an empty Cocoa application and set things up by myself. No big deal.</p>
<p>I used the <a href="https://developer.apple.com/devcenter/mac/resources/opengl/">samples from Apple</a> to get me started. I could have grabbed those and started adding stuff, but for some reason they have all the logic built into the OpenGL views, and I like to keep my views as simple as possible: they hold the surface to render, and they collect input and other window events. Done. So I had to do some moving around of code and responsibilities, which at the same time allowed me to make it more like the structure I used on iOS.</p>
<p>The AppDelegate does most of the initialization and creation on applicationDidFinishLaunching, and the OpenGL view gets created through the minimal nib file (with just a menu, window, and a view). AppDelegate is also responsible for setting up the display link callback, and then all the rest of the execution happens in my own code, away from those classes.</p>
<p>That was all pretty smooth. The only weird gotcha I ran into is that, unlike with previous Xcode 4 projects on iOS, I was no able to add any files to it that were not under the project root. They would turn red and not be available in the project. I tried adding them in every possible way and always got the same result. So, in the end, I gave in and just moved my External dir under the same directory as the Xcode project. Some people on Twitter had the same experience, while others didn&rsquo;t, so there&rsquo;s something fishy going on in there.</p>
<p>I have all my game static libraries (I refuse to call it an &ldquo;engine&rdquo;) as a separate Xcode project. I was able to add the project to the workspace and just change the target to be MacOS, and everything worked without a hitch.</p>
<h2 id="opengl">OpenGL</h2>
<p>I knew I was going to have to make some changes to the graphics code because all my iOS code uses OpenGL ES 2.0, and the Mac supports OpenGL &ldquo;non ES&rdquo; version. But I never did any graphics programming on the Mac, so I had no idea what to expect.</p>
<p>I decided to start with <a href="http://developer.apple.com/library/mac/#samplecode/GLEssentials/Introduction/Intro.html">this sample code</a> from Apple. After all, it seemed to be exactly what I was looking for: A simple project that sets up OpenGL both on iOS and MacOS. Score!</p>
<p>Once I started digging into it, I realized that it wasn&rsquo;t going to be as straightforward as I realized. It turns out there were lots and lots of differences between OpenGL ES 2.0 and the OpenGL version on the Mac. Some were easy to catch, like different syntax for the shaders (&ldquo;varying&rdquo; became &ldquo;in&rdquo;, &ldquo;uniform&rdquo; was &ldquo;out&rdquo;, etc). Some were a pain to track down (needed to bind some Vertex Array Objects, and I was forced to use Vertex Buffers).</p>
<p>The documentation wasn&rsquo;t clear on this point at all, but fortunately I got some good tips from Twitter. It turns out that the sample I used as a starting point created an OpenGL 3.2 context, and OpenGL 3.2 is very different from OpenGL ES 2.0.</p>
<pre tabindex="0"><code>	NSOpenGLPixelFormatAttribute attrs[] =
	{
		NSOpenGLPFADoubleBuffer,
		NSOpenGLPFADepthSize, 24,
		NSOpenGLPFAOpenGLProfile,
		NSOpenGLProfileVersion3_2Core,
		0
	};

	NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
	NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil];
	int swapInt = 1;
	[context setValues:&amp;swapInt forParameter:NSOpenGLCPSwapInterval];
</code></pre><p>It turns out that leaving out the last attribute (NSOpenGLPFAOpenGLProfile) creates an OpenGL 2.1 profile, which is very similar to OpenGL ES 2.0 (GLSL 1.2 is the shader version that OpenGL 2.1 uses and that&rsquo;s also very similar to GLSL ES). With that change, all the OpenGL code worked perfectly, with the only exception of the precision modifiers in shaders. Fortunately, I we can wrap those up in a simple #ifdef like this</p>
<pre tabindex="0"><code>#ifdef GL_ES
precision lowp float;
#endif
</code></pre><h2 id="unit-tests">Unit tests</h2>
<p>Apart from input, which will require a total re-work, the last major thing I had left was running unit tests after each build. I&rsquo;ve seen references to Xcode&rsquo;s unit testing functionality, but I was hoping to reuse <a href="http://code.google.com/p/unittestpp/">UnitTest++</a> and run it like I do on iOS projects. It turns out it was even easier because you can run them natively without the extra step of the simulator like on iOS projects.</p>
<p>All I had to do was create a new phase in the Debug scheme to run a script. The &ldquo;script&rdquo; is just the name of the executable that was just build with the -unittest parameter added to it. I suspect that there&rsquo;s probably a &ldquo;better&rdquo; way than hardcoding the .app/Contents/MacOS/ string in the middle to find the binary itself, so if someone knows the correct variable that includes that, let me know.</p>
<p><img alt="UnitTests" loading="lazy" src="/porting-my-game-code-to-mac-os/images/UnitTests.png"></p>
<p>The only other thing that came up is that apparently Xcode adds the parameter -NSDocumentRevisionsDebugMode when you debug it from the IDE. No big deal, unless you have your program exit with an error if you pass an unrecognized parameter. I just made it accept and ignore that parameter, and everything worked like a charm.</p>
<h2 id="conclusion">Conclusion</h2>
<p>It took a bit longer than I expected, but I finally have my code base running on MacOS. Iteration time is faster because it doesn&rsquo;t even launch the simulator, and I suspect graphics performance will also be a lot faster (the iOS simulator does all the graphics processing in software), so I might end up doing more prototyping on the Mac unless the touch input is an integral part of the game.</p>]]></content:encoded></item><item><title>What The Rovio Deal With Casey's Contraptions Means To Me</title><link>https://gamesfromwithin.com/what-the-rovio-deal-with-caseys-contraptions-means-to-me/</link><pubDate>Fri, 11 May 2012 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/what-the-rovio-deal-with-caseys-contraptions-means-to-me/</guid><description>&lt;p&gt;&lt;img alt="CaseysContraptionsIcon" loading="lazy" src="https://gamesfromwithin.com/what-the-rovio-deal-with-caseys-contraptions-means-to-me/images/CaseysContraptionsIcon.png"&gt;I imagine everybody reading this already knows that &lt;a href="http://www.gamasutra.com/view/news/170084/Rovio_confirms_acquisition_of_Caseys_Contraptions_IP.php"&gt;we sold the Casey&amp;rsquo;s Contraptions game and IP to Rovio&lt;/a&gt;. They&amp;rsquo;ll be relaunching the game as &lt;a href="http://amazingalex.com/"&gt;Amazing Alex&lt;/a&gt; for iOS and other platforms soon, and putting all the Rovio marketing might behind it. Exciting times ahead for Casey!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been receiving a lot of questions about how it happened, how&amp;rsquo;s affecting me, and what my plans for the future are. So here&amp;rsquo;s my attempt to answer some of those questions.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="CaseysContraptionsIcon" loading="lazy" src="/what-the-rovio-deal-with-caseys-contraptions-means-to-me/images/CaseysContraptionsIcon.png">I imagine everybody reading this already knows that <a href="http://www.gamasutra.com/view/news/170084/Rovio_confirms_acquisition_of_Caseys_Contraptions_IP.php">we sold the Casey&rsquo;s Contraptions game and IP to Rovio</a>. They&rsquo;ll be relaunching the game as <a href="http://amazingalex.com/">Amazing Alex</a> for iOS and other platforms soon, and putting all the Rovio marketing might behind it. Exciting times ahead for Casey!</p>
<p>I&rsquo;ve been receiving a lot of questions about how it happened, how&rsquo;s affecting me, and what my plans for the future are. So here&rsquo;s my attempt to answer some of those questions.</p>
<h3 id="the-game">The Game</h3>
<p>It might come as a surprise to a lot of people, but selling Casey&rsquo;s Contraptions was never in our minds. <a href="https://twitter.com/#!/mysterycoconut">Miguel</a> and I put all our energy into making a great game and infusing it with lots of personality. Half way through development we realized we had something special in hand, and when Apple selected it as the iPad game of the week and the reviews and comments came pouring in, we knew the game had connected with a lot of people. We were thrilled.</p>
<p>We were in for a big surprise when sometime after the iPad release, Rovio approached us and offered to buy Casey&rsquo;s Contraptions. We were understandably very attached to the game we had just released, but Rovio eventually made us an offer we couldn&rsquo;t refuse.</p>
<p>Rovio is one of the biggest players in the mobile market, and sometimes people get tired of seeing the top 10 charts full of Angry Birds. I&rsquo;ve always had a lot of respect for them: Angry Birds wasn&rsquo;t just a fluke, it&rsquo;s a super approachable game, perfectly suited for mobile phones, and crafted to perfection. They deserve all the success they got. I don&rsquo;t think I would have agreed to sell Casey&rsquo;s Contraptions to most of the other big game companies.</p>
<p>As the co-creator of Casey&rsquo;s Contraptions, I&rsquo;m super excited to see it reach a much wider audience we could have ever dreamed of reaching ourselves. Every developer&rsquo;s dream is to see people playing your games, and Rovio can make that happen with their huge marketing power and influence. Just look at all the media sites covering the news for the Amazing Alex announcement (most of those sites never talked about Casey&rsquo;s Contraptions at launch :-)).</p>
<p>Miguel and I chose not to be involved in future development of Casey&rsquo;s Contraptions/Amazing Alex. As an indie developer, your time is the most limited and precious resource. Every game you release takes some of that time away even after it launches: new content, higher-resolution graphics, fixing problems with the latest OS version, porting to other platforms, etc. This was a great opportunity to pass the baton to Rovio and be able to focus 100% on new creative projects.</p>
<p>Yes, it&rsquo;s hard to let go. Not like I have experienced that yet, but it probably feels like sending your kid to college, knowing that he&rsquo;s starting a new life without you. At least we can rest easier knowing Casey is in good hands. Whenever Amazing Alex becomes a worldwide hit, we can proudly point to that and say we started that game.</p>
<p><img alt="Cc" loading="lazy" src="/what-the-rovio-deal-with-caseys-contraptions-means-to-me/images/cc.jpg"></p>
<h3 id="personal-life">Personal life</h3>
<p>On a personal level, my life hasn&rsquo;t changed at all. <a href="http://www.snappytouch.com/flowergarden">Flower Garden</a> has been doing a good job at keeping my family fed for the last few years, so getting more money doesn&rsquo;t have a huge impact. This unexpected deal bumped up those numbers in the bank, but hasn&rsquo;t otherwise changed much for me. No Ferraris in the garage, or even, for those who know me, no fancy new road bikes (still riding my trusty 12-year old Trek 5200). The only splurge was <a href="/big-displays-the-good-the-shiny-and-the-ugly/">buying a 30&quot; Apple Cinema Display</a>.</p>
<p>The deal has, however, definitely affected my future projects. At one level, it means I don&rsquo;t have to worry about funding for my next few games, which is great. Both Flower Garden and Casey&rsquo;s Contraptions were done on a minimal budget. Now I can afford to spend more money in areas where it can make a difference, and be able to offer people money up front instead of just some percent of royalties.</p>
<p>One thing I never want to do is have full time employees though. Full time employees bring constant burn rate, and start adding a sense of pressure I do not want. One of the best things about being indie is the flexibility that it brings. Collaborations with other indies have worked really well so far, and I&rsquo;ll continue to do that as much as possible for future projects.</p>
<p>The other way the deal has affected my future projects is that there will be more pressure to follow up Casey&rsquo;s Contraptions with a great game. Even though Casey&rsquo;s Contraptions is the same it was a few months ago, the fact that it was bought by Rovio will make a lot of people take notice and compare it to any of my future games.</p>
<p>I&rsquo;ve already been struggling with those effects for several months. I&rsquo;ve been making and discarding prototype after prototype. More than half of those would have made for fine games, but I have no desire to release a &ldquo;just OK&rdquo; game for the sake of releasing something. I&rsquo;ve also decided that I&rsquo;m not even going to consider potential for financial success for my next game. It&rsquo;s not going to be aimed at the mass market, it&rsquo;s not going to be full of zombies, and it&rsquo;s certainly not going to be a typical freemium game.</p>
<p>Whatever my next game is, it&rsquo;s going to be a more personal, more niche game. Something that I can be really excited about working for however many months it takes, and something I can be really proud of after launch.</p>
<p>Bye, bye Casey! We&rsquo;ll miss you, but we can&rsquo;t wait to see what you do out there!</p>]]></content:encoded></item><item><title>Office Space</title><link>https://gamesfromwithin.com/office-space/</link><pubDate>Mon, 16 Jan 2012 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/office-space/</guid><description>&lt;p&gt;Those who put up with my incessant chatter (or rants, depending how long I&amp;rsquo;ve gone without a run) &lt;a href="https://twitter.com/#!/noel_llopis"&gt;on Twitter&lt;/a&gt;, know that I recently moved out of my home office and leased an office &lt;a href="http://maps.google.com/maps?q=carlsbad,+ca&amp;amp;hl=en&amp;amp;sll=33.158093,-117.350594&amp;amp;sspn=0.481134,0.737457&amp;amp;vpsrc=0&amp;amp;hnear=Carlsbad,+San+Diego,+California&amp;amp;t=m&amp;amp;z=12"&gt;in town&lt;/a&gt;. This change was mostly due to my wife and I having a baby daughter a few months ago. I&amp;rsquo;ve taken most of this time as an extended paternity leave, but when it was time to do some work again, it was clear that working from home wasn&amp;rsquo;t the ideal environment anymore.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Those who put up with my incessant chatter (or rants, depending how long I&rsquo;ve gone without a run) <a href="https://twitter.com/#!/noel_llopis">on Twitter</a>, know that I recently moved out of my home office and leased an office <a href="http://maps.google.com/maps?q=carlsbad,+ca&amp;hl=en&amp;sll=33.158093,-117.350594&amp;sspn=0.481134,0.737457&amp;vpsrc=0&amp;hnear=Carlsbad,+San+Diego,+California&amp;t=m&amp;z=12">in town</a>. This change was mostly due to my wife and I having a baby daughter a few months ago. I&rsquo;ve taken most of this time as an extended paternity leave, but when it was time to do some work again, it was clear that working from home wasn&rsquo;t the ideal environment anymore.</p>
<p>Having a separate office not only gives me the distraction- and interruption-free environment I need, but also gives me some much-needed separation between home and work. My office is about a mile away from home, so that makes for a very nice 15-minute walking commute (with the Macbook Pro in my backpack). It&rsquo;s also located right in the Carlsbad village, so it&rsquo;s a block or two away from tons of cool places to have lunch, grab a coffee, or even go to the beach for a quick break!</p>
<p>Here are a few pictures from the new office. Things aren&rsquo;t completely set up yet (that bare wall is waiting for some Flower Garden and Casey&rsquo;s Contraptions posters that should be arriving today).</p>
<p><img alt="CRW 5052" loading="lazy" src="/office-space/images/CRW_5052.jpg"></p>
<p><img alt="CRW 5056" loading="lazy" src="/office-space/images/CRW_5056.jpg"></p>
<p><img alt="CRW 5059" loading="lazy" src="/office-space/images/CRW_5059.jpg"></p>
<p><img alt="CRW 5055" loading="lazy" src="/office-space/images/CRW_5055.jpg"></p>
<p>The thing I like the most about this office is the light. It&rsquo;s a corner office and it&rsquo;s aiming north, so that means great, indirect light all day long. Oh, and the windows can be opened to let some fresh air in. That might seem like an odd detail to mention to some of you, but you&rsquo;d be surprised how many office buildings in the US have windows that can&rsquo;t be opened. Really.</p>
<p>Both desks are adjustable, standing desks. The main desk in the pictures is the <a href="http://www.geekdesk.com/">large frame GeekDesk</a> one. I used to have the small frame because I didn&rsquo;t have the room at home, but I love the extra space, especially with the <a href="/big-displays-the-good-the-shiny-and-the-ugly/">30&quot; display</a>! I&rsquo;ve kept the small desk to the side, that way I can invite other people to come work from here for the day (indie work day!) or even (gasp) hire someone if the right time comes.</p>
<p>The rest is pretty standard: whiteboard (I prefer use one much larger, but that&rsquo;s what I had around), bouncy ball (gotta have a bouncy ball!), and couch (pretty important to unwind, or just to take a break from standing all day).</p>
<p>So far, I&rsquo;m very happy with this setup. Working from here is definitely invigorating, and the separation between work and home helps a lot in both locations. Maybe once our daughter is older and going to school I&rsquo;ll consider working from home again, but this is perfect for now.</p>
<p>What does your work setup look like? Post some pictures and let me know. I love seeing other devs work setups.</p>]]></content:encoded></item><item><title>Quick Tip: Working With Shaders On iOS</title><link>https://gamesfromwithin.com/quick-tip-working-with-shaders-on-ios/</link><pubDate>Fri, 06 Jan 2012 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/quick-tip-working-with-shaders-on-ios/</guid><description>&lt;p&gt;I&amp;rsquo;m taking a couple of days to upgrade some of my libraries for doing prototyping both in 2D and 3D. One of the many overdue things I wanted to do, was to finally ditch OpenGL ES 1.1 and move to 2.0 exclusively. Yes, even if you&amp;rsquo;re only doing a 2D game, OpenGL ES 2.0 is way worth it.&lt;/p&gt;
&lt;p&gt;There were even a couple of cases during Casey&amp;rsquo;s Contraptions that we wanted a particular effect, and couldn&amp;rsquo;t get it quite right, but it would have been trivial to whip up a shader if we had been using OpenGL ES 2.0. In the end, we had to resort to &lt;a href="https://gamesfromwithin.com/customizable-color-sections-with-opengl-es-1-1/"&gt;texture combiners&lt;/a&gt; (yuck), and it wasn&amp;rsquo;t exactly what we had in mind.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;m taking a couple of days to upgrade some of my libraries for doing prototyping both in 2D and 3D. One of the many overdue things I wanted to do, was to finally ditch OpenGL ES 1.1 and move to 2.0 exclusively. Yes, even if you&rsquo;re only doing a 2D game, OpenGL ES 2.0 is way worth it.</p>
<p>There were even a couple of cases during Casey&rsquo;s Contraptions that we wanted a particular effect, and couldn&rsquo;t get it quite right, but it would have been trivial to whip up a shader if we had been using OpenGL ES 2.0. In the end, we had to resort to <a href="/customizable-color-sections-with-opengl-es-1-1/">texture combiners</a> (yuck), and it wasn&rsquo;t exactly what we had in mind.</p>
<p>OpenGL ES 2.0 requires that you write shaders for any different kind of &ldquo;thing&rdquo; you render, whether it&rsquo;s a simple 2D quad, or a fancy skinned character. I wanted to provide at least a basic 2D rendering shader in my graphics library, but the workflow was a bit awkward.</p>
<p>First of all, shaders on iOS are compiled at runtime <a href="#1">[1]</a>, so we need to access the shader source and compile it. Initially I was thinking of having the shader source files as text in the graphics library, but for the game to access those files, it would have to explicitly add them to its resources so they can be copied during the build phase. That&rsquo;s error prone (I would always forget to do that with every new project) and just plain ugly.</p>
<p>Another possibility would be to include the source text as a string in the library. That would simplify things, but it would mean that:</p>
<ol>
<li>You would lose shader syntax highlighting.</li>
<li>You would need to have the annoying \ at the end of every line.</li>
</ol>
<p>After <a href="https://twitter.com/#!/noel_llopis/status/155072436113649665">asking on Twitter and getting some good suggestions</a>, I decided the easiest way would be to use <a href="http://linuxcommand.org/man_pages/xxd1.html">xxd</a>. It&rsquo;s a shell tool that comes preinstalled in all Macs (and Linux) that takes a file and converts it into a C array that can be included in a program directly.</p>
<p>I liked xxd even better than the old standby of <a href="http://wiki.wxwidgets.org/Embedding_PNG_Images-Bin2c_In_Python">bin2c</a> because it already comes installed, and it generates the whole file, not just an array that then needs to be included from another file. Yes, it would be easy enough to modify, but why bother when you have a perfect tool for the job already?</p>
<p>Now, I can set up a custom rule in Xcode 4 like this:</p>
<p><img alt="Custom rule" loading="lazy" src="/quick-tip-working-with-shaders-on-ios/images/custom_rule1.png"></p>
<p><strong>Update:</strong> The array generated by xxd isn&rsquo;t null-terminated, so we need to add a zero to the array. The easiest way is to use sed. Thanks to <a href="http://twitter.com/#!/SixEchoStudios">SixEcho Studios</a> for the heads up. Also, I updated it to use the varaibles INPUT_FILE_DIR and INPUT_FILE_NAME thanks to <a href="http://twitter.com/#!/mysterycoconut">Miguel&rsquo;s</a> comments.</p>
<p>Now, whenever the shader source changes, it generates a header file like this:</p>
<pre tabindex="0"><code>unsigned char PassThrough_fsh[] = {
  0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x6f,
  0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x44, 0x65, 0x73, 0x74,
  0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
  0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e,
  0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f,
  0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20,
  0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43,
  0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d
,0x00};
unsigned int PassThrough_fsh_len = 91;
</code></pre><p>To compile that shader in the game, all I have to add is two lines:</p>
<pre tabindex="0"><code>#include 
//...
const int fs = ShaderUtils::CompileShader(PassThrough_fsh, GL_FRAGMENT_SHADER);
</code></pre><p>Done! Clean, simple, and minimal cruft.</p>
<p><strong>Update:</strong> I haven&rsquo;t tried it yet because I haven&rsquo;t had the need for any expensive shaders, but I hear really good things about Aras PranckeviÄius GLSL optimizer. In that case, I would add it before the xxd step. You would still use the shader the same way, but it would be optimized and perform faster.</p>
<p>[1] That&rsquo;s a huge mistake and I hope Apple fixes that ASAP. <a href="https://github.com/aras-p/glsl-load-speed">Loading times for any amount of non-trivial shaders adds up really quickly</a>. That&rsquo;s the last thing you want on a mobile device! The OpenGL ES 2.0 standard provides an optional way to load binary shaders, and all that Apple has to do is provide a tool that will compile shaders for the iOS hardware. To be completely future-proof, you they can even mandate that if the binary load fails, you still need to compile from source.</p>]]></content:encoded></item><item><title>Big Displays: The Good, The Shiny, and The Ugly</title><link>https://gamesfromwithin.com/big-displays-the-good-the-shiny-and-the-ugly/</link><pubDate>Fri, 23 Dec 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/big-displays-the-good-the-shiny-and-the-ugly/</guid><description>&lt;p&gt;I remember back in the mid-90s, I went through 5 or 6 19&amp;quot; CRT monitors before I found one that I thought was acceptable running at 1600x1200. I believe it was a Samsung and it even needed BNC cables to get the signal without interference and degradation to get the quality I wanted.&lt;/p&gt;
&lt;p&gt;Fortunately, display technology caught up over the years and I&amp;rsquo;ve been happy with the LCD monitors I have since then.&lt;/p&gt;
&lt;p&gt;Until now.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been looking into large LCD monitors to set up in my new office with my Macbook Pro, and I find myself pushing into the limit of technology once again. The results: I went through 3 monitors of about $1K each. Two fell completely short, and one was perfect.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I remember back in the mid-90s, I went through 5 or 6 19&quot; CRT monitors before I found one that I thought was acceptable running at 1600x1200. I believe it was a Samsung and it even needed BNC cables to get the signal without interference and degradation to get the quality I wanted.</p>
<p>Fortunately, display technology caught up over the years and I&rsquo;ve been happy with the LCD monitors I have since then.</p>
<p>Until now.</p>
<p>I&rsquo;ve been looking into large LCD monitors to set up in my new office with my Macbook Pro, and I find myself pushing into the limit of technology once again. The results: I went through 3 monitors of about $1K each. Two fell completely short, and one was perfect.</p>
<h2 id="the-shiny-27-apple-thunderbolt-display">The Shiny: 27&quot; Apple Thunderbolt Display</h2>
<p>The top contenders starting out were the <a href="http://www.apple.com/displays/">27&quot; Apple Thunderbolt Display</a>, and the <a href="http://accessories.us.dell.com/sna/productdetail.aspx?c=us&amp;cs=04&amp;l=en&amp;s=bsd&amp;sku=224-8284&amp;redirect=1">27&quot; Dell U2711</a>. I read reports that they both use the same display technology, and the differences between the two were relatively minor. After some conflicting reviews (that should have been the first warning), I decided to go with the Apple Display.</p>
<p>This display seemed perfect for me. It looks gorgeous, like an oversized iPad. The image quality is fantastic, with text being sharp and clear and having a great resolution. Since I&rsquo;m only connecting a Macbook Pro to it, the connections are perfect: The Thunderbolt cable is great because it deals with display, USB, ethernet, and even audio in one fell swoop. The display also has a power cable for the Macbook Pro, so it&rsquo;s like a perfect docking station.</p>
<p>It really was almost perfect. Almost.</p>
<p><img alt="465078317" loading="lazy" src="/big-displays-the-good-the-shiny-and-the-ugly/images/465078317.jpg"></p>
<p>The glare was simply horrible and I could see myself reflected on the screen, even with a white background. The shiny display was almost a perfect mirror. It might be the ideal display if you like to work in a dungeon, but I like light, the more the better. Even though my office has no direct sunlight, just the indirect light coming in was enough to see everything brightly reflected on it.</p>
<p><a href="https://twitter.com/#!/noel_llopis/status/144143019862528000"><img alt="347027484 f4552c672b" loading="lazy" src="/big-displays-the-good-the-shiny-and-the-ugly/images/347027484_f4552c672b.jpg"><br>
One possible way to work with the Apple Display</a></p>
<p>What&rsquo;s worse, if one day I had to rearrange things or move to a different office and I had a window behind me, it would go from distracting to impossible to see anything.</p>
<p>Another annoying aspect of that monitor is that the stand height wasn&rsquo;t adjustable. I like to look at a monitor straight while my arms are about a 90-100 degree angle, so the monitor ended up being several inches too low. I can do the old phone book trick, but it seemed ridiculous having to do that on such a beautiful display.</p>
<p>As much as I liked that display, it just wasn&rsquo;t for me.</p>
<h2 id="the-ugly-dell-u2711">The Ugly: Dell U2711</h2>
<p>In spite of some comments complaining about &ldquo;over aggressive&rdquo; anti-glare coating, I decided to give the <a href="http://accessories.us.dell.com/sna/productdetail.aspx?c=us&amp;cs=04&amp;l=en&amp;s=bsd&amp;sku=224-8284&amp;redirect=1">Dell U2711</a> a try. I had used Dell monitors before and I was never bothered by the screen. And after all, the antiglare coating could fix the problem the Apple display had. Apart from the antiglare, it had some attractive options: Multi-card reader, several video inputs, and better color options. It could be the perfect screen.</p>
<p>It turns out it was far from that. It was the opposite of the Apple display in many ways. Connecting it to the Macbook Pro was a hassle since it shipped with a Displayport cable, but not a Mini Displayport one. I tried using my Mini Displayport to DVI adaptor, but it turns out it was single-link and you need a dual link to drive the full 2560 x 1440 resolution.</p>
<p>Once I finally got it up and running (with a Mini Displayport to Displayport cable), the resulting image was plain ugly. The colors were off, but more seriously, the antiglare coating really was horrible. It made the screen look like there was a fine coating of dust on it, or like it was film with a very obvious grain to it. I had to strain my eyes to focus on the text because the graininess kept throwing me off.</p>
<p>I suppose I could have gotten used to it, but since I use the Macbook Pro display next to it, going back and forth was torture. One moment I would see this clean, sharp, beautiful display, the next moment I would see this horrible grainy mess.</p>
<p>To make sure I wasn&rsquo;t hallucinating, I took a picture of both displays with my iPhone displaying the same content. The differences are obvious (click on them to see them full size).</p>
<p><a href="http://twitpic.com/7wsaos/full"><img alt="MBP antiglare small" loading="lazy" src="/big-displays-the-good-the-shiny-and-the-ugly/images/MBP_antiglare_small.jpg"><br>
Macbook Pro with antiglare</a></p>
<p><a href="http://twitpic.com/7wsc0h/full"><img alt="Dell u2711 small" loading="lazy" src="/big-displays-the-good-the-shiny-and-the-ugly/images/dell_u2711_small.jpg"><br>
Dell U2711</a></p>
<p>In case that wasn&rsquo;t enough, the colors were severely off. I played around for an hour with the custom settings and some advice from the internet, but I just managed to make them a bit better. I still liked the colors on the Apple Display (or the Macbook Pro) way better.</p>
<h2 id="the-good-30-apple-cinema-display">The Good: 30&quot; Apple Cinema Display</h2>
<p>At this point I thought I was out of luck, and that I was going to have to settle for either one of those two monitors (I would take the 27&quot; Apple one), or something smaller but without those problems.</p>
<p>Fortunately, <a href="https://twitter.com/#!/ruttencutter">several</a> <a href="https://twitter.com/#!/lilwhitebear">people</a> on Twitter encouraged me to try out the <a href="http://www.everymac.com/monitors/apple/studio_cinema/specs/apple_cinema_display_30.html">30&quot; Apple Cinema Display</a>. I never saw paid attention to one, but apparently they had fantastic image quality and a good antiglare coating. That sounded promising!</p>
<p>One of the pleasures of being a small company is that once I decide to do something, I can do it right away. There&rsquo;s no paperwork, approval, ordering through certain channels, or any of that overhead. Since Apple doesn&rsquo;t make that display anymore, I hopped on Craigslist, called a guy up, and picked it up a few hours later. Done!</p>
<p>And boy was I glad I did! That monitor is everything that was cracked up to be and more! Since it&rsquo;s an older display, it doesn&rsquo;t have Mini Displayport cables, so I had to use a Mini Displayport to Dual DVI adaptor. The image quality is indeed, outstanding, and the colors are quite good (although maybe a touch redder than the laptop).</p>
<p>I actually love that it&rsquo;s a 16:10 ratio instead of the more common 16:9 in most monitors today. That gives results in a resolution of 2560 x 1600, which gives me some much-needed vertical space when writing code (which is 80-90% of my day).</p>
<p>As a totally minor, but nice side effect, the brightness controls on the keyboard control the screen brightness (which is kind of surprising considering it&rsquo;s connected over the dual DVI adaptor, but there&rsquo;s also a USB cable going into the display, so maybe it&rsquo;s communicating through that channel).</p>
<p>The only drawback is that the back only has two USB ports (I wish it had 4 or more). It does have two Firewire ports as well, although I don&rsquo;t have any devices that use those.</p>
<p>For completeness sake, I took a picture of the new monitor with the same image I used as a test earlier. It shows how much cleaner the image is than the Dell.</p>
<p><a href="http://twitpic.com/7ww43p/full"><img alt="Cinema 30 small" loading="lazy" src="/big-displays-the-good-the-shiny-and-the-ugly/images/cinema_30_small.jpg"><br>
30&quot; Apple Cinema Display</a></p>
<h2 id="conclusion">Conclusion</h2>
<p><img alt="Lineup" loading="lazy" src="/big-displays-the-good-the-shiny-and-the-ugly/images/lineup.jpg"><br>
From left to right: The shiny, the ugly, and the good.</p>
<p>If you&rsquo;re picky like me about the quality of your displays, and you&rsquo;re looking for a large monitor, I can&rsquo;t recommend the 30&quot; Apple Cinema Display enough. It&rsquo;s a shame that Apple stopped manufacturing it, so check Cragislist or Ebay for it. If you work in a dark place, maybe the 27&quot; Thunderbolt one will work as well. Whatever you do, stay far, far away from the Dell one.</p>
<p>We can only hope that Apple will make a revision of the 27&quot; Thunderbolt Display soon with a high-quality antiglare coating like the laptops. In the meanwhile, I&rsquo;m thankful both Apple and Dell have good return policies.</p>]]></content:encoded></item><item><title>iCloud Demystified</title><link>https://gamesfromwithin.com/icloud-demystified/</link><pubDate>Thu, 22 Dec 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/icloud-demystified/</guid><description>&lt;p&gt;Play a game on a device, put it down, pick up another device, and continue playing exactly where you left off. This is the future of games.&lt;/p&gt;
&lt;p&gt;That future is a reality today for some games and apps (Netflix, Kindle), and I&amp;rsquo;m convinced that players will expect that in most games in the next year or so. So obviously, the next bit of new iOS tech I decided to try was iCloud. I would love to turn Flower Garden into that kind of seamless experience, independently of the device you use to access it.&lt;/p&gt;
&lt;p&gt;As a quick spoiler, it turns out I won&amp;rsquo;t be able to make Flower Garden quite so seamless without a lot of extra work. But I learned a lot along the way and I should be able to take a small step in that direction.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Play a game on a device, put it down, pick up another device, and continue playing exactly where you left off. This is the future of games.</p>
<p>That future is a reality today for some games and apps (Netflix, Kindle), and I&rsquo;m convinced that players will expect that in most games in the next year or so. So obviously, the next bit of new iOS tech I decided to try was iCloud. I would love to turn Flower Garden into that kind of seamless experience, independently of the device you use to access it.</p>
<p>As a quick spoiler, it turns out I won&rsquo;t be able to make Flower Garden quite so seamless without a lot of extra work. But I learned a lot along the way and I should be able to take a small step in that direction.</p>
<h2 id="design-considerations">Design considerations</h2>
<p>iCloud promises to be the &ldquo;available from everywhere&rdquo; storage solution that will be a key component towards the scenario of playing on any device at any time. Unfortunately, it&rsquo;s just a component of that whole scenario and still requires quite a bit of work on the part of the developer.</p>
<p>Since I&rsquo;m just retrofitting Flower Garden to work with iCloud, I wanted a simple way to simply replicate the game state on iCloud. Then, whenever you play it from any device, you get the latest state and everything works as expected.</p>
<p>The big problem with that approach is that you can&rsquo;t always count on having an active (or fast enough) internet connection. iPod Touches, iPads, or even iPhone in a plane or a cell tower black spot will make it so your device has no way to communicate with iCloud. So what happens if the player plays without an internet connection, then comes home, grabs another device, plays for a bit with internet connection, and finally launches the original device, this time with internet connection. You&rsquo;ll end up with two conflicting game states. Not fun!</p>
<p><img alt="Whatis icloud" loading="lazy" src="/icloud-demystified/images/whatis_icloud.jpg"></p>
<p>I can think of two different strategies to deal with this situation:</p>
<ul>
<li>Require internet connection to play. Some games do this today. It can be quite frustrating not being able to play your favorite game in the plane, but it does solve the game state conflict problem because they can always communicate with iCloud, so they usually provide seamless multi-device play.</li>
<li>Detect changes on both game states and intelligently solve them. Sounds good in theory, but it&rsquo;s a pain in practice. Unless you have a very simple game state (a percentage completion for example), it means not only do you have to record the state, but you have to record the events that led to that state, and be ready to examine them, compare them, and marge them in the case of a conflict. And the worst part is that even if you put lots of care into it, there will be cases where the merge is not ideal and the player will feel like he lost something in the merge.</li>
</ul>
<p>For Flower Garden, neither solution is particularly attractive. It&rsquo;s the proverbial rock and a hard place. So for the moment I&rsquo;ve decided to implement just a small step in that direction: Sync things that only progress in one direction, without any danger of conflict. That includes purchased IAPs and unlocked seeds. Later on, once that&rsquo;s working solidly without any problems, I can consider adding counts like Fertilizer, Color Dust, or Green Thumb points. That will be a bit trickier because there&rsquo;s still chance for conflict since the count can go up and down, but it&rsquo;s possible to change each amount into two different values that always go up: Earned amount, and spent amount. That way I can always grab the maximum value that I find either local or on iCloud and things should work smoothly. (Update: What I wrote there about separating them in two different values is totally wrong, and any DB programmer worth his salt would be laughing at that. Separating them in two different values won&rsquo;t help at all. That&rsquo;s what I get for doing brain-dump posts on the fly :-)</p>
<p>Apple provides <a href="https://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/iCloud/iCloud.html#//apple_ref/doc/uid/TP40007072-CH5-SW1">two APIs to store data in iCloud</a>: key-value storage and file storage.</p>
<h2 id="key-value-storage">Key Value storage</h2>
<p>Initially, this seems like a great way to go. It&rsquo;s a <a href="https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSUbiquitousKeyValueStore_class/Reference/Reference.html#//apple_ref/occ/cl/NSUbiquitousKeyValueStore">very simple API</a>, and it&rsquo;s very familiar to most iOS programmers because it&rsquo;s just like <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html">NSUserDefaults</a>.</p>
<p>Don&rsquo;t be fooled into thinking you need to store data in strings or one field at the time. You can stuff whatever binary chunk of data you want with NSData, so it&rsquo;s quite versatile.</p>
<p>It does have three pretty big drawbacks thought:</p>
<ul>
<li>
<p><strong>Size</strong>. You can only store up to 64KB of data. That&rsquo;s definitely a big deal if you&rsquo;re planning on storing large data files. Even for Flower Garden, each pot is about 30KB, so I wouldn&rsquo;t be able to save the full garden state this way.</p>
</li>
<li>
<p><strong>Syncing</strong>. The Apple docs say that &ldquo;Keys and values are transferred to and from iCloud at periodic intervals.&rdquo; Ouch! What does that mean? Clearly this is intended for non-crucial data (like settings), so the potential delay isn&rsquo;t a big deal. In my tests, I found that data was often not available when starting the app, but would become available a few seconds later.</p>
</li>
<li>
<p><strong>No way to check state.</strong> When starting the app, there&rsquo;s no way to find out if the values you&rsquo;re reading are up to date. Combined with the slow syncing, it makes it less than idea for important data. On the flip side, <a href="https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSUbiquitousKeyValueStore_class/Reference/Reference.html#//apple_ref/occ/cl/NSUbiquitousKeyValueStore">you can be notified when the data changes</a>, but that means having to deal with changes while the game is running (which I was hoping not to do).</p>
</li>
</ul>
<h2 id="file-storage">File storage</h2>
<p>File storage might be a better option then since it doesn&rsquo;t have any of those drawbacks: there&rsquo;s no size limit, data is synced much more aggressively, and you can check if the data is up-to-date, and wait until it is otherwise.</p>
<p>What&rsquo;s not to like about file storage then? The cumbersome and intrusive API that Apple created around it. If you read the docs, they make it sound like you need to inherit from UIDocument and load all your data through that class. I like to keep things simple and portable, so I&rsquo;d really rather not introduce UIDocument into the file-loading process if I don&rsquo;t have to.</p>
<p>It turns out that <a href="https://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/iCloud/iCloud.html#//apple_ref/doc/uid/TP40007072-CH5-SW1">Apple&rsquo;s docs on the iCloud SDK</a> are quite sparse and lacking details. I was able to put together a demo from those docs and some experimentation, so hopefully this will be useful to other devs as well.</p>
<p>The device has an iCloud storage daemon running, monitoring specific directories for changes. You get the directory assigned to your app by calling <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/URLForUbiquityContainerIdentifier:">URLForUbiquityContainerIdentifier</a>.</p>
<p>To add a new file, the docs recommend first creating the file somewhere else, and then calling <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/setUbiquitous:itemAtURL:destinationURL:error:">NSFileManager:setUbiquitous:itemAtURL:destinationURL:error:</a> to move it to iCloud. Interestingly, I accidentally skipped this step and just wrote to the iCloud directory directly, and the files were stored correctly anyway. Might as well leave it just in case that behavior changes later on, or there&rsquo;s some side effect I didn&rsquo;t notice.</p>
<p>After that, every time you write to the file, the iCloud daemon will detect the changes and push them out to iCloud. This is an important point because a) You don&rsquo;t have explicit control to say &ldquo;start send it now&rdquo; or even &ldquo;This file is ready to be sent to iCloud&rdquo; (that would be my choice), and b) I don&rsquo;t know what it does with partial updates, so I would be very careful about writing to those files and make sure it&rsquo;s an atomic operation (save somewhere else, and them move the file in one operation).</p>
<p>To get the latest version of the files on iCloud, you can check whether they&rsquo;re fully downloaded or not by calling <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html#//apple_ref/occ/instm/NSURL/getResourceValue:forKey:error:">NSURL:getResourceValue:&amp;isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:</a>. If they are up to date, you can move on, otherwise, you can initiate a download of the files by calling <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/startDownloadingUbiquitousItemAtURL:error:">NSFileManager:startDownloadingUbiquitousItemAtURL:error:</a>.</p>
<p>One weird thing is that the startDownloading function doesn&rsquo;t have a callback (that I can see). So I had to set up a timer to check periodically if the files are synced.</p>
<p>Since all the syncing happens at startup, there&rsquo;s no complexity involved with data changing while the app is running. If that&rsquo;s a case you need to handle, you might be better off using UIDocument since it at least detects conflicts. If you do it this way, the latest one will overwrite any past changes.</p>
<p>Also, working this way, it seemed easier to keep the files in Application Support (or Documents), and only move them to/from iCloud when I wanted to. That has the advantage of iCloud not changing things from under you while the game is running, and the fact that, if for some reason the files in iCloud are corrupt, you always have good local files to fall back to.</p>
<h2 id="demo">Demo</h2>
<p><a href="/wp-content/uploads/2011/12/iCloudTest.zip" title="iCloudTest.zip">iCloudTest.zip</a></p>
<p>The demo iCloudTest saves data both with the key value pair, and the file storage system directly like I described above. If you run it from different devices, you&rsquo;ll see that it&rsquo;s amazing how quickly file data gets propagated, but key-value data takes a few more seconds.</p>
<p>The demo project also works in the simulator (there&rsquo;s no iCloud support, so it just uses local files), and it even works with iOS4 (also using local files, and it avoids using any iOS5 symbols while detecting iCloud support).</p>
<h2 id="sharing-data-between-multiple-apps">Sharing Data Between Multiple Apps</h2>
<p>Once you&rsquo;re at this point, sharing data between multiple apps is really straightforward.</p>
<p>First you need to make sure the app IDs of both apps start with the seam Team ID. For some unknown reason lost in the midsts of time, Flower Garden and Flower Garden Free use different prefixes, so that option is out for me. Hopefully most people having been using the Team ID only.</p>
<p>Then you need to decide which type of data you want to share. If you want to share files, you need to add the app ID of the other app to your iCloud entitlement, and then as for the correct app ID (including prefix!) when you call <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/URLForUbiquityContainerIdentifier:">URLForUbiquityContainerIdentifier</a>. If you just want the app&rsquo;s own iCloud data, you can pass NULL as the parameter.</p>
<p>As far as I can tell, each application can only have one set of key-value data. So sharing it between two apps means changing one app to use the app ID of the other app in the com.snappytouch.icloudtest field of the iCloud entitlements file. As long as both apps use the same Team ID prefix, it should work fine without having to do anything else.</p>]]></content:encoded></item><item><title>Trying Out Multisampling On iOS</title><link>https://gamesfromwithin.com/trying-out-multisampling-on-ios/</link><pubDate>Fri, 16 Dec 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/trying-out-multisampling-on-ios/</guid><description>&lt;p&gt;I only recently broke free of iOS3.x for Flower Garden, so I&amp;rsquo;m finally adding all the features I had been itching to add that required higher OS support. I had already added some iOS4+ features, but I was keeping them to a minimum because it&amp;rsquo;s always a huge cause of bugs to target multiple versions of the OS at once.&lt;/p&gt;
&lt;p&gt;One of the first features I looked into adding was &lt;a href="http://en.wikipedia.org/wiki/Multisample_anti-aliasing"&gt;multisample antialiasing (MSAA)&lt;/a&gt; support for OpenGL, which was originally introduced in iOS 4.0. The geometry generated for the petals in Flower Garden is fairly high contrast, and since it&amp;rsquo;s not like the textures were carefully created and laid out by an artist, the result is pretty bad aliasing around the edges. Perfect candidate for multisampling!&lt;/p&gt;</description><content:encoded><![CDATA[<p>I only recently broke free of iOS3.x for Flower Garden, so I&rsquo;m finally adding all the features I had been itching to add that required higher OS support. I had already added some iOS4+ features, but I was keeping them to a minimum because it&rsquo;s always a huge cause of bugs to target multiple versions of the OS at once.</p>
<p>One of the first features I looked into adding was <a href="http://en.wikipedia.org/wiki/Multisample_anti-aliasing">multisample antialiasing (MSAA)</a> support for OpenGL, which was originally introduced in iOS 4.0. The geometry generated for the petals in Flower Garden is fairly high contrast, and since it&rsquo;s not like the textures were carefully created and laid out by an artist, the result is pretty bad aliasing around the edges. Perfect candidate for multisampling!</p>
<p>I based everything on the <a href="http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html#//apple_ref/doc/uid/TP40008793-CH103-SW12">Apple documentation on multisampling</a>. It was very straightforward and it works for both off-screen and view-based render targets. It was also extremely helpful to keep both the ability to use regular and multisampled render targets. That way I can easily run performance and visual comparisons, and, if necessary, I can disable multisampling on a particular device.</p>
<p>The main gotcha was making sure I used the GL_RGBA8_OES color format on the multisampling color buffer (otherwise it won&rsquo;t work, and all you&rsquo;ll get are 1282 &ldquo;invalid operation&rdquo; OpenGL errors). Also, if you&rsquo;re in the same boat as Flower Garden, which uses OpenGL ES 1.1 and the fixed function pipeline, you&rsquo;ll have to add _OES to just about every constant in the documentation.</p>
<h2 id="visual-results">Visual results</h2>
<p>I will let the screenshots speak for themselves.</p>
<p><img alt="Multisample" loading="lazy" src="/trying-out-multisampling-on-ios/images/multisample.png"></p>
<p>In this screenshot you can see the rendering of the pots using off-screen render targets.</p>
<p><img alt="Multisample2" loading="lazy" src="/trying-out-multisampling-on-ios/images/multisample2.png"></p>
<p>Pretty impressive improvement, even if I say so myself! The improvement is even more striking in-game because the animation of the flowers moving in the wind doesn&rsquo;t have jaggies popping in and out.</p>
<p>The improvements are more noticeable on the iPad because the pixels are bigger, and, not surprisingly, less so on retina-display iPhones. But even on the retina displays, jaggies are less noticeable during the flower wind-swaying animations.</p>
<h2 id="performance">Performance</h2>
<p>So, no doubt: They look pretty. But how about performance? Under the hood, the rasterizer is generating four samples for every pixel, and then combining them at the end in a separate step. So you&rsquo;ll get more of a performance hit with complex pixel shaders. <strong>Edit:</strong> My bad. I spaced out and I forgot that MSAA only evaluates the pixel shader once, so performance doesn&rsquo;t depend on pixel shader complexity. Instead, the performance hit probably comes from the extra writes (four per pixel) to the render target, and should be fairly similar between games.</p>
<p>It turns out that Flower Garden is still using OpenGL ES 1.1, which is implemented using shaders at the driver level. Fortunately, even though I&rsquo;m using some texture combiner operations and several input textures, those pixel shaders aren&rsquo;t all that complex.</p>
<p>These are the frames per second I recorded with one particular flower pot on the different devices I have for testing. Notice that the lowest device I have listed is the iPhone 3GS. That&rsquo;s because I have also stopped supporting arm6 CPUs to keep things simpler (and the market share is minimal).</p>
<p><strong>Update:</strong> I was only running the game loop at 30 fps, so the initial performance numbers I had listed are pretty meaningless. Here are the correct numbers running at a max of 60 fps.</p>
<table>
	<thead>
			<tr>
					<th>Device</th>
					<th>Without MSAA</th>
					<th>With MSAA</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>iPhone 3GS</td>
					<td>39 fps (25.6 ms)</td>
					<td>37 fps (27.0 ms)</td>
			</tr>
			<tr>
					<td>iPhone 4</td>
					<td>48 fps (20.8 ms)</td>
					<td>23 fps (43.5 ms)</td>
			</tr>
			<tr>
					<td>iPhone 4S</td>
					<td>60 fps (16.7 ms)</td>
					<td>60 fps (16.7 ms)</td>
			</tr>
			<tr>
					<td>iPad 1</td>
					<td>60 fps (16.7 ms)</td>
					<td>18 fps (55.6 ms)</td>
			</tr>
			<tr>
					<td>iPad 2</td>
					<td>60 fps (16.7 ms)</td>
					<td>60 fps (16.7 ms)</td>
			</tr>
	</tbody>
</table>
<p>Of the devices I tested, MSAA didn&rsquo;t slow down things much on the iPhone 3GS, and the iPhone 4S was maxed out at 60 fps both ways. The iPad 1 was a different story, and performance crashed from 60 fps to 18 fps. Like Rory pointed in the comments, looking at the actual time instead of the fps gives a better insight. Using MSAA adds 38.9 ms to each frame! The iPhone 4 also suffered from a big performance hit due to all the extra pixels in the retina display. I don&rsquo;t care how pretty the flowers are, that&rsquo;s just not acceptable (and no, I&rsquo;m not adding user-tweakable graphics settings like PC games).</p>
<p>I should also add that Flower Garden is hugely CPU bound. It generates all that geometry every frame on the CPU, and that&rsquo;s a lot of vector transforms. So if your game is GPU bound, you&rsquo;re likely to see higher performance hits.</p>
<p>I was initially very surprised to see that the performance on the simulator tanked big time (as in, going from 30 fps to 5 fps). This was news to me, but apparently the iOS simulator runs completely in software, so the quadrupling of pixels brings it to its knees. I&rsquo;m really, really, impressed at how smoothly it usually runs for being in software though. It had me fooled thinking it was using OpenGL under the hood!</p>
<p>As far as memory goes, after an <a href="https://twitter.com/#!/Frogblast/status/144811240177405952">animated discussion on Twitter</a>, it seems that the iPhone does create full buffers for the multisample frame buffers, so there is a significant increase in memory usage. It&rsquo;s not something easy to track because it all happens at the driver level, but it&rsquo;s something to be aware of. Because of this, I might consider turning multisampling off on retina displays, since the improvement is not mind-blowing (and the extra memory is very significant because of the amount of pixels). I&rsquo;ll also probably turn it off in the simulator so I can achieve a decent frame rate during development.</p>
<h2 id="conclusions">Conclusions</h2>
<p>Multisampling only required adding a few lines of code and resulted in an impressive visual improvement and minimal performance impact in some devices. It&rsquo;s a no-brainer on the 3GS and iPad 2. I&rsquo;m wishing I had implemented it earlier!</p>]]></content:encoded></item><item><title>View Controller Notification Changes on iOS5</title><link>https://gamesfromwithin.com/view-controller-notification-changes-on-ios5/</link><pubDate>Fri, 09 Dec 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/view-controller-notification-changes-on-ios5/</guid><description>&lt;p&gt;If you use view controllers in your iOS apps, here&amp;rsquo;s a doozie: The behavior of viewWillAppear/viewDidApear/viewWillDisappear/viewDidDisappear silently changed on iOS5. Depending how your app is organized, this might range from not mattering to being a total disaster.&lt;/p&gt;</description><content:encoded><![CDATA[<p>If you use view controllers in your iOS apps, here&rsquo;s a doozie: The behavior of viewWillAppear/viewDidApear/viewWillDisappear/viewDidDisappear silently changed on iOS5. Depending how your app is organized, this might range from not mattering to being a total disaster.</p>
<p>Pre-iOS5, if you added a view with [self.view addSubview:myView], myView didn&rsquo;t get any notifications. That was weird, but we learned to live with it. Tens (hundreds?) of thousands of developers worked around that and wrote gobs and gobs of code that worked with and counted on that behavior.</p>
<p>Then along comes the iOS5 SDK and someone decided that it would be good to &ldquo;fix&rdquo; that behavior, but doing it silently. By silently I mean no compile-time errors or warnings, but apparently it wasn&rsquo;t deemed worthy of including in the <a href="https://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-5_0/_index.html">iOS5 release notes either</a>. I&rsquo;m sure they thought they were doing us a favor. After all, if someone had a problem with it, it&rsquo;s because they hadn&rsquo;t structured their code correctly.</p>
<p>So now every view you add/remove will get those notifications. Which is fine, except if you had decided to call those by hand yourself. In that case, now they get executed twice, so you may be allocating things twice, making multiple network calls, and just causing general mayhem.</p>
<p>I also noticed that if you call presentModalViewController with a view controller, all the views underneath the modal view controller will get the viewWillDisappear/viewDidDisappear event. In my case this causes total chaos because those events trigger the freeing of some views that the modal view controller will need.</p>
<p>But wait, it gets even better! From what I&rsquo;ve been able to tell, if your app compiled with the iOS5 SDK runs on iOS4, then you don&rsquo;t get those events! That means that now you need to be ready to both deal with receiving them and not receiving them at the same time. Is that useful to anyone (other than devs making iOS5+ apps)?</p>
<p>Fortunately, existing apps compiled with the iOS4 SDK are consistent running both on iOS4 and iOS5 (no view events automatically generated). Phew! Dodged that bullet.</p>
<p>It seems I <a href="/xcode-4-trials-and-tribulations/">complain</a> <a href="/quick-notes-on-lion/">a lot</a> lately, but this seems like another very justified complaint. Wasn&rsquo;t there a way for Apple to add that behavior to new functions without changing the old ones? For example, they could have introduced UIView:addSubview:withNotifications: and eventually deprecated the old ones. Yes, that means that they would have had to duplicate 10-20 functions related to adding/removing views, but they wouldn&rsquo;t have broken half the iOS code out there.</p>
<p>This is probably my fault for relying on viewDidAppear events and calling them myself. I started working around this problem by being super-careful about how and when I call viewDidAppear, but as soon as I realized that iOS4 does it differently, I threw in the towel and went for a different approach. Now, I just implement my own function in the different view controllers and call that instead of viewDidAppear. That way Apple can change those events all they want and it won&rsquo;t affect me anymore.</p>
<p>Of course, all of this only matters if you&rsquo;re making heavy use of view controllers (which unfortunately I am doing in Flower Garden). I&rsquo;ve already said that my future game projects are going to be UIKit-free, so I won&rsquo;t have to deal with this kind of problems again.</p>]]></content:encoded></item><item><title>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>Designing Good Free-To-Play Games</title><link>https://gamesfromwithin.com/designing-good-free-to-play-games/</link><pubDate>Tue, 15 Nov 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/designing-good-free-to-play-games/</guid><description>&lt;p&gt;It&amp;rsquo;s pretty clear that &lt;a href="http://blog.flurry.com/bid/65656/Free-to-play-Revenue-Overtakes-Premium-Revenue-in-the-App-Store"&gt;free-to-play games are the way to go&lt;/a&gt; if you care about making money from your games. And don&amp;rsquo;t give me that line about being indie and not caring about the money. On the contrary, being able to make money from the games we love to make, allows us to keep doing what we&amp;rsquo;re passionate about.&lt;/p&gt;
&lt;p&gt;I was having a discussion today about free games with other developers and I thought I would post here some random thoughts and open it up for discussion.&lt;/p&gt;</description><content:encoded><![CDATA[<p>It&rsquo;s pretty clear that <a href="http://blog.flurry.com/bid/65656/Free-to-play-Revenue-Overtakes-Premium-Revenue-in-the-App-Store">free-to-play games are the way to go</a> if you care about making money from your games. And don&rsquo;t give me that line about being indie and not caring about the money. On the contrary, being able to make money from the games we love to make, allows us to keep doing what we&rsquo;re passionate about.</p>
<p>I was having a discussion today about free games with other developers and I thought I would post here some random thoughts and open it up for discussion.</p>
<p>Free-to-play (or freemium&ndash;even if they aren&rsquo;t exactly the same, I&rsquo;m bundling them all under the same category for this discussion), have have a fairly bad reputation, and they&rsquo;ve been under fire recently from developers. It&rsquo;s true that a lot of those games have been rather poor from a game design point of view, while raking in loads of money from players who are apparently happy to play them.</p>
<p>It&rsquo;s important to separate the financial model (free with other ways for players to spend money in-game), and the quality of those early games or the intentions behind them. I am convinced that free games is the future of mass-market games (it&rsquo;s already pretty much the present, so that&rsquo;s not much of a stretch).</p>
<p>There&rsquo;s no doubt that the financial model of game affects its design. Compare arcade games, retail console games, and subscription-based games just as an example. Free-to-play has a huge impact on the design as well.</p>
<p>Free-to-play games are in their infancy. Not only are they a relatively recent happening, but they were also wildly successful, which encouraged a lot of copying and not much innovation. So they&rsquo;re stuck in a type of design that results in a local maximum of profit, while providing a not very satisfying experience for a lot of players. As game developers, we need to find out how to make great games while using the free-to-play model.</p>
<p>I&rsquo;ve been going around this quite a bit recently, because I&rsquo;m in the stages of deciding what my next game is going to be. The reality of the App Store are pushing me towards free-to-play, but I&rsquo;m not interested in making a Farm/Store/Pet game.</p>
<p>These are my random thoughts on what we can charge for in a free game and how it affects game design:</p>
<ul>
<li><strong>Reduce delays</strong>. This is very effective, but feels cheap and somewhat manipulative (yes, this is coming from the guy who did <a href="http://www.snappytouch.com/flowergarden">Flower Garden</a>&hellip; but that was before IAPs and the whole point of the game was the nurturing/waiting part). It also falls in the category of the question I often ask myself: If I remove this from the game, will it be better or worse? The answer is (almost) always &ldquo;better&rdquo; by removing those delays.</li>
<li><strong>In-game currency</strong>. This is seems like a better approach as long as there&rsquo;s no competitive multiplayer. However, it does wreck havoc with the game balance. Either it becomes too easy and not fun for those who paid, or boring and grindy for those who didn&rsquo;t. Still, especially on mobile, it&rsquo;s not a totally bad way to go. You&rsquo;re letting people make a choice how they want their experience.</li>
<li><strong>Extra content</strong>. That seems to be the traditional, developer-approved way to go. PC and console games have been doing that with DLCs for a long time. The main problem is that not many players want that content, the amount of content you can sell is limited, and it often requires a lot of extra effort to generate.</li>
<li><strong>Extra choices</strong>. This includes different characters, clothes, weapons, etc. I see this as the sweet spot between the last two options. What you buy doesn&rsquo;t completely throw off the game curve, but it&rsquo;s also not just new levels or missions. Combine that with letting players earn credits to get those choices (by grinding if they want to, but it&rsquo;s all optional) and it seems like a good way to go. You can also go the way of <a href="http://na.leagueoflegends.com/">League of Legends</a> (which I have yet to play!) and you can rotate in that extra content for limited amounts of time, so players get a taste and they have the option of buying them permanently.</li>
<li><strong>Cheats</strong>. By cheats I mean more lives, rewind/replay, invulnerability, etc. It feels like a throwback to the arcade days. Some players will be put off by it (either by the fact it exists, or by the fact that they finished the game too quickly with the help of those cheats), but it can work in the right game. You&rsquo;d probably want to do something about high scores, like putting players who used those cheats in a different leaderboard.</li>
</ul>
<p>What are your thoughts on this? What are some other ways that players can pay for in free games and still allows us to make a great game?</p>]]></content:encoded></item><item><title>Duplicating Launchboard Wobble</title><link>https://gamesfromwithin.com/duplicating-launchboard-wobble/</link><pubDate>Fri, 30 Sep 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/duplicating-launchboard-wobble/</guid><description>&lt;p&gt;One of the most requested features for Flower Garden is to be able to move pots around. Not only do players want to group similar flowers or colors together, but they also want to be able to take advantage of the properties of the different gardens. I figured the best thing to do this is by mimicking the wobble on the iPhone launchboard icons when you enter edit mode.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the most requested features for Flower Garden is to be able to move pots around. Not only do players want to group similar flowers or colors together, but they also want to be able to take advantage of the properties of the different gardens. I figured the best thing to do this is by mimicking the wobble on the iPhone launchboard icons when you enter edit mode.</p>
<p>I have to say, I&rsquo;m not a huge fan of the wobble movement, but it does indicate that icons are &ldquo;loose&rdquo; and movable. And since most players are already familiar with that metaphor, and the overhead view of Flower Garden resembles the launchboard quite a bit (not coincidence), I might as well go with it.</p>
<p><img alt="Garden02" loading="lazy" src="/duplicating-launchboard-wobble/images/garden02.jpg"></p>
<p>Each pot is a UIButton with a custom image (<a href="/opengl-and-uikit-demo/">rendered from OpenGL into an off-screen target</a>). So when I enter edit mode, I need to wobble them like the launchboard. Easier said than done.</p>
<p>I searched online and <a href="http://twitter.com/#!/noel_llopis/status/119795265069785088">asked on Twitter</a>, but surprisingly, nobody had done a perfect, reverse-engineering of the wobble movement. Most mentions just do a z rotation on a sine wave, which is not that close of the launchboard animation.</p>
<p>I found that to get closer to the real thing, you need to do that rotation around a random point offset from the center. That&rsquo;s better, but it&rsquo;s still not perfect. There&rsquo;s an additional extra twitch in the original Apple animation. I&rsquo;d love it if someone already reverse-engineered it and has a better model for that animation.</p>
<p>In the meanwhile, I figured I would share the core I&rsquo;m using. It&rsquo;s all very straightforward, except for the part about rotating a UIView around a different point other than the center. I initially thought I could just concatenate transforms, but no matter how you do it, UIKit always interprets the transform around the center.</p>
<p>To be more precise, it interprets the rotation around the anchor point, and that&rsquo;s what you need to modify. The anchor point is defined in units that are a percentage of the layer&rsquo;s size, so by default it&rsquo;s 0.5, 0.5. When you move the anchor point, the layer itself will move, so you need to fix it up by moving the layer&rsquo;s position by the same amount in the opposite direction.</p>
<p>This is what the final code looks like:</p>
<pre tabindex="0"><code>void StartPotWobble(UIButton* button, Random&amp; random)
{
	const Range posOffset(0.10f, 0.2f);
	const float amplitude = random.GetFloat(1,1.5f);
	const Vec2 startCenter(Sign(random.GetFloat(-1,1))*random.GetFloat(posOffset), Sign(random.GetFloat(-1,1))*random.GetFloat(posOffset));
	const Vec2 endCenter(Sign(random.GetFloat(-1,1))*random.GetFloat(posOffset), Sign(random.GetFloat(-1,1))*random.GetFloat(posOffset));

	CGPoint center = button.center;	
	button.layer.anchorPoint = CGPointMake(0.5f + startCenter.x, 0.5f + startCenter.y);
	CGRect bounds = button.bounds;
	button.layer.position = CGPointMake(button.layer.position.x + bounds.size.width*startCenter.x, 
									button.layer.position.y + bounds.size.height*startCenter.y);
	button.transform = CGAffineTransformMakeRotation(-amplitude*DegToRad);
		
	[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationRepeatAutoreverses:YES];
	[UIView setAnimationRepeatCount:FLT_MAX];
	[UIView setAnimationDuration:0.12];
	[UIView setAnimationDelay:random.GetFloat(0,0.09f)];
		button.transform = CGAffineTransformMakeRotation(+amplitude*DegToRad);
	[UIView commitAnimations];
}
	
	
void StopPotWobble(UIButton* button)
{
	[button cancelAllAnimationsRecursively];
	button.transform = CGAffineTransformIdentity;
	CGPoint anchor = button.layer.anchorPoint;
	CGPoint offset = CGPointMake((0.5f - anchor.x)*button.width, (0.5f - anchor.y)*button.height);
	button.layer.anchorPoint = CGPointMake(0.5f, 0.5f);
	button.layer.position = CGPointMake(button.layer.position.x + offset.x, button.layer.position.y + offset.y);
}
</code></pre><p>Ah yes, and I couldn&rsquo;t find a way to loop the animation infinitely (without using the new UIView animation syntax), so FLT_MAX will have to do :-) Any cleaner way?</p>
<p>If someone has an animation that more closely resembles the iPhone launchboard, I&rsquo;d love to hear about it. Let me know and I&rsquo;ll update this post.</p>]]></content:encoded></item><item><title>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>Quick Notes On Lion</title><link>https://gamesfromwithin.com/quick-notes-on-lion/</link><pubDate>Wed, 21 Sep 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/quick-notes-on-lion/</guid><description>&lt;p&gt;&lt;img alt="Mac OS X Lion" loading="lazy" src="https://gamesfromwithin.com/quick-notes-on-lion/images/Mac-OS-X-Lion.png" title="Mac-OS-X-Lion.png"&gt;A couple of days ago I had the misfortune of getting back home to find my 6 month-old MacBook Pro completely dead (my second Apple laptop casualty in three years&amp;ndash;not a great track record). Long story short, the Apple Store wasn&amp;rsquo;t able to help me in any way other than ship out the laptop for repairs. Since without it I&amp;rsquo;m dead on the water, I bought a 17&amp;quot; MacBook Pro on the spot. They didn&amp;rsquo;t have one with SSD hard drive, so this is most likely going back to the store when I get back my repaired laptop. In the meanwhile, I can continue working and it lets me check out first hand Lion and Xcode 4.&lt;/p&gt;
&lt;p&gt;These are mostly quick notes to myself so I remember what to change when I upgrade my main machine, but I thought other developers hesitant to upgrade to Lion might find it useful as well.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Mac OS X Lion" loading="lazy" src="/quick-notes-on-lion/images/Mac-OS-X-Lion.png" title="Mac-OS-X-Lion.png">A couple of days ago I had the misfortune of getting back home to find my 6 month-old MacBook Pro completely dead (my second Apple laptop casualty in three years&ndash;not a great track record). Long story short, the Apple Store wasn&rsquo;t able to help me in any way other than ship out the laptop for repairs. Since without it I&rsquo;m dead on the water, I bought a 17&quot; MacBook Pro on the spot. They didn&rsquo;t have one with SSD hard drive, so this is most likely going back to the store when I get back my repaired laptop. In the meanwhile, I can continue working and it lets me check out first hand Lion and Xcode 4.</p>
<p>These are mostly quick notes to myself so I remember what to change when I upgrade my main machine, but I thought other developers hesitant to upgrade to Lion might find it useful as well.</p>
<h2 id="things-that-had-to-go">Things that had to go</h2>
<p>I found Snow Leopard (and Leopard before it) to be very palatable out of the box. I don&rsquo;t remember any things I absolutely had to do. Lion, however, had some questionable defaults. Or at least, ones that I just can&rsquo;t take.</p>
<p>After making these changes, Lion was quite usable:</p>
<ul>
<li>
<p>Turn off &ldquo;natural&rdquo; scroll direction. The fact that before you can run Lion for the first time it forces you to scroll that way should be a tip off that people aren&rsquo;t ready for this one yet. Maybe in a few years it will make sense to have it as the default, but now it&rsquo;s just against every single computer out there (including most Macs).</p>
</li>
<li>
<p>Autocorrect. This is not an iPhone. It *has* a perfectly fine keyboard. Thank you.</p>
</li>
<li>
<p>Setting up Spaces. Oh, excuse me, Mission Control (sigh). This is the one I was really afraid of. I absolutely rely on having about 8 spaces (2 monitors in each) open at all times and swapping with a keystroke. That&rsquo;s something that I&rsquo;ve been using for many years (first in Linux, then hacked onto Windows XP, and finally in Leopard/Snow Leopard). I just absolutely have to have that.</p>
<p><strong>Update:</strong> There are still a couple annoying things with the new setup. You can&rsquo;t see the number of the desktop you&rsquo;re currently on, like you did with earlier versions of OS X. <a href="https://twitter.com/#!/daniel_collin/status/116889821707902976">Daniel Collin</a> pointed me to an <a href="http://stackoverflow.com/questions/6768684/osx-lion-applescript-how-to-get-current-space-from-mission-control">interesting thread on StackOverflow</a> where people are discussing how to get access to desktop numbers. Give it a few more weeks. Also, when you restart the computer, Lion is smart enough to restore all the apps to their last state&hellip; except that they&rsquo;re all opened in the first desktop, not in the one they were when the system restarted. How difficult would that have been? Here&rsquo;s hoping it&rsquo;s fixed in a patchupdate soon.</p>
<p>The good news is that it&rsquo;s possible to set up Lion that way. The bad news is that by default, it&rsquo;s quite far from that. Bring up Mission Control and create by hand as many desktops as you want. Then go to System Settings | Keyboard | Keyboard Shortcuts and turn on one for each desktop. And for the love of god, please go to Mission Control settings and turn off &ldquo;Automatically rearrange spaces based on most recent use&rdquo;. Clearly Apple doesn&rsquo;t think people want to go to a space directly, and instead prefer to browse them one at the time.</p>
</li>
</ul>
<p>The next few changes just made my experience better, but they&rsquo;re not absolutely musts:</p>
<ul>
<li>This might sound dumb, but Finder didn&rsquo;t have a good way to easily browse my files. Instead, it has this weird &ldquo;All My Files&rdquo; view that jumbles together all your junk there. I have no idea who thought that was a good idea. Maybe Apple is trying to wean users from browsing around the file system. In any case, you can drag your home directory to the sidebar in Finder and that makes it much easier to browse. While you&rsquo;re at it, turn off the &ldquo;Hide extensions in files&rdquo; dumb setting.</li>
<li>Having used a Mac for several years, I&rsquo;m much more sensitive to ugly UI elements. That&rsquo;s why it&rsquo;s so weird that, by default, Lion has the sidebar font in all programs just very slightly larger than the regular system font. Fortunately I wasn&rsquo;t the <a href="http://navinpeiris.com/2011/07/23/os-x-lion-change-finder-sidebar-font-size/">only one bothered by that and it&rsquo;s an easy fix</a>.</li>
</ul>
<p>That&rsquo;s about it. Lion is not very nice and usable (i.e. looks like Snow Leopard). You have that weird &ldquo;full screen&rdquo; button on the top right of all windows, but that&rsquo;s much better ignored (which funny that, was the feature Apple really pushed in their PR for Lion). I have no idea why anyone would want to use that other than the usual word processor that blocks out everything else. If I want to have crippled multitasking, I&rsquo;ll just use the iPad.</p>
<h2 id="good-things-about-lion">Good things about Lion</h2>
<p>So far, if all I&rsquo;m going to do is disable new features so it looks like Snow Leopard, is there there any reason to upgrade to Lion? I surprised myself, but the answer is yes (although they&rsquo;re all very, very minor).</p>
<ul>
<li>Resize a window in any corner and cursor feedback (finally, only 20 years late to the party).</li>
<li>Perfect contact and calendar syncing with Google. I can&rsquo;t tell you how much I appreciate that. I use Google as the backend for all my mail, calendar, and contacts. With Snow Leopard you could sync them, but you had to do some digging and mess around with the sync program. With Lion it works out of the box. Totally awesome. That alone makes it worth the upgrade.</li>
<li>Much improved Mail UI: Better layout, better shortcuts, better conversation view, and, my favorite by far, finally an Archive command for Gmail. Archive doesn&rsquo;t exactly do the same as archiving in Gmail, but it&rsquo;s close enough. Finally I can have two different keyboard shortcuts: One for trashing an email and another one for archiving it.</li>
<li>The jury is still out on how Lion restores the application state when you launch an app. I&rsquo;ve been pleasantly surprised a couple of times, and annoyed a couple other times that I had to close a bunch of useless tabs. Maybe there&rsquo;s a shortcut like Shift + Cmd + Q that quits and app without saving state? That&rsquo;d be handy (OK, that one is not it :-) Oh wow, it&rsquo;s Option + Cmd + Q! I love it when something makes sense like that and you can guess it. OK, so that makes this feature very cool.</li>
<li>Slightly improved Safari (better download management). I really don&rsquo;t see a reason to use Firefox or Chrome when you can use the preinstalled Safari. But then again, I can&rsquo;t stand web UIs and I use native clients for lots of things.</li>
</ul>
<h2 id="must-have-apps">Must-have apps</h2>
<p>It&rsquo;s actually quite refreshing to use the bare minimum number of extra apps beyond what comes with the OS. But there are some apps I just have to have in order to do anything. The main two are <a href="https://agilebits.com/products/1Password">1Password</a> and <a href="http://www.alfredapp.com/">Alfred</a>. I can&rsquo;t recommend them highly enough. They completely change how I work and make me ten times as productive (you&rsquo;ve probably noticed by now that I&rsquo;m not a mouse person).</p>
<p>After those two awesome super-apps, is the second tear of very useful ones: <a href="http://selfcoded.com/app/justnotes/">JustNotes</a>, <a href="http://culturedcode.com/things/">Things</a>, and <a href="http://www.barebones.com/products/textwrangler/">TextWrangler</a>.</p>
<p>Probably <a href="http://www.dropbox.com/">Dropbox</a> should be there somewhere, but for some reason, I still haven&rsquo;t felt the need to use it heavily. I know some people put almost everything on Dropbox and can use across computers. Maybe it&rsquo;s because I only have one that I haven&rsquo;t felt the need for it too much. 1Password and Things both sync from the iPhone so it was really handy restoring all my data. I probably could have done the same thing with Dropbox.</p>
<p>Tomorrow I&rsquo;ll post similar quick notes about Xcode 4. Those might not be quite as positive though.</p>]]></content:encoded></item><item><title>URL Shorteners In Under Two Minutes</title><link>https://gamesfromwithin.com/url-shorteners-in-under-two-minutes/</link><pubDate>Fri, 26 Aug 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/url-shorteners-in-under-two-minutes/</guid><description>&lt;p&gt;This morning I added the goo.gl URL shortener to Flower Garden, so I thought a quick post with sample code might be helpful for other developers looking to do something similar.&lt;/p&gt;
&lt;p&gt;I use the URL shortener in Flower Garden to send bouquets through SMS. Space is limited in a text message, so the message just contains some text explaining what is it and the URL pointing to the bouquet image. (Yes, I would much rather send them through MMS, but Apple isn&amp;rsquo;t exposing that yet to developers).&lt;/p&gt;
&lt;p&gt;&lt;img alt="Sms" loading="lazy" src="https://gamesfromwithin.com/url-shorteners-in-under-two-minutes/images/sms.png"&gt;&lt;/p&gt;
&lt;p&gt;In this case, the full URL is &lt;a href="http://flowers.snappytouch.com/sms.php?id=949618b4b3c6f3d76e32b45446e238a0"&gt;http://flowers.snappytouch.com/sms.php?id=949618b4b3c6f3d76e32b45446e238a0&lt;/a&gt; which gets thankfully shortened to &lt;a href="http://goo.gl/IV5cq"&gt;http://goo.gl/IV5cq&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This morning I added the goo.gl URL shortener to Flower Garden, so I thought a quick post with sample code might be helpful for other developers looking to do something similar.</p>
<p>I use the URL shortener in Flower Garden to send bouquets through SMS. Space is limited in a text message, so the message just contains some text explaining what is it and the URL pointing to the bouquet image. (Yes, I would much rather send them through MMS, but Apple isn&rsquo;t exposing that yet to developers).</p>
<p><img alt="Sms" loading="lazy" src="/url-shorteners-in-under-two-minutes/images/sms.png"></p>
<p>In this case, the full URL is <a href="http://flowers.snappytouch.com/sms.php?id=949618b4b3c6f3d76e32b45446e238a0">http://flowers.snappytouch.com/sms.php?id=949618b4b3c6f3d76e32b45446e238a0</a> which gets thankfully shortened to <a href="http://goo.gl/IV5cq">http://goo.gl/IV5cq</a>.</p>
<p>Sending bouquets through SMS has been in Flower Garden for several months, but it was using bit.ly before, which is probably the most popular URL shortener out there. I like their web interface and their super-easy to use API, but unfortunately it seems that I hit some mysterious API limit during the Mother&rsquo;s Day Flower Garden promotion. That limit isn&rsquo;t public anywhere, and as far as I can tell, I can&rsquo;t even see it myself through the web interface or through an API query.</p>
<p>Finding out that I reached the API limit was quite shocking, because sending bouquets through SMS isn&rsquo;t a particularly popular feature. Unfortunately I don&rsquo;t have <a href="/analytics-for-ios-games/">good analytics hooked up to that step</a>, but I can&rsquo;t imagine there were more than a few thousand per day.</p>
<p>They were very nice and contacted me instead of shutting down my account since it was just a spike. They also tried to sell me their &ldquo;Enterprise&rdquo; account, but $995/month is a tad too expensive for me. By about $990 probably, so I had to look for other options.</p>
<p>After a very quick research, <a href="http://googlesystem.blogspot.com/2011/01/api-for-google-url-shortener.html">goo.gl</a> was the perfect alternative. Not only is it very fast (and backed up by the giant Google no less), but they have an API limit of 1,000,000 queries/day. If I ever blow that budget, I&rsquo;ll be able to afford the $995/month without a problem :-)</p>
<p>All URL shorteners are very easy to use. You need an API key, and figure out the exact format of the HTTP message you send and the response you get.</p>
<h3 id="googl">goo.gl</h3>
<p><a href="http://goo.gl">Goo.gl</a> has a great <a href="http://code.google.com/apis/urlshortener/v1/getting_started.html">Getting Started Guide</a> that tells you everything you need to know. Get your private API key from <a href="https://code.google.com/apis/console">here</a>, and you&rsquo;re ready to rock.</p>
<p>Drop this in your app and start shortening away. You&rsquo;ll notice I used a synchronous HTTP request, which is usually a big no-no. Here I felt it was justified since the user is blocked waiting for the SMS to be prepared and sent. Besides, goo.gl is very, very fast, so it&rsquo;s never even noticeable.</p>
<pre tabindex="0"><code>const NSString* GooGlAPIURL = @&#34;https://www.googleapis.com/urlshortener/v1/url?key=YOUR_API_KEY_HERE&#34;;

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

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

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

	NSString* response = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
	return response;
}
</code></pre><p>That&rsquo;s it. You should be able to drop in either one of those snippets in your project and spend your time working on the things that really matter in your games.</p>]]></content:encoded></item><item><title>Analytics For iOS Games</title><link>https://gamesfromwithin.com/analytics-for-ios-games/</link><pubDate>Thu, 25 Aug 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/analytics-for-ios-games/</guid><description>&lt;p&gt;Unlike a lot of console and PC games, most mobile and web games keep evolving over time &lt;a href="#1"&gt;[1]&lt;/a&gt;. It&amp;rsquo;s up to a game&amp;rsquo;s designers to ultimately decide how to change and improve the game, but the more data about players&amp;rsquo; habits they have, the more informed a decision they&amp;rsquo;ll be able to make. Having good analytics on iOS games is simply essential these days.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Unlike a lot of console and PC games, most mobile and web games keep evolving over time <a href="#1">[1]</a>. It&rsquo;s up to a game&rsquo;s designers to ultimately decide how to change and improve the game, but the more data about players&rsquo; habits they have, the more informed a decision they&rsquo;ll be able to make. Having good analytics on iOS games is simply essential these days.</p>
<p>Recording particular events as part of the analytics is only part of it. The most important part is how that data is presented to the developer. Having tables with millions of entries does me no good, and as a busy indie developer, I can&rsquo;t afford to spend hours writing scripts to analyze it. I want something that allows me to easily visualize the data and makes sense out of it at a glance.</p>
<p>One possible snagging point about analytics is that Apple was cracking down on some applications with analytics enabled a while back. Specifically, the <a href="https://developer.apple.com/programs/terms/ios/standard/ios_standard_agreement_20110215.pdf">iOS developer agreement</a> states:</p>
<blockquote>
<p>3.3.9 You and Your Applications may not collect user or device data without prior user consent, and then only to provide a service or function that is directly relevant to the use of the Application, or to serve advertising. You may not use analytics software in Your Application to collect and send device data to a third party.</p>
</blockquote>
<p>Where does that leave us? Reading it carefully, it seems that the restrictions are limited to &ldquo;user or device data&rdquo;. I&rsquo;m interpreting that to mean things like UDIDs and emails, not anonymous player usage data (how long did it take to reach level 5, how long are play sessions, etc), so I think we&rsquo;re clear there.</p>
<p>The puzzling thing is that a lot (all?) of the third party analytics libraries do report device information, like what kind of hardware or iOS version is running. That is extremely important information that developers really benefit from knowing, but it seems to go against point 3.3.9. Maybe &ldquo;device data&rdquo; only applies to information about that specific device? (as in, <a href="http://venturebeat.com/2011/08/23/ios-5-udid-privacy/">the UDID that is now going away</a>). I hope so.</p>
<p>Not having analytics isn&rsquo;t really an option. Unless you make a game that you plan to throw on the App Store, never touch again, and hope for the best, you&rsquo;re flying blind without analytics.</p>
<p>What are some of the options we have then?</p>
<h3 id="home-brewed">Home brewed</h3>
<p>If you read this blog regularly, you probably know that I&rsquo;m a <a href="/360idev-cranking-up-floating-point-performance-to-11/">low-level</a>, do-it-myself kind of guy, with <a href="/my-fear-of-middleware/">a deep mistrust and suspicion of middleware</a>. So you would think that I would want to write my own analytics package. After all, how hard can it be? Collect the data you want and ping your server with it. If you get fancy, you can even use a scalable server back end like <a href="http://aws.amazon.com/">AWS</a> or <a href="http://code.google.com/appengine/">GAE</a>. Done.</p>
<p>Not so fast. To do that well, it&rsquo;s a lot more involved than that. You want to batch when you send out the information, and you might want to distinguish between WiFi and 3G connection (to avoid causing extra data usage for players on a limited data plan).</p>
<p>That in itself is not even that bad. The real pain comes in visualizing that data, and that&rsquo;s where you can easily sink in days or weeks, and you would still not have something as good as some of the other alternatives.</p>
<p>The other drawback is that if you have some successful applications, you may be generating Terabytes of data per day. Think about the storage and bandwidth costs for that. Yes, I know that sounds insane, but Playfish reported generating that much analytics data at a <a href="http://www.gdcvault.com/play/1014544/Scaling-Social-Games-What-Game">GDC 2011 talk</a> (<a href="http://www.gdcvault.com/play/1014543/Scaling-Social-Games-What-Game">video for paid GDC Vault members</a>).</p>
<h3 id="flurry">Flurry</h3>
<p><a href="http://www.flurry.com/product/analytics/index.html">Flurry Analytics</a> appears to be the most common analytics package out there among my indie iOS dev friends. It&rsquo;s free and it&rsquo;s easy to integrate. The visualization page is pretty good, and it even offers some fancy features beyond session length and events, such as flow through the application.</p>
<p>So what&rsquo;s not to like? I was never able to make heads or tails of the application flow. When you get at that level, you start needing to spend some serious time making sense of data, which is what I don&rsquo;t have as an indie. The web page to visualize the data is written in Flash, so for those of you using an iPad to check it, it&rsquo;s not a good option. <strong>Update:</strong> Flurry apparently added a Flash-free web page since I last looked at it a few months back. Thanks Charilaos Kalogirou for the tip.</p>
<p>The killer deal for me was bloat. Adding the Flurry analytics library to an app increased the executable size by 500KB. I&rsquo;m sorry, but that&rsquo;s completely unacceptable for me. Memory is tight, and half a MB is very significant. I would rather add another large texture or another music track. And if you think about it, why does it need 500KB to buffer and send some events? That&rsquo;s simply ridiculous.</p>
<h3 id="google-analytics">Google Analytics</h3>
<p>I never actually tried out <a href="http://code.google.com/mobile/analytics/docs/iphone/">Google Analytics</a>. They have an iOS SDK and it integrates quite well into the web page Google Analytics environment. The main drawback I heard from other developers is that it&rsquo;s designed more for web pages rather than for apps and games, so it wasn&rsquo;t a perfect fit.</p>
<p>Anyone who used it want to expand on this in the comments?</p>
<h3 id="localytics">Localytics</h3>
<p><a href="http://www.localytics.com/app-analytics/">Localytics</a> is a relative newcomer to the iOS analytics field, but it was love at first sight for me.</p>
<p>It has the same ease of integration of Flurry, and it provides very similar functionality. Localytics, however, is completely open source, so instead of a black box library, you get the source code and you can add it directly to your game. How much does it increase executable size? 4KB! You have to wonder what the other 496KB were for in the Flurry library.</p>
<p>As a bonus, their visualization web page works great on an iPad, although it can be a bit slow for very large data sets sometimes.</p>
<p>One of their biggest selling points is that they report the analytics in real time, but I really don&rsquo;t care one way or another. Waiting 12 or 24 hours to see the analytics doesn&rsquo;t bother me one bit.</p>
<p>Unlike Flurry, you can only add strings as parameters to events. That works fine if I have a set of discrete options. For example, when someone sends a bouquet in Flower Garden, I can send a &ldquo;bouquet sent&rdquo; event with a parameters that is &ldquo;email&rdquo;, &ldquo;facebook&rdquo;, or &ldquo;sms&rdquo;. As a result, I can see a nice pie chart with the breakdown of how people are sending bouquets. Very useful stuff!</p>
<p>But how about things that don&rsquo;t have discrete options? For example, in Casey&rsquo;s Contraptions, we wanted to see how long players take to solve each level. It turns out you can&rsquo;t have a number as a parameter, but you can easily get around that by discretizing it yourself, which in the end, is easier to visualize. So when we send the LevelXXFinished event, we look at how long the player took to finish it, and we break it down into ranges: under 30s, 30s-1min, 1min-2min, etc.</p>
<p>This is what the report looks like for one of Casey&rsquo;s Contraptions levels:</p>
<p><img alt="Piechart" loading="lazy" src="/analytics-for-ios-games/images/piechart.png"></p>
<p>It looks like a fairly balanced level with the majority of the people spending under 3 minutes to solve it.</p>
<h3 id="random-tips">Random tips</h3>
<p>A couple random things we learned along the way about analytics:</p>
<ul>
<li>Less is more. Start with just a few events and go from there. If you have tons of data, you might never have the time to look at it.</li>
<li>Use analytics during playtesting. One thing is what people tell you, and another thing is what they really do. Since most of our playtesting is done remotely and we can&rsquo;t observe as people play (which is invaluable), we can at least gather some hard data about it.</li>
<li>Turn off analytics reporting in debug mode. Trust me on that one.</li>
</ul>
<p>How about you? What&rsquo;s your favorite analytics package and why?</p>
<p>[1] For example, Flower Garden has been on the App Store for almost two and a half years, and it has changed radically in that time!</p>]]></content:encoded></item><item><title>Casey's Contraptions Postmortem</title><link>https://gamesfromwithin.com/caseys-contraptions-postmortem/</link><pubDate>Tue, 26 Jul 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/caseys-contraptions-postmortem/</guid><description>&lt;p&gt;&lt;img alt="Banner" loading="lazy" src="https://gamesfromwithin.com/caseys-contraptions-postmortem/images/banner.png"&gt;&lt;/p&gt;
&lt;p&gt;Casey&amp;rsquo;s Contraptions is an iOS game created by the two of us, &lt;a href="http://twitter.com/#!/noel_llopis"&gt;Noel Llopis&lt;/a&gt; and &lt;a href="http://twitter.com/#!/mysterycoconut"&gt;Miguel Ã ngel Friginal&lt;/a&gt;. Noel, an industry veteran for over a decade, turned indie over four years ago and found success with microtransaction-based &lt;a href="http://www.snappytouch.com/flowergarden"&gt;Flower Garden&lt;/a&gt; on iOS. Miguel worked as a graphic designer in the advertising industry for years before becoming a web developer. Casey&amp;rsquo;s Contraptions is his first published video game, although his first paper role-playing game came out almost 20 years ago. We met through Twitter several years ago, and then finally in person at a 360iDev conference. Even thought we didn&amp;rsquo;t plan it that way, we ended up working together during a game jam, and that set us in the path to collaborate in a future project.&lt;/p&gt;
&lt;p&gt;We knew we wanted to target iOS for our next project because we love the platform from a user and a developer point of view, and because it&amp;rsquo;s a platform where it&amp;rsquo;s possible for indies to succeed financially. Beyond that, starting a new game is never easy. Even though we have page after page of possible ideas, settling on a specific game idea is always very hard. We wanted something that met three requirements: The game had to be creative in nature as opposed to using destruction as the main gameplay element, it had to be something we were excited about, and it had to be something with the potential to sell reasonably well on the Apple App Store. Easier said than done!&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Banner" loading="lazy" src="/caseys-contraptions-postmortem/images/banner.png"></p>
<p>Casey&rsquo;s Contraptions is an iOS game created by the two of us, <a href="http://twitter.com/#!/noel_llopis">Noel Llopis</a> and <a href="http://twitter.com/#!/mysterycoconut">Miguel Ã ngel Friginal</a>. Noel, an industry veteran for over a decade, turned indie over four years ago and found success with microtransaction-based <a href="http://www.snappytouch.com/flowergarden">Flower Garden</a> on iOS. Miguel worked as a graphic designer in the advertising industry for years before becoming a web developer. Casey&rsquo;s Contraptions is his first published video game, although his first paper role-playing game came out almost 20 years ago. We met through Twitter several years ago, and then finally in person at a 360iDev conference. Even thought we didn&rsquo;t plan it that way, we ended up working together during a game jam, and that set us in the path to collaborate in a future project.</p>
<p>We knew we wanted to target iOS for our next project because we love the platform from a user and a developer point of view, and because it&rsquo;s a platform where it&rsquo;s possible for indies to succeed financially. Beyond that, starting a new game is never easy. Even though we have page after page of possible ideas, settling on a specific game idea is always very hard. We wanted something that met three requirements: The game had to be creative in nature as opposed to using destruction as the main gameplay element, it had to be something we were excited about, and it had to be something with the potential to sell reasonably well on the Apple App Store. Easier said than done!</p>
<p>We prototyped game idea after game idea, and even though a lot of them were not bad, none were a complete standout. Eventually, after seven or eight different prototypes, we settled on the concept of creating physics-based, Rube Goldberg-like contraptions to solve different puzzles. At its core, the game has similar mechanics to some classic games like The Incredible Machine, but with an emphasis on exploration of creative solutions rather than finding the one right answer to each puzzle, designed around sharing, and built from the ground up for a touch interface on iOS.</p>
<p>We structured this project as a pure 50-50 partnership, and without any external funding or publishers. Miguel quit his full time job (as a web programmer no less!) to do the art for Casey&rsquo;s Contraptions, and Noel took care of the programming. Design was a fully collaborative activity, where we both contributed equal amounts to everything from the rules, the feel of the game, or level creation. Everything else we split up based on our strengths and expertise: web site, server back end, PR, etc.</p>
<p>This is not a true postmortem, but more of a post-launch analysis. Games today, and especially iOS and Facebook games, are becoming more of a service rather than a product. Development and launch are only the beginning of the story. If all goes well, we&rsquo;ll have a lot more to say about Casey&rsquo;s Contraptions in a few months.</p>
<h2 id="what-went-right">What went right</h2>
<h3 id="strong-theme-and-style">Strong theme and style</h3>
<p>Casey&rsquo;s Contraptions started life without Casey! The initial prototype focused only on the creation of contraptions and the physics simulation behind it. It showed a lot of potential, but it was missing something to make it stand out. It needed more personality.</p>
<p>After some brainstorming, we quickly zeroed-in the idea of a smart 8 year old building the contraptions. Not only did that add the much-needed personality to the game, but it also focused the rest of the development. Instead of doing a physics game with generic pulleys and levers and other industrial-looking items, we naturally went with toys and household items Casey could have access to: His sister&rsquo;s doll, paper planes, or his RC truck.</p>
<p>The choice of toys as game items not only influenced the level design, but also the goal of the levels. At the beginning we were thinking of doing levels to accomplish tasks Casey would have to deal with in real life, such as putting toys away or popping a balloon. After a while, the idea of â€œplaytimeâ€ levels came up, where the setting and the goal were completely imaginary (rescue explorers from a jungle in their hot air balloon) just as Casey would have imagined during his playtime sessions.</p>
<p>The character of Casey also helped anchor the art direction. We were aiming for something that would appeal to a very wide range of people, from the very young to adult casual gamers. Although Miguel looked into everything from a most modern Cartoon Network style to manga, to crazier Warner Bros., we ended up settling with a mix of Calvin &amp; Hobbes and something out of a 50s Hanna-Barbera show, with strong outlines and solid colors, to make people of all ages feel comfortable with the visuals. We were able to carry this distinct style to all the items, locations, and user interface in the game, which gave it a very consistent and unique look.</p>
<p><img alt="CaseyEvolution" loading="lazy" src="/caseys-contraptions-postmortem/images/CaseyEvolution.jpg"></p>
<h3 id="social-features">Social features</h3>
<p>Creating something is fun, but creating something and being able to share it with people is twice as much fun. We wanted to make Casey&rsquo;s Contraptions a very social experience from the start. Not something that you played through and put away, but something you could share with friends along the way.</p>
<p>Since Casey&rsquo;s Contraptions uses a full physics simulation at its core, it&rsquo;s possible to come up with very unique, chaotic, and often unexpected solutions to most puzzles. Weeks after launch, we&rsquo;re still amazed at how some people are solving some levels, coming up with item combinations we never thought about during development. Since these solutions are very unique and fun to watch, they were a perfect candidate to share with friends.</p>
<p>With that in mind, we designed the game with sharing from the start. After you complete each level, you can share your solution with all your friends just with the tap of a button (and, in the latest update, the default is to autosubmit a solution if you improved your score). Your friends&rsquo; solutions are equally accessible, as cropped thumbnails in the level completion screen, and tapping on any of them will bring up a full-screen view that you can even replay and watch the full solution.</p>
<p>In addition to sharing solutions, we also included a level editor to allow players to create their own contraptions from scratch. This was the same level editor we used to create all the levels in the game. Nothing like eating your own dog food to make something solid and usable. Initially, players were able to share these levels through email, and, in the first update, we also added the ability to share them publicly through a web site (<a href="http://shared.caseyscontraptions.com">http://shared.caseyscontraptions.com</a>), effectively giving players access to hundreds of new levels.</p>
<p>As it&rsquo;s the case with most games that include level editors, we were aware that only a small minority of players would take the time to create their own contraptions. But it&rsquo;s also those players that are really devoted to the game, and take it upon themselves to spread the word about your game and champion it to all their friends.</p>
<p><img alt="2" loading="lazy" src="/caseys-contraptions-postmortem/images/2.png"></p>
<h3 id="iterative-development">Iterative development</h3>
<p>For Casey&rsquo;s Contraptions we used a very stripped down and relaxed form of iterative development. We had short iterations and in each iteration we aimed to fully implement what we considered the most important features at the time. We didn&rsquo;t do any real estimating of tasks (other than, â€œyeah, we think we can do that in about two weeksâ€ ), and we didn&rsquo;t set a hard-limit on the iteration (they varied naturally between one and a half and three weeks). The most important concept is that at the beginning of each iteration we would make decisions about what to work on next, and those decisions were made with all the knowledge leading up to that point.</p>
<p>For example, we didn&rsquo;t start the project by coming up with the full list of items we were going to have in the game. Instead, we had a list on the wiki of possible items (to which we would add more whenever we thought of a new one during development), and we only decided which new items to add to the game at the beginning of each iteration. That allowed us to make good decisions based on what we had learned so far: â€œMost objects we have so far fall down. We need more items that add forces upwardsâ€ , or â€œThe magnet is fun, but we need more metal items to make it more usefulâ€ .</p>
<p>This mentality applied to everything: From level creation, to menus, features, etc. Looking back, we can say there&rsquo;s no way we would have made the same decisions early in the project than we did as we went along.</p>
<h3 id="strong-launch">Strong launch</h3>
<p>In less than 24 hours after launch, Casey&rsquo;s Contraptions worked its way up to the top 10 paid apps in the US and in over 20 different countries. A day later, it reached the #2 overall spot in the US and had great initial weekend sales.</p>
<p>This strong launch wasn&rsquo;t just pure luck. It was something we planned months in advance and worked hard to achieve (although we did need a dash of good luck). We wanted to build awareness and buzz around the game, but given the short development cycle for iOS games, we would have to do it in a shortened scale.</p>
<p>We started out by announcing the game more than six months before release (25% of the way into development). During the following months, we continued talking about the game on Twitter and our blogs, often showing work in progress or outtakes. The next big milestone was showing the game around at GDC. Not only did we get a lot of other developers to play it and give us invaluable feedback on it, but we also met with some of the game press, and that resulted in some very nice previews afterwards.</p>
<p>The final push came as soon as we submitted the game to Apple for review. We decided to set a fixed release date three weeks after the submission, which would give us enough time to do all the PR work: creating a video, putting together a media packet, contacting media outlets, etc. In the weeks leading up to the launch, we also stepped up our blogging of different interesting aspects of the game.</p>
<p>As a result of everything we had done up to that point, we were very lucky that Casey&rsquo;s Contraptions attracted Apple&rsquo;s attention, and they featured it prominently on launch day as iPad Game of the Week worldwide. We had given the press enough time with the game, so a lot of very positive game reviews came in right around launch day, helping get the word out for the game.</p>
<p>Even though we had been originally thinking of pricing the game at $4.99, we decided to shoot for volume instead and priced it at $2.99. That turned out to be the right decision and immediately put us on the top 10. Sales on iOS charts follow a sharp, exponential drop off, so being in the top 5 represents a huge increase in sales over just a few positions down the chart.</p>
<p>Looking at the App Store today, it&rsquo;s apparent that it&rsquo;s becoming harder for small, quick games to be really successful and top the charts. With over half a million different apps on the App Store, and hundreds of games released every day, you really need to stand out from the rest to be noticed. Most of the games that manage to do that are ones that required significant time and effort investment and have good production values. The App Store gold rush is over.</p>
<h3 id="enough-development-time">Enough development time</h3>
<p>From start until launch, Casey&rsquo;s Contraptions was in development for 8 months. That seems like a long time by iOS standards, although more and more successful iOS games are starting to take that long.</p>
<p>Our initial plan was to ship the game by Christmas. It wasn&rsquo;t based on any rigorous estimating, just an off-the-cuff estimate. It just â€œfeltâ€ like we could be done by then. Obviously we were wrong.</p>
<p>Taking the amount of time that we did was a very positive thing. We didn&rsquo;t really waste much time, it&rsquo;s just that the game needed that amount of time to mature and get to where it is today. If we had chosen to ship it earlier, the final product would have suffered significantly.</p>
<p>One of the hardest things in a game like Casey&rsquo;s Contraptions is making interesting levels. Having this amount of development time, with a working game editor since the very beginning, allowed us to make a lot of levels along the way. Looking back at a lot of the early levels we made, they were laughably hard and not that interesting. After several months, were able to develop a sense about what made good levels and what the appropriate difficulty was.</p>
<p>Having enough time allowed us to make fairly fundamental changes to the game design when something wasn&rsquo;t working. For instance, initially each level had three different goals you could achieve. Depending on the number of goals you accomplished, you earned a bronze, silver, or gold medal. It quickly became apparent that players were extremely confused by the three goals and weren&rsquo;t able to keep them straight.</p>
<p>We changed levels to have a single goal, but since we still wanted to have some replayability beyond â€œsolvingâ€ a level, we added optional stars you could collect by touching them with any item in the game. The first star would be very easy to get, the second one a bit harder, and the third one would require some serious thinking. That was a huge improvement, but then we discovered that most players expected to get all three stars in their first playthrough, and would stubbornly keep playing the same level until they got them all or quit in frustration. That prompted us to change the stars yet again. This time the difficulty of getting them was tied to the overall level difficulty, so players could easily get all three stars in the early levels. We&rsquo;re very happy with the final design, and we would not have gotten there if the project had been rushed.</p>
<p>We also gave ourselves sufficient time at the end for polish and style. Polish isn&rsquo;t going to make the game design any better, but it&rsquo;s going to contribute a huge amount to first impressions. Every animation, sound, and particle effect becomes really important in those crucial first few seconds with the game. On a mobile platform, polish becomes even more crucial. If your game doesn&rsquo;t immediately engage the player, there are lots of other things they can shift their attention to.</p>
<p><img alt="CaseysContraptions08" loading="lazy" src="/caseys-contraptions-postmortem/images/CaseysContraptions08.jpg"></p>
<h2 id="what-went-wrong">What went wrong</h2>
<h3 id="no-simultaneous-iphone-launch">No simultaneous iPhone launch.</h3>
<p>The initial prototype of Casey&rsquo;s Contraptions was running on an iPhone. While it showed a lot of promise and it was fun to assemble contraptions even that early on, it was clearly begging for more screen space.</p>
<p>The iPad was the obvious platform of choice. Its large screen can display very nicely detailed graphics, and allows for very natural, direct manipulation of items. It was a perfect fit for Casey&rsquo;s Contraptions.</p>
<p>Even so, while there are a lot of iPads out there (14 million), the iPhone and iPod Touch are the undisputed kings of the App Store (about 185 million devices). Especially for a game that relies on the social component, getting a critical mass of users playing at the same time, sharing solutions, and sending levels is very important. We definitely stormed up the iPad charts, but that still left the majority of iOS users not being able to purchase our game.</p>
<p>Why didn&rsquo;t we wait until we had the iPhone version to launch? No particularly good reason other than we were itching to get the game out. We also had no idea what kind of impact a strong launch would have on our servers, so the idea of an iPad-first launch seemed like the way to go. In hindsight, we would have been better off waiting to launch both versions at the same time (or almost the same time, maybe a week or two apart at most).</p>
<p>To make up for this, we&rsquo;re planning on making the iPhone release a second launch of sorts: We&rsquo;ll make the iPhone version coincide with a new game update that includes a lot of new content (for free for people who already bought it), and we&rsquo;ll try to repeat the same strong launch we had on the iPad. The idea is to get everybody who&rsquo;s already bought the game playing again, along with all the new iPhone players and create that critical mass.</p>
<h3 id="butting-heads-too-much">Butting heads too much</h3>
<p>We make the perfect two person team: We have complementary specialties, but we also have a lot of overlapping skills. We also seem to always approach things from opposite ends: Aesthetics vs. usability, performance vs. gameplay, simplicity vs. interest, uniqueness vs. familiarity, or tea vs. coffee. That is actually a really good thing and the success of Casey&rsquo;s Contraptions was in no small part due to our combination of personalities and skills.</p>
<p>There is, however, such a thing as too much of a good thing. We are both very stubborn and it will take a lot to convince us to see things in a different way. There were some times during development that we spent more time debating one point than actually implementing it.</p>
<p>The fact that we&rsquo;re working remotely didn&rsquo;t really affect most of our day to day development, but it definitely made hashing out these situations significantly harder, dragging them out for far longer than they should have. This was also the first time we were working together on a significant project, so it made resolving those situations more difficult. Now that we&rsquo;ve gone through this first project, we&rsquo;ll hopefully be better equipped to handle similar situations in the future.</p>
<h3 id="unnecessary-rework">Unnecessary rework</h3>
<p>Rework is a necessary part of a creative process. You&rsquo;re unlikely to get everything right in the first draft of a text or a music composition. That&rsquo;s even more so the case for game development because there are so many parts interacting with each other. Not only is it hard to predict the exact final outcome, but even if you could, you often don&rsquo;t know exactly what you want until you&rsquo;ve seen one version of it.</p>
<p>Just about every screen and every item in the game went through several revisions of art, behavior, sounds, or layout. There&rsquo;s no doubt that every revision made them better. However, we had a few parts of the game that we had to revise a few too many times. This was mostly in some of the UI screens, like the now infamous â€œlevel completedâ€ screen, or the look and positioning of the in-game menu, which we must have gone through at least 6 or 7 complete redesigns.</p>
<p>We believe that design doesn&rsquo;t just flow one way. If you want the best final product, you can&rsquo;t just decide on the functionality of some user interface (or any part of the game for that matter), implement it, and then give it a pretty face with some graphics. Both the implementation and the graphic design will actually feed back into the functionality of the UI. Once you go around this cycle a few times, you can zero in on a very strong design, both from a functional and a design point of view.</p>
<p>The problem comes when you go around that loop too many times, or when the loop doesn&rsquo;t converge into a particular design, but keeps shifting around. That was often caused because we were fuzzy on some of the details, or when we were forgetting about some particular feature that had to be reworked into the design. Some other times feedback from our testers made us realize that a screen wasn&rsquo;t clear enough as we had designed it and caused us to rework it. As tempting as it was to push through and call it good enough since it was already completely done, it was always the right decision to go back and re-work things as needed.</p>
<p>For example, at the beginning of each level Casey explains what goal you need to achieve. This screen seemed straightforward enough, except that the version we had early on was blocking the view of the level while it was up. Our testers complained it was hard to remember what you had to do without seeing the items it was referring to at the same time, so the final design shows Casey&rsquo;s dialog along the bottom of the screen, and the goal items are even circled with a marker.</p>
<p>We can alleviate this problem by iterating on particular pieces of UI or the game in smaller cycles, without taking each one to completion. Instead of starting by completely implementing a screen, or completely creating a perfect mock up with all the graphic elements, we need to start by laying out a screen with simple boxes and buttons and implement the basic functionality. Then we can make a first pass at a real layout and some graphical element, implement some of the new functionality and animations suggested by that, and continue iterating until it&rsquo;s done. We got much better about this in the last third of development, and it&rsquo;s something we want to carry forward to future projects.</p>
<p><img alt="LevelGoals1" loading="lazy" src="/caseys-contraptions-postmortem/images/LevelGoals1.jpg"><img alt="LevelGoals2" loading="lazy" src="/caseys-contraptions-postmortem/images/LevelGoals2.jpg"><img alt="LevelGoals3" loading="lazy" src="/caseys-contraptions-postmortem/images/LevelGoals3.jpg"></p>
<h3 id="not-enough-unit-testing">Not enough unit-testing</h3>
<p>Noel is a big fan of unit testing and test-driven development (TDD). Those are some techniques we used in past projects to very good effect and something we definitely wanted to carry into Casey&rsquo;s Contraptions as well.</p>
<p>The goal was never to have 100% unit-test coverage or write every single line of code through TDD, but to write only the tests that would benefit the project. That usually meant some code that a lot of other code relied on (the game item management), or something complicated (toolbox interaction), or something prone to breaking (rope manipulation).</p>
<p>In the end, we slipped to the side of not having as many unit tests as we would have liked. Some things like object attachments kept repeatedly giving me headaches during development because of the complicated, untested code. By the time we noticed those problems and wanted to start adding tests, it was too late because some of that code relied on non-unit test friendly APIs like UIKit or Box2d.</p>
<p>We should have taken the time when those problems started appearing to start writing some tests and slowly refactor the code as we fixed the bugs and added new features. Instead, since we seemed to be constantly â€œjust a few months away from shippingâ€ , we decided to skip that and definitely paid the price later on. We even shipped with a few off edge cases that we knew were buggy but we didn&rsquo;t dare fix weeks before submission.</p>
<p>We&rsquo;re already working on updates and and an iPhone version of Casey&rsquo;s Contraptions, so we&rsquo;ll continue dealing with that code for quite a while to come. We&rsquo;ll slowly introduce unit tests in areas of the code that we need to revisit during this time.</p>
<h3 id="fixed-price-model">Fixed price model</h3>
<p>The pricing model is something we went back and forth about several times during development. In spite the long-term success of Flower Garden and other free games with microtransactions on the App Store, we chose to go with a fixed-price model for Casey&rsquo;s Contraptions.</p>
<p>We thought our audience would appreciate a traditional fixed-price model better than a microtransaction-based one. We also figured it was a model that was working well for other similar iPad games such as Angry Birds or Cut The Rope, so it made sense to follow their lead on that.</p>
<p>Unfortunately it seems that might have been the wrong decision from a financial point of view. After a really strong initial launch, Casey&rsquo;s Contraptions dropped down the charts very rapidly after just a few weeks. Since revenue follows a very sharp exponential drop off, even being in the top 100 iPad games means very little revenue per day, and points to a very thin â€œtailâ€ to the sales curve.</p>
<p>In spite of the bad reputation microtransaction games have in traditional game development circles, they&rsquo;re a lot harder to develop than single-purchase, fixed-price games. Not only do you need to implement very robust server features, but you need to finely balance the in-game economy, the pace of rewards, and the cost of new purchases. Our optimistic estimate was that it would add at least a full month to the development time (and given how our estimates were, it probably meant two months for real).</p>
<p>A possible alternative would be to have a traditionally-priced game, but offer new levels or locations as extra purchases. This would have been a lot simpler to implement, but it probably wouldn&rsquo;t have made much difference in revenue. Usually, only about between 2% and 5% of the players buy any extra content, so for microtransactions to really pay off, they need to be unlimited (in-game currency, fertilizer, etc), or have a very large user base. With a small, fixed amount of possible things to buy, we would need to rely on having lots of players to make much of a difference.</p>
<p>We&rsquo;re hoping releasing the iPhone version will generate lots of renewed interest in Casey&rsquo;s Contraptions, spur lots of sales on both platforms, and hopefully increase the long-term chart staying power. If that&rsquo;s not the case, we can always consider the possibility of experimenting by changing the pricing model in the future.</p>
<p><img alt="CaseysContraptions10" loading="lazy" src="/caseys-contraptions-postmortem/images/CaseysContraptions10.png"></p>
<h2 id="conclusion">Conclusion</h2>
<p>We&rsquo;re extremely happy with the development of Casey&rsquo;s Contraptions and with the initial launch. We managed to create a unique game around creativity that was very well received critically and from a sales point of view.</p>
<p>The first free update should be available by the time you read this. It adds the ability to share contraptions with everybody through the web site, as well as browing public contraptions, which should increase the popularity of that feature quite a bit. It also adds some of the most-requested features, such as multiple player profiles for all the parents playing Casey&rsquo;s Contraptions with their children out there.</p>
<p>Unlike a traditional retail game though, the story is far from over. What we do in the next few months will have a very significant impact on the long-term success of the game.</p>
<h3 id="facts">Facts</h3>
<ul>
<li>Web site: <a href="http://www.caseyscontraptions.com">http://www.caseyscontraptions.com</a></li>
<li>Release date: May 19, 2011 (iPad). Summer 2011 (iPhone)</li>
<li>Development time: 8 months</li>
<li>Team size: 2 (full time)</li>
<li>Development cost: Cost of living for 8 months + a tad over $1000</li>
<li>Open source code: Box2d, UnitTest++</li>
<li>Primary tools: Xcode, svn, Versions, Trac, TexturePacker, Adobe Illustrator, Audacity</li>
<li>Lines of code: 46,518</li>
<li>Raw asset size: 510 MB</li>
<li>Total app size: 12.2 MB</li>
<li>Subversion commits: 2442</li>
<li>Trac tickets closed: 683</li>
<li>Gallons of tea brewed: 77</li>
<li>Shots of espresso consumed: around 1500</li>
</ul>
<p><em>This article was initially published on <a href="http://www.gamasutra.com/view/feature/6412/postmortem_llopis_and_friginals_.php">Gamasutra in June 22, 2011</a>. I reprinted it here for completeness, to keep it with all the other Casey&rsquo;s Contraptions articles.</em></p>]]></content:encoded></item><item><title>One Price Does Not Fit All</title><link>https://gamesfromwithin.com/one-price-does-not-fit-all/</link><pubDate>Sun, 24 Jul 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/one-price-does-not-fit-all/</guid><description>&lt;p&gt;A few days ago I gave &lt;a href="http://www.developconference.com/page.cfm/Action=Seminars/SeminarID=20"&gt;a talk at Evolve 2011&lt;/a&gt; (part of the &lt;a href="http://www.developconference.com/"&gt;Develop Conference&lt;/a&gt; in Brighton, England) titled &amp;ldquo;One Price Does Not Fit All&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The main idea of the talk was the importance of &amp;ldquo;flexible pricing&amp;rdquo;: Letting players spend as much money as they want to get more enjoyment out of the game and customize their play experience. Flexible pricing can result in revenues much higher than the traditional fixed price approach (derived from manufactured goods). It&amp;rsquo;s also orthogonal to the concepts of freemium and social games, and we&amp;rsquo;re only scratching the surface in ways to effectively implement it in games.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the official conference abstract:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Did the biggest fans of your game spend more money on it than someone who played it just a few times? If not, you&amp;rsquo;re leaving a huge percentage of money on the table. This session will talk about how digital distribution has made fixed prices obsolete and how you can take advantage of flexible pricing through in-app purchases in your games. We&amp;rsquo;ll also talk about the consequences (good and bad) of making a game free to play. The session will present hard data from iOS platforms, but applies to all digital distribution platforms.&lt;/em&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p>A few days ago I gave <a href="http://www.developconference.com/page.cfm/Action=Seminars/SeminarID=20">a talk at Evolve 2011</a> (part of the <a href="http://www.developconference.com/">Develop Conference</a> in Brighton, England) titled &ldquo;One Price Does Not Fit All&rdquo;.</p>
<p>The main idea of the talk was the importance of &ldquo;flexible pricing&rdquo;: Letting players spend as much money as they want to get more enjoyment out of the game and customize their play experience. Flexible pricing can result in revenues much higher than the traditional fixed price approach (derived from manufactured goods). It&rsquo;s also orthogonal to the concepts of freemium and social games, and we&rsquo;re only scratching the surface in ways to effectively implement it in games.</p>
<p>Here&rsquo;s the official conference abstract:</p>
<p><em>Did the biggest fans of your game spend more money on it than someone who played it just a few times? If not, you&rsquo;re leaving a huge percentage of money on the table. This session will talk about how digital distribution has made fixed prices obsolete and how you can take advantage of flexible pricing through in-app purchases in your games. We&rsquo;ll also talk about the consequences (good and bad) of making a game free to play. The session will present hard data from iOS platforms, but applies to all digital distribution platforms.</em></p>
<p><img alt="Screen shot 2011 07 24 at 12 11 23 PM" loading="lazy" src="/one-price-does-not-fit-all/images/Screen-shot-2011-07-24-at-12.11.23-PM.png"></p>
<p>Answering questions preemptively: I definitely don&rsquo;t think that allowing players to spend the amount of money they want is &ldquo;evil&rdquo; in any way. And someone during the comment came up with a great point: Isn&rsquo;t it more &ldquo;evil&rdquo; to have players spend $60 on a game, just to find out 10 minutes afterwards that they don&rsquo;t like it or it doesn&rsquo;t run very well on their system/network?</p>
<p> </p>
<p>I was going to record the audio, but unfortunately I forgot to turn on Audacity before the talk. Note to self: Start recording when I set up the laptop, even if it&rsquo;s 10 minutes ahead of time.</p>
<p><strong><a href="http://www.slideshare.net/llopis/one-price-does-not-fit-all" title="One Price Does Not Fit All">One Price Does Not Fit All</a></strong></p>
<iframe src="http://www.slideshare.net/slideshow/embed_code/8675456" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="425" height="355"></iframe>
<p>View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/llopis">Noel Llopis</a></p>
<p> </p>
<p>[<a href="http://m.slideshare.net/llopis/one-price-does-not-fit-all">Slideshare mobile</a>] [<a href="/wp-content/uploads/2011/07/Evolve2011_Llopis.pdf">Slides in pdf format</a>]</p>]]></content:encoded></item><item><title>Good Things Take Time</title><link>https://gamesfromwithin.com/good-things-take-time/</link><pubDate>Fri, 01 Jul 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/good-things-take-time/</guid><description>&lt;p&gt;If you&amp;rsquo;ve read this blog recently, you probably know that &lt;a href="http://twitter.com/mysterycoconut"&gt;Miguel&lt;/a&gt; and I are busy working on the iPhone version of Casey&amp;rsquo;s Contraptions. What may be surprising is that we&amp;rsquo;ve been working on it for over three weeks and we&amp;rsquo;re still not done. After all, to make an iPhone version all we have to do is make the project Universal, recompile, and done, right?&lt;/p&gt;</description><content:encoded><![CDATA[<p>If you&rsquo;ve read this blog recently, you probably know that <a href="http://twitter.com/mysterycoconut">Miguel</a> and I are busy working on the iPhone version of Casey&rsquo;s Contraptions. What may be surprising is that we&rsquo;ve been working on it for over three weeks and we&rsquo;re still not done. After all, to make an iPhone version all we have to do is make the project Universal, recompile, and done, right?</p>
<p><img alt="Preview CaseyOniPhone" loading="lazy" src="/good-things-take-time/images/Preview_CaseyOniPhone.jpg"></p>
<p>Are we slacking? Sipping piÃ±a coladas by the beach? Did we grow complacent with the successful launch of Casey&rsquo;s Contraptions on the iPad?</p>
<p><img alt="5862132784 aa27e193f4" loading="lazy" src="/good-things-take-time/images/5862132784_aa27e193f4.jpg"></p>
<p>The reason it&rsquo;s taking so long is that we&rsquo;re not putting out a rushed version of Casey&rsquo;s Contraptions on the iPhone. Instead, we&rsquo;re taking the time to re-work every screen to fit the smaller screen. Even if we could just cram everything into the screen, fingers don&rsquo;t get any smaller on the iPhone, so the target areas need to be just as easy to touch.</p>
<p>This goes beyond just every UI screen. Quick, name a popular iPhone game that can&rsquo;t be played with just your thumbs. I&rsquo;m drawing a blank, and that&rsquo;s for a good reason. The gold standard for iPhone games is whether it can be played with two thumbs. If it can&rsquo;t, then it&rsquo;s probably a bad design. So even though the levels are the same, we&rsquo;re having to make major changes to how objects are manipulated.</p>
<p>In other words, good things take time.</p>
<p>Which reminds me of this wonderful quote from the <a href="http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959/tag=gamesfromwith-20">Mythical Man Month</a>:</p>
<p><em>Good cooking takes time. If you are made to wait, it is to serve you better, and to please you. Menu of Restaurant Antoine, New Orleans</em></p>
<h3 id="all-the-little-details">All The Little Details</h3>
<p>It&rsquo;s more than just doing a good job though. There&rsquo;s often a surprisingly large amount of work involved implementing small parts of a game. Things that, when you do them right, go completely unnoticed, but when you don&rsquo;t, are jarring and irritating. Games are full of examples of things like that, from AI to menu screens.</p>
<p>In this case, I&rsquo;ve spent a whole day and a half getting the behavior of the toolbox area working correctly on the iPhone. On the iPad, the toolbox area is the bottom wooden box that holds the items you can use in the game.</p>
<p><img alt="Ipad toolbox" loading="lazy" src="/good-things-take-time/images/ipad_toolbox.jpg"></p>
<p>On the iPhone, since we&rsquo;re dealing with a different screen aspect ratio, we decided to spend all our screen real estate on the game area, and keep the toolbox hidden. (And yes, since you asked, you can zoom and pan on the game area). Whenever you want to use the toolbox, you press the button and it slides out. Easy isn&rsquo;t it? How could that possibly take a day and a half?</p>
<p><img alt="Iphone toolbox1" loading="lazy" src="/good-things-take-time/images/iphone_toolbox1.jpg"></p>
<p><img alt="Iphone toolbox2" loading="lazy" src="/good-things-take-time/images/iphone_toolbox2.jpg"></p>
<p>That&rsquo;s one of those cases where the devil is in the details.</p>
<ul>
<li>Apart from pushing the button, the player can also tap it and slide in and out. When that happens, we need to detect what you mean with that gesture and finish opening/closing the toolbox after you release the touch.</li>
<li>Whenever the player grabs an item out of the toolbox, we need to close the toolbox so it&rsquo;s not in the way.</li>
<li>Whenever the player grabs an item in game and drag it near the toolbox, it needs to open so you can drop it there.</li>
<li>But dragging an item towards the edge of the screen indicates that you want to move it outsize the zoomed area, so we don&rsquo;t always want to open the toolbox. Only when the player drags it near the button that opens the toolbox.</li>
<li>But perhaps it wasn&rsquo;t possible to scroll down any further (either because we&rsquo;re zoomed out all the way, or we&rsquo;ve moved the camera as far down as it goes), in which case dragging any object anywhere near the bottom of the screen indicates we should open the toolbox.</li>
<li>Of course, it&rsquo;s possible that the player just grabbed an object out of the toolbox, the toolbox closed automatically, and he didn&rsquo;t move the touch near the bottom of the screen. In that case, we want to be aware of that and not open the toolbox.</li>
<li>Dragging an item towards the toolbox, and then away from it should close it since it means the player changed his mind and doesn&rsquo;t want to get rid of it yet.</li>
</ul>
<p>Take all those cases, and make them work with and without zoom. And there are even a few more weird combinations we need to deal with, but you get the idea. If that sounds like crazy, well, it is kind of crazy. Fortunately it was something I was able to implement writing unit tests, so it&rsquo;s pretty easy to modify and update as we need to change things.</p>
<p>For the curious, this is what just a couple of the unit tests look like:</p>
<pre tabindex="0"><code>struct F
{
	F()
	{
		camera.pixelSpaceWidth = GameParams::WorldWidthInPixels;
		camera.centerSS = Vec2(0.5f*GameParams::WorldWidthInPixels, 0.5f*GameParams::WorldHeightInPixels);
	}

	Camera camera;
	ActionQueue actionQueue;
};

TEST_FIXTURE(F, ItemOnBottomRightCornerDoesNotOpenToolbox)
{
	camera.zoomFactor = 2.0f;
	camera.centerSS = ScreenCenter;
	CameraUtils::Update(0.02f, camera, true, Vec2(ScreenCenter.x + 0.5f*ScreenCenter.x, ScreenCenter.y - 0.5f*ScreenCenter.y), false, actionQueue);
	CHECK(camera.triggeredToolboxOpen == false);
	CHECK_EQUAL(0, actionQueue.count);
}

TEST_FIXTURE(F, ItemOnBottomLeftCornerOpensToolbox)
{
	camera.centerSS = ScreenCenter;
	CameraUtils::Update(0.02f, camera, true, Vec2(10, 10), false, actionQueue);
	CHECK(camera.triggeredToolboxOpen == true);
	CHECK_EQUAL(1, actionQueue.count);
	CHECK_EQUAL(ActionType::OpenToolbox, actionQueue.actions[0].type);
}

TEST_FIXTURE(F, ItemOnBottomRightCornerOpensToolboxIfCantScroll)
{
	camera.centerSS = ScreenCenter;
	CameraUtils::Update(0.02f, camera, true, Vec2(GameParams::WorldWidthInPixels, 0), false, actionQueue);
	CHECK(camera.triggeredToolboxOpen == true);
	CHECK_EQUAL(1, actionQueue.count);
	CHECK_EQUAL(ActionType::OpenToolbox, actionQueue.actions[0].type);
}

TEST_FIXTURE(F, ItemOnBottomLeftCornerWithZoomOpensToolbox)
{
	camera.zoomFactor = 2.0f;
	camera.centerSS = ScreenCenter;
	CameraUtils::Update(0.02f, camera, true, Vec2(ScreenCenter.x - 0.5f*ScreenCenter.x, ScreenCenter.y - 0.5f*ScreenCenter.y), false, actionQueue);
	CHECK(camera.triggeredToolboxOpen == true);
	CHECK_EQUAL(1, actionQueue.count);
	CHECK_EQUAL(ActionType::OpenToolbox, actionQueue.actions[0].type);
}
</code></pre><p>When it&rsquo;s all working, if we did our job correctly, all that players will think about is using their toolbox items and none of those weird cases will cross their mind. Things will just work as expected.</p>
<h3 id="one-more-thing">One More Thing</h3>
<p>Here&rsquo;s another example of another task with &ldquo;hidden&rdquo; work to behave as expected. When moving object in place in Casey&rsquo;s Contraptions, and releasing the touch, how many times did the item move slightly because your finger grazed the screen as you released it? I hope the answer is never (or not very often). That&rsquo;s not coincidence. We have some logic in place to detect those really annoying, but very common touch movements as people lift their fingers from the screen. Without it in place, it was pretty frustrating placing pieces accurately. With it, nobody notices because it works as expected.</p>
<p>So next time you find yourself using a smooth user interface, take a second to consider all the work that went into making it as transparent as possible and thank those poor developers.</p>
<p>Next week we&rsquo;ll have a post showing some of the specific changes we had to make for the iPhone and comparing screenshots side by side (let&rsquo;s see if I can get <a href="http://twitter.com/mysterycoconut">Miguel</a> to write that one).</p>
<p>We&rsquo;re convinced that the update will be well worth the wait. To tie you over, I leave you with a video from our friends at <a href="http://pocketgod.blogspot.com/">Bolt Creative</a>.</p>
<iframe src="http://www.youtube.com/embed/I8jkz0pdHk8" frameborder="0" width="640" height="390"></iframe>]]></content:encoded></item><item><title>Writing Reusable Code</title><link>https://gamesfromwithin.com/writing-reusable-code/</link><pubDate>Tue, 21 Jun 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/writing-reusable-code/</guid><description>&lt;p&gt;&lt;em&gt;Some people asked what I meant by a &amp;ldquo;toolkit architecture&amp;rdquo; in &lt;a href="https://gamesfromwithin.com/my-fear-of-middleware/"&gt;the previous post about my middleware fears&lt;/a&gt;. It turns out I wrote about that in a previous Inner Product column that for some reason I never reposted here. I think at the time I wrote this (late 2008), I already wasn&amp;rsquo;t very concerned about writing reusable code, and I was focusing it mostly with respect to using other people&amp;rsquo;s code and how I wanted it to be architected.&lt;/em&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>Some people asked what I meant by a &ldquo;toolkit architecture&rdquo; in <a href="/my-fear-of-middleware/">the previous post about my middleware fears</a>. It turns out I wrote about that in a previous Inner Product column that for some reason I never reposted here. I think at the time I wrote this (late 2008), I already wasn&rsquo;t very concerned about writing reusable code, and I was focusing it mostly with respect to using other people&rsquo;s code and how I wanted it to be architected.</em></p>
<p>As programmers, we&rsquo;re constantly reusing code. Sometimes it&rsquo;s in the form of low-level OS function calls, or game middleware, and sometimes code that our teammates wrote. At the same time, unless you&rsquo;re writing top-level game script code, chances are that the code you&rsquo;re writing will be used by people as well.</p>
<p>I&rsquo;m purposefully avoiding labeling reusable code as &ldquo;libraries&rdquo; or &ldquo;middleware&rdquo;. Those are just two of the many forms in which we end up reusing code. Copying some source files onto your project, calling an API function, or instantiating a class written by someone else in your team, are all different forms of code reuse.</p>
<h2 id="getting-started">Getting Started</h2>
<p>Without a doubt, the most difficult job writing reusable code, is making sure it solves a problem correctly and meets everybody&rsquo;s needs. That&rsquo;s not a easy task when we&rsquo;re writing code for ourselves, but it&rsquo;s much more difficult when we&rsquo;re targeting other programmers. Too many libraries get it only half right, and they solve some problems at the expense of introducing a bunch of new ones. Or they force the user to jump through all sorts of hoops to get the desired result in the end. We need a clear understand of the exact problem we&rsquo;re trying to solve with our code.</p>
<p>Libraries often fall in the trap of presenting an implementation-centric interface. That is, their interface is based on the implementation details of the library, rather than how the users are going to use it in their programs.</p>
<p>The best way I&rsquo;ve found to address both those shortcomings is to start by implementing code that solves the problem for one person. Just one. Forget about multiple users and code reusability for now. If you don&rsquo;t have immediate and constant access to that one person, then you need to play that role and create a game or application that is as close as possible to what one of your users is going to be developing. By using this approach, I find that the interface to the reused code is much more natural, and it&rsquo;s based on the experience of having solved the problem at least once. Otherwise, you run the risk of creating an interface that is not a good fit and forcing everything to conform to it in unnatural ways.</p>
<p>Once you have implemented a solution, take a moment to think before you dive into doing any more work. Many times you&rsquo;ll find there is no reason to abstract it any further since your code is only going to be used in one place. If that&rsquo;s the case, step away from the code and go do something more productive. You can always come back later whenever there is a real need to reuse it later in the project or in a future game.</p>
<p>There are exceptions to this approach of implementing a solution first, and abstracting it later. Some problems are very simple, or very well understood, so we might be able to jump in and implement the reusable solution directly (an optimized search algorithm, or a compression function for example). It&rsquo;s also possible that you&rsquo;ve implemented a similar system several times before, and you know exactly at what kind of level to expose the interface and how things should look like. In that case, it&rsquo;s perfectly valid to draw on your past experience. Just try to avoid the second-system effect: The tendency to follow up a successful, simple first system, by an overly-complex system with all the ideas that didn&rsquo;t make it into the first one. Setting Goals</p>
<p>Most successful reusable code was created with specific goals about how it was meant to be used. Sometimes those goals are explicitly stated, most of the time they are implied in the code design.</p>
<p>Some of the most common goals are flexibility, protection, simplicity, robustness, or performance. You can obviously not meet all those goals at once, and even if you could, you probably shouldn&rsquo;t try. That would be a tremendous waste of time and resources. Stop thinking in the abstract and think about your one user. What does he or she need? What is the most important goal for them?</p>
<p>Many APIs and middleware packages are designed with protection as one of the primary goals: They don&rsquo;t want the user to accidentally do anything wrong. In itself is not a bad goal, and it can often be implemented by having clean, unambiguous interfaces, clearly-named types and functions, and strongly-typed data types. Unfortunately, a design with protection as a main goal can often result in encumbered interfaces, verbose code, slow performance, and inflexible code. There is nothing more frustrating than wanting to do something that is explicitly being protected against, and having to work around the interface.</p>
<p>If your target users are professional game developers, give them the benefit of the doubt and don&rsquo;t try to overprotect all your code. Save that for the scripting API exposed to junior designers and released to the customers with the game. If you&rsquo;re concerned about programmers using your code correctly and not making mistakes, provide good sample code, tests, and documentation. If that&rsquo;s not enough, and you feel that everybody would benefit from some level of protection, try to keep it to a minimum and maybe even provide lower-level functions that bypass it for power users.</p>
<p>Whatever the primary goal, the libraries and APIs I prefer to work with, help me get whatever I need done, while getting out of the way as much as possible.</p>
<h2 id="architecture">Architecture</h2>
<p>There are many different ways to architect code that is intended for reuse. The best approach will depend on the particular code: How complex is it? How much of it is there? What are its goals?</p>
<p>Unless your goals are to make quick, throwaway applications, I strongly recommend against a framework type of architecture (see Figure 1.) A framework is a system in which you add a few bits of functionality to customize your program into an existing system. They may sound like a clean and easy way to use complex code, but they&rsquo;re inevitably very restrictive, and they make it very difficult, if not impossible, to do things with them beyond what they were intended to.</p>
<p><img alt="Framework" loading="lazy" src="/writing-reusable-code/images/framework.png"></p>
<p>A more flexible approach is a layered architecture (see Figure 2.) Each layer is relatively simple and provides a well-defined set of functionality. Higher-level layers build on top of lower-level layers to create more complex or more specific functionality.</p>
<p><img alt="Layered" loading="lazy" src="/writing-reusable-code/images/layered.png"></p>
<p>Keep in mind that it is not necessary, or even desirable, to have higher-level layers completely abstract out and hide the lower-level ones. By letting layers be fully transparent, they allow you to mix and match at what level you want to access the code. This can be very important, especially towards the end of a game when fixing some bugs or trying to squeeze some more performance out of the engine.</p>
<p>For example, one layer can expose functionality to create and manipulate pathfinding networks and nodes, another one can implement searches and other queries on those networks, while a third, higher-level layer, can expose functions to reason on the state of the network.</p>
<p>A toolkit architecture (see Figure 3), is the most flexible of all. It provides small, well-defined modules or functions with very few dependencies on other modules. This allows users to pull in whatever modules they need into their game to meet their needs and nothing else. Users can also start by reusing some modules, and but replace them down the line when they want to go beyond the existing functionality. Because of this, toolkit architectures are particularly well suited to game development.</p>
<p><img alt="Toolkit" loading="lazy" src="/writing-reusable-code/images/toolkit.png"></p>
<h2 id="object-oriented">Object Oriented</h2>
<p>I tend to avoid complex class hierarchies in most of my code, but that&rsquo;s especially important in the case of reusable code. Class hierarchies are very rigid, and impose a particular structure on their users.</p>
<p>If you want to remain object-oriented, a better approach is to emphasize composition of objects instead of inheritance. That allows users to much more easily pull in the functionality they need, and create their own objects based on their own constraints.</p>
<p>You can even go a step further and provide purely procedural interfaces. Plain static functions that operate on data types. Interfaces based on static functions are often much easier to understand and grasp than interfaces that involve classes and inheritance. They are also much more convenient for users to wrap and use in many different ways.</p>
<p>Remember what you learned about object-oriented design and having private data? Forget about it, and keep everything accessible. You may think you&rsquo;re doing the user a favor by making some variables private and reducing the complexity of the interface. That&rsquo;s partly true, but eventually, your users will want to have access to some of those variables that you took pains to hide. And if they really want to, they will get to them, even if it means direct addressing into an object or vtable.</p>
<p>It&rsquo;s true that large codebases can be intimidating, and exposing all the internal details along with the regular interface would make it unwieldy for new users. An effective approach is to separate the public interface from what is intended for internal use only, but still make it available through some other means. For example, private data and functions could be wrapped in a different namespace, or simply in a different set of headers. Anything that clearly sets them apart, and doesn&rsquo;t clutter the initial look at the interface, but that allows experienced developers to get to them and get their hands dirty. Extensibility</p>
<p>As soon as you make your code available to a wide range of developers, you&rsquo;ll find that people want to use it in progressively more complex and bizarre situations. Your code might have completely solved the case of your first couple of users, and since it&rsquo;s layered and modular, it can meet a lot of different requirements. But eventually, some people will start taking it to extremes you hadn&rsquo;t imagined and it falls short for them. What to do?</p>
<p>You could start adding more options and more modules and more callbacks to your code. That way programmers can hook up into almost any part of the code and replace it with their own. The problem with that approach is that you&rsquo;ve taken something that was relatively simple and made it into an large, ugly, fully-customizable, behemoth that tries to keep everybody happy. That sounds like a lot of common APIs we know and hate. Most successful products try to completely meet the need of some people rather than meet everybody&rsquo;s needs part way. Otherwise you inconvenience 95% of your users for the benefit of 5% of them.</p>
<p>A better approach is to let those 5% users fend for themselves, but give them the means to do it. How so? With source code. Without source code, developers feel caged and constrained. They know they can&rsquo;t look behind the interfaces, let alone modify anything in case something goes wrong (and we all know something will go wrong). The more code there is, and the more a project relies on it, the more important it is to have access to the full source code. Many teams will refuse to use some libraries or middleware unless the full source code is available. As soon as you make source code available to your users, you immediately put them more at ease because they feel more in control, and you allow those with special requirements to make whatever modifications they need to do.</p>
<p>Even those developers without a need to modify the code, they will be able to browse the code and see how certain functions are implemented. Not only will it make people much more likely to use your code, but they will probably also fix your bugs and suggest performance improvements, so it&rsquo;s a win-win situation for everybody.</p>
<p>For extra bonus points, the source code should be accompanied by a set of tests. The more comprehensive the better (unit tests, functional tests, etc). Hopefully you created all those tests while you were developing the code, so distributing it along with the source code shouldn&rsquo;t be any extra effort, but it will make a huge difference to your users. It will give them much more confidence modifying the code to suit their needs and still see that all the tests are passing.</p>
<h2 id="upgrades">Upgrades</h2>
<p>As soon as you release some code and you have your first user, the question comes up of how to deal with new versions. There are many ways you can go about it, depending on how often you&rsquo;ll release new versions, and how important it is to maintain backwards compatibility.</p>
<p>On one extreme, you can change the code and the interface to fit new features, changes in architecture, or any other reason. Whenever you release a new version, users will have to choose to remain with their current version or upgrade to the latest and make whatever changes are necessary. This is a common approach in open source projects and internal company code.</p>
<p>On the other extreme, once you release a version, you stick to that interface whether it&rsquo;s a good idea or not. This can be good for users because they can get new versions without any extra work on their part, but it can be very constraining. It can make new features impossible to add, and it can prevent performance optimizations. This approach is more common on code that will become the foundation of many programs, like OS libraries and low-level APIs.</p>
<p>A good compromise is to keep interfaces the same during minor versions, and only change them whenever a major version is released. That way other developers only have to put in the time to upgrade to a major release if they really need the new features at that time.</p>
<p>Another approach is not to change existing functions or classes, but to introduce new ones and slowly deprecate the old ones over time. That way code continues to work, but users can take advantage of the new functions. After a few versions, you can completely drop off deprecated functionality, at which point most people will have upgraded already. If you do this, make sure to label deprecated functions with a #pragma warning or some other way. That way, developers know it will be phased out and they can start thinking about upgrading to the new interface.</p>
<p>The easier you make the transition to the new version, the better for your users, and the more likely they will be continue using your code. For example, you can provide scripts that parse their source code and upgrade it to match the new interfaces. That can be a bit risky, but it can be really worthwhile if you have a lot of required changes that are relatively mechanical (renamed functions, changed parameter order, etc).</p>
<p>Is there any point to all this talk of interfaces if you made your source code available? Yes, very much so. Most developers will look at the source code to know how things work under the hood, but they probably won&rsquo;t modify it. Even if they do, they know that&rsquo;s something they do at their own risk, so they&rsquo;ll be more than willing to make a few changes whenever a new version is released. Everybody else will still definitely benefit from a relatively stable interface.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Writing reusable code starts with solving a problem and solving it well. The rest should all fall from there, and you can pick whichever method is more appropriate for your particular code and how you want to share it.</p>
<p> </p>
<p>This article was originally printed in the March 2009 issue of <a href="http://gdmag.com">Game Developer</a>.</p>]]></content:encoded></item><item><title>My Fear of Middleware</title><link>https://gamesfromwithin.com/my-fear-of-middleware/</link><pubDate>Fri, 17 Jun 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/my-fear-of-middleware/</guid><description>&lt;p&gt;Once upon a time, the idea of using some kind of middleware or major external library in my projects was out of the question. Writing all my code was the one and true way! I had a bad case of &lt;a href="http://en.wikipedia.org/wiki/Not_Invented_Here"&gt;NIH syndrome&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Over the years I&amp;rsquo;ve mellowed out quite a bit. Now I recognize my obsession with writing endless tools and technology was more of an escape from doing the really hard part of game development. In comparison to making all the decisions involved in the design and implementation of the game itself, writing the perfect resource streaming system sounds like a really good time. It&amp;rsquo;s amazing how early it started too: I still remember spending weeks writing a Basic-to-assembly translator in 1986, before I had even heard the word &amp;ldquo;compiler&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Now I just want to make games.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Once upon a time, the idea of using some kind of middleware or major external library in my projects was out of the question. Writing all my code was the one and true way! I had a bad case of <a href="http://en.wikipedia.org/wiki/Not_Invented_Here">NIH syndrome</a>.</p>
<p>Over the years I&rsquo;ve mellowed out quite a bit. Now I recognize my obsession with writing endless tools and technology was more of an escape from doing the really hard part of game development. In comparison to making all the decisions involved in the design and implementation of the game itself, writing the perfect resource streaming system sounds like a really good time. It&rsquo;s amazing how early it started too: I still remember spending weeks writing a Basic-to-assembly translator in 1986, before I had even heard the word &ldquo;compiler&rdquo;.</p>
<p>Now I just want to make games.</p>
<p>I&rsquo;ll gladly use code other people have written as long as they fit my needs. For example, I&rsquo;m very happy with <a href="http://www.box2d.org/">Box2d</a> in <a href="http://www.box2d.org/">Casey&rsquo;s Contraptions</a>. Was Box2d perfect? Far from it, but it was good enough and I&rsquo;m very happy with the tradeoff.</p>
<p>So how come that Casey&rsquo;s Contraptions, apart from Box2d, is all custom code, written in C and OpenGL? Why didn&rsquo;t I use some of the great tools and libraries available like <a href="http://www.cocos2d-iphone.org/">Cocos2d</a> or <a href="http://unity3d.com/">Unity</a>?</p>
<p>In the land of AAA console games, developers routinely pull off the performance card: Only our code will allow us to make something that is so tailored to the hardware that it will make the game stand out above all other games. But for Casey&rsquo;s Contraptions that&rsquo;s not much of an issue: Any of the middleware options would be able to handle that amount of performance on an iPad just fine.</p>
<p>It wasn&rsquo;t a lack of features either. We&rsquo;re not doing anything particularly fancy, and I&rsquo;m sure it would be possible to implement it in almost any other framework.</p>
<p>So if it&rsquo;s not performance of features, why not?</p>
<p><img alt="2373515952 8dbda5be74 m" loading="lazy" src="/my-fear-of-middleware/images/2373515952_8dbda5be74_m.jpg">Creating a game is a craft. It&rsquo;s a mix of art and technique, and the craftsman or artisan has a vision and slowly probes, guides, and implements the final product. As with most crafts, the tools you use are extremely important and will directly affect the final product. If I&rsquo;m going to change my tools and my techniques, the payoff I get needs to be huge to make up for the change. It&rsquo;s as if I give up a set of hand woodworking tools for a power tool. Maybe it will be faster when I&rsquo;m cutting in a straight line, but it will be very different and will completely change what I create.</p>
<p>As a game developer, my main tool is the language I use (C with a dash of C++). Things like editors or IDEs are secondary, and I can easily adapt to different ones without much of a problem (like when going from Visual Studio to Xcode). The way I like to work involves fast iterations, unit tests, very explicit memory layout, and processing data at a global, rather than local (entity) level.</p>
<p>I feel that by going to Unity or Cocos2d, I would have to completely give that up. A lot of middleware are frameworks instead of toolkits. That means I&rsquo;m restricted to implementing bits of code that are embedded in a larger system and called by the rest of the framework. I give up the ability to architect the game in the way I want. Maybe it wouldn&rsquo;t be a big deal if I liked a component or inheritance-based, entity-centered approach like a lot of frameworks, but I don&rsquo;t.</p>
<p>Will I get enough benefits from using one of those frameworks to make up for the loss of productivity and techniques I like to use? Doubtful. All of a sudden I can&rsquo;t just use fwrite on a memory block for serialization, I have to parse data files to load game state, undo/redo isn&rsquo;t as simple as copying a block of memory, rendering becomes much more generic and less tied to the game, I can&rsquo;t easily do test-driven development, iterate quickly, etc.</p>
<p><img alt="Wood Router" loading="lazy" src="/my-fear-of-middleware/images/Wood_Router.jpg">Sometimes, shifting workflows and techniques is inevitable. You may be used to solving collisions in a particular way, but when you move to a full physics engine, you need to process things differently. The payoff you get from using a pre-made physics engine is huge, so it&rsquo;s worth it in my book.</p>
<p>For 2D games, there isn&rsquo;t that much that I need: cross-platform support, simple math functions, ways to load textures, play sounds, and render simple things. Throw in some kind of simple UI display and layout tool, and that&rsquo;s it. The rest I can handle. Actually, that&rsquo;s not true, let me rephrase that: The rest I <strong>prefer</strong> to do myself, because it&rsquo;s always highly dependent on the game.</p>
<p>What I really want is a toolkit-based middleware that does exactly those things without imposing any workflow or architecture on me. It saves me from doing the boring bits, gets out of the way as much as possible, and lets me work the way I want to. That&rsquo;s already what I have with my current code, minus the UI library/tool part, which I&rsquo;m still stuck using mostly UIKit. The idea of using Unity just so I can have cross-platform UI seems total overkill.</p>
<p>Even in the case of middleware that fits my style, I still need to be weary of the quality of the code. The last thing I want to do is trade time implementing my own code for time debugging someone else&rsquo;s crappy code. Also, having learned my lesson years ago, I&rsquo;ve sworn that I will never use a middleware/library that I don&rsquo;t have source code access to. Nothing more frustrating than having to reverse-engineer UIKit classes to work around their bugs just because I don&rsquo;t have the source code.</p>
<p>I&rsquo;m not even going to go in the debate about middleware lock-in, future portability, building tech vs. relying on it, and financial aspects. All those are important, but secondary to how using some middleware will affect my everyday development.</p>
<p>If my next game were a networked, 3D game involving moving some kind of character or vehicle around a world, and I had nothing to start from, then the pain of adopting a foreign workflow and architecture might be worth it. Might. Even though it might be a wash on the code side, the tools and pipeline might be the thing that sways me over to adopt it.</p>
<p>In the end, as an indie developer, I chose to make games because it&rsquo;s something I enjoy doing. I get up every morning excited about it, and I enjoy the development process. Whichever <a href="http://fairyengine.blogspot.com/2011/05/android-experiment-porting-my-xna-game.html">platform</a>, tool, middleware or process I end up choosing, it needs to be enjoyable. The day I&rsquo;m not having fun making my own games, I shouldn&rsquo;t be an indie anymore.</p>
<p>What do you think? Am I being overly paranoid? Is there a good solution out there that&rsquo;s multiplatform and will double my productivity once I get used to it? Has anyone written their own code for a 2D game and later switched to Cocos2d/Unity and liked it?</p>]]></content:encoded></item><item><title>The Making Of Casey's Contraptions</title><link>https://gamesfromwithin.com/the-making-of-caseys-contraptions/</link><pubDate>Tue, 14 Jun 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-making-of-caseys-contraptions/</guid><description>&lt;p&gt;Pocket Gamer &lt;a href="http://www.pocketgamer.biz/r/PG%2EBiz/Casey%27s+Contraptions/feature.asp?c=30643"&gt;just published an article on &amp;ldquo;The Making of Casey&amp;rsquo;s Contraptions&amp;rdquo;&lt;/a&gt;. It&amp;rsquo;s an in-depth interview with Miguel and I, talking about the origins and development of Casey&amp;rsquo;s Contraptions. Learn what influenced the art style in Casey&amp;rsquo;s Contraptions, how we almost went with a freemium model but pulled out at the last minute, and more.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Pg" loading="lazy" src="https://gamesfromwithin.com/the-making-of-caseys-contraptions/images/pg.png"&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p>Pocket Gamer <a href="http://www.pocketgamer.biz/r/PG%2EBiz/Casey%27s+Contraptions/feature.asp?c=30643">just published an article on &ldquo;The Making of Casey&rsquo;s Contraptions&rdquo;</a>. It&rsquo;s an in-depth interview with Miguel and I, talking about the origins and development of Casey&rsquo;s Contraptions. Learn what influenced the art style in Casey&rsquo;s Contraptions, how we almost went with a freemium model but pulled out at the last minute, and more.</p>
<p><img alt="Pg" loading="lazy" src="/the-making-of-caseys-contraptions/images/pg.png"></p>
]]></content:encoded></item><item><title>Casey's Contraptions on the Media</title><link>https://gamesfromwithin.com/caseys-contraptions-on-the-media/</link><pubDate>Mon, 23 May 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/caseys-contraptions-on-the-media/</guid><description>&lt;p&gt;What an incredible last few days it has been! &lt;a href="http://www.caseycontraptions.com/"&gt;Casey&amp;rsquo;s Contraptions&lt;/a&gt; launched last Thursday, and it&amp;rsquo;s now sitting at the #2 slot on the top selling iPad apps in the US and it&amp;rsquo;s in the top 10 in many other countries in the world (and would probably be #1 if it wasn&amp;rsquo;t because Infinity Blade had a major update and is on sale).&lt;/p&gt;
&lt;p&gt;Casey&amp;rsquo;s Contraptions went on sale on Thursday, and in a few hours it entered the top 100 charts all around the world. We were super-fortunate the Apple picked Casey&amp;rsquo;s Contraptions as their iPad Game of the Week worldwide and that gave it enough momentum to reach #2 on the top apps chart!&lt;/p&gt;</description><content:encoded><![CDATA[<p>What an incredible last few days it has been! <a href="http://www.caseycontraptions.com/">Casey&rsquo;s Contraptions</a> launched last Thursday, and it&rsquo;s now sitting at the #2 slot on the top selling iPad apps in the US and it&rsquo;s in the top 10 in many other countries in the world (and would probably be #1 if it wasn&rsquo;t because Infinity Blade had a major update and is on sale).</p>
<p>Casey&rsquo;s Contraptions went on sale on Thursday, and in a few hours it entered the top 100 charts all around the world. We were super-fortunate the Apple picked Casey&rsquo;s Contraptions as their iPad Game of the Week worldwide and that gave it enough momentum to reach #2 on the top apps chart!</p>
<p><img alt="Gameoftheweek" loading="lazy" src="/caseys-contraptions-on-the-media/images/gameoftheweek.jpg"></p>
<p>The response so far has been overwhelmingly positive. Not just the press, but the comments on <a href="http://forums.toucharcade.com/showthread.php?t=94614">forums</a>, <a href="http://twitter.com/#!/search/casey's%20contraptions">Twitter</a>, <a href="http://www.facebook.com/contraptions">Facebook</a>, and even on the <a href="http://itunes.apple.com/us/app/caseys-contraptions/id399408335?mt=8">App Store</a>. I keep reading stories of parents playing the game along with their 3 and 4 year olds (as well as sneaking out later and playing it by themselves). I&rsquo;m really glad it resonates with people and so many people are able to enjoy it!</p>
<p>Here are just a few of the main reviews Casey&rsquo;s Contraptions has received in the few days since launch:</p>
<ul>
<li><strong><a href="http://www.tuaw.com/2011/05/19/tuaws-daily-ios-app-caseys-contraptions/">TUAW</a></strong> <em>I thought it was the most impressive iOS game I&rsquo;d ever seen.</em></li>
<li><strong><a href="http://www.148apps.com/reviews/caseys-contraptions-review/">148Apps</a> Editor&rsquo;s Choice</strong>. <em>I donâ€™t think Iâ€™ve played a better iOS puzzle game this year.</em></li>
<li><strong><a href="http://www.pocketgamer.co.uk/r/iPad/Casey%27s+Contraptions/review.asp?c=29956">Pocket Gamer</a> Gold Award</strong> <em>[&hellip;] one of the most polished iOS games you can currently lay your hands on</em></li>
<li><strong><a href="http://toucharcade.com/2011/05/18/caseys-contraptions-for-ipad-review-rube-goldberg-would-be-proud/">TouchArcade</a></strong>. <em>I can tell you this â€“ Casey&rsquo;s Contraptions is a joy to play.</em></li>
<li><strong><a href="http://applenapps.com/reviews/caseys-contraptions/">AppleNApps</a> 5/5</strong> <em>Caseyâ€™s Contraptions is without a doubt one of the best games ever made for the iPad.</em></li>
<li><strong><a href="http://theappera.com/2011/05/23/caseys-contraptions-review-the-best-ipad-puzzle-game-right-now/">TheAPPera</a> 10/10</strong> <em>Caseyâ€™s Contraptions is the best puzzle game on the iPad right now.</em></li>
</ul>
<p>It has been an amazing release. I&rsquo;ll write a post soon on what we did for marketing to create this launch. The only thing I could have wished for was that the story had been picked up by one of the super popular web sites like Gizmodo or Kotaku. It&rsquo;s not every day that two indies can get together and storm the App Store charts!</p>
<p>We have lots of updates planned, so the story doesn&rsquo;t end here. This is just the beginning! We&rsquo;ll keep posting on our progress and some initial sales info as soon as the dust settles down.</p>
]]></content:encoded></item><item><title>Making Contraptions</title><link>https://gamesfromwithin.com/making-contraptions/</link><pubDate>Wed, 18 May 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/making-contraptions/</guid><description>&lt;p&gt;Casey&amp;rsquo;s Contraptions will be available in the US in a few hours! For those of you living in other parts of the world, it&amp;rsquo;s probably already available on your App Store. &lt;a href="http://itunes.apple.com/us/app/id399408335?mt=8&amp;amp;partnerId=30&amp;amp;siteID=aDkhM0mDflg"&gt;Go get it&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;For the rest of you still twiddling your thumbs, eagerly awaiting for midnight, here&amp;rsquo;s some insight on what went on in the level creation for Casey&amp;rsquo;s Contraptions.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Casey 640x100" loading="lazy" src="https://gamesfromwithin.com/making-contraptions/images/Casey-640x100.jpg"&gt;&lt;/p&gt;
&lt;h3 id="built-in-editor"&gt;Built-in editor&lt;/h3&gt;
&lt;p&gt;From the beginning of the project, the idea was to have a level editor built in to the game. The level editor was the very first thing I implemented in the game. Before there were menus, or levels, or anything else, the game was a level editor without any goals.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Casey&rsquo;s Contraptions will be available in the US in a few hours! For those of you living in other parts of the world, it&rsquo;s probably already available on your App Store. <a href="http://itunes.apple.com/us/app/id399408335?mt=8&amp;partnerId=30&amp;siteID=aDkhM0mDflg">Go get it</a>!</p>
<p>For the rest of you still twiddling your thumbs, eagerly awaiting for midnight, here&rsquo;s some insight on what went on in the level creation for Casey&rsquo;s Contraptions.</p>
<p><img alt="Casey 640x100" loading="lazy" src="/making-contraptions/images/Casey-640x100.jpg"></p>
<h3 id="built-in-editor">Built-in editor</h3>
<p>From the beginning of the project, the idea was to have a level editor built in to the game. The level editor was the very first thing I implemented in the game. Before there were menus, or levels, or anything else, the game was a level editor without any goals.</p>
<p>That&rsquo;s what <a href="http://twitter.com/#!/mysterycoconut">Miguel</a> and I used to create all the levels we shipped with. Nothing like <a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food">eating your own dog food</a> to make something solid and usable. This is the final level editor that players can use to create their own contraptions from scratch and send them to friends.</p>
<p><img alt="Level editor" loading="lazy" src="/making-contraptions/images/level_editor.jpg"></p>
<p>The only difference is that user-created levels only have the goal of getting the 3 stars in the level, whereas game levels have a separate goal. This was mostly because of the UI work required to allow the user to set different goals affecting multiple objects. It would have been way too complicated, although we&rsquo;re not ruling out the possibility of extending it in the future. Miguel and I had to edit level files by hand to add the extra goal information.</p>
<h3 id="levels-evolved">Levels. Evolved.</h3>
<p>One thing that worked really well in Casey&rsquo;s Contraptions is that we had a working level editor from day one. The first prototype was a tiny level editor! Of course, we&rsquo;ve been refining it since then, but the core was there.</p>
<p>After a month or two of development, we implement some goals and the ability to play through the levels created. That means we&rsquo;ve been able to make, play, and test levels for 6 months before shipping.</p>
<p>It was having that amount of time to create levels that allowed the level creation to mature and let us discover what went into a fun level, to refine the difficulty, and create much more interesting levels in the end. Some of that was influenced by what mechanics were fun and which ones weren&rsquo;t (placing something in a pixel-perfect position).</p>
<p>The different game items also had a huge influence over the level design. Clearly their functionality is going to affect level design hugely, but the surprise was that the character of the items also influenced level design quite a bit.</p>
<p>For example, early on, most of the levels were about solving everyday tasks Casey had to deal with: put toys away, knock down a ball from the roof, pop a balloon, etc. But as soon as we started adding some of the more colorful items, like the doll, the piggy bank, or the RC truck, our levels shifted into being mini-stories: The doll is jumping from a building and you need to catch her, the piggie is being taken away on the truck, etc. That&rsquo;s when we realized that we could make really fun levels based on playtime stories, not just real situations. Probably about a third of the shipping levels are playtime levels.</p>
<p><img alt="Skateboard" loading="lazy" src="/making-contraptions/images/skateboard.jpg"></p>
<h3 id="creation-process">Creation process</h3>
<p>Initially, we just created levels without thinking too much about it. Used whatever items we wanted and created something that seemed fun. We were learning a lot by doing that: Playing with item interactions, seeing what was possible and what wasn&rsquo;t, which items we were gravitating towards and which ones were no fun to play with. We weren&rsquo;t doing it consciously, but what we really doing was exploring the possibilities of the &ldquo;level space&rdquo;.</p>
<p>As you can imagine, most of what we created early on went out of the window pretty quickly. Most of the levels were insanely difficult, and a lot of them were simply no fun at all. We were also creating the levels to challenge each other to solve them, and while that was really fun, a lot of those levels were devilishly difficult. We&rsquo;ve been dialing back the difficulty level ever since then.</p>
<p>The actual process for creating a level wasn&rsquo;t very involved. Either one of us would go ahead and create a first pass at a level. Sometimes I would sit down and consciously decide to create a new level (especially if it was a level designed to teach about a new item), but more often than not, an idea would come up while doing something unrelated in the game.</p>
<p>Once we had this first pass, we would send it over to the other person and have them either poke holes on the design (if the level can be solved trivially by just dropping a ball somewhere for example), or tweak it to tighten it and make it more fun. Later on, we would revisit levels based on tester feedback or us becoming more experienced.</p>
<p>I estimate that the average time to create a level, from the first item added to the time it was added to the game, was about half an hour. Some of them were much faster, and some much slower though. And for yet some others, we struggled with them for a whole day and finally dropped the idea completely.</p>
<h3 id="what-makes-a-good-level">What makes a good level</h3>
<p>As we quickly learned, making a cool-looking contraption and removing a few pieces does not a good level make.</p>
<p>The best levels always have multiple solutions. Otherwise, it becomes a game of &ldquo;guess what the designer had in mind&rdquo;. There are plenty of games like that out there (and I hate them all when I feel that it turns into that). So even if we started with a complete contraption, we would always make sure there were at least two different ways of accomplishing the goals.</p>
<p>The other thing to avoid in a level is the possibility of trivial solutions. If a level can be accomplished by placing a single item that drops and causes the goal to complete, that&rsquo;s not very fun. It was a tough balance between leaving enough freedom to create your own solutions, but making it so there were no really &ldquo;cheap&rdquo; and boring ones.</p>
<p>The stars were tricky. Each level has thee stars you can get, but they&rsquo;re completely optional. Initially I wanted our levels to be easy to solve, but each star was progressively more difficult to get. Getting the third star required some serious thinking. My reasoning was that people would solve the levels first, get comfortable with the game, and then come back and get three stars in everything. Boy, was I wrong! It was clear right away that most people wanted (no, expected!) to get all three stars in their first pass through the game. So we changed most of the levels so getting the stars is not hugely difficult, especially in the early levels.</p>
<p>Letting the testers loose on the game was an extremely valuable experience. Not only did they catch a fair share of bugs, but they also had a fresh perspective on the game. It was amazing seeing them solve levels in totally different ways than we had anticipated. It was extremely rewarding to see people come up with solutions and even interactions I had never considered even though I had written all the code.</p>
<p>Here&rsquo;s a good example (<strong>Spoiler alert</strong>. Skip ahead to the next section if you don&rsquo;t want to learn multiple solution to one level).</p>
<p>Here&rsquo;s one level I designed called &ldquo;Angry Doll&rdquo; (any references to popular iOS games must be purely coincidence, by the way :-)</p>
<p><img alt="Doll1" loading="lazy" src="/making-contraptions/images/doll1.jpg"></p>
<p>This was a level intended to highlight the use of the slingshot, but you already had the doll and one slingshot in place (and the doll misses the pig with its initial flying kick). One possible solution I had in mind was to use the remaining balls and slingshots to alter the course of the doll and knock the pig down.</p>
<p><img alt="Doll2" loading="lazy" src="/making-contraptions/images/doll2.jpg"></p>
<p>There are a few different ways you can do that, which made it an interesting level. However, I was totally unprepared for some of the solutions the testers came up with.</p>
<p>This solution uses multiple slingshots on the doll, which changes its course and adds a lot more force to it. It flies straight for the pig and smashes it on impact. Not just that, but for extra style points, the tennis balls go flying out on a totally chaotic pattern, and they get all the stars!!</p>
<p><img alt="Doll4" loading="lazy" src="/making-contraptions/images/doll4.jpg"></p>
<p>This other solution might be my favorite. It completely bypasses even the intermediate goal (alter the doll&rsquo;s trajectory) and instead attaches a slingshot directly on the piggie bank and smashes it against the wall (getting a star along the way). Genius!</p>
<p><img alt="Doll3" loading="lazy" src="/making-contraptions/images/doll3.jpg"></p>
<h3 id="item-sequence">Item sequence</h3>
<p>There was one additional constraint to making levels that we didn&rsquo;t start dealing with until fairly late in the project: Item sequence. Initially, only a few, simple items are available to solve the goals in each level. As you play your way through the game, we introduce new items slowly, making sure their properties are well understood before introducing a new one.</p>
<p>The first time you complete a level with a new item, you&rsquo;re &ldquo;awarded&rdquo; that item, and you can start using it in your own contraptions in the level editor. You can even see the stickers of the items you&rsquo;ve earned so far on the cover of the &ldquo;My Contraptions&rdquo; book (I was playing Psychonauts at the time, so I suspect that might have influenced that design decision a bit).</p>
<p><img alt="Mainmenu" loading="lazy" src="/making-contraptions/images/mainmenu.jpg"></p>
<p>Having a set item sequence meant we had to be very careful which items were available in which level. We kept a spreadsheet with all the levels, and which items were introduced when. Every new item we introduce follows the following steps:</p>
<ul>
<li>When an item first appears, it&rsquo;s already placed in the level. That means the player gets to see how that item behaves.</li>
<li>The next level, we give that item to the player so he or she can place it in the level to solve the contraption.</li>
<li>Another level or two making use of that item. That reinforces the behavior of the item and makes the player comfortable with it before moving on.</li>
</ul>
<p>We were shooting for fewer levels, but it&rsquo;s not hard to see why we ended up with 72 levels in the first version of the game.</p>
<p>To be really sure we were respecting the right item sequence, we even wrote a script that parsed all the level files in order and spit out where each item was used. It even made sure that every item followed the rules above (first placed in the world, then available to place by the player). This will continue being extremely useful as we add more items and levels in future updates.</p>
<p><img alt="Tank" loading="lazy" src="/making-contraptions/images/tank.jpg"></p>
<h3 id="make-your-own">Make your own</h3>
<p>There you go. That should give you an idea of what was involved in creating the levels for Casey&rsquo;s Contraptions. In the near future we&rsquo;re planning on holding contraption-creation contests and we hope to highlight some player-created contraptions. <a href="http://itunes.apple.com/us/app/id399408335?mt=8&amp;partnerId=30&amp;siteID=aDkhM0mDflg">Go ahead and buy the game</a> and start practicing to make your own contraptions. Remember: The crazier the better!</p>
]]></content:encoded></item><item><title>The Curious Case of Casey and The Clearly Deterministic Contraptions</title><link>https://gamesfromwithin.com/casey-and-the-clearly-deterministic-contraptions/</link><pubDate>Fri, 13 May 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/casey-and-the-clearly-deterministic-contraptions/</guid><description>&lt;p&gt;As we gear up for &lt;a href="http://www.caseyscontraptions.com/"&gt;Casey&amp;rsquo;s Contraptions&lt;/a&gt; launch on May 19th, this is the first post in a series dealing with different aspects of the game. I&amp;rsquo;m planning on covering technical aspects like today, but also design and other parts of development.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Casey 640x100" loading="lazy" src="https://gamesfromwithin.com/casey-and-the-clearly-deterministic-contraptions/images/Casey-640x100.jpg"&gt;&lt;/p&gt;
&lt;p&gt;For those of you who have been living under a rock and haven&amp;rsquo;t seen the Casey&amp;rsquo;s Contraptions video, go watch it now. I&amp;rsquo;ll wait. Or even better, here it is. You don&amp;rsquo;t even have to leave this page:&lt;/p&gt;
&lt;iframe src="http://www.youtube.com/embed/JlqNa9mEqNE" frameborder="0" width="640" height="390"&gt;&lt;/iframe&gt;</description><content:encoded><![CDATA[<p>As we gear up for <a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a> launch on May 19th, this is the first post in a series dealing with different aspects of the game. I&rsquo;m planning on covering technical aspects like today, but also design and other parts of development.</p>
<p><img alt="Casey 640x100" loading="lazy" src="/casey-and-the-clearly-deterministic-contraptions/images/Casey-640x100.jpg"></p>
<p>For those of you who have been living under a rock and haven&rsquo;t seen the Casey&rsquo;s Contraptions video, go watch it now. I&rsquo;ll wait. Or even better, here it is. You don&rsquo;t even have to leave this page:</p>
<iframe src="http://www.youtube.com/embed/JlqNa9mEqNE" frameborder="0" width="640" height="390"></iframe>
<p>The core interaction loop of Casey&rsquo;s Contraptions gameplay is placing some items, pressing the Play button, seeing the simulation, and repeating based on what you learned from seeing the simulation. We designed this loop to be very tight and without any penalty: Running/stopping the simulation is instant, there&rsquo;s no limit on the number of times you run it, and you can even stop the simulation by tapping anywhere on the screen. Even if you painted yourself in a wall by creating a solution that needs a very specific placement of items on the screen, making small changes is very quick and painless.</p>
<p>There&rsquo;s a very important, underlaying assumption in that loop: Running the same simulation multiple times will result in the same behavior. Imagine how frustrating it would be to create a complex chain reaction, just to find out it only works every other time you run it. That would truly deserve a ONE STAR WANT MY MONEY BACK!!</p>
<h3 id="determinism">Determinism</h3>
<p>That&rsquo;s referred to as the game being deterministic: Given the same inputs, it produces the same outputs. It&rsquo;s not the first time I&rsquo;ve had to deal with that. Actually, it seems that I&rsquo;ve had to deal with that in <a href="/back-to-the-future-part-1/">one form</a> <a href="/back-to-the-future-part-2/">or another</a> for all my games in the last 10 years (except for Flower Garden). Most recently, it was a key component of gameplay for the <a href="http://kotaku.com/259968/prototyping-for-fun-and-profit">unreleased game we were working on at Power of Two Games</a>.</p>
<p>To make a game deterministic, you need to remove the obvious sources of &ldquo;accidentally different&rdquo; inputs. That&rsquo;s usually random number generators, and making sure the initial state is truly the same. It&rsquo;s too easy to have some leftover state from the previous simulation that throws things off a little bit.</p>
<p>Another potential source of problems are uninitialized variables. If at some point the simulation depends on an uninitialized variable, different runs will cause different results based on whatever value happened to be in memory at that time.</p>
<p>Once you fix all of those little things, that should be it, right? Same input should create the same output. Not really. We&rsquo;re missing the most crucial input: The timer.</p>
<p>Casey&rsquo;s Contraptions runs at 60 fps on an iPad one, but the timestep isn&rsquo;t set to a fixed 16.667ms. Instead, I use a high-resolution timer to measure how much time has really elapsed since last frame, and I advance the simulation by that much.</p>
<p>The problem is that the timer doesn&rsquo;t always return the exact same amount. It&rsquo;s not super-precise, and it can be slightly affected by other things going on in the device. It won&rsquo;t be off by more than 1/10th of a ms, but that&rsquo;s enough to cause different results and start diverging the simulation.</p>
<h3 id="fixed-timestep">Fixed timestep</h3>
<p>One way to get around this problem is to hardcode the timestep to always be 16.667ms, independently of what it really was. That would fix the determinism problem, but it would add its own drawbacks. If the simulation can&rsquo;t keep up with 60 fps, the game will appear to slow down, which is not the effect we want. Casey&rsquo;s Contraptions includes a level editor to make your own free-form contraptions, and even though we have a cap in the maximum number of items you can add, it&rsquo;s probably possible to add enough of them to start slowing down an iPad 1.</p>
<p><img alt="CaseyDollTruck" loading="lazy" src="/casey-and-the-clearly-deterministic-contraptions/images/CaseyDollTruck.jpg"></p>
<h3 id="recording-timesteps">Recording timesteps</h3>
<p>A tempting solution (and one I&rsquo;m ashamed I even briefly tried), is to record the exact timestep during the first run of the simulation. Then, in subsequent runs when nothing has changed, we use the initially recorded stream of timesteps instead of the real ones from the clock.</p>
<p>Apart from being a clumsy-looking solution (I hate having two modes for doing the same thing), the solution only works in the case of replaying the exact same input. This approach falls apart if you make a change to an item that doesn&rsquo;t affect the simulation until after several seconds have passed. At that point, you&rsquo;re running a new simulation with new timesteps and everything can diverge before the affected object is changed. Bad, idea. Bad.</p>
<h3 id="fixed-simulation-timesteps">Fixed simulation timesteps</h3>
<p>This is the correct solution and it&rsquo;s what we&rsquo;re doing in Casey&rsquo;s Contraptions.</p>
<p>You probably already know that physics simulations are a lot more stable if you take small steps, always of the same size. So you really never want to advance your physics simulation by your frame time. Instead, you want to have a small and fixed simulation step (we&rsquo;re running at 120Hz, but 200 or even 300 are not unheard of). Then, you run the physics simulation as many times as you can fit into your larger timestep. It&rsquo;s also important to keep around the amount of leftover time you haven&rsquo;t simulated, to apply it to the next frame.</p>
<p>The simulation loop code looks something like this:</p>
<pre tabindex="0"><code>	const float timestep = 1.0f/120.0f;
	accumulator += dt;
	while (accumulator &gt;= timestep)
	{
		// Do physics simulation by timestep
		accumulator -= timestep;
	}
</code></pre><p>Once we have this loop in place, our real frame time doesn&rsquo;t matter anymore. The physics simulation will either run for a full step (or multiple steps), or it won&rsquo;t. There&rsquo;s no half-way states. So it doesn&rsquo;t matter if in the first run of the simulation the loop gets executed 3 times in the first frame and 2 times in the second, and in the next simulation is 2 times in the first and 3 in the second. The state of the world will be the same.</p>
<p><a href="http://gafferongames.com/">Glenn Fiedler</a> writes about this kind of simulation loop in much more detail in <a href="http://gafferongames.com/game-physics/fix-your-timestep/">this excellent article</a>.</p>
<h3 id="jitterbug">Jitterbug</h3>
<p>There&rsquo;s still a slight problem with the above loop. Nothing horrible; the simulation is deterministic at this point (assuming everything else is taken care of correctly). But you might notice some annoying jittering as things move around.</p>
<p><img alt="CaseysDollKick" loading="lazy" src="/casey-and-the-clearly-deterministic-contraptions/images/CaseysDollKick1.jpg"></p>
<p>That&rsquo;s because how we&rsquo;re sampling the simulation. We might render a frame after 3 steps of the physics simulation, but another one after 2. So movement isn&rsquo;t going to be very smooth.</p>
<p>To get around it, we need to interpolate the state of the world to match the time at which the frame is rendered. To do that, we need to simulate one timestep in the future, and then interpolate between the previous one and the future one by the percentage amount left in the accumulator.</p>
<p>Something like this:</p>
<pre tabindex="0"><code>	const float timestep = 1.0f/120.0f;
	accumulator += dt;
	while (accumulator &gt;= timestep)
	{
		GameState lastState = gameState;
		// Do physics simulation by timestep
		accumulator -= timestep;
	}

	const float t = accumulator/timestep;
	GamePhysicsUtils::LerpState(interpolatedState, prevState, gameState, t);
</code></pre><p>The interpolation is just the positions and rotations of every item in the world. That&rsquo;s only used for rendering, so no need to worry about velocities or forces (unless those are affecting rendering in a very obvious way too).</p>
<p>This is when it comes really handy to have the game state as a contiguous, relocatable block of memory. You can really easily copy states around without having to worry about allocating any memory or fixing any pointers. Yes, I really like my <a href="/start-pre-allocating-and-stop-worrying/">simple, pre-allocated data</a>.</p>
<p>One added benefit of this approach: If you do it right, you can have extreme slow-motion in your game and everything will be right. Even if you only run one physics simulation loop every 10 rendering frames, the interpolation will take care of making sure everything is super smooth.</p>
<h3 id="odds-and-ends">Odds and ends</h3>
<p>A couple gotchas to watch out for (that&rsquo;s code speak for &ldquo;I didn&rsquo;t think of this and it bit me hard&rdquo;).</p>
<p>If you have any game logic that affects the physical state of your game objects, it needs to be executed in the inner, simulation loop. Anything that deals with visual or audio stuff can go in the regular update loop and only be executed once per frame.</p>
<p>A good example of this was the balloon code. Every frame, I iterate through all existing balloons, and apply some upward force based on buoyancy and other factors. Initially that was done once per frame, after the physics simulation, but that&rsquo;s obviously wrong because it will leave balloons (and everything else) in a different state depending on your frame delta time. I moved it to the inner simulation loop and everything became deterministic again.</p>
<p><img alt="CaseyBalloons" loading="lazy" src="/casey-and-the-clearly-deterministic-contraptions/images/CaseyBalloons.png"></p>
<p>This second gotcha sounds silly, but it was a big deal: Make sure you deal with the situation where you have different numbers of items in the previous game state than in the next game state. For example, if a balloon is destroyed, between the two states, the item count will be different. In my case I don&rsquo;t free any memory, but I was initially making the assumption that I could interpolate based on the index of the items on both states. But since I removed the balloon and pushed all the items behind it forward, the interpolation was totally wrong.</p>
<p>I solved that problem by marking items as invalid, and removing them only after the inner simulation loop was complete. That allowed me to still interpolate in a very straightforward way and not have to worry about missing items.</p>
<h3 id="taking-it-further">Taking it further</h3>
<p>Not only are we relying on this determinism while you play a level of Casey&rsquo;s Contraptions, but also to let you replay solutions from your friends. We simply load their initial layout and run the simulation locally.</p>
<p>[Pause]</p>
<p>Ah, yes, astute reader, you&rsquo;re right to be puzzled about that. How do we make the simulation deterministic across platforms and versions? Good question. Stay tuned.</p>]]></content:encoded></item><item><title>The Business of iPhone and iPad App Development</title><link>https://gamesfromwithin.com/the-business-of-iphone-and-ipad-app-development/</link><pubDate>Mon, 11 Apr 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-business-of-iphone-and-ipad-app-development/</guid><description>&lt;p&gt;&lt;a href="http://amzn.to/eGD2fv"&gt;&lt;img alt="Business cover" loading="lazy" src="https://gamesfromwithin.com/the-business-of-iphone-and-ipad-app-development/images/business_cover.jpg"&gt;&lt;/a&gt;Full disclosure: Apress asked me to review this book and sent me a free copy. I agreed with my usual condition of being able to really say what I thought about the book, good or bad. So here it is.&lt;/p&gt;
&lt;h3 id="tldr"&gt;TL;DR&lt;/h3&gt;
&lt;p&gt;Great book for someone starting out on iOS development. You would be at a severe disadvantage if you don&amp;rsquo;t know about most practices described in the book. Single resource for lots of good practices you&amp;rsquo;d have to pick up from blogs or Twitter otherwise.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="http://amzn.to/eGD2fv"><img alt="Business cover" loading="lazy" src="/the-business-of-iphone-and-ipad-app-development/images/business_cover.jpg"></a>Full disclosure: Apress asked me to review this book and sent me a free copy. I agreed with my usual condition of being able to really say what I thought about the book, good or bad. So here it is.</p>
<h3 id="tldr">TL;DR</h3>
<p>Great book for someone starting out on iOS development. You would be at a severe disadvantage if you don&rsquo;t know about most practices described in the book. Single resource for lots of good practices you&rsquo;d have to pick up from blogs or Twitter otherwise.</p>
<h3 id="in-more-detail">In More Detail&hellip;</h3>
<p>Don&rsquo;t be fooled by the title. <a href="http://amzn.to/eGD2fv">The Business of iPhone and iPad App Development by Dave Wooldridge and Michael Schneider</a> isn&rsquo;t one of your boss&rsquo; stuffy business book. This is a practical, hands on, guide to making a successful iOS app. It assumes you already have an idea and know how to develop it, but it guides you through the steps of focusing the app, designing it so it can be profitable, and releasing it with the best possible chance of becoming a good seller.</p>
<p>You&rsquo;ve probably heard a dozen stories of developers who create a great app, submit it to the App Store, and then wonder why they only sold a dozen copies. This is the book they need to go along with that great app.</p>
<p>The book roughly follows the development timeline of an app, from the initial concept, design, implementation, testing, and release. At each of the stages, it covers any aspects that can have a significant impact in the sales success of the app. Even though you can read the book cover to cover, the chapters are very well defined, so it&rsquo;s easy to jump directly to the part that interests you the most.</p>
<p>With <a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a> almost ready to submit to Apple, I read with particular interest the chapters on creating prerelease buzz and increasing awareness of the app. Lots of good advice there.</p>
<p>Don&rsquo;t expect anything groundbreaking though. If you&rsquo;ve been following this blog for a while, or you&rsquo;ve been hanging out on <a href="http://twitter.com/#!/noel_llopis/ios-gamedevs">Twitter with all the iOS developers</a>, you will know most of what the book has to offer. It might still be worth it for a few pearls of wisdom here and there to fill some blind spot. However, the book should be required reading for any new iOS developer. Easily the best $20 you can spend as far as impact in the final app sales.</p>
<p>I usually have no patience for technical books with filler chapters and sections. This book is very good about getting to the point, although it has a few sections that feel a bit out of place in that they&rsquo;re quite basic and technical (like details of generating provisioning profiles, did we really need that in this book?). All in all, that&rsquo;s a pretty minor point and easy to get around them.</p>
<h3 id="delayed-release">Delayed Release</h3>
<p>Probably my main criticism is that the book doesn&rsquo;t mention one release technique that I consider to be a requirement for any major launch these days: The delayed launch. As the authors mention several times in the last few chapters, once you submit your app, you have no control over when Apple approves it, so you have to play some guessing games.</p>
<p>Instead, you can delay the release of the app once it has been approved, and set it to a known, fixed date in the future (say, a week from approval). At that point, you can really kick in your PR in high gear, contact media outlets, and, most importantly, send them promo codes for your app, even though it&rsquo;s not available for sale yet.</p>
<p>The goal is to have all the PR hit on launch day or shortly after. The more you can make that happen, the more successful any PR efforts will be, and the bigger the initial launch (and hopefully the following sales) will be.</p>
<p>All in all, The Business of iPhone and iPad App Development is an easy recommendation for the new iOS developer. Go read it right now before you even think of shipping another app.</p>
]]></content:encoded></item><item><title>All It Needs Is Love</title><link>https://gamesfromwithin.com/all-it-needs-is-love/</link><pubDate>Fri, 18 Mar 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/all-it-needs-is-love/</guid><description>&lt;p&gt;The App Store today is a different beast from the one in early 2009, when &lt;a href="http://www.wired.com/gadgetlab/2009/02/shoot-is-iphone/"&gt;iShoot ruled the charts&lt;/a&gt;. Look at the top paid games on the App Store today. Actually, don&amp;rsquo;t worry, I did all the leg work for you. Here they are:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Top paid" loading="lazy" src="https://gamesfromwithin.com/all-it-needs-is-love/images/top_paid.png"&gt;&lt;/p&gt;
&lt;p&gt;What can we tell by looking at those games? I see two clear categories: Games with a strong, established IP (Street Fighter, Sonic), or independent games with a huge amount of polish and style.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The App Store today is a different beast from the one in early 2009, when <a href="http://www.wired.com/gadgetlab/2009/02/shoot-is-iphone/">iShoot ruled the charts</a>. Look at the top paid games on the App Store today. Actually, don&rsquo;t worry, I did all the leg work for you. Here they are:</p>
<p><img alt="Top paid" loading="lazy" src="/all-it-needs-is-love/images/top_paid.png"></p>
<p>What can we tell by looking at those games? I see two clear categories: Games with a strong, established IP (Street Fighter, Sonic), or independent games with a huge amount of polish and style.</p>
<h3 id="its-all-about-polish">It&rsquo;s All About Polish</h3>
<p>The love and care developers put into those games shows the moment you start them up. Look at the textures in Tiny Wings, the sound effects in Angry Birds, the feedback animations in Words With Friends, or all the little details in Cut The Rope. All the tiny particle effects, transitions, sounds, and general squish and responsiveness. Every single one of those games is oozing with its own style and contributes to a very enjoyable first (and repeat) experience.</p>
<p>And that is the main point of this post: To make a successful game on the App Store, the main thing you need is love. You can skimp on features, on content, on marketing, on a web site, or even on gameplay balance. All those are things that you can add or improve after shipping, but polish and style are responsible for that crucial first impression. Miss the chance to hit the player with all you&rsquo;ve got the first time they play your game, and that might be a lost sale (and a lost advocate of your game since word of mouth is such a strong force on the App Store).</p>
<p>Not convinced about the difference polish and style makes?</p>
<p>This game is essentially Tiny Wings with just a little bit of polish (and it does have *some* polish).</p>
<iframe title="YouTube video player" src="http://www.youtube.com/embed/uRt3ccRzxOo" frameborder="0" width="480" height="390"></iframe>
<p>And this is Tiny Wings.</p>
<iframe title="YouTube video player" src="http://www.youtube.com/embed/VUnlE4cGgz0" frameborder="0" width="640" height="390"></iframe>
<p>I rest my case.</p>
<h3 id="ship-as-soon-as-possible">Ship As Soon As Possible?</h3>
<p>Traditional game development (especially for consoles) usually goes along these lines: Plan everything, create a game with everything that you want/can fit, ship it once it&rsquo;s done, and hope not to touch it again. On the other hand, in this day of web/Facebook/mobile development the favored approach is to release a product as soon as possible, and then iterate from there.</p>
<p>My preference in the last few years has been more along the shipping as soon as possible lines (even if I haven&rsquo;t always been successful at it). But then I paused and really thought about why and what I would accomplish by shipping early. These are the main reasons I could think about:</p>
<ul>
<li><strong>Getting to market first</strong>. This is a big one in the web world (and maybe even in the hardware world). Even if your product is imperfect, or its UI is less than ideal, getting that initial critical mass of users could be what tips the balance in your favor.</li>
<li><strong>Canceling the project early</strong>. Maybe it takes as long as the first version of a product to realize there isn&rsquo;t demand for it. So it was better to have spent 6 months instead of 3 years before canceling the project.</li>
<li><strong>Focussing your efforts</strong>. An impending ship date will make wonders to keep people on track and focused on what&rsquo;s important to ship a game.</li>
<li><strong>Become profitable as soon as possible.</strong> Even if you make the same amount of money and spend the same amount of time working on a project, if you start bringing in money at the 6 month mark rather than at the 3 year mark, you&rsquo;ll be profitable earlier. And as any RTS fan will tell you, getting extra resources early in the game can put you at a huge advantage.</li>
<li><strong>Changing the product based on early user feedback</strong>. Otherwise you might spend years working on a product that people don&rsquo;t really want, or they would prefer something slightly different.</li>
</ul>
<p>How do those reasons apply to iOS games?</p>
<ul>
<li>As an iOS game, your biggest moment is launch. That&rsquo;s when you can get most momentum and get the word of mouth ball rolling. First impressions matter a lot and a lot of people will make snap decisions about your game in the first few seconds. If it&rsquo;s not looking its best, it doesn&rsquo;t matter if it came earlier than another game. Besides, games, for the most part, aren&rsquo;t providing as much of a service as they&rsquo;re a form of entertainment. Barring brand new genres or whole new platforms, getting to market first doesn&rsquo;t mean much. And even if you&rsquo;re making a brand new genre, chances are it&rsquo;s unique so the clones won&rsquo;t start showing up until after you launch and becomes popular (unless you announce way in advance).</li>
<li>Stopping development on an unsuccessful game earlier rather than later is always a good thing.</li>
<li>Likewise, having a milestone around the corner does wonders for focussing your efforts. That was one of the big benefits we got from <a href="/caseys-contraptions-and-the-igf/">submitting Casey&rsquo;s Contraptions to the IGF</a>.</li>
<li>The last one is tricky. It might seem like a benefit for iOS games as well, but I&rsquo;m going to argue it isn&rsquo;t. Don&rsquo;t get me wrong, I think that testing and user feedback is very valuable. But games ultimately are a form of art[1] and you are the creator. In the end, you need to decide what your game and your vision are like. Feedback will help with usability and balancing issues, but not with what the game is fundamentally. Stick to your vision.</li>
</ul>
<h3 id="my-approach">My Approach</h3>
<p>Looking at those lists, it makes it clear to me that iOS game development is not all about getting a product out of the door as soon as possible. There&rsquo;s no need to create a finished product for your first release. Instead, save every feature and content you can for free updates or even future in-app purchases.</p>
<p>I&rsquo;m convinced that polish and style are one of the most important things an iOS game can have. <a href="/the-importance-of-first-impressions/">It&rsquo;s not the first time I say that</a>. So get the product out as soon as you can, but do not, under any circumstances, cut any polish from your game. Plan on spending a good month or longer after your game is &ldquo;done&rdquo; polishing it. That time will definitely be well spent and will increase the value of your game more than any other month you spent developing it.</p>
<p>What I&rsquo;m suggesting here is actually quite different from what <a href="http://chrishecker.com/Please_Finish_Your_Game">Chris Hecker talked about at last year&rsquo;s GDC</a>. Even though we&rsquo;re both saying &ldquo;take your time and do your game right&rdquo;, he&rsquo;s emphasizing the completeness of the game (in the sense of exploring all its potential), while I&rsquo;m emphasizing the presentation. I think the main reason our messages are so different is the platform we&rsquo;re developing for. On a platform like iOS, I really think you can explore the full potential of a game after it ships without any real drawbacks.</p>
<p>Right now we&rsquo;re in the polish phase in <a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a>. The game has been &ldquo;done&rdquo; for a while, in the sense that we have all the items, lots of levels, you can play through all the puzzles, make your own contraptions, etc. Even though it already has a lot of style and polish, it definitely needs that extra layer of shine to make it really stand out and bring it to the quality of those games in the top 10 list. We can only hope that Casey&rsquo;s Contraptions joins them after we launch!</p>
<p><img alt="Caseys1" loading="lazy" src="/all-it-needs-is-love/images/caseys1.jpg"></p>
<p><img alt="Caseys2" loading="lazy" src="/all-it-needs-is-love/images/caseys2.jpg"></p>
<p> </p>
<p>Interested in keeping up with Casey&rsquo;s Contraptions as we&rsquo;re gearing up for launch? <a href="http://www.facebook.com/contraptions">Join the Facebook page</a>.</p>
<iframe style="border: none; overflow: hidden; width: 450px; height: 80px;" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.facebook.com%2Fcontraptions&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;font&amp;colorscheme=light&amp;height=80" frameborder="0" scrolling="no" width="320" height="240"></iframe>
<p> </p>
<p>[1] Feel free to substitute whatever word you want there that isn&rsquo;t offensive to you: entertainment, interactive media, etc. Games are something *you* create from your imagination, so art seems like the best term to me.</p>]]></content:encoded></item><item><title>Snappy Touch Picked As Top 50 Developer</title><link>https://gamesfromwithin.com/snappy-touch-picked-as-top-50-developer/</link><pubDate>Mon, 21 Feb 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/snappy-touch-picked-as-top-50-developer/</guid><description>&lt;p&gt;&lt;img alt="Top 50" loading="lazy" src="https://gamesfromwithin.com/snappy-touch-picked-as-top-50-developer/images/top_50.jpg"&gt;Pocket Gamer &lt;a href="http://www.pocketgamer.biz/r/PG%2EBiz/PG%2EBiz+Top+50+Developers/feature.asp?c=27692"&gt;just picked Snappy Touch as a top-50 developer for mobile and portable devices for the year&lt;/a&gt;. I&amp;rsquo;m really honored they counted me among the best 50 of the year, especially on a year with so many great games and new developers.&lt;/p&gt;
&lt;p&gt;2010 was &lt;a href="https://gamesfromwithin.com/2010-living-the-dream/"&gt;the year I was hoping to ship Casey&amp;rsquo;s Contraptions&lt;/a&gt;, but that didn&amp;rsquo;t happen. However, it&amp;rsquo;s great to see Pocket Gamer took notice of the ongoing work on Flower Garden. Every update feels like a small product release on its own, and there were many updates in 2010!&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Top 50" loading="lazy" src="/snappy-touch-picked-as-top-50-developer/images/top_50.jpg">Pocket Gamer <a href="http://www.pocketgamer.biz/r/PG%2EBiz/PG%2EBiz+Top+50+Developers/feature.asp?c=27692">just picked Snappy Touch as a top-50 developer for mobile and portable devices for the year</a>. I&rsquo;m really honored they counted me among the best 50 of the year, especially on a year with so many great games and new developers.</p>
<p>2010 was <a href="/2010-living-the-dream/">the year I was hoping to ship Casey&rsquo;s Contraptions</a>, but that didn&rsquo;t happen. However, it&rsquo;s great to see Pocket Gamer took notice of the ongoing work on Flower Garden. Every update feels like a small product release on its own, and there were many updates in 2010!</p>
<p>Flower Garden has come a long way since its initial release on April 2009 (almost two years ago!). There is so much more to the game now than the initial release! These are just some of the most important new features since then:</p>
<ul>
<li>Multiple seed packs</li>
<li>Multiple garden locations</li>
<li>Day/night cycles</li>
<li>Fertilizer</li>
<li>Green Thumb Point awards</li>
<li>Game Center achievements and leaderboards</li>
<li>Sending bouquets through Facebook (and SMS in this next update)</li>
</ul>
<p>Flower Garden also recently reached the milestone of 5 million bouquets sent. That&rsquo;s a lot of flowers! Thanks to all the Flower Garden fans for making this possible!</p>
]]></content:encoded></item><item><title>Finding the Loose Change</title><link>https://gamesfromwithin.com/finding-the-loose-change/</link><pubDate>Tue, 15 Feb 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/finding-the-loose-change/</guid><description>&lt;p&gt;&lt;em&gt;I&amp;rsquo;m thrilled to present a guest post by&lt;/em&gt; &lt;a href="http://twitter.com/#!/eeen"&gt;&lt;em&gt;Ian Marsh&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, 1/2 of the independent studio (and wildly successful)&lt;/em&gt; &lt;a href="http://nimblebit.com/"&gt;&lt;em&gt;NimbleBit&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. They&amp;rsquo;re the creators of iPhone hits such as Pocket Frogs, Scoops, and Sky Burger, and they recently announced &lt;a href="http://twitter.com/#!/NimbleBit/status/37201707305943040"&gt;they reached 20 million downloads on the App Store&lt;/a&gt;__!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="images/nb_logo128.png"&gt; One of the most important steps on the way to becoming a profitable independent iOS developer is diversifying your revenue stream. Â While business lingo like that makes me throw up a little, all it really means is discovering all the ways you can earn money using the platform. Â New developers sometimes pigeonhole themselves into a single App Store strategy: &amp;ldquo;Sell as many copies at 99 cents as possible&amp;rdquo;. Â More savvy developers mix Â multiple strategies: &amp;ldquo;Paid apps&amp;rdquo;, &amp;ldquo;In-App Purchases&amp;rdquo;, and &amp;ldquo;Advertising&amp;rdquo;. Â I want to make sure all developers know about another additional option often overlooked: LinkShare.&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>I&rsquo;m thrilled to present a guest post by</em> <a href="http://twitter.com/#!/eeen"><em>Ian Marsh</em></a><em>, 1/2 of the independent studio (and wildly successful)</em> <a href="http://nimblebit.com/"><em>NimbleBit</em></a><em>. They&rsquo;re the creators of iPhone hits such as Pocket Frogs, Scoops, and Sky Burger, and they recently announced <a href="http://twitter.com/#!/NimbleBit/status/37201707305943040">they reached 20 million downloads on the App Store</a>__!</em></p>
<p><img loading="lazy" src="images/nb_logo128.png"> One of the most important steps on the way to becoming a profitable independent iOS developer is diversifying your revenue stream. Â While business lingo like that makes me throw up a little, all it really means is discovering all the ways you can earn money using the platform. Â New developers sometimes pigeonhole themselves into a single App Store strategy: &ldquo;Sell as many copies at 99 cents as possible&rdquo;. Â More savvy developers mix Â multiple strategies: &ldquo;Paid apps&rdquo;, &ldquo;In-App Purchases&rdquo;, and &ldquo;Advertising&rdquo;. Â I want to make sure all developers know about another additional option often overlooked: LinkShare.</p>
<p><a href="http://www.linkshare.com/publishers/">LinkShare</a> is a company which pairs publishers with retailers who pay said developers for driving clicks to their sites that result in sales. Â How does this apply to iOS developers? Â Luckily Apple (specifically iTunes) is one of the retailers which uses LinkShare. Â A good FAQ page for the iTunes affiliate program can be found <a href="http://www.apple.com/itunes/affiliates/resources/documentation/frequently-asked-questions.html">here</a>, but the basic gist of it that you earn a 5% commission on items bought on the App Store from your affiliate links. Â As an iOS developer you are probably already using links to your apps (and perhaps others) in lots of places, including &ldquo;More Games&rdquo; screens, twitter, newsletters, banner ads, or your web site. Â Replacing all these existing (and future) links to the App Store with your affiliate links is a great start. Â Retro Dreamer even wrote a <a href="http://retrodreamer.com/blog/2010/07/slight-change-of-plan/">nice quick guide</a> to creating links that work seamlessly in iOS (there are some pros and cons to different link formats).</p>
<p>Now you might think the chances of someone actually buying an app you link to are relatively low, but that&rsquo;s where things get interesting. Â If you read the fine print it turns out affiliates get paid 5% of any purchases made within a 72 hours after following your link. Â Lets say Joe clicks on a link to say, <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=386644958&amp;mt=8&amp;partnerId=30&amp;siteID=0JkCNyaaKoo">Pocket Frogs</a> (our latest free game) which included your affiliate id, which even doesn&rsquo;t result in a paid purchase even if the app is downloaded. Â But perhaps Joe ends up buying Angry Birds ($0.99) an hour later earning you $0.05, or Real Racing 2 ($4.99) that night earning you $0.25, or just maybe the Beatles Box Set ($149.00) the next morning earning you $7.45! Â The cool thing about the iTunes affiliate program is that it gives the affiliate 5% of any and all purchases made through iTunes within 72 hours including ring tones, songs, apps, in-app purchases, movies, tv shows, or rentals.</p>
<p>This of course means you can still earn revenue from linking to free apps, Â which can end up being a powerful thing. Â For example, in Pocket Frogs we run a promotion every week where we offer an in game item for downloading a certain free app (with a LinkShare link of course). Â This not only keeps players checking back, but lets us promote apps we like (like Flower Garden) or even our own. Â Like most other revenue sources LinkShare isn&rsquo;t going to make you a whole lot of money if there aren&rsquo;t that many people clicking your links, but it will certainly grow along with the number of users you have. Â While the majority of revenue generated from Pocket Frogs (which fluctuates between 150k and 200k daily active users) comes from the IAP included in the game, it also generates a healthy amount of revenue from LinkShare (in conjunction with some links inside other apps) as seen below.</p>
<p><img alt="pf_promo.jpg" loading="lazy" src="/finding-the-loose-change/images/pf_promo.jpg"></p>
<p><img alt="pf_promo.jpg" loading="lazy" src="images/PF_LS.png"></p>
<p>The great thing about LinkShare is that it gives you a lot of freedom on how you use it. It doesn&rsquo;t use up any bandwidth or take up CPU cycles, and it doesn&rsquo;t require you to shoehorn 3rd party code into your app. It is as invisible or invasive as you want it to be. So whether you&rsquo;re a new iOS developer just starting out or an experienced dev, you owe it to yourself to take a look at using LinkShare if you&rsquo;re not using it already.</p>
]]></content:encoded></item><item><title>Flower Garden Featured For Valentine's Day!</title><link>https://gamesfromwithin.com/flower-garden-featured-for-valentines-day/</link><pubDate>Thu, 10 Feb 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-featured-for-valentines-day/</guid><description>&lt;p&gt;Two years ago, when I was working on the first release of Flower Garden, Valentine&amp;rsquo;s Day was my target ship date. Unfortunately (or fortunately depending on how you look at it), I missed it and rescheduled it for April. Last year I was eagerly awaiting the Valentine&amp;rsquo;s Day features hoping for a feature by Apple, but Flower Garden wasn&amp;rsquo;t one of the apps to be selected. It was disappointing but understandable given how many newer quality apps are out there.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Two years ago, when I was working on the first release of Flower Garden, Valentine&rsquo;s Day was my target ship date. Unfortunately (or fortunately depending on how you look at it), I missed it and rescheduled it for April. Last year I was eagerly awaiting the Valentine&rsquo;s Day features hoping for a feature by Apple, but Flower Garden wasn&rsquo;t one of the apps to be selected. It was disappointing but understandable given how many newer quality apps are out there.</p>
<p>Fast-forward another year, and this morning I woke up to a very pleasant and unexpected surprise: Flower Garden was featured on the App Store under Apps For Valentine&rsquo;s Day!</p>
<p><img alt="Valentines apple feature" loading="lazy" src="/flower-garden-featured-for-valentines-day/images/valentines_apple_feature.png"></p>
<p>Flower Garden is still going strong, but I wasn&rsquo;t expecting that at all. Thank you, Apple! Not only that, but this feature also appears on the device App Store. Flower Garden was featured twice before by Apple, but never before on a spot that appeared on the device. So that&rsquo;s a first for Flower Garden!</p>
<p><img alt="Valentines apple feature iphone" loading="lazy" src="/flower-garden-featured-for-valentines-day/images/valentines_apple_feature_iphone.png"></p>
<p>To make things more interesting, I had been planning on doing a bit of promotion around Valentine&rsquo;s Day like last year. So a few days ago I <a href="http://www.facebook.com/iphoneflowergarden/posts/165687373479182">released a new update</a>, and included another in-app purchase for the most asked-for feature: More pots in another garden space.</p>
<p><img alt="Secret Garden" loading="lazy" src="/flower-garden-featured-for-valentines-day/images/Secret_Garden.jpg"></p>
<p>Finally, to round things off, I planned on doing a similar promotion to what I did last year around Mother&rsquo;s Day, and I set Flower Garden to be free from today until Valentine&rsquo;s Day to encourage even more people to try it. To get the word out of the price drop, I got some promotion going from <a href="http://itunes.apple.com/us/app/pocket-frogs/id386644958?mt=8">Pocket Frogs</a> and a few other apps encouraging users try out the now free Flower Garden. I&rsquo;m also hoping a few media outlets cover the sale to get the word out as much as possible.</p>
<p><img alt="Pf fg" loading="lazy" src="/flower-garden-featured-for-valentines-day/images/pf_fg.jpg"></p>
<p>As of this moment, Flower Garden is in the top 100 apps in the US and in the top 50 games, so the combination of everything seems to be working. We&rsquo;ll see how things develop over this coming week. Until then, it&rsquo;s going to be an exciting ride.</p>
<p>For the latest news on Flower Garden, join the Facebook page by clicking &ldquo;Like&rdquo;:</p>
<iframe src="http://www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Ffacebook.com%2Fiphoneflowergarden&amp;width=500&amp;colorscheme=light&amp;show_faces=true&amp;stream=true&amp;header=true&amp;height=427" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:427px;" allowtransparency="true"></iframe>
]]></content:encoded></item><item><title>Casey's Contraptions Weekly Update (Jan 7)</title><link>https://gamesfromwithin.com/caseys-contraptions-weekly-update-jan-7/</link><pubDate>Fri, 07 Jan 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/caseys-contraptions-weekly-update-jan-7/</guid><description>&lt;p&gt;So much for &amp;ldquo;weekly&amp;rdquo; updates. Last time &lt;a href="https://gamesfromwithin.com/caseys-contraptions-weekly-update-oct-29/"&gt;I wrote one was Oct 29&lt;/a&gt;. Oops! That&amp;rsquo;s what happens when I get really busy and then the holidays hit. But now that&amp;rsquo;s over (the holiday part at least), so I&amp;rsquo;ll write to write more frequent updates.&lt;/p&gt;
&lt;h3 id="this-week"&gt;This Week&lt;/h3&gt;
&lt;p&gt;&lt;img alt="caseyescape.jpg" loading="lazy" src="https://gamesfromwithin.com/caseys-contraptions-weekly-update-jan-7/images/caseyescape.jpg"&gt;This week Miguel and I are wrapping up our current iteration with the main focus of the first five minutes of gameplay. The reason we&amp;rsquo;re doing this now is that we spent quite a bit of time on the user interaction experience and we tried to nail that before adding more items and more levels. All along, we&amp;rsquo;ve been testing the game with unsuspecting victims and we quietly watched over their shoulders as they fumbled with the game without any instructions or tutorials.&lt;/p&gt;</description><content:encoded><![CDATA[<p>So much for &ldquo;weekly&rdquo; updates. Last time <a href="/caseys-contraptions-weekly-update-oct-29/">I wrote one was Oct 29</a>. Oops! That&rsquo;s what happens when I get really busy and then the holidays hit. But now that&rsquo;s over (the holiday part at least), so I&rsquo;ll write to write more frequent updates.</p>
<h3 id="this-week">This Week</h3>
<p><img alt="caseyescape.jpg" loading="lazy" src="/caseys-contraptions-weekly-update-jan-7/images/caseyescape.jpg">This week Miguel and I are wrapping up our current iteration with the main focus of the first five minutes of gameplay. The reason we&rsquo;re doing this now is that we spent quite a bit of time on the user interaction experience and we tried to nail that before adding more items and more levels. All along, we&rsquo;ve been testing the game with unsuspecting victims and we quietly watched over their shoulders as they fumbled with the game without any instructions or tutorials.</p>
<p>I really believe we made huge improvements. We designed the whole game with touch interface from the ground up, and it really shows. I think it&rsquo;s a very direct and intuitive interface, but even so, there&rsquo;s only so much you can do without any instructions.</p>
<p>So, the focus of this last iteration is to concentrate on what a new player will see in the first five minutes of gameplay. That way, we can continue testing the game on new players and get a much better feel for how they learn to interact with the game and what works and what doesn&rsquo;t.</p>
<h3 id="iterations">Iterations</h3>
<p>For every iteration (roughly about 2 weeks each) we focus on one main area, based on what we feel needs to be addressed the most at that point. To give you an idea, these have been the focus of some of the past iterations:</p>
<ul>
<li>Proof-of-concept prototype</li>
<li>New, non-physical items</li>
<li>Game screen flow and level progression</li>
<li>Final user interaction</li>
<li>New items and locations</li>
</ul>
<p><img alt="caseyspace.jpg" loading="lazy" src="/caseys-contraptions-weekly-update-jan-7/images/caseyspace.jpg"></p>
<p>One thing that we&rsquo;ve been doing is trying to take each goal to completion. This is an idea from Scrum and Agile development that I really like. If you implement an idea to the 90% state, apart from the fact that the remaining 10% is going to take another 90% of the time, you probably don&rsquo;t have a good idea how it will really be once it&rsquo;s completed. That makes future planning and re-prioritizing more difficult.</p>
<p>Obviously there&rsquo;s such a thing as going overboard. Trying to get every single, tiny effect and animation to fully complete before moving on would be crippling. I try to think about the impact that feature, even if it&rsquo;s very small, will have in the final game. The exact effect when you pick up a star isn&rsquo;t crucial (assuming you have some sounds and some effects already), but the animations for the item selection and manipulation contribute a lot more to the feel of the game, so they&rsquo;re more important.</p>
<p>In some of my past projects I took a different approach and built the game bottom up. At the very end all the little niceties and polish touches went in, which made the game radically different. Now I&rsquo;ve come to admit that all those little touches contribute a lot to the final feel of the game and should be considered all along and not as an afterthought at the end.</p>
]]></content:encoded></item><item><title>Data-Oriented Design Now And In The Future</title><link>https://gamesfromwithin.com/data-oriented-design-now-and-in-the-future/</link><pubDate>Tue, 04 Jan 2011 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/data-oriented-design-now-and-in-the-future/</guid><description>&lt;p&gt;&lt;em&gt;There has been a lot of recent discussion (and criticism) on Data Oriented Design recently. I want to address some of the issues that have been raised, but before that, I&amp;rsquo;ll start with this reprint from my most recent Game Developer Magazine. If you have any questions you&amp;rsquo;d like addressed, add write a comment and I&amp;rsquo;ll try to answer everything I can.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="https://gamesfromwithin.com/data-oriented-design/"&gt;Last year I wrote about the basics of Data-Oriented Design&lt;/a&gt; (see the September 2009 issue of Game Developer). In the time since that article, Data-Oriented Design has gained a lot of traction in game development and many of teams are thinking in terms of data for some of the more performance-critical systems.&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>There has been a lot of recent discussion (and criticism) on Data Oriented Design recently. I want to address some of the issues that have been raised, but before that, I&rsquo;ll start with this reprint from my most recent Game Developer Magazine. If you have any questions you&rsquo;d like addressed, add write a comment and I&rsquo;ll try to answer everything I can.</em></p>
<p> </p>
<p><a href="/data-oriented-design/">Last year I wrote about the basics of Data-Oriented Design</a> (see the September 2009 issue of Game Developer). In the time since that article, Data-Oriented Design has gained a lot of traction in game development and many of teams are thinking in terms of data for some of the more performance-critical systems.</p>
<p>As a quick recap, the main goal of Data-Oriented Design is achieving high-performance on modern hardware platforms. Specifically, that means making good use of memory accesses, multiple cores, and removing any unnecessary code. A side effect of Data-Oriented Design is that code becomes more modular and easier to test.</p>
<p>Data-Oriented Design concentrates on the input data available and the output data that needs to be generated. Code is not something to focus on (like traditional Computer Science), but is something that is written to transform the input data into the output data in an efficient way. In modern hardware, that often means applying the same code to large, contiguous blocks of homogeneous memory.</p>
<h3 id="applying-data-oriented-design">Applying Data-Oriented Design</h3>
<p><img alt="data.jpg" loading="lazy" src="/data-oriented-design-now-and-in-the-future/images/data.jpg">Itâ€™s pretty easy to apply these ideas to a self-contained system that already works over mostly-homogeneous data. Most particle systems in games are probably designed that way because one of their main goals is to be very efficient and handle a large number of particles at high framerates. Sound processing is another system that is naturally implemented thinking about data first and foremost.</p>
<p>So, whatâ€™s stopping us from applying it to all the performance-sensitive systems in a game code base? Mostly just the way we think about the code. We need to be ready to really look at the data and be willing to split up the code into different phases. Letâ€™s take a high-level example and see how the code would have to be restructured when optimizing for data access.</p>
<p>Listing 1 shows pseudocode for what could be a typical update function for a generic game AI. To make things worse, that function might even be virtual and different types of entities might implement it in different ways. Letâ€™s ignore that for now and concentrate on what it does. In particular, the pseudocode highlights that, as part of the entity update, it does many conditional ray casting queries, and also updates some state based on the results of those queries. In other words, weâ€™re confronted with the typical tree-traversal code structure so common in Object-Oriented Programming.</p>
<pre tabindex="0"><code>void AIEntity::Update(float dt)
{
    DoSomeProcessing();
    if (someCondition &amp;&amp; Raycast(world))
       DoSomething();
    if (someOtherCondition &amp;&amp; BunchOfRayCasts(world))
       DoSomethingElse();
    UpdateSomeOtherStuff();
}
</code></pre><p><em>Listing 1</em></p>
<p>Ray casts against the world are a very common operation for game entities. Thatâ€™s how they â€œseeâ€ whatâ€™s around them and thatâ€™s what allows them to react correctly to their surroundings. Unfortunately, ray casting is a very heavy weight operation, and it involves potentially accessing many different areas in memory: a spatial data structure, other entity representations, polygons in a collision mesh, etc.</p>
<p>Additionally, the entity update function would be very hard to paralellize on multiple cores. Itâ€™s unclear how much data is read or written in that function, and some of that data (like the world data structure) might be particularly hard and expensive to protect from updates from multiple threads.</p>
<p>If we re-organize things a bit, we can significantly improve performance and paralellization.</p>
<h3 id="break-up-and-batch">Break Up And Batch</h3>
<p>Without seeing any of the details of whatâ€™s going on inside the entity update, we can see the raycasts sticking out like a sore thumb in the middle. A raycast operation is fairly independent of anything else related to the entity, itâ€™s heavyweight, and there could be many of them, so itâ€™s a perfect candidate to break up into a separate step.</p>
<p>Listing 2 shows how the broken up entity update code would look like. The update is now split in two different passes: The first pass does some of the updating that can be done independently of any ray casts, and decides which, if any, raycasts need to be performed sometime this frame.</p>
<pre tabindex="0"><code>void AIEntity::InitialUpdate(float dt, RayCastQueries&amp; queries)
{
    DoSomeProcessing();
    if (someCondition)
        AddRayCastQuery(queries);
    if (someOtherCondition)
        AddBunchOfRayCasts(queries);
}

void AIEntity::FinalUpdate(const RayCastResults&amp; results)
{
    UpdateSomeOtherStuff(results);
}
</code></pre><p><em>Listing 2</em></p>
<p>The game code in charge of updating the game processes all AI entities in batches (Listing 3). So instead of calling InitialUpdate(), solve ray casts, and FinalUpdate() for each entity, it iterates over all the AI entities calling InitialUpdate() and adds all the raycast query requests to the output data. Once it has collected all the raycast queries, it can process them all at once and store their results. Finally, it does one last pass and calls FinalUpdate() with the raycast results on each entity.</p>
<pre tabindex="0"><code>RayCastQueries queries;
for (int i=0; i&lt;entityCount; ++i)
    entities[i].InitialUpdate(dt, queries);

// Other update that might need raycasts

RayCastResults results;
for (int i=0; i&lt;queries.count; ++i)
    PerformRayCast(queries[i], results);

for (int i=0; i&lt;entityCount; ++i)
    entities[i].FinalUpdate(results);
</code></pre><p><em>Listing 3</em></p>
<p>By removing the raycast calls from within the entity update function, weâ€™ve shortened the call tree significantly. The functions are more self-contained, easier to understand, and probably much more efficient because of better cache utilization. You can also see how it would be a lot easier to parallelize things now by sending all raycasts to one core while another core is busy updating something unrelated (or maybe by spreading all raycasts across multiple cores, depending on your level of granularity).</p>
<p>Note that after calling InitialUpdate() on all entities, we could do some processing on other game objects that might also need raycast queries and collect them all. That way, we can batch all the raycasts at compute them all at once. For years, weâ€™ve been drilled by graphics hardware manufacturers how we should batch our render calls and avoid drawing individual polygons. This is the same way: By batching all raycasts in a single call, we have the potential to achieve much higher performance.</p>
<h3 id="splitting-things-up">Splitting Things Up</h3>
<p>Have we really gained much by reorganizing the code this way? Weâ€™re doing two full passes over the AI entities, so wouldnâ€™t that be worse from a memory point of view? Ultimately you need to measure it and compare the two. In modern hardware platforms, I would expect performance to be better because, even though weâ€™re traversing through the entities twice, weâ€™re using the code cache much better and weâ€™re accessing them sequentially (which allows us to pre-fetch the next one too).</p>
<p>If this is the only change we make to the entity update, and the rest of the code is the usual deep tree traversal code, we might not have gained much because weâ€™re still blowing the cache limits with every update. We might need to apply the same design principles to the rest of the update function to start seeing performance improvements. But at the very least, even with this small change, we have made it easier to parallelize.</p>
<p>One thing weâ€™ve gained now is the ability to modify our data to fit the way weâ€™re using it, and thatâ€™s the key to big performance gains. For example, after seeing how the entity is updated in two separate passes, you might notice that only some of the data that was stored in the entity object is touched from the first update, and the second pass accesses more specific data.</p>
<p>At that point we can split up the entity class into two different sets of data. One of the most difficult things at this point is naming these sets data in some meaningful way. Theyâ€™re not representing real objects or real-world concepts anymore, but different aspects of a concept, broken down purely by how the data is processed. So what before was an AIEntity, can now become a EntityInfo (containing things like position, orientation, and some high-level data) and AIState (with the current goals, orders, paths to follow, enemies targeted, etc).</p>
<p>The overall update function now deals with EntityInfo structures in the first pass, and AIState structures in the second pass, making it much more cache friendly and efficient.</p>
<p>Realistically, both the first and second passes will have to access some common data (for example the entity current state: fleeing, engaged, exploring, idle, etc). If itâ€™s only a small amount of data, the best solution might be to simply duplicate that data on both structures (going against all â€œcommon wisdomâ€ in Computer Science). If the common data is larger or is read-write, it might make more sense to give it separate data structure of its own.</p>
<p>At this point, a different kind of complexity is introduced: Keeping track of all the relationships from the different structures. This can be particularly challenging while debugging because some of the data belonging to the same logical entity isnâ€™t stored in the same structure and itâ€™s harder to explore in a debugger. Even so, making good use of indices and handles makes this problem much more manageable (see Managing Data Relationships in the September 2008 issue of Game Developer).</p>
<h3 id="conditional-execution">Conditional Execution</h3>
<p>So far things are pretty simple because weâ€™re assuming that every AI entity needs both updates and some ray casts. Thatâ€™s not very realistic because entities are probably very bursty: sometimes they need a lot of ray casts, and sometimes theyâ€™re idle or following orders and donâ€™t need any for a while. We can deal with this situation by adding a conditional execution to the second update function.</p>
<p>The easiest way to conditionally execute the update would be to add an extra output parameter to the FirstUpdate() function indicating whether the entity needs a second update or not. The same information could be derived form the calling code depending on whether there were any raycasts queries added. Then, in the second pass, we only update those entities that appear in the list of entities requiring a second update.</p>
<p>The biggest drawback of this approach is that the second update went from traversing memory linearly to skipping over entities, potentially affecting cache performance. So what we thought was going to be a performance optimization ended up making things slower. Unless weâ€™re gaining a significant performance improvement, itâ€™s often better to simply do the work for all entities whether they need it or not. However, if on average less than 10 or 20 percent of the entities need a ray cast, then it might be worth avoiding doing the second update on all the other entities and paying the conditional execution penalty.</p>
<p>If the number of entities to be updated in the second pass is fairly small, another approach would be to copy all necessary data from the first pass into a new temporary buffer. The second pass can then process that data sequentially without any performance penalties and it would completely offset the performance hit of copying the data.</p>
<p>Finally, another alternative, especially if the conditional execution remains fairly similar from frame to frame, is to relocate entities that need raycasting together. That way the copying is minimal (swapping an entity to a new location in the array whenever it needs a raycast), and we still get the benefit of the sequential second update. For this to work all your entities need to be fully relocatable, which means working with handles or some other indirection, or updating all the references to the entities that swapped places.</p>
<h3 id="different-modes">Different Modes</h3>
<p>What if the entity can be in several, totally different modes of execution? Even if itâ€™s the same type of entity, traversing through them linearly calling the update function could end up using completely different code for each of them, so it will result in poor code cache performance.</p>
<p>There are several approached we can take in a situation like that:</p>
<ul>
<li>If the different execution modes also are tied to different parts of the entity data, we could treat them as if they were completely different entities and break each of their data components apart. That way, we can iterate through each type separately and get all the performance benefits.</li>
<li>If the data is mostly the same, and itâ€™s just the code that changes, we could keep all the entities in the same memory block, but rearrange them so that entities in the same mode are next to each other. Again, if you can relocate your data, this is very easy and efficient (it only requires swapping a few entities whenever the state changes).</li>
<li>Leave it alone! Ultimately, Data-Oriented Design is about thinking about the data and how it affects your program. It doesnâ€™t mean you always have to optimize every aspect of it, especially if the gains arenâ€™t significant enough to warrant the added complexity.</li>
</ul>
<h3 id="the-future">The Future</h3>
<p>Is thinking about a program in terms of data and doing these kind of optimizations a good use of our time? Is this all going to go away in the near future as hardware improves? As far as we can tell right now, the answer is a definite no. Efficient memory access with a single CPU is a very complicated problem, and matters get much worse as we add more cores. Also, the amount of transistors in CPUs (which is a rough measure of power) continues to increase much faster than memory access time. That tells us that, barring new technological breakthroughs, weâ€™re going to be dealing with this problem for a long time. This is a problem we need to deal with right now and build our technology around it.</p>
<p>There are some things Iâ€™d like to see in the future to make Data-Oriented Design easier. We can all dream up of a new language that will magically allow for great memory access and easy paralellization, but replacing C/C++ and all existing libraries is always going to be a really hard sell. Historically, the best advances in game technology have been incremental, not throwing away existing languages, tools, and libraries (thatâ€™s why weâ€™re still stuck with C++ today).</p>
<p>Here are two things that could be done right now and work with our existing codebases. I know a lot of developers are working on similar systems in their projects, but it would be great to have a common implementation released publicly so we can all build on top of them.</p>
<h3 id="language">Language</h3>
<p>Even though a functional language might be ideal, either created from scratch or reusing an existing one, we could temporarily extend C to fit our needs. I would like to see a set of C extensions where functions have clearly defined inputs and outputs, and code inside a function is not allowed to access any global state or call any code outside that function (other than local helper functions defined in the same scope). This could be done as a preprocessor or a modified C compiler, so it remains very compatible with existing libraries and code.</p>
<pre tabindex="0"><code>void FirstEntityUpdate(input Entities* entities, input int entityCount, output RayCastQueries* queries, output int queryCount);
</code></pre><p>Dependencies between functions would be expressed by tying the outputs of some functions to the input of other functions. This could be done in code or through the use of GUI tools that help developers manage data relationships visually. That way we can construct a dependency diagram of all the functions involved in every frame.</p>
<h3 id="scheduler">Scheduler</h3>
<p>Once we have the dependencies for every function, we can create a directed acyclic graph (DAG) from it, which would give us a global view of how data is processed every frame. At that point, instead of running functions manually, we can leave that job in the hands of a scheduler.</p>
<p>The scheduler has full information about all the functions as well as the number of available cores (and information from the previous frame execution if we want to use that as well). It can determine the critical path through the DAG and optimize the scheduling of the tasks so the critical path is always being worked on. If temporary memory buffers are a limitation for our platform, the scheduler can take that into account and trade some performance time for a reduced memory footprint.</p>
<p>Just like the language, the scheduler would be a very generic component, and could be made public. Developers could use it as a starting point, build on top of it, and add their own rules for their specific games and platforms.</p>
<p> </p>
<p>Even if weâ€™re not ready to create those reusable components, every developer involved in creating high-performance games should be thinking about data in their games right now. Data is only going to get more important in the future as the next generation of consoles and computers rolls in.</p>
<p> </p>
<p><em>This article was originally printed in the September 2010 issue of <a href="http://gdmag.com">Game Developer</a>.</em></p>]]></content:encoded></item><item><title>2010: Living The Dream</title><link>https://gamesfromwithin.com/2010-living-the-dream/</link><pubDate>Fri, 31 Dec 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/2010-living-the-dream/</guid><description>&lt;p&gt;It&amp;rsquo;s that time of the year again. We all look back at what happened and have high hopes for the coming year.&lt;/p&gt;
&lt;p&gt;&lt;img alt="New-Year-in.jpg" loading="lazy" src="https://gamesfromwithin.com/2010-living-the-dream/images/New-Year-in.jpg"&gt;&lt;/p&gt;
&lt;p&gt;For me this marked my fourth year as an indie developer. It&amp;rsquo;s not a huge milestone by any standard, but the fact that I&amp;rsquo;ve been going at it for this long and I&amp;rsquo;m not broke yet means it&amp;rsquo;s a sustainable business. Actually, as you know if you followed some of &lt;a href="https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/"&gt;my&lt;/a&gt; &lt;a href="https://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/"&gt;numbers&lt;/a&gt; &lt;a href="https://gamesfromwithin.com/the-power-of-free/"&gt;posts&lt;/a&gt;, this was the first year that income from my apps finally became (reasonably) profitable. Now, *that* is something worth celebrating!&lt;/p&gt;</description><content:encoded><![CDATA[<p>It&rsquo;s that time of the year again. We all look back at what happened and have high hopes for the coming year.</p>
<p><img alt="New-Year-in.jpg" loading="lazy" src="/2010-living-the-dream/images/New-Year-in.jpg"></p>
<p>For me this marked my fourth year as an indie developer. It&rsquo;s not a huge milestone by any standard, but the fact that I&rsquo;ve been going at it for this long and I&rsquo;m not broke yet means it&rsquo;s a sustainable business. Actually, as you know if you followed some of <a href="/making-a-living-barely-on-the-iphone-app-store/">my</a> <a href="/making-a-living-comfortably-on-the-app-store/">numbers</a> <a href="/the-power-of-free/">posts</a>, this was the first year that income from my apps finally became (reasonably) profitable. Now, *that* is something worth celebrating!</p>
<p>Doing this kind of small-scale game development is exactly what I would do if I didn&rsquo;t have to worry about money at all, so this is truly living the dream for me.</p>
<h3 id="goals">Goals</h3>
<p>All is not sunshine and roses in Noel indie-land though. I accomplished some of my goals for this year, but missed others by a mile and a half:</p>
<p><img alt="goals.png" loading="lazy" src="/2010-living-the-dream/images/goals.png"></p>
<p>I released a bunch of Flower Garden updates and ran a bunch of promotions that kept bringing revenue up. That went very well. Check.</p>
<p><a href="http://twitter.com/#!/mysterycoconut">Miguel</a> and I also submitted <a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a> to the <a href="/caseys-contraptions-and-the-igf/">IGF</a> (with three hours to spare the day of the deadline). I&rsquo;m very proud of that one. Even if we&rsquo;re not selected as a finalist, the experience of submitting it and finally participating in the IGF was fantastic. Check.</p>
<p>Games shipped. Hmm&hellip;. That&rsquo;s the total fail. The only new game I shipped this year was <a href="http://itunes.apple.com/us/app/lorax-garden/id366510234?mt=8&amp;partnerId=30&amp;siteID=aDkhM0mDflg">Lorax Garden</a>, a very short project in collaboration with <a href="http://oceanhousemedia.com">Oceanhouse Media</a>, mixing their Dr. Seuss license with the flower technology I had already developed. I didn&rsquo;t even manage to ship Casey&rsquo;s before Christmas like I was hoping to do. I could make excuses but there&rsquo;s no point. Real life happens and things go slower than planned (that topic is already brewing for a future post).</p>
<p>My goal for next year is to ship three new games, but always of the quality that I can be proud of. I&rsquo;ll have to be very careful about design and scope to achieve that (I&rsquo;m hoping that hanging out with <a href="http://twitter.com/#!/eeen">Ian</a> and <a href="http://twitter.com/#!/nimbledave">Dave</a> will rub off some of that genius they have for making <a href="http://nimblebit.com/">awesome games on a crazy-short schedule</a>).</p>
<h3 id="games-from-within">Games From Within</h3>
<p>I started my blog, Games From Within, <a href="/book-review-slack-getting-past-burnout-busywork-and-the-myth-of-total-efficiency/">exactly 7 years ago today</a>. I guess that counts as my longest-running project. Some years it was sorely neglected with just a few posts, but this year I spent a significant amount of time on it, thanks in large part to <a href="http://idevblogaday.com/">#idevblogaday</a>.</p>
<p>These were the most popular posts for this year (based on page views, which RSS readers make much harder to track):</p>
<ul>
<li><a href="/making-a-living-barely-on-the-iphone-app-store/">Making A Living (Barely) On The iPhone App Store (aka The Numbers Post)</a></li>
<li><a href="/data-oriented-design/">Data-Oriented Design (Or Why You Might Be Shooting Yourself in The Foot With OOP)</a></li>
<li><a href="/the-const-nazi/">The Const Nazi</a> (This one is a total surprise that it made it this high up!)</li>
<li><a href="/making-a-living-comfortably-on-the-app-store/">Making A Living (Comfortably) On The App Store (aka The Numbers Post #2)</a></li>
<li><a href="/prototyping-youre-probably-doing-it-wrong/">Prototyping: Youâ€™re (Probably) Doing It Wrong</a></li>
<li><a href="/google-app-engine-as-back-end-for-iphone-apps/">Google App Engine As Back End For iPhone Apps</a></li>
<li><a href="/increase-your-app-ratings-on-the-app-store/">Increase Your App Ratings On The App Store</a></li>
<li><a href="/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/">GDC 2010: The Best of Both Worlds: Using UIKit with OpenGL</a></li>
</ul>
<p>2011 should be an exciting year for me personally and for all indie game developers out there. Happy new year everybody!</p>
]]></content:encoded></item><item><title>Jigsaw Guru For The Windows Phone 7 Postmortem</title><link>https://gamesfromwithin.com/jigsaw-guru-for-the-windows-phone-7-postmortem/</link><pubDate>Thu, 23 Dec 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/jigsaw-guru-for-the-windows-phone-7-postmortem/</guid><description>&lt;p&gt;&lt;em&gt;This is a new guest post by &lt;a href="http://twitter.com/#!/fredericmy"&gt;Frederic My&lt;/a&gt;. Frederic and I worked together in the past in big console games development, and now we&amp;rsquo;re both enjoying the indie life and making games for mobile platforms. Frederic is sharing with us how the development of his first Windows Phone 7 game went. Thanks Frederic!&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="new-beginning"&gt;New beginning&lt;/h3&gt;
&lt;p&gt;When my job position got terminated last summer, I decided I would take a break from working for big companies, and try to make a game on my own at home. I&amp;rsquo;ve been in the video game industry since the late nineties, I&amp;rsquo;ve written code for a few released PC and console AAA titles and probably as many canceled ones, and I wanted to do something different at least for a few months. Go back to the roots of game development, when one or two guys could create something in their garage or bedroom, without spending years and millions of dollars on it.&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>This is a new guest post by <a href="http://twitter.com/#!/fredericmy">Frederic My</a>. Frederic and I worked together in the past in big console games development, and now we&rsquo;re both enjoying the indie life and making games for mobile platforms. Frederic is sharing with us how the development of his first Windows Phone 7 game went. Thanks Frederic!</em></p>
<h3 id="new-beginning">New beginning</h3>
<p>When my job position got terminated last summer, I decided I would take a break from working for big companies, and try to make a game on my own at home. I&rsquo;ve been in the video game industry since the late nineties, I&rsquo;ve written code for a few released PC and console AAA titles and probably as many canceled ones, and I wanted to do something different at least for a few months. Go back to the roots of game development, when one or two guys could create something in their garage or bedroom, without spending years and millions of dollars on it.</p>
<h3 id="platform-choice">Platform choice</h3>
<p>I&rsquo;m a C# fan, I won&rsquo;t deny it, I even <a href="http://www.fairyengine.com/articles/cppvscsharp.htm">explained why</a> back in 2007. I also toyed with XNA each time a new version was released, and I like how straightforward it is to use. When the beta version of the tools to develop for the Windows Phone 7 (WP7 for short) became available, just at the right time for me, it seemed like the obvious choice for what I wanted to do. And developing for a brand new platform sounded exciting as well, even if it was perhaps a riskier bet than targeting well established markets. For those who don&rsquo;t know much about WP7 development, I just want to highlight a few key points:</p>
<ul>
<li>Applications are written in Visual Studio using C#, and either XNA or Silverlight. This may come in the future, but at this point you are not allowed to mix them, and use the controls of Silverlight with the faster rendering of XNA, for example.</li>
<li>In App Purchases are not supported yet.</li>
<li>Programmable shaders are not available for WP7 (they obviously are for the PC and XBox360) in the current version of XNA. Instead, you have 5 predefined shaders with features that can be toggled on and off (such as fog or per pixel lighting). These shaders should cover most of the usual needs, but if you want something very specific that they don&rsquo;t support, you&rsquo;re out of luck (or have to fall back to multiple passes and alpha blending).</li>
<li>Paid applications have a trial mode, that allows users to evaluate them before making a purchase. Unlike on XBox Live Indie Games (XBLIG), where the game just abruptly stops after 8 minutes, developers have a complete control over what they want to show in trial mode (for example, the first few levels of a game, with no time limit, or without the ability to save, etc). In theory, this means you shouldn&rsquo;t have to make a free version of your game in addition to the paid one, but I&rsquo;ll come back to this later.</li>
<li>The certification requirement document is only 27 pages long, table of content and change history included.</li>
</ul>
<h3 id="the-project">The project</h3>
<p><img alt="aaa9dd16-fbda-df11-a844-00237de2db9e.png" loading="lazy" src="/jigsaw-guru-for-the-windows-phone-7-postmortem/images/aaa9dd16-fbda-df11-a844-00237de2db9e.png">I wrote a few ideas on paper, but they all looked too ambitious for a first project. One thing in particular that I wanted to avoid was to require a lot of content, since I didn&rsquo;t even know how I was going to find an artist yet. During a bike ride, I thought about using photos, and that&rsquo;s how I decided to make a jigsaw puzzle game. Not super original, I know, there are several of those on the iPhone and iPad, but there was none on the WP7 since it wasn&rsquo;t released yet :), and it looked like a good project of the right scope to keep things under control and learn the platform. For example, I had never worked with a touch screen device, and it was pretty obvious from the start that I was going to spend quite some time iterating on the user interface part of the game. ï¿¼ The game is called Jigsaw Guru, and you can go to <a href="http://www.fairyengine.com/">http://www.fairyengine.com</a> to see more screenshots and a video.</p>
<h3 id="what-went-right">What went right</h3>
<p>I actually already mentioned some of the things that went right in my opinion, but here is the full list:</p>
<ul>
<li>Working on a short project, without too much content to integrate, instead of picking another more ambitious and time consuming idea, was the right choice. My goal was to have Jigsaw Guru on the marketplace the day of the WP7 launch, I submitted it on 10/18 and it got approved on 10/23 (the update I submitted in December passed even faster than that), two weeks before the US launch and two days after the other territories started getting their phones. At times I still had more items on my to-do list than I would have liked, and I made a good push in the last 3 weeks to get everything wrapped up in time, but it never got too crazy.</li>
<li>Knowing the tools beforehand, and using C# and XNA, definitely made me feel productive. The phone emulator was surprisingly stable in the beta, and the XNA forums were very helpful when I wasn&rsquo;t sure about something. It&rsquo;s also worth noting that the website used to submit bug reports allows everybody to see what other people have written, and vote on issues you think are important and should be fixed first.</li>
<li>Garbage collection is the one thing that can hurt your framerate really bad when using XNA on XBox360 and WP7. But it&rsquo;s not that hard to avoid: when I had a look at my memory usage late in the project, I only found two spots where I was creating some amount of garbage each frame (both related to strings). Basically what I do is each time the player goes from one screen to another, I load everything I need for the new screen, and I force a garbage collection. This gets rid of temporary objects that may have been created during the loading process, and objects from the previous screen that are not used anymore. After that, I don&rsquo;t allocate anything, and the garbage collector never has to do any work.</li>
<li>Finally: testing. Very few people tested my game while I was developing it, but my friend Alexis alone kept giving me more feedback than I thought I could handle. He never said anything was good just to make me happy, he reported every little detail he didn&rsquo;t like, even and especially the ones I was aware of but never had time to fix (and maybe thought nobody would notice). Even if I sometimes felt he was nitpicking, this was exactly what I needed.</li>
</ul>
<p><img alt="jigsawguru2small.png" loading="lazy" src="/jigsaw-guru-for-the-windows-phone-7-postmortem/images/jigsawguru2small.png"></p>
<h3 id="what-went-wrong">What went wrong</h3>
<p>Developing for a new platform has its share of drawbacks, it&rsquo;s just how it is. The final version of XNA 4.0 only came out mid-September, and before that I was working with the beta version. As mentioned before, it was pretty solid already, but there was no redistribution of the runtime. Which means you had to install all the tools to be able to just run the game, and you could only install them under Vista or Windows 7 because the phone emulator requires DirectX10, and some of my potential testers were still using Windows XP. So, even if what I was sending was a PC version of the game, they couldn&rsquo;t run it on XP just because the phone emulator, which they didn&rsquo;t need, requires a more recent operating system. To work around this problem, I made an XNA 3.1 PC version of Jigsaw Guru, but maintaining two versions side by side for several weeks and merging back and forth between them was not fun.</p>
<p>Coding for a device that wasn&rsquo;t released yet also meant I could not test what I was doing on real hardware. I unsuccessfully tried to get a phone prototype, and basically the only way I found to run my game on a WP7 at the end of September was to go to a Microsoft event. Even there, I thought there would be phones locked to the tables, that developers could connect to their laptop and use for the whole day, but I was wrong: there was no such thing, and the 4-5 persons who already had a working application to test like me had to do it on the phone of the event&rsquo;s organizer, when he wasn&rsquo;t using it for something else. I was able to run my application twice for about 5 minutes each time, and fortunately everything seemed to be working fine, which is a testament of the reliability of the emulator.</p>
<p>When the game began to be really playable, with most of the screens that are in the final version, I started looking for an artist and a musician. I did it way too late, and I was lucky to find Aimee and Tim through the XNA forums, and that the time estimates they gave me just matched my own programming deadline. So, in the end everything worked out well, but even if I wanted to wait and be sure the UI elements were final before asking somebody to redo them, I believe I also waited just because I was more comfortable doing my programming tasks first, and that was a mistake.</p>
<p>Marketing was a difficult problem: I knew I needed to do some, but how? When Jigsaw Guru got approved, the WP7 wasn&rsquo;t out yet in the US, and had just been released in a few countries of Europe and Asia, as well as Australia and New Zealand. Basically, nobody had that phone yet, and I couldn&rsquo;t find any website reviewing its games. Even when I had a second look for the US launch, I only saw a couple of sites testing 2 or 3 of the official XBox Live games (that&rsquo;s how they&rsquo;re called even if they run on a phone), but nothing related to indie games. So, what ended up happening is I did nothing, and just hoped that because there weren&rsquo;t too many applications on the marketplace yet (which is the reason for being a launch title, right?), people interested in jigsaw puzzle games would fine mine. Of course I was wrong, and the fact that the search in the Zune software didn&rsquo;t seem to care about the keywords you enter when submitting your app, or couldn&rsquo;t find my game when searching for &lsquo;jigsaw&rsquo;, didn&rsquo;t help (this seems to be fixed now). I don&rsquo;t know how other developers releasing WP7 games around the same time as me handled their marketing, but I would be curious to hear it, that question is still a mystery to me.</p>
<h3 id="downloads-and-sales">Downloads and sales</h3>
<p>This could have been another paragraph in the &ldquo;what went wrong&rdquo; category, but I think this subject deserves its own section. Download and sale numbers for WP7 apps became available on Wednesday 12/08, and I don&rsquo;t think anybody was thrilled. Don&rsquo;t get me wrong: WP7 is a very young platform, there aren&rsquo;t tens of millions of phones in circulation, sale expectations have to be low for now, and can certainly not be compared with those of competing platforms. No, what really surprised me is not the number of sales, but the number of downloads.</p>
<p>On the &ldquo;top selling&rdquo; tab of the Zune software (which is more likely based on downloads, like the Bing visual search), Jigsaw Guru has always been in the middle of the paid games from the puzzle &amp; trivia category, the biggest category by far (about 45% of all games). Today for example, it&rsquo;s 174th out of 363. How many downloads do you think this means on average? About 0.65 per day. This totally blows my mind, but is in line with <a href="http://wmpoweruser.com/developer-sales-data-reveals-logarithmic-marketplace-70000-downloads/">a graph a developer made with the numbers from his 4 apps</a>, that shows the relationship between the marketplace rank and the number of downloads.</p>
<p>One potential problem is it&rsquo;s not obvious enough that lots of paid games support the free trial mode, and some players don&rsquo;t know they can download them for free. But really, it all comes down to most players only checking the XBox Live and the free sections, and rarely visiting the paid one. Which is why although I said earlier that in theory, and thanks to the trial mode, you shouldn&rsquo;t need to make a free version of your paid game, in practice it&rsquo;s obvious this doesn&rsquo;t work, and you have to do it. My friend Noel, who is an experienced iPhone developer, had actually told me I should release my game as a free, ad supported app; unfortunately, the ad SDK&rsquo;s for XNA didn&rsquo;t exist at launch and are still in their infancy, the one from Microsoft got released this month and only serves ads in the US, the other ones are either not finished or not stable yet.</p>
<p>So, what&rsquo;s next? I&rsquo;m submitting Jigsaw Guru Free (with the Microsoft ad SDK) this week, because as a developer, I still want people to play my game and hopefully have a good time with it. The two projects I started working on after Jigsaw Guru might follow the same path and be free apps from the start, whether it&rsquo;s on the WP7 or another platform.</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>The Power Of In-App Purchases</title><link>https://gamesfromwithin.com/the-power-of-in-app-purchases/</link><pubDate>Tue, 09 Nov 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-power-of-in-app-purchases/</guid><description>&lt;p&gt;I finally managed to get through the hotel wifi and upload the slides for this morning&amp;rsquo;s &lt;a href="http://360idev.com"&gt;360iDev&lt;/a&gt; talk: The Power Of In-App Purchases. Thanks everybody who attended for the great questions and feedback!&lt;/p&gt;
&lt;h3 id="session-description"&gt;Session description&lt;/h3&gt;
&lt;p&gt;The common-sense approach to make money on the App Store used to be to do anything to get on the top charts. In-app purchases changed all of that. Good in-app purchases can make your app profitable without being anywhere on the charts, and are the best hope for the independent developer. Come to this session to learn why IAPs can be so effective and how to leverage them effectively: what makes a good IAP, how to increase your user involvement, how to present IAPs in an attractive way, what things attract users, and what things turn them away. We&amp;rsquo;ll go through lots of detailed real-world data from Flower Garden and other games with strong IAPs.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I finally managed to get through the hotel wifi and upload the slides for this morning&rsquo;s <a href="http://360idev.com">360iDev</a> talk: The Power Of In-App Purchases. Thanks everybody who attended for the great questions and feedback!</p>
<h3 id="session-description">Session description</h3>
<p>The common-sense approach to make money on the App Store used to be to do anything to get on the top charts. In-app purchases changed all of that. Good in-app purchases can make your app profitable without being anywhere on the charts, and are the best hope for the independent developer. Come to this session to learn why IAPs can be so effective and how to leverage them effectively: what makes a good IAP, how to increase your user involvement, how to present IAPs in an attractive way, what things attract users, and what things turn them away. We&rsquo;ll go through lots of detailed real-world data from Flower Garden and other games with strong IAPs.</p>
<p><img alt="purchases_vs_users.png" loading="lazy" src="/the-power-of-in-app-purchases/images/purchases_vs_users.png"></p>
<p><strong>Presentation slides:</strong> [<a href="http://www.slideshare.net/llopis/power-iap">Slideshare</a>] [<a href="/wp-content/uploads/2010/11/power_iap.pdf">pdf</a>]</p>
]]></content:encoded></item><item><title>Chronicle Of A Failed Experiment</title><link>https://gamesfromwithin.com/chronicle-of-a-failed-experiment/</link><pubDate>Thu, 04 Nov 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/chronicle-of-a-failed-experiment/</guid><description>&lt;p&gt;In the last year and a half, I&amp;rsquo;ve written about the different things that I&amp;rsquo;ve tried with Flower Garden and their effects on sales. From &lt;a href="https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/"&gt;adding Facebook support, creating a free version&lt;/a&gt;, &lt;a href="https://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/"&gt;adding in-app purchases&lt;/a&gt;, or &lt;a href="https://gamesfromwithin.com/the-power-of-free/"&gt;giving Flower Garden for free for a limited time&lt;/a&gt;. Some strategies worked and some didn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Today I want to share my latest experiment, and how it was a total and complete failure: Adding the option to gift IAP items from within the game.&lt;/p&gt;</description><content:encoded><![CDATA[<p>In the last year and a half, I&rsquo;ve written about the different things that I&rsquo;ve tried with Flower Garden and their effects on sales. From <a href="/making-a-living-barely-on-the-iphone-app-store/">adding Facebook support, creating a free version</a>, <a href="/making-a-living-comfortably-on-the-app-store/">adding in-app purchases</a>, or <a href="/the-power-of-free/">giving Flower Garden for free for a limited time</a>. Some strategies worked and some didn&rsquo;t.</p>
<p>Today I want to share my latest experiment, and how it was a total and complete failure: Adding the option to gift IAP items from within the game.</p>
<p><img alt="gift_this.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/gift_this.png"></p>
<h3 id="promo-codes">Promo Codes</h3>
<p>Before I can talk about how I implemented the &ldquo;Gift This&rdquo; feature, we need to talk about promo codes. Since Flower Garden has so many in-app purchases, I figured it would be very handy to have the ability to give some of them away to people for any reason: They mistakenly downloaded the wrong thing, they bought it in the free version and want to upgrade to the full one, or they supposedly paid for one but they never got it. Whatever the reason, having my own promo codes for in-app purchases was one of the best decisions I could have made. I would highly recommend it if you have IAPs, especially consumables.</p>
<p>The implementation of promo codes was totally straightforward. I have two tables in the Google App Engine: One for active promo codes and one for redeemed ones. The active promo code includes the code itself, the IAP item it refers to, the amount, and whether it&rsquo;s limited to one user or not (if it&rsquo;s limited to one user, the code goes away as soon as it&rsquo;s redeemed, otherwise, any amount of users can redeem it).</p>
<p>Here&rsquo;s an example of a code I just added (yes, feel free to redeem it in the Flower Shop):</p>
<p><img alt="promo_code.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/promo_code.png"></p>
<p>Whenever a promo code is redeemed, I enter that data in the other table. That way not only do I have a log of what codes where redeemed and when, but I can also check and prevent the same device from redeeming the same code multiple times.</p>
<p>Another important reason to keep a redeemed promo code table is that I want promo codes to be as valid as purchasing the IAP directly. That means that if you ever attempt to purchase an item, I check first to see if you&rsquo;ve redeemed a promo code for it, and if so, you can re-download it for free. Same thing when you do a restore purchases (although I believe I haven&rsquo;t gotten around to implementing that part yet :-)</p>
<p>Here&rsquo;s my plea to Apple: <strong>Please, please, please, give us an &ldquo;iTunes Account ID&rdquo; along with the IAP data</strong>. Right now the best we can do is associate a purchase with a device (which is not good enough), or have a whole registration system for users (which is a pain and more time consuming for users). They&rsquo;re already doing this with a Game Center ID, so why not with an iTunes Account?</p>
<h3 id="gift-this">Gift This</h3>
<p>Once the promo code system was in place and field tested for a couple of months, I finally implemented the Gift This functionality. In the Flower Shop, users have the option to buy an item for themselves, or for someone else.</p>
<p>The first time you use the Gift This feature it explains how it works: You purchase the item and then you send it to someone else through email.</p>
<p>Under the hood, it purchases the IAP, contacts the server to generate a new promo code for that item, and then creates an email with the promo code and even a custom URL. Whenever someone receives a gift email, they can just click on the custom link and they immediately receive the item (assuming they have Flower Garden installed, of course).</p>
<p><img alt="gift_email.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/gift_email.png"></p>
<p>One interesting consequence is that to implement this, you need to create one new IAP item for every item you want to gift (especially if they&rsquo;re not consumable). Otherwise, someone couldn&rsquo;t gift an item they had already purchased, or they couldn&rsquo;t gift it more than once. This can add quite a few extra IAPs in your list!</p>
<p>In the case of Flower Garden, I started with the easiest case, and I only implemented gifting for fertilizer purchases (because they&rsquo;re consumable, so I don&rsquo;t have to keep track of who receives them and restoring them).</p>
<h3 id="total-failure">Total Failure</h3>
<p>I really had great hopes for the Gift This feature. I had already envisioned writing a blog post showing IAP revenue going up 20-30% because of that feature. Not quite! It was pretty much a complete flop. The only positive thing I can say about it is that it didn&rsquo;t actually lower regular sales.</p>
<p>See for yourself. In a period of about a month and a half, all the fertilizer gifting in the free and paid versions of Flower Garden amounted to a whopping $191!</p>
<p><img alt="gift_revenue.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/gift_revenue.png"></p>
<p>Definitely not worth the 3-4 days it took me to implement it (and the opportunity cost of not being able to add some other feature or IAP).</p>
<p>Compare it to fertilizer sales during that period of over $7,000:</p>
<p><img alt="fertilizer_revenue.png" loading="lazy" src="/chronicle-of-a-failed-experiment/images/fertilizer_revenue.png"></p>
<p>(That&rsquo;s the spike of the new feature plus <a href="/communicating-with-players/">the Pocket Frogs cross promotion</a> if you were wondering about it).</p>
<p>I&rsquo;d love to know how the Gift This feature on the App Store is working out for Apple. I&rsquo;m sure it&rsquo;s doing better than my attempt at it, but I&rsquo;m going to bet it&rsquo;s still a very small percentage compared to regular sales.</p>
<p>Here comes the important question: Why was it a failure? Do people don&rsquo;t like to gift? Was it presented badly? Did most people not know it existed?</p>
<p>There&rsquo;s no way to know for sure, but my current guess is that <strong>people don&rsquo;t like to gift something they don&rsquo;t already own</strong>. Psychologically, there are several too many steps involved: Oh, I want to gift something, look for it in the store, purchase it, and send the email. Not a very fulfilling experience.</p>
<p>On the other hand, gifting something you already own is much more appealing. You have it in front of you, you&rsquo;re proud of it and it looks great. You tap on a button and send it to someone. That is a lot more satisfying. So in the future I&rsquo;ll take that approach and allow people to gift things they already own, even if they had to previously pay for it in some way.</p>
<p>What do you think? Do you have a better theory? How could it have been improved?</p>
<p><em>This post is part of <a href="http://idevblogaday.com/">iDevBlogADay</a>, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the <a href="http://idevblogaday.com/">web site</a>, <a href="http://feeds.feedburner.com/idevblogaday">RSS feed</a>, or <a href="http://twitter.com/#search?q=%23idevblogaday">Twitter</a>.</em></p>
]]></content:encoded></item><item><title>Casey's Contraptions Weekly Update (Oct 29)</title><link>https://gamesfromwithin.com/caseys-contraptions-weekly-update-oct-29/</link><pubDate>Fri, 29 Oct 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/caseys-contraptions-weekly-update-oct-29/</guid><description>&lt;p&gt;&lt;img alt="Casey-Portrait-2.png" loading="lazy" src="https://gamesfromwithin.com/caseys-contraptions-weekly-update-oct-29/images/Casey-Portrait-2.png"&gt;I like to be as open as possible about any project I&amp;rsquo;m working on, whether it&amp;rsquo;s giving talks, sharing technology, or discussing sales numbers. That goes for projects in progress too, although sometimes it makes sense to wait a while before announcing them. In the case of &lt;a href="http://www.caseyscontraptions.com/"&gt;Casey&amp;rsquo;s Contraptions&lt;/a&gt;, we had an &lt;a href="https://gamesfromwithin.com/caseys-contraptions-and-the-igf/"&gt;early announcement&lt;/a&gt; because of the &lt;a href="http://www.igf.com/php-bin/entry2011.php?id=384"&gt;IGF entry&lt;/a&gt;, so we might as well start talking about the game.&lt;/p&gt;
&lt;p&gt;At one point I was half-seriously toying with the idea of creating a Twitter account that would show our latest commits to Subversion. Apart from the 140 character limit, that falls in the TMI category.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Casey-Portrait-2.png" loading="lazy" src="/caseys-contraptions-weekly-update-oct-29/images/Casey-Portrait-2.png">I like to be as open as possible about any project I&rsquo;m working on, whether it&rsquo;s giving talks, sharing technology, or discussing sales numbers. That goes for projects in progress too, although sometimes it makes sense to wait a while before announcing them. In the case of <a href="http://www.caseyscontraptions.com/">Casey&rsquo;s Contraptions</a>, we had an <a href="/caseys-contraptions-and-the-igf/">early announcement</a> because of the <a href="http://www.igf.com/php-bin/entry2011.php?id=384">IGF entry</a>, so we might as well start talking about the game.</p>
<p>At one point I was half-seriously toying with the idea of creating a Twitter account that would show our latest commits to Subversion. Apart from the 140 character limit, that falls in the TMI category.</p>
<p>So instead, I thought it might be interesting to give a weekly update with what Miguel and I have been up to each week. Hopefully it will give you a glimpse at what&rsquo;s going on behind the scenes. Any feedback in what you want to see more or less of is totally welcome.</p>
<h3 id="week-of-oct-29">Week Of Oct 29</h3>
<p><img alt="sidebar2.png" loading="lazy" src="/caseys-contraptions-weekly-update-oct-29/images/sidebar2.png">Both Miguel and I felt this was a very slow week. I&rsquo;m not sure exactly why, but I suspect post-IGF submission syndrome. We&rsquo;re feeling the mini-crunch we did leading up to it, and now we have lots of not-so-fun tasks to do on our planes. Still, I think we&rsquo;ve been slowly picking up speed. Next week should be a fully productive one.</p>
<h4 id="sound-effects">Sound Effects</h4>
<p>We added audio for in-game sound effects. Up until now we only had background music and no sound effects at all. Yes, that means we submitted to the IGF without sounds. Yikes! We had to cut corners somewhere. Fortunately, since the IGF takes updates, the next update will include some initial sound effects.</p>
<p>We&rsquo;re using OpenAL for audio playback, and I was pleasantly surprised to see how simple and efficient it is. What a great change from using AVAudioPlayer!</p>
<p>We&rsquo;re currently trying to define the style of the sound effects. It&rsquo;s a strange mix of slightly cartoony, but not too much. Hopefully we&rsquo;ll zero in on that next week.</p>
<h4 id="sharing-of-levels">Sharing Of Levels</h4>
<p>Sharing of levels. We can finally share levels through email. It makes sending levels to each other much easier, and it should come in handy for the next round of testing. Of course, we still can&rsquo;t reference an attached file from an email using the Apple API, so we&rsquo;re having to submit levels and a screenshot to the server and store it there.</p>
<h4 id="sandbox-editor">Sandbox editor</h4>
<p>There&rsquo;s more to creating a level than just placing objects. To create a playable level we need a title, a specific background, some goals, and a set of available items in the toolbox. Since we want people to share fully-featured levels, we&rsquo;re building this UI right into the game, and it&rsquo;s what we&rsquo;re going to use to create all the levels ourselves. We can&rsquo;t wait to see what people create, but, I have to admit, it&rsquo;s somewhat of a pain to implement :-). We still have a few days of work in this one.</p>
<p>Right now it&rsquo;s all using UIKit on top of OpenGL. I&rsquo;m still waiting for a great, cross-platform GUI library + tools that gives us the basic features from UIKit + Interface Builder but it&rsquo;s fully cross-platform.</p>
<p>Also, while Miguel isn&rsquo;t looking, I&rsquo;ll share with you what we have so far for the level editor sidebar.</p>
<p>In case you missed it, <a href="http://twitter.com/#!/caseycs">Casey has a Twitter account</a>. And apparently <a href="http://twitter.com/#!/caseycs/status/28752775787">he likes Angry Birds quite a bit</a>! :-)</p>
<p>Also, don&rsquo;t forget to join the <a href="http://www.facebook.com/pages/Caseys-Contraptions/158351050866139">Casey&rsquo;s Contraptions Facebook page</a>.</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>Start Pre-allocating And Stop Worrying</title><link>https://gamesfromwithin.com/start-pre-allocating-and-stop-worrying/</link><pubDate>Mon, 25 Oct 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/start-pre-allocating-and-stop-worrying/</guid><description>&lt;p&gt;&lt;em&gt;One of the more frequent questions I receive is what kind of memory allocation strategy I use in my games. The quick answer is none (at least frame to frame, I do some allocation at the beginning of each level on a stack-based allocator). This reprint of one of my Inner Product column covers quite well how I feel about memory allocation.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve all had things nagging us in the back of our minds. They&amp;rsquo;re nothing we have to worry about this very instant, just something we need to do sometime in the future. Maybe that&amp;rsquo;s changing those worn tires in the car, or making an appointment with the dentist about that tooth that has been bugging you on and off.&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>One of the more frequent questions I receive is what kind of memory allocation strategy I use in my games. The quick answer is none (at least frame to frame, I do some allocation at the beginning of each level on a stack-based allocator). This reprint of one of my Inner Product column covers quite well how I feel about memory allocation.</em></p>
<p>We&rsquo;ve all had things nagging us in the back of our minds. They&rsquo;re nothing we have to worry about this very instant, just something we need to do sometime in the future. Maybe that&rsquo;s changing those worn tires in the car, or making an appointment with the dentist about that tooth that has been bugging you on and off.</p>
<p>Dynamic memory allocation is something that falls in that category for most programmers. We all know we can&rsquo;t just go on allocating memory willy-nilly whenever we need it, yet we put off dealing with it until the end of the project. By that time, deadlines are piling on the pressure and it&rsquo;s usually too late to make significant changes. With a little bit of forethought and pre-planning, we can avoid those problems and be confident our game is not going to run out of memory in the most inopportune moment.</p>
<h3 id="on-demand-dynamic-memory-allocation">On-Demand Dynamic Memory Allocation</h3>
<p><img alt="memory-all-ranks.jpg" loading="lazy" src="/start-pre-allocating-and-stop-worrying/images/memory-all-ranks.jpg">The easiest way to get started with memory management is to allocate memory dynamically whenever you need it. This is the approach many software engineering books consider as ideal and it&rsquo;s often encouraged in Computer Science classes.</p>
<p>It&rsquo;s certainly an easy approach to use. Need a new animation instance when the player is landing on a ledge? Allocate it. Need a new sound when we reach the goal? Just allocate another one!</p>
<p>On-demand dynamic memory allocation can help to keep memory usage to a minimum, because, you only allocate the memory that you need and no more. In practice it&rsquo;s not quite as neat and tidy because there can be a surprisingly large amount of overhead per allocation, which adds up if programmers become really allocation-happy.</p>
<p>It&rsquo;s also a good way to shoot yourself in the foot.</p>
<p>Games don&rsquo;t live inside a Computer Science textbook, so we have to deal with real world limitations, which make this approach cumbersome, clunky, and potentially disastrous. What can go wrong with on-demand dynamic memory allocation? Almost everything!</p>
<h4 id="limited-memory">Limited Memory</h4>
<p>Games, or any software for that matter, run on machines with limited amounts of memory. As long as you know what that limit is, and you keep extremely careful track of your memory usage, you can remain under the limit. However, since the game is allocating memory any time it needs it, there will most likely come a time when the game tries to allocate a new block but there is no memory left. What can you do then? Nothing easy I&rsquo;m afraid. You can try to free an older memory block and allocate the new one there, or you can try to make your game tolerant to running out of memory. Both those solutions are very complex and difficult to implement correctly.</p>
<p>Even setting memory budgets and sticking to them can be very difficult. How can a designer know that a given particle system isn&rsquo;t going to run out of memory? Are these AI units going to create too many pathfinding objects and crash the game? Hard to say until we run the game in all possible combinations. And even then, how do you know it isn&rsquo;t going to crash five minutes later? Or ten? It&rsquo;s almost impossible to know for certain.</p>
<p>If you insist in using this approach, at the very least, you should tag all memory allocations, so you have an idea of how memory is being used. You can either tag each allocation based on what system initiated it (physics, textures, animation, sound, AI, etc) or even on the filename where it originated, which has the advantage that it can be automated and should still give you a good picture of the overall memory usage.</p>
<h4 id="memory-fragmentation">Memory Fragmentation</h4>
<p>Even if you take lots of pain not to go over your the available memory, you might still run into trouble because of memory fragmentation. You might have enough memory for a new allocation, but in the form of many small memory blocks instead of a large contiguous one. Unless you provide your own memory allocation mechanism, fragmentation is something that is very hard to track on your own, so you can&rsquo;t even be ready for it until the allocation fails.</p>
<h4 id="virtual-memory">Virtual Memory</h4>
<p>Virtual memory could solve all those problems. In theory, if you run out of real memory, the operating system swaps out some older, unused pages to disk and makes room for the new memory you requested. In practice, it&rsquo;s just a bad caching scheme because it can be triggered at the worst possible moment, and it doesn&rsquo;t know about what data it&rsquo;s swapping out or how your game uses it.</p>
<p>Games, unlike most other software, have a &ldquo;soft realtime&rdquo; requirement: The game needs to keep updating at an acceptable interactive rate, which is somewhere around 15 or more frames per second. That means that gamers are going to make a trip to the store to return your game if it pauses for a couple of seconds every few minutes to &ldquo;make some room&rdquo; for new memory. So relying on virtual memory isn&rsquo;t a particularly attractive solution.</p>
<p>Additionally, lots of games run in platforms with fixed amounts of RAM and no virtual memory. So when memory runs out, things won&rsquo;t get slow and chuggy, they&rsquo;ll crash hard. When the memory is gone, it&rsquo;s really gone.</p>
<h4 id="performance-problems">Performance Problems</h4>
<p>There are some performance issues that are relatively easy to track down and fix. Usually ones that occur every frame and are happening in a single spot: some expensive operation, a O(n3) algorithm, etc. Then there are performance problems introduced by dynamic memory allocations, which can be really hard to track down.</p>
<p>Standard malloc returns memory pretty quickly, and usually doesn&rsquo;t ever register on the the profiler. Every so often though, whenever the game has been running for a while and memory is pretty fragmented, it can spike up and cause a significant delay for just a frame. Trying to track down those spikes has caused more than one programmer to age prematurely. You can avoid some of those problems by using your own memory manager, but don&rsquo;t attempt to write a generic one yourself from scratch. Instead start with some of the ones listed in the references.</p>
<p>Malloc spikes are not the only source of performance problems. Allocating many small blocks of memory can lead to bad cache coherence when the game code access them sequentially. This problem usually manifests itself as a general slowdown that can&rsquo;t be narrowed down in the profiler. With today&rsquo;s hardware of slow memory systems and deep caches, good memory access patterns are more important than ever.</p>
<h4 id="keeping-track-of-memory">Keeping Track Of Memory</h4>
<p>Another source of problems with dynamic memory allocation are bugs in the logic that keeps track of the allocated memory blocks. If we forget to free some of them, our program will have memory leaks and has the potential to run out of memory.</p>
<p>The flip side of memory leaks are invalid memory access. If we free a memory block and later we access it as if it were allocated, we&rsquo;ll either get a memory access exception, or we&rsquo;ll manage to corrupt our own game.</p>
<p>Some techniques, such as reference counting and garbage collection can help keep track of memory allocations, but introduce their own complexities and overhead.</p>
<h3 id="introducing-pre-allocation">Introducing Pre-allocation</h3>
<p>On the opposite corner of the boxing ring is the purely pre-allocated game. It excels at everything that the dynamically-allocated game is weak at, but it has a few weaknesses of its own. All in all, it&rsquo;s probably a much safer approach for most games though.</p>
<p>The idea behind a pre-allocation memory strategy is to allocate everything once and never have to do any dynamic allocations in the middle of the game. Usually you grab as big a block of memory as you can, and then you carve it out to suit your game&rsquo;s needs.</p>
<p>Some advantages are very clear: no performance penalties, knowing exactly how your memory is used, never running out of memory, and no memory fragmentation to worry about. There are some other more subtle advantages, such as being able to put data in contiguous areas of memory to get best cache coherency, or having blazingly-fast load times by loading a baked image of a level directly into memory.</p>
<p>The main drawback of pre-allocation is that is more complex to implement than the dynamic allocation approach and it takes some planning ahead.</p>
<h4 id="know-your-data">Know Your Data</h4>
<p>For preallocation to work, you need to know ahead of time how much of every type of data you will need in the game. That can be a daunting proposition, especially to those used to a more dynamic approach. However, with a good data baking system (see last month&rsquo;s Inner Product column), you can get a global view of each level and figure out how big things need to be.</p>
<p>There is one important design philosophy that needs to be adopted for preallocation to work: Everything in the game has to be bounded. That shouldn&rsquo;t feel too restrictive; after all, the memory in your target platform is bounded, as well as every single resource. That means that everything that can create new objects, including high-level game constructs, should operate on a fixed number of them. This might seem like an implementation detail, but it often bubbles up to what&rsquo;s exposed to game designers. A common example is an enemy spawner. Instead of designing a spawner with an emission rate, it should have a fixed number of enemies it can spawn (and potentially reuse them after they&rsquo;re dead).</p>
<h4 id="potentially-wasted-space">Potentially Wasted Space</h4>
<p>If you allocate enough data for the worst case in your game, that can lead to a lot of unused data most of the time. That&rsquo;s only an issue if that unused data is preventing you from adding more content to the game. We might initially balk at the idea of having 2000 preallocated enemies when we&rsquo;re only going to see 10 of them at once. But when you realize that each of those enemies is only taking 256 bytes and the total overhead is 500 KB, which can be easily accommodated in most modern platforms today.</p>
<p>Preallocation doesn&rsquo;t have to be as draconian as it sounds though. You could relax this approach and commit to having each level preallocated and never having dynamic memory allocations while the game is running. That still allows you to dynamically allocate the memory needed for each level and keep wasted space to a minimum. Or you can take it even further and preallocate the contents of memory blocks that are streamed in memory. That way each block can be divided in the best way for that content and wasted space is kept to a minimum.</p>
<h4 id="reuse-recyclem">Reuse, RecycleM</h4>
<p>If you don&rsquo;t want to preallocate every single object you&rsquo;ll ever use, then you can create a smaller set, and reuse them as needed. This can be a bit tricky though. First of all, it needs to be very much specific to the type of object that is reused. So particles are easy to reuse (just drop the oldest one, or the ones not in view), but might be harder with enemy units or active projectiles. It&rsquo;s going to take some game knowledge of those objects to decide which ones to reuse and how to do it.</p>
<p>It also means that systems need to be prepared to either fail an allocation (if your current set of objects is full and you don&rsquo;t want to reuse an existing one), or they need to cope with an object disappearing from one frame to another. That&rsquo;s a relatively easy problem to solve by using handles or other weak references instead of direct pointers.</p>
<p>Then there&rsquo;s the issue that reusing an object isn&rsquo;t as simple as constructing a new one. You really need to make sure that when you reuse it, there&rsquo;s nothing left from the object it replaced. This is easy when your objects are just plain data in a table, but can be more complicated when they&rsquo;re complex C++ classes tied together with pointers. In any case, you can&rsquo;t apply the Resource Acquisition Is Initialization (RAII) pattern, but it doesn&rsquo;t seem to be a pattern very well suited for games, and it&rsquo;s a small price to pay for the simplicity that preallocation provides.</p>
<h3 id="specialized-heaps">Specialized Heaps</h3>
<p>Truth be told, a pure pre-allocated approach can be hard to pull off, especially with highly dynamic environments or games with user-created content. Specialized heaps is a combination of dynamic memory allocation and pre-allocation that takes the best of both worlds.</p>
<p>The idea behind specialized heaps is that the heaps themselves are pre-allocated, but they allow some form of specialized dynamic allocation within them. That way you avoid the problems of running out of memory, or memory fragmentation globally, but you still can perform some sort of dynamic allocation when needed.</p>
<p>One type of specialized heaps is based on the object type. If you can guarantee that all objects allocated in that heap are going to be of the same size, or at least a multiple of a certain size, memory management becomes much easier and less error prone, and removes a lot of the complexity of a general memory manager.</p>
<p>My favorite approach for games is to create specialized heaps based on the lifetime of the objects allocated in them. These heaps use sequential allocators, always allocating memory from the beginning of a memory block. When the lifetime of the objects is up, the heap is reset and allocations can start from the beginning again. The use of a simple sequential allocator bypasses all the insidious problems of general memory management: fragmentation, compaction, leaks, etc. See the code in <a href="http://gdmag.com/resources/code.htm">http://gdmag.com/resources/code.htm</a> for an implementation of a SequentialAllocator class.</p>
<p>The heap types most often used in games are:</p>
<ul>
<li>Level heap. Here you allocate all the assets and data for the level at load time. When the level is unloaded, all objects are destroyed at once. If your game makes heavy use of streaming, this can be a streaming block instead of a full level.</li>
<li>Frame heap. Any temporary objects that only need to last a frame or less get allocated here, and destroyed at the end of the frame.</li>
<li>Stack heap. This one is a bit different from the others. Like the other heaps, it uses a sequential allocator and objects are allocated from the beginning, but instead of destroying all objects at once, it only destroys objects up to the marker that is popped fro the stack.</li>
</ul>
<h3 id="what-about-tools">What About Tools?</h3>
<p>You can take everything I&rsquo;ve written here, and (almost) completely ignore it for tools. I fall in the camp of the programmers who consider the runtime as a totally separate beast from the tools. That means that the runtime can be lean and mean and minimalistic, but I can relax and use whatever technique makes me more productive when writing tools. That means you can allocate memory any time you want, you can use complex libraries like STL and Boost, etc. Most tools are going to run on a beefy PC and a few extra allocations here and there won&rsquo;t make any difference.</p>
<p>Be careful with performance-sensitive tools though. Tools that build assets or compute complex lighting calculations might be a bottleneck in the build process. In that case, performance becomes crucial again and you might want to be a bit more careful about memory layout and cache coherency.</p>
<p>On the other hand, if the tool you&rsquo;re writing is not performance sensitive, you should ask yourself if it really needs to be written in C++. Maybe C# or Python are better languages if all you&rsquo;re doing is transforming XML files or verifying that a file format is correct. Trading performance for ease of development is almost always a win with development tools.</p>
<p>Next time you reach out for a malloc inside your main loop, think about how it can fail. Maybe you can pre-allocate that memory and stop worrying about what&rsquo;s going to happen the day you prepare the release candidate.</p>
<p><em>This article was originally printed in the February 2009 issue of <a href="http://gdmag.com">Game Developer</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>Forget Length. Give Me Awesome</title><link>https://gamesfromwithin.com/forget-length-give-me-awesome/</link><pubDate>Tue, 17 Aug 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/forget-length-give-me-awesome/</guid><description>&lt;p&gt;&lt;img alt="harold-lloyd.jpg" loading="lazy" src="https://gamesfromwithin.com/forget-length-give-me-awesome/images/harold-lloyd.jpg"&gt;It pains me to see &lt;a href="http://www.planetxbox360.com/article_11176/Limbo_Review"&gt;great&lt;/a&gt; &lt;a href="http://www.gaming-age.com/review/xbox360_xbla/limbo"&gt;games&lt;/a&gt; &lt;a href="http://www.thereviewcrew.com/reviews/review-limbo/"&gt;criticized&lt;/a&gt; for being too short or not having a lower price point. In a world where everything surrounding us is constantly vying for our attention, time is a premium, and filling it up with mediocre experiences, a waste.&lt;/p&gt;
&lt;p&gt;I want to have great experiences, not just long ones, and I&amp;rsquo;m willing to pay for them. Just like other media, each game has an ideal length to develop its ideas fully, and we shouldn&amp;rsquo;t fall to pressures to make then any longer than they should be. I don&amp;rsquo;t want endless grinding or backtracing through the level to meet a minimum time quota. Just like every book doesn&amp;rsquo;t have to be The Lord Of The Rings, there is room for both epic sagas like Dragon Age and Fallout and short experiences like Limbo or Braid. Maybe there&amp;rsquo;s even room for the equivalent of Italo Calvino&amp;rsquo;s shortest short story, &lt;a href="http://www.amazon.com/Complete-Cosmicomics-Penguin-Modern-Classics/dp/1846141656/?tag=gamesfromwith-20"&gt;The Dinosaur&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="harold-lloyd.jpg" loading="lazy" src="/forget-length-give-me-awesome/images/harold-lloyd.jpg">It pains me to see <a href="http://www.planetxbox360.com/article_11176/Limbo_Review">great</a> <a href="http://www.gaming-age.com/review/xbox360_xbla/limbo">games</a> <a href="http://www.thereviewcrew.com/reviews/review-limbo/">criticized</a> for being too short or not having a lower price point. In a world where everything surrounding us is constantly vying for our attention, time is a premium, and filling it up with mediocre experiences, a waste.</p>
<p>I want to have great experiences, not just long ones, and I&rsquo;m willing to pay for them. Just like other media, each game has an ideal length to develop its ideas fully, and we shouldn&rsquo;t fall to pressures to make then any longer than they should be. I don&rsquo;t want endless grinding or backtracing through the level to meet a minimum time quota. Just like every book doesn&rsquo;t have to be The Lord Of The Rings, there is room for both epic sagas like Dragon Age and Fallout and short experiences like Limbo or Braid. Maybe there&rsquo;s even room for the equivalent of Italo Calvino&rsquo;s shortest short story, <a href="http://www.amazon.com/Complete-Cosmicomics-Penguin-Modern-Classics/dp/1846141656/?tag=gamesfromwith-20">The Dinosaur</a>.</p>
<p>I would go as far to say that games should err on the side of being too short rather than too long. There&rsquo;s a saying in Spanish that goes &ldquo;<a href="http://es.wikipedia.org/wiki/Baltasar_Graci%C3%83%C2%A1n">Lo bueno, si breve, dos veces bueno</a>&rdquo;, which roughly translates into &ldquo;Good things, if short, twice as good&rdquo;. I&rsquo;d rather be left wanting more than not being able to finish something. As a busy gamer, I don&rsquo;t get to finish many games these days, and the ones that I do really stand out from the others and hold a special spot in my heart.</p>
<p>Besides, a lot of other games can&rsquo;t even be measured in length. How long is <a href="http://us.battle.net/sc2/">Starcraft</a>? <a href="http://www.teamfortress.com/">Team Fortress</a>? <a href="http://www.civilization.com/">Civilization</a>? <a href="http://www.onemanleft.com/tilttolive/index.php">Tilt To Live</a>? They are as long or as short as you want. Should we be docking them for being too short? Should we force all games to have infinite replay value? No, the important thing is that they&rsquo;re great experiences.</p>
<p>Forget length. Give me awesome.</p>
<h4 id="other-indie-voices-on-game-length">Other Indie Voices On Game Length</h4>
<ul>
<li><a href="http://www.tunahq.com/2010/08/size-doesnt-matter-day/">Alex Amsel of Tuna</a></li>
<li><a href="http://www.paradeofrain.com/2010/08/size-doesnt-matter-day">Alex Okafor of One Man Left</a></li>
<li><a href="http://www.brettdouville.com/mt-archives/2010/08/most_expensive.html">Brett Douville of Bethesda Softworks</a></li>
<li><a href="http://www.hobbygamedev.com/spx/short-videogame-design/">Chris DeLeon of HobbyGameDev</a></li>
<li><a href="http://spyparty.com/2010/08/17/size-doesnt-matter-day">Chris Hecker of Spy Party</a></li>
<li><a href="http://positech.co.uk/cliffsblog/?p=810">Cliff Harris of Positech Games</a></li>
<li><a href="http://nygamedev.blogspot.com/2010/08/coming-up-short.html">Dave Gilbert of Wadjet Eye Games</a></li>
<li><a href="http://www.firehosegames.com/2010/08/how-much-is-enough/">Eitan Glinert of Fire Hose Games</a></li>
<li><a href="http://mile222.com/2010/08/a-haiku-about-game-length/">Greg Wohlwend of Intution Games</a></li>
<li><a href="http://retrodreamer.com/blog/2010/08/size-doesnt-matter-day/">Gavin Bowman of Retro Dreamer</a></li>
<li><a href="http://www.gamedevblog.com/2010/08/so-i-was-going-to-show-my-solidarity-with-the-game-length-bloggers-today-by-re-posting-an-old-post-that-i-thought-was-entitle.html">Jamie Fristrom of Torpex Games</a></li>
<li><a href="http://blog.wolfire.com/2010/08/Game-length-and-value">Jeffrey Rosen of Wolfire</a></li>
<li><a href="http://the-witness.net/news/?p=438">Jonathan Blow of Number None</a></li>
<li><a href="http://pocketcyclone.com/2010/08/17/game-length-vs-price/">Markus Nigrin of The Pocket Cyclone</a></li>
<li><a href="http://www.brokenrul.es/blog/?p=314">Martin Pichlmair of Broken Rules</a></li>
<li><a href="http://24caretgames.com/2010/08/17/does-game-length-matter/">Matt Gilgenbach of 24 Caret Games</a></li>
<li><a href="http://retroaffect.com/blog/160/Size_Doesn_t_Matter_Day/#b">Peter Jones of Retro Affect</a></li>
<li><a href="http://www.lazy8studios.com/size_doesnt_matter">Rob Jagnow of Lazy 8 Studios</a></li>
<li><a href="http://2dboy.com/2010/08/17/too-short/">Ron Carmel of 2DBoy</a></li>
<li><a href="http://macguffingames.com/2010/if-size-doesnt-matter-where-do-you-get-the-virtual-goods">Scott Macmillan of Macguffin Games</a></li>
<li><a href="http://www.enemyairship.com/2/The_Finite__Irreplaceable_Hours_of_Your_Life/#b">Steve Swink of Enemy Airship</a></li>
</ul>
<p>Twitter tag: <a href="http://search.twitter.com/search?q=%23gamelength">#gamelength</a></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>Indie Project Management For One: Tools</title><link>https://gamesfromwithin.com/indie-project-management-for-one-tools/</link><pubDate>Thu, 05 Aug 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/indie-project-management-for-one-tools/</guid><description>&lt;p&gt;I&amp;rsquo;ve been making computer games in some form or another for just over 25 years now. At the &lt;a href="http://computeremuzone.com/ficha.php?id=695&amp;amp;sec=amstrad"&gt;very beginning&lt;/a&gt;, as a hobby (passion) and completely by myself (although not for lack of trying to get some of my friends involved). In the late 90s, when I finally left academia and started making games professionally, teams were still relatively small, with a total of around 10-15 people per team. As we all know, budgets and scopes kept growing, and so did team sizes. At its peak, the largest team I worked at had around 200 people. That&amp;rsquo;s when I decided to go indie and started &lt;a href="https://gamesfromwithin.com/tag/power-of-two/"&gt;Power of Two Games&lt;/a&gt;, which was obviously just two of us. Finally, now as &lt;a href="http://www.snappytouch.com/"&gt;Snappy Touch&lt;/a&gt;, I&amp;rsquo;ve gone full circle: It&amp;rsquo;s just me again.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve been making computer games in some form or another for just over 25 years now. At the <a href="http://computeremuzone.com/ficha.php?id=695&amp;sec=amstrad">very beginning</a>, as a hobby (passion) and completely by myself (although not for lack of trying to get some of my friends involved). In the late 90s, when I finally left academia and started making games professionally, teams were still relatively small, with a total of around 10-15 people per team. As we all know, budgets and scopes kept growing, and so did team sizes. At its peak, the largest team I worked at had around 200 people. That&rsquo;s when I decided to go indie and started <a href="/tag/power-of-two/">Power of Two Games</a>, which was obviously just two of us. Finally, now as <a href="http://www.snappytouch.com/">Snappy Touch</a>, I&rsquo;ve gone full circle: It&rsquo;s just me again.</p>
<p><img alt="gears.jpg" loading="lazy" src="/indie-project-management-for-one-tools/images/gears.jpg">Development tools and hardware have changed quite a bit from the times I was writing in <a href="http://www.cpcwiki.eu/index.php/Hisoft_Devpac">straight Z80 assembly and saving the programs to a tape</a>. But I&rsquo;ve also changed and learned a lot during all those years developing games, and even though I&rsquo;m writing games by myself again, I&rsquo;m doing things very differently from how I did them back at the start.</p>
<p>One thing that I&rsquo;ve always done is to question everything. Why should I do things a certain way? Why is that the &ldquo;accepted&rdquo; way of doing something? And not surprisingly, at each step of the way, I&rsquo;ve changed my development style to match my situation (often in ways that went against the &ldquo;common wisdom&rdquo;).</p>
<p>When it comes to solo development, I rely heavily on the concept of goals and iterations at multiple levels:</p>
<ul>
<li>Immediate (&lt; 1 minute): Prioritizing the ideas going through my mind. Writing tests. Writing code.</li>
<li>Short Range (&lt; few hours): Tasks that move the project forward in some way.</li>
<li>Mid Range (&lt; 2 weeks): &ldquo;Stories&rdquo; that define a self-contained, significant part of the project.</li>
<li>Long Range (full project, several months): Ship date, beta testing, etc.</li>
</ul>
<p>It turns out, I use a different set of tools to help me manage the items at each level of the development cycle.</p>
<h3 id="immediate">Immediate</h3>
<p>These are the actions I take and complete in less than a minute or two. Most of them are writing tests (with <a href="http://code.google.com/p/unittestpp/">UnitTest++</a>, of course), writing code to make those tests pass, refactor code, and check it into <a href="http://subversion.tigris.org/">Subversion</a>. I have my Subversion repository hosted on <a href="http://www.dreamhost.com/">Dreamhost</a> and I access it through SSH so it&rsquo;s secure, accessible from anywhere with an internet connection (or 3G signal and <a href="http://appshopper.com/blog/2010/07/20/handy-light-tethering-app-camouflaged-as-flashlight/">HandyLight</a>), offsite, and easy to backup. And because Subversion works great offline (unlike Perforce), it&rsquo;s not a problem to work without connection to the repository for a while.</p>
<p>I also need to manage my minute-to-minute thoughts, write down ideas and reprioritize them when the time comes. When I&rsquo;m &ldquo;in the zone&rdquo;, I get way more ideas than I can execute with my fingers: This function needs to be moved to a different file, I really should be compacting that data over there, who was stupid enough to name this file this way?, that variable shouldn&rsquo;t be cached, etc. If I don&rsquo;t write things down, I will either forget them, or I&rsquo;ll stress for hours until I finally get around to doing them. I could also do things as I think about them, but then I would be chasing a rabbit down a neverending hole and wouldn&rsquo;t get any work done (I&rsquo;m sure anybody who&rsquo;s gotten lost browsing web pages can identify with that).</p>
<p>I used to do this the old-fashioned way, simply with paper and pencil (<a href="http://www.appsizematters.com/2010/08/tip-othe-day-3-use-lists-to-stay-focused/">like Bob described in his blog post</a>). However, I found that physical paper and pencil was just too limiting: I can type a lot faster than I can write, switching to writing requires moving away from the keyboard, and, most importantly, I need to bring the notes with me everywhere and it&rsquo;s very difficult to rearrange, sort, or coalesce them in any way.</p>
<p>So instead, my tool of choice these days is <a href="http://selfcoded.com/justnotes/">JustNotes</a>. It&rsquo;s perfect for jotting down thoughts in a matter of seconds without even interrupting my train of thought. I have JustNotes bound to a global key, so in the middle of typing a line of code, I can press that key, enter whatever I&rsquo;m thinking about, press the key again, and finish the line of code. All in 4-5 seconds. Don&rsquo;t laugh: The fact that I can do that in just a few seconds without moving my hands away from the keyboard means I can use it any time without much penalty. It&rsquo;s amazing how many things I jot down that I wouldn&rsquo;t do otherwise.</p>
<h3 id="short-range">Short Range</h3>
<p>To manage tasks up to a few hours in length, I use <a href="http://trac.edgewall.org/">Trac</a>. Trac is a fantastic issue-tracking tool: It&rsquo;s free, it&rsquo;s fast, it&rsquo;s simple, and it&rsquo;s configurable. In the past I&rsquo;ve used anything from spreadsheets, to Bugzilla, to publisher-owned bug databases, and nothing comes close to Trac for my needs. It also scales very well to teams of more than one person (although it might not be good enough for hundreds of people).</p>
<p>Just like Subversion, I have Trac hosted externally, through my web hosting company. Sometimes it&rsquo;s frustrating if I need to access it and the server is down, but again, the convenience of having it off site makes it well-worth it.</p>
<p>Any task that requires more than 10-15 minutes goes in Trac, and then I can easily prioritize tasks depending on their importance. Usually, if an item has been on my instant queue in JustNotes for about a day and I haven&rsquo;t gotten around to it, it either gets deleted or it gets moved into a full item in Trac. The only way progress happens is by ticking off Trac tasks. In the end, my projects live and die by Trac.</p>
<h3 id="medium-range">Medium Range</h3>
<p>User stories (to borrow terminology from Scrum/XP) are visible, relatively self-contained features of the final project. They&rsquo;re made up of several tasks, and usually take a few days to a few weeks to implement. A group of user stories make up a full iteration (sprint) of the game, which is usually between one and two weeks long. Sometimes user stories are complex enough (add a replay feature visible on the web site) that the full iteration is just the one user story.</p>
<p>I keep track of these stories in Trac as well. Trac is both an issue-tracking system and a wiki, so the wiki part is perfect to keep these user stories. In addition to that, I label tasks as belonging o a particular iteration. That allows me to separate what needs to be done for this iteration, from other tasks that I added for the future. At the start of each iteration, I decide on the user stories and either generate new tasks or label existing tasks as due for this iteration.</p>
<p>The wiki in Trac is extremely valuable for all sorts of other things: game design ideas, general brainstorming, gathering reference material, etc.</p>
<p>Trac ends up being the perfect mid-range vision of my project.</p>
<h3 id="long-range">Long Range</h3>
<p>User stories and tasks in Trac aren&rsquo;t enough to cover a project that is potentially 3-4 months long. I need something that helps me with the longer view, otherwise I find that things creep up on me without realizing it because I&rsquo;m so focused on the short and mid-range items.</p>
<p>The best tool I&rsquo;ve found so far is very low-tech: <a href="http://www.printfree.com/Calendars.htm">A printable month-per-page calendar</a> covering the full length of the project. Right now I&rsquo;m shooting for a November release of my current project, so I printed August, September, October, and November and pinned them to the corkboard on my office. It&rsquo;s amazing the sense of urgency that seeing your ship date gives you. You realize that you only have a handful of weeks before shipping and makes it much easier to prioritize tasks (and chop off features or save them for an update).</p>
<p>I realize this long-term, calendar view isn&rsquo;t very useful if you don&rsquo;t have a set release date and you want to continue chipping at your game until it&rsquo;s ready. But even if your release date is flexible, having this long-term view can help you keep budgets in perspective and manage them accordingly.</p>
<p>Finally, for an extra bit of motivation (or maybe this falls in the category of excessive pressure), I just started using <a href="http://www.apple.com/downloads/dashboard/status/countdowndashboardwidget.html">a countdown widget for the Mac OS Dashboard</a>. Just in case the calendar view wasn&rsquo;t enough, here&rsquo;s a countdown (down to the second) of the time left until release.</p>
<p><img alt="countdown.png" loading="lazy" src="/indie-project-management-for-one-tools/images/countdown.png"></p>
<p>Speaking of which, I think it&rsquo;s time I get back to work. Only 102 days left!</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>Mock Objects: Friends Or Foes?</title><link>https://gamesfromwithin.com/mock-objects-friends-or-foes/</link><pubDate>Mon, 26 Jul 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/mock-objects-friends-or-foes/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/nitty-gritty-unit-testing/"&gt;In a previous article&lt;/a&gt; we covered all the details necessary to start using unit testing on a real-world project. That was enough knowledge to get started and tackle just about any codebase. Eventually you might have found yourself doing a lot of typing, writing redundant tests, or having a frustrating time interfacing with some libraries and still trying to write unit tests. Mock objects are the final piece in your toolkit that allow you to test like a pro in just about any codebase.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/nitty-gritty-unit-testing/">In a previous article</a> we covered all the details necessary to start using unit testing on a real-world project. That was enough knowledge to get started and tackle just about any codebase. Eventually you might have found yourself doing a lot of typing, writing redundant tests, or having a frustrating time interfacing with some libraries and still trying to write unit tests. Mock objects are the final piece in your toolkit that allow you to test like a pro in just about any codebase.</p>
<h3 id="testing-code">Testing Code</h3>
<p>The purpose of writing unit tests is to verify the code does what it&rsquo;s supposed to do. How exactly do we go about checking that? It depends on what the code under test does. There are three main things we can test for when writing unit tests:</p>
<ul>
<li>
<p><strong>Return values</strong>. This is the easiest thing to test. We call a function and verify that the return value is what we expect. It can be a simple boolean, or maybe it&rsquo;s a number resulting from a complex calculation. Either way, it&rsquo;s simple and easy to test. it doesn&rsquo;t get any better than this.</p>
</li>
<li>
<p><strong>Modified data</strong>. Some functions will modify data as a result of being called (for example, filling out a vertex buffer with particle data). Testing this data can be straightforward as long as the outputs are clearly defined. If the function changes data in some global location, then it can be more complicated to test it or even find all the possible places that can be changed. Whenever possible, pass the address of the data to be modified as an input parameter to the functions. That will make them easier to understand and test.</p>
</li>
<li>
<p><strong>Object interaction</strong>. This is the hardest effect to test. Sometimes calling a function doesn&rsquo;t return anything or modify any external data directly, and it instead interacts with other objects. We want to test that the interaction happened in the order we expected and with the parameters we expected.</p>
</li>
</ul>
<p>Testing the first two cases is relatively simple, and there&rsquo;s nothing you need to do beyond what a basic unit testing-framework provides. Call the function and verify values with a CHECK statement. Done. However, testing that an object &ldquo;talks&rdquo; with other objects in the correct way is much trickier. That&rsquo;s what we&rsquo;ll concentrate on for the rest of the article.</p>
<p>As a side note, when we talk about object interaction, it simply refers to parts of the code calling functions or sending messages to other parts of the code. It doesn&rsquo;t necessarily imply real objects. Everything we cover here applies as well to plain functions calling other functions.</p>
<p>Before we go any further, let&rsquo;s look at a simple example of object interaction. We have a game entity factory and we want to test that the function CreateGameEntity() finds the entity template in the dictionary and calls CreateMesh() once per each mesh.</p>
<pre tabindex="0"><code>TEST(CreateGameEntityCallsCreateMeshForEachMesh)
{
    EntityDictionary dict;
    MeshFactory meshFactory;
    GameEntityFactory gameFactory(dict, meshFactory);

    Entity* entity = gameFactory.CreateGameEntity(gameEntityUid);
    // How do we test it called the correct functions?
}
</code></pre><p>We can write a test like the one above, but after we call the function CreateGameEntity(), how do we test the right functions were called in response? We can try testing for their results. For example, we could check that the returned entity has the correct number of meshes, but that relies on the mesh factory working correctly, which we&rsquo;ve probably tested elsewhere, so we&rsquo;re testing things multiple times. It also means that it needs to physically create some meshes, which can be time consuming or just need more resources than we want for a unit test. Remember that these are unit tests, so we really want to minimize the amount of code that is under test at any one time. Here we only want to test that the entity factory does the right thing, not that the dictionary or the mesh factory work.</p>
<h3 id="introducing-mocks">Introducing Mocks</h3>
<p>To test interactions between objects, we need something that sits between those objects and intercepts all the function calls we care about. At the same time, we want to make sure that the code under test doesn&rsquo;t need to be changed just to be able to write tests, so this new object needs to look just like the objects the code expects to communicate with.</p>
<p>A mock object is an object that presents the same interface as some other object in the system, but whose only goal is to attach to the code under test and record function calls. This mock object can then be inspected by the test code to verify all the communication happened correctly.</p>
<pre tabindex="0"><code>TEST(CreateGameEntityCallsCreateMeshForEachMesh)
{
    MockEntityDictionary dict;
    MockMeshFactory meshFactory;
    GameEntityFactory gameFactory(dict, meshFactory);

dict.meshCount = 3;

    Entity* entity = gameFactory.CreateGameEntity(gameEntityUid);

    CHECK_EQUAL(1, dict.getEntityInfoCallCount);
    CHECK_EQUAL(gameEntityUid, dict.lastEntityUidPassed);
    CHECK_EQUAL(3, meshFactory.createMeshCallCount);
}
</code></pre><p>This code shows how a mock object helps us test our game entity factory. Notice how there are no real MeshFactory or EntityDictionary objects. Those have been removed from the test completely and replaced with mock versions. Because those mock objects implement the same interface as the objects they&rsquo;re standing for, the GameEntityFactory doesn&rsquo;t know that it&rsquo;s being tested and goes about business as usual.</p>
<p>Here are the mock objects themselves:</p>
<pre tabindex="0"><code>struct MockEntityDictionary : public IEntityDictionary
{
    MockEntityDictionary() 
        : meshCount(0)
        , lastEntityUidPassed(0)
        , getEntityInfoCallCount(0)
    {}

    void GetEntityInfo(EntityInfo&amp; info, int uid)
    {
        lastEntityUidPassed = uid;
        info.meshCount = meshCount;
        ++getEntityInfoCallCount;
    }

    int meshCount;
    int lastEntityUidPassed;
    int getEntityInfoCallCount;
};

struct MockMeshFactory : public IMeshFactory
{
    MockMeshFactory() : createMeshCallCount(0)
    {}

    Mesh* CreateMesh()
    {
        ++createMeshCallCount;
        return NULL;
    }
};
</code></pre><p>Notice that they do no real work; they&rsquo;re just there for bookkeeping purposes. They count how many times functions are called, some parameters, and return whatever values you fed them ahead of time. The fact that we&rsquo;re setting the meshCount in the dictionary to 3 is how we can then test that the mesh factory is called the correct number of times.</p>
<p>When developers talk about mock objects, they&rsquo;ll often differentiate between mocks and fakes. Mocks are objects that stand in for a real object, and they are used to verify the interaction between objects. Fakes also stand in for real objects, but they&rsquo;re there to remove dependencies or speed up tests. For example, you could have a fake object that stands in for the file system and provides data directly from memory, allowing tests to run very quickly and not depend on a particular file layout. All the techniques presented in this article apply both to mocks and fakes, it&rsquo;s just how you use them that sets them apart from each other.</p>
<h3 id="mocking-frameworks">Mocking Frameworks</h3>
<p><img alt="mock.jpg" loading="lazy" src="/mock-objects-friends-or-foes/images/mock.jpg">The basics of mocking objects are as simple as what we&rsquo;ve seen. Armed with that knowledge, you can go ahead and test all the object interactions in your code. However, I bet that you&rsquo;re going to get tired quickly from all that typing every time you create a new mock. The bigger and more complex the object is, the more tedious the operation becomes. That&rsquo;s where a mocking framework comes in.</p>
<p>A mocking framework lets you create mock objects in a more automated way, with less typing. Different frameworks use different syntax, but at the core they all have two parts to them: A semi-automatic way of creating a mock object from an existing class or interface. A way to set up the mock expectations. Expectations are the results you expect to happen as a result of the test: functions called in that object, the order of those calls, or the parameters passed to them.</p>
<p>Once the mock object has been created and its expectations set, you perform the rest of the unit test as usual. If the mock object didn&rsquo;t receive the correct calls the way you specified in the expectations, the unit test is marked as failed. Otherwise the test passes and everything is good.</p>
<h4 id="googlemock">GoogleMock</h4>
<p><a href="http://code.google.com/p/googlemock">GoogleMock</a> is the free C++ mocking framework provided by Google. It takes a very straightforward implementation approach and offers a set of macros to easily create mocks for your classes, and set up expectations. Because you need to create mocks by hand, there&rsquo;s still a fair amount of typing involved to create each mock, although they provide a Python script that can generate mocks automatically from from C++ classes. It still relies on your classes inheriting from a virtual interface to hook up the mock object to your code.</p>
<p>This code shows the game entity factory test written with GoogleMock. Keep in mind that in addition to the test code, you still need to create the mock object through the macros provided in the framework.</p>
<pre tabindex="0"><code>TEST(CreateGameEntityCallsCreateMeshForEachMesh) 
{
    MockEntityDictionary dict;
    MockMeshFactory meshFactory;
    GameEntityFactory gameFactory(dict, meshFactory);

    EXPECT_CALL(dict, GetEntityInfo())
        .Times(1)
        .WillOnce(Return(EntityInfo(3));

    EXPECT_CALL(meshFactory, CreateMesh())
        .Times(3);

    Entity* entity = gameFactory.CreateGameEntity(gameEntityUid);
}
</code></pre><h4 id="mockitnow">MockItNow</h4>
<p><a href="http://www.rorydriscoll.com/mockitnow">This open-source C++ mocking framework</a> written by <a href="http://www.rorydriscoll.com/">Rory Driscoll</a> takes a totally different approach from GoogleMock. Instead of requiring that all your mockable classes inherit from a virtual interface, it uses compiler support to insert some code before each call. This code can then call the mock and return to the test directly, without ever calling the real object.</p>
<p>From a technical point of view, it&rsquo;s a very slick method of hooking up the mocks, but the main advantage of this approach is that it doesn&rsquo;t force a virtual interface on classes that don&rsquo;t need it. It also minimizes typing compared to GoogleMock. The only downside is that it&rsquo;s very platform-specific implementation, and the version available only supports Intel x86 processors, although it can be re-implemented for PowerPC architectures.</p>
<h3 id="problems-with-mocks">Problems With Mocks</h3>
<p>There is no doubt that mocks are a very useful tool. They allow us to test object interactions in our unit tests without involving lots of different classes. In particular, mock frameworks make using mocks even simpler, saving typing and reducing the time we have to spend writing tests. What&rsquo;s not to like about them?</p>
<p>The first problem with mocks is that they can add extra unnecessary complexity to the code, just for the sake of testing. In particular, I&rsquo;m referring to the need to have a virtual interface that objects are are going to be mocked inherit from. This is a requirement if you&rsquo;re writing mocks by hand or using GoogleMock (not so much with MockItNow), and the result is more complicated code: You need to instantiate the correct type, but then you pass around references to the interface type in your code. It&rsquo;s just ugly and I really resent that using mocks is the only reason those interfaces are there. Obviously, if you need the interface and you&rsquo;re adding a mock to it afterwards, then there&rsquo;s no extra complexity added.</p>
<p>If the complexity and ugliness argument doesn&rsquo;t sway you, try this one: Every unnecessary interface is going to result in an extra indirection through a vtable with the corresponding performance hit. Do you really want to fill up your game code with interfaces just for the sake of testing? Probably not.</p>
<p>But in my mind, there&rsquo;s another, bigger disadvantage to using mock frameworks. One of the main benefits of unit tests is that they encourages a modular design, with small, independent objects, that can be easily used individually. In other words, unit tests tend to push design away from object interactions and more towards returning values directly or modifying external data.</p>
<p>A mocking framework can make creating mocks so easy, to the point that it doesn&rsquo;t discourage programmers from creating a mock object any time they think of one. And when you have a good mocking framework, every object looks like a good mock candidate. At that point, your code design is going to start looking more like a tangled web of objects communicating in complex ways, rather than simple functions without any dependencies. You might have saved some typing time, but at what price!</p>
<h3 id="when-to-use-mock-frameworks">When to Use Mock Frameworks</h3>
<p>That doesn&rsquo;t mean that you shouldn&rsquo;t use a mocking framework though. A good mocking framework can be a lifesaving tool. Just be very, very careful how you use it.</p>
<p>The case when using a mocking framework is most justified when dealing with existing code that was not written in unit testing in mind. Code that is tangled together, and impossible to use in isolation. Sometimes that&rsquo;s third-party libraries, and sometimes it&rsquo;s even (yes, we can admit it) code that we wrote in the past, maybe under a tight deadline, or maybe before we cared much about unit tests. In any case, trying to write unit tests that interface with code not intended to be tested can be extremely challenging. So much so, that a lot of people give up on unit tests completely because they don&rsquo;t see a way of writing unit tests without a lot of extra effort. A mocking framework can really help in that situation to isolate the new code you&rsquo;re writing, from the legacy code that was not intended for testing.</p>
<p>Another situation when using a mocking framework is a big win is to use as training wheels to get started with unit tests in your codebase. There&rsquo;s no need to wait until you start a brand new project with a brand new codebase (how often does that happen anyway?). Instead, you can start testing today and using a good mock framework to help isolate your new code from the existing one. Once you get the ball rolling and write new, testable code, you&rsquo;ll probably find you don&rsquo;t need it as much.</p>
<p>Apart from that, my recommendation is to keep your favorite mocking framework ready in your toolbox, but only take it out when you absolutely need it. Otherwise, it&rsquo;s a bit like using a jackhammer to put a picture nail on the wall. Just because you can do it, it doesn&rsquo;t mean it&rsquo;s a good idea.</p>
<p>Keep in mind that these recommendations are aimed at using mock objects in C and C++. If you&rsquo;re using other languages, especially more dynamic or modern ones, using mock objects is even simpler and without many of the drawbacks. In a lot of other languages, such as Lua, C#, or Python, your code doesn&rsquo;t have to be modified in any way to insert a mock object. In that case you&rsquo;re not introducing any extra complexity or performance penalties by using mocks, and none of the earlier objections apply. The only drawback left in that case is the tendency to create complex designs that are heavily interconnected, instead of simple, standalone pieces of code. Use caution and your best judgement and you&rsquo;ll make the best use of mocks.</p>
<p><em>This article was originally printed in the June 2009 issue of <a href="http://gdmag.com">Game Developer</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>Nitty Gritty Unit Testing</title><link>https://gamesfromwithin.com/nitty-gritty-unit-testing/</link><pubDate>Sun, 18 Jul 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/nitty-gritty-unit-testing/</guid><description>&lt;p&gt;It&amp;rsquo;s one thing to see someone drive a car and have a theoretical understanding of what the pedals do and how to change gears. It&amp;rsquo;s is a completely different thing to be able to drive a car safely on the street. There are some activities that require many small details and some hands-on experience to be able to execute them successfully.&lt;/p&gt;
&lt;p&gt;The good news is that unit testing is a lot simpler than driving a standard shift, but there are a lot of small details you need to get right to do it successfully. Even after reading about unit testing and being convinced of its benefits, programmers are often not sure how to get started. This month&amp;rsquo;s column is not going to try to convince you of the many benefits of unit testing (I hope you are already convinced), but rather, describe some very concrete tips to help you get started right away.&lt;/p&gt;</description><content:encoded><![CDATA[<p>It&rsquo;s one thing to see someone drive a car and have a theoretical understanding of what the pedals do and how to change gears. It&rsquo;s is a completely different thing to be able to drive a car safely on the street. There are some activities that require many small details and some hands-on experience to be able to execute them successfully.</p>
<p>The good news is that unit testing is a lot simpler than driving a standard shift, but there are a lot of small details you need to get right to do it successfully. Even after reading about unit testing and being convinced of its benefits, programmers are often not sure how to get started. This month&rsquo;s column is not going to try to convince you of the many benefits of unit testing (I hope you are already convinced), but rather, describe some very concrete tips to help you get started right away.</p>
<h3 id="goals-of-unit-testing">Goals of Unit Testing</h3>
<p>There are many different reasons to write unit tests:</p>
<ul>
<li>Correctness testing. Checking that the code behaves as designed.</li>
<li>Boundary testing. Checking that the code behaves correctly in odd or boundary situations.</li>
<li>Regression testing. Checking that the behavior of the code doesn&rsquo;t change unintentionally over time.</li>
<li>Performance testing. Checking that the program meets certain minimum performance or memory constraints.</li>
<li>Platform testing. Checking that the code behaves the same across multiple platforms.</li>
<li>Design. Tests provide a way to advance the code design and architecture. This is usually referred as Test-Driven Development (TDD).</li>
<li>Full game or tool testing. Technically this is a functional test, not a unit test anymore because it involves the whole program instead of a small subset of the code, but a lot of the same techniques apply.</li>
</ul>
<p>Some developers use unit tests only for one of the reasons listed above, while others use many kinds of tests for a variety of different reasons. It&rsquo;s important to recognize that because there are so many different uses for unit tests, no single solution is going to fit everybody. The ideal setup for some of those situations is going to be slightly different than for others. The basics are the same for all of them though.</p>
<p>When working with unit tests, these are our main goals:</p>
<ul>
<li>Spend as little time as possible writing a new test.</li>
<li>Be notified of failing tests, and see at a glance which ones failed and why.</li>
<li>Trust our tests. Have them be consistent from run to run and robust in the face of bad code.</li>
</ul>
<h3 id="testing-framework">Testing Framework</h3>
<p><a href="http://www.flickr.com/photos/sebastian_bergmann/2282734669/"><img alt="lack_of_tests.jpg" loading="lazy" src="/nitty-gritty-unit-testing/images/lack_of_tests.jpg"></a>Most of us have created one-off programs in the past to test some particularly complicated code. It&rsquo;s usually a quick command line program that runs through a bunch of cases and asserts after each one that the results were correct. That&rsquo;s the most bare-bones way of creating unit tests.</p>
<p>Unfortunately, it&rsquo;s also a pain and it misses on most of the unit-testing goals described in the previous section: creating a new program just for that is a pain, we have to go out of our way to run the tests, and it usually gets out of date faster than the latest Internet meme. That is in part why a lot of programmers have an initial aversion to writing unit tests.</p>
<p>If you&rsquo;re considering writing even a small unit test, you should use a unit-testing framework. A unit-testing framework removes all the busy work from writing unit tests and lets you spend your time on the logic of what to test. This doesn&rsquo;t mean that the framework writes the tests for you. Be very wary of any tool that claims to do that! No, a unit-testing framework is simply a small library that provides all the glue for running unit tests and reporting the results. Sorry, you still need to use your brain and do (some of) the typing.</p>
<p>A quick search will reveal plenty of unit-testing frameworks to choose from for your language of choice, and most of them are free and open source so you can rely on them and modify them to suit your needs. For C/C++ and game development, I strongly recommend starting with <a href="http://unittest-cpp.sourceforge.net/">UnitTest++</a>. <a href="http://cnicholson.net/">Charles Nicholson</a> and I wrote that framework a few years ago specifically with games and consoles in mind. Many game teams have adopted it for their games and tools, and it has been used on lots of different game platforms including current and last generation consoles, Windows, Linux, and Mac PCs, and even on the iPhone. In most situations, it should be a straight drop-in to your project and you&rsquo;re up and running.</p>
<p>If you end up using a different testing framework, or even if you roll your own, the techniques described here still apply, even if the syntax is slightly different.</p>
<h3 id="hello-tests">Hello Tests</h3>
<p>Writing your first test is easy as pie:</p>
<pre tabindex="0"><code>#include &lt;UnitTest++.h&gt;

TEST(MyFirstTest)
{
    int a = 4;
    CHECK(a == 4);
}
</code></pre><p>To run it you need to add the following line to your executable somewhere. We&rsquo;ll talk more about the physical organization of tests in a moment.</p>
<pre tabindex="0"><code>int failedCount = UnitTest::RunAllTests();
</code></pre><p>Done! Easy, wasn&rsquo;t it? When you compile and run the program you should see the following output:</p>
<pre tabindex="0"><code>Success: 1 test passed.
Test time: 0.00 seconds.
</code></pre><p>Let&rsquo;s add a failing test:</p>
<pre tabindex="0"><code>TEST(MyFailingTest)
{
    int a = 5;
    CHECK(a == 4);
}
</code></pre><p>Now we get:</p>
<pre tabindex="0"><code>/fullpath/filename.cpp:17: error: Failure in MyFailingTest: a == 4
FAILURE: 1 out of 2 tests failed (1 failures).
Test time: 0.00 seconds.
</code></pre><p>That&rsquo;s great, but if we&rsquo;re going to diagnose the problem, we probably need to know the value of the variable a, and all the test is telling us is that it&rsquo;s not 4. So instead, we can change the CHECK statement to the following:</p>
<pre tabindex="0"><code>TEST(MyFailingTest)
{
    int a = 5;
    CHECK_EQUAL(4, a);
}
</code></pre><p>And now the output will be</p>
<pre tabindex="0"><code>/fullpath/filename.cpp:17: error: Failure in MyFailingTest: Expected 4 but was 5
FAILURE: 1 out of 2 tests failed (1 failures).
Test time: 0.00 seconds.
</code></pre><p>Much better. Now we get both the error information and the value of the variable under test. Virtually all unit-testing frameworks include different types of CHECK statements to get more information when testing floats, arrays, or other data types. You can even make your own CHECK statement for your own common data types such as colors or lists.</p>
<p>As a bonus, if you&rsquo;re using an IDE, double-clicking on the test failure message should bring you automatically to the failing test statement.</p>
<h3 id="when-to-run">When To Run</h3>
<p>When to run unit tests will depend on what is being tested and how long it takes to do so. In general, the more frequently you run the tests, the better. The sooner you get feedback that something went wrong, the easier it will be to fix. Maybe even before it was checked in and it spread to the rest of the team. On the flip side, realistically, building and running a set of unit tests takes a certain amount of time, so it&rsquo;s important to find the right balance between feedback frequency and time spent waiting for tests.</p>
<p>At the very least, all tests should run once a day, during the nightly build process in your build server (You have a build server, don&rsquo;t you? If not, run over and <a href="/the-heartbeat-of-the-project/">read this column in the August 2008 issue</a>). It doesn&rsquo;t matter how long they take or how how many different projects you need to run. Just add them to the build script, and hook their output into the build results.</p>
<p>On the other extreme, you can build your tests every time you build the project and execute them as a postbuild step. That way, any time you make a change to a project, all tests will execute and you&rsquo;ll see if anything went wrong. This is a great approach, but I wouldn&rsquo;t recommend it if tests add more than a couple of seconds to the incremental build time, otherwise, they&rsquo;ll be slowing you down more than they help.</p>
<p>For most developers, some approach in the middle will make most sense. For example, take a small, fast subset of tests that are more likely to break, and run those with every build. Whenever any code is checked in to version control, the build server can run those tests plus a few more, slower ones. And finally, at night, you can bring out the big guns and run those really long, really thorough ones that take a few hours to complete. You can separate those tests into different projects, or, if your framework supports them, into different test suites, which allow you to decide which sets of tests to execute at runtime. Reporting Results</p>
<p>If a unit test fails and nobody notices, is it really an error? Just running the tests isn&rsquo;t good enough. We have to make sure that someone sees the failure it and fixes the problem.</p>
<p>Most unit-testing frameworks will let you customize how you want the failure errors to be reported. By default they will probably be sent to stdout, but you can easily customize the framework to send them to debug log streams, save to a file, or upload them to a server.</p>
<p>Even more important than the actual error messages is detecting whether there were any failures. After running all the tests, there is usually some way to detect how many tests failed. The program that was running the tests can detect any failures, print an error message, and exit with an error code. That error code will propagate to the build server and trigger a build failure. Hopefully by now alarm sounds are going off across the office and someone is on his way to fix it.</p>
<h3 id="project-organization">Project Organization</h3>
<p>When people start down the unit test path, they often struggle to figure out how to physically lay out the unit tests. In the end, it really doesn&rsquo;t matter too much as long as it makes sense to you, the final build doesn&rsquo;t contain any tests, and they&rsquo;re still easy to build and run.</p>
<p>My personal preference is to keep unit tests separate from the rest of the code. Usually I end up creating one file of tests for every cpp file. So FirstPersonCameraController.h and .cpp have a corresponding TestFirstPersonCameraController.cpp. Since I use this convention regularly throughout all of my code, I have a custom IDE macro to toggle between a file and its corresponding test file. I also put all the tests in a separate subdirectory to keep them as physically separate as possible.</p>
<p>I prefer to break up my code into several static libraries for each major subsystem: graphics, networking, physics, animations, etc. Each of those libraries has a set of unit tests, but instead of compiling them into the library, I create a separate project that creates a simple executable program. That project contains all the unit tests and links against the library itself, and in its main entry point it just calls the function to runs all unit tests and returns the number of failures. This keeps the tests separate from the library, but still very easy to build.</p>
<p>If all your code is organized into libraries, and your game is just a collection of libraries linked together, that&rsquo;s all you need. Most games and tools, however, have a fair amount of code that you might want to test in the project itself. Since the game is an executable, you can&rsquo;t easily link against it from a different project like we did before. In this case, I build the unit tests into the game itself, and I optionally call them whenever a particular command-line parameter like -runtests is present. Just make sure to #ifdef out all the tests in the final build.</p>
<h3 id="multiplatform-testing">Multiplatform Testing</h3>
<p>Running the tests on the PC where you build the code is very straightforward. But unless you&rsquo;re only creating games and tools for that platform, you will definitely want to run your tests on different platforms as well. Unit tests are an invaluable tool for catching slight platform inconsistencies caused by different compilers, architecture idiosyncrasies, or varying floating point rules.</p>
<p>Unfortunately, running unit tests on a different platform from your build machine is usually a bit more involved and not nearly as fast as doing it locally. You need to start by compiling the tests for the target platform. This is usually not a problem since you&rsquo;re already building all your code for that platform, and hopefully your unit testing framework already supports it. Then you need to upload your executable with the tests and any data required to the target platform and run it there. Finally, you need to get the return code back to detect if there were any failures. This is surprisingly the trickiest part of the process with a lot of console development kits. If getting the exit code is not a possibility, you&rsquo;ll need to get creative by parsing the output channel, or even waiting for a notification on a particular network port.</p>
<p>Some target platforms are more limited than others in both resources and C++ support. One of the features that makes <a href="http://unittest-cpp.sourceforge.net/">UnitTest++</a> a good choice for games is that it requires minimal C++ features (no STL) and it can be trimmed down even further (no exceptions or streams).</p>
<p>For example, running unit tests on the PS3 SPUs was extremely useful, but it required stripping the framework down to the minimum amount of features. It was also tricky being able to fit the library code plus all the tests in the small amount of memory available. To get around that, we ended up changing the build rules for the SPUs so each test file created its own SPU executable (or module). We then wrote a simple main SPU program that would load each module separately, run its tests, keep track of all the stats, and finally report them.</p>
<p>Running a set of unit tests on the local machine can be an almost instant process, but running them on a remote machine is usually much slower, and can take up to 10 or 20 seconds just with the overhead of copying them and launching the program remotely. For this reason, you&rsquo;ll want to run tests on other platforms less frequently.</p>
<h3 id="no-leaking-allowed">No Leaking Allowed</h3>
<p>Finally, if you&rsquo;re going to have this all this unit testing code running on a regular basis, you might as well get as much information out of it as possible. I have found it invaluable to keep track of memory leaks around the unit test code.</p>
<p>You&rsquo;ll have to hook into your own memory manager, or use the platform-specific memory tracking functions. The basic idea is to get a memory status before running the tests, and another one after all the tests execute. If there are any extra memory allocations, that&rsquo;s probably a leak. In that case, you can report it as a failed build by returning the correct error code.</p>
<p>Watch out for static variables or singletons that allocate memory the first time they&rsquo;re used. They might be reported as memory leaks even though it wasn&rsquo;t what you were hoping to catch. In that case, you can explicitly initialize and destroy all singletons, or, even better, not use them at all, and keep your memory leak report clean.</p>
<p>You&rsquo;re now armed with all you need to know to set up unit tests into your project and build pipeline. Grab a testing framework and get started today.</p>
<p><em>This article was originally printed in the May 2009 issue of <a href="http://gdmag.com">Game Developer</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>When Is It OK Not To TDD?</title><link>https://gamesfromwithin.com/when-is-it-ok-not-to-tdd/</link><pubDate>Thu, 01 Jul 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/when-is-it-ok-not-to-tdd/</guid><description>&lt;p&gt;The basic principles of &lt;a href="https://gamesfromwithin.com/backwards-is-forward-making-better-games-with-test-driven-development/"&gt;Test-Driven Development&lt;/a&gt; (TDD) are very simple and easy to understand. Every programmer quickly grasps those and is able to apply them to simple cases and low level libraries (math libraries seem to be everybody&amp;rsquo;s favorite TDD proving ground &lt;a href="#1"&gt;[1]&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;What becomes significantly more difficult is learning to effectively apply TDD to code with more dependencies. A question that I&amp;rsquo;m often asked from people trying to use TDD for the first time is &amp;ldquo;How can you possibly use TDD for high-level game code? It&amp;rsquo;s impossible!&amp;rdquo;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The basic principles of <a href="/backwards-is-forward-making-better-games-with-test-driven-development/">Test-Driven Development</a> (TDD) are very simple and easy to understand. Every programmer quickly grasps those and is able to apply them to simple cases and low level libraries (math libraries seem to be everybody&rsquo;s favorite TDD proving ground <a href="#1">[1]</a>).</p>
<p>What becomes significantly more difficult is learning to effectively apply TDD to code with more dependencies. A question that I&rsquo;m often asked from people trying to use TDD for the first time is &ldquo;How can you possibly use TDD for high-level game code? It&rsquo;s impossible!&rdquo;.</p>
<h3 id="when-the-going-gets-tough">When The Going Gets Tough</h3>
<p>At that point, the temptation to give up on using TDD for high-level code becomes very strong. It seems that all the time spent writing mocks and hooking objects together is a waste of time and that you could be writing game code much faster without it. &ldquo;Maybe it would be best to skip TDD, just for that part&rdquo;.</p>
<p>Bad idea!</p>
<p><img alt="tdd_cycle.jpg" loading="lazy" src="/when-is-it-ok-not-to-tdd/images/tdd_cycle.jpg">By giving up on TDD for high-level code, you&rsquo;ll be missing out on the main benefit of TDD: designing better code. I&rsquo;ve said this many times, but it bears repeating: TDD is <strong>not</strong> a testing technique. It&rsquo;s a design technique. You get lots of benefits from applying TDD <a href="#2">[2]</a>, but one of the main one is much more modular and dependency-free code.</p>
<p>That&rsquo;s because TDD turns our weaknesses into advantages. We&rsquo;re humans and we&rsquo;re lazy. We don&rsquo;t want to repeat ourselves constantly or write complex code. If we&rsquo;re writing a test for some code we&rsquo;ll write in the future, we&rsquo;re going to create a very simple test. We&rsquo;re probably going to want to put some object or data on the stack and make a function call and nothing else. We certainly don&rsquo;t want to initialize the graphics system, create a new world, add some level data, start the physics simulation, and then call the function! So by being lazy, we end up writing very simple code with the least amount of dependencies.</p>
<p>What does that mean for our high-level code? The AI logic seems to need access to every single game system, at least the way we implemented it in the past. Using TDD to implement AI logic doesn&rsquo;t mean writing tests to write the same code you would have written before. It means writing tests and then writing some code that makes those tests pass and nothing else. For example, we might realize that the AI doesn&rsquo;t need to access the physics system, cast a ray in the world, find out what entities is interesting, and return that information. Instead, all it might need to do is output some data saying that it wants a ray query done at a later time (which in turn is the key to batching those ray casts and achieving high performance).</p>
<p>You soon realize that the code you write is very different (and better!) to what you would have written before. Once you get over that hump, TDDing high-level code is not about twisting your code with mocks, but becomes simpler code that takes simple input data and creates simple output data. By pushing through and forcing yourself to apply TDD, you made a breakthrough and reaped all the benefits.</p>
<p>That&rsquo;s the main reason why TDD books push the idea that no code can be written without a test first. Otherwise, inexperienced TDD programmers would be too quick to quit and would miss out on the technique completely.</p>
<p>Not only that, but code that is not created with TDD tends to have the bad habit of spreading. When code was not designed through TDD, it means that other code that uses it will probably be difficult to TDD itself. So it&rsquo;s a bit like const-correctness: You&rsquo;re either in our out, and there&rsquo;s very little room for half measures.</p>
<p>On the other hand, I would argue that using TDD on a math library is a bad idea. It&rsquo;s essential to write good unit tests for a math library, but probably not to design it through TDD. Are you really going to implement a cross product differently just because you wrote tests before? The emphasis there has to be on correctness and performance, not on creating the interface or implementation through tests.</p>
<h3 id="its-a-tool-to-help-development">It&rsquo;s A Tool To Help Development</h3>
<p>A few days ago, I received an email from <a href="http://twitter.com/nairou">Caleb Gingles</a> with a great question:</p>
<p><em>I&rsquo;ve started a new game project and have been making an effort to strictly follow TDD from the beginning. Which has been a challenge, as much of the coding at the beginning of the project has consisted of operating system requirements and framework stuff. [&hellip;] However, there are other situations that seem much harder to test. Like the main loop in a game. According to Kent Beck&rsquo;s book, everything begins with testing, and no code is written unless a test requires it. But how can a test require the main loop framework in a game? The loop just&hellip; is. It exists to allow you to do certain other things, it doesn&rsquo;t have much purpose in and of itself.</em></p>
<p>Applying what I just talked about, we could use TDD to create the main loop of a game. It definitely requires thinking about it differently and breaking preconceptions. It&rsquo;s about writing code to pass the tests, not writing tests to fit the code we want to write.</p>
<p>So we could do something like this:</p>
<pre tabindex="0"><code>TEST(MainLoopExecutesCorrectNumberOfTimes)
{
    MainLoopState loopState;
    MainLoopUtils::Execute(loopState, 4);
    CHECK_EQUAL(4, loopState.frameCount);
}
</code></pre><p>All of a sudden we see a way to test something that before it seemed impossible to test. We can add tests to make sure certain functions are getting called (maybe we add those function pointers to the loopState), that the main loop exits under certain conditions, etc.</p>
<p>For some games with complex GUIs and different game modes, it might make a lot of sense to have a more flexible main loop and develop it completely through TDD. On the other hand, for a simple iPhone game that has a single main loop that never changes, there might be no point at all in using TDD. The loop code is going to end up looking more or less the same as it would without TDD, just more complex and generic. TDD didn&rsquo;t help any in that case.</p>
<p>How about code that calls into OpenGL, or some other non-TDD-friendly library? Do we have to TDD that? Frankly, I wouldn&rsquo;t bother. I did give it a good try at one point several years ago and I can say it <strong>is</strong> possible, but it&rsquo;s a pain and you gain almost nothing from it. The main benefits is trusting that the library you&rsquo;re using really does what it&rsquo;s supposed to do, but it won&rsquo;t affect much the design of your code. So what you&rsquo;re really doing is adding tests to that library (which might or might not be of value).</p>
<p>My advice in a situation like that: Call the library from as few places as possible (I didn&rsquo;t want to say make a thin wrapper because that implies isolation which is not the goal here), and just test that your code is called at the right time with the right data. The actual code that calls the library should be small and simple enough that you should feel OK not having any tests for it.</p>
<p>Even though it seems to go against what I said in the previous section, TDD is not all or nothing. It&rsquo;s not a religion.</p>
<p>When you&rsquo;re starting out, I encourage you to push yourself to think how you could apply TDD to situations you don&rsquo;t think are possible. Once you&rsquo;re experienced enough, you&rsquo;ll know when to say enough is enough, and use TDD only when it actually benefits you. At that point you&rsquo;ll also know how to write code in a way that plays well with TDD, even if the code itself was not developed through TDD.</p>
<p>In the end, TDD is a tool to help you develop better and faster. Don&rsquo;t ever let it get in the way of that.</p>
<p>[1] That&rsquo;s actually a horrible place to apply TDD. More on that in a second.</p>
<p>[2] Usable API, simple code, unit tests, documentation, safety net for refactoring among others.</p>
]]></content:encoded></item><item><title>Paying Off: The Story Behind Unearthed</title><link>https://gamesfromwithin.com/paying-off-the-story-behind-unearthed/</link><pubDate>Wed, 30 Jun 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/paying-off-the-story-behind-unearthed/</guid><description>&lt;p&gt;&lt;em&gt;Today I have the pleasure to introduce the first-ever guest post in Games From Within, &lt;a href="http://twitter.com/Gyrovation"&gt;Joey Chang&lt;/a&gt;. Like me, Joey worked for many years in the game industry, and finally took the plunge last October to become an &lt;a href="http://www.gyrovation.com/"&gt;independent game developer&lt;/a&gt;. &lt;a href="http://itunes.apple.com/us/app/unearthed/id370826160?mt=8"&gt;Unearthed&lt;/a&gt; is his first iPhone project and it&amp;rsquo;s a very unique free to play, augmented reality (AR) game with an X-Files-like theme.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Joey was kind enough to share the story behind Unearthed, some of the decisions leading up to the final game, and the initial reception and sales numbers. Thanks Joey!&lt;/em&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>Today I have the pleasure to introduce the first-ever guest post in Games From Within, <a href="http://twitter.com/Gyrovation">Joey Chang</a>. Like me, Joey worked for many years in the game industry, and finally took the plunge last October to become an <a href="http://www.gyrovation.com/">independent game developer</a>. <a href="http://itunes.apple.com/us/app/unearthed/id370826160?mt=8">Unearthed</a> is his first iPhone project and it&rsquo;s a very unique free to play, augmented reality (AR) game with an X-Files-like theme.</em></p>
<p><em>Joey was kind enough to share the story behind Unearthed, some of the decisions leading up to the final game, and the initial reception and sales numbers. Thanks Joey!</em></p>
<h3 id="inspiration">Inspiration</h3>
<p>Nine months ago, without warning, a gnome crept into my head. It was an idea inspired from a friend&rsquo;s chance mention of an activity called geocaching, where participants use a GPS to hide and seek containers across the world. Within hours, I had envisioned a global cross between geocaching, the Amazing Race, and online travel agency representatives. The idea didn&rsquo;t look much like the resultant product nine months later, but it formed the most critical ingredient to any venture: the obsession to see it completed.</p>
<p>I spent my evenings for a few short weeks hammering out a design, scoping and cutting features, and beginning a prototype, but it didn&rsquo;t take long for me to admit to the unavoidable truth that such a project would take months working full time or probably 3 to 4 times as many months working nights and weekends. I had to sit and carefully consider the pros and cons of leaving my job to pursue something I desperately wanted to create.</p>
<h3 id="half-hearted-dissent">Half-Hearted Dissent</h3>
<p><img alt="UnearthedPoster.jpg" loading="lazy" src="/paying-off-the-story-behind-unearthed/images/UnearthedPoster.jpg">For two weeks, I debated with my wife and close friends with startup experience. I drafted a list of pros and cons to quitting my job to pursue an iphone project and stared at it for hours. Those of you who have made the leap or considered it may recognize some of the points or have more of your own to add:</p>
<p>Advantages of quitting to work full time on an iphone idea</p>
<ul>
<li>Focus effort, complete project 3-4 times faster</li>
<li>Gain valuable unique experience of running solo</li>
<li>Avoid coding burnout, alienating loved ones, loss of sanity</li>
<li>Resume padding</li>
</ul>
<p>Advantages of keeping day job while working on iphone idea</p>
<ul>
<li>Steady income in a scary economy</li>
<li>Not having to job search in a scary economy</li>
<li>Peace of mind (in a scary economy)</li>
</ul>
<p>You can see where a large portion of the dissenting argument forms its basis. After two weeks of listening to unanimous encouragement (bordering on persistent nagging) to quit my job, two weeks of trying my best to convince myself why I should not quit my job, I did what my gut knew from day one was going to be best for me. I marched to my boss&rsquo;s room and quit my job. Ok, I had maybe two false starts where I turned around and went back to my seat.</p>
<h3 id="the-project-unearthed">The Project Unearthed</h3>
<p>Over the next 8 months, scoping and an inclination to appeal to a casual segment evolved the project into a global paranormal investigation titled Unearthed. I tried my best to figure how to maximize the success of the product, and compiled a list of all the ways I could imagine increasing the product&rsquo;s exposure:</p>
<ul>
<li>Banner ads</li>
<li>Spamming blogs and websites to review my product</li>
<li>Spamming friends on facebook</li>
<li>Writing a blog</li>
<li>Viral app features</li>
</ul>
<p>I had trouble justifying the cost to pay for banner ads, and I had too much urgency to implement the product to devote time to a blog, so I focused on occasionally talking about the app on facebook, compiling a list of potential blog candidates for the day the app released, and devising viral features.</p>
<p><img alt="Screen1.jpg" loading="lazy" src="/paying-off-the-story-behind-unearthed/images/Screen13.jpg">Apart from typical facebook posting and email-a-friend features, I decided to employ a &ldquo;refer-an-agent&rdquo; feature which would enable users to invite others to join their network, essentially a grouping of users that correlated with how effectively their app could process scanned creature data. The larger the network, the more credit users would receive for uploading data, and the better they would perform in leaderboards and achievements. The approach was an &ldquo;everybody wins&rdquo; style where anytime any user in the network gained a referral, every single person in the network would benefit from the growth of the network. The hope was that this feature would gain a viral quality.</p>
<p>Friends placed immense pressure to release the product as soon as humanly possible under the theory that doing so would reveal the 70% of my design that was wrong, so I divided Unearthed into three releases. The app itself has three game modes, each incrementally accessible as a given region &ldquo;levels up&rdquo; from users&rsquo; data uploads. I would have time to release the latter modes while the first mode of the game, the most casual mode where users look around where they stand and scan for anomalies, was being played.</p>
<h3 id="in-app-purchases-and-ads">In App Purchases and Ads</h3>
<p><img alt="Screen0.jpg" loading="lazy" src="/paying-off-the-story-behind-unearthed/images/Screen0.jpg">Considering the App Store was flooded with free apps and that I had no name in the industry to immediately convince users to immediately pay for my app, I concluded that the most likely approach for success was to release a free app with In App Purchases. This appeared to be the best way to get as many users to at least try the app and decide how much they wanted to spend to access more functionality. Initially, I offered the following items:</p>
<ul>
<li>All content, present and future ($5.99)</li>
<li>Scanner upgrades level 2-3 ($1.99)</li>
<li>Scanner upgrades level 4-5 ($1.99)</li>
<li>Bounty Mode (coming soon) ($1.99)</li>
<li>Blitz Mode (coming soon) ($1.99)</li>
</ul>
<p>However, I hit a snag with Apple&rsquo;s terms which did not permit me to even mention any features that were not yet implemented. The first item was intended to be a bulk pricing investment in the forthcoming completion of the app, and the &lsquo;coming soon&rsquo; items were just client-side displays to tease of the future modes (not actually registered products in the IAP servers). Because I had to remove them, I revised my IAP content to the following:</p>
<ul>
<li>Scanner upgrades level 2 ($.99)</li>
<li>Scanner upgrades level 3 ($.99)</li>
<li>Scanner upgrades level 4 ($.99)</li>
<li>Scanner upgrades level 5 ($.99)</li>
<li>Scanner upgrades 2-5 ($2.99)</li>
</ul>
<p>The app essentially gives users access to all features of the game, but with a lowly basic scanner that doesn&rsquo;t boast the speed, range, and creature clearance levels of a fully boosted scanner.</p>
<p>I added Greystripe&rsquo;s ad system as a means to offset the cost I might incur from using Google App Engine as my server solution. Considering the large amount of rank tracking required by my app, I estimated the revenue from ads to break even with the cost of using App Engine.</p>
<h3 id="release-and-reception">Release and Reception</h3>
<p>The app was approved in the early afternoon of June 21st, a Monday. Excited, I quickly moved up the release date and it hit the stores later that afternoon. One week later, the sales are dismal, with about 400 total downloads and only a handful of purchases.</p>
<p><img alt="UnearthedWeek1.jpg" loading="lazy" src="/paying-off-the-story-behind-unearthed/images/UnearthedWeek1.jpg"></p>
<p>I considered possible contributors to this could be the following (in order of impact):</p>
<ul>
<li>Requiring 3GS</li>
<li>Releasing 4 days before the iPhone 4 (dropping off New Releases)</li>
<li>Requiring OS 3.1.3 (instead of 3.1)</li>
<li>Releasing the app in the late afternoon (dropping off New Releases faster)</li>
</ul>
<p>Without knowing the specifics on the sales of the 3GS versus the 3G and the iPod Touch, the fraction of 3GS users able to even see my app in the store might be a small fraction. Unnecessarily releasing under an OS that prevented users from installing unless they went back to iTunes to update their OS was likely a dealbreaker for browsing users (quickly remedied but days later). And considering how many of the 1.5 million users would be browsing the App Store for free apps Thursday, releasing a few days too early may have been the biggest avoidable mistake yet.</p>
<h3 id="moving-forward">Moving Forward</h3>
<p>As uninspiring as it was getting only a few hundred downloads and enough revenue for lunch, I had heard that word of mouth was a powerful vehicle, possibly the best vehicle, for an unknown developer, so my plan is to continue giving it more time and implement the GPS-enabled Bounty Mode which will take considerably less time, possibly a short 1-2 months. One week is certainly not a large enough measure of success, and already I&rsquo;ve received a few responses from blogs willing to write reviews, so I&rsquo;m hopeful of seeing the userbase grow and eagerly anticipating the next big server issue. In the coming weeks, there will definitely be no &ldquo;sitting back while the cash rolls in&rdquo;, as I recently had the blessing/curse of another inspiring must-create iPad app revelation and am sweating bullets designing and scoping while scheduling in work on Unearthed, all the while keeping a grave eye on the lifeline of my business.</p>
<p>Looking back at the struggling decision I made to quit my job, I&rsquo;m reminded of some advice that was given to me beforehand. &ldquo;Quitting your job will be the hardest decision, but it will make you feel great.&rdquo; And like an enormous burden lifted from me, it did. And to this day, with earned lunch money in hand, it continues to.</p>
]]></content:encoded></item><item><title>Managing Data Relationships</title><link>https://gamesfromwithin.com/managing-data-relationships/</link><pubDate>Sun, 27 Jun 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/managing-data-relationships/</guid><description>&lt;p&gt;_I&amp;rsquo;ve been meaning to put up the rest of the &lt;a href="https://gamesfromwithin.com/tag/inner-product/"&gt;Inner Product columns&lt;/a&gt; I wrote for &lt;a href="http://gdmag.com"&gt;Game Developer Magazine&lt;/a&gt;, but I wasn&amp;rsquo;t finding the time. With all the &lt;a href="https://gamesfromwithin.com/the-always-evolving-coding-style/"&gt;recent discussion on data-oriented design&lt;/a&gt;, I figured it was time to dust some of them off.&lt;/p&gt;
&lt;p&gt;This was one of the first columns I wrote. At first glance it might seem a completely introductory topic, not worth spending that much time on it. After all, all experience programmers know about pointers and indices, right? True, but I don&amp;rsquo;t think all programmers really take the time to think about the advantages and disadvantages of each approach, and how it affects architecture decisions, data organization, and memory traversal.&lt;/p&gt;</description><content:encoded><![CDATA[<p>_I&rsquo;ve been meaning to put up the rest of the <a href="/tag/inner-product/">Inner Product columns</a> I wrote for <a href="http://gdmag.com">Game Developer Magazine</a>, but I wasn&rsquo;t finding the time. With all the <a href="/the-always-evolving-coding-style/">recent discussion on data-oriented design</a>, I figured it was time to dust some of them off.</p>
<p>This was one of the first columns I wrote. At first glance it might seem a completely introductory topic, not worth spending that much time on it. After all, all experience programmers know about pointers and indices, right? True, but I don&rsquo;t think all programmers really take the time to think about the advantages and disadvantages of each approach, and how it affects architecture decisions, data organization, and memory traversal.</p>
<p>It should provide a good background for this coming Thursday&rsquo;s <a href="http://twitter.com/#search?q=%23idevblogaday">#iDevBlogADay</a> post on how to deal with heterogeneous objects in a data-oriented way._</p>
<p>From a 10,000-Foot view, all video games are just a sequence of bytes. Those bytes can be divided into code and data. Code is executed by the hardware and it performs operations on the data. This code is generated by the compiler and linker from the source code in our favorite computer language. Data is just about everything else. <a href="#1">[1]</a></p>
<p>As programmers, weâ€™re obsessed with code: beautiful algorithms, clean logic, and efficient execution. We spend most of our time thinking about it and make most decisions based on a code-centric view of the game.</p>
<p>Modern hardware architectures have turned things around. A data-centric approach can make much better use of hardware resources, and can produce code that is much simpler to implement, easier to test, and easier to understand. In the next few months, weâ€™ll be looking at different aspects of game data and how everything affects the game. This month we start by looking at how to manage data relationships.</p>
<h2 id="data-relationships">Data Relationships</h2>
<p>Data is everything that is not code: meshes and textures, animations and skeletons, game entities and pathfinding networks, sounds and text, cut scene descriptions and dialog trees. Our lives would be made simpler if data simply lived in memory, each bit totally isolated from the rest, but thatâ€™s not the case. In a game, just about all the data is intertwined in some way. A model refers to the meshes it contains, a character needs to know about its skeleton and its animations, and a special effect points to textures and sounds.</p>
<p>How are those relationships between different parts of data described? There are many approaches we can use, each with its own set of advantages and drawbacks. There isnâ€™t a one-size-fits-all solution. Whatâ€™s important is choosing the right tool for the job.</p>
<h2 id="pointing-the-way">Pointing The Way</h2>
<p>In C++, regular pointers (as opposed to â€œsmart pointersâ€ which weâ€™ll discuss later on) are the easiest and most straightforward way to refer to other data. Following a pointer is a very fast operation, and pointers are strongly typed, so itâ€™s always clear what type of data theyâ€™re pointing to.</p>
<p>However, they have their share of shortcomings. The biggest drawback is that a pointer is just the memory address where the data happens to be located. We often have no control over that location, so pointer values usually change from run to run. This means if we attempt to save a game checkpoint which contains a pointer to other parts of the data, the pointer value will be incorrect when we restore it.</p>
<p>Pointers represent a many-to-one relationship. You can only follow a pointer one way, and it is possible to have many pointers pointing to the same piece of data (for example, many models pointing to the same texture). All of this means that it is not easy to relocate a piece of data that is referred to by pointers. Unless we do some extra bookkeeping, we have no way of knowing what pointers are pointing to the data we want to relocate. And if we move or delete that data, all those pointers wonâ€™t just be invalid, theyâ€™ll be <em>dangling pointers</em>. They will point to a place in memory that contains something else, but the program will still think it has the original data in it, causing horrible bugs that are no fun to debug.</p>
<p>One last drawback of pointers is that even though theyâ€™re easy to use, somewhere, somehow, they need to be set. Because the actual memory location addresses change from run to run, they canâ€™t be computed offline as part of the data build. So we need to have some extra step in the runtime to set the pointers after loading the data so the code can use them. This is usually done either by explicit creation and linking of objects at runtime, by using other methods of identifying data, such as resource UIDs created from hashes, or through pointer fixup tables converting data offsets into real memory addresses. All of it adds some work and complexity to using pointers.</p>
<p>Given those characteristics, pointers are a good fit to model relationships to data that is never deleted or relocated, from data that does not need to be serialized. For example, a character loaded from disk can safely contain pointers to its meshes, skeletons, and animations if we know weâ€™re never going to be moving them around.</p>
<h2 id="indexing">Indexing</h2>
<p>One way to get around the limitation of not being able to save and restore pointer values is to use offsets into a block of data. The problem with plain offsets is that the memory location pointed to by the offset then needs to be cast to the correct data type, which is cumbersome and prone to error.</p>
<p>The more common approach is to use indices into an array of data. Indices, in addition to being safe to save and restore, have the same advantage as pointers in that theyâ€™re very fast, with no extra indirections or possible cache misses.</p>
<p>Unfortunately, they still suffer from the same problem as pointers of being strictly a many-to-one relationship and making it difficult to relocate or delete the data pointed to by the index. Additionally, arrays can only be used to store data of the same type (or different types but of the same size with some extra trickery on our part), which might be too restrictive for some uses.</p>
<p>A good use of indices into an array are particle system descriptions. The game can create instances of particle systems by referring to their description by index into that array. On the other hand, the particle system instances themselves would not be a good candidate to refer to with indices because their lifetimes vary considerably and they will be constantly created and destroyed.</p>
<p>Itâ€™s tempting to try and extend this approach to holding pointers in the array instead of the actual data values. That way, we would be able to deal with different types of data. Unfortunately, storing pointers means that we have to go through an extra indirection to reach our data, which incurs a small performance hit. Although this performance hit is something that we&rsquo;re going to have to live with for any system that allows us to relocate data, the important thing is to keep the performance hit as small as possible.</p>
<p>An even bigger problem is that, if the data is truly heterogeneous, we still need to cast it to the correct type before we use it. Unless all data referred to by the pointers inherits from a common base class that we can use to query for its derived type, we have no easy way to find out what type the data really is. On the positive side, now that weâ€™ve added an indirection (index to pointer, pointer to data), we could relocate the data, update the pointer in the array, and all the indices would still be valid. We could even delete the data and null the pointer out to indicate it is gone. Unfortunately, what we canâ€™t do is reuse a slot in the array since we donâ€™t know if thereâ€™s any data out there using that particular index still referring to the old data.</p>
<p>Because of these drawbacks, indices into an array of pointers is usually not an effective way to keep references to data. Itâ€™s usually better to stick with indices into an array of data, or extend the idea a bit further into a handle system, which is much safer and more versatile.</p>
<h2 id="handle-ing-the-problem">Handle-Ing The Problem</h2>
<p>Handles are small units of data (32 bits typically) that uniquely identify some other part of data. Unlike pointers, however, handles can be safely serialized and remain valid after theyâ€™re restored. They also have the advantages of being updatable to refer to data that has been relocated or deleted, and can be implemented with minimal performance overhead.</p>
<p>The handle is used as a key into a handle manager, which associates handles with their data. The simplest possible implementation of a handle manager is a list of handle-pointer pairs and every lookup simply traverses the list looking for the handle. This would work but itâ€™s clearly very inefficient. Even sorting the handles and doing a binary search is slow and we can do much better than that.</p>
<p><a href="/wp-content/uploads/2010/06/HandleManager.zip">Here&rsquo;s an efficient implementation of a handle manager</a> (released under the usual <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>, so go to town with it). The handle manager is implemented as an array of pointers, and handles are indices into that array. However, to get around the drawbacks of plain indices, handles are enhanced in a couple of ways.</p>
<p>In order to make handles more useful than pointers, weâ€™re going to use up different bits for different purposes. We have a full 32 bits to play with, so this is how weâ€™re going to carve them out:</p>
<p><img alt="Handle.png" loading="lazy" src="/managing-data-relationships/images/Handle.png"></p>
<ul>
<li>
<p><strong>The index field</strong>. These bits will make up the actual index into the handle manager, so going from a handle to the pointer is a very fast operation. We should make this field as large as we need to, depending on how many handles we plan on having active at once. 14 bits give us over 16,000 handles, which seems plenty for most applications. But if you really need more, you can always use up a couple more bits and get up to 65,000 handles.</p>
</li>
<li>
<p><strong>The counter field</strong>. This is the key to making this type of handle implementation work. We want to make sure we can delete handles and reuse their indices when we need to. But if some part of the game is holding on to a handle that gets deletedâ€”and eventually that slot gets reused with a new handleâ€”how can we detect that the old handle is invalid? The counter field is the answer. This field contains a number that goes up every time the index slot is reused. Whenever the handle manager tries to convert a handle into a pointer, it first checks that the counter field matches with the stored entry. Otherwise, it knows the handle is expired and returns null.</p>
</li>
<li>
<p><strong>The type field</strong>. This field indicates what type of data the pointer is pointing to. There are usually not that many different data types in the same handle manager, so 6â€“8 bits are usually enough. If youâ€™re storing homogeneous data, or all your data inherits from a common base class, then you might not need a type field at all.</p>
</li>
</ul>
<pre tabindex="0"><code>struct Handle
{
    Handle() : m_index(0), m_counter(0), m_type(0)
    {}

    Handle(uint32 index, uint32 counter, uint32 type)
        : m_index(index), m_counter(counter), m_type(type)
    {}

    inline operator uint32() const;
    
    uint32 m_index : 12;
    uint32 m_counter : 15;
    uint32 m_type : 5;
};

Handle::operator uint32() const
{
    return m_type &lt;&lt; 27 | m_counter &lt;&lt; 12 | m_index;
}
</code></pre><p>The workings of the handle manager itself are pretty simple. It contains an array of HandleEntry types, and each HandleEntry has a pointer to the data and a few other bookkeeping fields: freelist indices for efficient addition to the array, the counter field corresponding to each entry, and some flags indicating whether an entry is in use or itâ€™s the end of the freelist.</p>
<pre tabindex="0"><code>struct HandleEntry
{
	HandleEntry();
	explicit HandleEntry(uint32 nextFreeIndex);
	
	uint32 m_nextFreeIndex : 12;
	uint32 m_counter : 15;
	uint32 m_active : 1;
	uint32 m_endOfList : 1;
	void* m_entry;
};
</code></pre><p>Accessing data from a handle is just a matter of getting the index from the handle, verifying that the counters in the handle and the handle manager entry are the same, and accessing the pointer. Just one level of indirection and very fast performance.</p>
<p>We can also easily relocate or invalidate existing handles just by updating the entry in the handle manager to point to a new location or to flag it as removed.</p>
<p>Handles are the perfect reference to data that can change locations or even be removed, from data that needs to be serialized. Game entities are usually very dynamic, and are created and destroyed frequently (such as enemies spawning and being destroyed, or projectiles). So any references to game entities would be a good fit for handles, especially if this reference is held from another game entity and its state needs to be saved and restored. Examples of these types of relationships are the object a player is currently holding, or the target an enemy AI has locked onto.</p>
<h2 id="getting-smarter">Getting Smarter</h2>
<p>The term smart pointers encompasses many different classes that give pointer-like syntax to reference data, but offer some extra features on top of â€œrawâ€ pointers.</p>
<p>A common type of smart pointer deals with object lifetime. Smart pointers keep track of how many references there are to a particular piece of data, and free it when nobody is using it. For the runtime of games, I prefer to have very explicit object lifetime management, so Iâ€™m not a big fan of this kind of pointers. They can be of great help in development for tools written in C++ though.</p>
<p>Another kind of smart pointers insert an indirection between the data holding the pointer and the data being pointed. This allows data to be relocated, like we could do with handles. However, implementations of these pointers are often non- serializable, so they can be quite limiting.</p>
<p>If you consider using smart pointers from some of the popular libraries (STL, Boost) in your game, you should be very careful about the impact they can have on your build times. Including a single header file from one of those libraries will often pull in numerous other header files. Additionally, smart pointers are often templated, so the compiler will do some extra work generating code for each data type you instantiated templates on. All in all, templated smart pointers can have a significant impact in build times unless they are managed very carefully.</p>
<p>Itâ€™s possible to implement a smart pointer that wraps handles, provides a syntax like a regular pointer, and it still consists of a handle underneath, which can be serialized without any problem. But is the extra complexity of that layer worth the syntax benefits it provides? It will depend on your team and what youâ€™re used to, but itâ€™s always an option if the team is more comfortable dealing with pointers instead of handles.</p>
<h2 id="conclusion">Conclusion</h2>
<p>There are many different approaches to expressing data relationships. Itâ€™s important to remember that different data types are better suited to some approaches than others. Pick the right method for your data and make sure itâ€™s clear which one youâ€™re using.</p>
<p>In the next few months, weâ€™ll continue talking about data, and maybe even convince you that putting some love into your data can pay off big time with your code and the game as a whole.</p>
<p><em>This article was originally printed in the September 2008 issue of <a href="http://gdmag.com">Game Developer</a>.</em></p>
<p>[1] I&rsquo;m not too happy about the strong distinction I was making between code and data. Really, data is any byte in memory, and that includes code. Most of the time programs are going to be managing references to non-code data, but sometimes to other code as well: function pointers, compiled shaders, compiled scripts, etc. So just ignore that distinction and think of data in a more generic way.</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><item><title>Increase Your App Ratings On The App Store</title><link>https://gamesfromwithin.com/increase-your-app-ratings-on-the-app-store/</link><pubDate>Mon, 14 Jun 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/increase-your-app-ratings-on-the-app-store/</guid><description>&lt;p&gt;Every iPhone developer fears the one-star-on-uninstall rating. I understand Apple&amp;rsquo;s reasoning for adding the prompt for rating on uninstall, but since that&amp;rsquo;s the only time users are prompted, it becomes a very biased, negative rating. There may be hundreds of users happy with your app who never rate it on iTunes, but everybody who uninstalls it gets asked to give it a review. That&amp;rsquo;s quite unfair from the developer point of view.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Every iPhone developer fears the one-star-on-uninstall rating. I understand Apple&rsquo;s reasoning for adding the prompt for rating on uninstall, but since that&rsquo;s the only time users are prompted, it becomes a very biased, negative rating. There may be hundreds of users happy with your app who never rate it on iTunes, but everybody who uninstalls it gets asked to give it a review. That&rsquo;s quite unfair from the developer point of view.</p>
<p>First one bit of good news: That prompt-on-delete feature seems to be gone on iOS 4.0. That should make everybody happy. Even so, taking a pro-active position on this can only benefit developers.</p>
<p>Next a personal opinion without any real hard data to back it up: I don&rsquo;t think App Store ratings matter very much. I see plenty of quality, 5-star apps that never go anywhere, as well as horrible apps with close to 1-star rating on the top 10. I&rsquo;m sure good ratings help a bit, but not as much as some people may think.</p>
<p>One of the little features I snuck in <a href="http://www.facebook.com/iphoneflowergarden?v=wall&amp;story_fbid=130406023644468&amp;ref=mf">the latest update of Flower Garden</a>, was a prompt to rate (or re-rate) the app. <a href="http://www.mobileorchard.com/fighting-back-against-the-app-stores-negative-rating-bias/">This idea isn&rsquo;t new</a>, and I&rsquo;ve seen quite a few apps doing it already. I think it makes a lot of sense and provides rating that is much more balanced and representative of how users feel about the app.</p>
<p>You have to be careful about how you prompt users though. This are the priorities I had in mind when I implemented the rating prompt in Flower Garden, roughly in order of importance:</p>
<ol>
<li>Don&rsquo;t be annoying!</li>
<li>Disrupt the user as little as possible</li>
<li>Make rating the app as easy as possible.</li>
<li>Prompt at every update.</li>
</ol>
<p><img alt="fg_prompt.jpg" loading="lazy" src="/increase-your-app-ratings-on-the-app-store/images/fg_prompt.jpg"></p>
<h3 id="dont-be-annoying">Don&rsquo;t be annoying</h3>
<p>This is by far the most important priority. If your prompt for review is annoying, you might get more angry users and one-star reviews than you would have without it. Be respectful of the user and don&rsquo;t nag.</p>
<p>For quite a few versions, I&rsquo;ve had a review button in the &ldquo;Feedback&rdquo; tab in the settings screen. Not many people use it or even know about it because it was several taps away from the normal flow of Flower Garden. That&rsquo;s an example of a feedback prompt that is <strong>too</strong> unobtrusive. Clearly, I needed something a bit more noticeable.</p>
<p>What I did was to add an actual alert view with the prompt. That alert comes up very infrequently, and gives users the option to either rate it right away, be reminded later, or just stop asking altogether. Many more users rated the app through this mechanism (and I haven&rsquo;t gotten a single complaint about it being annoyed yet&ndash;keeping my fingers crossed).</p>
<h3 id="disrupt-the-user-as-little-as-possible">Disrupt the user as little as possible</h3>
<p>First of all, you should never ask the user to rate the first time they launch it. They haven&rsquo;t had a chance to check it out yet! Give them a few days (or a few launches of the app). That will benefit you in two ways: users will have a better chance to give an honest rating, and users who didn&rsquo;t like your app probably won&rsquo;t be around in two days, so they&rsquo;ll never see the prompt.</p>
<p>Second, choose a good time to ask. Please, don&rsquo;t ask me as soon as I launch the app! Chances are I want to do something with it, so being pestered with a review prompt is disruptive, especially because adding a rating involves leaving the app and going to iTunes. At the same time, don&rsquo;t ask me in the middle of a level or when I&rsquo;m engrossed in game. A good moment to ask for a rating would be after completing a level or two, or, in the case of Flower Garden, after sending a bouquet.</p>
<p>For extra bonus points, catch the user on a &ldquo;good&rdquo; moment. Maybe only ask them to rate the app if they actually beat the level. They&rsquo;ll probably leave a better review than if they just lost and are in a bad mood.</p>
<p>The exception I made was if a certain amount of time went by and the user never got to the point of being prompted (some people just don&rsquo;t send bouquets in Flower Garden). In that case, I will ask at startup or at some other, non-ideal point.</p>
<h3 id="make-rating-the-app-as-easy-as-possible">Make rating the app as easy as possible</h3>
<p>This is the funnel principle at work. For every action the user has to do in order to leave a review, the fewer users will actually do it. It would be ideal if users could rate the app directly from the alert box. That would involve no extra actions (or leaving the app) and would result in the maximum number of ratings [1]. Unfortunately, that&rsquo;s not the case, so we have to do the best we can with what we have.</p>
<p>So we want to minimize the amount of actions from the moment the user taps &ldquo;Rate now&rdquo; until they can enter the rating. We could send them to the product page on the App Store, but that would still involve them scrolling around, finding the rating button, tapping it, and entering the rating. We can do better than that: We can send them directly to the rating screen. Check out <a href="http://bjango.com/articles/ituneslinks/">this great post</a> for a dissection of iTunes links and how to create one to the review page. Make sure the technique you choose works on an iPhone (not all of them do!).</p>
<h3 id="prompt-at-every-update">Prompt at every update</h3>
<p>This one is easy: Just store the number of the last version the user wrote a review for, and if it changes, start from scratch again. That way you don&rsquo;t have to write any custom code at every release. Also, make sure to respect the &ldquo;Don&rsquo;t ask anymore&rdquo; option if the user selected that in a previous update.</p>
<h3 id="source-code">Source code</h3>
<p>Here&rsquo;s the <a href="/wp-content/uploads/2010/06/ReviewRequest.zip" title="ReviewRequest.zip">review request source code</a> (released under the MIT license). It consists of only two standalone files, and all the review state is kept in the default, global settings. There are only three functions and it should be very self-explanatory:</p>
<pre tabindex="0"><code>	bool ShouldAskForReview();
	bool ShouldAskForReviewAtLaunch();
	void AskForReview();
</code></pre><p>The ShouldAskForReviewAtLaunch() function simply adds an extra condition of launching it X number of times before asking for review (this is in case the user never triggers the review condition).</p>
<h3 id="results">Results</h3>
<p>Does this prompt for ratings work? This is a screen grab from iTunes 5 days after Flower Garden 2.4 was released:</p>
<p><img alt="fg_itunes_ratings.png" loading="lazy" src="/increase-your-app-ratings-on-the-app-store/images/fg_itunes_ratings.png"></p>
<p>A few interesting observations:</p>
<ul>
<li>Ratings are higher than they were before. Before the free day, Flower Garden had an average of 3.5 to 4 stars.</li>
<li>Reviews are often shorter and less useful than unprompted reviews. There are a lot of 5-star &ldquo;I love this app!&rdquo; reviews without much more substance. (I&rsquo;m not complaining, really).</li>
<li>Still a huge number of users chose not to leave a review. There are only 148 ratings, but there have been 30,000 upgrades to the latest version. A lot of people might have upgraded and not launched it, but even so, it&rsquo;s a very small percentage.</li>
</ul>
<p>Overall, it was a very small time investment and the results show it was definitely worth it. I&rsquo;ll be using this approach in my future projects (unless future iOS versions take care of it automatically somehow).</p>
<p>[1] Apple, can we fix that? How about a REST API for leaving ratings and reviews? Pretty please?</p>
]]></content:encoded></item><item><title>Flower Garden Selected As An Apple Staff Favorite Across Europe</title><link>https://gamesfromwithin.com/flower-garden-selected-as-an-apple-staff-favorite-across-europe/</link><pubDate>Fri, 14 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-selected-as-an-apple-staff-favorite-across-europe/</guid><description>&lt;p&gt;&lt;img alt="fg_europe.jpg" loading="lazy" src="https://gamesfromwithin.com/flower-garden-selected-as-an-apple-staff-favorite-across-europe/images/fg_europe.jpg"&gt;Right on the heels of the Mother&amp;rsquo;s Day promotion, &lt;a href="http://bit.ly/fg_gfw"&gt;Flower Garden&lt;/a&gt; just got its &lt;a href="https://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/"&gt;second&lt;/a&gt; ever App Store feature. This time it was selected as a Staff Favorite across most of Europe (UK, Spain, Ireland, Denmark, Finland, Greece, Netherlands, Norway, Portugal, Switzerland, and Sweden!).&lt;/p&gt;
&lt;p&gt;And if you haven&amp;rsquo;t picked up your &lt;strong&gt;free&lt;/strong&gt; copy of Flower Garden, make sure to do it now. It will probably go back to full price after this weekend.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="fg_europe.jpg" loading="lazy" src="/flower-garden-selected-as-an-apple-staff-favorite-across-europe/images/fg_europe.jpg">Right on the heels of the Mother&rsquo;s Day promotion, <a href="http://bit.ly/fg_gfw">Flower Garden</a> just got its <a href="/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/">second</a> ever App Store feature. This time it was selected as a Staff Favorite across most of Europe (UK, Spain, Ireland, Denmark, Finland, Greece, Netherlands, Norway, Portugal, Switzerland, and Sweden!).</p>
<p>And if you haven&rsquo;t picked up your <strong>free</strong> copy of Flower Garden, make sure to do it now. It will probably go back to full price after this weekend.</p>
<p>Gracias! Obrigado! Grazie! Î£Î±Ï‚ ÎµÏ…Ï‡Î±ÏÎ¹ÏƒÏ„ÏŽ! Tak!</p>
]]></content:encoded></item><item><title>Making A Living (Comfortably) On The App Store (aka The Numbers Post #2)</title><link>https://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/</link><pubDate>Fri, 14 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/making-a-living-comfortably-on-the-app-store/</guid><description>&lt;p&gt;A few months ago, I wrote &lt;a href="https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/"&gt;a post analyzing how Flower Garden had done since it was released&lt;/a&gt;. It was a story with lots of ups and downs, tales of trials and failure, but ending on a positive, optimistic note. It went on to become one of the most read posts in this blog, and the comments were all very encouraging. Clearly, people, and especially other developers, are hungry for this kind of data.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A few months ago, I wrote <a href="/making-a-living-barely-on-the-iphone-app-store/">a post analyzing how Flower Garden had done since it was released</a>. It was a story with lots of ups and downs, tales of trials and failure, but ending on a positive, optimistic note. It went on to become one of the most read posts in this blog, and the comments were all very encouraging. Clearly, people, and especially other developers, are hungry for this kind of data.</p>
<p>So here we go with the second part. How did Flower Garden fare after the new year? Was it just the Christmas purchasing frenzy that had a momentary effect on sales, or was there something more to it?</p>
<h2 id="recap-and-overview">Recap and Overview</h2>
<p>Here&rsquo;s where we left off last time. The unusual part was how profits increased as soon as I added in-app purchases to Flower Garden in early December. It made for a very atypical sales plot.</p>
<p><img alt="Full" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/Full.png" title="Flower Garden profit"></p>
<p>And here is how things look now. This plot includes the previous data so it&rsquo;s easier to contrast before and after. The area in blue is the new data since the last post.</p>
<p><img alt="fg_total.png" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/fg_total.png"></p>
<p>Just glancing at that chart makes it clear that that the increase around Christmas wasn&rsquo;t a fluke. It actually wasn&rsquo;t even done going up. After all the spikes, and the weekly ups and downs, Flower Garden ended up settling to about $1,500/week. And that, even in California, I would consider it to be a comfortable living. What a different from the $50/day it was making last year!</p>
<p>So what exactly happened there? Let&rsquo;s look at the new data in more detail.</p>
<p><img alt="fg_recent.png" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/fg_recent.png"></p>
<p>At a glance, there are three, very different sections.</p>
<h2 id="the-feature">The Feature</h2>
<p>The first one starts with a significant increase in sales (A), and is in large part due to <a href="/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/">being featured on the App Store worldwide as a Staff Favorite</a>. It&rsquo;s a nice spike, but it&rsquo;s nothing like the x10 spikes other developers have seen with App Store features. That&rsquo;s because the Staff Favorite slot, even though it&rsquo;s a very prestigious one, it does not appear on the iPhone, only on iTunes. I do all my browsing and shopping through iTunes, but apparently I&rsquo;m in the minority, so the effect on sales is greatly reduced.</p>
<p>That spike is also in part due to <a href="/making-a-living-barely-on-the-iphone-app-store/">my last &ldquo;numbers post&rdquo;</a>, which happened right at the same time (not completely accidentally). The page attracted about 15,000 views in a few days, so I&rsquo;m sure a few of them translated in people checking out Flower Garden out of curiosity.</p>
<h2 id="valentines-day">Valentine&rsquo;s Day</h2>
<p>The second spike isn&rsquo;t hard to guess: It&rsquo;s the weekend of February 14th, Valentine&rsquo;s Day. The more things happen at once and the more something is in the public eye, the more of an impact it has. PR people have known that for a long time, and it was really brought home for me back <a href="/making-a-living-barely-on-the-iphone-app-store/">in December</a>.</p>
<p>Fortunately, I managed to make quite a few things happen in the days leading to Valentine&rsquo;s Day weekend:</p>
<ul>
<li>I released an update with couple new in-app purchases: A new set of seeds (Seeds of Love), and a greenhouse garden, for $0.99 each.</li>
<li>I sent out a newsletter to the 25,000 subscribers to <a href="http://www.facebook.com/l.php?u=http%3A%2F%2Fymlp.com%2Fsignup.php%3Fid%3Dgemmyyugmgj&amp;h=cf570">the mailing list</a> announcing the new items.</li>
<li>I put Flower Garden on sale for $0.99 (down from the regular price of $2.99).</li>
<li>Several web sites, <a href="http://toucharcade.com/2010/02/14/valentines-day-picks-for-that-special-iphone-in-your-life/">including TouchArcade</a>, covered the sale and the new update, giving it lots of visibility.</li>
<li>Flower Garden Free was the free app for February 14th on the <a href="http://bit.ly/iPhoneValentine">Valentine&rsquo;s Day Calendar</a>.</li>
</ul>
<p>All of that combined to cause the big spike in profits (B). You really need to look at the first plot to put it in perspective. Two days in around Valentine&rsquo;s Day had higher profit than the initial release spike back in April of last year!</p>
<h2 id="winding-down">Winding Down</h2>
<p>Of course, everything that goes up, must eventually come down. So the weeks following Valentine&rsquo;s Day profits went rapidly down. It was at the very end of April that I started working on <a href="/dr-seuss-lorax-garden-up-the-charts/">Lorax Garden</a>, so for that period of time I wasn&rsquo;t able to do anything related to Flower Garden. For a while sales were dropping quite rapidly, but they eventually flattened out to about $1,500/week (C).</p>
<p>The good thing about having consumable items as in-app purchases (fertilizer in this case), is that profits are related to active user base, not just initial sales. So even though the amount of downloads decreased significantly during this time, the user base had grown a large amount, and with it, the daily profits.</p>
<h2 id="flower-garden-free">Flower Garden Free</h2>
<p>Back in December, there seemed to be a connection between the amount of downloads of the free version of Flower Garden and profits. They both picked up right around the time I added in-app purchases, although I was never able to tell if it was cause or consequence.</p>
<p>This is the amount of downloads of the free version for this period of time.</p>
<p><img alt="fg_free.png" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/fg_free.png"></p>
<p>It stays pretty regularly at about 800 downloads per day (which is not much compared to a lot of free versions out there), and has a massive spike on Valentine&rsquo;s Day (caused by word of mouth, lots of sent bouquets, and the <a href="http://bit.ly/iPhoneValentine">Valentine&rsquo;s Day Calendar</a>).</p>
<p>Notice that the App Store feature for Flower Garden (full version) in January had virtually no effect on downloads of the free version. It seems that people are willing to buy something full price without trying the free version first if Apple features it.</p>
<p>Both versions of Flower Garden (free and full) have in-app purchases in them. Even though there&rsquo;s a higher percentage of users with the full version that buy in-app purchases, the free version is much more popular and the majority of the revenue comes from the free version (orange). This is a tren that was already noticable around the holidays, but now is much more clear, with over 50% of the revenue coming from in-app purchases in the free version.</p>
<p><img alt="iap_profit.png" loading="lazy" src="/making-a-living-comfortably-on-the-app-store/images/iap_profit.png"></p>
<h2 id="the-future">The Future</h2>
<p>The data for this post stops at May 5th. That&rsquo;s because on May 6th I released a new set of seeds and <a href="/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/">gave Flower Garden away for free as part of the Mother&rsquo;s Day promotion</a>. As soon as the dust settles from that, I&rsquo;ll write a third post detailing how it turned out.</p>
]]></content:encoded></item><item><title>Going The iPad Way: All You Wanted to Know About Creating Universal Apps</title><link>https://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/</link><pubDate>Mon, 10 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/</guid><description>&lt;p&gt;&lt;img alt="flower_garden_ipad.jpg" loading="lazy" src="https://gamesfromwithin.com/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/flower_garden_ipad.jpg"&gt; It&amp;rsquo;s one thing to go on record saying &lt;a href="https://gamesfromwithin.com/figuring-out-the-ipad/"&gt;I wouldn&amp;rsquo;t be creating an iPad-specific version of Flower Garden&lt;/a&gt;, and another seeing the iPhone version running on an iPad with all the ugly jaggies and huge, pixelated text. So when it came time to do a new update, I decided to at least take advantage of the iPad capabilities to make the existing app prettier by making Flower Garden into a universal app. It&amp;rsquo;s &lt;a href="http://bit.ly/fg_gfw"&gt;now available on the App Store&lt;/a&gt;, so go get it and check it out!&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="flower_garden_ipad.jpg" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/flower_garden_ipad.jpg"> It&rsquo;s one thing to go on record saying <a href="/figuring-out-the-ipad/">I wouldn&rsquo;t be creating an iPad-specific version of Flower Garden</a>, and another seeing the iPhone version running on an iPad with all the ugly jaggies and huge, pixelated text. So when it came time to do a new update, I decided to at least take advantage of the iPad capabilities to make the existing app prettier by making Flower Garden into a universal app. It&rsquo;s <a href="http://bit.ly/fg_gfw">now available on the App Store</a>, so go get it and check it out!</p>
<p>Surprisingly, there wasn&rsquo;t that much documentation on how to go about making a universal iPhone/iPad version. There&rsquo;s <a href="http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html#//apple_ref/doc/uid/TP40009370-CH9-SW1">a document from Apple showing some initial steps</a>, but that&rsquo;s about it. So I wanted to share what I learned along the way, including some very useful tips I learned through trial and error or by doing a lot of digging through Twitter and the development forums.</p>
<p>Flower Garden is a <a href="/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/">strange hybrid of OpenGL and UIKit</a>, which made things more complicated than if it were just one or the other. Learning curve and all, it took two full days of my time. If you&rsquo;re using just OpenGL or just UIKit, the conversion to a universal app will be significantly faster.</p>
<h2 id="universal-project">Universal Project</h2>
<p>The first thing you need to do is understand what&rsquo;s going on with all the SDK versions. At this time, the latest iPhone OS version is 3.1.3, but you&rsquo;re going to be developing the universal app with SDK 3.2. You want the resulting binary to run on both 3.X OS on iPhones and 3.2 OS on iPad. It&rsquo;s a very similar situation to when we were <a href="/targeting-2-x-with-3-0-features-trouble-ahead/">writing apps that worked on both 3.X and 2.X</a>.</p>
<p>So fire up XCode 3.2.2 (yes, all those version numbers start getting very confusing&ndash;that&rsquo;s the XCode version that comes with SDK 3.2), and load your iPhone project you want to make into a universal one. If you look under the Project menu item, you&rsquo;ll see an entry called &ldquo;Upgrade Current Target For iPad&rdquo;. The Apple documentation even warns you not to create a universal app in any other way.</p>
<p>Go ahead and use it if you want. It will work&hellip; as long as you have a single target you want to convert. For some inexplicable reason <a href="#1">[1]</a>, it will only work once per project (even though it&rsquo;s phrased as working with whatever the current target is). When would you have more than one target executable? If you have a <a href="/from-full-to-lite-in-under-an-hour/">free and a paid version</a> for example.</p>
<p>Besides, I&rsquo;m uncomfortable with automated &ldquo;smart&rdquo; tools that do things behind my back without me knowing exactly what&rsquo;s going on, so I upgraded by hand by looking at the diffs of what the upgrade command did. It turns out it&rsquo;s extremely simple.</p>
<ol>
<li>Under the project properties, set your base SDK to 3.2.</li>
<li>Set Architectures to &ldquo;Optimized (arm6, arm7)&rdquo;</li>
<li>Uncheck &ldquo;Build Active Architectures Only&rdquo;
<img alt="proejct_settings_1.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/proejct_settings_1.png">5. In the Deployment section, set it to SDK 3.1.3 (or whatever 3.X you want to target)
<img alt="project_settings_2.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/project_settings_21.png"></li>
</ol>
<p>That&rsquo;s it, really. That&rsquo;s all you need to compile and run your app both on an iPhone and an iPad. When you build for the device, it will compile both arm6 and arm7 versions and create a combined fat executable with both. And yes, this means the size of your executable is going to double (which could be an issue if you&rsquo;re near the 20MB limit). In the case of Flower Garden, the combined executable is 3.4MB, so that&rsquo;s not a big deal.</p>
<h2 id="ipad-functionality">iPad Functionality</h2>
<p>What about that new xib file that the upgrade process creates? You don&rsquo;t really need it. It&rsquo;s there in case you want to have a different set of xibs for each platform, and it&rsquo;s hooked up to the info file so the app knows to load it at startup.</p>
<p><img alt="ib.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/ib.png">For the universal version of Flower Garden, I wasn&rsquo;t trying to make a whole new brand experience on the iPad. Instead, I was looking for a quick and easy way to make it look much better. Because of it, I decided to reuse the same xib files as for the iPhone version.</p>
<p>That meant I had to go in Interface Builder, and adjust the autosize properties for a lot of the views. Some of them I wanted to stretch and get bigger with the high resolution iPad screen (background views). Others, I wanted to leave at the same size, but remain at the same relative distance from a particular border (buttons). Some other ones, I left the same size and their position just scaled up with the resolution (info boxes). All in all, that was the most time-consuming part of the process. It also required a few tweaks here and there to support the resolution change correctly.</p>
<p>The other big change was updating the resolution of the 3D views. Fortunately, that was just worked without a single line change. The <a href="/opengl-and-uikit-demo/">render target code</a> I&rsquo;m using, takes the view dimensions and creates a frame buffer of the correct size. And it&rsquo;s not just the dimensions: Remember that the iPad has a different aspect ratio (grumble, grumble), so you need to make sure your perspective and orthographic projections take that into account.</p>
<p>The only other changes I had to make was supporting an upside-down portrait orientation. That was very easy because the frame buffer didn&rsquo;t have to change. Make sure you support it both at launch time and during gameplay. If you have a root controller whose view is attached directly to the main window from the start, it&rsquo;s as easy as adding this to your controller:</p>
<pre tabindex="0"><code>- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait ||
            interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
</code></pre><p>And make sure you add the supported orientations to your plist.</p>
<p><img alt="plist.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/plist.png"></p>
<p>Finally, before you submit it to the App Store, you&rsquo;ll need an iPad-specific icon. The documentation explains how to explicitly list all the icons in the info file, but at the very least, you can provide a file called Icon-72.png that is a 72x72 image and you&rsquo;re done.</p>
<h2 id="running-on-the-simulator">Running On The Simulator</h2>
<p>This is one that should be a lot easier than it is. You&rsquo;re creating a universal binary with SDK 3.2. Now you want to run it on the simulator. No problem, you run it as usual and you get the iPad simulator. You can debug it and do everything you normally do.</p>
<p>Now you want to run it on the simulator on iPhone mode. It turns out, that&rsquo;s not so obvious.</p>
<p>You can&rsquo;t just turn the simulator hardware setting to iPhone, because whenever you launch it from XCode it will override that again with the iPad one. Building and running on the 3.1.3 SDK is a no-no because you&rsquo;re really running a different build than you&rsquo;re going to be submitting (3.2) and all 3.2 SDK features you&rsquo;re using are going to result in compile errors.</p>
<p>So after much searching and tweeting, here&rsquo;s the solution:</p>
<ul>
<li>Build for 3.2 SDK on the simulator platform.</li>
<li>Change project drop-down to 3.1.3 SDK
<img alt="sdk_version.png" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/sdk_version.png">- Launch with debugger (Cmd + Options + Y). Don&rsquo;t build and run!</li>
</ul>
<p>That will launch the simulator on iPhone mode, but still run your 3.2 build. Talk about unintuitive! <a href="#2">[2]</a>. The worst thing is, when you&rsquo;re done, you need to switch the project to 3.2 again or you&rsquo;ll get tons of compiler errors. That definitely has to go for SDK 4.0.</p>
<p>Here&rsquo;s an invaluable tip. Maybe it&rsquo;s obvious to long-term Mac users, but it baffled me for a while. The iPad simulator is very well thought out, and it has a 100% and a 50% mode. That makes it possible to use the simulator on screens without very high resolution. Even my external monitor at 1680x1050 can&rsquo;t display the iPad simulator at full 1024x768 resolution in portrait mode because of the window borders.</p>
<p>The problem comes in when you want to take a screenshot to add to the App Store or anything else. On the iPhone simulator it was easy, but how do you do that with the iPad since you can&rsquo;t fit it on the screen? Cmd + Ctrl + C will take a screenshot <strong>at full resolution</strong> even when running at 50% mode and add it to the clipboard! Switch over to Preview and select New from Clipboard and voila! Full resolution screenshot!</p>
<h2 id="sdk-32-features">SDK 3.2 Features</h2>
<p>Chances are that even if you do a simple iPad port, you&rsquo;re going to end up using a few 3.2 features. The main one I used in the case of Flower Garden is a UIPopoverController. Here you should follow the steps outlined in the Apple documentation down to a T. But it comes down to this: If a symbol that is defined on 3.2 appears anywhere, even as a member pointer variable in a class, it will compile and run on the iPad fine, but will crash and burn on the iPhone.</p>
<p>So you need to both check that the 3.2 features are available, and you need to &ldquo;hide&rdquo; the new symbol so it never appears anywhere: Use an id variable and cast it based on the class info. Even casting it directly to the symbol you want will cause a crash.</p>
<pre tabindex="0"><code>Class classPopoverController = NSClassFromString(@&#34;UIPopoverController&#34;);
if (classPopoverController)
{
    m_moreGamesPopover = [[classPopoverController alloc] initWithContentViewController:moreGames]; 
    [m_moreGamesPopover setDelegate:self];
    [m_moreGamesPopover setPopoverContentSize:CGSizeMake(320, moreGamesHeight) animated:NO];
    [m_moreGamesPopover presentPopoverFromRect:m_moreGamesButton.frame inView:self.view
                        permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
</code></pre><p>Not pretty, uh? It works, but I couldn&rsquo;t imagine doing this all over the place.</p>
<h2 id="gotchas">Gotchas</h2>
<p>In the process of creating a universal app, I found a couple more things to watch out for.</p>
<p>When you submit the new binary through iTunes Connect and it&rsquo;s accepted, the application status will change to something like &ldquo;Missing screenshot&rdquo;. If you go back and edit the app information, you&rsquo;ll see there&rsquo;s a new set of screenshots you can submit. You&rsquo;ll need at least one for your application to enter &ldquo;Waiting for Review&rdquo; state. And if you have localized descriptions of your app, you&rsquo;ll need to do that for every language.</p>
<p>Last, and perhaps most puzzling because I never figured this one out: I was not able to get in-app purchases to work with a test account from a development version of a universal app running on the iPad. I must have tried everything, but whenever I tried purchasing anything, it never brought up the familiar &ldquo;sandbox environment&rdquo; message. Also, items that hadn&rsquo;t been approved yet did not show up in the list of available items. The exact same code worked fine on an iPhone, so that&rsquo;s quite puzzling. Is it a major bug on Apple&rsquo;s part, or did I miss some obscure &ldquo;enable IAPs in debug mode&rdquo; checkbox somewhere? It was a bit of a gamble submitting it like that, but fortunately, the approved version on the App Store allows in-app purchases without any problem.</p>
<p>I thought afterwards that maybe that was because the app version on the App Store was no universal, so the Store Kit server was not allowing the iPad version to access the store through the test account. But I tried it again even after it was approved and I had the same problem.</p>
<p>Has anybody managed to use an App Store test account from an iPad on a universal app?</p>
<h2 id="conclusion">Conclusion</h2>
<p>All in all, it was a relatively painless process considering it&rsquo;s different hardware, with a different resolution, and it&rsquo;s the first iteration of the SDK. Was it worth it? I think so. Apart from looking a lot better on an iPad, universal apps get ranked on both iPhone and iPad charts. Flower Garden managed to get all the way up to #14 on the free games chart on the iPad (and around #60 free app overall on the iPad). I&rsquo;m sure it got some exposure from being so high up, which in turn helped the iPhone rankings as well.</p>
<p>I can&rsquo;t imagine that my next game is going to be iPad-only, but I&rsquo;ll certainly have the iPad in mind from the beginning and release it on both platforms. Whether I choose to go universal or separate apps will depend on the game and business decisions, but at least it&rsquo;s good to know that it&rsquo;s fairly easy to create a universal app.</p>
<p><img alt="flower_garden_ipad_charts.jpg" loading="lazy" src="/going-the-ipad-way-all-you-wanted-to-know-about-creating-universal-apps/images/flower_garden_ipad_charts.jpg"></p>
<p>[1] Actually, there&rsquo;s a pattern that is clear by looking at the hoops we have to jump to do a universal build: Apple was clearly scrambling to get this out the door. As a result, things are buggy, unintuitive, and clunky. Hopefully all that will be fixed for SDK 4.0.</p>
<p>[2] See? That confirms point <a href="#1">[1]</a>.</p>
]]></content:encoded></item><item><title>Flower Garden Is Free This Weekend To Celebrate Mother's Day!</title><link>https://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/</link><pubDate>Sat, 08 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/</guid><description>&lt;p&gt;&lt;img alt="Icon-128x128.png" loading="lazy" src="https://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/images/Icon-128x128.png"&gt;&lt;img alt="flower_shop.jpg" loading="lazy" src="https://gamesfromwithin.com/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/images/flower_shop.jpg"&gt;Since this Sunday is Mother&amp;rsquo;s Day (in the US at least), I&amp;rsquo;m making &lt;a href="http://freeappcalendar.com/details.php?id=159"&gt;Flower Garden &lt;strong&gt;FREE&lt;/strong&gt; for the weekend&lt;/a&gt;. Yes, that&amp;rsquo;s right, completely free!&lt;/p&gt;
&lt;p&gt;Am I going crazy? Giving away the fruit of my labor for so many months? The App Store will do that to people, but this is a bit more sane. The idea is to encourage many more people to try it out. I&amp;rsquo;m actually hoping some of them will like it so much, they&amp;rsquo;ll buy a few of the in-app purchases from the Flower Shop. And even if they don&amp;rsquo;t, hopefully they&amp;rsquo;ll spread the (good) word about Flower Garden and they might also sign up for the mailing list. And in this business, expanding your user base is a great strategy that can be leveraged for future projects.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Icon-128x128.png" loading="lazy" src="/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/images/Icon-128x128.png"><img alt="flower_shop.jpg" loading="lazy" src="/flower-garden-is-free-this-weekend-to-celebrate-mothers-day/images/flower_shop.jpg">Since this Sunday is Mother&rsquo;s Day (in the US at least), I&rsquo;m making <a href="http://freeappcalendar.com/details.php?id=159">Flower Garden <strong>FREE</strong> for the weekend</a>. Yes, that&rsquo;s right, completely free!</p>
<p>Am I going crazy? Giving away the fruit of my labor for so many months? The App Store will do that to people, but this is a bit more sane. The idea is to encourage many more people to try it out. I&rsquo;m actually hoping some of them will like it so much, they&rsquo;ll buy a few of the in-app purchases from the Flower Shop. And even if they don&rsquo;t, hopefully they&rsquo;ll spread the (good) word about Flower Garden and they might also sign up for the mailing list. And in this business, expanding your user base is a great strategy that can be leveraged for future projects.</p>
<p>The idea of giving away a free app isn&rsquo;t anything new. There are whole sites like <a href="http://freeappcalendar.com">FreeAppCalendar</a> dedicated to doing exactly that, and other developers, like <a href="http://nimblebit.com">NimbleBit</a> have been doing that on and off very successfully to reach a wider audience with their games.</p>
<p>How will it work out? I don&rsquo;t know yet, but Flower Garden is quickly going up the charts even early on Saturday. It&rsquo;s currently in the top 50 free apps in Japan, and about to get in the top 10 kids games in the US, so it&rsquo;s looking good.</p>
<p>If you haven&rsquo;t picked it up yet, this is the time. And if you have, make sure you tell your friends and family to download it and check it out before it goes back to the regular price. I&rsquo;ll report back on the results of this promotion in a few days.</p>
]]></content:encoded></item><item><title>Dr. Seuss Lorax Garden Up The Charts</title><link>https://gamesfromwithin.com/dr-seuss-lorax-garden-up-the-charts/</link><pubDate>Sun, 02 May 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/dr-seuss-lorax-garden-up-the-charts/</guid><description>&lt;p&gt;&lt;img alt="LoraxGarden.jpg" loading="lazy" src="https://gamesfromwithin.com/dr-seuss-lorax-garden-up-the-charts/images/LoraxGarden.jpg"&gt;If you follow this blog regularly you&amp;rsquo;ve probably noticed that there&amp;rsquo;s been a kind of blackout period. I hardly posted during the last couple of months. What happened? &lt;a href="http://bit.ly/iphoneloraxgarden"&gt;Lorax Garden&lt;/a&gt; is what happened.&lt;/p&gt;
&lt;p&gt;In late February I agreed to collaborate with &lt;a href="http://www.oceanhousemedia.com/products/"&gt;Oceanhouse Media&lt;/a&gt; on a game project. They had the &lt;a href="http://www.oceanhousemedia.com/products/drseuss/"&gt;Dr. Seuss license&lt;/a&gt; and I had &lt;a href="http://www.snappytouch.com/flowergarden/"&gt;the flowers&lt;/a&gt;. Perfect match for a Lorax-themed game! And so the &lt;a href="http://bit.ly/iphoneloraxgarden"&gt;Lorax Garden&lt;/a&gt; was born.&lt;/p&gt;
&lt;p&gt;I was originally hoping to write some entries here on the progress of the game as I worked on it, but I quickly realized that I wouldn&amp;rsquo;t have any spare time for anything other than the project. We wanted to have the Lorax Garden (and &lt;a href="http://bit.ly/iphonelorax"&gt;the Lorax book app&lt;/a&gt;) on the App Store by &lt;a href="http://www.earthday.org/earthday2010"&gt;Earth Day&lt;/a&gt; (April 20th), so that left us with a very aggressive 5-week schedule (and GDC somewhere in the middle!). Fortunately, we managed to hit our deadline, and you can see the results today by yourself by &lt;a href="http://bit.ly/iphoneloraxgarden"&gt;downloading it from the App Store&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="LoraxGarden.jpg" loading="lazy" src="/dr-seuss-lorax-garden-up-the-charts/images/LoraxGarden.jpg">If you follow this blog regularly you&rsquo;ve probably noticed that there&rsquo;s been a kind of blackout period. I hardly posted during the last couple of months. What happened? <a href="http://bit.ly/iphoneloraxgarden">Lorax Garden</a> is what happened.</p>
<p>In late February I agreed to collaborate with <a href="http://www.oceanhousemedia.com/products/">Oceanhouse Media</a> on a game project. They had the <a href="http://www.oceanhousemedia.com/products/drseuss/">Dr. Seuss license</a> and I had <a href="http://www.snappytouch.com/flowergarden/">the flowers</a>. Perfect match for a Lorax-themed game! And so the <a href="http://bit.ly/iphoneloraxgarden">Lorax Garden</a> was born.</p>
<p>I was originally hoping to write some entries here on the progress of the game as I worked on it, but I quickly realized that I wouldn&rsquo;t have any spare time for anything other than the project. We wanted to have the Lorax Garden (and <a href="http://bit.ly/iphonelorax">the Lorax book app</a>) on the App Store by <a href="http://www.earthday.org/earthday2010">Earth Day</a> (April 20th), so that left us with a very aggressive 5-week schedule (and GDC somewhere in the middle!). Fortunately, we managed to hit our deadline, and you can see the results today by yourself by <a href="http://bit.ly/iphoneloraxgarden">downloading it from the App Store</a>.</p>
<p>It was very interesting starting a totally new project from the existing Flower Garden codebase. I had to add some new flower-tech to make flowers more Seussian (curvy, uneven) and make Truffula Trees. Lorax Garden has a definite game structure and progression, so all the game code was completely new. It even has a flower-growing minigame to earn extra care hearts. All that had to be created by ripping out Flower Garden code and writing new one. It was a pleasure to see how easy it was to reuse all the flower-tech code that was well isolated and tested from the beginning though.</p>
<p><img alt="LoraxGardenScreenshot.jpg" loading="lazy" src="/dr-seuss-lorax-garden-up-the-charts/images/LoraxGardenScreenshot.jpg"></p>
<p>The Lorax Garden is currently featured by Apple on the App Store, and <a href="http://bit.ly/iphoneloraxgarden">it&rsquo;s on sale for $0.99</a> (down from the regular price of $2.99). All of that combined with a strong launch and mentions on <a href="http://www.usatoday.com/tech/columnist/jinnygudmundsen/2010-04-29-kid-apps-ipad_N.htm">USA Today</a> and <a href="http://appmodo.com/18108/lorax-garden-app-review-bring-the-trees-back/">other media outlets</a> have brought it up to the #39 (edit: #37!) paid app overall in the US App Store charts. A fantastic result, and with any luck it will continue climbing for another day or two.</p>
<p><img alt="LoraxGardenFeatured.png" loading="lazy" src="/dr-seuss-lorax-garden-up-the-charts/images/LoraxGardenFeatured.png"></p>
]]></content:encoded></item><item><title>OpenGL And UIKit Demo</title><link>https://gamesfromwithin.com/opengl-and-uikit-demo/</link><pubDate>Sat, 10 Apr 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/opengl-and-uikit-demo/</guid><description>&lt;p&gt;&lt;img alt="uikit_demo.png" loading="lazy" src="https://gamesfromwithin.com/opengl-and-uikit-demo/images/uikit_demo.png"&gt;This coming Monday I&amp;rsquo;ll be giving a presentation at &lt;a href="http://360idev.com"&gt;360iDev&lt;/a&gt; titled &amp;ldquo;All You Wanted To Know About Mixing OpenGL with UIKit (And More)&amp;rdquo;. It&amp;rsquo;s an extended version of &lt;a href="https://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/"&gt;my talk&lt;/a&gt; at this year&amp;rsquo;s &lt;a href="http://www.gdconf.com/conference/iphone.html"&gt;GDC iPhone Summit&lt;/a&gt;. It&amp;rsquo;s going to be 1h 20min long instead of just half an hour.&lt;/p&gt;
&lt;p&gt;The main difference is that I&amp;rsquo;m going to go in detail about each of the different cases of mixing OpenGL and UIKit, and what better way to do that than with a live demo. I&amp;rsquo;ll be switching back and forth between Keynote and XCode and going over the details, which is where a lot of the tricky parts are.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="uikit_demo.png" loading="lazy" src="/opengl-and-uikit-demo/images/uikit_demo.png">This coming Monday I&rsquo;ll be giving a presentation at <a href="http://360idev.com">360iDev</a> titled &ldquo;All You Wanted To Know About Mixing OpenGL with UIKit (And More)&rdquo;. It&rsquo;s an extended version of <a href="/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/">my talk</a> at this year&rsquo;s <a href="http://www.gdconf.com/conference/iphone.html">GDC iPhone Summit</a>. It&rsquo;s going to be 1h 20min long instead of just half an hour.</p>
<p>The main difference is that I&rsquo;m going to go in detail about each of the different cases of mixing OpenGL and UIKit, and what better way to do that than with a live demo. I&rsquo;ll be switching back and forth between Keynote and XCode and going over the details, which is where a lot of the tricky parts are.</p>
<p><a href="/wp-content/uploads/2010/04/OpenGLUIKit.zip" title="OpenGLUIKit.zip">Here is the source code for the demo</a>. That way you can look at it now and come to the session prepared with more questions, or ready to discuss what works and what doesn&rsquo;t work for you. I love to have interactive sessions, so definitely come ready to ask questions.</p>
<p>If you&rsquo;re not coming to 360iDev&hellip; shame on you! It&rsquo;s the best iPhone conference around. You&rsquo;ll be missing not just my session, but tons of other great talks, and the <a href="http://iphonegamejam.com">iPhone Game Jam</a> (sponsored by <a href="http://toucharcade.com">TouchArcade</a> this year). If you can&rsquo;t make it this time, make a note on your calendar for next time!</p>
<ul>
<li><a href="/wp-content/uploads/2010/04/OpenGLUIKit.zip" title="OpenGLUIKit.zip">Demo source code</a>. Released under the MIT license.</li>
</ul>
]]></content:encoded></item><item><title>GDC 2010: The Best of Both Worlds: Using UIKit with OpenGL</title><link>https://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/</link><pubDate>Sat, 13 Mar 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/</guid><description>&lt;p&gt;&lt;img alt="borg-701632.jpg" loading="lazy" src="https://gamesfromwithin.com/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/images/borg-701632.jpg"&gt;Here are the slides for my session at the &lt;a href="http://www.gdconf.com/conference/iphone.html"&gt;GDC iPhone Summit&lt;/a&gt;, &lt;a href="https://www.cmpevents.com/GD10/a.asp?option=C&amp;amp;V=11&amp;amp;SessID=10541"&gt;The Best of Both Worlds: Using UIKit With OpenGL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It was a 30-minute slot, so the material is pretty condensed without the chance to expand on the topics. I&amp;rsquo;m giving an extended version of this talk at &lt;a href="http://www.360idev.com/"&gt;360iDev&lt;/a&gt; in a few weeks, so I&amp;rsquo;ll be able to get into more details then and have a cool sample app that shows off all those concepts.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="borg-701632.jpg" loading="lazy" src="/gdc-2010-the-best-of-both-worlds-using-uikit-with-opengl/images/borg-701632.jpg">Here are the slides for my session at the <a href="http://www.gdconf.com/conference/iphone.html">GDC iPhone Summit</a>, <a href="https://www.cmpevents.com/GD10/a.asp?option=C&amp;V=11&amp;SessID=10541">The Best of Both Worlds: Using UIKit With OpenGL</a>.</p>
<p>It was a 30-minute slot, so the material is pretty condensed without the chance to expand on the topics. I&rsquo;m giving an extended version of this talk at <a href="http://www.360idev.com/">360iDev</a> in a few weeks, so I&rsquo;ll be able to get into more details then and have a cool sample app that shows off all those concepts.</p>
<p>It was great seeing a bunch of you at my session and at around the iPhone and Indie Summits. It was a great couple of days!</p>
<ul>
<li><a href="http://www.slideshare.net/llopis/the-best-of-both-worlds-mixing-uikit-with-opengl">Presentation slides</a> (<a href="/wp-content/uploads/2010/03/GDC10_uikit_opengl.pdf">pdf format</a>)</li>
<li><a href="/opengl-and-uikit-demo/">Sample code</a></li>
</ul>
]]></content:encoded></item><item><title>GDC Time!</title><link>https://gamesfromwithin.com/gdc-time/</link><pubDate>Sun, 07 Mar 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-time/</guid><description>&lt;p&gt;&lt;img alt="GDCbug_2010_200x200.jpg" loading="lazy" src="https://gamesfromwithin.com/gdc-time/images/GDCbug_2010_200x200.jpg"&gt;It&amp;rsquo;s that time of the year when all the &lt;a href="http://gdconf.com"&gt;games industry converges on San Francisco&lt;/a&gt;. Even though this is my 12th GDC (in a row, no less), and the conference has grown and matured a lot, it still feels as exciting as the first one.&lt;/p&gt;
&lt;p&gt;This year will GDC will host the &lt;a href="http://www.gdconf.com/conference/iphone.html"&gt;first ever iPhone Summit&lt;/a&gt; on Tuesday and Wednesday. It&amp;rsquo;s great to see the iPhone getting that much recognition as a gaming platform. Definitely way more than last year&amp;rsquo;s presence at the conference. Both days are going to be packed with awesome sessions, and I will be giving a presentation on &lt;a href="https://www.cmpevents.com/GD10/a.asp?option=C&amp;amp;V=11&amp;amp;SessID=10541"&gt;mixing OpenGL and UIKit on Tuesday at 11:15am&lt;/a&gt;. I&amp;rsquo;ll definitely be around throughout all the summit (except when I sneak out for a few minutes over to the &lt;a href="http://www.gdconf.com/conference/igs.html"&gt;Indie Summit&lt;/a&gt; which unfortunately happens at the same time).&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="GDCbug_2010_200x200.jpg" loading="lazy" src="/gdc-time/images/GDCbug_2010_200x200.jpg">It&rsquo;s that time of the year when all the <a href="http://gdconf.com">games industry converges on San Francisco</a>. Even though this is my 12th GDC (in a row, no less), and the conference has grown and matured a lot, it still feels as exciting as the first one.</p>
<p>This year will GDC will host the <a href="http://www.gdconf.com/conference/iphone.html">first ever iPhone Summit</a> on Tuesday and Wednesday. It&rsquo;s great to see the iPhone getting that much recognition as a gaming platform. Definitely way more than last year&rsquo;s presence at the conference. Both days are going to be packed with awesome sessions, and I will be giving a presentation on <a href="https://www.cmpevents.com/GD10/a.asp?option=C&amp;V=11&amp;SessID=10541">mixing OpenGL and UIKit on Tuesday at 11:15am</a>. I&rsquo;ll definitely be around throughout all the summit (except when I sneak out for a few minutes over to the <a href="http://www.gdconf.com/conference/igs.html">Indie Summit</a> which unfortunately happens at the same time).</p>
<p>The rest of the conference looks amazing as usual. There are always way more talks that I want to see than I can actually attend. In particular, I&rsquo;m really looking forward to a lot of the design talks because they&rsquo;re very inspiring and directly applicable to any kind of game development. Also, rumor has it I might be making a quick guest appearance in a certain session on Saturday.</p>
<p>Finally, if you&rsquo;re an iPhone developer, make sure to come to the <a href="http://forums.toucharcade.com/showpost.php?p=894892&amp;postcount=14">IDU party on Wednesday evening</a>, and meet us for <a href="http://twitter.com/SnappyTouch/status/9833358335">drinks on Thursday evening</a> after the IGF ceremony.</p>
<p>I&rsquo;ll be running around with a busy schedule, but you can always <a href="http://twitter.com/snappytouch">follow my Twitter updates</a> to know where I&rsquo;m at every moment. I look forward to seeing everybody again this year!</p>
]]></content:encoded></item><item><title>Flower Garden a Finalist for The 2010 Pocket Gamer Awards for Most Innovative Game!</title><link>https://gamesfromwithin.com/flower-garden-a-finalist-for-the-2010-pocket-gamer-awards-for-most-innovative-game/</link><pubDate>Wed, 03 Mar 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-a-finalist-for-the-2010-pocket-gamer-awards-for-most-innovative-game/</guid><description>&lt;p&gt;&lt;a href="http://www.pocketgamer.co.uk/r/Various/Pocket%20Gamer%20Awards/feature.asp?c=17875"&gt;&lt;img alt="10AF654B-A6A5-4C29-BE46-D58B3A09BAEA.jpg" loading="lazy" src="https://gamesfromwithin.com/flower-garden-a-finalist-for-the-2010-pocket-gamer-awards-for-most-innovative-game/images/10AF654B-A6A5-4C29-BE46-D58B3A09BAEA.jpg"&gt;&lt;/a&gt;Pocket Gamer just announced the finalists for the &lt;a href="http://www.pocketgamer.co.uk/r/Various/Pocket%20Gamer%20Awards/feature.asp?c=17875"&gt;2010 Pocket Gamer Awards&lt;/a&gt;. I was thrilled to see that Flower Garden has been selected as a finalist for the Most Innovative iPhone Game award.&lt;/p&gt;
&lt;p&gt;On a personal level, this nomination means quite a bit for me. Flower Garden has gotten &lt;a href="http://fingergaming.com/2009/04/24/review-flower-garden/"&gt;some&lt;/a&gt; &lt;a href="http://theportablegamer.com/2009/04/iphone-review-flower-garden/"&gt;great&lt;/a&gt; &lt;a href="http://www.pocketgamer.co.uk/r/iPhone/Flower+Garden/review.asp?c=12825"&gt;reviews&lt;/a&gt;, and some incredible user feedback, and it was even featured as an &lt;a href="https://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/"&gt;Apple Staff Favorite on the App Store&lt;/a&gt;, but it had never been up for an award of this importance.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="http://www.pocketgamer.co.uk/r/Various/Pocket%20Gamer%20Awards/feature.asp?c=17875"><img alt="10AF654B-A6A5-4C29-BE46-D58B3A09BAEA.jpg" loading="lazy" src="/flower-garden-a-finalist-for-the-2010-pocket-gamer-awards-for-most-innovative-game/images/10AF654B-A6A5-4C29-BE46-D58B3A09BAEA.jpg"></a>Pocket Gamer just announced the finalists for the <a href="http://www.pocketgamer.co.uk/r/Various/Pocket%20Gamer%20Awards/feature.asp?c=17875">2010 Pocket Gamer Awards</a>. I was thrilled to see that Flower Garden has been selected as a finalist for the Most Innovative iPhone Game award.</p>
<p>On a personal level, this nomination means quite a bit for me. Flower Garden has gotten <a href="http://fingergaming.com/2009/04/24/review-flower-garden/">some</a> <a href="http://theportablegamer.com/2009/04/iphone-review-flower-garden/">great</a> <a href="http://www.pocketgamer.co.uk/r/iPhone/Flower+Garden/review.asp?c=12825">reviews</a>, and some incredible user feedback, and it was even featured as an <a href="/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/">Apple Staff Favorite on the App Store</a>, but it had never been up for an award of this importance.</p>
<p>It&rsquo;s also the category that it was nominated for. It makes me really proud that it was nominated for Most Innovative Game, because one of my original goals was to create something unique and original.</p>
<p>Finally, these awards are particularly meaningful because they&rsquo;re not based on popularity, sales, or voting, which are bound to bias awards towards best-selling titles. Instead, these finalists were hand-picked by the editors of Pocket Gamer. With the crazy amount of good apps out there, it really is an honor that they selected Flower Garden as one of the top 5 for 2009.</p>
<p>Thank you, Pocket Gamer!</p>
]]></content:encoded></item><item><title>Figuring Out The iPad</title><link>https://gamesfromwithin.com/figuring-out-the-ipad/</link><pubDate>Thu, 28 Jan 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/figuring-out-the-ipad/</guid><description>&lt;p&gt;Everybody was buzzing with excitement yesterday morning. A flurry of Twitter comments scrolled by all throughout the morning and the afternoon. You could taste the &lt;a href="http://www.apple.com/ipad/"&gt;iPad&lt;/a&gt; in the air (OK, almost).&lt;/p&gt;
&lt;p&gt;Shortly after the &lt;a href="http://events.apple.com.edgesuite.net/1001q3f8hhr/event/index.html"&gt;unveiling&lt;/a&gt;, people divided themselves in to two camps: &lt;a href="http://gizmodo.com/5458382/8-things-that-suck-about-the-ipad"&gt;the iPad haters&lt;/a&gt;, and &lt;a href="http://iphonedevelopment.blogspot.com/2010/01/gizmodo-knows-about-sucking-apparently.html"&gt;the iPad defenders&lt;/a&gt;. Each of them was intent in convincing the other camp that their view is the right one. Just like most of the pointless human conflict over the last two thousand years minus the bloody wars part.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Everybody was buzzing with excitement yesterday morning. A flurry of Twitter comments scrolled by all throughout the morning and the afternoon. You could taste the <a href="http://www.apple.com/ipad/">iPad</a> in the air (OK, almost).</p>
<p>Shortly after the <a href="http://events.apple.com.edgesuite.net/1001q3f8hhr/event/index.html">unveiling</a>, people divided themselves in to two camps: <a href="http://gizmodo.com/5458382/8-things-that-suck-about-the-ipad">the iPad haters</a>, and <a href="http://iphonedevelopment.blogspot.com/2010/01/gizmodo-knows-about-sucking-apparently.html">the iPad defenders</a>. Each of them was intent in convincing the other camp that their view is the right one. Just like most of the pointless human conflict over the last two thousand years minus the bloody wars part.</p>
<p>Of course, I felt the same way. As a consumer, I was very disappointed by the lack of video camera and the non-widescreen form factor. But I stepped back and realized that the iPad is here, and it is what it is. All the wishing and convincing in the world isn&rsquo;t going to make a difference. The platform is here to stay, and with Apple&rsquo;s genius behind it, I&rsquo;m sure it&rsquo;s going to be anywhere from &ldquo;moderately successful&rdquo; to &ldquo;a huge success&rdquo;.</p>
<p>The only question to answer as a developer is, how can I make the most out of the iPad? And for that, we need to understand what the iPad is.</p>
<p><img alt="apple-ipad-5.jpg" loading="lazy" src="/figuring-out-the-ipad/images/apple-ipad-5.jpg"></p>
<p>There&rsquo;s been a lot of talk on the <a href="http://www.apple.com/ipad/specs/">iPad specs</a>: 1024x768 resolution, a custom <a href="http://www.engadget.com/2010/01/28/apples-a4-is-an-arm-based-system-on-a-chip-a-la-tegra-2/">A4 chipset</a> including a CPU and a modern GPU, etc. But those are just dry facts about the hardware. They will be crucial things to keep in mind to develop for the iPad, but they don&rsquo;t help us that much understanding it.</p>
<p>Some people are claiming <a href="http://mactipspodcast.com/ipad1/">the iPad is a large iPod Touch</a>, but I think that nothing could be further from the truth.</p>
<p>Precisely because the iPad is larger, it&rsquo;s not a device you&rsquo;re going to carry in your pocket. It&rsquo;s something that&rsquo;s going to be laying on your desk, or piled on top of a few books on the coffee table. And that changes everything.</p>
<p>Whereas on the iPhone/iPod Touch users could use an app for a few seconds or minutes during the day, the iPad is going to encourage longer sessions, just once or twice a day. The kind of apps, and in particular the kind of games that are going to be well suited to the iPad are going to be much more than a higher-resolution iPhone game. For the most part, they&rsquo;re going to be totally different genres.</p>
<p>For example, <a href="http://itunes.apple.com/us/app/civilization-revolution/id324563544?mt=8">Civilization</a> never made much sense for me on the iPhone, but it now becomes a perfect iPad game. On the other hand, <a href="http://itunes.apple.com/us/app/flower-garden-free-grow-flowers/id327466677?mt=8">Flower Garden</a>, was designed from the beginning to have multiple, short sessions throughout the day, so it will make very little sense as an iPad game. I suppose that makes me one of the first developers going on record saying I&rsquo;m not going to port my existing iPhone app to the iPad :-)</p>
<p>The differences with the iPod Touch go beyond how frequently people use it. For example, games controlled by tilt are going to be restricted to a more hard core audience. Someone who really wants to sit down and spin the iPad around like a driving wheel controlling a car. Casual users will be less likely to grab the iPad and play a quick game of <a href="http://itunes.apple.com/us/app/scoops-ice-cream-fun-for-everyone/id291591378?mt=8">Scoops</a> or <a href="http://itunes.apple.com/us/app/doodle-jump-be-warned-insanely/id307727765?mt=8">Doodle Jump</a> because it&rsquo;s going to feel like a bigger deal than slightly tilting the iPhone in your hand.</p>
<p>The target demographic for the iPad is very different than the iPhone and iPod Touch. It will appeal mostly to people in their 30s and older, whereas the iPod Touch is really spreading on the younger demographic of middle and even elementary school. That will also radically change the kind of apps and games people will play on the iPad.</p>
<p>So it&rsquo;s clear that the iPad is not a large iPod Touch, and it doesn&rsquo;t pretend to replace it. That&rsquo;s a key point. Instead of replacing it, us as developers should think about it as complementing the iPhone and iPod Touch. The kind of experience I expect from the ideal iPad application is one that lets me access the same data set or game state I was using with my iPhone during the day. Maybe I&rsquo;ll put up with the iPhone interface to play some Civilization while I&rsquo;m commuting to work, but I expect to come back home, sit down on the couch, pick up my iPad and continue the same game with a much better interface. So we&rsquo;re going to see a trend towards more apps and games that store all their state in the server, and let you access it from any device.</p>
<p>The older demographic, deeper games, and server integration, combined with a higher-resolution screen is going to make people expect a more polished experience, and development costs are going to increase significantly. It&rsquo;s definitely a new challenge in a market that&rsquo;s ever changing, and whoever figures it out will have a good chance to have an early iPad hit in their hands.</p>
]]></content:encoded></item><item><title>Buy Flower Garden This Wednesday To Help Haiti</title><link>https://gamesfromwithin.com/buy-flower-garden-this-wednesday-to-help-haiti/</link><pubDate>Tue, 19 Jan 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/buy-flower-garden-this-wednesday-to-help-haiti/</guid><description>&lt;p&gt;As part of &lt;a href="http://www.indierelief.com/"&gt;Indie+Relief&lt;/a&gt;, all proceeds from &lt;a href="http://click.linksynergy.com/fs-bin/stat?id=aDkhM0mDflg&amp;amp;offerid=146261&amp;amp;u1=st_fg&amp;amp;type=3&amp;amp;subid=0&amp;amp;tmpid=1826&amp;amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252FWebObjects%252FMZStore.woa%252Fwa%252FviewSoftware%253Fid%253D311265471%2526mt%253D8%2526uo%253D6%2526partnerId%253D30"&gt;Flower Garden&lt;/a&gt; this Wednesday will be donated to Haiti through &lt;a href="http://www.msf.ca//"&gt;Doctors Without Borders&lt;/a&gt;. Encourage your friends to buy Flower Garden for a good cause! That includes in-app purchases, so feel free to load up on fertilizer :-)&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve already purchased Flower Garden and you&amp;rsquo;d still like to help out, you can check out &lt;a href="http://www.indierelief.com"&gt;the great lineup of Mac and iPhone apps at Indie+Relief&lt;/a&gt;, or &lt;a href="http://www.msf.ca/donate/"&gt;donate directly to Doctors Without Borders here&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>As part of <a href="http://www.indierelief.com/">Indie+Relief</a>, all proceeds from <a href="http://click.linksynergy.com/fs-bin/stat?id=aDkhM0mDflg&amp;offerid=146261&amp;u1=st_fg&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252FWebObjects%252FMZStore.woa%252Fwa%252FviewSoftware%253Fid%253D311265471%2526mt%253D8%2526uo%253D6%2526partnerId%253D30">Flower Garden</a> this Wednesday will be donated to Haiti through <a href="http://www.msf.ca//">Doctors Without Borders</a>. Encourage your friends to buy Flower Garden for a good cause! That includes in-app purchases, so feel free to load up on fertilizer :-)</p>
<p>If you&rsquo;ve already purchased Flower Garden and you&rsquo;d still like to help out, you can check out <a href="http://www.indierelief.com">the great lineup of Mac and iPhone apps at Indie+Relief</a>, or <a href="http://www.msf.ca/donate/">donate directly to Doctors Without Borders here</a>.</p>
<p><a href="http://www.indierelief.com/"><img alt="ir_500" loading="lazy" src="/buy-flower-garden-this-wednesday-to-help-haiti/images/ir_500.png" title="ir_500"></a></p>
]]></content:encoded></item><item><title>Making A Living (Barely) On The iPhone App Store (aka The Numbers Post)</title><link>https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/</link><pubDate>Fri, 15 Jan 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/making-a-living-barely-on-the-iphone-app-store/</guid><description>&lt;p&gt;The App Store is a very hit-driven environment. A few apps sell a large amount of units, and the great majority sell next to nothing. That&amp;rsquo;s somewhat similar to the music industry, except that the audience for music is much larger, so both the big hits and the small players get more sales. We&amp;rsquo;ve drooled over the numbers &lt;a href="http://firemint.com/blog/?p=123"&gt;chart&lt;/a&gt; &lt;a href="http://games.venturebeat.com/2009/07/10/pocket-god-is-a-case-study-of-a-hit-iphone-game/"&gt;toppers&lt;/a&gt; sold, I&amp;rsquo;ve seen sales reports of very &lt;a href="http://toucharcade.com/wp-content/uploads/2009/09/featured.png"&gt;successful&lt;/a&gt; &lt;a href="http://www.nimblebit.com/2010/01/nimblebit-numbers-2009/"&gt;games&lt;/a&gt;, and we&amp;rsquo;ve also seen what happens when &lt;a href="http://www.streamingcolour.com/blog/2009/03/09/the-numbers-post-aka-brutal-honesty/"&gt;apps&lt;/a&gt; languish at the bottom.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The App Store is a very hit-driven environment. A few apps sell a large amount of units, and the great majority sell next to nothing. That&rsquo;s somewhat similar to the music industry, except that the audience for music is much larger, so both the big hits and the small players get more sales. We&rsquo;ve drooled over the numbers <a href="http://firemint.com/blog/?p=123">chart</a> <a href="http://games.venturebeat.com/2009/07/10/pocket-god-is-a-case-study-of-a-hit-iphone-game/">toppers</a> sold, I&rsquo;ve seen sales reports of very <a href="http://toucharcade.com/wp-content/uploads/2009/09/featured.png">successful</a> <a href="http://www.nimblebit.com/2010/01/nimblebit-numbers-2009/">games</a>, and we&rsquo;ve also seen what happens when <a href="http://www.streamingcolour.com/blog/2009/03/09/the-numbers-post-aka-brutal-honesty/">apps</a> languish at the bottom.</p>
<p>I want to share the sales data for <a href="http://www.snappytouch.com/flowergarden">Flower Garden</a>. Not just the raw data, but a bit of the story behind it, my thoughts, struggles, and why things happened the way they did.</p>
<p>The first thing that you&rsquo;ll notice is that Flower Garden is a strange in-between app. It&rsquo;s far from being very successful or being at the top of any chart, but at the same time it probably made more money than 99% of the apps on the App Store. It was also relelased on April 10th, so this represents 10 months of data, an age after which most apps are usually on drip support. So this should be an interesting new data point.</p>
<h2 id="the-full-monty">The Full Monty</h2>
<p>I know that if I put it off, you&rsquo;re just going to skip to the end to see the sales plot, so let&rsquo;s get that out of the way. Here it is.</p>
<p><img alt="Full" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/Full.png" title="Flower Garden profit"></p>
<p>The vertical axis is daily profit in US $ (after Apple&rsquo;s 30% cut). Flower Garden generated a bit over $21,500 over a period of 10 months. I would hardly consider that an entry-level salary, much less in California, but it&rsquo;s enough for someone without a family or mortgage to (barely) make a living. I supplemented that with some <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">teaching</a>, <a href="http://gdmag.com/homepage.htm">writing</a>, contracting and consulting, so overall I managed do fine and even save a bit of money last year, all while being totally indie and having full creative control over what I did every day. I&rsquo;m not getting rich, but it&rsquo;s not a bad life, really.</p>
<p>How many hours of work does Flower Garden represent? It&rsquo;s really hard to say. It was 6 solid months of work from conception to release, but then there was the fuzzy time spent on marketing, updates, support, new features, etc. I would estimate it was a total of 8 months of full time work, which, at 50 hours per week, makes it 1600 hours. So that&rsquo;s a depressing $13.44/hour. At least it&rsquo;s over minimum wage! :-) On the positive side, Flower Garden should continue to sell in the foreseeable future, so that amount will go up a bit over time.</p>
<p>There&rsquo;s clearly a story behind that graph. It&rsquo;s not the usual exponential drop off you expect from most (unsuccessful apps) and shows how an aging app can pick up steam on its own after many months on the store, without ever being featured by Apple.</p>
<h2 id="launch">Launch</h2>
<p>Let&rsquo;s start from the beginning. Release day!</p>
<p><img alt="Beginning2" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/Beginning2.png" title="Flower Garden initial profit"></p>
<p>After six hard months of work, I submitted Flower Garden to Apple sometime at the beginning of April, and on April 10th I was surprised to see it had been approved. It caught me a bit off guard without my marketing campaign in place, but I announced it high and wide on <a href="/flower-garden-released/">this blog</a>, Twitter, Facebook, and I even spammed all my friends with an email. The results are the area marked as (A): About $50-$60 in revenue per day (so about 25-30 sales). Not bad considering that was mostly my friends taking pity on me and people randomly seeing it on the new releases list, but it was far from an auspicious start.</p>
<p>I also contacted all the media sites I knew with a press release and promo codes to entice them to write a review. I was lucky that many reviews appeared over the next couple of weeks, but unfortunately they were all spread out, minimizing the PR effect. The biggest effect was when Flower Garden was simultaneously covered on <a href="http://toucharcade.com/2009/04/16/flower-garden-well-its-not-really-a-game/">TouchArcade</a> and <a href="http://www.macrumors.com/iphone/2009/04/16/flower-garden-for-iphone-is-a-beautifully-designed-app/">MacRumors</a>. That&rsquo;s what caused the big sales spike (B). From there, it was a standard exponential drop off, until, on the last day of the month, just three weeks after launch, revenue dropped below $100/day again. If that was all there was to it, Flower Garden was a big flop and I should start dusting off my resume.</p>
<h2 id="mothers-day">Mother&rsquo;s Day</h2>
<p>I wasn&rsquo;t ready to throw in the towel yet. I had a couple cards up my sleeve that I was hoping would change things around. After all, May 5th is Mother&rsquo;s Day in the US. What better time to do some promotion and get Flower Garden noticed?</p>
<p>I decided to run a contest and give away $100 in real flowers to the winner at the same time I put Flower Garden on sale for $1.99 for the week of Mother&rsquo;s Day. The result? The revenue dip you see in (A).</p>
<p><img alt="Middle_long" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/Middle_long.png" title="Flower Garden profit in the middle"></p>
<p>Mother&rsquo;s day is probably the small, second spike in that period, but overall, that week was a loss. Lesson learned: Don&rsquo;t make a sale unless your app is in a visible position (on a top chart somewhere). Flower Garden was nowhere to be seen, so the sale had no effect other than to cut profits by 33%.</p>
<p>I released a couple updates and did the trick updating the release date to get on the new releases list (which no longer works) and I got a couple minor spikes with (B) and (C). Subsequent updates later that summer had almost no effect anymore on sales. The trend was worryingly clear as profits dipped as low as $10/day in mid June (I have no idea what happened that day, but it was the lowest day ever for Flower Garden).</p>
<h2 id="app-treasures">App Treasures</h2>
<p>In early June we launched <a href="http://apptreasures.com">App Treasures</a>. App Treasures is a label for indie iPhone game developers with top-quality games, and one of the main tools we&rsquo;re leveraging is some cross-promotion for our games, both through the web site, and from an in-game view liking to each other&rsquo;s games.Â Initially there was no measurable effect, but then <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=313014213&amp;mt=8">Harbor Master</a> was released and shot all the way to the #2 position on the US store and held its position on the top 50 for a while. The results is the area under (D). It definitely brought in some sales to Flower Garden and reversed the downward trend.</p>
<p>Unfortunately all good things come to an end, and referrals from Harbor Master dropped off and its slipped down the charts, and Flower Garden sales continued sinking.</p>
<h2 id="facebook-and-lite">Facebook and Lite</h2>
<p>At this point I had to face reality. Was it time to give up on Flower Garden and move on to another project? I was ready to do that, but every day I would get several emails from users saying how much they loved Flower Garden, how much happiness it was bringing to their lives, etc. Some of the stories were really touching.</p>
<p>At the same time, every time I would show the game to someone, they usually really liked it. Not liked-it-because-I&rsquo;m-there, but really, genuinely liked it. Why weren&rsquo;t more people buying it then? Two problems: First, screenshots were not conveying how cool growing, animated flowers you could touch were, and second, most people didn&rsquo;t even know Flower Garden existed. It had never been featured by Apple on the App Store, and the audience I was trying to reach didn&rsquo;t read TouchArcade or other iPhone review sites.</p>
<p>It was at this point that I decided to give it one more try. My goal wasn&rsquo;t adding more features as I had done with the updates so far, but to make Flower Garden more visible. I wanted more people to know that Flower Garden existed.</p>
<p>The first thing I did was to add Facebook integration. Not only could you send bouquets through email, but you were able to send them directly to your Facebook friends. The advantage of that approach from my point of view is that all your friends also saw the flowers so for every bouquet sent on Facebook, hopefully dozens or hundreds of people were being exposed to Flower Garden. The result on sales: Not much. Maybe it made the early part of July a little higher than it would have been otherwise, but no noticeable difference.</p>
<p>The second approach was to release a lite version of Flower Garden in early September. I was confident that Flower Garden was a good app, and I was hoping that once people had a chance to try the lite version, they would purchase the full version. Fortunately I was right and the effect on sales was very noticeable, pretty much doubling sales (E),Â but it never really took off in any significant way, and sales slowly declined over time.</p>
<h2 id="second-wind">Second Wind</h2>
<p>You&rsquo;d think that I would give up at this point, wouldn&rsquo;t you? And I don&rsquo;t say that with pride. I mean, it probably would have been smarter to quit a long time ago. But somehow, every time I was ready to move on , something else would come up that would entice me to try something else with Flower Garden.</p>
<p>This time it was in-app purchases (IAP). <a href="http://developer.apple.com/iphone/program/sdk/inapppurchase.html">Apple had announced IAP</a> back in June. They seemed like a very natural fit for Flower Garden, but given how few units Flower Garden had sold, I would have a very limited audience for IAP. A small percentage of a small number is a tiny number! :-( However, in late October Apple announced that <a href="http://theappleblog.com/2009/10/15/apple-allows-iphone-in-app-purchases-for-free-apps/">IAP were finally allowed from free apps</a> as well. That encouraged me to give Flower Garden one&hellip; last&hellip; try&hellip;</p>
<p>To be totally honest, I wasn&rsquo;t expecting very much. Even including all the units of the Lite version out there, there just weren&rsquo;t that many units. Especially not that many people using it on a daily basis (I&rsquo;m sure a lot of the free ones were downloaded and quickly forgotten). But I thought it would be a good experience and if I only spent a week on it and made $1,000 I could call it even.</p>
<p><img alt="End" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/End.png" title="Flower Garden profit after IAP"></p>
<p>The result was totally unexpected. The Flower Shop opened on December 6th and revenue immediately shot up (A). On December 21st I released a new IAP called Seeds of Winter with 8 new winter-themed flowers, and people loved it and immediately purchased it. Christmas day came and went with somewhat of an increase in sales (C) but nothing really spectacular. Finally, to wrap up the year, there was a big spike on New Year&rsquo;s Eve (D) (do people send flowers on New Year&rsquo;s Eve? Really?).</p>
<p>Afterwards revenue flattened out, but at a much higher amount than before.Â Before IAP, daily revenue was about $50/day. Now it&rsquo;s more around $180/day. That&rsquo;s totally beyond any of my expectations!</p>
<p>But hang on, where is the revenue coming from? There are three possible sources: You can purchase Flower Garden, you can make IAP in the full version, and you can also make purchases in the free version. Here&rsquo;s the breakdown:</p>
<p><img alt="End_broken_down" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/End_broken_down.png" title="Flower Garden IAP profit broken down"></p>
<p>It looks like sales for Flower Garden (blue) continue to be more or less the same, with a slight increase after Christmas. The IAP from the full version of Flower Garden (green) account for most of the extra revenue, especially at the beginning. But it&rsquo;s very interesting that the purchases coming from Flower Garden Free (orange) are steadily increasing and, as of last week, they became almost as large as the ones from the full version.</p>
<p>That can be explained because more and more people are getting the free version and upgrading it instead of buying the full version (which is exactly what I was hoping for). What&rsquo;s also really interesting is the downloads of Flower Garden Free.</p>
<p><img alt="fg_free" loading="lazy" src="/making-a-living-barely-on-the-iphone-app-store/images/fg_free.png" title="Flower Garden Free downloads"></p>
<p>Flower Garden Free was never a big player. It had the usual big initial spike, but then it settled down at around 100-200 downloads per day (which is very few considering there were 50-60 purchases per day of Flower Garden Full during that period). But, as soon as the in-app Flower Shop was released, downloads started climbing, and on Christmas day they went through the roof (relatively speaking). So it&rsquo;s no surprise that IAP from Flower Garden Free picked up in these last few weeks.</p>
<h2 id="the-future">The Future</h2>
<p>I have no idea what the future will hold for Flower Garden. This week Apple selected Flower Garden and f<a href="/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/">eatured it on the App Store as a Staff Favorite</a> worldwide (that period is not show in the sales graphs). I&rsquo;m also already preparing a new update and some more IAP for Valentine&rsquo;s Day, so I&rsquo;m sure there will be more ups and downs in the near future. I&rsquo;d certainly like to continue supporting Flower Garden for as long as it&rsquo;s profitable.</p>
<p>I&rsquo;ll follow up this post in a couple of months with the aftermath of the App Store feature and Valentine&rsquo;s Day. Also, stay tuned for another post with more details of the IAP, what&rsquo;s successful, purchase patterns, and more.</p>
]]></content:encoded></item><item><title>Flower Garden Now An Apple Staff Favorite On The App Store Worldwide!</title><link>https://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/</link><pubDate>Tue, 12 Jan 2010 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/</guid><description>&lt;p&gt;Aparently Santa came to town a little later this year. Or maybe it was the &lt;a href="http://en.wikipedia.org/wiki/Biblical_Magi#Traditions"&gt;Reyes Magos&lt;/a&gt; (also bit late). In either case, I woke up this morning to find a very nice present waiting for me at my &lt;a href="http://twitter.com/MKripalani/status/7660447268"&gt;computer&lt;/a&gt;: Apple featured Flower Garden as an Apple Staff Favorite! Apparently this is in all App Stores worldwide too (I have confirmations for &lt;a href="http://twitter.com/OwenGoss/status/7668421503"&gt;Canada&lt;/a&gt; and &lt;a href="http://www.facebook.com/photo.php?pid=3204730&amp;amp;id=74897183702&amp;amp;comments&amp;amp;ref=mf"&gt;Thailand&lt;/a&gt;, so I imagine it applies to other territories as well).&lt;/p&gt;</description><content:encoded><![CDATA[<p>Aparently Santa came to town a little later this year. Or maybe it was the <a href="http://en.wikipedia.org/wiki/Biblical_Magi#Traditions">Reyes Magos</a> (also bit late). In either case, I woke up this morning to find a very nice present waiting for me at my <a href="http://twitter.com/MKripalani/status/7660447268">computer</a>: Apple featured Flower Garden as an Apple Staff Favorite! Apparently this is in all App Stores worldwide too (I have confirmations for <a href="http://twitter.com/OwenGoss/status/7668421503">Canada</a> and <a href="http://www.facebook.com/photo.php?pid=3204730&amp;id=74897183702&amp;comments&amp;ref=mf">Thailand</a>, so I imagine it applies to other territories as well).</p>
<p><img alt="fg_appstore_feature" loading="lazy" src="/flower-garden-now-an-apple-staff-favorite-on-the-app-store-worldwide/images/fg_appstore_feature.jpg" title="fg_appstore_feature"></p>
<p>This is the first time Flower Garden has received any kind of &ldquo;Apple love&rdquo;, so it&rsquo;s particularly exciting, especially considering that Flower Garden was released all the way back in April. I imagine the recent update, which included the Flower Shop with in-app purchases, must have caught someone&rsquo;s eye.</p>
<p>The only downside is that the featuring might throw off the sales data I was collecting to show the effect on sales that in-app purchases and the holiday season had. But I&rsquo;m not really complaining. That&rsquo;s a very nice reason to have the data thrown off :-) Thank you Apple!</p>
]]></content:encoded></item><item><title>All About In-App Purchases Part 4: iTunes Connect</title><link>https://gamesfromwithin.com/in-app-purchases-part-4/</link><pubDate>Tue, 29 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/in-app-purchases-part-4/</guid><description>&lt;p&gt;Weâ€™re used to going through t&lt;a href="https://gamesfromwithin.com/at-the-mercy-of-apples-whim/"&gt;he approval process for binaries&lt;/a&gt;, but in-app purchases are a bit different. Hereâ€™s some of what I learned going through this for &lt;a href="http://www.facebook.com/iphoneflowergarden"&gt;Flower Garden&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="purchase-states"&gt;Purchase States&lt;/h2&gt;
&lt;p&gt;When you first create an in-app purchase in iTunes Connect, it is listed as â€œPending Developer Approvalâ€. This means that if you ask for info on that product id with a SKProductsRequest, youâ€™ll get the info for the item only on development builds, not in distributions builds.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Weâ€™re used to going through t<a href="/at-the-mercy-of-apples-whim/">he approval process for binaries</a>, but in-app purchases are a bit different. Hereâ€™s some of what I learned going through this for <a href="http://www.facebook.com/iphoneflowergarden">Flower Garden</a>.</p>
<h2 id="purchase-states">Purchase States</h2>
<p>When you first create an in-app purchase in iTunes Connect, it is listed as â€œPending Developer Approvalâ€. This means that if you ask for info on that product id with a SKProductsRequest, youâ€™ll get the info for the item only on development builds, not in distributions builds.</p>
<p>Once your in-app purchase item is ready, you need to upload a screenshot of it working in the app, and approve it yourself. At that point it enters the queue to be approved by Apple. Once an item has been approved by Apple (marked as Ready for Sale), it will appear both in development and distribution builds.</p>
<p>This behavior is very convenient because you can add in-app purchases normally for development, and not worry about them showing up for all your existing users until theyâ€™re done. Just make sure to keep around a distribution build of your app to test what the end user sees.</p>
<p>In addition to that, you can flag items as available for sale or not. That way you have the added flexibility of temporarily removing an item from sale, or making it available at a later time.</p>
<p><img alt="itunesconnect" loading="lazy" src="/in-app-purchases-part-4/images/itunesconnect.jpg" title="itunesconnect"></p>
<h2 id="approval-process">Approval Process</h2>
<p>The first time you submit any in-app purchases, youâ€™ll probably do it along with a binary update (since you need to code in <a href="/in-app-purchases-part-1/">support for displaying</a> and <a href="/in-app-purchases-part-2/">allowing the purchases of items</a>). Youâ€™ll have an option to mark the items to be approved along with the binary, so everything will become available on the App Store at the same time. In that case, the approval process is just like for a regular binary update (it seems to be averaging a week lately).</p>
<p>You can also submit in-app purchase items by themselves, without an app binary update. I did this for the Seeds of Winter pack in Flower Garden. Somehow, I was expecting a turnaround time of a day or two. After all, I figured they would look at the provided screenshot and approve it. Unfortunately, that wasnâ€™t the case. In this particular situation, approval took almost a week, and Iâ€™m not sure it was because of the normal process, or because I emailed Apple asking what the procedure was to submit a product by itself (the product was approved within an hour of me getting a response from them saying they would look into it).</p>
<p>I was monitoring iTunes Connect pretty obsessively at the time it was approved (because it was right before my two-week break for the holidays) and I saw that the Seeds of Winter pack went from â€œWaiting for Reviewâ€ to â€œIn Reviewâ€ to â€œApproved for Saleâ€ in a matter of two minutes. That was one quick check! (Iâ€™m not complaining though).</p>
<p>Whatâ€™s even more interesting is that I didnâ€™t know that an item wouldnâ€™t appear on a distribution build unless it was approved by Apple, so I had added an extra layer on <a href="http://flowers.snappytouch.com/Shop/ShopCatalog.plist">the shop catalog file on my server</a> that allowed me to prevent an item from showing up on the Flower Shop until I turned it on myself. And since that check wasnâ€™t turned on, it means that Apple approved the in-app purchase by looking at the provided screenshot, without running it in the app.</p>
<p>This shouldnâ€™t be too surprising. After all, Iâ€™m not even sure what the point is for in-app purchase approvals. For content that comes from the server, I can change it at any time, so the only thing they can approve is the name and description provided in iTunes Connect. I suppose the screenshot is fine for that, but I would also expect really speedy approval times. After all, not having to wait for lengthy approval processes is one of the big draws for in-app purchases.</p>
<p>I did learn one important lesson from going through this process. Next time I submit a binary prepared for more in-app purchases, Iâ€™m going to create stand-ins for all possible in-app purchases Iâ€™m considering and submit them for approval at the same time as the app binary, but marked as not ready for sale. That way they will all be approved at once, and I can take my time creating the final version for those items and making them available instantly whenever I want.</p>
<h2 id="purchasing-items">Purchasing Items</h2>
<p>The same way that non-Apple approved items only show up in development builds, the only accounts that can purchase any items on development builds are test accounts using the sandbox environment. These are accounts you create on iTunes Connect and allow you to purchase items in your programs without spending real money (otherwise Iâ€™d be in trouble considering how many times I ended up purchasing items during the development of the Flower Shop!). Conversely, distribution builds only work with non-test accounts and non-sandbox environment.</p>
<p>One thing that threw me off was that I started getting support requests from people who had trouble logging in with their account to make in-app purchases. They claimed they were being asked about this â€œsandbox environmentâ€. That threw me in a panic for a second, because I thought that everybody was somehow accessing the sandbox environment and nobody could make any purchases (because they had full iTunes accounts). It turns out, thatâ€™s a problem that happens with jailbroken phones with a particular app installed. Itâ€™s <a href="http://www.facebook.com/l.php?u=http%3A%2F%2Fbit.ly%2F70C1Zw&amp;h=92bfb053b357f0588362e316b88d9f32">nicely documented here</a> so Iâ€™ve been pointing people in that direction.</p>
<p>Finally, I believe thereâ€™s no provision in iTunes Connect to deal with different binary versions, but thatâ€™s something thatâ€™s very important to handle. If I release a new binary with some new feature built into the app, and an in-app purchase to unlock it, I donâ€™t want people with an earlier version purchasing it and getting mad that itâ€™s not working. Ideally this should be an option in iTunes Connect, but in the meanwhile, I build a version check into <a href="http://flowers.snappytouch.com/Shop/ShopCatalog.plist">the shop catalog itself</a>. That way only apps with that version or higher can even display a particular item. Or I can even take it a step further and display the item but notify the user that they need to update the app before the purchase it.</p>
]]></content:encoded></item><item><title>All About In-App Purchases Part 3: Anti-Piracy Measures</title><link>https://gamesfromwithin.com/in-app-purchases-part-3/</link><pubDate>Mon, 21 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/in-app-purchases-part-3/</guid><description>&lt;p&gt;One of the big advantages of in-app purchases for some people is that it makes pirating content more difficult. For me it wasnâ€™t much of an issue because a) Most of the people who enjoy Flower Garden arenâ€™t the ones checking out the app warez sites, and b) I know better than to waste my time trying to prevent piracy &lt;a href="#1"&gt;[1]&lt;/a&gt;. Besides, I always roll my eyes whenever I hear that 90% or some other large percentage of the users are using a pirated copy, so the developer lost all that money. News flash: 99% of those users using a cracked version wouldnâ€™t have bought your product anyway, so you can rest a bit easier at night.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the big advantages of in-app purchases for some people is that it makes pirating content more difficult. For me it wasnâ€™t much of an issue because a) Most of the people who enjoy Flower Garden arenâ€™t the ones checking out the app warez sites, and b) I know better than to waste my time trying to prevent piracy <a href="#1">[1]</a>. Besides, I always roll my eyes whenever I hear that 90% or some other large percentage of the users are using a pirated copy, so the developer lost all that money. News flash: 99% of those users using a cracked version wouldnâ€™t have bought your product anyway, so you can rest a bit easier at night.</p>
<p>Even so, I decided to take a few extra steps that at least will make things a bit more difficult to crack and keep things more secure. I could have gone way beyond this, but I donâ€™t think that would have been worth my time.</p>
<h3 id="verify-the-purchase">Verify the purchase</h3>
<p><img alt="fg_pirate" loading="lazy" src="/in-app-purchases-part-3/images/fg_pirate.jpg" title="fg_pirate">Right now, you can download programs that will automatically crack an app by extracting its data and resigning it so it works on any jailbroken phone. Thereâ€™s no doubt that even if you implement in-app purchases just like I described in <a href="/in-app-purchases-part-1/">earlier</a> <a href="/in-app-purchases-part-2/">posts</a>, crackers will have to analyze the code and do some steps by hand, so that might be enough to slow down the pace of cracked apps.Â Even so, an experienced cracker wonâ€™t take long to crack your in-app purchases unless you take some extra steps. All they have to do is find the function that you call in response to getting the go ahead from the App Store and theyâ€™ll gain access to all content.</p>
<p>The first thing you should do is to verify that the purchase happened correctly. To do that, once you get the notification in your app that the payment was complete, you send the receipt to your server, and have your server verify it in turn with the App Store. Since crackers donâ€™t have access to your server (if they do youâ€™re in more trouble than a few cracked apps), that step is secure. If your app was cracked and the user didnâ€™t pay for the purchase, the App Store will fail the verification of the receipt and you donâ€™t have to deliver the content.</p>
<p>How do you check that the receipt is valid? First of all, you need to send the receipt of the purchase to your server. I send it along with some other info, like the userâ€™s UDID, what product was purchased, etc so I can keep general usage statistics. The relevant bits of code are the following:</p>
<pre tabindex="0"><code>NSString* receiptString = [self createEncodedString:transaction.transactionReceipt];
//...
[postBody appendData:[[NSString stringWithFormat:@&#34;\r\n--%@\r\n&#34;, boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[@&#34;Content-Disposition: form-data; name=\&#34;receipt\&#34;\r\n\r\n&#34; dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[receiptString dataUsingEncoding:NSUTF8StringEncoding]];
//...
[req setHTTPBody:postBody];
</code></pre><p>The createEncodedString function takes some arbitrary data and creates a <a href="http://en.wikipedia.org/wiki/Base64">base64 encoding</a>. Thatâ€™s one of the parts that is not particularly well documented in the SDK documentation.</p>
<pre tabindex="0"><code>- (NSString*) createEncodedString:(NSData*)data
{
    static char table[] = &#34;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=&#34;;

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

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

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

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

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

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

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

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

	$purchase-&gt;storeReceipt = $response-&gt;{&#39;receipt&#39;};
	return true;
}
</code></pre><p>If things check out, the server returns a valid code, and you can go ahead and make the content available to the user. Otherwise, it means the user is trying to pass up a fake purchase as valid and you can deal with it any way you want.</p>
<h3 id="get-content-from-the-server">Get content from the server</h3>
<p>Of course, if the content is already embedded in the app itself, the cracker can bypass both the App Store purchase and the receipt verification through your server, and just access the content directly. If you want a better chance of not being cracked, have your server deliver the content. That way, if the receipt doesnâ€™t check out, you never transfer the content.</p>
<p>In the case of Flower Garden, all seed packets are downloaded from the server, but the other purchases (extra pots, extra fertilizer) are just changing a few internal variables, so they would be a lot easier to crack.</p>
<p>One of the easiest ways that crackers can get around this verification is by buying the content once and saving the receipt that comes with it. Then, cracked versions can pass that receipt to your server, theyâ€™ll be validated as correctly, and theyâ€™ll be able to download the content.Â So, as an added precaution, you might want to keep track how many times a certain purchase is re-downloaded, especially from different UDIDs. I canâ€™t imagine a legitimate reason for a user to download the same purchase more than 20-30 times from different devices, so denying the purchase at that point in the server seems justified.</p>
<h3 id="save-those-receipts">Save those receipts</h3>
<p>The last step I to make cracking more difficult was to save the receipt itself to disk along with the content that was downloaded. Then, periodically, the game can pick one of those receipts, and verify with the server that itâ€™s still valid. If itâ€™s ever reported as an invalid receipt, the game deletes the content for that purchase. This is not as draconian as it sounds, because even if itâ€™s ever triggered for a legitimate user (and I have no idea how that could be other than data corruption), they can always re-purchase it again for free (and they would want to do that to fix their data corruption anyway).</p>
<p>To be able to delete things easily and cleanly, I keep each downloaded in-app purchase on a separate directory. So itâ€™s very easy to delete the whole directory without having to access files everywhere. The hardest thing is making sure the game deals with the missing data and that nothing is referencing it. Iâ€™ll touch on that on a future part of this article.</p>
<p>Keeping purchases in separate directories also makes it easier to reset all purchases. Thatâ€™s something I didnâ€™t originally include in Flower Garden, but I should have. Sometimes, data can get corrupted or maybe a bug occurs because of some combination of purchases (hopefully not, but you never know!). Allowing the user to reset the purchases and re-download them allows them to fix those problems without having to reinstall the app and lose their progress.</p>
<p>[1] I know from first hand experience that one dedicated teenager with all the time in his hands can spend inordinate amounts of time bypassing the most elaborate anti-piracy schemes. The harder it is, the more of a challenge it becomes, and the more fun it is. To this day, I still remember the thrill of finally bypassing the copy protection of <a href="http://tacgr.emuunlim.com/downloads/filedetail.php?recid=3">1943 on the Amstrad CPC</a> after two days of non-stop hacking, which included several loops XORing all the available memory (including the currently executing code), and messages from the developers taunting me!</p>
]]></content:encoded></item><item><title>Great Presentation on Data-Oriented Design</title><link>https://gamesfromwithin.com/great-presentation-on-data-oriented-design/</link><pubDate>Sun, 20 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/great-presentation-on-data-oriented-design/</guid><description>&lt;p&gt;&lt;img alt="Memory CPU gap" loading="lazy" src="https://gamesfromwithin.com/great-presentation-on-data-oriented-design/images/mem_cpu_gap.jpg" title="Memory CPU gap"&gt;A few days ago, &lt;a href="http://twitter.com/TonyAlbrecht"&gt;Tony Albrecht&lt;/a&gt; posted the slides of his presentation titled &lt;a href="http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf"&gt;&amp;ldquo;Pitfalls of Object-Oriented Design&amp;rdquo;&lt;/a&gt; &lt;a href="#1"&gt;[1]&lt;/a&gt;. Even though the title is really broad and could easily be &lt;a href="http://www.reddit.com/r/programming/comments/ag43j/pitfalls_of_object_oriented_programming_pdf/"&gt;misinterpreted&lt;/a&gt;, it&amp;rsquo;s not just a general bash on OOD. Instead, it&amp;rsquo;s very much focused on how object-oriented design is not a good match for high-performance apps (games) on modern hardware architectures with slow memory access and deep memory hierarchies. His proposed solution: Data-oriented design.Â Spot on!&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Memory CPU gap" loading="lazy" src="/great-presentation-on-data-oriented-design/images/mem_cpu_gap.jpg" title="Memory CPU gap">A few days ago, <a href="http://twitter.com/TonyAlbrecht">Tony Albrecht</a> posted the slides of his presentation titled <a href="http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf">&ldquo;Pitfalls of Object-Oriented Design&rdquo;</a> <a href="#1">[1]</a>. Even though the title is really broad and could easily be <a href="http://www.reddit.com/r/programming/comments/ag43j/pitfalls_of_object_oriented_programming_pdf/">misinterpreted</a>, it&rsquo;s not just a general bash on OOD. Instead, it&rsquo;s very much focused on how object-oriented design is not a good match for high-performance apps (games) on modern hardware architectures with slow memory access and deep memory hierarchies. His proposed solution: Data-oriented design.Â Spot on!</p>
<p>If you haven&rsquo;t seen the presentation, go download it right now. It&rsquo;s really well put together and he has some great detailed examples on how caches are affected with traditional object-oriented design vs. a more data-oriented approach.</p>
<p>[1] Thanks to <a href="http://twitter.com/ChristerEricson/status/6783005918">Christer Ericson</a> for pointing that out.</p>
]]></content:encoded></item><item><title>All About In-App Purchases Part 2: Selling The Goods</title><link>https://gamesfromwithin.com/in-app-purchases-part-2/</link><pubDate>Fri, 18 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/in-app-purchases-part-2/</guid><description>&lt;p&gt;The &lt;a href="https://gamesfromwithin.com/in-app-purchases-part-1/"&gt;last entry about in-app purchases&lt;/a&gt; left off with the products correctly displayed on the store and ready for purchase. Let&amp;rsquo;s push that buy button!&lt;/p&gt;
&lt;h3 id="purchasing-a-product"&gt;Purchasing a product&lt;/h3&gt;
&lt;p&gt;&lt;img alt="iap_1" loading="lazy" src="https://gamesfromwithin.com/in-app-purchases-part-2/images/iap_1.jpg" title="iap_1"&gt;The store is fully populated, the items are displayed and, if all goes well, the user presses the buy button. What now?&lt;/p&gt;
&lt;p&gt;At this point I check that in-app purchases are enabled and if they arenâ€™t, I put up a message box. Apple says you can also do this earlier, but I figured Iâ€™d rather show users whatâ€™s available and entice them to buy it. By the time they get that message, theyâ€™ll be much more likely to enable them and continue the purchase than if they never saw the store in the first place.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The <a href="/in-app-purchases-part-1/">last entry about in-app purchases</a> left off with the products correctly displayed on the store and ready for purchase. Let&rsquo;s push that buy button!</p>
<h3 id="purchasing-a-product">Purchasing a product</h3>
<p><img alt="iap_1" loading="lazy" src="/in-app-purchases-part-2/images/iap_1.jpg" title="iap_1">The store is fully populated, the items are displayed and, if all goes well, the user presses the buy button. What now?</p>
<p>At this point I check that in-app purchases are enabled and if they arenâ€™t, I put up a message box. Apple says you can also do this earlier, but I figured Iâ€™d rather show users whatâ€™s available and entice them to buy it. By the time they get that message, theyâ€™ll be much more likely to enable them and continue the purchase than if they never saw the store in the first place.</p>
<p>Actually, before I even do that check, I see if the item is currently offered for free. If it is, the code takes an alternative path that doesnâ€™t involve the App Store because apparently you canâ€™t set an in-app purchase to free. Really! Why not? Itâ€™s yet something else we need to implement ourselves. Please, Apple, fix that. In the case of free purchases (like the Bonus Seeds included in the full version of Flower Garden) I contact my server directly and download everything from there. If you&rsquo;re thinking that a hacker can just set the free flag to true and have access to all your content, it&rsquo;s not that easy, because the server checks that the product is really marked as free when it&rsquo;s contacted, and if it isn&rsquo;t, it declines the transaction. So they have to work a bit harder than that to crack things (more on that next time).</p>
<p>But if the product is not marked as free and in-app purchases are enabled, then you can add the payment to the StoreKit payment queue which is, of course, another asynchronous call. So now weâ€™re back to having to make a decision of what we want the user to do after they attempt to purchase something. Does someone really want to move away from the screen before they complete the purchase? I donâ€™t, so I set another blocking activity screen explaining whatâ€™s going on with an activity indicator.</p>
<pre tabindex="0"><code>if ([SKPaymentQueue canMakePayments])
{
    SKPayment* payment = [SKPayment paymentWithProductIdentifier:m_product.m_id];
    SKPaymentQueue* queue = [SKPaymentQueue defaultQueue];
    [queue addPayment:payment];
    [m_progressViewController setText:@&#34;Accessing store&#34; completed:NO];
    [m_progressViewController display:YES animated:YES];
}
</code></pre><p>To be able to test the actual purchase, you need to create a test account in iTunes Connect. Itâ€™s slightly annoying that you need to explicitly log out from the Settings | Store screen and you canâ€™t do that from the app itself, but itâ€™s not nearly as much of a big deal as not being able to test purchases from the simulator at all. Thatâ€™s a big fail as far as Iâ€™m concerned, and I canâ€™t imagine a single reason why that was done that way (other than lack of time/manpower on Appleâ€™s side).</p>
<h3 id="completing-the-purchase">Completing the purchase</h3>
<p>You think we might be done by now, but not. Far from it. Weâ€™re just getting warmed up.</p>
<p>Now that the payment has entered the queue, youâ€™re going to get a callback notification every time its status changes. That means you&rsquo;ll get one right away because it was just added to the queue, another time when the payment is approved by the App Store, or when it fails, or if itâ€™s detected that it was already purchased and this a re-purchase.</p>
<p><img alt="iap_2" loading="lazy" src="/in-app-purchases-part-2/images/iap_2.jpg" title="iap_2">While thatâ€™s happening, the StoreKit code will bring up those ugly message boxes asking the user if theyâ€™re really sure they want to purchase the item for that price, and possibly ask them for their login info. Itâ€™s funny that the first time I implemented this part, I thought that it was up to me to put those message boxes up, so they were showing up twice. You donâ€™t have to do anything for that, whether you want to or not. Whatâ€™s worse, is that each time one of those message boxes comes up, your app gets a message putting it on hold, which usually means the sound is temporarily muted. Looks very unprofessional and Iâ€™m surprised Apple forces that on us while they leave everything else so open ended and requiring so much work.</p>
<p>Once the purchase is marked as complete, you can obtain the content for that purchase and make it available in your app. After that step is complete, you can remove the payment from the queue and the transaction is considered complete. In the case of Flower Garden, most purchases involve accessing my server and downloading some data from there for new seeds. Some purchases donâ€™t require any downloading though, and all they do is twiddle a few bits internally.</p>
<p>It&rsquo;s important to understand the payment queue well. First of all, it&rsquo;s persistent, so once a purchase payment has been added to it, it will be there next time the application starts if it was never removed. It was designed that way to make sure an application can deliver on the product that was purchased even if the app is stopped, crashes, or is interrupted in any way. So initially, a payment is added to the queue meaning that the user has initiated the purchase transaction. At that point, the transaction can fail for multiple reasons: User cancels payment during one of the prompts, wrong user ID, the servers are down, the product was removed from the store, etc. Assuming the purchase is successful, the user account will be charged the cost of the product and the payment will be marked as successful. It&rsquo;s at this time that you have to deliver the goods. Only once you&rsquo;ve successfully done that you can go ahead and remove the payment from the queue. Otherwise, next time that the app starts, your code should detect a payment there and continue processing it. You really never want to get in a situation that the user pays for something and it&rsquo;s never delivered to them.</p>
<p>I&rsquo;m happy with how the StoreKit API will keep track of past purchases, and if a user tries to buy the same item again, they&rsquo;ll be given the option to redownload it for free. It&rsquo;s a great relief not to have to keep track of that ourselves. It will also cut down on customer support emails a huge amount because users can always redownload something if they had to uninstall their app, or somehow, in spite of all our precautions, they bought something but it was never updated in their app. In that case a quick re-download should fix it (just make sure your code is pretty stateless and can deal with re-downloading the same content multiple times).</p>
<p>It gets a bit trickier though. It turns out the payment queue can have more than one payment in it. Why is that? First of all, because the buy process wasnâ€™t blocking the way Apple designed it, a hyperactive user could initiate multiple purchases at once. The other, more realistic situation is that the user initiates a purchase, itâ€™s verified with the App Store, but before you can complete the download, your application is shut down. The Store Kit queue will be restored next time the application starts, but at that point the user could go to the store again and start another purchase.</p>
<p>In any case, you really need to deal with that situation, otherwise you risk losing purchases and angering users (and you really don&rsquo;t want to rely on users re-downloading something for free if you can avoid it). This is trickier than it sounds when youâ€™re dealing with downloads from your own server because it might involve multiple downloads, multiple files, etc. So in my case, whenever I get an update of status in the SKPaymentQueue, I add it to my own queue. Then I can process that queue sequentially, one purchase at the time.</p>
<pre tabindex="0"><code>- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction* transaction in transactions)
        [m_transactionQueue addObject:transaction];

    [self processNextTransaction];
}

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

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

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

SKProductsRequest* request = [[SKProductsRequest alloc] initWithProductIdentifiers:productIds];
request.delegate = self;
#ifdef WORK_WITHOUT_APP_STORE
[self productsRequest:request didReceiveResponse:nil];
#else
[request start];
#endif
[productIds release];
</code></pre><p>There are a couple interesting things in that code. First of all, notice that before we ask for the product info, we check if the product is already included in the app. Thatâ€™s because some items, such as the extra pots or the common seeds, already come as part of Flower Garden Full. But at the same time, I wanted to show them in the store and mark them as purchased. So I need to have a parallel path for those items that doesnâ€™t go through the App Store. More on that in a future post.</p>
<p>The other interesting bit is the #ifdef. This one really sucks, so get ready: The simulator canâ€™t make any StoreKit calls. It fails with a nice message box explaining why, but it fails nonetheless. To put it in highly technical terms: That blows! Seriously, that means youâ€™re stuck developing on the device. Turnaround times are about 20-30 seconds, and debugging on the device directly is no fun at all. Iâ€™m convinced that alone was part of the reason it took me longer than my initial estimate. So that #ifdef was my attempt to try to get as much done on the simulator as possible. At least I was able to display the products on the flower shop. The actual buying had to be done on the device though. No way around it as far as I know. Why, oh, why, doesnâ€™t Apple let us add a test account on the simulator? Maybe a feature for SDK 4.0?</p>
<h3 id="displaying-the-products">Displaying the products</h3>
<p><img alt="fg_flowershop3" loading="lazy" src="/in-app-purchases-part-1/images/fg_flowershop3.jpg" title="fg_flowershop3"></p>
<p>Some time after sending the request for info on the products, and assuming we have a valid internet connection and that the App Store is in a good mood (to their credit, Appleâ€™s servers have been very reliable), weâ€™ll get a response. The response will include more information for each of the products we requested, including localized name, description, and price. This is all information taken from the in-app purchases you created in iTunes Connect. And yes, that means that you need to keep multiple sets of data in sync: Your shop catalog and the in-app purchases in iTunes Connect.</p>
<p>Notice that because everything weâ€™ve done so far has been asynchronous (and asynchronous is the name of the game for a lot of the remaining steps as well) it introduces a lot of complexity. What do we do during that time? Do we let the user wander around to other parts of the program? Do we block and make the UI modal? I went with the latter approach for simplicity both coding and in the UI for the user.</p>
<p>At this point you can display them in your shop. In my case I ended up using a very similar interface to the App Store on the iPhone. I figured users are already familiar with that kind of interface, so might as well build on top of that. So that meant the flower shop is a table showing all available products. Clicking on a cell brings up a view with details and a description of each product.</p>
<p>To make my life easier, the only elements that are hardwired on the product page are the icon, the title, and the price/purchase button. The actual description and screenshots is just an embedded web view and part of the product description in the catalog has the correct URL for each project. You can even access <a href="http://flowers.snappytouch.com/Shop/catalog/CourtyardDesc.html">some of them directly here</a>.</p>
<p>So far all this has done for us is let us populate a list of products that are available to be sold. Next entry will cover the details of the actual transaction and a few things to watch out for.</p>
]]></content:encoded></item><item><title>Data-Oriented Design (Or Why You Might Be Shooting Yourself in The Foot With OOP)</title><link>https://gamesfromwithin.com/data-oriented-design/</link><pubDate>Fri, 04 Dec 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/data-oriented-design/</guid><description>&lt;p&gt;Picture this: Toward the end of the development cycle, your game crawls, but you don&amp;rsquo;t see any obvious hotspots in the profiler. The culprit? Random memory access patterns and constant cache misses. In an attempt to improve performance, you try to parallelize parts of the code, but it takes heroic efforts, and, in the end, you barely get much of a speed-up due to all the synchronization you had to add. To top it off, the code is so complex that fixing bugs creates more problems, and the thought of adding new features is discarded right away. Sound familiar?&lt;/p&gt;</description><content:encoded><![CDATA[<p>Picture this: Toward the end of the development cycle, your game crawls, but you don&rsquo;t see any obvious hotspots in the profiler. The culprit? Random memory access patterns and constant cache misses. In an attempt to improve performance, you try to parallelize parts of the code, but it takes heroic efforts, and, in the end, you barely get much of a speed-up due to all the synchronization you had to add. To top it off, the code is so complex that fixing bugs creates more problems, and the thought of adding new features is discarded right away. Sound familiar?</p>
<p>That scenario pretty accurately describes almost every game I&rsquo;ve been involved with for the last 10 years. The reasons aren&rsquo;t the programming languages we&rsquo;re using, nor the development tools, nor even a lack of discipline. In my experience, it&rsquo;s object- oriented programming (OOP) and the culture that surrounds it that is in large part to blame for those problems. OOP could be hindering your project rather than helping it!</p>
<p>It&rsquo;s All About Data</p>
<p>OOP is so ingrained in the current game development culture that it&rsquo;s hard to think beyond objects when thinking about a game. After all, we&rsquo;ve been creating classes representing vehicles, players, and state machines for many years. What are the alternatives? Procedural programming? Functional languages? Exotic programming languages?</p>
<p>Data-oriented design is a different way to approach program design that addresses all these problems. Procedural programming focuses on procedure calls as its main element, and OOP deals primarily with objects. Notice that the main focus of both approaches is code: plain procedures (or functions) in one case, and grouped code associated with some internal state in the other. Data-oriented design shifts the perspective of programming from objects to the data itself: The type of the data, how it is laid out in memory, and how it will be read and processed in the game.</p>
<p>Programming, by definition, is about transforming data: It&rsquo;s the act of creating a sequence of machine instructions describing how to process the input data and create some specific output data. A game is nothing more than a program that works at interactive rates, so wouldn&rsquo;t it make sense for us to concentrate primarily on that data instead of on the code that manipulates it?</p>
<p>I&rsquo;d like to clear up potential confusion and stress that data-oriented design does not imply that something is data- driven. A data-driven game is usually a game that exposes a large amount of functionality outside of code and lets the data determine the behavior of the game. That is an orthogonal concept to data-oriented design, and can be used with any type of programming approach.</p>
<p>Ideal Data</p>
<p>If we look at a program from the data point of view, what does the ideal data look like? It depends on the data and how it&rsquo;s used. In general, the ideal data is in a format that we can use with the least amount of effort. In the best case, the format will be the same we expect as an output, so the processing is limited to just copying that data. Very often, our ideal data layout will be large blocks of contiguous, homogeneous data that we can process sequentially. In any case, the goal is to minimize the amount of transformations, and whenever possible, you should bake your data into this ideal format offline, during your asset-building process.</p>
<p>Because data-oriented design puts data first and foremost, we can architect our whole program around the ideal data format. We won&rsquo;t always be able to make it exactly ideal (the same way that code is hardly ever by-the-book OOP), but it&rsquo;s the primary goal to keep in mind. Once we achieve that, most of the problems I mentioned at the beginning of the column tend to melt away (more about that in the next section).</p>
<p>When we think about objects, we immediately think of treesâ€” inheritance trees, containment trees, or message-passing trees, and our data is naturally arranged that way. As a result, when we perform an operation on an object, it will usually result in that object in turn accessing other objects further down in the tree. Iterating over a set of objects performing the same operation generates cascading, totally different operations at each object (see Figure 1a).</p>
<p>To achieve the best possible data layout, it&rsquo;s helpful to break down each object into the different components, and group components of the same type together in memory, regardless of what object they came from. This organization results in large blocks of homogeneous data, which allow us to process the data sequentially (see Figure 1b). A key reason why data-oriented design is so powerful is because it works very well on large groups of objects. OOP, by definition, works on a single object. Step back for a minute and think of the last game you worked on: How many places in the code did you have only one of something? One enemy? One vehicle? One pathfinding node? One bullet? One particle? Never! Where there&rsquo;s one, there are many. OOP ignores that and deals with each object in isolation. Instead, we can make things easy for us and for the hardware and organize our data to deal with the common case of having many items of the same type.</p>
<p>Does this sound like a strange approach? Guess what? You&rsquo;re probably already doing this in some parts of your code: The particle system! Data-oriented design is turning our whole codebase into a gigantic particle system. Perhaps a name for this approach that would be more familiar to game programmers would have been particle-driven programming.</p>
<p>Advantages of Data-Oriented Design</p>
<p>hinking about data first and architecting the program based on that brings along lots of advantages.</p>
<p>Parallelization.</p>
<p>These days, there&rsquo;s no way around the fact that we need to deal with multiple cores. Anyone who has tried taking some OOP code and parallelizing it can attest how difficult, error prone, and possibly not very efficient that is. Often you end up adding lots of synchronization primitives to prevent concurrent access to data from multiple threads, and usually a lot of the threads end up idling for quite a while waiting for other threads to complete. As a result, the performance improvement can be quite underwhelming.</p>
<p>When we apply data-oriented design, parallelization becomes a lot simpler: We have the input data, a small function to process it, and some output data. We can easily take something like that and split it among multiple threads with minimal synchronization between them. We can even take it further and run that code on processors with local memory (like the SPUs on the Cell processor) without having to do anything differently.</p>
<p>Cache utilization.</p>
<p>In addition to using multiple cores, one of the keys to achieving great performance in modern hardware, with its deep instruction pipelines and slow memory systems with multiple levels of caches, is having cache-friendly memory access. Data-oriented design results in very efficient use of the instruction cache because the same code is executed over and over. Also, if we lay out the data in large, contiguous blocks, we can process the data sequentially, getting nearly perfect data cache usage and great performance. Possible optimizations. When we think of objects or functions, we tend to get stuck optimizing at the function or even the algorithm level; Reordering some function calls, changing the sort method, or even re-writing some C code with assembly.</p>
<p>That kind of optimization is certainly beneficial, but by thinking about the data first we can step further back and make larger, more important optimizations. Remember that all a game does is transform some data (assets, inputs, state) into some other data (graphics commands, new game states). By keeping in mind that flow of data, we can make higher-level, more intelligent decisions based on how the data is transformed, and how it is used. That kind of optimization can be extremely difficult and time- consuming to implement with more traditional OOP methods.</p>
<p>Modularity.</p>
<p>So far, all the advantages of data-oriented design have been based around performance: cache utilization, optimizations, and parallelization. There is no doubt that as game programmers, performance is an extremely important goal for us. There is often a conflict between techniques that improve performance and techniques that help readability and ease of development. For example, re-writing some code in assembly language can result in a performance boost, but usually makes the code harder to read and maintain.</p>
<p>Fortunately, data-oriented design is beneficial to both performance and ease of development. When you write code specifically to transform data, you end up with small functions, with very few dependencies on other parts of the code. The codebase ends up being very â€œflat,â€ with lots of leaf functions without many dependencies. This level of modularity and lack of dependences makes understanding, replacing, and updating the code much easier.</p>
<p>Testing.</p>
<p>The last major advantage of data-oriented design is ease of testing. As we saw in the June and August Inner Product columns, writing unit tests to check object interactions is not trivial. You need to set up mocks and test things indirectly. Frankly, it&rsquo;s a bit of a pain. On the other hand, when dealing directly with data, it couldn&rsquo;t be easier to write unit tests: Create some input data, call the transform function, and check that the output data is what we expect. There&rsquo;s nothing else to it. This is actually a huge advantage and makes code extremely easy to test, whether you&rsquo;re doing test-driven development or just writing unit tests after the code.</p>
<p>Drawbacks of Data-Oriented Design</p>
<p>Data-oriented design is not the silver bullet to all the problems in game development. It does help tremendously writing high-performance code and making programs more readable and easier to maintain, but it does come with a few drawbacks of its own.</p>
<p>The main problem with data-oriented design is that it&rsquo;s different from what most programmers are used to or learned in school. It requires turning our mental model of the program ninety degrees and changing how we think about it. It takes some practice before it becomes second-nature.</p>
<p>Also, because it&rsquo;s a different approach, it can be challenging to interface with existing code, written in a more OOP or procedural way. It&rsquo;s hard to write a single function in isolation, but as long as you can apply data-oriented design to a whole subsystem you should be able to reap a lot of the benefits.</p>
<p>Applying Data-Oriented Design</p>
<p>Enough of the theory and overview. How do you actually get started with data-oriented design? To start with, just pick a specific area in your code: navigation, animations, collisions, or something else. Later on, when most of your game engine is centered around the data, you can worry about data flow all the way from the start of a frame until the end.</p>
<p>The next step is to clearly identify the data inputs required by the system, and what kind of data it needs to generate. It&rsquo;s OK to think about it in OOP terms for now, just to help us identify the data. For example, in an animation system, some of the input data is skeletons, base poses, animation data, and current state. The result is not â€œthe code plays animations,â€ but the data generated by the animations that are currently playing. In this case, our outputs would be a new set of poses and an updated state.</p>
<p>It&rsquo;s important to take a step further and classify the input data based on how it is used. Is it read- only, read-write, or write-only? That classification will help guide design decisions about where to store it, and when to process it depending on dependencies with other parts of the program.</p>
<p>At this point, stop thinking of the data required for a single operation, and think in terms of applying it to dozens or hundreds of entries. We no longer have one skeleton, one base pose, and a current state, and instead we have a block of each of those types with many instances in each of the blocks.</p>
<p>Think very carefully how the data is used during the transformation process from input to output. You might realize that you need to scan a particular field in a structure to perform a pass on the data, and then you need to use the results to do another pass. In that case, it might make more sense to split that initial field into a separate block of memory that can be processed independently, allowing for better cache utilization and potential parallelization. Or maybe you need to vectorize some part of the code, which requires fetching data from different locations to put it in the same vector register. In that case, that data can be stored contiguously so vector operations can be applied directly, without any extra transformations.</p>
<p>Now you should have a very good understanding of your data. Writing the code to transform it is going to be much simpler. It&rsquo;s like writing code by filling in the blanks. You&rsquo;ll even be pleasantly surprised to realize that the code is much simpler and smaller than you thought in the first place, compared to what the equivalent OOP code would have been.</p>
<p>If you think back about most of the topics we&rsquo;ve covered in this column over the last year, you&rsquo;ll see that they were all leading toward this type of design. Now it&rsquo;s the time to be careful about how the data is aligned (Dec 2008 and Jan 2009), to bake data directly into an input format that you can use efficiently (Oct and Nov 2008), or to use non- pointer references between data blocks so they can be easily relocated (Sept 2009).</p>
<p>Is Thre Room For OOP?</p>
<p>Does this mean that OOP is useless and you should never apply it in your programs? I&rsquo;m not quite ready to say that. Thinking in terms of objects is not detrimental when there is only one of each object (a graphics device, a log manager, etc) although in that case you might as well write it with simpler C-style functions and file-level static data. Even in that situation, it&rsquo;s still important that those objects are designed around transforming data.</p>
<p>Another situation where I still find myself using OOP is GUI systems. Maybe it&rsquo;s because you&rsquo;re working with a system that is already designed in an object-oriented way, or maybe it&rsquo;s because performance and complexity are not crucial factors with GUI code. In any case, I much prefer GUI APIs that are light on inheritance and use containment as much as possible (Cocoa and CocoaTouch are good examples of this). It&rsquo;s very possible that a data-oriented GUI system could be written for games that would be a pleasure to work with, but I haven&rsquo;t seen one yet.</p>
<p>Finally, there&rsquo;s nothing stopping you from still having a mental picture of objects if that&rsquo;s the way you like to think about the game. It&rsquo;s just that the enemy entity won&rsquo;t be all in the same physical location in memory. Instead, it will be split up into smaller subcomponents, each one forming part of a larger data table of similar components.</p>
<p>Data-oriented design is a bit of a departure from traditional programming approaches, but by always thinking about the data and how it needs to be transformed, you&rsquo;ll be able to reap huge benefits both in terms of performance and ease of development.</p>
<p>Thanks to Mike Acton and Jim Tilander for challenging my ideas over the years and for their feedback on this article.</p>
<p>Picture this: Toward the end of the development cycle, your game crawls, but you don&rsquo;t see any obvious hotspots in the profiler. The culprit? Random memory access patterns and constant cache misses. In an attempt to improve performance, you try to parallelize parts of the code, but it takes heroic efforts, and, in the end, you barely get much of a speed-up due to all the synchronization you had to add. To top it off, the code is so complex that fixing bugs creates more problems, and the thought of adding new features is discarded right away. Sound familiar?</p>
<p>That scenario pretty accurately describes almost every game I&rsquo;ve been involved with for the last 10 years. The reasons aren&rsquo;t the programming languages we&rsquo;re using, nor the development tools, nor even a lack of discipline. In my experience, it&rsquo;s object- oriented programming (OOP) and the culture that surrounds it that is in large part to blame for those problems. OOP could be hindering your project rather than helping it!</p>
<h2 id="its-all-about-data">It&rsquo;s All About Data</h2>
<p>OOP is so ingrained in the current game development culture that it&rsquo;s hard to think beyond objects when thinking about a game. After all, we&rsquo;ve been creating classes representing vehicles, players, and state machines for many years. What are the alternatives? Procedural programming? Functional languages? Exotic programming languages?</p>
<p>Data-oriented design is a different way to approach program design that addresses all these problems. Procedural programming focuses on procedure calls as its main element, and OOP deals primarily with objects. Notice that the main focus of both approaches is code: plain procedures (or functions) in one case, and grouped code associated with some internal state in the other. Data-oriented design shifts the perspective of programming from objects to the data itself: The type of the data, how it is laid out in memory, and how it will be read and processed in the game.</p>
<p>Programming, by definition, is about transforming data: It&rsquo;s the act of creating a sequence of machine instructions describing how to process the input data and create some specific output data. A game is nothing more than a program that works at interactive rates, so wouldn&rsquo;t it make sense for us to concentrate primarily on that data instead of on the code that manipulates it?</p>
<p>I&rsquo;d like to clear up potential confusion and stress that data-oriented design does not imply that something is data- driven. A data-driven game is usually a game that exposes a large amount of functionality outside of code and lets the data determine the behavior of the game. That is an orthogonal concept to data-oriented design, and can be used with any type of programming approach.</p>
<h2 id="ideal-data">Ideal Data</h2>
<p><img alt="Call sequence with an object-oriented approach" loading="lazy" src="/data-oriented-design/images/oo_design.png" title="oo_design"></p>
<p><em>Figure 1a. Call sequence with an object-oriented approach</em></p>
<p>If we look at a program from the data point of view, what does the ideal data look like? It depends on the data and how it&rsquo;s used. In general, the ideal data is in a format that we can use with the least amount of effort. In the best case, the format will be the same we expect as an output, so the processing is limited to just copying that data. Very often, our ideal data layout will be large blocks of contiguous, homogeneous data that we can process sequentially. In any case, the goal is to minimize the amount of transformations, and whenever possible, you should bake your data into this ideal format offline, during your asset-building process.</p>
<p>Because data-oriented design puts data first and foremost, we can architect our whole program around the ideal data format. We won&rsquo;t always be able to make it exactly ideal (the same way that code is hardly ever by-the-book OOP), but it&rsquo;s the primary goal to keep in mind. Once we achieve that, most of the problems I mentioned at the beginning of the column tend to melt away (more about that in the next section).</p>
<p>When we think about objects, we immediately think of treesâ€” inheritance trees, containment trees, or message-passing trees, and our data is naturally arranged that way. As a result, when we perform an operation on an object, it will usually result in that object in turn accessing other objects further down in the tree. Iterating over a set of objects performing the same operation generates cascading, totally different operations at each object (see Figure 1a).</p>
<p><img alt="Call sequence with a data-oriented approach" loading="lazy" src="/data-oriented-design/images/do_design1.png" title="do_design"></p>
<p><em>Figure 1b. Call sequence with a data-oriented approach</em></p>
<p>To achieve the best possible data layout, it&rsquo;s helpful to break down each object into the different components, and group components of the same type together in memory, regardless of what object they came from. This organization results in large blocks of homogeneous data, which allow us to process the data sequentially (see Figure 1b). A key reason why data-oriented design is so powerful is because it works very well on large groups of objects. OOP, by definition, works on a single object. Step back for a minute and think of the last game you worked on: How many places in the code did you have only one of something? One enemy? One vehicle? One pathfinding node? One bullet? One particle? Never! Where there&rsquo;s one, there are many. OOP ignores that and deals with each object in isolation. Instead, we can make things easy for us and for the hardware and organize our data to deal with the common case of having many items of the same type.</p>
<p>Does this sound like a strange approach? Guess what? You&rsquo;re probably already doing this in some parts of your code: The particle system! Data-oriented design is turning our whole codebase into a gigantic particle system. Perhaps a name for this approach that would be more familiar to game programmers would have been particle-driven programming.</p>
<h2 id="advantages-of-data-oriented-design">Advantages of Data-Oriented Design</h2>
<p>Thinking about data first and architecting the program based on that brings along lots of advantages.</p>
<h3 id="parallelization">Parallelization.</h3>
<p>These days, there&rsquo;s no way around the fact that we need to deal with multiple cores. Anyone who has tried taking some OOP code and parallelizing it can attest how difficult, error prone, and possibly not very efficient that is. Often you end up adding lots of synchronization primitives to prevent concurrent access to data from multiple threads, and usually a lot of the threads end up idling for quite a while waiting for other threads to complete. As a result, the performance improvement can be quite underwhelming.</p>
<p>When we apply data-oriented design, parallelization becomes a lot simpler: We have the input data, a small function to process it, and some output data. We can easily take something like that and split it among multiple threads with minimal synchronization between them. We can even take it further and run that code on processors with local memory (like the SPUs on the Cell processor) without having to do anything differently.</p>
<h3 id="cache-utilization">Cache utilization.</h3>
<p>In addition to using multiple cores, one of the keys to achieving great performance in modern hardware, with its deep instruction pipelines and slow memory systems with multiple levels of caches, is having cache-friendly memory access. Data-oriented design results in very efficient use of the instruction cache because the same code is executed over and over. Also, if we lay out the data in large, contiguous blocks, we can process the data sequentially, getting nearly perfect data cache usage and great performance. Possible optimizations. When we think of objects or functions, we tend to get stuck optimizing at the function or even the algorithm level; Reordering some function calls, changing the sort method, or even re-writing some C code with assembly.</p>
<p>That kind of optimization is certainly beneficial, but by thinking about the data first we can step further back and make larger, more important optimizations. Remember that all a game does is transform some data (assets, inputs, state) into some other data (graphics commands, new game states). By keeping in mind that flow of data, we can make higher-level, more intelligent decisions based on how the data is transformed, and how it is used. That kind of optimization can be extremely difficult and time- consuming to implement with more traditional OOP methods.</p>
<h3 id="modularity">Modularity.</h3>
<p>So far, all the advantages of data-oriented design have been based around performance: cache utilization, optimizations, and parallelization. There is no doubt that as game programmers, performance is an extremely important goal for us. There is often a conflict between techniques that improve performance and techniques that help readability and ease of development. For example, re-writing some code in assembly language can result in a performance boost, but usually makes the code harder to read and maintain.</p>
<p>Fortunately, data-oriented design is beneficial to both performance and ease of development. When you write code specifically to transform data, you end up with small functions, with very few dependencies on other parts of the code. The codebase ends up being very â€œflat,â€ with lots of leaf functions without many dependencies. This level of modularity and lack of dependences makes understanding, replacing, and updating the code much easier.</p>
<h3 id="testing">Testing.</h3>
<p>The last major advantage of data-oriented design is ease of testing. As we saw in the June and August Inner Product columns, writing unit tests to check object interactions is not trivial. You need to set up mocks and test things indirectly. Frankly, it&rsquo;s a bit of a pain. On the other hand, when dealing directly with data, it couldn&rsquo;t be easier to write unit tests: Create some input data, call the transform function, and check that the output data is what we expect. There&rsquo;s nothing else to it. This is actually a huge advantage and makes code extremely easy to test, whether you&rsquo;re doing test-driven development or just writing unit tests after the code.</p>
<h2 id="drawbacks-of-data-oriented-design">Drawbacks of Data-Oriented Design</h2>
<p>Data-oriented design is not the silver bullet to all the problems in game development. It does help tremendously writing high-performance code and making programs more readable and easier to maintain, but it does come with a few drawbacks of its own.</p>
<p>The main problem with data-oriented design is that it&rsquo;s different from what most programmers are used to or learned in school. It requires turning our mental model of the program ninety degrees and changing how we think about it. It takes some practice before it becomes second-nature.</p>
<p>Also, because it&rsquo;s a different approach, it can be challenging to interface with existing code, written in a more OOP or procedural way. It&rsquo;s hard to write a single function in isolation, but as long as you can apply data-oriented design to a whole subsystem you should be able to reap a lot of the benefits.</p>
<h2 id="applying-data-oriented-design">Applying Data-Oriented Design</h2>
<p>Enough of the theory and overview. How do you actually get started with data-oriented design? To start with, just pick a specific area in your code: navigation, animations, collisions, or something else. Later on, when most of your game engine is centered around the data, you can worry about data flow all the way from the start of a frame until the end.</p>
<p>The next step is to clearly identify the data inputs required by the system, and what kind of data it needs to generate. It&rsquo;s OK to think about it in OOP terms for now, just to help us identify the data. For example, in an animation system, some of the input data is skeletons, base poses, animation data, and current state. The result is not â€œthe code plays animations,â€ but the data generated by the animations that are currently playing. In this case, our outputs would be a new set of poses and an updated state.</p>
<p>It&rsquo;s important to take a step further and classify the input data based on how it is used. Is it read- only, read-write, or write-only? That classification will help guide design decisions about where to store it, and when to process it depending on dependencies with other parts of the program.</p>
<p>At this point, stop thinking of the data required for a single operation, and think in terms of applying it to dozens or hundreds of entries. We no longer have one skeleton, one base pose, and a current state, and instead we have a block of each of those types with many instances in each of the blocks.</p>
<p>Think very carefully how the data is used during the transformation process from input to output. You might realize that you need to scan a particular field in a structure to perform a pass on the data, and then you need to use the results to do another pass. In that case, it might make more sense to split that initial field into a separate block of memory that can be processed independently, allowing for better cache utilization and potential parallelization. Or maybe you need to vectorize some part of the code, which requires fetching data from different locations to put it in the same vector register. In that case, that data can be stored contiguously so vector operations can be applied directly, without any extra transformations.</p>
<p>Now you should have a very good understanding of your data. Writing the code to transform it is going to be much simpler. It&rsquo;s like writing code by filling in the blanks. You&rsquo;ll even be pleasantly surprised to realize that the code is much simpler and smaller than you thought in the first place, compared to what the equivalent OOP code would have been.</p>
<p>If you think back about most of the topics we&rsquo;ve covered in this column over the last year, you&rsquo;ll see that they were all leading toward this type of design. Now it&rsquo;s the time to be careful about how the data is aligned (Dec 2008 and Jan 2009), to bake data directly into an input format that you can use efficiently (Oct and Nov 2008), or to use non- pointer references between data blocks so they can be easily relocated (Sept 2009).</p>
<h2 id="is-there-room-for-oop">Is There Room For OOP?</h2>
<p>Does this mean that OOP is useless and you should never apply it in your programs? I&rsquo;m not quite ready to say that. Thinking in terms of objects is not detrimental when there is only one of each object (a graphics device, a log manager, etc) although in that case you might as well write it with simpler C-style functions and file-level static data. Even in that situation, it&rsquo;s still important that those objects are designed around transforming data.</p>
<p>Another situation where I still find myself using OOP is GUI systems. Maybe it&rsquo;s because you&rsquo;re working with a system that is already designed in an object-oriented way, or maybe it&rsquo;s because performance and complexity are not crucial factors with GUI code. In any case, I much prefer GUI APIs that are light on inheritance and use containment as much as possible (Cocoa and CocoaTouch are good examples of this). It&rsquo;s very possible that a data-oriented GUI system could be written for games that would be a pleasure to work with, but I haven&rsquo;t seen one yet.</p>
<p>Finally, there&rsquo;s nothing stopping you from still having a mental picture of objects if that&rsquo;s the way you like to think about the game. It&rsquo;s just that the enemy entity won&rsquo;t be all in the same physical location in memory. Instead, it will be split up into smaller subcomponents, each one forming part of a larger data table of similar components.</p>
<p>Data-oriented design is a bit of a departure from traditional programming approaches, but by always thinking about the data and how it needs to be transformed, you&rsquo;ll be able to reap huge benefits both in terms of performance and ease of development.</p>
<p>Thanks to <a href="http://www.cellperformance.com/mike_acton">Mike Acton</a> and <a href="http://www.tilander.org/aurora/">Jim Tilander</a> for challenging my ideas over the years and for their feedback on this article.</p>
<p>This article was originally printed in the September 2009 issue of <a href="http://gdmag.com">Game Developer</a>.</p>
<p><a href="http://www.lameproof.com/zboard/zboard.php?id=bbs2&amp;no=790">Here&rsquo;s a Korean translation of this article</a> byÂ Hakkyu Kim.</p>
]]></content:encoded></item><item><title>Two Day iPhone OpenGL Class Coming to The Bay Area</title><link>https://gamesfromwithin.com/two-day-iphone-opengl-class-coming-to-the-bay-area/</link><pubDate>Sun, 18 Oct 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/two-day-iphone-opengl-class-coming-to-the-bay-area/</guid><description>&lt;p&gt;&lt;img alt="cars" loading="lazy" src="https://gamesfromwithin.com/two-day-iphone-opengl-class-coming-to-the-bay-area/images/cars.png" title="cars"&gt;After the success of the OpenGL class in Denver, we&amp;rsquo;re bringing the &lt;a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/"&gt;iPhone OpenGL class&lt;/a&gt; to the Bay Area. It will be held November 19th and 20th in &lt;a href="http://maps.google.com/maps?q=10950+North+Blaney+Avenue+Cupertino,+CA+95014&amp;amp;oe=utf-8&amp;amp;client=firefox-a&amp;amp;ie=UTF8&amp;amp;gl=us&amp;amp;ei=imnbSoj4OYakMfvskN8H&amp;amp;ved=0CA0Q8gEwAA&amp;amp;hq=&amp;amp;hnear=10950+N+Blaney+Ave,+Cupertino,+Santa+Clara,+California+95014&amp;amp;ll=37.334072,-122.02362&amp;amp;spn=0.026377,0.043731&amp;amp;z=15"&gt;Cupertino&lt;/a&gt;, right next to Apple&amp;rsquo;s headquarters at Infinite Loop.&lt;/p&gt;
&lt;p&gt;The class is aimed at iPhone developers without previous OpenGL or 3D graphics experience. As part of the class, we&amp;rsquo;ll create both 2D and 3D OpenGL applications, and we&amp;rsquo;ll cover a broad range of topics, start with the basics of setting up OpenGL and rendering triangles on screen, to multitexturing and point sprites in the last day. This is definitely a hands-on class, so you&amp;rsquo;ll need to bring your laptop and be ready to do some coding.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="cars" loading="lazy" src="/two-day-iphone-opengl-class-coming-to-the-bay-area/images/cars.png" title="cars">After the success of the OpenGL class in Denver, we&rsquo;re bringing the <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">iPhone OpenGL class</a> to the Bay Area. It will be held November 19th and 20th in <a href="http://maps.google.com/maps?q=10950+North+Blaney+Avenue+Cupertino,+CA+95014&amp;oe=utf-8&amp;client=firefox-a&amp;ie=UTF8&amp;gl=us&amp;ei=imnbSoj4OYakMfvskN8H&amp;ved=0CA0Q8gEwAA&amp;hq=&amp;hnear=10950+N+Blaney+Ave,+Cupertino,+Santa+Clara,+California+95014&amp;ll=37.334072,-122.02362&amp;spn=0.026377,0.043731&amp;z=15">Cupertino</a>, right next to Apple&rsquo;s headquarters at Infinite Loop.</p>
<p>The class is aimed at iPhone developers without previous OpenGL or 3D graphics experience. As part of the class, we&rsquo;ll create both 2D and 3D OpenGL applications, and we&rsquo;ll cover a broad range of topics, start with the basics of setting up OpenGL and rendering triangles on screen, to multitexturing and point sprites in the last day. This is definitely a hands-on class, so you&rsquo;ll need to bring your laptop and be ready to do some coding.</p>
<p>Check out the <a href="http://www.mobileorchard.com/iphone-opengl-programming-training-class/">Mobile Orchard page for discounts and registration details</a>. Feel free to <a href="/contact/">contact me</a> if you have any questions.</p>
<p>Hope to see you there!</p>
]]></content:encoded></item><item><title>Space in Stereo iPhone Game Jam Postmortem</title><link>https://gamesfromwithin.com/space-in-stereo-iphone-game-jam-postmortem/</link><pubDate>Mon, 05 Oct 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/space-in-stereo-iphone-game-jam-postmortem/</guid><description>&lt;p&gt;A week ago, I sent out a &lt;a href="http://twitter.com/SnappyTouch/status/4409865477"&gt;quick tweet&lt;/a&gt; asking if anyone would be interested in doing an iPhone Game Jam at the &lt;a href="http://www.360idev.com/"&gt;360iDev conference&lt;/a&gt;. The response was &lt;a href="http://twitter.com/%23search?q=jam%2520360idev"&gt;immediate and hugely positive&lt;/a&gt;, so, with the help of the organizers of 360iDev, we put together an informal &lt;a href="http://iphonegamejam.com/"&gt;iPhone Game Jam&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The idea was to get together Tuesday evening, starting at around 7PM, and to code all night and have an iPhone game (or at least a prototype) done by morning. About 25 showed up, working on about &lt;a href="http://iphonegamejam.com/index.php?title=Projects"&gt;a dozen projects&lt;/a&gt;. Participants were welcome to group into teams or work solo. There were no restrictions as far as themes or technology. The only rules were that you had to finish something by morning (no leaving something that was 5% of a game) and you had to start the game from scratch (no finishing a game you had started a while ago).&lt;/p&gt;</description><content:encoded><![CDATA[<p>A week ago, I sent out a <a href="http://twitter.com/SnappyTouch/status/4409865477">quick tweet</a> asking if anyone would be interested in doing an iPhone Game Jam at the <a href="http://www.360idev.com/">360iDev conference</a>. The response was <a href="http://twitter.com/%23search?q=jam%2520360idev">immediate and hugely positive</a>, so, with the help of the organizers of 360iDev, we put together an informal <a href="http://iphonegamejam.com/">iPhone Game Jam</a>.</p>
<p>The idea was to get together Tuesday evening, starting at around 7PM, and to code all night and have an iPhone game (or at least a prototype) done by morning. About 25 showed up, working on about <a href="http://iphonegamejam.com/index.php?title=Projects">a dozen projects</a>. Participants were welcome to group into teams or work solo. There were no restrictions as far as themes or technology. The only rules were that you had to finish something by morning (no leaving something that was 5% of a game) and you had to start the game from scratch (no finishing a game you had started a while ago).</p>
<p><img alt="space" loading="lazy" src="/space-in-stereo-iphone-game-jam-postmortem/images/space.jpg" title="space"></p>
<p>The reason behind doing a game jam is to be able to quickly create game prototypes and decide if theyâ€™re worth pursuing further or not. Much better to spend a few hours one night and then throwing it away, than spending several months with multiple people involved. Also, the heavy time constraints often help participants by focusing them in the ultimate goal and forcing them to adopt creative solutions. Being all together in one large room added a lot of energy and made it possible to work really focused for many hours without a huge amount of caffeine (although the large amounts of coffee provided by <a href="http://twitter.com/javahead">Jay</a> really helped!). In the end, we even ended up getting <a href="http://www.youtube.com/watch?v=KCYsZqp573o">a late-night fiddle serenade</a> by <a href="http://www.philhassey.com/blog/">Phil Hassey</a>. Try that at home by yourself! <a href="http://www.streamingcolour.com/blog/">Owen Goss</a> liked the idea so much, he decided to jam with use remotely through video conferencing!</p>
<p>One specific thing that I wanted to avoid with the game jam was the idea of giving any sort of prices at the end. I really wanted to keep the jam as an environment where people would be free to experiment and fail. If people were thinking of potential prices at the end, they would be a lot less willing to go out on a limb and try different things.</p>
<p>My goal going into the jam was to experiment with game mechanics that relied heavily on multi touch. I felt that very few games made good use of multi touch (aside from pinching) and that it had the potential to create something very different from the single-touch based game that weâ€™re used to from mice for the last 20 years. The flip side of it is that a multi-touch game was much riskier and unknown. Could something that multiple simultaneous touches be fun, or would it be frustrating? Would your fingers get in the way and clutter the screen, or would it be a new experience? In the back of my mind, I was definitely drawing inspiration from the fantastic game <a href="http://click.linksynergy.com/fs-bin/stat?id=aDkhM0mDflg&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;RD_PARM1=http%25253A%25252F%25252Fitunes.apple.com%25252FWebObjects%25252FMZStore.woa%25252Fwa%25252FviewSoftware%25253Fid%25253D315613006%252526mt%25253D8%252526uo%25253D6%252526partnerId%25253D30">Bug Bugs</a>, by <a href="http://igloo-games.com/">Igloo Games</a>.</p>
<p>I did all the coding myself, but I teamed up with <a href="http://twitter.com/veiledgames">Evan McMahon</a> from <a href="http://veiledgames.com/">Veiled Games</a> and he did all the awesome art in the prototype.</p>
<p><img alt="Owen Goss joining the iPhone Game Jam remotely" loading="lazy" src="/space-in-stereo-iphone-game-jam-postmortem/images/owen.jpg" title="owen"></p>
<p><em>Owen Goss joining the iPhone Game Jam remotely</em></p>
<h2 id="what-went-right">What Went Right</h2>
<h3 id="started-with-an-idea"><strong>Started with an idea</strong></h3>
<p>I went into the jam with the idea of experimenting with multi-touch game mechanics. I also had in mind a setting that would be a good backdrop to those mechanics: You control a large, round spaceship in interstellar travel. As you travel between the stars, you need to collect different resources to power your ship and provide all necessary materials. Each type of resource goes in a different bay (which are located along the outer rim), so with two fingers you rotate the ship to move the collecting bay forward, and with the other hand you drag the different resources you encounter. Some resources arenâ€™t useful, so you need to flick them away so they donâ€™t hit the ship. Finally, other resources need to be combined before they can be processed, so you first need to bring them together, and then drag them to the ship.</p>
<p>You only have 10-12 hours to build a game, so if I didnâ€™t have an idea going into the jam, I would have wasted precious time trying to figure out what to do while I could have been working on the game.</p>
<p>At the same time, I didnâ€™t have the idea fully fleshed out and set in stone. I definitely let things change based on what I saw as I was implementing it. So itâ€™s good to strike a flexible medium between having an idea and letting it evolve during the jam.</p>
<h3 id="used-familiar-tools"><strong>Used familiar tools</strong></h3>
<p>Just the day before, <a href="http://criticalthoughtgames.com/">David Whatley</a> raved about how great <a href="http://cocos2d.org/">Cocos2d</a> was for prototyping, and that same day, my friend <a href="http://hiddenelephant.com/blog/">Serban</a> gave <a href="http://hiddenelephant.com/blog/2009/10/01/360idev-introduction-to-2d-game-programming-using-cocos2d/">a presentation on using Cocos2d</a>. Iâ€™m <a href="http://twitter.com/SnappyTouch/status/4480633461">on record</a> saying that I canâ€™t stand to work with Cocos2d because it imposes a particular (totally backwards) architecture on you, and I canâ€™t ever see myself shipping a game with it, but I can see the value in using it for prototyping.</p>
<p>The point of this jam (for me anyway) wasnâ€™t to learn some new tech, but to experiment with gameplay. So I really considered it, but in the end, I decided to work with something I was familiar with, and used my (very small) codebase using straight OpenGL. Iâ€™m very glad that I did because I never felt that working at that level got in the way (other than one frustrating moment related to the first point in â€œwhat went wrongâ€),</p>
<h3 id="didnât-worry-about-performance"><strong>Didnâ€™t worry about performance</strong></h3>
<p>This is a hard one for me! The last <a href="../../../../../gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone">two</a> <a href="../../../../../360idev-cranking-up-floating-point-performance-to-11">talks</a> Iâ€™ve given are all about performance on the iPhone, but even thinking about performance here would have been a waste of time and resources. Sure, the game had to be fast enough to run on the actual device because playing a game on the phone is a very different experience than playing it on the simulator. Besides, a game like this requiring lots of multi-touch was impossible to play on the simulator.</p>
<p>But at the same time, I didnâ€™t have to submit it to the App Store come morning, so I decided that as long as it ran on my 3GS, I didnâ€™t care about anything else. That meant it could be very suboptimal and be a total memory hog. I didnâ€™t care! I wasnâ€™t even releasing resources!</p>
<p>The result, it played perfectly fine on my phone, and I spent zero time trying to optimize it or taking a longer route because of performance or memory reasons. On the other hand, just the tiny, single level I created is about 12MB, so itâ€™s clearly very bloated.</p>
<h3 id="teaming-up"><strong>Teaming up</strong></h3>
<p>As I mentioned earlier, I teamed up with Evan McMahon to create the art for the game. He wasnâ€™t at the conference, so we organized everything through IM and <a href="http://www.getdropbox.com/">Dropbox</a>. The experience was great because not only did he create some awesome-looking art, but he really motivated me along the way. We played off each otherâ€™s energy and came up with new ideas because of the collaboration.</p>
<p>Going solo would have been OK because I was surrounded by a room full of like-minded developers hacking away at their games, so that would have helped keep up the energy levels, but it wouldnâ€™t have had nearly as much of an effect as working directly with someone else. My only regret is that Evan wasnâ€™t there with me.</p>
<p><img alt="ScreenWithButton" loading="lazy" src="/space-in-stereo-iphone-game-jam-postmortem/images/ScreenWithButton.jpg" title="ScreenWithButton"></p>
<p>What about the art itself? Was it a waste of time to add it to the game? After all, it didnâ€™t help me make a better decision about the multi-touch game mechanics, did it? It wasnâ€™t a waste of time at all for me. First of all, it took just as long adding some nice art than it took to add stand-in art because there wasnâ€™t anything special about it. But most importantly, there is a feedback loop between the look of the game and the gameplay and feel of the game. So seeing the art in the game definitely changed how I felt about it and the decisions I made about it during the night.</p>
<h2 id="what-went-wrong"><strong>What Went Wrong</strong></h2>
<h3 id="didnât-have-a-project-ready"><strong>Didnâ€™t have a project ready</strong></h3>
<p>This just goes to show my lack of experience with super-rapid prototyping. I didnâ€™t have a project ready to get started with the prototyping. I originally created a blank OpenGL project from XCode, and quickly realized I would be missing all the set up for sound, the view controller structure, and even some of the default touch-handling. So I grabbed one of my current projects in development, stripped it of everything game specific, and turned it into the project for the game jam. Not a big deal, except that it took me a good 20-30 minutes to go through this, and in the process I deleted a couple crucial lines that gave me lots of problems with OpenGL for the next 30 minutes. Doh!</p>
<p>Next time: Come prepared with a blank project, ready to go.</p>
<h3 id="running-up-against-technical-stuff"><strong>Running up against technical stuff</strong></h3>
<p>I went with OpenGL instead of Cocos2d on purpose to avoid having to deal with learning technical stuff sleep deprived in the middle of the jam. Unfortunately, it turns out my understanding of the multi touch event API wasnâ€™t up to snuff to handle 5 simultaneous touches, starting, moving, and ending, each of them affecting a different object (or different parts of the same object). During the jam I wasnâ€™t writing unit tests either, so that made for a pretty confusing time until I stepped back for a second, hit the documentation and Appleâ€™s touch sample program, and tried to gain a better understanding of what was going on. Hint: Apparently looking at the touches in the UIEvent* parameter passed to touchesBegan is not a good idea, and you need to look at the ones passed in NSSet*.</p>
<h3 id="not-enough-time"><strong>Not enough time!</strong></h3>
<p>I certainly didnâ€™t get as far in the prototype as I had hoped I would. Thereâ€™s only one type of resource (ice chunks) and the control mechanics need to be improved quite a bit.</p>
<p>Is it possible that if I had used Cocos2d I would have gotten more done of the prototype? Yes, itâ€™s possible, although I wonâ€™t know until I try it. Is it possible that half way through the prototype I would have encountered something that Cocos2d couldnâ€™t do and I was left stranded? Yes, thatâ€™s also possible. And thatâ€™s a big reason why I donâ€™t like framework-y type of APIs, and instead I would rather have a toolkit type of API so I can call into it and do the work myself whenever I want instead.</p>
<p>In any case, this is the flip side of â€œusing familiar toolsâ€. I will definitely experiment with Cocos2d in the future and consider it for another game jam if Iâ€™m familiar enough with it and I feel it speeds up development.</p>
<p><img alt="Everybody still going strong late at night (but not quite so perky anymore)" loading="lazy" src="/space-in-stereo-iphone-game-jam-postmortem/images/gamejam.jpg" title="gamejam"></p>
<p><em>Everybody still going strong late at night (but not quite so perky anymore)</em></p>
<h2 id="conclusions"><strong>Conclusions</strong></h2>
<p>I think Space in Stereo has potential, but right now itâ€™s too early to tell if itâ€™s any good. The basic mechanic is there, but itâ€™s not fun by any stretch of the imagination. I already learned a bunch about it though, including that some things werenâ€™t nearly as much fun as I was hoping would be. For example, rotating the space station with two fingers&hellip; well, sucks. The better control scheme is to move the space station by dragging around the middle, and rotating it by dragging a finger around the edge in a circular motion. That was also what everybody was instinctively doing when they were trying out the game.</p>
<p>The game is just at the point that spending another 4-5 hours on it would answer a lot of questions about how fun it can be. Iâ€™m definitely planning on spending that time and then making a decision. If I decide not to go ahead with it, itâ€™s not a big deal. Great games come out of making a lot of different prototypes and throwing away all the so-so ones along the way.</p>
<p>As far as the Game Jam itself, it can only be described in one word: Awesome. It was everything I was hoping for and more. I canâ€™t stress enough how much it helped to have everybody else around you and being so focused for that period of time. I had heard much about game jams, but I had never actually participated in one. After this one Iâ€™m sold. I canâ€™t wait until the next one!</p>
<p><em>Gameplay footage of Space in Stereo</em></p>]]></content:encoded></item><item><title>360iDev: Cranking Up Floating Point Performance To 11</title><link>https://gamesfromwithin.com/360idev-cranking-up-floating-point-performance-to-11/</link><pubDate>Tue, 29 Sep 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/360idev-cranking-up-floating-point-performance-to-11/</guid><description>&lt;p&gt;&lt;img alt="360iDev_speaker" loading="lazy" src="https://gamesfromwithin.com/360idev-cranking-up-floating-point-performance-to-11/images/360iDev_speaker.png" title="360iDev_speaker"&gt;Here are the slides and the source code for my talk this afternoon at 360iDev in Denver. Thanks to everyone who came to the talk. I was surprised to see so much interest on this topic, so that was great.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Session description:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The iPhone has a very powerful engine under that shiny hood when it comes to floating-point computations. This is something that surprises a lot of programmers because by default, things can slow down a lot whenever any floating point numbers are involved. This session will explain the secrets to unlocking maximum performance for floating point calculations, from the mysteries of Thumb mode, to harnessing the full power of the forgotten vector floating point unit. Stay away from this session if he thought of reading or even (gasp!) writing assembly code scares you.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="360iDev_speaker" loading="lazy" src="/360idev-cranking-up-floating-point-performance-to-11/images/360iDev_speaker.png" title="360iDev_speaker">Here are the slides and the source code for my talk this afternoon at 360iDev in Denver. Thanks to everyone who came to the talk. I was surprised to see so much interest on this topic, so that was great.</p>
<p><strong>Session description:</strong></p>
<p>The iPhone has a very powerful engine under that shiny hood when it comes to floating-point computations. This is something that surprises a lot of programmers because by default, things can slow down a lot whenever any floating point numbers are involved. This session will explain the secrets to unlocking maximum performance for floating point calculations, from the mysteries of Thumb mode, to harnessing the full power of the forgotten vector floating point unit. Stay away from this session if he thought of reading or even (gasp!) writing assembly code scares you.</p>
<ul>
<li><a href="http://www.slideshare.net/llopis/cranking-floating-point-performance-to-11-on-the-iphone-2111775">Presentation slides</a> (<a href="/wp-content/uploads/2009/09/iPhoneFP.pdf.zip">pdf format</a>)</li>
<li><a href="/wp-content/uploads/2009/09/vfpperf.zip">Sample project</a></li>
</ul>
]]></content:encoded></item><item><title>GDC Austin 2009: Squeezing Every Drop Of Performance Out Of The iPhone</title><link>https://gamesfromwithin.com/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/</link><pubDate>Wed, 16 Sep 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/</guid><description>&lt;p&gt;&lt;img alt="austin" loading="lazy" src="https://gamesfromwithin.com/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/images/austin.jpg" title="austin"&gt;I just put up &lt;a href="http://www.slideshare.net/llopis/squeezing-every-drop-of-performance-out-of-the-iphone"&gt;the slides for my talk&lt;/a&gt; this morning at GDC Austin: &lt;a href="https://www.cmpevents.com/GDAU09/a.asp?option=C&amp;amp;V=11&amp;amp;SessID=9869"&gt;Squeezing Every Drop Of Performance Out Of The iPhone.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks for everyone who attended the session and for the great feedback so far. If you&amp;rsquo;re going to be in China next month, I&amp;rsquo;ll be giving a very similar talk at &lt;a href="http://www.gdcchina.com/"&gt;GDC China&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Session description:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This session will describe the iPhone performance optimization lessons learned through many hours of tuning. We&amp;rsquo;ll start with an overview of the performance analysis tools available on the iPhone SDK to help you narrow down your performance bottlenecks. Then we&amp;rsquo;ll cover the best way to set up your render loops, rendering best practices, how to deal with the limited memory, or even how to drop down to assembly to use the forgotten vector floating point unit.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="austin" loading="lazy" src="/gdc-austin-2009-squeezing-every-drop-of-performance-out-of-the-iphone/images/austin.jpg" title="austin">I just put up <a href="http://www.slideshare.net/llopis/squeezing-every-drop-of-performance-out-of-the-iphone">the slides for my talk</a> this morning at GDC Austin: <a href="https://www.cmpevents.com/GDAU09/a.asp?option=C&amp;V=11&amp;SessID=9869">Squeezing Every Drop Of Performance Out Of The iPhone.</a></p>
<p>Thanks for everyone who attended the session and for the great feedback so far. If you&rsquo;re going to be in China next month, I&rsquo;ll be giving a very similar talk at <a href="http://www.gdcchina.com/">GDC China</a>.</p>
<p><strong>Session description:</strong></p>
<p>This session will describe the iPhone performance optimization lessons learned through many hours of tuning. We&rsquo;ll start with an overview of the performance analysis tools available on the iPhone SDK to help you narrow down your performance bottlenecks. Then we&rsquo;ll cover the best way to set up your render loops, rendering best practices, how to deal with the limited memory, or even how to drop down to assembly to use the forgotten vector floating point unit.</p>
<p><a href="https://www.cmpevents.com/GDAU09/a.asp?option=C&amp;V=11&amp;SessID=9869">Presentation slides</a> (<a href="/wp-content/uploads/2009/09/iPhone_performance.pdf">pdf format</a>)</p>
]]></content:encoded></item><item><title>From Full to Lite in Under An Hour</title><link>https://gamesfromwithin.com/from-full-to-lite-in-under-an-hour/</link><pubDate>Mon, 14 Sep 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/from-full-to-lite-in-under-an-hour/</guid><description>&lt;p&gt;&lt;img alt="Icon_lite_rounded" loading="lazy" src="https://gamesfromwithin.com/from-full-to-lite-in-under-an-hour/images/Icon_lite_rounded.png" title="Icon_lite_rounded"&gt;A bit over a month ago &lt;a href="#1"&gt;[1]&lt;/a&gt;, I decided it was time to create a &lt;a href="http://itunes.com/apps/flowergardenlite"&gt;&amp;ldquo;lite&amp;rdquo; version of Flower Garden&lt;/a&gt; &lt;a href="#2"&gt;[2]&lt;/a&gt;. I really thought it was going to be a pretty easy task: Disable a few pots, remove some seeds, and repackage it. Sounds simple enough. But before that, I had to decide how to structure the project for the lite version.&lt;/p&gt;
&lt;h3&gt;&lt;/h3&gt;</description><content:encoded><![CDATA[<p><img alt="Icon_lite_rounded" loading="lazy" src="/from-full-to-lite-in-under-an-hour/images/Icon_lite_rounded.png" title="Icon_lite_rounded">A bit over a month ago <a href="#1">[1]</a>, I decided it was time to create a <a href="http://itunes.com/apps/flowergardenlite">&ldquo;lite&rdquo; version of Flower Garden</a> <a href="#2">[2]</a>. I really thought it was going to be a pretty easy task: Disable a few pots, remove some seeds, and repackage it. Sounds simple enough. But before that, I had to decide how to structure the project for the lite version.</p>
<h3></h3>
<p>#defining The Problem</p>
<p>The first approach that came to mind was to use #ifdefs. Hopefully, if I did things well, it wouldn&rsquo;t require too many of them. As soon as I gave it some more thinking, it was clear this was a pretty flawed approach.</p>
<p>I like to be able to create a build with zero human interaction: Press a button, wait, and the build is ready. I don&rsquo;t want to have to do any manual (read, error-prone) steps. So I couldn&rsquo;t just have an #ifdef that I turned on and off depending on whether I was building the lite version or the full one. I can get around that by creating a new configuration in XCode, except that it wouldn&rsquo;t be one, it would be one for every existing configuration I already have: Debug, Release, Distribution Ad Hoc, and Distribution App Store. So this would make a total of 8 configurations. That&rsquo;s rather ugly!</p>
<p>In case the explosion of configurations wasn&rsquo;t ugly enough, there was one other, even bigger problem: An #ifdef wouldn&rsquo;t allow me to change the assets included in each version of Flower Garden, and, most importantly, I couldn&rsquo;t change the Info.plist file to have a different bundle id (although maybe I could change the Info.plist for each of the new configurations and point it to the new one).</p>
<p>Not an attractive option. So how else can we do it?</p>
<h3 id="new-xcode-project">New XCode Project</h3>
<p>The idea is straightforward: Make a copy of the existing project for the full version of the game, and change it in any way you want: Remove resources, add new ones, change Info.plist, etc. You can still share common source files and define a preprocessor macro LITE in the new project to #ifdef parts of the code.</p>
<p>This approach sounds more promising, until you realize that changes made to one project don&rsquo;t carry over to the other one. So if you&rsquo;re done developing the full version, and you create the lite version at the very end, maybe that won&rsquo;t be a problem (although, how can you be sure you&rsquo;re done?) And making changes to two separate projects is never fun.</p>
<p>You could improve things a bit by starting out the lite version as a branch in source control. That way, changes made to one of the branches can (hopefully) be merged back into the main line or another branch (have fun merging xcodeproj files). I think it&rsquo;s because I&rsquo;ve had the displeasure of working in projects that went totally overboard branching, that just the word branch makes me recoil in disgust. Yes, this method might work, but it seemed cumbersome and error prone.</p>
<p>Any other solutions?</p>
<h3 id="stay-on-target">Stay On Target</h3>
<p>It turns out I kept thinking in terms of a solution I could have implemented in Visual Studio (that&rsquo;s what I get for spending so many years working with it). But fortunately we&rsquo;re not in Windows-land anymore. This is XCode, and XCode totally rocks.</p>
<p>XCode&rsquo;s build system, once you wrap your head around it, is much more flexible and natural than Visual Studio&rsquo;s. It&rsquo;s much more like a make file (and I say that in a good way&ndash;I do like make files!). You have files, and then you have targets. And there&rsquo;s nothing that says a file can&rsquo;t be in multiple targets (and the file only appears in the project once). Once you have multiple target, whenever you add a new file you have the option to add it to both targets the same time if you want. Perfect!</p>
<p>My Flower Garden project contains about 15 targets: 7 &ldquo;engine&rdquo; libraries, 7 test executables for each of the libraries, and one main executable target for the game itself. So the (now obvious) solution, was to simply create a new target for the lite version, in that same project, with the same files. It turns out this solution had all the advantages of the previous approaches with none of the drawbacks.</p>
<h3 id="lite-target-details">Lite Target Details</h3>
<p><img alt="targets" loading="lazy" src="/from-full-to-lite-in-under-an-hour/images/targets.png" title="targets">Once I landed on the target idea, it really was quite straightforward to create the Lite version by following a few, simple steps:</p>
<ul>
<li>Make a duplicate of the target for the full version. Just right click on the full target, and select duplicate.</li>
<li>Rename new target to something else (Flower Garden Lite&ndash;I&rsquo;m highly imaginative when it comes to naming things like this! :-)</li>
<li>Make a duplicate of your Info.plist (InfoLite.plist)</li>
<li>Change the info.plist file setting for the lite target to point to InfoLite.plist</li>
<li>Edit InfoLite.plist to have a different bundle identifier and maybe a different bundle display name (the name that&rsquo;s going to show up under the icon on the iPhone).</li>
<li>Add a compiler define to the lite target called LITE or something like that. That way you can #ifdef a few parts of the code depending on the version you&rsquo;re compiling.</li>
</ul>
<p>And that&rsquo;s almost it. There&rsquo;s one more trick that made my life a lot easier. It turns out that you will definitely want to change not just some code, but some assets depending on which version you&rsquo;re using. So maybe you&rsquo;ll have a Wall.png texture in the full version, but you&rsquo;ll want to have a different version of that texture in the Lite version. I started out creating a new file called WallLite.png, but then it quickly cascaded into a bunch of code changes loading either Wall.png or WallLite.png depending on the version and it was ugly and time consuming.</p>
<p>A much better approach is to rely on the resource copy step of XCode. By default, XCode will grab the resources in your project and copy them all in the same folder, flattening the hierarchy completely. This can be a pain if you have resources with the same name organized in different folders because they will clash. But here we can use it to our advantage to supply different versions of the resource for the full and lite versions.</p>
<p>Just create a Lite directory and put any variations of your resources there. Then, in the Resources Copy step of the target, remove the resources you&rsquo;re replacing and add the ones from the Lite directory. Whenever you build, XCode will put those new resources in the same place where the full resources were and your code won&rsquo;t have to change one bit. This trick works even with xib files, which is great because I had to modify one of them to reduce the number of pots in the garden screen.</p>
<p>Once you have that set up, the rest is just a matter of deciding what functionality goes in the lite version and how it is presented. It can be as simple or as complex as you want.</p>
<p>In the case of Flower Garden, it was very straightforward. I limited the number of pots to two, and the number of different seeds to three. So I just had to change a few resources and add a couple of #ifdefs with the number of total pots and seeds. I also removed the resources that weren&rsquo;t used in the lite version (the seed data for all the unavailable seeds for example).</p>
<p>Flower Garden lite was finally approved and it has been available on the App Store for a few days. So far it has been downloaded several thousand times, it has been very well received, and has definitely bumped up the sales of the full version. Definitely a few hours well spent!</p>
<p>[1] The lite version took a couple of hours to create and a month to approve by Apple.</p>
<p>[2] It was something I wanted to have created from the beginning, but my hands were tied because email bouquets were being sent through my server and I had a maximum number of emails I was allowed to send per day because of spam limits. Fortunately, as soon as the 3.0 OS was released, apps were able to use in-app email and that restriction went away.</p>]]></content:encoded></item><item><title>At The Mercy of Apple's Whim</title><link>https://gamesfromwithin.com/at-the-mercy-of-apples-whim/</link><pubDate>Tue, 01 Sep 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/at-the-mercy-of-apples-whim/</guid><description>&lt;p&gt;We&amp;rsquo;ve known for a long time that Apple are king-makers when it comes to bringing up an app through the ranks of the App Store. A nice feature on the front page, and boom, guaranteed sales for at least a week. We&amp;rsquo;ve all complained at the randomness of it all, but we&amp;rsquo;ve all wished to be there. It&amp;rsquo;s random, but at least it&amp;rsquo;s something positive, so it&amp;rsquo;s a bit like winning the lottery.&lt;/p&gt;</description><content:encoded><![CDATA[<p>We&rsquo;ve known for a long time that Apple are king-makers when it comes to bringing up an app through the ranks of the App Store. A nice feature on the front page, and boom, guaranteed sales for at least a week. We&rsquo;ve all complained at the randomness of it all, but we&rsquo;ve all wished to be there. It&rsquo;s random, but at least it&rsquo;s something positive, so it&rsquo;s a bit like winning the lottery.</p>
<p>There&rsquo;s a darker side to Apple&rsquo;s randomness. Something developers have been complaining for quite a while and it&rsquo;s just getting worse: The approval process.</p>
<p>This is nothing new though. For a while developers have been reporting random rejections by Apple. Some of them extremely <a href="http://hiddenelephant.com/blog/2009/05/15/ridiculous-app-store-rejection/">unfair</a> and <a href="http://neverodd.wordpress.com/2009/02/23/apple-slays-the-dragon/">illogical</a>.</p>
<p>A few months ago, if you got hit with one of those random rejects, it was annoying, but it was bearable. Usually a resubmit would get approved in under a week, so it was possible to fix whatever random thing Apple flagged down (or show them that it wasn&rsquo;t an issue), and resubmit without wasting too much time.</p>
<p>Now things are different. Supposedly 95% of apps are approved (or rejected) under 14 days (although my <a href="http://bit.ly/iphoneapprovaltime">informal and biased survey</a> shows <a href="http://bit.ly/iphoneapprovalresults">very different percentages</a>). A mistake from Apple rejecting an app doesn&rsquo;t cost you a week anymore, but perhaps as much as an extra 3-4 weeks! That&rsquo;s a big deal for a company that&rsquo;s trying to time the release of a product.</p>
<p>So far, I had been one of the lucky developers and I never got a rejection from Apple with Flower Garden. Actually, updates were usually approved withing 7 days <strong>to the hour</strong> (very suspicious, isn&rsquo;t it?). But my luck ran out and I joined the group of developers hit hard by random and unfair updates.</p>
<p>Two days ago, Flower Garden 1.7, which had been in review for 24 days was rejected with the following explanation from Apple:</p>
<blockquote>
<p>Dear Noel,</p>
<p>Thank you for submitting Flower Garden to the App Store. We&rsquo;ve reviewed Flower Garden and determined that we cannot post this version of your iPhone application to the App Store because your application contains pricing information in the application, located in the &ldquo;More Games&rdquo; page. Providing specific pricing information in this location may lead to user confusion because of pricing differences in countries. It would be appropriate to remove pricing information from your application.</p>
<p>Once these modifications have been made please upload a new binary using iTunes Connect</p>
<p>Regards,</p>
<p>iPhone Developer Program</p>
</blockquote>
<p>I was completely floored when I read that email. So apparently displaying a web page with prices for other apps is not allowed unless you localize that based on the language settings of the iPhone. How many apps are doing that? I doubt many (any?) are doing it. I can certainly bring up piles and piles of other games that are showing non-localized prices. But precedence is clearly not an argument with Apple. Even previous versions of Flower Garden had that exact same view with prices and it wasn&rsquo;t a problem! Random reviewer strikes again.</p>
<p>But wait, there&rsquo;s more. The prices are shown on a web page fed through my server. I made that change in 30 seconds and emailed them back, hoping they could simply re-test that functionality and approve it on the spot. No, that would be too easy! I had to resubmit a new binary and start the approval process again! I just gave them the change to cut back their work to a fraction of the time (supposedly they had tested other things that they&rsquo;ll have to re-test because they have no way of knowing I didn&rsquo;t change/update anything else). Sigh! I resubmitted it and I&rsquo;m hoping for a quick approval, but somehow I&rsquo;m ready for another 24-day wait.</p>
<p>So this morning I was excited to receive another email from Apple, I open it and&hellip;</p>
<blockquote>
<p>Hello Noel,</p>
<p>Flower Garden Lite cannot be posted because it is a feature-limited version. Free or &ldquo;Lite&rdquo; versions are acceptable, however the application must be a fully functional app and cannot reference features that are not implemented or up-sell to the full version.</p>
<p>Users can view unlockable seeds on the &ldquo;Seeds&rdquo; tab but cannot access them in the Lite version of the application. Please refer to the attached screenshot for an example.</p>
<p>Please upload a new binary and correct metadata using iTunes Connect .</p>
<p>Regards,</p>
<p>iPhone Developer Program</p>
</blockquote>
<p>and they attached the following screenshot:</p>
<p><a href="/wp-content/uploads/2009/09/IMG_0014.PNG"><img alt="IMG_0014" loading="lazy" src="/at-the-mercy-of-apples-whim/images/IMG_0014.PNG" title="IMG_0014"></a></p>
<p>Users can be unlockable seeds but can&rsquo;t unlock them? If you follow the included tutorial (2 messages) you unlock the first one. Another message tells them that growing the second seed unlocks the last one. Did they read that, or did they see a locked seed and had a knee-jerk reaction?</p>
<p>I replied to their email right away and explained how to unlock them. I&rsquo;m afraid I&rsquo;ll get an email back tomorrow asking me to resubmit and throwing Flower Garden Lite at the back of the queue. I hope not, but I&rsquo;m prepared for the worst.</p>
<p>It might just be slightly annoying for hobbyist developers, but all of this is making the App Store very difficult to build a reliable, sustainable business around it. The lack of visibility, random approval process, unpredictability, and lack of direct contact make it impossible to have a reliable process or combine release dates with other events such as PR or marketing campaigns. At this point, I would even consider a &ldquo;professional&rdquo; iPhone developer account that costs $1K per year and gives you a direct contact in Apple and better visibility and predictability with the approval process. Otherwise, if things continue this way, I&rsquo;m afraid that professional developers will only put up with this for so long and are soon going to consider the iPhone as a secondary platform and they&rsquo;ll move on to other pastures like the PSP Mini or new opportunities that come up.</p>
]]></content:encoded></item><item><title>iSimulate: A Great Add-On For The iPhone Simulator</title><link>https://gamesfromwithin.com/isimulate-a-great-add-on-for-the-iphone-simulator/</link><pubDate>Fri, 28 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/isimulate-a-great-add-on-for-the-iphone-simulator/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/08/isimulate.png"&gt;&lt;img alt="isimulate" loading="lazy" src="https://gamesfromwithin.com/isimulate-a-great-add-on-for-the-iphone-simulator/images/isimulate.png" title="isimulate"&gt;&lt;/a&gt;I just had a chance to check out &lt;a href="http://www.vimov.com/isimulate/"&gt;iSimulate&lt;/a&gt;, a tool for iPhone developers created by &lt;a href="http://www.vimov.com/"&gt;Vimov&lt;/a&gt;. iSimulate is intended to complement the current iPhone simulator by adding most of the features a real iPhone has. In the spirit of full disclosure, Vimov sent me a promo code to try it out for free, but I only accepted it with the condition I could write my unfiltered impressions. So here we go.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/isimulate.png"><img alt="isimulate" loading="lazy" src="/isimulate-a-great-add-on-for-the-iphone-simulator/images/isimulate.png" title="isimulate"></a>I just had a chance to check out <a href="http://www.vimov.com/isimulate/">iSimulate</a>, a tool for iPhone developers created by <a href="http://www.vimov.com/">Vimov</a>. iSimulate is intended to complement the current iPhone simulator by adding most of the features a real iPhone has. In the spirit of full disclosure, Vimov sent me a promo code to try it out for free, but I only accepted it with the condition I could write my unfiltered impressions. So here we go.</p>
<p>iSimulate consists of two different parts: <a href="http://click.linksynergy.com/fs-bin/stat?id=aDkhM0mDflg&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;u1=gfw_isimulate&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252FWebObjects%252FMZStore.woa%252Fwa%252FviewSoftware%253Fid%253D306908756%2526mt%253D8%2526uo%253D6%2526partnerId%253D30">The iPhone app</a>, which you need to purchase through the App Store, and a static library that you link with your program. Once your app is using the library, launching the iSimulate iPhone app lets you connect your device to your app and forward accelerometer, touch, and GPS events. In other words, most of the things the simulator doesn&rsquo;t do natively.</p>
<p>iSimulate definitely passed my picky installation requirements with flying colors. I was afraid the installation would hook up with existing framework libraries, add new configurations, and in general mess up my system. Fortunately, hooking up the iSimulate library couldn&rsquo;t be easier: Copy the provided .a library anywhere you want, link with it in your app (don&rsquo;t forget the -ObjC linker flag), make sure you&rsquo;re using the Core framework, and you&rsquo;re good to go. That simple. That&rsquo;s how I want external libraries to work.</p>
<p>You don&rsquo;t even need to initialize anything. Just launch your app in the simulator, launch iSimulate on the iPhone and it detects your program running and lets you connect to it. The iPhone app itself even looks very pretty and polished. The overall package is definitely very professional-looking.</p>
<p>From there, any touch on the device is forwarded to the simulator. So you can finally do off-center multi touches, or two touches that happen at different times, or even 5-touch events (the max the iPhone support). The other big one is being able to tilt or shake your device and see the game react correctly on the simulator, which is would have been very handy when writing the accelerometer code to move flowers around in <a href="http://snappytouch.com/flowergarden">Flower Garden</a>, but would almost be necessary when you&rsquo;re making heavy use of accelerometer input for games like <a href="http://click.linksynergy.com/fs-bin/stat?id=aDkhM0mDflg&amp;u1=gfw_skyburger&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252FWebObjects%252FMZStore.woa%252Fwa%252FviewSoftware%253Fid%253D311972587%2526mt%253D8%2526uo%253D6%2526partnerId%253D30">Sky Burger</a>. Finally, it also claims to give you location information, but I didn&rsquo;t have an app I could easily test it with.</p>
<p><a href="/wp-content/uploads/2009/08/fg_accelerometer.jpg"><img alt="Flowers affected by gravity on the simulator" loading="lazy" src="/isimulate-a-great-add-on-for-the-iphone-simulator/images/fg_accelerometer.jpg" title="fg_accelerometer"></a></p>
<p><em>Flowers affected by gravity on the simulator</em></p>
<p>Another situation where iSimulate is a life savior is when trying to capture a video of your game. If you rely on multi touch or accelerometer features, then your only options are to either hack in something yourself, or dig out a physical video camera and record it the old-fashioned way (which is surprisingly time consuming and creates less-than-ideal results). With iSimulate you can still use a <a href="http://store.shinywhitebox.com/home/home.html">desktop video capture software</a> on the simulator and create a top-quality in a fraction of the time.</p>
<p>Not everything is perfect though. I thought the forwarding of touch events would be incredibly useful, until I realize I have no idea what I&rsquo;m about to tap because the program is running on the simulator, not on the device. So I&rsquo;m just making a guess about where my finger is going to land. It&rsquo;s not even like a mouse cursor that you see where it&rsquo;s going and then you click. You&rsquo;re literally tapping blind hoping you touch what you wanted. That works with a static UI, but if you have moving elements you need to touch, you&rsquo;re totally out of luck. I wonder if they could extend iSimulate to capture the image from the simulator and forward it to the iPhone. Even if they only refreshed the image a few times per second, that would be enough to make touch input a lot more friendly.</p>
<p>There&rsquo;s another big problem with touch input though. From their docs page, iSimulate works great with OpenGL apps, but doesn&rsquo;t work with the following UIKit controls: Keyboard, UIScrollView (including MKMapView), UIPickerView and UITableView. Wow! Apart from the keyboard one (no big deal, we have a real keyboard attached) the other ones are pretty major. I&rsquo;m sure they have a good reason why, but I can&rsquo;t imagine what that might be from my knowledge of how the touch even system works (anybody from Vimov care to comment on that?). Heck, I&rsquo;d even be willing to add some extra code to my app to hook directly into iSimulate input events if it means it would work with those classes. Apart from that, I found one case in Flower Garden where iSimulate failed: Touching the bouquet tag to bring up the editing mode. It&rsquo;s weird, it would let me touch-drag it to move it, but it wouldn&rsquo;t go into editing mode.</p>
<p>The accelerometer input worked flawlessly, but here iSimulate has some competition from <a href="http://code.google.com/p/accelerometer-simulator/wiki/Home">Accelerometer Simulator</a>, an open-source app plus library to forward accelerometer data from the device to the app. It&rsquo;s not nearly as slick as iSimulate, but it&rsquo;s free, so that migth be a more attractive solution for some people.</p>
<p>Overall, is iSimulate worth the $32 price tag (it&rsquo;s $15.99 at the moment)? I would say yes if you&rsquo;re developing OpenGL iPhone games with heavy use of multi touch and accelerometer input and you&rsquo;re planning on making money from them. In that case, you&rsquo;re better off spending an hour of your time polishing the game (or taking a break from programming) and buying iSimulate. However, if you&rsquo;re using UIKit objects or you just need accelerometer input, then you might be better off just using Accelerometer Simulator. If Vimov can fix the UIKit input and display the output of the simulator on the device, iSimulate would become an indispensable tool in every programmer&rsquo;s toolbox.</p>
]]></content:encoded></item><item><title>Early Bird Registration Ending For Denver OpenGL Class And 360iDev</title><link>https://gamesfromwithin.com/early-bird-registration-ending-for-denver-opengl-class-and-360idev/</link><pubDate>Thu, 27 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/early-bird-registration-ending-for-denver-opengl-class-and-360idev/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/08/OpenGL_iPhone.png"&gt;&lt;img alt="OpenGL_iPhone" loading="lazy" src="https://gamesfromwithin.com/early-bird-registration-ending-for-denver-opengl-class-and-360idev/images/OpenGL_iPhone.png" title="OpenGL_iPhone"&gt;&lt;/a&gt;For those of you still on the fence about attending my &lt;a href="http://www.mobileorchard.com/opengl"&gt;iPhone OpenGL class&lt;/a&gt; in Denver, you should sign up before this Sunday if you want to get the super-combo deal. Right now you get a total combined discount of over $300 if you sign up both for the OpenGL class and the &lt;a href="http://www.360idev.com/"&gt;360iDev conference&lt;/a&gt;. If you&amp;rsquo;re only interested in the OpenGL class, the early-bird registration ends next Friday, September 4th.&lt;/p&gt;
&lt;p&gt;Obviously I&amp;rsquo;m biased when I say the class is going to be awesome (which it is), but I can also say with total honesty that 360iDev is an incredible conference. It&amp;rsquo;s very different from &lt;a href="http://developer.apple.com/WWDC/"&gt;WWDC&lt;/a&gt;, but that&amp;rsquo;s what makes it so great: It has top-quality &lt;a href="http://www.360idev.com/sessionsschedules"&gt;content&lt;/a&gt; and &lt;a href="http://www.360idev.com/denver-2009-speakers"&gt;speakers&lt;/a&gt;, but it&amp;rsquo;s small and intimate, so you get to meet and hang out with all the other speakers and participants. It was at the first 360iDev conference back in March that I met &lt;a href="http://twitter.com/kshepherd"&gt;Keith&lt;/a&gt; and &lt;a href="http://twitter.com/owengoss"&gt;Owen&lt;/a&gt; (among &lt;a href="http://twitter.com/serban"&gt;many&lt;/a&gt; &lt;a href="http://twitter.com/byteclub"&gt;other&lt;/a&gt; &lt;a href="http://twitter.com/jasoncitron"&gt;cool&lt;/a&gt; &lt;a href="http://twitter.com/chews"&gt;developers&lt;/a&gt;) in person for the first time and that&amp;rsquo;s how &lt;a href="http://apptreasures.com"&gt;App Treasures&lt;/a&gt; was born.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/OpenGL_iPhone.png"><img alt="OpenGL_iPhone" loading="lazy" src="/early-bird-registration-ending-for-denver-opengl-class-and-360idev/images/OpenGL_iPhone.png" title="OpenGL_iPhone"></a>For those of you still on the fence about attending my <a href="http://www.mobileorchard.com/opengl">iPhone OpenGL class</a> in Denver, you should sign up before this Sunday if you want to get the super-combo deal. Right now you get a total combined discount of over $300 if you sign up both for the OpenGL class and the <a href="http://www.360idev.com/">360iDev conference</a>. If you&rsquo;re only interested in the OpenGL class, the early-bird registration ends next Friday, September 4th.</p>
<p>Obviously I&rsquo;m biased when I say the class is going to be awesome (which it is), but I can also say with total honesty that 360iDev is an incredible conference. It&rsquo;s very different from <a href="http://developer.apple.com/WWDC/">WWDC</a>, but that&rsquo;s what makes it so great: It has top-quality <a href="http://www.360idev.com/sessionsschedules">content</a> and <a href="http://www.360idev.com/denver-2009-speakers">speakers</a>, but it&rsquo;s small and intimate, so you get to meet and hang out with all the other speakers and participants. It was at the first 360iDev conference back in March that I met <a href="http://twitter.com/kshepherd">Keith</a> and <a href="http://twitter.com/owengoss">Owen</a> (among <a href="http://twitter.com/serban">many</a> <a href="http://twitter.com/byteclub">other</a> <a href="http://twitter.com/jasoncitron">cool</a> <a href="http://twitter.com/chews">developers</a>) in person for the first time and that&rsquo;s how <a href="http://apptreasures.com">App Treasures</a> was born.</p>
<p>So if you&rsquo;re on the fence, I hope you give it a try. See you in Denver!</p>
]]></content:encoded></item><item><title>Getting Started With Shaders On The iPhone 3GS</title><link>https://gamesfromwithin.com/getting-started-writing-shaders-on-the-iphone-3gs/</link><pubDate>Mon, 24 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/getting-started-writing-shaders-on-the-iphone-3gs/</guid><description>&lt;p&gt;&lt;a href="https://gamesfromwithin.com/wp-content/uploads/2009/08/shader.jpg"&gt;&lt;img alt="shader" loading="lazy" src="https://gamesfromwithin.com/getting-started-writing-shaders-on-the-iphone-3gs/images/shader.jpg" title="shader"&gt;&lt;/a&gt;I just wrote &lt;a href="http://www.mobileorchard.com/getting-started-with-opengl-es-20-on-the-iphone-3gs"&gt;an article for Mobile Orchard&lt;/a&gt; on how to get started with OpenGL ES 2.0 on the iPhone 3GS. It goes over all the steps necessary to set up a barebones project that renders a quad on screen using a vertex and a fragment shader. It&amp;rsquo;s not the most stunning thing ever visually, but I think it makes for a good starting point for OpenGL ES 2.0 projects.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/shader.jpg"><img alt="shader" loading="lazy" src="/getting-started-writing-shaders-on-the-iphone-3gs/images/shader.jpg" title="shader"></a>I just wrote <a href="http://www.mobileorchard.com/getting-started-with-opengl-es-20-on-the-iphone-3gs">an article for Mobile Orchard</a> on how to get started with OpenGL ES 2.0 on the iPhone 3GS. It goes over all the steps necessary to set up a barebones project that renders a quad on screen using a vertex and a fragment shader. It&rsquo;s not the most stunning thing ever visually, but I think it makes for a good starting point for OpenGL ES 2.0 projects.</p>
]]></content:encoded></item><item><title>Dirty Coding Tricks</title><link>https://gamesfromwithin.com/dirty-coding-tricks/</link><pubDate>Fri, 21 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/dirty-coding-tricks/</guid><description>&lt;p&gt;&lt;img loading="lazy" src="https://gamesfromwithin.com/dirty-coding-tricks/images/2.jpg"&gt;If you haven&amp;rsquo;t read it already on Game Developer Magazine, don&amp;rsquo;t miss the &lt;a href="http://www.gamasutra.com/view/feature/4111/dirty_coding_tricks.php"&gt;Dirty Coding Tricks feature article&lt;/a&gt; on Gamasutra. I contributed two &amp;ldquo;dirty tricks&amp;rdquo; used in some of my past projects.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Identity Crisis&lt;/em&gt; deals with the horrors of a CRC clash on a resource right before submitting the gold master. And &lt;em&gt;The Programming Antihero&lt;/em&gt; shows a fairly common trick in the games industry to get that extra memory after the artists and designers swear up and down that they can&amp;rsquo;t cut any more content.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img loading="lazy" src="/dirty-coding-tricks/images/2.jpg">If you haven&rsquo;t read it already on Game Developer Magazine, don&rsquo;t miss the <a href="http://www.gamasutra.com/view/feature/4111/dirty_coding_tricks.php">Dirty Coding Tricks feature article</a> on Gamasutra. I contributed two &ldquo;dirty tricks&rdquo; used in some of my past projects.</p>
<p><em>Identity Crisis</em> deals with the horrors of a CRC clash on a resource right before submitting the gold master. And <em>The Programming Antihero</em> shows a fairly common trick in the games industry to get that extra memory after the artists and designers swear up and down that they can&rsquo;t cut any more content.</p>
<p>Nothing like a good dose of reality to make everybody feel better about their own code :-)</p>
]]></content:encoded></item><item><title>Handling App Store and LinkShare Links</title><link>https://gamesfromwithin.com/handling-app-store-and-linkshare-links/</link><pubDate>Sat, 15 Aug 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/handling-app-store-and-linkshare-links/</guid><description>&lt;p&gt;One of the perks of being part of the &lt;a href="http://apptreasures.com"&gt;App Treasures label&lt;/a&gt; is that we get some nice cross-promotion with an in-game view to display other titles in the label. This list is, of course, stored in our server and pulled in through a standard UIWebView. It links to other pages with details for each of our games, and a link to buy it directly from the App Store. Everything is really straightforward, except for the App Store link.&lt;/p&gt;</description><content:encoded><![CDATA[<p>One of the perks of being part of the <a href="http://apptreasures.com">App Treasures label</a> is that we get some nice cross-promotion with an in-game view to display other titles in the label. This list is, of course, stored in our server and pulled in through a standard UIWebView. It links to other pages with details for each of our games, and a link to buy it directly from the App Store. Everything is really straightforward, except for the App Store link.</p>
<p><a href="/wp-content/uploads/2009/08/AppTreasuresWebView.jpg"><img alt="AppTreasuresWebView" loading="lazy" src="/handling-app-store-and-linkshare-links/images/AppTreasuresWebView.jpg" title="AppTreasuresWebView"></a></p>
<p>By default, the UIWebView will try to open the App Store link itself, which results in an error. What we want to do instead is intercept the request and launch it directly with an NSURLConnection so the call can be redirected to the iPhone App Store app. The best place to implement this is in the <code>-[UIWebViewDelegate webView:shouldStartLoadWithRequest:navigationType:]</code> method:</p>
<pre tabindex="0"><code>- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
    if ([[[request URL] host] isEqualToString:@&#34;phobos.apple.com&#34;])
    {
        NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[request URL]] delegate:self startImmediately:YES];
        [conn release];
        return NO;
    }
    return YES;
}
</code></pre><p>While we&rsquo;re in the topic of links, I also recently added some <a href="http://www.linkshare.com/">LinkShare</a> links to my apps. The 5% kickback for each purchase is nice, but the tracking capabilities it gives you is the real reason I wanted to use it. The way LinkShare works is by providing a custom URL that contains your referral ID to allow LinkShare to track the transaction. Unfortunately, unlike the Amazon referral program for example, LinkShare is a third party company and is not tied directly into the App Store. That means the links they provide go through click.linksynergy.com and then are redirected to the App Store. The result is that trying to follow one of those links from your app will result in Safari coming up, opening up a new page, shutting down, and then opening the App Store app. Not pretty!</p>
<p>Fortunately, there&rsquo;s a workaround. Just like we did with the App Store links, we can open the LinkShare link directly with a NSURLConnection instead of letting Safari handle it. Then, once the link resolves to the forwarded one, we can open it directly with the App Store app:</p>
<pre tabindex="0"><code>- (IBAction)buyItNow
{
    NSString* link = @&#34;http://click.linksynergy.com/fs-bin/click?........&#34;;
    NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:link]] delegate:self startImmediately:YES];
    [conn release];Â Â  Â 
}

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

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

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

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

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

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

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

	NSLog(txt);
	[txt release];
}

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

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

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

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

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

UIKIT_EXTERN_CLASS @interface UIPickerView : UIView &lt;NSCoding&gt;
{
Â //... snip....
Â  @package
Â Â Â  struct {
Â Â Â Â Â Â Â  unsigned int needsLayout:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToNumberOfComponentsInPickerView:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToNumberOfRowsInComponent:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToDidSelectRow:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToViewForRow:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToTitleForRow:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToWidthForComponent:1;
Â Â Â Â Â Â Â  unsigned int delegateRespondsToRowHeightForComponent:1;
Â Â Â Â Â Â Â  unsigned int showsSelectionBar:1;
Â Â Â Â Â Â Â  unsigned int allowsMultipleSelection:1;
Â Â Â Â Â Â Â  unsigned int allowSelectingCells:1;
Â Â Â Â Â Â Â  unsigned int soundsDisabled:1;
Â Â Â  } _pickerViewFlags;
}
</code></pre><p>See that last flag? soundsDisabled. Sounds promising, doesn&rsquo;t it? Unfortunately _pickerViewFlags has @package protection, which means I can&rsquo;t get to it. Or so the theory goes.</p>
<p>Objective C is surprisingly &ldquo;good&rdquo; about letting you get under the hood and bypass protection levels. So I tried accessing those flags with NSObject function setValueForKey, but the stubborn picker would refuse to let me have access and throw an exception instead. Now he was starting to really annoy me. After all, I&rsquo;m supposed to be working on my other project, not hacking this little app.</p>
<p>I couldn&rsquo;t stop though. It&rsquo;s not in my nature.</p>
<p>Oh yeah, Objective C is refusing to give me access to those flags? Fine. I&rsquo;ll resort to the hackiest or hacks. But I <strong>will</strong> turn that damn bit off! An object is just a block of memory really, and each member variable is located at a fixed offset from the start of the object. See where this is going? Are you horrified enough? Yup. In the debugger I saw that _pickerViewFlags was exactly 16 bytes from the start UIViewPicker. So I grabbed the pointer to the picker, moved forward to the _pickerViewFlags variable, and stomped the soundsDisabledBit. Mwahahahaha! That will teach you, annoying picker!</p>
<p>Compile, run, and&hellip;. &ldquo;click&rdquo;. WTF!?!?!? I went in the debugger and checked that I was changing the right bits. Everything was fine. Except that, somehow, the picker was ignoring that. Defeated, I gave up in disgust.</p>
<p>It was that evening when I saw a tweet from <a href="http://twitter.com/jeff_lamarche">@jeff_lamarche</a> about accessing an undocumented function to turn off the sounds in the clicker. Nice timing! He pointed me to <a href="http://iphonedevelopment.blogspot.com/2008/10/you-shouldnt-but-you-will.html">his blog post</a> about how to get a listing of all the undocumented SDK functions and how to access them from your programs. I couldn&rsquo;t believe that there was a function to do exactly what I wanted, but Apple wasn&rsquo;t exposing it. And for something so simple too!!</p>
<p>It was as simple as</p>
<pre tabindex="0"><code>@interface CustomPicker(hidden)
- (void)setSoundsEnabled:(BOOL)isEnabled;
@end
</code></pre><p>followed by</p>
<pre tabindex="0"><code>Â Â Â  [m_picker setSoundsEnabled:NO];
Â Â Â  [m_picker selectRow:settings.m_teaType inComponent:0 animated:NO];
Â Â Â  [m_picker selectRow:settings.m_teaStrength inComponent:1 animated:NO];
Â Â Â  [m_picker selectRow:settings.m_teaFormat inComponent:2 animated:NO];
Â Â Â  [m_picker setSoundsEnabled:YES];
</code></pre><p>Finally! I had defeated UIPickerView!</p>
<p>Now the catch is, you&rsquo;re not supposed to use undocumented SDK functions. Apparently that&rsquo;s grounds for getting your app rejected by Apple and having to resubmit. But I figured I had nothing to lose, and it might be an interesting learning lesson. After all, how exactly does Apple check for undocumented functionality? Do they scan the submitted executable against a set of forbidden entry points? I couldn&rsquo;t imagine that&rsquo;s a manual process. But on the other hand, there are reports of other apps getting onto the App Store using undocumented SDK features.</p>
<p>I figured, what the heck, it was a tiny little thing that wasn&rsquo;t going to hurt anyone. Might as well try it.</p>
<p><img alt="teatime" loading="lazy" src="/tea-time-11-update-gets-its-way/images/teatime.png" title="teatime">I went ahead submitted the update last Friday, and today (Tuesday) I got the official email with the approval of my new version. Not a bad turnaround time since I imagine they don&rsquo;t work weekends. It even just <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8">made it to the App Store</a> as I was writing this. Shweet!</p>
<p>I&rsquo;m still left wondering how Apple tries to monitor undocumented SDK usage. Did they not bother with my app since it was so small? Is it really a manual process? (I feel bad for the person in charge of that just thinking about it). Did they catch it and realized it was totally harmless and let it through? Only Apple knows I&rsquo;m afraid. They really should make their process both more transparent and more consistent and fair for everybody.</p>
<p>But hey, I&rsquo;m not complaining. No more annoying click at startup :-)</p>
]]></content:encoded></item><item><title>Twittering Around</title><link>https://gamesfromwithin.com/twittering-around/</link><pubDate>Tue, 27 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/twittering-around/</guid><description>&lt;p&gt;&lt;img alt="twitter_logo_s" loading="lazy" src="https://gamesfromwithin.com/twittering-around/images/twitter_logo_s.png" title="twitter_logo_s"&gt;As the 0.5% of you who are not using an RSS reader might have noticed, I&amp;rsquo;ve added a new sidebar with &lt;a href="http://twitter.com/SnappyTouch"&gt;my Twitter activity&lt;/a&gt;. I&amp;rsquo;m pretty new to Twitter&amp;hellip; actually, that&amp;rsquo;s not true. I did join quite a bit ago, but I just didn&amp;rsquo;t get it. Nobody I knew was really using it and I didn&amp;rsquo;t want to read a random stream of posts from everybody.&lt;/p&gt;
&lt;p&gt;A couple of weeks ago, prompted by seeing a few &lt;a href="http://twitter.com/VeiledGames"&gt;other&lt;/a&gt; &lt;a href="http://twitter.com/antairgames"&gt;indie&lt;/a&gt; &lt;a href="http://twitter.com/OwenGoss"&gt;iPhone&lt;/a&gt; &lt;a href="http://twitter.com/handcircus"&gt;devs&lt;/a&gt; on Twitter, I decided to give it another try. I&amp;rsquo;m glad I did! It has been really fun and useful. Unlike &lt;a href="http://www.facebook.com/home.php#/profile.php?id=507582780"&gt;Facebook&lt;/a&gt;, which is all about connecting with long-lost friends, and seeing pictures people&amp;rsquo;s new babies, I&amp;rsquo;m using Twitter exclusively for iPhone development. I keep my &lt;a href="http://twitter.com/SnappyTouch/friends"&gt;follow list&lt;/a&gt; to a relatively small amount of people, all of them independent iPhone game developers (so please, don&amp;rsquo;t feel offended if you&amp;rsquo;re a friend and I&amp;rsquo;m not following you).&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="twitter_logo_s" loading="lazy" src="/twittering-around/images/twitter_logo_s.png" title="twitter_logo_s">As the 0.5% of you who are not using an RSS reader might have noticed, I&rsquo;ve added a new sidebar with <a href="http://twitter.com/SnappyTouch">my Twitter activity</a>. I&rsquo;m pretty new to Twitter&hellip; actually, that&rsquo;s not true. I did join quite a bit ago, but I just didn&rsquo;t get it. Nobody I knew was really using it and I didn&rsquo;t want to read a random stream of posts from everybody.</p>
<p>A couple of weeks ago, prompted by seeing a few <a href="http://twitter.com/VeiledGames">other</a> <a href="http://twitter.com/antairgames">indie</a> <a href="http://twitter.com/OwenGoss">iPhone</a> <a href="http://twitter.com/handcircus">devs</a> on Twitter, I decided to give it another try. I&rsquo;m glad I did! It has been really fun and useful. Unlike <a href="http://www.facebook.com/home.php#/profile.php?id=507582780">Facebook</a>, which is all about connecting with long-lost friends, and seeing pictures people&rsquo;s new babies, I&rsquo;m using Twitter exclusively for iPhone development. I keep my <a href="http://twitter.com/SnappyTouch/friends">follow list</a> to a relatively small amount of people, all of them independent iPhone game developers (so please, don&rsquo;t feel offended if you&rsquo;re a friend and I&rsquo;m not following you).</p>
<p>My routine now consists on sitting to work with a warm cup of tea, firing up <a href="http://www.tweetdeck.com">the Twitter client du jour</a>, and let it sit in the background (without alerts, thank you). Every so often I check it out, update my status, read what other devs are up to, and get into short conversations. The effect is surprisingly similar to being back working with a team of people and having quick IM conversations with them. Don&rsquo;t get me wrong, I love working by and for myself, but I do miss the camaraderie, the interactions, and the energy of working with a team of really talented people. Twitter gives me a lot of what I&rsquo;ve been missing.</p>
<p>Last night, <a href="http://twitter.com/timhaines">@timhaines</a> put together a <a href="http://is.gd/hlhV">Google Spreadsheet of iPhone devs on Twitter</a>, along with <a href="http://is.gd/hlhv">a form to add yourself</a>. He sent out <a href="http://twitter.com/timhaines/status/1151607456">a Twitter message</a> asking people to add themselves and pass the word. The effect was stunning. Within minutes there were dozens of devs on the list, and as people continued re-tweeting the message, hundreds more were added! That&rsquo;s a great resource to hook up with your favorite iPhone developers.</p>
<p>On a similar note, <a href="http://qforq.com/">Sam Houston</a> put together a <a href="http://gameindustrytweet.com/video-game-companies-on-twitter/">list of video game companies with people on Twitter</a>. That&rsquo;s not quite as interesting for me right now, but seems like another great resource if you&rsquo;re into video game development.</p>
<p>So give Twitter a try. Especially if you&rsquo;re an indie developer working by yourself. Don&rsquo;t think of it as another Facebook, but as a way to chat and develop connections with other people.</p>
<p>See you there!</p>
]]></content:encoded></item><item><title>Speaking at iPhone Conference And A Teaser</title><link>https://gamesfromwithin.com/speaking-at-iphone-conference-and-a-teaser/</link><pubDate>Wed, 21 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/speaking-at-iphone-conference-and-a-teaser/</guid><description>&lt;p&gt;&lt;img alt="360|iDev" loading="lazy" src="https://gamesfromwithin.com/speaking-at-iphone-conference-and-a-teaser/images/8u2n8y.png" title="360|iDev"&gt;I missed the &lt;a href="http://developer.apple.com/events/iphone/techtalks/"&gt;iPhone Tech Talk World Tour&lt;/a&gt; last Fall. At the time it wasn&amp;rsquo;t a big deal because I was still soaking in all the information from the iPhone SDK docs. Now, on the other hand, I&amp;rsquo;m at the point that I&amp;rsquo;m getting into more advanced stuff, either not covered in the docs, or that it&amp;rsquo;s just plain tricky. For example, I spent all day today trying to coerce my app into sending an email with an image attachment&amp;ndash;in the end I either kind of succeeded, or I bypassed the problem, depending how you look at it. But that&amp;rsquo;s another story for another day.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="360|iDev" loading="lazy" src="/speaking-at-iphone-conference-and-a-teaser/images/8u2n8y.png" title="360|iDev">I missed the <a href="http://developer.apple.com/events/iphone/techtalks/">iPhone Tech Talk World Tour</a> last Fall. At the time it wasn&rsquo;t a big deal because I was still soaking in all the information from the iPhone SDK docs. Now, on the other hand, I&rsquo;m at the point that I&rsquo;m getting into more advanced stuff, either not covered in the docs, or that it&rsquo;s just plain tricky. For example, I spent all day today trying to coerce my app into sending an email with an image attachment&ndash;in the end I either kind of succeeded, or I bypassed the problem, depending how you look at it. But that&rsquo;s another story for another day.</p>
<p>So last week, I was excited to learn there was a new iPhone development conferenceÂ  called <a href="http://www.360conferences.com/360iDev/">360|iDev</a> (not the greatest conference name&ndash;sounds too much like an Xbox development conference). It looks like a very hands-on, for developers by developers kind of conference, instead of half-marketing, half-development like Apple&rsquo;s offerings (Yes, we&rsquo;re already on board, you don&rsquo;t have to sell us on how cool the iPhone is. We know. We&rsquo;ve banked our life and savings on it actually). The lineup of speakers looks really promising (including <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=291176027&amp;mt=8">Urban Tycoon</a> author, <a href="http://www.mikehuntington.com/">Mike Huntington</a>).</p>
<p>What really excites me the most is meeting the other attendees though. It looks like it&rsquo;s not going to be a huge conference (hundreds instead of thousands or tens of thousands like <a href="http://gdconf.com">GDC</a>), and we&rsquo;re all staying at the same hotel, so there should be plenty of opportunities to meet people, chat, trade tips, and compare horror stories over beers.</p>
<p>I actually liked the idea so much, that I decided to jump in and submit a session proposal, and the organizers very kindly accepted it (which is great because otherwise I might not have been able to have afforded going :-)). I&rsquo;ll be talking about my experience going from a AAA console development environment, to a single-person iPhone development team. Both the obvious differences, the not so obvious similarities, and how a single person can really deliver a top-notch iPhone game.</p>
<p>I encourage everybody to have a look at the <a href="http://www.360conferences.com/360iDev/">360|iDev</a> site and register if you haven&rsquo;t already. It&rsquo;s not very expensive (especially if you buy the ticker sooner, rather than later), and it&rsquo;s going to be a blast. It&rsquo;s in San Jose in early March, a couple of weeks before GDC, so no conflicts for game developers there. Also, if you&rsquo;re interested in speaking, check out their <a href="http://www.360conferences.com/360iDev/2008/12/360idev-whats-this-is-all-about-and.html">call for speakers</a> while they&rsquo;re still accepting new submissions. I hope to see some of you there!</p>
<p>On a totally different note, a couple of weeks ago, Evan at <a href="http://www.veiledgames.com/">Veiled Games</a> (<a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=299876012&amp;mt=8">Up There</a>), which is one of my favorite indie iPhone developers, promised to put <a href="http://www.veiledgames.com/blog/?p=319">a daily image with a teaser of their upcoming project</a>. This was soon picked up by Gavin at <a href="http://www.antairgames.com/blog/2009/01/10/weekly-update-14/">Antair Games</a>, who is <a href="http://www.antairgames.com/blog/2009/01/10/weekly-update-14/">letting us peek under the covers</a> of what&rsquo;s coming up after <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298155609&amp;mt=8">Sneezies</a>.</p>
<p>I figured it would be fun to follow their steps, but don&rsquo;t hold your breath of a daily update. Maybe weekly if you&rsquo;re lucky. Maybe.</p>
<p>So here&rsquo;s this week&rsquo;s teaser. Draw whatever conclusions you want from it :-)</p>
<p><img alt="gnome" loading="lazy" src="/speaking-at-iphone-conference-and-a-teaser/images/gnome.jpg" title="gnome"></p>
]]></content:encoded></item><item><title>Status: Pending Contract :-(</title><link>https://gamesfromwithin.com/status-pending-contract/</link><pubDate>Tue, 13 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/status-pending-contract/</guid><description>&lt;p&gt;&lt;img alt="pending" loading="lazy" src="https://gamesfromwithin.com/status-pending-contract/images/pending.jpg" title="pending"&gt; Based on all the horror stories I had read from other developers, I really thought I got out easy submitting Tea Time! It only took a week and a half to approve, there were no complications, and I was able to change to a company status half way through.&lt;/p&gt;
&lt;p&gt;I guess I really got out too easy and Apple had to remedy that. Today I found that Tea Time! shows up in the App Store listings, but it&amp;rsquo;s unavailable when you try to buy it. When I looked in the app management site, much to my surprise, Tea Time! was listed as &amp;ldquo;Pending Contract&amp;rdquo;.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="pending" loading="lazy" src="/status-pending-contract/images/pending.jpg" title="pending"> Based on all the horror stories I had read from other developers, I really thought I got out easy submitting Tea Time! It only took a week and a half to approve, there were no complications, and I was able to change to a company status half way through.</p>
<p>I guess I really got out too easy and Apple had to remedy that. Today I found that Tea Time! shows up in the App Store listings, but it&rsquo;s unavailable when you try to buy it. When I looked in the app management site, much to my surprise, Tea Time! was listed as &ldquo;Pending Contract&rdquo;.</p>
<p>What I thought was a relatively fast switch from individual to a company status, just propagated through their database and cancelled my previous contract. So I had to enter all the banking and tax information (exactly the same as before) and wait for the bureaucracy to approve it. So it looks like Tea Time! is going to be out of commission for a few days (or weeks or months?).</p>
<p>It really blows because it will kill whatever little momentum it had. Boy am I glad I went through this now and not with my other project!</p>
]]></content:encoded></item><item><title>Tea Time! Back Up</title><link>https://gamesfromwithin.com/tea-time-back-up/</link><pubDate>Tue, 13 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/tea-time-back-up/</guid><description>&lt;p&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;amp;mt=8"&gt;&lt;img alt="snappy" loading="lazy" src="https://gamesfromwithin.com/tea-time-back-up/images/snappy.jpg" title="Tea Time!"&gt;&lt;/a&gt;I was just pleasantly surprised to see that my new sales contract as &lt;a href="http://www.snappytouch.com/"&gt;Snappy Touch&lt;/a&gt; for the App Store was approved and that &lt;a href="http://www.snappytouch.com/teatime"&gt;Tea Time!&lt;/a&gt; is once again &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;amp;mt=8"&gt;available for sale&lt;/a&gt;. I was fearing it would be gone for days, but the blackout only lasted about a day. Not too bad.&lt;/p&gt;
&lt;p&gt;The only difference is that now it&amp;rsquo;s listed with Snappy Touch being the seller instead of my name. Will this be the end of the App Store saga? Let&amp;rsquo;s hope so.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8"><img alt="snappy" loading="lazy" src="/tea-time-back-up/images/snappy.jpg" title="Tea Time!"></a>I was just pleasantly surprised to see that my new sales contract as <a href="http://www.snappytouch.com/">Snappy Touch</a> for the App Store was approved and that <a href="http://www.snappytouch.com/teatime">Tea Time!</a> is once again <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8">available for sale</a>. I was fearing it would be gone for days, but the blackout only lasted about a day. Not too bad.</p>
<p>The only difference is that now it&rsquo;s listed with Snappy Touch being the seller instead of my name. Will this be the end of the App Store saga? Let&rsquo;s hope so.</p>
<p>In the meanwhile, a sales update for those of you curious about it: In the first three days, Tea Time! sold 83 units. On one hand, that&rsquo;s more than I expect (although I suspect that half of those are people following this blog and my announcement on Facebook). But on the other hand, it&rsquo;s nothing if you&rsquo;re trying to make a profit from it, even if it just took a couple of days to put together.</p>
<p>Granted, this is an extreme example. It has gotten exactly <strong>zero</strong> marketing of any kind, and it&rsquo;s aimed at a very specific audience. I&rsquo;m sure if a place like <a href="http://www.republicoftea.com/">Republic of Tea</a> or <a href="http://www.adagio.com">Adagio Tea</a> advertised it in their catalogs, sales would go way up. But it gives you a base line of what you can expect in the worst case.</p>
]]></content:encoded></item><item><title>The "One Day" iPhone App Experiment</title><link>https://gamesfromwithin.com/the-one-day-iphone-app-experiment/</link><pubDate>Mon, 12 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-one-day-iphone-app-experiment/</guid><description>&lt;p&gt;I&amp;rsquo;ve been working full time on an iPhone app for the last three months. Realistically, I still have another month ahead of me. Four months is nothing compared to projects for current game consoles, but it&amp;rsquo;s pretty long for an iPhone app. It&amp;rsquo;s not like I&amp;rsquo;m slacking off (I swear that playing &lt;a href="%20http://www.worldofwarcraft.com"&gt;WoW&lt;/a&gt; has nothing to do with it!), but it&amp;rsquo;s a relatively complex project for an iPhone, involving 3D graphics, procedural geometry generation, custom user interface, and network access among other things. Definitely not your everyday, quick iPhone app.&lt;/p&gt;
&lt;p&gt;&lt;img alt="teatimeitunesicon" loading="lazy" src="https://gamesfromwithin.com/the-one-day-iphone-app-experiment/images/teatimeitunesicon.png" title="teatimeitunesicon"&gt;A couple of weeks ago, I decided to take a few days off from my project to enjoy the holidays with friends and family. Of course, I couldn&amp;rsquo;t stop thinking about the project. Soon my thoughts turned to how much more I had to go, and how some parts of the development process were still unknown to me, like the Apple submission process, or making a build for distribution on the App Store.&lt;/p&gt;
&lt;p&gt;At that point, inspiration struck, and I decided to use one day during the holidays to write a quick, one-day app. That way it wouldn&amp;rsquo;t take any time away from my project and I would learn a lot from it. And maybe, just maybe, I would make a buck or two in the process.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve been working full time on an iPhone app for the last three months. Realistically, I still have another month ahead of me. Four months is nothing compared to projects for current game consoles, but it&rsquo;s pretty long for an iPhone app. It&rsquo;s not like I&rsquo;m slacking off (I swear that playing <a href="%20http://www.worldofwarcraft.com">WoW</a> has nothing to do with it!), but it&rsquo;s a relatively complex project for an iPhone, involving 3D graphics, procedural geometry generation, custom user interface, and network access among other things. Definitely not your everyday, quick iPhone app.</p>
<p><img alt="teatimeitunesicon" loading="lazy" src="/the-one-day-iphone-app-experiment/images/teatimeitunesicon.png" title="teatimeitunesicon">A couple of weeks ago, I decided to take a few days off from my project to enjoy the holidays with friends and family. Of course, I couldn&rsquo;t stop thinking about the project. Soon my thoughts turned to how much more I had to go, and how some parts of the development process were still unknown to me, like the Apple submission process, or making a build for distribution on the App Store.</p>
<p>At that point, inspiration struck, and I decided to use one day during the holidays to write a quick, one-day app. That way it wouldn&rsquo;t take any time away from my project and I would learn a lot from it. And maybe, just maybe, I would make a buck or two in the process.</p>
<p>The app itself was a very simple <a href="http://www.snappytouch.com/teatime">tea timer</a>, inspired by tea maker machines: Enter the type of tea you want, the strength, and whether it&rsquo;s loose leaves or in a bag, and it starts a timer with the correct steeping time for that particular tea. This was such a simple app, that it ended being exactly the way I had visualized the first time I thought about it.</p>
<h2 id="coding-the-app">Coding The App</h2>
<p>Just coding the app itself was an interesting learning experience. Up until that point, I had spent most of my time on the OpenGL side of the iPhone. Tea Time! on the other hand, was 100% Cocoa Touch, so that was a nice change of pace.</p>
<p>Why did it take me a day? It&rsquo;s such a trivial app that I should be able to throw it together in a few hours, right? Not quite. I had to deal with all the little quirks of Cocoa Touch, and get around the crippled functionality that Apple exposes in their API (while their own apps use a different API).</p>
<p>For example, it was a bit of a letdown to see I couldn&rsquo;t add images to the picker control. But my disappointment was immediately replaced with excitement when I saw how easy it was to subclass it and display whatever you wanted in it. Unfortunately, the excitement gave way to annoyance trying to work around some of the bugs Apple still has on the picker control.</p>
<p>It&rsquo;s <strong>really</strong> frustrating not having access to the same API Apple uses internally. I wanted to be able to turn off the iPhone while the timer was counting down, and have the device turn back on when the timer ends, just like the built-in alarm. Oh no, can&rsquo;t do. Apparently that&rsquo;s reserved for Apple. Fortunately, the longest you&rsquo;re going to steep a cup of tea is 6-7 minutes, so I just disabled the power-saving feature of the iPhone so it doesn&rsquo;t go to sleep while it&rsquo;s counting down.</p>
<p>Even for such a simple application, getting a polished user interface in place takes some effort and time. The <a href="http://developer.apple.com/tools/interfacebuilder.html">Interface Builder</a> allows me to throw a user interface together in a snap just to get the basic functionality up and running. Later, I can come back and tweak it until I&rsquo;m happy with it. Surprisingly, there are lots of things that the Interface Builder doesn&rsquo;t allow you to do, so a lot of controls have extra code to tweak some of their parameters (increasing the target area of the info button on the top right corner, or setting the background images for he start/stop buttons, which require a special stretching pattern). Looking on the bright side, it&rsquo;s very easy to combine a layout from the Interface Builder with custom code, which is a very important lesson for content-creation tools of any kind (and one that a lot of game tools get wrong!).</p>
<p>The rest of the coding time went into all the little things we don&rsquo;t usually think about: Saving preferences, remembering the last used combination of parameters, getting the right splash screen, etc. All in all, the coding was about a day&rsquo;s worth of work.</p>
<h2 id="creating-the-content">Creating The Content</h2>
<p>There&rsquo;s more to an app than code and a nice GUI layout, especially if you don&rsquo;t want it to look like a boring spreadsheet: Graphics and sounds. In my first pass, while I was coding the basic functionality, I just grabbed whatever images I found through <a href="http://images.google.com/images?hl=en&amp;q=tea+cup&amp;btnG=Search+Images&amp;gbv=2">Google Images</a> and threw them in. Then, once the app was pretty much finished, I set to replace them.</p>
<p><img alt="Tea cup" loading="lazy" src="/the-one-day-iphone-app-experiment/images/tea_cup_1.jpg" title="tea_cup_1"></p>
<p><em>Original photo of my tea cup that became the icon for Tea Time!</em></p>
<p>That&rsquo;s harder than it sounds because I&rsquo;m not a graphic designer. I&rsquo;m semi-proficient at <a href="http://www.gimp.org/">the Gimp</a>, but that&rsquo;s about it. I do quite a bit of photography and I love tea though, so I decided to take pictures of the tea I was preparing at home. The main icon of for Tea Time! is just my tea mug with the tea I was having that morning.</p>
<p>The images had to be processed in the Gimp quite a bit. Tweaked colors and brightness, removed background objects, and even altered to fit the constraints of the GUI. For example, the little cups in the picker are the same picture that was then carefully colorized in the Gimp to match different tea types.</p>
<p>For the alarm sound, I was hoping to be able to play the system alarm sounds that come with the iPhone. But again, Apple lets us down by not giving us access to those (Why not???). So I hit a couple web sites with free sounds, selected a few that I liked, and tweaked them with <a href="http://audacity.sourceforge.net/">Audacity</a> to get the right length and sampling rate.</p>
<p>It was a really fun process getting all the content ready. I really enjoyed it and it was a nice break from coding, but it sucked almost another full day of work. So my &ldquo;one day&rdquo; app, was already almost up to two days. But at least I was done now. Right?</p>
<h2 id="submitting-the-app">Submitting The App</h2>
<p>I had done ad-hoc builds before, but I hadn&rsquo;t prepared one for submission to the App Store. So I had to figure that out: Create a new distribution certificate, create a new configuration in XCode, test it&hellip; Not too bad.</p>
<p>Then I had to sign up for iTunes Connect and agree to a bunch of legalese non-sense. It was all done online and really quick, so that wasn&rsquo;t a problem either. Finally I was ready to submit the app and be done with it. I had to write up a description, figure out the categories it would be listed under, take screenshots, and prepare a high-res cover art. I get all that ready, I fill out the submission form, and press submit. Done!</p>
<p>Oh wait, I get a message about not being able to get paid until I get a contract in place. What? Apparently when I signed up for iPhone development that only covered free applications, but I needed to set up a new contract in place with Apple if I was going to sell anything. So I had to enter bank ids, account numbers, tax information, and everything else. Once all that information was in place, my contract was in &ldquo;Reviewing&rdquo; state, and a couple days later it was approved without any hitches. Be warned that if you&rsquo;re not in the US, apparently you have to mail a physical form to them before they approve the contract, so the process is likely to be much longer.</p>
<p>Along with the price (a very obvious $0.99), I had to set the &ldquo;Availability date&rdquo; for the app. I had read horror stories of developers who finally had their app approved, just to find it buried ten pages into the &ldquo;New Releases&rdquo; list in iTunes. The guys over at <a href="http://www.veiledgames.com/blog/?p=183">Veiled Games</a>, explained how the release date is a combination of when the app is approved and the availability date you set. So I set the availability date to two weeks in the future and was ready to tweak it if necessary.</p>
<p>Are we done yet? Not quite. The submission page wanted a URL for a web page describing the app, and I didn&rsquo;t have anything ready. I didn&rsquo;t want to just point to a page in this blog, and I had been thinking that I should set up a company as a real legal entity for doing iPhone development and consulting. Fortunately, I had gone through this process before with Power of Two Games, so it was relatively easy and painless, especially since this was a single-member LLC. So the rest of the day was spent coming up with a company name (Snappy Touch), registering the domain (<a href="http://www.snappytouch.com">http://snappytouch.com</a>), registering the LLC (in the state of Oregon no less because it&rsquo;s a lot cheaper than California), installing Wordpress in the new domain, and setting up a <a href="http://www.snappytouch.com/teatime">basic page describing Tea Time!</a>.</p>
<p>Finally done! Total time: Three days.</p>
<h2 id="waiting-and-waiting">Waiting And Waiting</h2>
<p>But Tea Time! wasn&rsquo;t on the App Store yet. It had just entered the review process. Now I had to wait for Apple to approve it (or reject it so I can fix it). I heard from other developers that the usual wait time was about two weeks, but between this coinciding with the new year, and Apple getting swamped with submissions for the holidays, I figured I would be more like three or four weeks. Glad nothing was riding on this app getting out quickly.</p>
<p>A few days later, when I was checking out the info for Tea Timer! in the Apple submission site, while it was still in review, I was shocked to see it was listed as requiring SDK 2.2. That made no sense! I made a point to develop it for SDK 2.0 so every iPhone and iPod Touch user could buy it. I made really sure I selected SDK 2.0 when I created the iTunes distribution build. What gives? Apparently just building against SDK 2.0 wasn&rsquo;t enough. I actually had to change the project settings to set SDK 2.0 as the default. That&rsquo;s a sneaky one!</p>
<p>So what to do? I rejected my own binary and uploaded a new, updated one. This one was correctly listed as requiring SDK 2.0. I wasn&rsquo;t too happy at having to do that because I&rsquo;m sure it put me back to the end of the line, but this is exactly the kind of thing I was hoping to learn with Tea Time! in a no-pressure situation.</p>
<p>Waiting is no fun, so I made things a bit more interesting. Since I had gone to the trouble of creating a legal company, I decided to change my Apple Developer account to be a company instead of an individual. That way the company information would show up correctly in iTunes whenever Tea Time! was available. I figured this would be a matter of checking off a checkbox in my account settings, but apparently not. I had to email the Apple Developer Connection support with the request, wait a few days for an answer, and then provide some legal proof that the company existed (like the articles of incorporation). Once I emailed those, they initiated the conversion process, during which time I was locked out of my account for three days.Â  What does it take to change one bit in my account record??? Fortunately I had nothing else better to do than wait by this time, and it wasn&rsquo;t impeding any work on my other project.</p>
<h2 id="finally">Finally!</h2>
<p>The very next day after getting changed over as a company status, I got the much-awaited email from Apple announcing that Tea Time! was approved. That was just a week and a half after my initial submission. That was fast, especially considering I re-submitted the binary half way through. I reset my availability date to that day, and within a couple of hours, <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8">there it was, in the App Store</a>. Mission accomplished!</p>
<p>Now, I get to learn about the sales reports, and, if I ever sell enough units, getting payments from Apple. They won&rsquo;t make a payment until you accumulate at least $250 in profit from a single territory, so I&rsquo;m not holding my breath for that one :-)</p>
<p>The &ldquo;one day&rdquo; app really took three days of work plus a week and a half of waiting. All in all, two weeks from idea to the moment it was available on the App Store. The process could be faster, but it wasn&rsquo;t too bad. The experience was a lot of fun, and I certainly learned a lot from my mistakes and what things to watch out for next time, when it really counts.</p>]]></content:encoded></item><item><title>Tea Time! Available on The App Store Now!</title><link>https://gamesfromwithin.com/first-iphone-app-available-on-the-app-store-now/</link><pubDate>Fri, 09 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/first-iphone-app-available-on-the-app-store-now/</guid><description>&lt;p&gt;My first iPhone app, &lt;a href="http://www.snappytouch.com/teatime"&gt;Tea Time!&lt;/a&gt;, just hit the &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;amp;mt=8"&gt;App Store&lt;/a&gt; today! Tea lovers of the world: Go get it now.&lt;/p&gt;
&lt;p&gt;What am I doing writing a little app like that? Don&amp;rsquo;t worry, that&amp;rsquo;s not what I&amp;rsquo;ve been doing for the last few months :-) It was an experiment to see how quick I could put a simple app together and getting the experience of going through the whole cycle with the App Store. Tomorrow I&amp;rsquo;ll write an entry with all that I&amp;rsquo;ve learned so far.&lt;/p&gt;</description><content:encoded><![CDATA[<p>My first iPhone app, <a href="http://www.snappytouch.com/teatime">Tea Time!</a>, just hit the <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301127187&amp;mt=8">App Store</a> today! Tea lovers of the world: Go get it now.</p>
<p>What am I doing writing a little app like that? Don&rsquo;t worry, that&rsquo;s not what I&rsquo;ve been doing for the last few months :-) It was an experiment to see how quick I could put a simple app together and getting the experience of going through the whole cycle with the App Store. Tomorrow I&rsquo;ll write an entry with all that I&rsquo;ve learned so far.</p>
<p>Enjoy your tea!</p>
]]></content:encoded></item><item><title>San Diego iPhone Developer Gathering Next Week</title><link>https://gamesfromwithin.com/san-diego-iphone-developer-gathering-next-week/</link><pubDate>Thu, 08 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/san-diego-iphone-developer-gathering-next-week/</guid><description>&lt;p&gt;Are you doing iPhone development? Are you in the San Diego area? Come meet a bunch of local iPhone developers next week. It will be an informal gathering, just to get to know each other, trade war stories, and bitch about the App Store over &lt;a href="http://www.karlstrauss.com/PAGES/Locations/Menu/Start.htm#5"&gt;pizza&lt;/a&gt; and &lt;a href="http://www.karlstrauss.com/PAGES/Beer/Start_Beer.htm"&gt;beers&lt;/a&gt;. Feel free to invite anybody interested as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: Wednesday January 14th from 7PM until whenever &lt;strong&gt;Where&lt;/strong&gt;: &lt;a href="http://maps.google.com/maps?q=9675+Scranton+Rd,+San+Diego,+CA&amp;amp;oe=utf-8&amp;amp;client=firefox-a&amp;amp;ie=UTF8&amp;amp;split=0&amp;amp;ll=32.899552,-117.196655&amp;amp;spn=0.055562,0.092525&amp;amp;z=14&amp;amp;iwloc=addr"&gt;Karl Strauss Brewery in Mira Mesa&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hope to see you all there!&lt;/p&gt;</description><content:encoded><![CDATA[<p>Are you doing iPhone development? Are you in the San Diego area? Come meet a bunch of local iPhone developers next week. It will be an informal gathering, just to get to know each other, trade war stories, and bitch about the App Store over <a href="http://www.karlstrauss.com/PAGES/Locations/Menu/Start.htm#5">pizza</a> and <a href="http://www.karlstrauss.com/PAGES/Beer/Start_Beer.htm">beers</a>. Feel free to invite anybody interested as well.</p>
<p><strong>When</strong>: Wednesday January 14th from 7PM until whenever <strong>Where</strong>: <a href="http://maps.google.com/maps?q=9675+Scranton+Rd,+San+Diego,+CA&amp;oe=utf-8&amp;client=firefox-a&amp;ie=UTF8&amp;split=0&amp;ll=32.899552,-117.196655&amp;spn=0.055562,0.092525&amp;z=14&amp;iwloc=addr">Karl Strauss Brewery in Mira Mesa</a></p>
<p>Hope to see you all there!</p>
]]></content:encoded></item><item><title>Break That Thumb For Best iPhone Performance</title><link>https://gamesfromwithin.com/break-that-thumb-for-best-iphone-performance/</link><pubDate>Mon, 05 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/break-that-thumb-for-best-iphone-performance/</guid><description>&lt;p&gt;I haven&amp;rsquo;t started doing any real performance optimizations on my iPhone app yet. I pretty much ported it from the original PC version, saw that it was running rather slow (2-3 fps) so I changed the number of elements on the screen until it was an &amp;ldquo;acceptable&amp;rdquo; 15 fps and left it there until I had time to come back and optimize things towards the end.&lt;/p&gt;
&lt;p&gt;I even ran it through some of the iPhone performance gathering tools and saw that it was spending half the time in the simulation and half the time rendering. A bit surprising, but it&amp;rsquo;s not like I had much to compare it against since this was my first performance-intensive iPhone app.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I haven&rsquo;t started doing any real performance optimizations on my iPhone app yet. I pretty much ported it from the original PC version, saw that it was running rather slow (2-3 fps) so I changed the number of elements on the screen until it was an &ldquo;acceptable&rdquo; 15 fps and left it there until I had time to come back and optimize things towards the end.</p>
<p>I even ran it through some of the iPhone performance gathering tools and saw that it was spending half the time in the simulation and half the time rendering. A bit surprising, but it&rsquo;s not like I had much to compare it against since this was my first performance-intensive iPhone app.</p>
<p>That was until this morning. Prompted by some of the comments in my previous post, I did a quick search about the iPhone floating-point performance. I had heard conflicting information on it: does it have hardware floating-point support? do you have to use fixed-point numbers for best performance? Apple is very tight-lipped about the specific hardware specs of the iPhone, which seems very strange to those of us coming from a console background. But people have been able to determine that the CPU is a 32-bit RISC <a href="http://www.arm.com/products/CPUs/ARM1176.html">ARM1176JZF</a>. The good news is that it have a full floating-point unit, so we can continue writing math and physics code the way we do in most platforms.</p>
<p>The ARM CPU also has <a href="http://www.arm.com/products/CPUs/archi-thumb.html">an architecture extension called the Thumb</a>. It seems to be a special set of 16-bit bitcodes that claim to improve performance. I image the performance increase comes from a smaller code footprint and faster code fetching and processing. As a bonus, you also get a smaller memory footprint, so it seems like a win for a lot of mobile platforms. XCode comes with the option to generate Thumb code turned on by default.</p>
<p>But, and this is a <strong>huge</strong> but, it seems that floating point operations cause the program to switch back and form between Thumb mode and regular 32-bit mode. I would be interesting to look at the assembly generated, but I haven&rsquo;t had time to do that yet. So the more floating-point calculations you do, the less of performance gain you&rsquo;ll get from Thumb optimizations. Or, in the extreme, you might even get a performance degradation.</p>
<p>Most 3D games are very floating-point intenstive, and my app is no different, so I decided to turn off Thumb code generation on a whim. The results:</p>
<ul>
<li>Thumb code generation ON (default): 15 fps</li>
<li>Thumb code generation OFF: 39 fps</li>
</ul>
<p>Whoa!!! That&rsquo;s a saving of 41 ms per frame! That has to be the optimization with most bang for the time spent on it that I&rsquo;ve ever done. This also probably means that my app is now totally render-bound, which is good news. I&rsquo;m sure I can optimize tons of stuff there</p>
<p>So if you&rsquo;re doing any kind of a 3D game, <em>turn off Thumb code generation</em>. Now!</p>
<p><em>Edit:</em> I realized I never explained how to turn the Thumb code generation off! Oops. Go to your project settings, add a new User-Defined setting called: GCC_THUMB_SUPPORT and set it to NO. That simple (but surprisingly there wasn&rsquo;t an already existing setting to check it on and off).</p>
<p><img alt="thumb" loading="lazy" src="/break-that-thumb-for-best-iphone-performance/images/thumb.png" title="thumb"></p>
]]></content:encoded></item><item><title>iPhone from A Game Developer's Perspective: The iPhone API</title><link>https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-the-iphone-api/</link><pubDate>Mon, 05 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-the-iphone-api/</guid><description>&lt;p&gt;Apple is very aware that a crucial aspect to the success of a new platform is getting developers on board. Requiring a Mac for all iPhone development isn&amp;rsquo;t a good start. That&amp;rsquo;s the first barrier of entry for a lot of developers, like me, who came from a Linux or Windows background. Strike one. Objective C, even though I have come to like it, isn&amp;rsquo;t exactly a hot, popular language (although &lt;a href="http://www.google.com/trends?q=%22objective+C%22"&gt;that&amp;rsquo;s changing a bit&lt;/a&gt;). Strike two. Fortunately, Apple doesn&amp;rsquo;t strike out and gets everything else right. They provide a top-notch development environment, tools, and great APIs.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t worry, I&amp;rsquo;m not going to get into the details of the iPhone API. You can get all that and more from &lt;a href="http://developer.apple.com/iphone/index.action"&gt;Apple&amp;rsquo;s iPhone development&lt;/a&gt; web site. I&amp;rsquo;m just going to talk about my experience starting with a new set of APIs and how they hold up in the process of a full project development.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Apple is very aware that a crucial aspect to the success of a new platform is getting developers on board. Requiring a Mac for all iPhone development isn&rsquo;t a good start. That&rsquo;s the first barrier of entry for a lot of developers, like me, who came from a Linux or Windows background. Strike one. Objective C, even though I have come to like it, isn&rsquo;t exactly a hot, popular language (although <a href="http://www.google.com/trends?q=%22objective+C%22">that&rsquo;s changing a bit</a>). Strike two. Fortunately, Apple doesn&rsquo;t strike out and gets everything else right. They provide a top-notch development environment, tools, and great APIs.</p>
<p>Don&rsquo;t worry, I&rsquo;m not going to get into the details of the iPhone API. You can get all that and more from <a href="http://developer.apple.com/iphone/index.action">Apple&rsquo;s iPhone development</a> web site. I&rsquo;m just going to talk about my experience starting with a new set of APIs and how they hold up in the process of a full project development.</p>
<h2 id="starting-out">Starting Out</h2>
<p>Apple has done a great job holding the hand of developers new to the iPhone. As soon as you sign up for iPhone development, you&rsquo;ll have access to several &ldquo;Getting Started&rdquo; documents and videos. Some of the videos are a bit on the fluffy, advertising side (&ldquo;look at our new platform, it&rsquo;s sooo cool!&rdquo;), but they&rsquo;re not a bad intro anyway. The docs on the other hand are pure gold. They&rsquo;re a perfect introduction but with a fair amount of detail as well. They cover everything, from UI, to graphics and sound, to platform-specific features such as the accelerometer. I still find myself referring back to those every so often.</p>
<p>When the &ldquo;Getting Started&rdquo; docs aren&rsquo;t enough, you have a full reference of all the classes and APIs at your fingertips, both online and through the XCode help system. I found the quality of the class reference to be pretty good. Usually, when something isn&rsquo;t clear from the function name, the help is good at clarifying things.</p>
<p>I have to admit that I&rsquo;m not a read-the-manual-first kind of guy. So while all those documents are great, and I use them a lot now, that&rsquo;s not how I started out. Apple provides a bunch of sample code, covering all the major APIs, so I just downloaded the ones I was interested in, compiled them and fired them up. Then I used the docs to answer my questions about what the code was doing. The Crash Landing project was a perfect example of how to get started with games. I must have spent a whole day just pouring over that code the day I got my hands on the SDK.</p>
<p>Keep in mind that while Apple does a great job of getting the experienced developer up and running on the iPhone, they&rsquo;re certainly not catering to new programmers. It&rsquo;s a shame because the iPhone is such a fun, little platform, that I could see lots of kids wanting to jump in and getting their first real programming experience there. I hope that books and other resources pop up with that audience in mind.</p>
<h2 id="low-level-stuff">Low Level Stuff</h2>
<p>Things will look very familiar at the bottom of the API chain. Most of the low-level functionality can be accessed through pretty standard POSIX libraries: thread, file IO, sockets, etc,Â  all in straight C. My code ported over to using this libraries without having to make a single change.</p>
<p>As game developers, the first thing that we worry about is how are we going to do graphics. Fortunately, the iPhone includes an OpenGL implementation, so that&rsquo;s very familiar territory. Specifically, it&rsquo;s <a href="http://www.khronos.org/opengles/1_X/">OpenGL ES 1.1</a> with a few extensions thrown in. The <a href="http://toucharcade.com/2008/07/07/under-the-hood-the-iphones-gaming-mettle/">hardware itself</a> is a fixed-function PowerVR chip with hardware vertex processing and texture combiners. Very 1999 :-) All of that makes writing 3D graphics app on the iPhone a breeze, even if <a href="http://www.glbenchmark.com/phonedetails.jsp?benchmark=pro&amp;D=Apple%20iPhone&amp;testgroup=lowlevel">performance isn&rsquo;t top notch</a>. At least they didn&rsquo;t throw yet another proprietary API at us.</p>
<p>Surprisingly, the online help falls short with OpenGL. There are actually hardly any docs on that, and they mostly cover a couple functions to interface with their view system. I guess they figured you can just go to the internet and <a href="http://www.khronos.org/opengles/sdk/1.1/docs/man/">read all about it there</a>, but I would have expected them to integrate them with the rest of the references at least.</p>
<p>OpenGL meshes relatively well with the user interface libraries, in the sense that you can render to almost any surface and combine it with other user interface elements. Unfortunately, it seems that putting any user interface views on top of OpenGL causes pretty major performance hits, so the integration isn&rsquo;t perfect.</p>
<p>I haven&rsquo;t used it yet, but Apple also provides the <a href="http://connect.creativelabs.com/openal/default.aspx">Open AL API</a> for 3D sound. Again, props to Apple for sticking to an existing API.</p>
<h2 id="cocoa-touch">Cocoa Touch</h2>
<p>This is where the real fun starts. At least for me, this is all new territory. Mac programmers should be a lot more familiar with it. Cocoa Touch are the libraries for all the high-level user interface and accessing device-specific features. Since the iPhone is such an interface-centric device, this is where a lot of your time is going to be spent. The exception is if you decide to make a game that is 100% OpenGL, user interface and all. In that case, you&rsquo;ll only be using this layer to access a few things, like touch inputs and accelerometer readings.</p>
<p>My impression coming to Cocoa Touch from an MFC/WTL/.Net background and no Cocoa experience was a breath of fresh air. Sure, the interface on the iPhone is simpler than the horrible monstrosities you can create with MFC, so maybe that&rsquo;s why the API seems simpler. But whatever the reason, it just makes sense. You have one window, views, and view controllers. Once you get how they relate, the rest just comes together. I find myself guessing how things should be and getting it right most of the time. That tells me they&rsquo;re doing something right (for the record, I never manage to guess anything with the .Net framework and it&rsquo;s always a struggle).</p>
<p>When something isn&rsquo;t obvious, you can look it up in the extensive online help, or just crack open the header file and look at what properties each class exposes. The class hierarchy isn&rsquo;t too crazy, and each level adds a manageable number of functions.</p>
<p>It&rsquo;s also really easy to extend controls and create your own versions to have special behaviors or even draw them in different ways. To me it was always a pain to create custom controls in MFC with their own rendering, but here it&rsquo;s a breeze.</p>
<p>I also really like how a lot of controls don&rsquo;t own your data, or even keep a copy that you need to refresh, but simply ask you for it when they need it. For example the picker (which you can quickly guess it&rsquo;s called UIPickerView) will ask a delegate how many columns and rows to display and what data or views to render in each of them. Nice and simple.</p>
<p>We&rsquo;re done with the fan boy raving. Not everything is perfect and some things are downright annoying.</p>
<p>Initialization of views and view controllers can be a bit weird. Sometimes the initFromNib gets called, sometimes it&rsquo;s the viewDidLoad, sometimes it&rsquo;s none of those and I have to hook up the loadView function, and sometimes I just have to make one myself. All depending on how the particular view gets created. Annoying.</p>
<p>Then there are some bugs and weird behaviors that you have to put up with. Because Apple doesn&rsquo;t provide the full source code, you can&rsquo;t just fix them or copy them and make your own version. Some controls are pretty elaborate so writing them from scratch is quite time consuming. For example, the segment control behaves as a toggle if you only have two segments, but as a button if you have more than two. There is a boolean variable that allows you to turn the toggle behavior off, but, guess what, it&rsquo;s protected. So to make such a simple change, you need to create your own class and extend the UISegmentedControl. Doh!</p>
<p>Sometimes you&rsquo;re not even so lucky. Looking at the header file for the UIPickerView class I noticed there was a flag to turn off the sound it makes when rotating the wheels. But it was marked as private (as @package actually), so I couldn&rsquo;t do a thing about it. Double doh!</p>
<p>And it&rsquo;s more than a flag here or there. Maybe you&rsquo;d like to change the background of the picker, or the way the selection works? Out of luck. That&rsquo;s all neatly wrapped up inside the picker class itself and you have no access to it. If you want to make a change, you need to reimplement it all from scratch. Hopefully Apple will continue refining the API and exposing more functionality where needed.</p>
<p>All of this leads me to my number one complaint about the Cocoa Touch API. It&rsquo;s something that annoys me profoundly and I can&rsquo;t believe Apple is doing. <em>The API you have exposed to you is different than the one Apple uses internally</em>. Why oh, why?? It violates everything I hold true and sacred about library and API design. I understand their wish to keep thing simple and clean, and to provide good documentation to everything is there. They managed to do those things admirably well. But why not provide whatever API calls they consider to be &ldquo;expert&rdquo; without documentation and a big warning saying you&rsquo;re on your own? Why???</p>
<p>But wait, it gets better. Apple has been actively rejecting apps from the App Store from people who went to the trouble of reverse engineering the libraries and calling undocumented functionality from them. What is up with that? Is it Apple&rsquo;s way of ensuring future compatibility? Then how are their own apps going to work when changes happen since they&rsquo;re obviously using a bunch of undocumented features. Not only that, but <a href="http://technologyexpert.blogspot.com/2008/12/app-store-incorrectly-rejects-app-over.html">they get it wrong sometimes</a>!</p>
<p>I thought this was as bad as it was going to get, but wait, there&rsquo;s more. Apple is playing favorites. So if you&rsquo;re a big company and have two Os in your name (and your name doesn&rsquo;t start with M) then you get to <a href="http://arstechnica.com/news.ars/post/20081126-google-admits-to-using-undocumented-api-in-google-mobile-app.html">use their undocumented APIs</a> without getting rejected. How totally annoying is that?</p>
<h2 id="all-in-all">All In All&hellip;</h2>
<p>Apart from the questionable decisions of what to expose in the API and a few stray bugs, the iPhone has a great set of APIs to develop for. I found it really easy to get into them and became productive in no time. If only they would expose the full functionality, it would be an almost perfect setup.</p>]]></content:encoded></item><item><title>2009: The Year of The Indie Developer?</title><link>https://gamesfromwithin.com/2009-the-year-of-the-indie-developer/</link><pubDate>Thu, 01 Jan 2009 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/2009-the-year-of-the-indie-developer/</guid><description>&lt;p&gt;A few days ago I went out to lunch with some friends and they brought up an interesting thought: Will 2009 be the year of the indie developer?&lt;/p&gt;
&lt;p&gt;I loved the sound of that! I&amp;rsquo;ve been an indie developer for a year and a half, and I&amp;rsquo;m seeing &lt;a href="http://appyentertainment.com/"&gt;more&lt;/a&gt; &lt;a href="http://www.torpexgames.com/index.php"&gt;and&lt;/a&gt; &lt;a href="http://2dboy.com/"&gt;more&lt;/a&gt; people taking tha route. I think indie development is necessary for a healthy game development industry. Where else are people going to try weird ideas, experimental development techniques, an commercially unproven designs? I think it&amp;rsquo;s a sign of maturity that we&amp;rsquo;re seeing a need filled by independent development next to the Maddens and Worlds of Warcraft and other chart-toppers.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A few days ago I went out to lunch with some friends and they brought up an interesting thought: Will 2009 be the year of the indie developer?</p>
<p>I loved the sound of that! I&rsquo;ve been an indie developer for a year and a half, and I&rsquo;m seeing <a href="http://appyentertainment.com/">more</a> <a href="http://www.torpexgames.com/index.php">and</a> <a href="http://2dboy.com/">more</a> people taking tha route. I think indie development is necessary for a healthy game development industry. Where else are people going to try weird ideas, experimental development techniques, an commercially unproven designs? I think it&rsquo;s a sign of maturity that we&rsquo;re seeing a need filled by independent development next to the Maddens and Worlds of Warcraft and other chart-toppers.</p>
<p>I think 2008 will go down as the year that indie games made it to the big time: <a href="http://braid-game.com/">Braid</a>, <a href="http://www.torpexgames.com/games.php">Schizoid</a>, and <a href="http://www.worldofgoo.com/">World of Goo</a> are just the top of the iceberg. It showed that it was possible to become an indie developer and make a living from it. 2009 has to be the year that indie development really explodes, right? The trend is certainly there. I&rsquo;m constantly hearing about people or even whole teams leaving <a href="http://www.ea.com/">large</a> <a href="http://www.activision.com/index.html">development</a> <a href="http://www.ubi.com/">houses</a> and starting their own, small companies. These developers are not trying to become the next EA, but they want to keep things small, creative, and, above all, fun.</p>
<p>If the only path for indie game development were downloadable console games on XBLA and PSN, the future wouldn&rsquo;t look so bright. I used to be really excited about those platforms, but the restrictive zeal of Microsoft and Sony, the dingy royalty deal on XBLA, plus the high-development costs required for most games in those platforms, makes them very difficult to develop for and make any money from them. More and more, I&rsquo;m hearing of donwloadable console titles with budgets around a million dollars. A million dollars!! That&rsquo;s &ldquo;just&rdquo; a tad bit out of my indie pocket range.</p>
<p>Fortunately there are other paths. We have the usual PC market, which seems to be on its way to being abandoned by the major players but leaves a void for indies. <a href="http://www.bit-blot.com/aquaria/">Some</a> <a href="http://www.wolfire.com/lugaru">guys</a> seem to be doing well there, especially if you consider the Mac and Linux markets in addition to Windows.</p>
<p>Then there&rsquo;s Nintendo&rsquo;s <a href="http://www.nintendo.com/wii/wiiware">WiiWare</a>, which seems surprisingly much more open than the Xbox360 or PS3. I don&rsquo;t have any friends who are personally developing for WiiWare, but I hear the barriers of access are not insurmountable. I&rsquo;d love to see some sales numbers though. Nintendo certainly has the name to attract players and developers. Maybe they need to open up their DS development a bit too. <a href="http://www.bobsgame.com">Bob would like that</a> for sure!</p>
<p>And then we have our last, best hope for indie game development: The iPhone <a href="#note1">[1]</a>.</p>
<p>The iPhone seems to hit all the right marks: Hardware advanced enough that you can develop really interesting and good-looking games, yet simple enough that one or two people can create a top title. Very open (<a href="http://developer.apple.com/iphone">the SDK and tools are available for free</a> to anyone!!) but with a very clear <a href="http://www.apple.com/iphone/appstore/">distribution channel</a>.</p>
<p>Given the low prices of games (between $0.99 and $10) on the iPhone, not only is it possible to make great games with a team of two people, but actually having larger teams can make development much less profitable. I can&rsquo;t imagine how EA or Maxis are making any money from their iPhone games if they put even just 10 or 20 people to work on them for a few months.</p>
<p>In order for indies to succeed in the app store, it&rsquo;s important that we get enough visibility. Right now, the big money is on the top lists that Apple publishes which are unfortunately out of reach for most of us. A trend I&rsquo;ve noticed lately is that big publishers are starting to elbow out indies out of the <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewCustomPage?name=pageiTunes2008_Apps">Top Ten charts</a>. I hope that&rsquo;s not a trend that continues much further.</p>
<p>I&rsquo;m glad to see that the app store has related links when you browse a product, and also a variety of independent web sites that are appearing trying to sort the iWheat from the iChaff. It&rsquo;s a start, but we need more initiatives along those lines. In the meanwhile, support your indie iPhone developers. Or at least go out of your way to learn a bit more about them. If you haven&rsquo;t seen it already, check out the <a href="http://www.newyearappblowout.com/">New Year&rsquo;s App Blowout Sale</a> and pick up <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298155609&amp;mt=8">Sneezies</a>, <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=299876012&amp;mt=8">Up There</a>, and <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=294789951&amp;mt=8">Mouse House</a>. All three totally adorable, very polished games.</p>
<p>Happy New Year 2009 to everybody! I&rsquo;m sure this year will bring a lot of surprises and interesting developments.</p>
<p>[1]Yes, I shamelessly stole that line from <a href="http://babylon5.warnerbros.com/">my favorite sci-fi show</a>.</p>]]></content:encoded></item><item><title>iPhone from A Game Developer's Perspective: Objective C</title><link>https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-objective-c/</link><pubDate>Tue, 30 Dec 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/iphone-from-a-game-developers-perspective-objective-c/</guid><description>&lt;p&gt;I have a feeling I don&amp;rsquo;t fit the profile for the average iPhone developer. I bet a lot of them come from Mac or Web development backgrounds. On the other hand, I come from over the years of professional game development on consoles and PCs, which gives me a different perspective on things. When I hear developers complaining about Apple&amp;rsquo;s approval process to put something on the App Store, I can&amp;rsquo;t help but laugh and wish they had a taste of submitting an Xbox or PS3 game for approval. Now, that&amp;rsquo;s a real bitch! On the other hand, long-time Mac developers will be throwing around all these API names and classes like everybody learned them in kindergarden.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve only been doing iPhone development for a few months, so I don&amp;rsquo;t claim to know everything. But they have been some intensive couple of months, that&amp;rsquo;s for sure. This is my attempt to share my experiences, and hopefully encourage more game developers to take the leap and consider this really fun little machine.&lt;/p&gt;
&lt;p&gt;As I explained in a previous post, I was a Mac-virgin. Sure, I had used one here and there, but never as my primary platform. Not only was I able to get up to speed and functional in a matter of days, but I totally love it and switched to it as my main computer. So, with that out of the way, how about the iPhone development itself? Over the next few days (or weeks, depending how busy I get), I&amp;rsquo;ll try and cover the major areas of iPhone development that I&amp;rsquo;ve experienced so far.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s get the most obvious one out of the way: &lt;a href="http://en.wikipedia.org/wiki/Objective_C"&gt;Objective C&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I have a feeling I don&rsquo;t fit the profile for the average iPhone developer. I bet a lot of them come from Mac or Web development backgrounds. On the other hand, I come from over the years of professional game development on consoles and PCs, which gives me a different perspective on things. When I hear developers complaining about Apple&rsquo;s approval process to put something on the App Store, I can&rsquo;t help but laugh and wish they had a taste of submitting an Xbox or PS3 game for approval. Now, that&rsquo;s a real bitch! On the other hand, long-time Mac developers will be throwing around all these API names and classes like everybody learned them in kindergarden.</p>
<p>I&rsquo;ve only been doing iPhone development for a few months, so I don&rsquo;t claim to know everything. But they have been some intensive couple of months, that&rsquo;s for sure. This is my attempt to share my experiences, and hopefully encourage more game developers to take the leap and consider this really fun little machine.</p>
<p>As I explained in a previous post, I was a Mac-virgin. Sure, I had used one here and there, but never as my primary platform. Not only was I able to get up to speed and functional in a matter of days, but I totally love it and switched to it as my main computer. So, with that out of the way, how about the iPhone development itself? Over the next few days (or weeks, depending how busy I get), I&rsquo;ll try and cover the major areas of iPhone development that I&rsquo;ve experienced so far.</p>
<p>Let&rsquo;s get the most obvious one out of the way: <a href="http://en.wikipedia.org/wiki/Objective_C">Objective C</a>.</p>
<p>Somehow, its very mention seems to fill people with fear. When other programmers hear I&rsquo;m doing iPhone development, they lower their voice, they get closer, and ask &ldquo;Do you _have_ to write it in Objective C?&rdquo; I think the main reason people are scare of it is because it&rsquo;s not very well known. It&rsquo;s not a sexy newcomer that the web is buzzing about like Rails, or a language with the backup of corporate giants like C# or Java. Objective C has been around since the early 80s, which is pretty amazing because it feels very modern in a lot of its features. Frankly, I&rsquo;m surprised that Microsoft chose to create C# instead of adopting/extending Objective C (or maybe I&rsquo;m not <strong>that</strong> surprised coming from Microsoft&ndash;OK, that was the last dig at MS and C# for today. Promise).</p>
<p>I had never used Objective C before I started doing iPhone development, but it was a breeze to get up to speed coming from a strong C and C++ background. The most important thing is that the interop between Objective C and C/C++ is nearly flawless. It&rsquo;s a pleasure to call Objective C functions from C++ and the other way around. So much so that the lines get all blurred between what is what. Take that C#! (oops, so much for my promise).</p>
<p>Objective C is organized like C++, with header files and implementation files. That&rsquo;s both good and bad. Good because it&rsquo;s familiar, it gives you a good separation between the public interface of a class and its implementation, and allows for fast build times. But it&rsquo;s bad because there is some annoying duplication between both files. Fortunately, Objective C gets this one right (again), and allows you to keep the header file to purely the public interface of the class. That means I can declare all the private member functions in the implementation file, which keeps duplication to a minimum.</p>
<p>A word of warning: You&rsquo;ll probably have to change all your .cpp files to be .mm so they compile as Objective C and you can freely include any Objective C headers. Also note that Objective C files are usually .m which only parses C header files. If you need to call C++ files you need to make them .mm, or you&rsquo;ll get some really bizarre errors.</p>
<p>If you&rsquo;re really a died-in-the-wool C++ fanatic, you can isolate yourself from all the Objective C stuff by writing a few wrappers that interface with the operating system. If not, you can go with the flow and embrace it and use it when it&rsquo;s needed.</p>
<p>Assuming you&rsquo;re willing to look at Objective C, how is it coming from a C++ game programming background? At first glance it&rsquo;s a bit ugly. I admit it. It looks like it&rsquo;s full of - and + and [[square:brackets] everywhere]. But it&rsquo;s very superficial. Objective C is a superset of C++, which means they introduced a different way to create Objective C classes (as opposed to C++ classes). The worst thing about the brackets, which are used for sending messages to objects, is that typing them is cumbersome. I often find myself having to move back to the beginning of the line to add new brackets as I&rsquo;m making new function calls.</p>
<p>Internally things are much more dynamic than C++, and instead of member function calls they&rsquo;re really messages that get passed around. That makes it easier to deal with null objects or objects that might or might not implement specific interfaces. I don&rsquo;t know if you can add new message handlers on the fly, but I suspect you could (although why you&rsquo;d want to do it other than for geek achievement points is beyond me&ndash;I&rsquo;ve certainly never felt the need to do it).</p>
<p>One of the features that I&rsquo;m using quite a bit are properties. You can declare member variables as properties, tag them with what kind of access is permitted (read-only, read-write, whether you want to take ownership or not, whether it&rsquo;s an atomic assignment, etc), and all the code is automatically provided for you. Nice time saver.</p>
<p>Protocols are also a nice, clean way to provide interfaces. Certainly much better than the madness of C++! It makes working with objects that implement certain interfaces very easy. It&rsquo;s also really easy to pass &ldquo;pointers&rdquo; to specific member variables through the use of selectors.</p>
<p>Enough with the raving. What&rsquo;s not to like? Only a couple of things, really. Or at least so far. Ask me again in a year and I&rsquo;ll probably have a laundry list of complaints. I doubt it will ever reach my level annoyance with C++ though. That&rsquo;s pretty much impossible.</p>
<p>My biggest complaint about Objective C is that, get this, C++ constructors for member variables in Objective C classes are not called. Yup. You read that right! I&rsquo;m sure there&rsquo;s a good reason, but it does suck. Fortunately most of the Objective C code is high level classes, so it&rsquo;s OK to new the C++ classes I need to work with. Still, it&rsquo;s annoying. I also wish that Objective C played better with namespaces, but that&rsquo;s a relatively small complaint.</p>
<p>This might sound like a strong statement, but if I were to design my ideal development language today, it would be pretty darn close to Objective C.</p>
<p>Something I still don&rsquo;t know much about: Performance. I haven&rsquo;t been doing much profiling on the iPhone yet, and all my performance-sensitive parts are written in C++. Still, I&rsquo;d be curious to see how much overhead Objective C adds on top of C++. I suspect that a fair bit given the message-passing architecture and the more dynamic nature of the language.</p>
<p>Someone asked me what am I using for unit testing with Objective C. Hmm&hellip; errr&hellip; I&rsquo;m not doing any unit testing in Objective C. There I said it :-) Not yet anyway. I&rsquo;m sure I will as soon as I start using more of it. Most of the Objective C code is high-level code interfacing with the iPhone API, so I haven&rsquo;t felt much the need to use TDD with it. If anybody has some recommended Objective C unit-testing frameworks that are lightweight and minimalistic, I&rsquo;d love to hear it.</p>
<p>If you&rsquo;re interested in learning Objective C, <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/ObjC.pdf">this document</a> was the best resource I found to learn Objective C. It&rsquo;s simple enough that you can use it to get up to speed, but detailed enough that I still refer to it from time to time. I haven&rsquo;t felt the need for any books or any other tutorials.</p>
<p>Coming up next: The iPhone API, Xcode, and more goodies.</p>]]></content:encoded></item><item><title>No Rest for The Indies</title><link>https://gamesfromwithin.com/no-rest-for-the-indies/</link><pubDate>Thu, 25 Dec 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/no-rest-for-the-indies/</guid><description>&lt;p&gt;You&amp;rsquo;d think that things would slow down around Christmas time over here. And that I would have lots of time to catch up and write about all the things I keep jotting down in my overflowing &amp;ldquo;to write&amp;rdquo; list. Right? Unfortunately that&amp;rsquo;s not the case.&lt;/p&gt;
&lt;p&gt;I do want to catch up and share my iPhone development experience with everybody, but it&amp;rsquo;s hard to make time, even during the holidays. To make things worse, I have a pretty hard deadline I set myself to have my iPhone app ready by early February.&lt;/p&gt;</description><content:encoded><![CDATA[<p>You&rsquo;d think that things would slow down around Christmas time over here. And that I would have lots of time to catch up and write about all the things I keep jotting down in my overflowing &ldquo;to write&rdquo; list. Right? Unfortunately that&rsquo;s not the case.</p>
<p>I do want to catch up and share my iPhone development experience with everybody, but it&rsquo;s hard to make time, even during the holidays. To make things worse, I have a pretty hard deadline I set myself to have my iPhone app ready by early February.</p>
<p>It&rsquo;s funny, I&rsquo;ve worked more hours in the last year than any other year during my career, but it has never felt like work. Quite the opposite actually, and I find myself doing &ldquo;work&rdquo; instead of other things that used to be more fun and having a blast with it. For example, my game-playing time has gone waaay down. If I have an hour that I can do anything, I think &ldquo;oh, maybe I can play a bit of World of Warcraft now&rdquo; followed by &ldquo;but it would be so much fun to finally add this other feature&hellip;&rdquo; I let you figure out which one ends up winning in the end. If it wasn&rsquo;t because of my weekly WoW session with <a href="http://www.tilander.org/aurora/">Jim</a>, <a href="http://www.hammerian.net/">Joey</a>, and Michael, I wouldn&rsquo;t make any progress in the game!</p>
<p>Not only am I enjoying what I do immensely, but it&rsquo;s very easy to spend lots of time doing it because I get to do it from the comfort of my own home. I never have to worry about getting to work by a particular time, so I can get in my morning runs or go grocery shopping when the stores are empty, I have all my stuff around me, my work area has an incredible view overlooking the whole of Mission Valley, and my kitchen is stocked up with <a href="http://www.uptontea.com">all my favorite teas</a>. It&rsquo;s really easy to spend hours and hours working. A bit too easy actually.</p>
<p>Burnout is the evil flip side of fun work. Even with incredibly rewarding and fun work, doing something for many hours a day can burn me out pretty easily. The symptoms are obvious: I start to lose interest, I&rsquo;m not as productive, my mind wanders, and I find all sorts of other things I&rsquo;d rather be doing. Fortunately, I can recognize those symptoms early on, so just backing off a bit, or taking an afternoon off, allows me to walk the fine line between work and burnout and keeps me productive.</p>
<p>Initially I was a bit concerned about the thought of working full time from home. Would I miss the interaction with coworkers and the sparks and new ideas from seeing all sorts of stuff around me in a company. It turns out that it wasn&rsquo;t anything to be worried about. Thanks to the Internet, it&rsquo;s very easy to reach out and connect with other people. I regularly share my progress with some friends and family members, and I always enjoy hearing their comments and reactions (even the not so positive ones&ndash;especially those actually). I also meet in a semi-regularly basis with my friend <a href="http://www.davidfennema.com/">Dave</a>, who is doing all the graphic design for my app (and he&rsquo;s the mastermind behind the Power of Two logo).Â  Those meetings are always very inspiring, and usually result in all sorts of new ideas flying around and a flurry of activity in the days following.</p>
<p>Having non-work related hobbies really helps to keep me from spending too much time on work. Training for half marathons (I keep saying that one of these days I&rsquo;ll do a full marathon&ndash;we&rsquo;ll see about that), or just getting back in shape to do a century on my bike require quite a time commitment and keep me in shape and in top mental shape.</p>
<p>I suppose this is exactly the feeling that some companies try to encourage in their employees. They hire people who are really passionate about their work, give them the means and the freedom to do it, and hope they pour their heart into it. They just have to hope that their employees are able to keep themselves from burning out. That might be easier if you&rsquo;re forced to work from an office environment, totally separate from home. On the other hand, being away from your family for longs periods of time eventually takes a toll on happiness and morale.</p>
<p>That&rsquo;s a totally different beast from the kind of crunch that is rampant in the games industry. I define crunch as having to mandate long work hours (either explicitly or through peer pressure&ndash;which is more sublte and infinitely more evil). In one case, you&rsquo;re so passionate about what you&rsquo;re doing that you can&rsquo;t wait to go back to work on Monday morning. In the other case, you&rsquo;re still stuck to your desk come Monday morning because you were forced to work the weekend and get a build ready for some marketing demo. One is a very rewarding life, the other is soul-draining. One results in happy, ultra-productive people and the other degenerates into a death march, people leaving, and projects being even more delayed.</p>
<p>So, even with the February deadline looming, I want to take a few more hours these next few days and get back into the wrting swing of things. Besides, with the app coming up so soon, I should start thinking about announcing it soon! First I need to wrap up the Game Developer Magazine column due on Monday, but after that, I&rsquo;ll try to start posting regular updates.</p>
<p>Until then, happy holidays to everybody. I hope you&rsquo;re taking some time off, or at least doing what you really love.</p>
]]></content:encoded></item><item><title>Build Server: The Heartbeat of The Project</title><link>https://gamesfromwithin.com/the-heartbeat-of-the-project/</link><pubDate>Fri, 12 Dec 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-heartbeat-of-the-project/</guid><description>&lt;p&gt;Have you ever given some thought to why you decided to become a game programmer? Iâ€™m pretty sure it wasnâ€™t to do mundane, repetitive tasks. Yet sometimes we find ourselves spending a significant portion of our time making sure that the code compiles for all platforms, or that there are no potential bugs lurking in the depths of the game, or even building the assets for each level and running them to make sure they load correctly.&lt;/p&gt;
&lt;p&gt;Clearly, those are all things that need to be done, but if they are so repetitive and mindless, couldnâ€™t we put some of the computers around us to good use and have them do the job for us?&lt;/p&gt;
&lt;p&gt;A build server will do all that and more, much faster and more reliably than we could, and it will free us to work on the thing that made us fall in love with this industry in the first place: the game.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Have you ever given some thought to why you decided to become a game programmer? Iâ€™m pretty sure it wasnâ€™t to do mundane, repetitive tasks. Yet sometimes we find ourselves spending a significant portion of our time making sure that the code compiles for all platforms, or that there are no potential bugs lurking in the depths of the game, or even building the assets for each level and running them to make sure they load correctly.</p>
<p>Clearly, those are all things that need to be done, but if they are so repetitive and mindless, couldnâ€™t we put some of the computers around us to good use and have them do the job for us?</p>
<p>A build server will do all that and more, much faster and more reliably than we could, and it will free us to work on the thing that made us fall in love with this industry in the first place: the game.</p>
<h2 id="getting-off-the-ground">Getting Off The Ground</h2>
<p>Before we can start thinking about setting up a build server, we need to be able to build the game with a single command from the command line. No clicking around, no GUI apps, no multiple steps, no magical incantations that only work during a full moon. Just type a command and the build for the game and all its libraries starts.</p>
<p>This is not just a necessary step to set up a build server; itâ€™s a very good engineering practice. So if youâ€™re not there, spend some time on it right away and youâ€™ll be glad you did when candidate submission time comes around.</p>
<p>Building the game with a single command should be fairly easy, but the specifics will depend on your environment and build system. If youâ€™re using Visual Studio, you can put the game and all the libraries in a single solution with the correct dependencies. Then you can invoke the devenv.com command line program specifying the solution and configuration you want to build: devenv.com mygame.sln /build Debug. You can wrap that up in a single batch file buildgame.bat for extra convenience and youâ€™re done.</p>
<p>If youâ€™re using another build system, such as make or jam, you can probably already build it with a single command. If youâ€™re using a bunch of mode-made scripts, at least wrap them all up in a single script file so they can be run with a single command.</p>
<p>Just building the game with a single command isnâ€™t enough. We must have a way to automatically detect whether the build succeeded or failed. Fortunately, most build systems (including devenv. com and make) return an error code when the build fails. If youâ€™re rolling your own build script file, make sure to capture build failure and return an error code as well.</p>
<h2 id="setting-up-the-build-server">Setting Up The Build Server</h2>
<p>A build server should be a dedicated machine with access to version control. Whenever a new build is needed, the server syncs to the latest version in version control, starts a build, and notifies the team in case of any errors.</p>
<p>Thatâ€™s a fine start, but we could make things much better. For example, we could include the error message in the notification email so programmers can see right there what the problem was instead of being forced to sync and build the game themselves. We could also trigger a build in different circumstances (for example, code checked-in, forced by a person, or some other event) instead of only at fixed intervals. We might want to distribute the build across multiple machines, or keep logs and make them available on a web page, or format emails better, or use more direct notification methods &hellip;</p>
<p>Put away those Python reference manuals because fortunately, someone has already done all the work for us: <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a> (and <a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET">CruiseControl.Net</a>). Itâ€™s a free, open source build server program with all the bells and whistles that you could possibly want. And did I mention itâ€™s free?</p>
<p>There are three main parts to it:</p>
<ol>
<li>The build server. It runs as an application or a Windows service. Itâ€™s configured through a very simple XML file that tells it when to sync, where to sync, what to build, and how to report it.</li>
<li>The web front end. CruiseControl features a pretty, web-based dashboard showing all the builds, their status, past logs, and other pertinent data.</li>
<li>The system tray notificator. This is a little app that runs in the system tray and shows the status of all the builds and notifies you of any changes right away with a message and by playing some sounds. This is my favorite way to keep up to date with the build status. Youâ€™ll be up and running in about 10 minutes. The most complicated part is probably installing a web server (if you donâ€™t already have one) and getting the web dashboard running. Youâ€™ll spend a few more hours tinkering with it to get it â€œjust right,â€ and then youâ€™re done. The only time I have to mess with it is to upgrade to a new version every so often. Other than that, itâ€™s virtually maintenance free.</li>
</ol>
<p>At this point youâ€™ll have a fully featured build server in place. It verifies that the game can be built from the latest checked-in version of the code. It notifies developers of failed and successful builds right away. It increases version numbers, keeps a build history and statistics, archives executables, and emails logs.</p>
<p>CruiseControl and CruiseControl.Net are the two build servers I have most experience with. There are other build servers out there, with slightly different features, integrations with different environments, and so forth. Some of them are commercial and come with full support in case youâ€™re more comfortable with that model.</p>
<p>Itâ€™s important to stress that a build server is not intended to be the only machine that builds the game. Every programmer (and maybe every member of the team) should be able to build the game in his or her own machine from scratch. The build server is there to verify that all the checked-in changes build correctly on a clean machine, and to make sure that all platforms and configurations are building successfully. Any official builds should be created exclusively from the build server, though. Especially any builds distributed externally to publishers or manufacturers. This ensures that the build is clean, was created in a repeatable manner, and is free of any idiosyncrasies from a particular machine.</p>
<h2 id="how-often">How Often?</h2>
<p>Once the build server is in place and is producing successful builds reliably, the question arises of how often to make builds of the game.</p>
<p>It used to be considered good practice to do a weekly build. The team would start ramping things up on Thursday to try and get a build out the door by the end of the day on Friday. Anybody who has done that knows how stressful it can be and how it can easily become a bottleneck.</p>
<p>Why wait a week if you can do one every night? More teams started switching to the daily build, which is much less stressful because there are fewer changes in each new build. It also gives the team a chance to fix anything that was found broken in the previous day&rsquo;s build. Soon, teams took it beyond the daily build and started making two builds a day, or even one every hour.</p>
<p>The build server has been very appropriately described as the heartbeat of the project. A â€œgreen buildâ€ is one heartbeat and one small step forward. A â€œred buildâ€ is done when something is wrong and needs to get fixed as soon as possible. If you have a red build several days in a row, the project is in serious trouble. The more often you make a successful build, the better. Youâ€™ll find fewer surprises and stay more on course that way.</p>
<p>My favorite approach is continuous integration. With continuous integration, the build server starts a new build as soon as thereâ€™s a new check-in. If multiple check-ins come in while the build is in progress, another build starts right after itâ€™s done, with all the new changes queued during that time. When following this practice, programmers sync to the latest version often, make small changes, and check-in code frequently, rather than batching many changes. Very conveniently, Cruise Control has a setting to start builds whenever anything changes.</p>
<p>The main benefit of continuous integration is that you are notified as soon as a check-in breaks the buildâ€”not a day later, or even an hour later, but minutes later. It tells you, â€œThe last build was good. This one is not.â€ You can look through the last couple of check-ins that happened during that short time period and quickly narrow down the problem and fix it. Imagine trying to narrow down an elusive crash bug from all the check- ins for a full day or two!</p>
<p>Another benefit is that all programmers are working on a version very close to the latest one. This means that there are fewer source code conflicts when checking-in code, and fewer surprises lurking in the code. The flip side of that is that working on the latest version is living in the proverbial bleeding edge. Itâ€™s not unusual for someone to check-in code that has some accidental bad side effects. As long as those bad check-ins are limited, and that whenever they happen they are fixed right away, I have found the benefits to outweigh some instability in the main branch. Some of the ways to minimize disruptions when working with continuous integration are:</p>
<ul>
<li>Make sure that any code compiles before checking it in (that should go without saying!)</li>
<li>Execute a fast set of unit tests to verify that basic functionality is working correctly, and</li>
<li>Have the build server notify everybody as soon as thereâ€™s a broken build so it can be fixed and so that nobody else syncs or checks-in any code while the build is broken.</li>
</ul>
<h2 id="need-for-speed">Need For Speed</h2>
<p>Ideally, Iâ€™d like to check in some code and see whether the build server found any problems right away. In the real world, things can be much slower. After all, the build server needs to sync to the latest code, kick off builds for multiple platforms and multiple configurations, and perform some other time-consuming steps. Even so, there is work we can do to get feedback as soon as possible. Perform incremental builds during the day, so only the affected sections of the code need to be built. Itâ€™s still a good idea to do a full build at least every night to make sure that everything can be built from scratch.</p>
<p>Set up each platform and configuration as separate builds. That way you get feedback as soon as one of them completes. The only downside is if an error makes it through that causes all the builds to fail, get ready for lots and lots of broken build sounds playing all over the company. Speed up build times through <a href="/physical-structure-and-c-part-2-build-times/">good physical dependencies, modularity, precompiled headers, and good use of forward declarations</a>.</p>
<p>Split up different builds and configurations in different machines. The easiest way is to set up one machine per platform and configuration (or maybe do a couple of configurations per machine). Cruise Control lets you easily integrate several build servers into the same web dashboard and system tray application, so this is a very easy solution.</p>
<h2 id="dont-skimp-on-hardware">Don&rsquo;t Skimp on Hardware</h2>
<p>Get the beefiest computers you can afford. Throw fast CPUs, disk access, and gigabit ethernet. Get multiprocessor cores and make sure your build system takes advantage of them. Does it sound like a lot of money? Not when you take into account how few servers youâ€™ll have and how much time youâ€™ll save all the members of the team.</p>
<p>I have tried several distributed build systems, and even though they can sometimes be beneficial for some codebases, Iâ€™m still not a huge fan. I find that you can often achieve the same (or better) results by using multiple processors and good build architectures, and you avoid the complexity and overhead of a distributed build system.</p>
<p>One â€œgotchaâ€ we ran into when we scaled our build farm beyond about 15 build servers was that each of them was hitting our version control repository every few seconds to see if anything had changed. That wasnâ€™t a trivial operation, and so many servers doing it so frequently definitely slowed things down to a crawl.</p>
<p>To remedy that, instead of having the build servers poll the overtaxed source control server, we had the source control server push out a notification. Whenever there was a check-in, the source control server changed a timestamp in a file located on an internal web server. We changed the build servers to constantly monitor the internal web server for changes in that file, and whenever it changed it triggered a build, which completely eliminated the overhead on the version control server.</p>
<h2 id="beyond-the-build">Beyond The Build</h2>
<p>So far, weâ€™ve only been talking about building the game. But the build server is a great tool that we can put to good use for many other purposes. Why restrict ourselves to just the game? All the in-house tools would also benefit from getting the same treatment. We can even take it a step further and deploy the freshly-built copies of all the tools on a network drive or web page so theyâ€™re available to the whole team.</p>
<p>The build server can also double up as a symbol server. That makes it much more convenient for programmers to debug an earlier version of the game and libraries and have all the debugging information available without having to rebuild everything locally.</p>
<p>Thereâ€™s no reason to limit the build server to just building source code. One of the most useful things you can do with it is use it to build game assets as well. Building assets is usually a slow process. Having a fast asset build system that can correctly perform incremental builds is crucial to keep asset build times down.</p>
<p>Build servers are general enough to perform just about any task. Running both unit tests (small tests on each class or function) and functional tests (tests that exercise a larger module or even the whole game) are perfect uses for the build server. Functional tests can be pretty slow, so make sure that theyâ€™re treated as a separate build and not as the last step in building the game. Nobody wants to wait for hours for all the functional tests to complete before they can see the successful build status after a check-in. The sky is the limit with what the build server can do. We use it to run static analysis of our source code, checking for spots in the code that can lead to subtle and dangerous bugs (uninitialized variables, implicit type conversions, and the like).</p>
<p>Another great use is to run through the different levels of the game, recording frame rate at different points of each level, logging the results, and failing the build if it ever drops below a certain threshold. Having the performance history for specific levels can be really useful to narrow down why a particular section is chugging at 20fps but was running at a solid 60 a couple of weeks ago. For bonus points, integrate all the collected data into easy-to-visualize graphs available through the web front end.</p>
<p>The build server is definitely the heartbeat of a project. Keep those check-ins coming and those builds green, and you know youâ€™re heading in the right direction.</p>
<p>This article was originally printed in the August 2008 issue of <a href="http://www.gdmag.com/homepage.htm">Game Developer</a>.</p>]]></content:encoded></item><item><title>Stranger in a Mac Land</title><link>https://gamesfromwithin.com/stranger-in-a-mac-land/</link><pubDate>Mon, 08 Dec 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/stranger-in-a-mac-land/</guid><description>&lt;p&gt;I&amp;rsquo;ve worked with many operating systems over the years: from the humble CP/M, to early versions of DOS, toÂ  Windows 3.0 (if you can even call that an OS), along with many different versions of Linux since 1993, a smattering of VMS, and, of course, all the recent flavors of Windows. But somehow, I always managed to avoid Apple operating systems.&lt;/p&gt;
&lt;p&gt;Starting iPhone development was a bit of a change since it required me to work exclusively under OSX and use a new IDE (XCode). I had talked to people who found the change very cumbersome and found the new environment got in their way, so I approached it with a bit of trepidation.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve worked with many operating systems over the years: from the humble CP/M, to early versions of DOS, toÂ  Windows 3.0 (if you can even call that an OS), along with many different versions of Linux since 1993, a smattering of VMS, and, of course, all the recent flavors of Windows. But somehow, I always managed to avoid Apple operating systems.</p>
<p>Starting iPhone development was a bit of a change since it required me to work exclusively under OSX and use a new IDE (XCode). I had talked to people who found the change very cumbersome and found the new environment got in their way, so I approached it with a bit of trepidation.</p>
<h2 id="its-an-os-x-world">It&rsquo;s An OS X World</h2>
<p>With my new Macbook Pro under my arm (actually, it wasn&rsquo;t new, I bought it used off Craigslist because I couldn&rsquo;t afford a new one), I embarked on an adventure to this strange, new world of OS X development.</p>
<p>Some background is necessary here: I&quot;m a minimalistic, no frills kind of guy when it comes to my preferences when working with computers (although now that I think about it, it probably applies to most other things in my life as well). The first thing I do with a new install of Windows is turn off all the GUI animations (don&rsquo;t get me started on the <a href="http://www.microsoft.com/windowsxp/using/helpandsupport/learnmore/crawford_september03.mspx">search puppy dog</a>!!), most of the sounds, all the auto-complete and auto-spellcheck features, and automatic upgrades. When I want the computer to do something, I&rsquo;ll tell it to do so. Otherwise I want it to be quiet and responsive.</p>
<p>My ideal Visual Studio setup is also pretty similar: No fancy web startup page, no animations, no autocompletions by default (unless I press CTRL-Space), out with all the toolbars, just give me two text windows side by side and control everything from keyboard shortcuts (which I&rsquo;m still using the ones from Visual C++ 6.0).</p>
<p>Needless to say, I was afraid of clashing with Mac OSX&rsquo;s environment. I had a suspicious that it was full of eye candy, GUI frills, and required a mouse for everything. Not a good match.</p>
<p>There wasn&rsquo;t as much of a learning curve as some getting-used-to. There are some Mac quirkiness that I just don&rsquo;t get: The disembodied menu on the top of the screen, the lack of change of mouse cursor when you can resize a window, or not being able to automatically restore a file to its original location from the recycle bin.</p>
<p>But those are all relatively small things that don&rsquo;t overshadow the fact that I just love this new environment. I used to like the Windows fonts, but after a week of using a Mac, I can&rsquo;t go back to those tiny, jaggedy Windows fonts. Handling of multiple monitors is perfectly integrated and works like a charm. In general, things Just Work (TM).</p>
<p>Then there are the things that I love from my time in Linux that I can&rsquo;t live without: Multiple desktops with Spaces, a decent command line shell, or being able to tweak settings directly in low-level config files.</p>
<p>And the thing that has changed how I work the most: <a href="http://www.apple.com/macosx/features/300.html#spotlight">Spotlight</a>. No need for icons everywhere, or &ldquo;Start | Programs&rdquo; or anything. Just start typing what you want and there it is. It&rsquo;s like the return of the command line on steroids. Between Spotlight, <a href="http://www.mozilla.com/en-US/firefox/features/#location-bar">Firefox smart locaton bar</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/2888">GMarks</a>, and <a href="http://labs.mozilla.com/projects/ubiquity/">Ubiquity</a>, I feel right at home. Now combine them all somehow and I&rsquo;ll be in heaven!</p>
<h2 id="but-wait-what-about-windows">But Wait, What About Windows?</h2>
<p>I ended up falling in love with OS X so much, that I quickly moved to it as my primary environment at home for everything. Frankly, these days, it&rsquo;s pretty easy for me to change environments since most of what I do is online. Just give me Firefox (or a good browser) and I&rsquo;m there: GMail, Google Calendar, Google Reader, Google Docs (hmm&hellip; I sense a theme here), and a Wiki cover most of what I do on a daily basis.</p>
<p>For the rest of the apps, almost everything I need runs under OS X: good media visualizer (Preview), photograph organizer (<a href="http://www.adobe.com/products/photoshoplightroom/">Lightroom</a>), image editor (<a href="http://www.gimp.org/">The Gimp</a>/<a href="http://www.adobe.com/products/photoshop/photoshop/">Photoshop</a>), audio editor (<a href="http://audacity.sourceforge.net/">Audacity</a>), music player (iTunes), and a few more odds and ends. OS X comes with some great utilities out of the box too, like Grab, Preview, or Activity Monitor.</p>
<p>Unfortunately, there are still a couple of things that I can only run under Windows. The main thing are games unfortunately, so I need to keep my Windows box around just for that. Although I just started playing <a href="http://en.wikipedia.org/wiki/Crack_cocaine">World of Warcraft</a> and it runs great on my Mac. Thanks Blizzard! Apart from that, every so often I need to do something in Visual Studio, or run some application I wrote in .Net. For that, I go about it in two different ways.</p>
<p>I can run it on the Windows box itself. Instead of keeping two sets of keyboards and mice (or a switch box), I used <a href="http://synergy2.sourceforge.net/">Synergy</a> for a while. It was pretty cool being able to move the mouse cursor from one screen on the Mac to the screen on Windows and continue working there, and that might be a great solution if you&rsquo;re working 50-50 on both platforms. In my case, it was more like 90-10 at the time (more like 99.9 to 0.1 now), so it felt a bit of a waste to have a full monitor dedicated to Windows. Instead, I decided to use Remote Desktop to control my Windows computer from the Mac. Amazingly enough, Microsoft wrote a <a href="http://www.microsoft.com/mac/products/remote-desktop/default.mspx">Remote Desktop app for OS X</a> that works like a charm, much better than some of the VNC programs I tried.</p>
<p>Whenever I don&rsquo;t need to run something that is performance critical, I reach for <a href="http://www.vmware.com/products/fusion/">Fusion</a>. I&rsquo;ve tried many products in the past that claim to run programs for another platform in your own computer: Wine, CrossOver Office, earlier versions of VMWare, but they&rsquo;re always plagued by problems and incompatibilities. VMWare Fusion really surprised me by running anything I threw at it flawlessly, including Quicken (yes, I need to switch to <a href="http://www.mint.com/">Mint</a> or <a href="http://www.buxfer.com/">Buxfer</a>) and some hardware-accelerated 3D programs (those were a bit chuggy though, but they worked). And the coolest feature ever: Unity&ndash;I can run Windows apps in a window of their own directly on the Mac desktop. Totally awesome! On top of all that, I can have multiple snapshots, restore earlier states, and I can even run other operating systems like different versions of Linux. A geek&rsquo;s true dream!</p>
<p>Some people will claim that I have drunk from the Apple kool-aid, and to a certain extent, they&rsquo;re right. But I&rsquo;d like to think I was swayed by many good reasons having to do with using the computer and being more productive, rather than Apple&rsquo;s brainwashy, lifestyle marketing message. That and the smooth feel of the Macbook against the palm of my hands, its sleek profile, and sexy design. :-)</p>
<p>What about XCode and development? That&rsquo;s another story for another day.</p>
]]></content:encoded></item><item><title>Get Your Games from Within Fix on The Go</title><link>https://gamesfromwithin.com/get-your-games-from-within-fix-on-the-go/</link><pubDate>Mon, 17 Nov 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/get-your-games-from-within-fix-on-the-go/</guid><description>&lt;p&gt;I hate driving. You have to deal with &lt;a href="http://www.youtube.com/watch?v=ZIECVT9KYvU"&gt;crowded roads&lt;/a&gt; and people who seem to be doing their best to get in your way. Worst of all, it&amp;rsquo;s dead time: you can&amp;rsquo;t read, you can&amp;rsquo;t write, you can&amp;rsquo;t use a computer, or even take a quick cat nap. So I really try to minimize how long I spend on a car and try to do everything remotely, or walk or ride my bike instead.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I hate driving. You have to deal with <a href="http://www.youtube.com/watch?v=ZIECVT9KYvU">crowded roads</a> and people who seem to be doing their best to get in your way. Worst of all, it&rsquo;s dead time: you can&rsquo;t read, you can&rsquo;t write, you can&rsquo;t use a computer, or even take a quick cat nap. So I really try to minimize how long I spend on a car and try to do everything remotely, or walk or ride my bike instead.</p>
<p>This being Southern California, cars are an inevitable reality. So what do I do while I&rsquo;m stuck in my tiny subcompact hatchback? Devour every broadcast of <a href="http://www.ted.com/">TedTalks</a>. I&rsquo;m totally, irreversibly hooked on that podcast. And now, we finally have our own game industry podcast.</p>
<p>Ryan Wiancko, over at <a href="http://www.industrybroadcast.com/">Industry Broadcast</a>, has started recording articles from several of the top <a href="http://www.lostgarden.com/">game</a> <a href="http://www.agilegamedevelopment.com/">development</a> <a href="http://www.gamedevblog.com/">blogs</a>. I&rsquo;m happy to announce that he has <a href="http://www.industrybroadcast.com/tag/gamesfromwithincom/">added Games from Within</a> to the list of articles he&rsquo;s recording. He started with the oldie-but-goodie <a href="http://www.industrybroadcast.com/2008/11/10/audio-article-23-optimzing-the-content-pipeline/">Optimizing the Content Pipeline</a> that I wrote for Game Developer Magazine a few years ago (Note to self: I need to write an updated version of that article with my current thinking on the topic). He&rsquo;ll be adding some of the most popular articles from the site as well as covering new entries.</p>
<p>So fill up your iPod with juicy game development recordings and have them handy wherever you go.</p>
]]></content:encoded></item><item><title>Feed Yourself</title><link>https://gamesfromwithin.com/feed-yourself/</link><pubDate>Sat, 15 Nov 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/feed-yourself/</guid><description>&lt;p&gt;I&amp;rsquo;m lost without feeds. In the last few years, my mode of operation with teh itarwebs has gone from poll to push. I used to have a set of bookmarks that I would visit every week. As the rate of change picked up, I started visiting every day, but it soon became overwhelming.&lt;/p&gt;
&lt;p&gt;Now I&amp;rsquo;m 100% feed driven. Content is pushed to me, and not the other way around. Interestingly, the number of sites I keep up with has gone up significantly (over 100 by last count) so it&amp;rsquo;s still as time consuming as it was earlier. I just get a lot more information during the same amount of time.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;m lost without feeds. In the last few years, my mode of operation with teh itarwebs has gone from poll to push. I used to have a set of bookmarks that I would visit every week. As the rate of change picked up, I started visiting every day, but it soon became overwhelming.</p>
<p>Now I&rsquo;m 100% feed driven. Content is pushed to me, and not the other way around. Interestingly, the number of sites I keep up with has gone up significantly (over 100 by last count) so it&rsquo;s still as time consuming as it was earlier. I just get a lot more information during the same amount of time.</p>
<p>So, for those of your who use the RSS feeds (and I hope it&rsquo;s 99% of you out there, if not, head over to <a href="http://www.google.com/reader">Google Reader</a> right now), I just enabled two new types of feeds:</p>
<ul>
<li><a href="/?feed=rss2">Feed with full content</a>. No more annoying excerpts and having to click through.</li>
<li><a href="/?feed=comments-rss2">Feed with all the comments</a>. So you can follow any discussions more easily.</li>
</ul>
<p>As a side note, <a href="http://wordpress.org/">WordPress</a> totally rocks. I&rsquo;ve used other blog systems before, but the latest version of WordPress is so slick, configurable, and easy to work with that it&rsquo;s a real pleasure. Adding new themes or plugins is as simple as downloading a file and administration is done 100% through a super-slick web interface. Definitely better than <a href="http://www.movabletype.org/">MovableType</a>, and light-years ahead of the hulking, slow beast of <a href="http://drupal.org/">Drupal</a>.</p>
<p>To give you an idea of how much I&rsquo;m liking WordPress, I&rsquo;m even using it to write posts. Seriously, that&rsquo;s no small feat for me. I usually loathe online editors, and always composed the text offline and then pasted it into the blog at the last minute. With WordPress I feel totally comfortable composing posts on the fly, which makes the whole process very painless (which hopefully translates into more posts :-).</p>
]]></content:encoded></item><item><title>Brave New iPhone World</title><link>https://gamesfromwithin.com/brave-new-iphone-world/</link><pubDate>Fri, 14 Nov 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/brave-new-iphone-world/</guid><description>&lt;p&gt;I know that things have been very quiet over here for the last few weeks. Lots of stuff happening and it&amp;rsquo;s hard to find time to write sometimes. But now I should be getting back into the swing of things and updating Games from Within more regularly.&lt;/p&gt;
&lt;p&gt;The big news is that we decided to call it quits on &lt;a href="http://powerof2games.com"&gt;Power of Two Games&lt;/a&gt;. It was an amazing experience and I learned a huge amount. I&amp;rsquo;m sure we&amp;rsquo;ll write a postmortem with some of the gems we learned along the way sometime soon. Unlike most postmortems, we really don&amp;rsquo;t have any office politics, bosses to suck up to, or publishers to keep happy, we&amp;rsquo;ll be able to be brutally honest.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I know that things have been very quiet over here for the last few weeks. Lots of stuff happening and it&rsquo;s hard to find time to write sometimes. But now I should be getting back into the swing of things and updating Games from Within more regularly.</p>
<p>The big news is that we decided to call it quits on <a href="http://powerof2games.com">Power of Two Games</a>. It was an amazing experience and I learned a huge amount. I&rsquo;m sure we&rsquo;ll write a postmortem with some of the gems we learned along the way sometime soon. Unlike most postmortems, we really don&rsquo;t have any office politics, bosses to suck up to, or publishers to keep happy, we&rsquo;ll be able to be brutally honest.</p>
<p>Against my better judgement, especially with the current horrible economy, I&rsquo;m still burning the indie development candle. This time by myself and on the iPhone. I&rsquo;ll get into many more details in the future, but so far iPhone development has been surprisingly fun and smooth.</p>
<p>One of the most attractive things about iPhone development is the short projects. Some of the top selling iPhone applications were written in just a week or two. The game/toy I&rsquo;m working on is a bit more involved than a <a href="http://www.maniacworld.com/iPhone-Fart-App-Banned.html">fart generator</a> or a <a href="www.maniacworld.com/iPhone-Fart-App-Banned.html">rotary dial</a>, so I expect it will take me a total of three months. Still, much better than trying to make a game for XBLA or PSN!</p>
<p>Another big plus of iPhone development is the approval process. Yes, Apple needs to approve the application, but the process is infinitely simpler than trying to certify your PS3 or 360 game. I haven&rsquo;t gone through that myself yet, but that&rsquo;s what I keep hearing from other developers.</p>
<p>And then you have the App Store. Ah, the App Store. A captive audience of impulse-buyers with their credit cards already in the system because of iTunes. Genius. The cut that Apple takes is very reasonable, just 30%. Let&rsquo;s hope they keep it that way and don&rsquo;t pull <a href="http://kotaku.com/359668/microsoft-cuts-indie-royalties-in-half">the Microsoft move</a> on us!</p>
<p>So, what&rsquo;s not to like? That everybody and their grandmother is writing iPhone apps and throwing them on the App Store on the hopes of making a quick buck. And the worst thing is that it&rsquo;s actually working. So people keep gambling with crappy apps hoping to become the next <a href="http://www.hottrix.com/software/">iBeer</a> or <a href="http://www.theblimppilots.com/The_Blimp_Pilots/Koi_Pond.html">Koi Pond</a>. As a result, the App Store is flooded with stuff, most of it horrible, some OK, a few good, and a very few great apps. Right now the App Store interface isn&rsquo;t ideal for discovering new, high-quality games and applications, and most of the exposure is limited to the Top Seller lists. I&rsquo;m hoping in the next few months they move towards something more along the lines of Amazon.</p>
<p>And speaking of interfaces, whose retarded idea was it to only be able to access the App Store from within iTunes? I like Apple, and I&rsquo;m totally digging Mac OS X (more on that later), but I hate having to use a slow, bloated application to do something that amounts to browsing a few web pages. Besides, you&rsquo;d think they would hook more people by making it more accessible. Oh well. That&rsquo;s not changing any time soon.</p>
<p>Stay tuned for more updates on my iPhone development adventures and maybe, just maybe, an early glimpse of the game :-)</p>
]]></content:encoded></item><item><title>Bad News for Scons Fans</title><link>https://gamesfromwithin.com/bad-news-for-scons-fans/</link><pubDate>Fri, 19 Sep 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/bad-news-for-scons-fans/</guid><description>&lt;p&gt;We have been talking a lot about Scons recently at the Power of Two Games World Headquarters. MSBuild has proven to be quite a pain to work with for our asset builds and eventually left us dissatisfied (that&amp;rsquo;s material for a whole other entry). So we kept looking over to Scons as a possible solution.&lt;/p&gt;</description><content:encoded><![CDATA[<p>We have been talking a lot about Scons recently at the Power of Two Games World Headquarters. MSBuild has proven to be quite a pain to work with for our asset builds and eventually left us dissatisfied (that&rsquo;s material for a whole other entry). So we kept looking over to Scons as a possible solution.</p>
<p>On paper it looks great:</p>
<ul>
<li>Built from the ground up for parallel builds</li>
<li>Uses a real programming language (Python) instead of overly-complicated XML files</li>
<li>It allows for discovery of assets to build as other assets are parsed</li>
</ul>
<p>The big question mark hanging over it was whether it was fast enough. I had done <a href="/the-quest-for-the-perfect-build-system-part-2/">some experiments</a> with Scons and other build systems a few years ago, and Scons totally failed by having ridiculously long incremental build times just checking if anything had changed. That was simply not acceptable. If no data has changed, I want the build system to detect it and come back in a second or less.</p>
<p>Since then, I&rsquo;ve been told that Scons had finally fixed its dependency checking and it was much faster now. Music to my ears!</p>
<p>So I resurrected the <a href="/wp-content/uploads/bin/generate_libs.zip">old script I wrote back then</a> to generate a nightmare stress test, downloaded <a href="http://www.scons.org/download.php">the latest stable version of Scons</a> (1.0.1) and fired it up.</p>
<p>I&rsquo;m sorry to report that Scons is still as unusable as it was back then. I generated a codebase like the one I used to measure all the build systems (50 libraries, 100 classes each, 15 internal includes, 5 external includes). I built everything once, then ran it again and it took 49 seconds. I have some pretty nice hardware, including a fast SATA hard drive and a 2.8GHz Core2Duo with plenty of RAM, and 49 seconds to say that nothing needs to be changed just doesn&rsquo;t cut it.</p>
<p>Now to be fair, right now we&rsquo;re looking at Scons to build our assets, not our code. Maybe the nested project configuration is not particularly realistic, so I tried something simpler: 5000 files in a single library without any dependencies among each other at all. This is a very conservative example for an asset build of a large commercial game.</p>
<ul>
<li>It&rsquo;s only 5000 files. A real game can easily have 10 times as many asset files.</li>
<li>All the files are tiny (cpp files in this case). Assets can get very large when dealing with textures, sounds, and animations.</li>
<li>There are zero dependencies among assets in this example. You&rsquo;ll often have models depending on shaders and textures, levels on game entity definitions, etc.</li>
</ul>
<p>Building assets doesn&rsquo;t have to be the instant, no delay kind of build that I require building code. I expect most developers will be building assets locally, tweaking things, rebuilding, and trying them in the game. The faster the build is, the better, but a delay of a few seconds can be acceptable. If Scons can&rsquo;t handle this build in less than 10 seconds, it&rsquo;s certainly doomed in a full-scale game.</p>
<p>The result: 37 seconds!</p>
<p>For purely masochistic reasons, I decided to see how it scales, so I threw 20,000 files at it (again, without any dependencies). Incremental build time without any changes: 3 minutes and 46 seconds. That&rsquo;s over 6 times longer for processing 4 times the number of files, so it doesn&rsquo;t even scale linearly.</p>
<p>Scons is definitely too slow, and MSBuild has its share of problems. What&rsquo;s left out there? Any recommendations for good parallel asset building systems? Hopefully something lightweight and easily configurable through a real language. Anything?</p>]]></content:encoded></item><item><title>Back to The Future (Part 2)</title><link>https://gamesfromwithin.com/back-to-the-future-part-2/</link><pubDate>Mon, 15 Sep 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/back-to-the-future-part-2/</guid><description>&lt;p&gt;I really enjoy a good cup of tea. On the surface, making tea is really easy: take some tea leaves, pour some hot water over them, and wait a few minutes. In practice, the difference between a bitter, undrinkable brew, and a perfect cup of tea is all in the details; the type and amount of tea, the temperature of the water, and the steeping, time all make a huge difference. A playback system for a game is very much the same. As we saw last month, the basic idea is really simple: Record all game inputs, make the game deterministic, and you get the same playback every time. Unfortunately things aren&amp;rsquo;t quite that simple in real life. Just as with tea making, the secret to a perfect playback system is all in the details.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I really enjoy a good cup of tea. On the surface, making tea is really easy: take some tea leaves, pour some hot water over them, and wait a few minutes. In practice, the difference between a bitter, undrinkable brew, and a perfect cup of tea is all in the details; the type and amount of tea, the temperature of the water, and the steeping, time all make a huge difference. A playback system for a game is very much the same. As we saw last month, the basic idea is really simple: Record all game inputs, make the game deterministic, and you get the same playback every time. Unfortunately things aren&rsquo;t quite that simple in real life. Just as with tea making, the secret to a perfect playback system is all in the details.</p>
<p>Let&rsquo;s look at some of the common problems that can trip up the playback system and what we can do about them. We&rsquo;ll warm up by starting with the easiest ones and work our way to the hardest ones.</p>
<h3 id="game-versions">Game Versions</h3>
<p>A playback of a game recorded with a different version is almost guaranteed to end up with different results than the original version. Any minor tweaks to AI parameters, pathfinding algorithms, or just about anything is most likely going to generate a different game state. It doesn&rsquo;t even have to be a change in code either: adding a new character or moving a trigger volume will also cause different playbacks.</p>
<p>In general, you&rsquo;re best off avoiding using recorded inputs from previous versions of the game. Inserting the game build version at the beginning of the recorded game state file allows you to detect version mismatches during playback. If a mismatch is detected, you can either print a warning or give up on the state verification altogether. This check will be particularly useful if you&rsquo;re sharing recorded sessions across the office (perhaps through a bug database) and people are on slightly different versions.</p>
<p>The idea of recording a session in release mode (all optimizations enabled, few debugging checks in place), and playing it back in debug mode is very tempting. Unfortunately, mixing and matching configurations is almost guaranteed not to work. Middleware libraries will often have slightly different behaviors in debug and release, which will throw off playback right away. But most likely so does your own code, and often in ways you might not expect. For example, you might have different floating point rounding modes in debug and release. Or even a more subtle difference: depending on the optimizations you have turned on, in debug mode a float variable might be copied back to memory after each operation (which rounds it back to a float), whereas in release the program might execute several operations in a row on that value before writing it back to main memory and causing the rounding only once. The results are going to be very close, but they&rsquo;ll often be cumulative and the simulation will quickly diverge.</p>
<p>As a general rule, treat debug and release builds as if they were different versions. Make sure to include which configuration it is along with the build number in the game state file so you can check for that as well.</p>
<h3 id="memory-state">Memory State</h3>
<p>Reading data from uninitialized memory is probably the number one cause of non-determinism in games. Uninitialized memory will contain whatever data was stored there before. That can mean anything from sane-looking values to total garbage. What&rsquo;s worse, they&rsquo;re going to change from run to run, so if your game ever uses the values contained in uninitialized memory, playback is not going to be deterministic.</p>
<p>The most common case of using uninitialized memory happens by reading a variable that was declared and not initialized. This mistake is easy to see when we&rsquo;re dealing with a standalone variable, but when it becomes a member variable hidden inside some class, it becomes a lot less obvious. It&rsquo;s also important to notice that this will only happen when we declare variables on the stack or we create them dynamically on the heap. For global and static variables, the C runtime takes care of initializing them all to zero for us.</p>
<p>Cranking up the compiler warning level to the maximum will allow it to catch some of the most obvious cases of reading uninitialized variables. For extra checks, I recommend a static code analysis program such as <a href="http://www.gimpel.com/html/lintinfo.htm">PC Lint.</a> That&rsquo;s almost guaranteed to catch every use of uninitialized variables (along with ten thousand other things, some of them extremely useful, though most of them you probably won&rsquo;t care about at all).</p>
<p>Another common mistake is to read past the end of a valid memory area, such as an array. The values read from memory in that case are going to depend on where that array is, and what happened before. In any case, it&rsquo;s going to become a source of non-determinsim, and it&rsquo;s a clear bug that should be fixed right away.</p>
<p>If you ever find that your game is deterministic in debug mode but not in release mode, start by suspecting access to uninitialized memory. In debug mode, a lot of platforms will fill the memory heap with specific bit patterns describing the memory status: allocated, freed, etc. Those patterns can be really useful to track down problems with memory allocations, but they also set memory values to a consistent state, which will make debug builds seem deterministic when they really aren&rsquo;t.</p>
<h3 id="pointer-values">Pointer Values</h3>
<p>Unless you&rsquo;re working on a platform over which you have total control, and you have a very strict memory allocation scheme, you should probably never rely on the actual numerical value of your pointer variables. The pointer values will change from run to run, and will depend on what happened before, including what other programs were running at the time.</p>
<p>If you&rsquo;re puzzled at the idea of using the pointer values as part of the logic in your program (and you should be), you still need to watch out for this possibility. Some well-known, open source compression libraries rely on this technique by hashing pointer values. This means that two consecutive runs of the same program might end up with two slightly different results.</p>
<p>In general, it&rsquo;s considered a good practice to avoid using pointer values for anything other than dereferencing them and accessing the data they&rsquo;re pointing to. Making decisions based on their actual numerical values is asking for trouble, and you can almost always achieve the same result by using offsets between pointer values (as long as you know they&rsquo;re coming from the same memory block), which has none of those problems.</p>
<h3 id="asynchronous-file-io">Asynchronous File I/O</h3>
<p>This is where things start to get fun. A lot of games perform background loads while the game is running. Whenever the game detects it will need an asset, it initiates an asynchronous load. When the load is complete, the game is notified and, optionally, does some processing on that asset. There is no guarantee about when exactly the load will complete, which means that each playback has the potential to be slightly different.</p>
<p>If the background load just brings in more mipmaps for a texture, it&rsquo;s not going to affect the simulation whether it happened a frame earlier or a frame later. On the other hand, if it&rsquo;s loading a more detailed AI navigation path, it can definitely affect the position and state of AI units. Even if you&rsquo;re not loading data that affects the simulation, it&rsquo;s very useful to have asynchronous file IO work deterministically to catch bugs more reliably. For example, the game might crash if a background texture load completes the same frame as a line of dialog sound is requested. As any programmer who&rsquo;s ever had to debug a problem like this will tell you, being able to reliably reproduce that crash is worth a small fortune.</p>
<p>We can turn asynchronous file loading into a deterministic operation by considering the read completions as inputs to the game. Whenever an asynchronous file load completes, we record it in the game input file at the corresponding frame. During playback, the game will request background loads as usual, but completion events are made available only when they&rsquo;re read from the input stream.</p>
<p>This can be easily implemented at the game level by buffering all background read completions. During recording and normal game operation, background read completion events are made available as soon as they happen. During playback, however, background read completion events need to be available the exact same frame they happened in the original session. If the read finishes earlier, it is simply buffered for a few frames until the correct time. If the read hasn&rsquo;t completed by the time it finished in the original session, the game blocks until it&rsquo;s done and it&rsquo;s made available right away. That means that playback might be a bit choppy at times, while the game blocks for data to be read, but it will ensure that playback is fully deterministic. Notice that blocking the game while waiting for a read to complete is not going to affect subsequent frames with a larger delta time because we&rsquo;re also reading the system clock from the input stream.</p>
<h3 id="network-data">Network Data</h3>
<p>What about online games? Our playback method has been concerned exclusively with local players. Playtesting and Q/A on online games is much more expensive and time consuming than single-player games because of the manpower required and the coordination necessary to set the games up. Wouldn&rsquo;t it be great to be able to replay a 30-person game that resulted in a crash without having to get 30 players again?</p>
<p>Data received from the network most definitely influences the game itself, so it&rsquo;s another input to the game. We could treat all network traffic like any of the other inputs. Record it along with the other game input and play it back by inserting the network packets as if they had come from the network card. That would work, but it&rsquo;s a bit more complicated than it has to be. Fully emulating the network traffic, connection status, and everything else can be a bit tricky to get just right.</p>
<p>A simpler approach consists of translating the data received through the network into higher-level game actions. For example, whenever a player fires a weapon, it results in a network packet, which is translated into a game-level action whenever it&rsquo;s received. Then, the local simulation applies the action that causes that player to fire locally. You probably already have a system like that in place in your multiplayer game anyway. Recording those actions is a much simpler task than the raw network traffic, and playing back a recorded multiplayer game is just a matter of inserting the game-level actions at the same time they occurred, just like any other input.</p>
<p>The game input file is going to grow significantly as soon as you start recording all the actions created by the players through the network. Fortunately, most games are extremely careful to minimize network bandwidth, so the input file will remain at a reasonable size even recording all that data.</p>
<h3 id="threads-and-multiprocessors">Threads And Multiprocessors</h3>
<p>In today&rsquo;s games, multithreading is an inevitable reality. Even if your code isn&rsquo;t explicitly multithreaded, parts of your engine and middleware are probably using multiple threads. The problem with threads is that you never know exactly when one thread stops working and another one resumes. So it is possible that two events in two different threads will happen in different order in two runs of the game. To make things even more fun, most of today&rsquo;s platforms have multiple cores, making determinism even more complicated. Do we need to give up determinism in a thread-dominated world?</p>
<p>The totally honest answer is that we&rsquo;ve already picked all the low-hanging fruit. If you really want your game to be 100 percent deterministic while running in multiple threads over multiple cores, get ready to roll up your sleeves and do some serious work. For the rest of us, we can still get most of the benefits of a playback system without total determinism. That means that there is potential for bugs caused by thread interactions that might not be repeatable from run to run. But at least the game simulation will be the same for every playback, so the recording technique should still be very useful.</p>
<p>In the easiest case, the simulation runs on a single thread, with the rest of the threads dedicated to graphics, sound, and other systems. If we apply all the techniques we&rsquo;ve covered so far, the simulation itself should be deterministic and we shouldn&rsquo;t have to do anything different than we did in the singlethreaded case.</p>
<p>However, as soon as the simulation is spread across multiple threads, we need to be a lot more careful. Even if we have no control over the thread context switches, we can at least ensure that major events happen in the same order no matter how they were executed. For example, if a worker thread creates a set of actions to be executed, we can sort those actions before processing them. If that&rsquo;s not an option (because those actions are processed as soon as they are created, for example), we could record the creation order as part of the input recording, although enforcing that order during playback might have far reaching consequences for many systems deep inside the game.</p>
<p>If achieving 100 percent determinism in a threaded environment is important to your project, have a look at <a href="http://www.replaysolutions.com/technology">Replay Director</a>. It&rsquo;s a commercial tool and set of libraries that gives you very accurate recordings and playbacks of your game, including thread context switches, with little extra programming on your part.</p>
<h3 id="more-than-just-for-debugging">More Than Just For Debugging</h3>
<p>At this point, if you&rsquo;ve applied all the techniques we&rsquo;ve discussed so far, you should have a pretty bullet-proof recording and playback system: lightweight, reliable, and accurate. It will be a great help as a debugging tool, but there&rsquo;s no reason to stop there. You could use the same system to record demo sequences to show off in presentations without the need to make a movie capture and degrade the image quality. You can also truthfully claim that it&rsquo;s a live demo, running on the game itself, not a canned movie, which always carries extra weight with most audiences.</p>
<p>You can even integrate the playback system as a key feature in your game. Halo 3 already does this by allowing you to replay any play session, examine what happen exactly, and let you take screenshots of the juiciest moments. It can be a great feature for a lot of games for almost no extra effort over what you&rsquo;ve already implemented. The main problem will be to make sure future updates to the game don&rsquo;t affect the playback of older gameplay sessions. This is really hard to achieve, since the most insignificant change can end up causing the simulation to diverge in unexpected ways. So if you&rsquo;re going to rely on it as a game feature, you need a suite of comprehensive tests verifying that nothing changes whenever the game is updated. Last month we saw how to verify that a playback results in the same game state as the original session, so again, there&rsquo;s very little extra work there.</p>
<p>With all these techniques in your toolbox, you should be able to make your game pretty close to 100 percent deterministicâ€”enough to have a solid playback system and use it to its fullest during production, and maybe even as a game feature.</p>
<p>This article was originally printed in the June 2008 issue of <a href="http://www.gdmag.com/homepage.htm">Game Developer</a>.</p>]]></content:encoded></item><item><title>Back to The Future (Part 1)</title><link>https://gamesfromwithin.com/back-to-the-future-part-1/</link><pubDate>Fri, 22 Aug 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/back-to-the-future-part-1/</guid><description>&lt;p&gt;&lt;em&gt;Insanity: doing the same thing over and over again and expecting different results.&lt;/em&gt; â€“ (attributed) Albert Einstein&lt;/p&gt;
&lt;p&gt;How would you like to be able to reproduce every crash report that QA adds to the bug database quickly and reliably? How useful would it be to be able to put a breakpoint the frame before a crash bug happens?&lt;/p&gt;
&lt;p&gt;You can do all that and more if your game is deterministic and you feed it the same inputs as an earlier run. Sounds easy? It is, if you implement it early on and you keep it that way during development. If you choose not to make your game deterministic, your team will go insane by Einsteinâ€™s definition, and maybe by a few other definitions as well by the time the project ends.&lt;/p&gt;</description><content:encoded><![CDATA[<p><em>Insanity: doing the same thing over and over again and expecting different results.</em> â€“ (attributed) Albert Einstein</p>
<p>How would you like to be able to reproduce every crash report that QA adds to the bug database quickly and reliably? How useful would it be to be able to put a breakpoint the frame before a crash bug happens?</p>
<p>You can do all that and more if your game is deterministic and you feed it the same inputs as an earlier run. Sounds easy? It is, if you implement it early on and you keep it that way during development. If you choose not to make your game deterministic, your team will go insane by Einsteinâ€™s definition, and maybe by a few other definitions as well by the time the project ends.</p>
<h3 id="determinism">Determinism</h3>
<p>A system is said to be deterministic if, given the same set of inputs, it produces the same set of outputs. Think of your game as a big, black box, with some inputs and outputs.</p>
<p>The two main input types for most games are:</p>
<ul>
<li><em>Player input devices.</em> The state of the gamepad, keyboard, mouse, or any other input device is used to update the simulation.</li>
<li><em>System clock.</em> Most games query the system clock once per frame to retrieve a current time and delta time. The game then advances the simulation forward by that amount of time. Even console games that expect to run at a rocksolid 60 Hz are often implemented this way to be able to deal with different TV refresh rates or with slower builds during development.</li>
</ul>
<p>The main outputs of a game system are the pixels on the screen and the generated sounds. Optionally there are other outputs such as network packets or force feedback.</p>
<p>To make the game deterministic we need to make sure that, for a given set of inputs, it always produces the same outputs. In other words, playing the game twice, entering the same button presses at the exact times, the game will end up in the same state both times (same location, same health, number of lives, NPC positions, etc).</p>
<p>What about random numbers, which we rely on so much in games? Arenâ€™t random numbers inputs as well? Yes and no. In games we use pseudo random number generators. That means that the sequence of numbers from a particular seed is always the same. For a given seed, all runs of the game are fully deterministic, so the random numbers are not really an input into the system. The seed to the random number generator is an input, since it will greatly affect the state of the simulation.</p>
<h3 id="record-and-playback">Record and Playback</h3>
<p>Recording all player inputs and the system clock is as straightforward as it sounds: At the beginning of the simulation loop, sample the clock and the player input devices. Then save those values to a file and continue the game simulation as usual. You want to make sure the file is flushed after writing the values for each frame. That way, if the game crashes, youâ€™ll have all the input leading up to that frame and youâ€™ll be able to play it back right up to the point where it crashed.</p>
<p>Recording the input has a negligible performance impact and the amount of data saved is very small. As an example, in our current game, every frame we save the frame number, the clock time, frame delta time, and a 20-byte structure for each gamepad (see Listing 1). Without any compression, thatâ€™s 52 bytes per frame for a two-player game. At 60 Hz, a 20-minute game would be a tiny 3.6 MB, which is small enough to attach to a bug tracking system, email to the team, or archive with the build itself.</p>
<p><strong>Listing 1. Game input structures.</strong></p>
<pre tabindex="0"><code>struct FameInput{    uint32 frameNumber;    float time;    float dt;};

struct RawControllerState{    uint32 buttons;    float leftStickX;    float leftStickY;    float rightStickX;    float rightStickY;};
</code></pre><p>Using the recorded input for playback is almost as easy. Every frame, before the simulation starts, we read the input data from the file and feed it to the game as if it came from the system clock and the input devices. A clean way to do that is to separate the reading of the data from where it comes from. In C++ we can use abstract base classes that define an interface describing how to retrieve the data. For example, a class IGameInput can define an interface, and the class GamepadGameInput reads the data from the hardware, while the class FileGameInput reads it from the recorded file (see Listing 2).</p>
<p><strong>Listing 2. IGameInput, GamepadGameInput and FileGameInput</strong></p>
<pre tabindex="0"><code>class IGameInput{public:    virtual void GetInputData(RawControllerState&amp; state) = 0;};

class GamepadGameInput: public IGameInput{public:    virtual void GetInputData(RawControllerState&amp; state);};

class FileGameInput: public IGameInput{public:    virtual void GetInputData(RawControllerState&amp; state);};
</code></pre><p>In addition to recording and playing back those inputs every frame, we also need to record the seed to the random number generator before the game starts, and read it and apply it during playback. That will ensure that all the random numbers are the same in both runs of the game.</p>
<h3 id="verification">Verification</h3>
<p>If youâ€™re going to rely on this recording system, you need to make sure the playback produces the exact same results as the original session. If they arenâ€™t the same, the whole system is worthless. Also, because weâ€™re just recording input, if the state of the game during playback ever starts to diverge, it will continue getting more and more out of sync from there. We need a way to make sure the playback produces the same state as the initial recording.</p>
<p>Earlier we identified some of the outputs of the game as the pixels on the screen or the sound produced by the speakers. We could compare pixels with a previous run of the game, but the storage requirements would be enormous, and the performance less than ideal. Besides, subtle changes in shaders, lighting, or a simple texture change would throw the comparison off. An easier solution is to check the game state itself. If an enemy is in a different location in two runs of the game, of course itâ€™s going to render to a different set of pixels. It will be a lot faster and easier to compare game states than raw output.</p>
<p>During recording, in addition to the game input, we can save some of the state of the game. Thereâ€™s no need to record it all, just some of the most important and representative state. Good candidates include player and enemy positions, prop transforms, score, etc. Unless itâ€™s crucial to your game, thereâ€™s no need to record things like player animations or enemy AI state. Chances are that if any of those diverge, the positions for those entities will also diverge right away.</p>
<p>Once we have all of this state recorded, we can verify the state does not change during playback. Every frame, we compare the current game state with the recorded game state. If theyâ€™re different, even by the smallest amount, we know something has gone wrong and we flag it right away. The game isnâ€™t quite deterministic and something needs to be fixed. We can choose to record and verify the game state anywhere in the simulation loop (as long as theyâ€™re both done in the same spot), but if we do it after the simulation step instead of before, weâ€™ll be able to see what the inputs were that caused the divergence this frame, which will help when debugging. The main loop is shown in Listing 3.</p>
<p><strong>Listing 3. Main loop structure</strong></p>
<pre tabindex="0"><code>while (!done){    SampleClockAndInputs();   // from different sources through the same interface    RecordInput();    UpdateSimulation();    if (recordGameState) RecordGameState();    if (verifyGameState) VerifyGameState();}
</code></pre><p>Unlike recording game input, recording the game state can be a much more expensive operation. Traversing the game structures can be a significant performance hit due to cache misses, and the data saved to disk often results in large files. Because of this, in our current game player input is recorded all the time, but recording game state is optional, and we can be controlled through a command-line parameter. Game state verification is also optional, since sometimes we want to play back a recorded set of inputs even knowing that the state of the game is going to diverge due to changes weâ€™ve made.</p>
<p>For a few of you, checking the game state wonâ€™t be enough. If youâ€™re writing a middleware graphics layer, you probably want to verify that the values youâ€™re generating in the back buffer are the same ones from a previous pass. Or maybe that improving the performance of a rendering algorithms still generates the same image. In that case, you might want to consider something like <a href="http://pdiff.sourceforge.net/">Perceptual Image Difference</a>, which will be a much less error-prone than comparing exact values for pixels.</p>
<h3 id="monkeying-around">Monkeying Around</h3>
<p>Once the game is fully deterministic and the playbacks are rock solid, you want to make sure it stays that way. Itâ€™s all too easy to introduce bugs that will cause playbacks to diverge. For example, a single, innocent-looking, uninitialized variable can change the simulation depending on the value it happens to have for this run.</p>
<p>The best method Iâ€™ve found to stress test the playback system is to use a recorded session of monkey input. The monkey input method consists of feeding the game pseudo-random inputs (as if a monkey were playing the game). Recording both the input and game state of a monkey input play session, and then playing it back verifying the game state kills two birds with one stone: You get some nice automated testing of your game, and you verify that the game is fully deterministic. It sounds too simple to be useful, but youâ€™ll be amazed at how many bugs your first session of monkey input will uncover.</p>
<p>A clean way to implement the monkey input, is writing a new class that implements the IGameInput interface. This new class will generate game input for all the buttons and axes of a game controller, but it wonâ€™t come from the hardware game controller or from a recorded session, but from randomly generated values. Apart from being a very clean way to insert input into the game, this approach has the advantage that the monkey input can be recorded just as if it were regular input coming from the controller. That means we can later replay a session and verify its game state, which makes for a very useful functional test.</p>
<p>It turns out that totally random input values are not ideal, as it becomes apparent as soon as you implement the naive random monkey input class. If the state of the jump button is truly random, it will be pressed and released almost every frame, which means the player will hardly ever jump high enough off the floor. A better implementation will use a range with a minimum and maximum press time durations, which will give much better results. You might also want to avoid pressing specific buttons (like the pause button, or the restart button combination). Resist the temptation to make the monkey input too smart and make it behave more like a real player, for example, by limiting the number of buttons it can have pressed simultaneously. Part of the benefit of the monkey input is that it will do very unexpected things, that no sane player will ever do on purpose, and by doing that, it will unearth many more problems and issues with the game.</p>
<p>One day, shortly after I implemented the monkey input system, the playback verification started failing. Some game entities were ending up in a different state than expected. After doing some digging, I realized that I was using the same random number generator for the game simulation and for the monkey input. Since the playback was just reading input values from the file and not generating them on the fly, the random number sequence was getting off sync right away, causing entities with some randomness in them to behave differently. Lesson learned: Make sure that nothing in the monkey input affects the game systems. In this case, I solved it by using two instances of the random number generator, one for the monkey and one for the game.</p>
<h3 id="playback-in-the-real-world">Playback in The Real World</h3>
<p>At this point we can easily reproduce bugs. We can re-run the game and put a breakpoint right before the game crashesâ€”except that the crash happens 20 minutes into the playback and nobody wants to wait that long.</p>
<p>Fortunately, we can make time go by faster. During playback we don&rsquo;t care about tearing artifacts, so we can turn off the vertical sync, which will speed things up a bit. Most importantly, we often donâ€™t even care whether we render anything or not, so if we turn off rendering completely, we can make the playback run significantly faster, particularly if you were graphics bound. One word of caution: If the rendering part of the game does significant work, and especially if you suspect it might be interacting with the rest of the game to cause a bug or some other source of non-determinism, you might want to do the same work in the rendering system, constructing the push buffer the way you would normally do, but never send it off to the graphics hardware.</p>
<p>Turning off the vertical sync and disabling the graphics rendering, is just reducing the amount of time we spend in each frame. But it still takes 10 minutes to get 10 minutes into the game, we just go through many more frames to get there. The last piece of the puzzle to make time go faster is to be able to set a fixed timestep. Now we can go through the simulation at a rate much faster than real time (and the beefier you computer, the faster it will go). In my current game, we can go through 10 minutes of game time in about 1 minute of real time.</p>
<p>One use for recording and playback that we havenâ€™t mentioned is performance comparisons. When youâ€™re optimizing the game, you can record a gameplay sequence and gather some performance statistics: average fps, longest frames, etc. Then you can apply your optimizations, playback the same input sequence, and compare the performance statistics to see how effective the optimizations really were. Just make sure you use real clock time and not the recorded clock time, otherwise you wonâ€™t see any differences, even with all the hard effort you put into the optimizations.</p>
<p>There are a few details we glossed over that might prevent some games from begin fully deterministic: network traffic, asynchronous file I/O, and threading issues. Weâ€™ll cover those in detail next month.</p>
<p>Youâ€™ll soon find that input recording and playback becomes an essential tool for in development process and youâ€™ll wonder how you ever lived without it. Spend a few hours implementing it early in the development cycle and reap the benefits many times over during production. Youâ€™ll be the hero of the day when that dreaded crash bug from QA arrives minutes before a deadline.</p>
<p>Thanks to <a href="http://www.tilander.org/aurora/">Jim Tilander</a> for being a great idea bouncing-board and proofreading the article.</p>
<p>This article was originally printed in the May 2008 issue of <a href="http://www.gdmag.com/homepage.htm">Game Developer</a>.</p>]]></content:encoded></item><item><title>The Measure Of Code</title><link>https://gamesfromwithin.com/the-measure-of-code/</link><pubDate>Fri, 13 Jun 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-measure-of-code/</guid><description>&lt;p&gt;I&amp;rsquo;ve gotten a lot of questions about how big our codebase is, how fast does it build, how many tests we have&amp;hellip; Fear not, Gentle Reader, all your burning questions will be answered here.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve gotten a lot of questions about how big our codebase is, how fast does it build, how many tests we have&hellip; Fear not, Gentle Reader, all your burning questions will be answered here.</p>
<h2 id="size">Size</h2>
<p>Charles and I were priding ourselves in keeping things small and minimal. But truth be told, it&rsquo;s not like we were keeping track of how many lines of code we had written. Were things as small as we hoped they were?</p>
<p>The most convenient way of counting lines of code that I know is <a href="http://cloc.sourceforge.net/">CLOC</a>. It&rsquo;s an extremely easy to use open source program which counts the lines of code in a codebase, gives very detailed information, strips out whitespace, breaks things down by language, and does just about everything you&rsquo;d want from a program like that.</p>
<p>Running it on the latest version of our code (not including any 3rd party libraries) produces this:</p>
<pre tabindex="0"><code>Â Â Â  1621 text files.Â Â Â  1579 unique files.Â Â Â  3721 files ignored.
-------------------------------------------------------------------------------
LanguageÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â filesÂ Â Â Â Â Â Â Â Â  blankÂ Â Â Â Â Â Â  commentÂ Â Â Â Â Â Â Â Â Â code
-------------------------------------------------------------------------------
C++Â Â Â Â Â Â  Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â 485Â Â Â Â Â Â Â Â Â  13577Â Â Â Â Â Â Â Â Â Â Â  303Â Â Â Â Â Â Â Â Â  46181
C#Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  324Â Â Â Â Â Â Â Â Â Â  4935Â Â Â Â Â Â Â Â Â Â Â  712Â Â Â Â Â Â Â Â Â  22966
C/C++ HeaderÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  407Â Â Â Â Â Â Â Â Â Â  4153Â Â Â Â Â Â Â Â Â Â Â Â  95Â Â Â Â Â Â Â Â Â  11975
MSBuild scriptsÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  18Â Â Â Â Â Â Â Â Â Â Â Â Â  0Â Â Â Â Â Â Â Â Â Â Â  126Â Â Â Â Â Â Â Â Â Â 1490
-------------------------------------------------------------------------------
SUM:Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  1234Â Â Â Â Â Â Â Â Â  22665Â Â Â Â Â Â Â Â Â Â  1236Â Â Â Â Â Â Â Â Â  82612
</code></pre><p>Almost 60K lines of C++ code seemed very high. At first I thought it was because CLOC was counting files twice: once in their regular location and once in the .svn directory, but apparently it&rsquo;s already removing all duplicates, so that wasn&rsquo;t it.</p>
<p>Almost more scary than the amount of C++ code (which is all our runtime and some of our tools) is the amount of C# code. For a language that claims to be of significantly higher level than C++, that&rsquo;s quite a mouthful of code!</p>
<p>Another surprising count in there is the number of lines with comments. Since we make heavy use of <a href="http://www.gamesfromwithin.com/articles/cat_testdriven_development.html">TDD</a>, I really didn&rsquo;t expect more than a couple dozen lines of code in the whole codebase. Still, I&rsquo;m kind of proud that we have less than one line of code per file on average :-)</p>
<p>Here&rsquo;s a more detailed breakdown, with the line count just for our runtime (engine and game):</p>
<pre tabindex="0"><code>1089 text files.    1053 unique files.    2338 files ignored.
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C++                            441          11997            245          40943
C/C++ Header                   385           3964             90          11405
-------------------------------------------------------------------------------
SUM:                           826          15961            335          52348
</code></pre><p>and for our tools:</p>
<pre tabindex="0"><code>532 text files.     531 unique files.    1383 files ignored.
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C#                             324           4935            712          22966
C++                             44           1580             58           5238
MSBuild scripts                 18              0            126           1490
C/C++ Header                    23            199              5            591
-------------------------------------------------------------------------------
SUM:                           409           6714            901          30285
</code></pre><h2 id="tests">Tests</h2>
<p>Then I realized that a good chunk of those were tests. So excluding all directories matching *Tests* gets the following result:</p>
<pre tabindex="0"><code>1206 text files.    1187 unique files.    4199 files ignored.
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C++                            283           6464            150          22464
C#                             213           2636            534          12402
C/C++ Header                   380           3824             94          10782
MSBuild scripts                 12              0             84            978
-------------------------------------------------------------------------------
SUM:                           888          12924            862          46626
</code></pre><p>A bit more than half the C++ code consisted of tests. That&rsquo;s pretty consistent with my experience with TDD. C# seems to follow a similar percentage as well.</p>
<p>As for the exact number of tests, running a grep for TEST shows all the C++ tests:</p>
<pre tabindex="0"><code>C:\pow2&gt;grep -r TEST SweetPea Engine Tools | grep -v svn | wcÂ Â  2163Â Â Â  3620Â  221953
</code></pre><p>And doing the same thing with [Test] brings up all C# tests:</p>
<pre tabindex="0"><code>C:\pow2&gt;grep -r \[Test\] SweetPea Engine Tools | grep -v svn | wcÂ Â  735Â Â Â  1470Â Â 52717
</code></pre><p>That means that our average C++ test is about 11.5 lines long, and C# tests 14.4. Frankly, that sounds rather high. We make heavy use of fixtures whenever possible and each test usually only checks for a single condition (even if it involves a couple check statements). I suppose that number is higher than expected because it probably includes all the lines from #include statements and all the fixtures as part of the average.</p>
<table>
	<thead>
			<tr>
					<th><strong>Language</strong></th>
					<th><strong>Lines</strong></th>
					<th><strong>Non test lines</strong></th>
					<th><strong>Test lines</strong></th>
					<th><strong>% of non test code</strong></th>
					<th><strong>Number of tests</strong></th>
					<th><strong>Lines per test</strong></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>C++</td>
					<td>58156</td>
					<td>33246</td>
					<td>24910</td>
					<td>57% *</td>
					<td>2163</td>
					<td>11.5</td>
			</tr>
			<tr>
					<td>C#</td>
					<td>22966</td>
					<td>12402</td>
					<td>10564</td>
					<td>54%</td>
					<td>735</td>
					<td>14.4</td>
			</tr>
	</tbody>
</table>
<p>* If we only count cpp files, that goes down to 49%</p>
<p>I was curious about that last part of checking a single thing per test, so I ran a grep for the number of CHECK statements in our code:</p>
<pre tabindex="0"><code>C:\pow2&gt;grep -r CHECK SweetPea Engine Tools | grep -v svn | wcÂ Â  3886Â Â  15079Â  399598
</code></pre><h2><img loading="lazy" src="images/tapemeasure.jpg"></h2>
<p>That&rsquo;s 1.8 CHECK statements per TEST, which is about right. Even though we&rsquo;re checking for a single condition, we&rsquo;ll often check a couple things about it (i.e. the camera stopped and it reached its final destination).</p>
<h2 id="build-times">Build Times</h2>
<p>So, given that amount of code, how long does it take to build it? Clearly it depends on your hardware. Since we&rsquo;re not exactly rolling in money, we don&rsquo;t have particularly powerful machines. Here at home, I&rsquo;m using a modest Core 2 Duo E4300 (overclocked to 2.6 GHz) with fast memory and a relatively fast SATA hard drive, so that&rsquo;s what I used for all my timings.</p>
<p>A full build of our game, plus all the libraries, all the tests, and running all the tests takes exactly 1 minute and 10 seconds. That&rsquo;s pretty good for two reasons:</p>
<ul>
<li>When we work with the game we don&rsquo;t build and run the unit tests for the engine. We have a separate solution for that. A full build of just the engine, the game, and the game unit tests only takes 43 seconds.</li>
<li>The game itself is a fairly large project and devenv doesn&rsquo;t know how to paralellize that build, so it&rsquo;s only using half the available CPU power for about half the build time.</li>
</ul>
<p>An incremental build after changing a single cpp file takes <a href="http://powerof2games.com/node/32">slightly over a second</a> (including half a second of unit test execution).</p>
<p>As you can imagine, working with that codebase is a dream come true. Snappy, responsive. Nothing is hard enough that can&rsquo;t be changed.</p>
<p>Unfortunately that&rsquo;s where the fairy tale ends. The tools are another story altogether. Our C# tools, with all their unit tests, build in a mere 18 seconds, and the C++ tools in 1 minute and 10 seconds. That&rsquo;s not too bad, except that it&rsquo;s a surprisingly large amount of time for the C++ tools since there aren&rsquo;t that many of them.</p>
<p>Here&rsquo;s the kicker, doing another build without changing a single thing take 38 seconds. Whoa! We&rsquo;re doing some C++/CLI trickery and apparently dependency checking is totally broken in VS2005 (either that, or we just don&rsquo;t know how to set it up right).</p>
<h2 id="keeping-things-fast">Keeping things fast</h2>
<p>What&rsquo;s the secret of a lighting-fast build? Clearly, keeping the code size down is crucial. If your codebase is 2 million lines of code, builds are going to be painful no matter what. But they can be a little less painful with some gentle care.</p>
<p>One of the main build-time killers that we&rsquo;re avoiding is the use of STL or <a href="http://www.boost.org/">Boost</a>. Those libraries pull in everything and the kitchen sink, and their heavy use of templates make build and link time go through the roof. No thanks.</p>
<p>Our template use is pretty minimal. We have a couple containers (which I love and I&rsquo;ll write about it one of these days) and that&rsquo;s about it.</p>
<p>We&rsquo;re pretty anal when it comes to keeping <a href="/physical-structure-and-c-part-2-build-times/%20">physical dependencies</a> to a minimum. We forward declare aggressively, and we only include the headers that are necessary for each cpp file (<a href="http://www.gimpel.com/">PC Lint</a> is &ldquo;kind&rdquo; of enough to remind us every time we have unnecessary #includes). We&rsquo;re not using external include guards or #pragma once.</p>
<p>Precompiled headers are either not used, or kept to a minimum. I think the only project that uses them is the game and only for Havok headers. We don&rsquo;t even have windows.h in a precompiled header (which would be a really bad idea because you&rsquo;d be putting all the junk in windows.h available to your whole program).</p>
<p>Finally, we are using incremental links whenever possible. I remember a few versions of Visual Studio ago they were pretty broken, but they&rsquo;re not giving us any problems. The only caveat is that if you modify a static library your program is linking with, it will force a full link. So they&rsquo;re really only good for modifying the executable itself.</p>
<p>We&rsquo;re not using any distributed builds. First of all, we don&rsquo;t have enough computers to make it worthwhile. And second, I had horrible experiences with distributed builds in the past. They would help with a badly structured codebase, at the cost of longer incremental builds and mysterious spurious bad builds. Besides, once they&rsquo;re in place, they tend to encourage even further disregard for keeping dependencies to a minimum.</p>
<h2 id="how-about-you">How about you?</h2>
<p>So, that&rsquo;s it for the Power of Two codebase. How about you? Want to share your size, build times, or any other data?</p>]]></content:encoded></item><item><title>What's Your Pain Threshold?</title><link>https://gamesfromwithin.com/whats-your-pain-threshold/</link><pubDate>Tue, 10 Jun 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/whats-your-pain-threshold/</guid><description>&lt;p&gt;Mine is two seconds.&lt;/p&gt;
&lt;p&gt;Here at Power of Two Games, we write all our code with &lt;a href="https://gamesfromwithin.com/backwards-is-forward-making-better-games-with-test-driven-development/"&gt;test-driven development.&lt;/a&gt; C++ tests use the fantastic &lt;a href="http://unittest-cpp.sourceforge.net/"&gt;UnitTest++ framework&lt;/a&gt; (no big surprise there :-) ) and we run all unit tests automatically as the last step of our build process. That means that every time we build anything, the tests for that library or program get executed. Every time. No exceptions.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Mine is two seconds.</p>
<p>Here at Power of Two Games, we write all our code with <a href="/backwards-is-forward-making-better-games-with-test-driven-development/">test-driven development.</a> C++ tests use the fantastic <a href="http://unittest-cpp.sourceforge.net/">UnitTest++ framework</a> (no big surprise there :-) ) and we run all unit tests automatically as the last step of our build process. That means that every time we build anything, the tests for that library or program get executed. Every time. No exceptions.</p>
<p>None of that would be an issue except that TDD creates lots of unit tests and encourages almost constant incremental builds. In the past I&rsquo;ve stressed how important it is to keep them fast. But this week that I was able to really feel what a dramatic difference slow unit tests make.</p>
<p>For many months, our unit tests ran under one second. Each library has its own set of unit tests, and so does the game and each tool. So even though we were writing lots of unit tests, we weren&rsquo;t always running them all at the same time. There was a definite snappiness to coding: write test, compile, fail, write code, compile, pass, move on. Go, go, go.</p>
<p>As the game project got larger, we started accumulating more unit tests and testing times started creeping up into the second range. At the time, I couldn&rsquo;t quite put my finger on what had changed, but there was a definite change in feel. Things weren&rsquo;t quite as snappy.</p>
<p>Then, about a couple of weeks ago, we hit the two second mark and things definitely changed.</p>
<pre tabindex="0"><code>&gt; bin\SweetPea_d.exe -unittestSuccess: 1145 tests passed.Test time: 2.13 seconds.
</code></pre><p>As the tests were running, my mind would wander, thinking about what test I would write next, or whether the code I had just written would be cache-friendly, or whether we&rsquo;d do Honey&rsquo;s or Manhattan for lunch. I would be jerked out of my <a href="http://en.wikipedia.org/wiki/Flow_%28psychology%29">state of flow</a>. It wasn&rsquo;t just me, Charles felt it too. The difference in productivity was huge.</p>
<h2 id="the-zones">The Zones</h2>
<p>For those of you laughing at those times and dismissing them as insignificant, you need to keep in mind that our build times are very short:</p>
<ul>
<li>An incremental build with just a change in a cpp file takes under a second (including link times).</li>
<li>A full build of *all* our runtime code, including libraries, is around 50 seconds in a dual-core machine <a href="#note1">[1]</a>.</li>
</ul>
<p>So adding on 2 seconds to the incremental build time is going from â€œpractically instantâ€ to â€œOK, I&rsquo;m waiting&hellip;â€.<img loading="lazy" src="images/antique-clocks.jpg"></p>
<p>Of course, none of this has anything to do with unit tests in particular. It&rsquo;s total incremental build times (including compiling, linking, and running unit tests) that matter. An incremental build that takes 3 seconds with no unit tests is just as bad as one that is under one second with 3 second unit tests. They both interrupt the flow the same way.</p>
<p>I&rsquo;ve often thought about how a company size affects communication and â€œfeelâ€. It&rsquo;s close to a step function with logarithmic scale: there&rsquo;s a distinct jump from a company of 3 to a company of 10, to one of 35, to one of 100+.</p>
<p>I think something similar applies to build times <a href="#note2">[2]</a></p>
<ul>
<li>0 to 2 seconds. Programmer stays in the flow. Productivity is way high.</li>
<li>2 to 8 seconds. Flow is broken. Definite feel of things being a bit painful and sluggish.</li>
<li>8 to 30 seconds. Attention wanders to other parts of the code, email, etc. Multitasking kicks in and overall productivity plummets.</li>
<li>30+ seconds. Builds seen as batch processing. After each build is started, some other action is started. Maybe even physically get up, get a drink, start a conversation. Full brain reboot between coding tasks.</li>
<li>5+ minutes. Programmers bang their heads against the desk, actively consider the merits of different forms of suicide, or at the very least start polishing their resumes.</li>
</ul>
<h2 id="the-fix">The Fix</h2>
<p>Having been spoiled by sub-second build times, neither one of us wanted to put up with the broken flow of 2+ second builds, so we decided it was time to fix things <a href="#note3">[3]</a>.</p>
<p>The good news is that our slow build times were solely due to running the unit tests. 2.13 seconds to run only about 1100+ tests is really bad, even on a so-so desktop machine like the ones we can afford. That&rsquo;s almost 2ms per test! Remember that these are unit tests, not functional tests. So I expect to be able to run several thousands of these under one second. Something was way off.</p>
<p>Things had gotten much worse in the last couple of weeks, so it wasn&rsquo;t a slow, steady creep up. Chances are we had introduced something very slow recently, which meant it was probably easy to fix.</p>
<p>As a first pass, we turned on the option to fail any test that takes over a certain amount of time in UnitTest++:</p>
<pre tabindex="0"><code>RunAllTests(reporter, UnitTest::Test::GetTestList(), NULL, 5); // fail any test over 5ms
</code></pre><p>That brought about tons of failing test, most of them added recently and creating one particular object in their fixtures. Digging a big deeper, that particular class had an array of 25,000 (yes, that many zeros) objects. Those objects were <a href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">plain-old-data structures</a>, but had a default constructor. Even though the constructor was simply initializing its members to zero, that was causing a significant slow down when so many objects were created. To make things worse, some of the code I had written was iterating over the array resetting the entries or shifting them up or down, repeatedly calling the constructor. Ouch!</p>
<p>A few minutes and lots of code hacking later, and the object didn&rsquo;t call a single constructor anymore. Our test times went down by almost half. Victory!</p>
<p>We were already at 1 second, which is in the acceptable range, but since we were here, maybe we could improve things a bit more. After all, 1ms per test is still too slow.</p>
<p>UnitTest++ wasn&rsquo;t reporting failing tests over 1ms very reliably. Different runs would cause very different results. Things were too spread out or other things in the computer were interfering too much.</p>
<p>About a fifth or so of our tests use Havok. Not with mocks, but directly. They each initialize Havok, create a world, and deal with a simple rigid body, constraint, or something of the sort. I suspected all along that the Havok system initialization and shutdown for each test was probably causing quite a slow down, so I changed it to be initialized only once before we ran any tests.</p>
<p>And that did the trick. With that change we were down to 0.16 seconds. Back to snappy, happy land!</p>
<pre tabindex="0"><code>&gt; bin\SweetPea_d.exe -unittestSuccess: 1145 tests passed.Test time: 0.16 seconds.
</code></pre><p>In release mode things are even better, but we do most development in debug mode, so that&rsquo;s the really important one:</p>
<pre tabindex="0"><code>&gt; bin\SweetPea.exe -unittestSuccess: 1145 tests passed.Test time: 0.06 seconds.
</code></pre><p>Perhaps sub-second build times are not realistic for all projects, but I think there&rsquo;s a lot to be gained by keeping compile, link, and test times as short as possible. For tips on how to keep compile times down, check out <a href="/physical-structure-and-c-part-1-a-first-look/%20">these articles</a> <a href="/physical-structure-and-c-part-2-build-times/%20">I wrote a while ago</a>. If your unit tests are slow and you really can&rsquo;t speed them up anymore, consider splitting them into two sets: one that is important or recent ones that runs with every build, and another, more comprehensive one that runs in the build server.</p>
<p>Even if you cut down from 20 seconds down to 10, you&rsquo;ll be making a huge shift in how you&rsquo;re able to work and iterate on your programming.</p>
<p>[1] We&rsquo;d love to keep detailed metrics with each build: executable size, number of lines of code, number of tests, etc, etc. Unfortunately, when the rubber hits the road, that ends up in the â€œnice to have categoryâ€ and we simply have no resources to spare on a two-man startup.</p>
<p>[2] For a whole whooping statistical population of one since I&rsquo;m only talking about my experience. Still, I suspect that the same applies to many other programmers by scaling the function by some constant.</p>
<p>[3] Perfect use of agile mentality. Fix things when you need them fixed, not before. But make sure you do fix them when you need them. Otherwise it&rsquo;s not agile, it&rsquo;s just lazy.</p>]]></content:encoded></item><item><title>Stupid C++ Tricks #2: Better Enums</title><link>https://gamesfromwithin.com/stupid-c-tricks-2-better-enums/</link><pubDate>Mon, 14 Apr 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/stupid-c-tricks-2-better-enums/</guid><description>&lt;p&gt;So much for the new year&amp;rsquo;s resolution to write some sort of an update every week. That went out the window pretty quickly. Especially now that I&amp;rsquo;ve taken over the Inner Product column for Game Developer Magazine and that&amp;rsquo;s taking away some of my writing time (check out the May issue for my first column!).&lt;br&gt;
It turns out that Charles&amp;rsquo; old article &lt;a href="http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/" title="Stupid C++ Tricks: Adventures in Assert"&gt;Stupid C++ Tricks: Adventures in Assert&lt;/a&gt; is one of our most viewed entries, even after all this time. So I figured I&amp;rsquo;d follow it up with a really, really simple C++ trick. It&amp;rsquo;s almost trivial, really, but I&amp;rsquo;ve totally fallen in love with it. At first, when Charles introduced me to it, I was kind of lukewarm. But now I&amp;rsquo;m finding myself going through refactoring rampages in the code changing things to be this way. Intrigued? Read on.&lt;/p&gt;</description><content:encoded><![CDATA[<p>So much for the new year&rsquo;s resolution to write some sort of an update every week. That went out the window pretty quickly. Especially now that I&rsquo;ve taken over the Inner Product column for Game Developer Magazine and that&rsquo;s taking away some of my writing time (check out the May issue for my first column!).<br>
It turns out that Charles&rsquo; old article <a href="http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/" title="Stupid C++ Tricks: Adventures in Assert">Stupid C++ Tricks: Adventures in Assert</a> is one of our most viewed entries, even after all this time. So I figured I&rsquo;d follow it up with a really, really simple C++ trick. It&rsquo;s almost trivial, really, but I&rsquo;ve totally fallen in love with it. At first, when Charles introduced me to it, I was kind of lukewarm. But now I&rsquo;m finding myself going through refactoring rampages in the code changing things to be this way. Intrigued? Read on.</p>
<p>C++ enums are great in practice, but they&rsquo;re a bit lacking once you really start flexing them. Don&rsquo;t get me wrong, they&rsquo;re definitely a step up from #defines, but you can&rsquo;t help but wish for more. Type safety is only so-so (enums get promoted to ints silently), you can&rsquo;t forward declare them so you&rsquo;re forced to have extra includes, you can&rsquo;t split up a declaration of enums across multiple files (the compiler would have to do more work, but it would be awesome to be able to create uids for different classes in their own header files instead of a global one). But the most grating of design decisions is their scoping rules.<br>
Take for example a set of enums describing the game flow:</p>
<pre tabindex="0"><code>enum GameFlowType
{
    Run,
Â    Exit,
   Â Restart,
   Â Restore,
};
</code></pre><p>Now functions can return a GameFlowType to indicate that the main loop should do. So far so good.</p>
<p>Except that, look at how it&rsquo;s used:</p>
<pre tabindex="0"><code>GameFlowType DoMainLoop(bool render)
{
    //...
   Â if (someCondition)
       Â return Exit;
   Â return Run;
}
</code></pre><p>Ouch! We&rsquo;ve managed to pollute the global namespace with totally generic keywords such as Run and Exit. What if I want to have an enum that controls what action an AI is going to take:</p>
<pre tabindex="0"><code>enum AIAction
{
Â Â Â  Enter,
Â Â Â  Exit,
Â Â Â  Stop,
Â Â Â  Walk,
Â Â Â  Run,
};
</code></pre><p>That won&rsquo;t even compile because the symbols conflict with the GameFlowType ones. Even worse, it will compile just fine if they don&rsquo;t happen to be included in the same compilation unit. So you might be fine all along until you write some AI code that has control over the game flow. Oops!<br>
OK, so you can prefix all your enums like this:</p>
<pre tabindex="0"><code>enum GameFlowType
{
    GameFlowTypeRun,
    GameFlowTypeExit,
    GameFlowTypeRestart,
    GameFlowTypeRestore,
};
</code></pre><p>and</p>
<pre tabindex="0"><code>enum AIAction{
    AIActionEnter,
    AIActionExit,
    AIActionStop,
    AIActionWalk,
    AIActionRun,
};
</code></pre><p>That will technically fix the problem, but it&rsquo;s a bit ugly, and we&rsquo;re still polluting the global namespace (what if I wanted to have a class called AIActionEnter?).</p>
<p>Another potential solution is to score the enum inside the class that is using them. So we could have:</p>
<pre tabindex="0"><code>class AIAction{
public:
    enum AIActionType
    {
        Enter,
        Exit,
        Stop,
        Walk,
        Run,
    };
};
</code></pre><p>Much cleaner, do doubt, but also with its share of problems: First of all, it forces you to associate a set of enums with a class, which is not something you always want to do. But the biggest problem is that as soon as you have more than one set of enums per class, they all get promoted to the same scope:</p>
<pre tabindex="0"><code>class AIAction
{
public:
    enum AIActionBehavior
    {
        Enter,
        Exit,
        Stop,
        Walk,
        Run,
    };

    enum AIActionGroup
    {
        None,
        Self,
        Team,
        All,
    };
};
</code></pre><p>When we see one of those enums in code referred to as AIAction::Self, we really have no idea that it&rsquo;s referring to that group the action is applied to, as opposed to AIAction::Enter, which is the type of action.<br>
Our solution? Move all enums into a descriptive namespace.</p>
<pre tabindex="0"><code>namespace GameFlowType
{
    enum Enum
    {
        Invalid,
        Run,
        Exit,
        Restart,
        Restore,
    };
}
</code></pre><p>When you have a variable of that enum type, it&rsquo;s listed as GameFlowType::Enum type, which clearly indicates what it does. And its values are referred to as GameFLowType::Exit. You get the ideal scoping, you&rsquo;re not tied to any particular class, things are explicit but not verbose, you&rsquo;re no polluting the global namespace, and it&rsquo;s doesn&rsquo;t affect the runtime or compilation times.<br>
Sometimes the best solutions are the simplest ones.</p>]]></content:encoded></item><item><title>LeChimp's Secret Weapon: Lint</title><link>https://gamesfromwithin.com/lechimps-secret-weapon-lint/</link><pubDate>Tue, 15 Jan 2008 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/lechimps-secret-weapon-lint/</guid><description>&lt;p&gt;&lt;a href="../../../../node/25"&gt;LeChimp&lt;/a&gt; has been rocking my world lately. I&amp;rsquo;ve been checking in code that passes all the unit tests, confident that everything was fine, just to find out the functional test fails loudly and obnoxiously &lt;a href="#%5B1%5D"&gt;[1]&lt;/a&gt;. The other day it even managed to put the game in an infinite loop (yes, my fault). It might sound annoying, but I love it how LeChimp keeps us honest and makes subtle problems immediately obvious.&lt;/p&gt;
&lt;p&gt;A couple of months ago something unusual happened: The functional test failed but I wasn&amp;rsquo;t able to reproduce the problem right away. The failure was not a crash, but an object in the world ending up in a different state than expected. That&amp;rsquo;s always tougher to track down. To make things even more fun, was object was affected changed depending on whether the game was run from the command line or the debugger. Oh, and did I mention it only happened in release mode? I&amp;rsquo;ve got a baaad feeling about this!&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="../../../../node/25">LeChimp</a> has been rocking my world lately. I&rsquo;ve been checking in code that passes all the unit tests, confident that everything was fine, just to find out the functional test fails loudly and obnoxiously <a href="#%5B1%5D">[1]</a>. The other day it even managed to put the game in an infinite loop (yes, my fault). It might sound annoying, but I love it how LeChimp keeps us honest and makes subtle problems immediately obvious.</p>
<p>A couple of months ago something unusual happened: The functional test failed but I wasn&rsquo;t able to reproduce the problem right away. The failure was not a crash, but an object in the world ending up in a different state than expected. That&rsquo;s always tougher to track down. To make things even more fun, was object was affected changed depending on whether the game was run from the command line or the debugger. Oh, and did I mention it only happened in release mode? I&rsquo;ve got a baaad feeling about this!</p>
<p>My first instinct was to blame it on <a href="http://www.havok.com/content/view/17/30/">Havok</a>. After some investigating, I narrowed it down to one of the enemies that was in mid-air. Sometimes it would fall down, and other times it would stay hovering, as if not affected by gravity. I knew that Havok was supposed to be deterministic, but it&rsquo;s every programmer&rsquo;s instinct to always mistrust other people&rsquo;s code. I should have known better.</p>
<p>I spent a whole day tracking this down. Adding more and more information to the recorded world state to detect the problem as soon as possible. Slowly circling in; silently creeping up on the unsuspecting bug. Eventually, I had my â€œaha!â€ moment. I had finally found it.</p>
<p>A member variable, m_alive, in the RobotLogical class was never initialized! That was causing the Havok character controller not to be updated sometimes, causing the discrepancy in object state between the recording pass and the playback pass. What made it even more difficult is that m_alive is a boolean, so any bit pattern other than zero, it&rsquo;s going to make it true, which is the initial state I expected for the robots. It never failed in debug mode because unused heap memory is filled with patterns like 0xdeadbeef or (the definitely less fun, but more practical) 0xcdcdcdcd, which all make the variable come up as true. Doh!</p>
<p>Yes, C++ sucks because of time-wasters like that, but it didn&rsquo;t prevent me from feeling really stupid for having sunk a whole day on it.</p>
<p>All the code Charles and I write is done through TDD so we have almost 100% unit-test coverage <a href="#%5B2%5D">[2]</a>. How come Test Driven Development didn&rsquo;t catch that? TDD is not about catching bugs, it&rsquo;s about designing code. This is the type of error that is only triggered once every thousand times, so running one or two unit tests that cover that path probably won&rsquo;t trigger it. That&rsquo;s one of the many reasons end-to-end functional tests are invaluable. Go LeChimp!</p>
<h3 id="help-lechimp-help">Help, LeChimp! Help!</h3>
<p>Detecting there&rsquo;s a problem is good, but if it takes a whole day to fix it, things are going to be pretty painful. The more complicated the game gets, the more difficult life will be.</p>
<p>A good start is to crank up the warning level of your compiler as far as it goes. We&rsquo;re compiling everything with warning level 4 in VC2005, so we&rsquo;re already covered in that end <a href="#%5B3%5D">[3]</a>. Unfortunately, warning level 4 doesn&rsquo;t warn us about uninitialized member variables. We need something else.</p>
<p>Fortunately we have a secret weapon in our arsenal we had been ignoring: <a href="http://en.wikipedia.org/wiki/Lint_(software)">Lint</a>.</p>
<p>Lint performs static analysis of C++ programs and spews out lots and lots of warnings. Think of it as an extremely pedantic warning level on a C++ compiler. And I mean extremely! It will warn you not only of potential errors and dodgy constructs, but of best practices, and sometimes even of recommendations in books like Effective C++.</p>
<p>As you can imagine, with all those things to check against, Lint is going to find lots to complain about. So taming the output into something readable is a definite challenge.</p>
<p>When it comes to Linting your code, there are a few options available.</p>
<p><strong>Team Edition Compiler</strong></p>
<p>My friend Jim Tilander brought up that <a href="http://www.tilander.org/aurora/2006/08/lint-hidden-in-the-psdk.html">there&rsquo;s a Lint-like tool</a> hidden in the bowels of the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=1D7F16B3-D2D5-48F7-9494-6696117EE712&amp;displaylang=en">Microsoft Platform SDK</a>. Boy, he wasn&rsquo;t kidding about the hidden part! It&rsquo;s a whopping 1.4 GB download for a DVD image that then needs to be extracted and installed in order to get to the small free compiler. When will Microsoft adopt a more modular approach?</p>
<p>Once I got past all the installation hurdles, I was pretty excited to give it a test. A free tool is a free tool. And if it has good integration with Visual Studio, so much the better. Strictly speaking, it&rsquo;s not really a Lint tool, but an optimizing compiler with a special /analyze switch, which performs a lot of the same checks as Lint. But as we know, a rose by any other name&hellip;</p>
<p>Right off the bat, it fell flat the moment I started using it. Apparently it doesn&rsquo;t know how to deal with vcproj files. To work on all the files in a project, I had to feed each cpp file separately. That in itself is only a slight annoyance, but it meant that you also need to pass it all the compiler switches set in the vcproj files: include directories, defines, etc. For a Microsoft product, I really would expect it to understand vcproj files. Oh well. It&rsquo;s not the end of the world. I can always write a quick script to do that for me.</p>
<p>Unfortunately, the next problem was more serious. There was no global way to control what warnings I wanted reported. I can disable specific warnings in the command line, but if I only care about a few, it gets really cumbersome.</p>
<p>Finally the killer: It simply doesn&rsquo;t report some of the most important warnings I expect out of Lint, such as uninitialized member variables or variables appearing in incorrect order in the initializer list.</p>
<p>In its defense, it had some decent features I would expect of good Lint tools, like the ability to suppress certain warnings from code or to give extra hits in the code itself. On the other hand, the way to control the behavior of the analyze switch is done with special keywords, which will make other compilers choke, making it harder to write cross-platform code. Somehow, I&rsquo;m not terribly surprised.</p>
<p>LeChimp&rsquo;s recommendation: Even for a free tool, it simply doesn&rsquo;t stand up to any serious use. Skip it.</p>
<p><strong>PC Lint</strong></p>
<p>Discouraged from the few hours I spent in the Team Edition compiler fiasco, I turned to <a href="http://www.gimpel.com/">Gimpel Software</a> <a href="http://www.gimpel.com/">PC Lint</a>.</p>
<p>Don&rsquo;t be put off by PC Lint&rsquo;s archaic web site that seems to be snatched straight out of 1995 <a href="#%5B4%5D">[4]</a>. PC Lint has been around forever and it shows. Not just in their web site, but in the program itself. Don&rsquo;t expect any fancy GUIs, or dialog boxes, or any fancy cyber-amenities developed in the last 20 years.</p>
<p>Still, what it lacks in sophistication and pleasing visuals it more than makes up in functionality: Three minutes, $239, and a 4MB download later, I was ready to go.</p>
<p>In about an hour, I had PC Lint fully integrated with our build server and checking for problems in all of our source code. In just half an hour more, all our code was passing Lint&rsquo;s rigorous inspection.</p>
<p>PC Lint can be quite intimidating out of the (virtual) box. If you run it on a typical codebase (or even a really high-quality one), it will treat you to megabytes of warning spew. Most of it useless, I have to say. So you have to take some time and tame it. Teach it to be a bit more polite, or more relevant. Or at least not to yell so much.</p>
<p>My preference is to start out with no warnings by starting out the options.lnt file with -e* and then add warning messages that I find useful: uninitalized member variables, unreferenced symbols, gotchas with virtual functions, etc..</p>
<p>Even running Lint with a small number warnings enabled, there were a few places in our code that caused PC Lint to complain but we didn&rsquo;t want to change (Vec4 really shouldn&rsquo;t initialize any member variables in its default constructor, or the NonCopyable class shouldn&rsquo;t have a virtual destructor). In those cases, we can add a few discrete comments directly in the code that tell Lint to be quiet. We know what we&rsquo;re doing, Lint. Really.</p>
<p>After we got all the code passing the initial set of checks, Charles dug into the Lint options file with a gleeful glint in his eyes and became the Lint-nazi, adding a good couple dozen extra warnings. It only took a few more minutes to get all the code to pass all the new checks. Frankly, the slowest part of the process is reading the thousands of different checks that PC Lint can do and decipher them (there are a couple of them I&rsquo;m still unsure what exactly they mean).</p>
<p>This is what our options.lnt file looks like today:</p>
<pre tabindex="0"><code>-d__debugbreak()=
-e*

+e539  // Did not expect positive indentation from Location
+e549  // Suspicious cast
+e616  // control flows into case/default
+e744  // switch statement has no default
+e750  // local macro &#39;Symbol&#39; (Location) not referenced
+e751  // local typedef &#39;Symbol&#39; (Location) not referenced
+e752  // local declarator &#39;Symbol&#39; (Location) not referenced
+e753  // local struct, union or enum tag &#39;Symbol&#39; (Location) not referenced
+e764  // switch statement does not have a case
+e766  // Include of header file FileName not used in module String
+e767  // macro &#39;Symbol&#39; was defined differently in another module
+e773  // Expression-like macro &#39;Symbol&#39; not parenthesized
+e777  // Testing floats for equality
+e783  // Line does not end with new-line
+e784  // Nul character truncated from string
+e789  // Assigning address of auto variable &#39;Symbol&#39; to static
+e796  // Conceivable access of out-of-bounds pointer
+e797  // Conceivable creation of out-of-bounds pointer
+e801  // Use of goto is deprecated
+e802  // Conceivably passing a null pointer to function &#39;Symbol&#39;
+e803  // Conceivable data overrun for function &#39;Symbol&#39;
+e804  // Conceivable access beyond array for function &#39;Symbol&#39;
+e806  // Small bit field is signed rather than unsigned
+e814  // useless declaration
+e815  // Arithmetic modification of unsaved pointer
+e817  // Conceivably negative subscript (Integer) in operator &#39;String&#39;
+e818  // Pointer parameter &#39;Symbol&#39; (Location) could be declared ptr to const
+e820  // Boolean test of a parenthesized assignment
+e825  // control flows into case/default without -fallthrough comment
+e940  // omitted braces within an initializer
+e954  // Pointer variable &#39;Symbol&#39; (Location) could be declared as pointing to a const

// TURN THESE ON IF WE CAN FIGURE OUT HOW TO APPLY IT ONLY TO VALUES AND NOT POINTERS!
//+e952  // Parameter &#39;Symbol&#39; (Location) could be declared const
//+e953  // Variable &#39;Symbol&#39; (Location) could be declared as const

+e1401 // member symbol &#39;Symbol&#39; (Location) not initialized by constructor
+e1404 // deleting an object of type &#39;Symbol&#39; before type is defined
+e1411 // Member with different signature hides virtual member &#39;Symbol&#39;
+e1413 // function &#39;Symbol&#39; is returning a temporary via a reference

+e1506 // Call to virtual function &#39;Symbol&#39; within a constructor or destructor
+e1507 // attempting to &#39;delete&#39; an array (not a pointer)
+e1509 // base class destructor for class &#39;Name&#39; is not virtual
+e1511 // Member hides non-virtual member &#39;Symbol&#39; (Location)
+e1512 // destructor for base class &#39;Symbol&#39; (Location) is not virtual
+e1516 // Data member hides inherited member &#39;Symbol&#39; (Location)
+e1520 // Multiple assignment operators for class &#39;Symbol&#39;
+e1521 // Multiple copy constructors for class &#39;Symbol&#39;
+e1534 // static variable &#39;Symbol&#39; found within inline function in header
+e1535 // Exposing low access data through member &#39;Symbol&#39;
+e1537 // const function returns pointer data member &#39;Symbol&#39;
+e1538 // base class &#39;Name&#39; absent from initializer list for copy constructor
+e1539 // member &#39;Symbol&#39; (Location) not assigned by assignment operator
+e1541 // member &#39;Symbol&#39; (Location) possibly not initialized by constructor
+e1542 // member &#39;Symbol&#39; (Location) possibly not initialized
+e1543 // member &#39;Symbol&#39; (Location) possibly not initialized
+e1544 // value of variable &#39;Symbol&#39; (Location) indeterminate (order of initialization)
+e1545 // value of variable &#39;Symbol&#39; used previously to initialize variable &#39;Symbol&#39; (Location)
+e1547 // Assignment of array to pointer to base class (Context)
+e1552 // Converting pointer to array-of-derived to pointer to base
+e1554 // Direct pointer copy of member &#39;Symbol&#39; within copy constructor
+e1555 // Direct pointer copy of member &#39;Symbol&#39; within copy assignment operator
+e1556 // &#39;new Type(integer)&#39; is suspicious
+e1557 // const member &#39;Symbol&#39; is not initialized
+e1561 // Reference initialization causes loss of const/volatile integrity

+e1705 // static class member may be accessed by the scoping operator
+e1706 // Declaration with scope operator is unusual within a class
+e1707 // static assumed for String
+e1710 // An implicit &#39;typename&#39; was assumed
+e1711 // class &#39;Symbol&#39; (Location) has a virtual function but is not inherited
+e1718 // expression within brackets ignored
+e1719 // assignment operator for class &#39;Symbol&#39; has non-reference parameter
+e1720 // assignment operator for class &#39;Symbol&#39; has non-const parameter
+e1724 // Argument to copy constructor for class &#39;Symbol&#39; should be a const reference
+e1726 // taking address of overloaded function name &#39;Symbol&#39;
+e1729 // Initializer inversion detected for member &#39;Symbol&#39;
+e1734 // Had difficulty compiling template function: &#39;Symbol&#39;
+e1736 // Redundant access specifier (String)

+e1931 // Constructor &#39;Symbol&#39; can be used for implicit conversions
</code></pre><p>I originally only had about a dozen warnings enabled, but, as you can see, Charles really went to town with it :-)</p>
<p>To integrate it into our functional test, we just set up a new target in msbuild. For each project, we call it twice: once to generate a lnt file for the project, and once to run it on the files for the project.</p>
<pre tabindex="0"><code>&lt;PropertyGroup&gt;
    &lt;LintDir&gt;..\Bin\Lint\&lt;/LintDir&gt;
    &lt;Lint&gt;$(LintDir)lint-nt.exe&lt;/Lint&gt;
&lt;/PropertyGroup&gt;

&lt;ItemGroup&gt;
    &lt;ProjectFiles Exclude=&#34;..\Engine\**\*Tests.vcproj&#34;
                  Include=&#34;Src\SweetPea.vcproj;..\Engine\**\*.vcproj;&#34;/&gt;
&lt;/ItemGroup&gt;

&lt;Target Name=&#34;Lint&#34; DependsOnTargets=&#34;CleanLint;RunLint&#34;/&gt;

&lt;Target Name=&#34;CleanLint&#34;&gt;
    &lt;Delete Files=&#34;%(ProjectFiles.RelativeDir)%(ProjectFiles.Filename).lnt&#34;/&gt;
&lt;/Target&gt;

&lt;Target Name=&#34;RunLint&#34; Inputs=&#34;@(ProjectFiles)&#34;
        Outputs=&#34;@(ProjectFiles -&gt; %(ProjectFiles.RelativeDir)%(ProjectFiles.Filename).lnt)&#34; &gt;
    &lt;Exec Command=&#34;$(Lint) -v -os(%(ProjectFiles.RelativeDir)%(ProjectFiles.Filename).lnt) %(ProjectFiles.Identity)&#34;/&gt;
    &lt;Exec WorkingDirectory=&#34;%(ProjectFiles.RelativeDir)&#34;
          Command=&#34;$(MSBuildProjectDirectory)\$(Lint) -i$(MSBuildProjectDirectory)\$(LintDir) std.lnt %(ProjectFiles.Filename).lnt&#34;/&gt;
&lt;/Target&gt;
</code></pre><p>Whenever PC Lint detects some code that violates one of its rules, it returns an error message, which fails the msbuild target and the whole build is reported as failed by Cruise Control .Net. I love it when things work exactly like you want them to without doing any extra work. To make it even better, because PC Lint can output errors in VC++ format, they&rsquo;re understood and parsed correctly by msbuild and CCNet, so they show up in the CCNet log like any other error.</p>
<p><img loading="lazy" src="/lechimps-secret-weapon-lint/images/lint.png" title="lint"></p>
<p>PC Lint runs surprisingly fast. It takes about 20 seconds to run on all of our source code. I was almost tempted to add it to the incremental build in the build server, but I really want to keep build times to a minimum there, so it runs once every hour, which seems to be good enough.</p>
<p>If you want to be more hands-on with PC Lint, it&rsquo;s a breeze to integrate with Visual Studio. Just set up a few custom commands in External Tools and you&rsquo;re good to go. The Visual Studio Lint options file even details exactly how to set up those commands.</p>
<p>My only minor complaint with PC Lint is the strange behavior of error 766 (Include of header file not used in module). I don&rsquo;t know what algorithm PC Lint uses to determine that, but it seems not to report some unused headers. That wouldn&rsquo;t be a big deal, but sometimes just rearranging headers or moving some code around will cause it to recognize a header as unused, triggering a failed build. It&rsquo;s <a href="/physical-structure-and-c-part-1-a-first-look/%20">a very useful warning though</a>, so I&rsquo;m willing to live with that quirk.</p>
<p>Working with PC Lint is a pleasure. It&rsquo;s really low level and old school, but that&rsquo;s precisely what made it so easy to integrate with our code and our build system. It doesn&rsquo;t need installation programs, databases, registry entries, dll deployments, or anything like that. Just a good-ol&rsquo; ini file with options and you&rsquo;re good to go. We even have it checked it in version control to make it easier to deploy to our development stations and the build server.</p>
<p>PC Lint has the characteristics I want in a tool: Easy to buy, deploy, and integrate into the way I want to work with it.</p>
<p>LeChimp&rsquo;s recommendation: An absolute must! Worth every penny. Two opposable thumbs up!</p>
<h3 id="other-lint-alternatives">Other Lint Alternatives</h3>
<p>Lint was originally a Unix utility developed in the late 70s. You would expect that lots of different versions would be available for modern compilers and platforms, but there aren&rsquo;t that many. Maybe it&rsquo;s not a really fun project to engage enough Open Source hackers?</p>
<p>I have to admit I haven&rsquo;t looked at any other alternatives to PC Lint and the Team Edition Compiler that work under Windows. A quick Google search reveals there are a few tools out there. Has anybody tried them? I&rsquo;d love to hear your experiences with them.</p>
<ul>
<li><a href="http://www.splint.org/">Splint.</a> Only works on C. Emphasis on security. Open source.</li>
<li><a href="http://www.abxsoft.com/codchk.htm">CodeCheck</a>. Works on C++. Commercial.</li>
<li><a href="http://www.aristeia.com/ddjpaper1_frames.html">A bunch for Linux/Unix</a>. As much as I&rsquo;d like to, the reality is that most game development happens under Windows.</li>
</ul>
<h3 id="conclusion-lechimp-rules-the-day-again">Conclusion: LeChimp Rules The Day (Again)</h3>
<p>PC Lint should be a requirement for any C++ project. The day you set up a build server (which should be the first day), go ahead and spend the extra hour setting up PC Lint as well. Be safe up front and avoid wasting any time down the line. We should have followed our own advice, but sometimes priorities slip a bit in the rush of getting a whole company off the ground.</p>
<p>Now I can finally sleep better knowing that LeChimp is keeping busy linting my code several times a day.</p>
<p>[1] <a href="http://www.siberkat.com/thewavszim/meetdoomz.wav">This</a> is our current broken build sound bite.</p>
<p>[2] There are some things we don&rsquo;t bother TDDing: main functions, super-high level leaf code, etc.</p>
<p>[3] Of course, you need to have a <strong>clean</strong> compile in warning level 4 in order to be worth it. That means builds without any warnings or other spew. Incidentally, I do hate the setting to treat warnings as errors because it means you can&rsquo;t temporarily have warnings while you&rsquo;re refactoring between checkins, which slows things down.</p>
<p>[5] That was just a wild guess, but it seems it really <a href="http://web.archive.org/web/19961222013655/http://gimpel.com/">wasn&rsquo;t that different in 1996</a>.</p>]]></content:encoded></item><item><title>LeChimp vs. Dr. Chaos</title><link>https://gamesfromwithin.com/lechimp-vs-dr-chaos/</link><pubDate>Mon, 24 Dec 2007 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/lechimp-vs-dr-chaos/</guid><description>&lt;p&gt;It&amp;rsquo;s no secret that I&amp;rsquo;m a big fan of unit tests. They provide a huge safety net for refactorings, double check the code logic, and prevent &lt;a href="http://en.wikipedia.org/wiki/Software_rot"&gt;code rot&lt;/a&gt;. In addition, unit tests written through &lt;a href="https://gamesfromwithin.com/backwards-is-forward-making-better-games-with-test-driven-development/"&gt;Test-Driven Development&lt;/a&gt; help define the architecture and keep programmers happy. They&amp;rsquo;ll even catch a bug or two along the way, but if you rely on them as your only way to catch bugs, you&amp;rsquo;re in for a surprise.&lt;/p&gt;</description><content:encoded><![CDATA[<p>It&rsquo;s no secret that I&rsquo;m a big fan of unit tests. They provide a huge safety net for refactorings, double check the code logic, and prevent <a href="http://en.wikipedia.org/wiki/Software_rot">code rot</a>. In addition, unit tests written through <a href="/backwards-is-forward-making-better-games-with-test-driven-development/">Test-Driven Development</a> help define the architecture and keep programmers happy. They&rsquo;ll even catch a bug or two along the way, but if you rely on them as your only way to catch bugs, you&rsquo;re in for a surprise.</p>
<h3 id="bug-hunting">Bug Hunting</h3>
<p>Unit tests, by their very nature, are limited to a single class or function at the time. There are all sorts of complex interactions between objects and systems that they simply can&rsquo;t test. Even if you use <a href="http://en.wikipedia.org/wiki/Mock_object">mock objects</a> and are extremely careful to test all your object interactions, there will be lots of unexpected cases and bugs that crawl out while running the game under real world conditions. Dr. Chaos is alive and well.</p>
<p>Besides, unit tests just test that the code does what you think it should do. So if the algorithm you have in your head is completely wrong, they&rsquo;ll just make sure that the implementation is as broken as you imagined. Bugs like that might only surface once the code is put in the context of the whole game and interacts with other systems.</p>
<p>Traditionally, game companies rely on QA to uncover and squash most of the bugs created by complex interactions. You know, the type of bug that gets only triggered when the player enter the cave while there&rsquo;s a blue moon and he spun around in place a seven times. Not only is this is an expensive process, but it&rsquo;s not even very good at uncovering all the bugs. Most games have millions and millions of combinations of possibilities and interactions, and it&rsquo;s completely impractical to try to run through all of them by hand.</p>
<h3 id="our-hero-lechimp">Our Hero: LeChimp</h3>
<p>At Power of Two Games it&rsquo;s just two of us. So no QA or even interns to play the game endlessly. But, even in preproduction, we can&rsquo;t afford to ignore those types of bugs. Instead, we enlisted the help of our hero: LeChimp.</p>
<p>LeChimp is our functional test server. It tirelessly runs the game every couple of hours and makes sure it loads and runs without any problem. Sure, ideally it should run more frequently, but LeChimp doubles up as our build server, and we don&rsquo;t have another good computer to spare (maybe if y&rsquo;all <a href="http://www.powerof2games.com/product">bought more t-shirts</a> we could afford to buy another cheapo Dell).</p>
<p>Running the game is a good start. It checks that it&rsquo;s possible to load every level and that nothing crashes. Frankly, that&rsquo;s a good percentage of what QA does a lot of the time, and a lot of teams would really benefit from having such a simple test and know as soon as a level stops loading. Still, it we can do much better than that.</p>
<h3 id="monkey-business">Monkey business</h3>
<p><img alt="lechimp" loading="lazy" src="images/monkey.jpg">LeChimp runs the game for a fixed number of frames, and makes sure the game doesn&rsquo;t crash or hits any asserts. But running the game without any action going on is not very useful, so it runs it with the -monkey switch, which feeds pseudo-random input to the game, as if a monkey were playing the game.</p>
<p>Actually, the input from -monkey is not random at all. I first made it truly random by generating new inputs through std::rand() every frame, but it looked more like a monkey on crack was playing the game and the characters shook violently back and forth and never managed to do anything interesting. Instead, now the monkey input holds the controller sticks and the buttons for some varying time interval, and it looks more like a monkey without its ADD medicine, which is clearly a step up.</p>
<p>When I first heard of this technique at a GDC tutorial a few years ago, I thought it would be pretty useless. How many bugs could feeding random input to the game really uncover? Shouldn&rsquo;t we try to be doing something more intelligent to mimic how players interact with the game? But since it was really easy to implement I decided to give it a try. Boy, was I in for a treat! Within a few runs, it uncovered several major bugs that nobody hadn&rsquo;t seen during their runs of the game. Since then, there isn&rsquo;t a game I work on that doesn&rsquo;t get treated with some monkey input love..</p>
<p>It&rsquo;s so simple to implement that if you haven&rsquo;t done it already, I really encourage you to go and do it right away. Do it over your next lunch break even. I guarantee you&rsquo;ll be amazed at what it uncovers (or I&rsquo;ll refund your money for this article :-).</p>
<h3 id="recording-for-posterity">Recording for posterity</h3>
<p>In addition to just trying to crash the game, LeChimp records all the inputs and the state of the game at every frame. Then, after running the game for a while, it runs it again, feeding it the recorded input, and verifies that the game is in the same state as it was during the recording session (every enemy is in the same place, every prop has the same orientation, every player has the same health, etc). This verifies that the game is fully deterministic, that is, given the same inputs, it always produces the same output.</p>
<p>We&rsquo;re planning on some cool features that rely on the game being fully deterministic, so this something very important to us. But even if we weren&rsquo;t planning on doing anything with it, determinism is an extremely useful feature to have when it comes time to track down bugs. Instead of getting lengthy descriptions of a crash from testers (which somehow always seems impossible to reproduce), they can include the playback file that lead to the crash along with the bug report, allowing us to catch it in the debugger in no time. Of course, it&rsquo;s not like we have actual testers, but we affectionately think of LeChimp as one, and he&rsquo;s always very careful to save all his playback files with every functional test run.</p>
<p>Right now we&rsquo;re just recording the inputs to the game: delta time every frame and controller inputs. Just with that, the game runs exactly the same time in and time out (thanks to Havok for being deterministic!). Things get more complicated as soon as multiple threads are involved, since the exact timing of context switches between threads can affect the output. Some tools out there, like <a href="http://www.replaysolutions.com/technology/replay-director-gaming.php">ReplayDirector</a> claim to address this, but I haven&rsquo;t looked into it very much.</p>
<p>Both the input file and the same state file are opened, written to, and closed every frame. That way there is no data loss if the game crashes unexpectedly and you get all the input leading up to that frame.</p>
<p>As far as checking that the world state is the same, it&rsquo;s totally an ad-hoc process. We simply pick some of the obvious state and save them to a file: player positions, enemy position, props transforms, etc. If we ever see something get out of sync, we add it to the game state that gets saved and compared so it doesn&rsquo;t happen in the future.</p>
<h3 id="no-waiting-around">No waiting around</h3>
<p>So far we have LeChimp running the following with every functional test:</p>
<pre tabindex="0"><code>sweetpea -frames=10000 -record=functional_test -monkey -level=level_name
</code></pre><p>followed by</p>
<pre tabindex="0"><code>sweetpea -playback=functional_test -level=level_name
</code></pre><p>At 60 Hz, running 10,000 frames is almost three minutes. 10,000 is just a number we pulled out of a hat. The longer you let the monkey loose with the game, the better the chance of uncovering something. Multiply that by the number of levels and sandboxes, and the functional test now takes quite a while to complete.</p>
<p>A good chunk of the time of the functional test is spent rendering each frame and waiting for the vertical sync signal. But nobody is actually looking at the output <a href="#%5B2%5D">[2]</a>, so why bother?</p>
<p>We added a couple more command line switches to make the game run without rendering or waiting on vsync. To make that really useful, we also added the ability to force the frame time to be a fixed timestep. So we can run the game like this:</p>
<pre tabindex="0"><code>sweetpea -frames=10000 -record=functional_test -monkey -level=level_name -render=no -vsync=no -timestep=0.01566
</code></pre><p>The game will cruise through the simulation as fast as possible, often cramming all three minutes of gameplay into 10 seconds or so. Perfect for poor monitor-less LeChimp.</p>
<h3 id="testing-testing">Testing, testing</h3>
<p>There&rsquo;s even more to LeChimp that just monkeying around. It also runs several other functional tests checking some high-level functionality:</p>
<ul>
<li>
<p>Player attacks. The player character attacks enemies using each different type of attack and verifies that each attack is successful. This is particularly useful when there are a few types of attacks (which themselves are unit tested), but there are many combinations that can be created between attacks and targets.</p>
</li>
<li>
<p>Level restart. LeChimp loads a level and then restarts it hundreds of times, checking for crashes and memory leaks.</p>
</li>
<li>
<p>Torture chamber. A tiny level in which the hero (in god mode) frantically mows down hundreds of enemies that get immediately respawned. This is a perfect stress test for performance and hardcoded limits.</p>
</li>
</ul>
<p>We&rsquo;re writing these tests as we go along. Whenever there&rsquo;s a feature that seems complex enough, or that it relies on other systems, or that it seems to break repeatedly, we take a few minutes, write a new functional test, and throw it to LeChimp to run with all the others.</p>
<p>Functional tests like these are about as high level as it gets. They deal with actions such as &ldquo;move the player to the right&rdquo;, &ldquo;spawn an enemy here&rdquo;, or &ldquo;perform special attack XXX&rdquo;, so it would make sense to implement them in the same way you implement game logic (which in our case is still C++, although we&rsquo;re considering a switch to Lua in some not very distant future).</p>
<h3 id="long-live-lechimp">Long Live LeChimp</h3>
<p>LeChimp has been invaluable battling against Dr. Chaos. Several times I made a refactoring or introduced a new feature, all the unit tests passed, I checked it in, and a little while later LeChimp screams at us that something is wrong. Once we see the functional test fail, it&rsquo;s usually pretty obvious how to fix it: a memory pool is too small, or a combination of events that causes the player to enter some unexpected state. Fixing it is a matter of writing a unit test, fixing the logic, and checking it in, all in a few minutes.</p>
<p>A few times, however, the problem hasn&rsquo;t been that obvious. The world gets out of sync, but only in release mode. Running it from the debugger often results in yet a different state. Sounds like some annoying memory overwrite, or perhaps some uninitialized memory. Any programmer who&rsquo;s had to deal with this before probably has shivers running down his back. Fortunately, LeChimp has a secret weapon in its arsenal to deal with that. But that&rsquo;s another story and shall be told another time.</p>
<p>Until then, happy holidays, everybody!</p>
<p>[1] Don&rsquo;t underestimate the power of keeping programmers happy! At a previous company I used to work for, a manager rewarded one of the programmers by buying him a DVD set of a TV show he was really into. That was only about $40, but they had a huge effect on the programmer&rsquo;s morale and productivity. Talk about well-spent money.</p>
<p>[2] LeChimp doesn&rsquo;t even have a monitor, although that sucks sometimes. RemoteDesktop is pretty cool, but it locks up the DirectX surfaces in some weird way, and then the graphics renderer refuses to initialize correctly. So we&rsquo;re forced to use&hellip; get this&hellip; NetMeeting! With fake phone rings and all! Ring, ring, calling LeChimp&hellip;</p>]]></content:encoded></item><item><title>Office Tools for Starving Startups</title><link>https://gamesfromwithin.com/office-tools-for-starving-startups/</link><pubDate>Mon, 13 Aug 2007 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/office-tools-for-starving-startups/</guid><description>&lt;p&gt;Yes, we&amp;rsquo;re a starving startup. There&amp;rsquo;s nothing wrong with that. It&amp;rsquo;s actually quite good: we don&amp;rsquo;t have any venture capital investment, and we&amp;rsquo;re running purely from savings out of our own pockets. On the flip side, we have full control over our company, and we can decide what do do and how to run it.&lt;/p&gt;
&lt;p&gt;Of course, we&amp;rsquo;re far from loaded with money, so keeping expenses to a minimum is definitely a top priority. It&amp;rsquo;s not coincidence that one of our most popular lunches is sharing a gigantic $5 sub at &lt;a href="http://www.menushark.com/%5Crestaurant.php?id=157&amp;amp;city=Encinitas"&gt;Manhattan Giant Pizza&lt;/a&gt; or the $3.50 &lt;a href="http://mmm-yoso.typepad.com/mmmyoso/2006/07/kealanis.html"&gt;Kealani&amp;rsquo;s&lt;/a&gt; chicken teriyaki sandwich (fortunately, they&amp;rsquo;re actually delicious too!).&lt;/p&gt;
&lt;p&gt;Whenever it makes sense, we&amp;rsquo;ve opted for the most inexpensive options&lt;a href="#%5B1%5D"&gt;[1]&lt;/a&gt;: plastic workbenches from Costco for our desks, lights from Ikea with unpronounceable names, an outdated P3 that became our file server given to us by a friend, or a free scanner/printer donated by my girlfriend.&lt;/p&gt;
&lt;p&gt;So when it came time to set up our office tools, we also looked for the most inexpensive solution that met all our needs.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Yes, we&rsquo;re a starving startup. There&rsquo;s nothing wrong with that. It&rsquo;s actually quite good: we don&rsquo;t have any venture capital investment, and we&rsquo;re running purely from savings out of our own pockets. On the flip side, we have full control over our company, and we can decide what do do and how to run it.</p>
<p>Of course, we&rsquo;re far from loaded with money, so keeping expenses to a minimum is definitely a top priority. It&rsquo;s not coincidence that one of our most popular lunches is sharing a gigantic $5 sub at <a href="http://www.menushark.com/%5Crestaurant.php?id=157&amp;city=Encinitas">Manhattan Giant Pizza</a> or the $3.50 <a href="http://mmm-yoso.typepad.com/mmmyoso/2006/07/kealanis.html">Kealani&rsquo;s</a> chicken teriyaki sandwich (fortunately, they&rsquo;re actually delicious too!).</p>
<p>Whenever it makes sense, we&rsquo;ve opted for the most inexpensive options<a href="#%5B1%5D">[1]</a>: plastic workbenches from Costco for our desks, lights from Ikea with unpronounceable names, an outdated P3 that became our file server given to us by a friend, or a free scanner/printer donated by my girlfriend.</p>
<p>So when it came time to set up our office tools, we also looked for the most inexpensive solution that met all our needs.</p>
<h2 id="email">Email</h2>
<p>Our requirements for our email solution were:</p>
<ul>
<li>
<p>Minimize costs. Not just the software, but the hardware needed to run any severs, support, etc.</p>
</li>
<li>
<p>Minimize maintenance. We&rsquo;re our own IT staff, so the less time we have to spend screwing around with severs and updates, the more time we can spend coding and designing the game.</p>
</li>
<li>
<p>Reliable. This, after all, is going to be used to send company emails, contracts out to outsourcing companies, responses to publishers, etc. We don&rsquo;t want to be missing any emails.</p>
</li>
<li>
<p>Good search capabilities.</p>
</li>
<li>
<p>Available from any location. I guess that implies a web front end.</p>
</li>
<li>
<p>Fully integrated with our domain powerof2games.com.</p>
</li>
</ul>
<p>In the past, the companies we had worked at all used Microsoft Exchange and Outlook or the god-awful Lotus Notes. Apart from having to endure the torture of using these day in and day out, they&rsquo;re quite expensive, so we looked for alternatives.</p>
<p>We could use the email server provided by our web hosting company. It would give us the bare bones functionality that we needed, including some form of <a href="http://www.squirrelmail.org/">web front end</a>. It could work, but after using Gmail for personal email for several years, it felt like a major step backwards.</p>
<p>Since Charles and I were already using Gmail for our personal accounts, we thought of creating a new account for Power of Two Games, but having <a href="mailto:pow2games@gmail.com">pow2games@gmail.com</a> in all our business emails doesn&rsquo;t exactly look very professional.</p>
<p>That&rsquo;s when we found out about <a href="http://www.google.com/a/smallbiz/">Google Apps for small business</a>. It&rsquo;s a free service offered by Google that allows integration of Gmail into your domain and use it as your corporate email. That seemed too good to be true. Gmail is hands down the best email web interface I have ever used, so the thought of using it as the company email was extremely tempting.</p>
<p>Setting up Gmail took a bit of messing around with some DNS advanced settings. All email sent to powerof2games.com had to be routed to Google somehow, so we had to set up a custom MX record in our web host and point it to Google&rsquo;s servers.</p>
<p>We also wanted to access our email through a nice URL like mail.powerof2games.com instead of some long (and hard to remember) default URL going through Google. For that, we had to add a CNAME record pointing the new mail subdomain to ghs.google.com.</p>
<p><img loading="lazy" src="images/gmail_1%5C%281%5C%29.png"></p>
<p>Once all that was set up, Gmail was up and running and fully integrated with our Power of Two domain. Not only that, but it was totally independent of our personal Gmail accounts, so we can even have them both open in different tabs in the same browser. Good job, Google!</p>
<h2 id="calendar">Calendar</h2>
<p>Gmail was just the tip of the iceberg. By going the Google route, we also get <a href="http://www.google.com/googlecalendar/overview.html">Google Calendar</a> for our domain. And Google Calendar totally rules. It&rsquo;s not like we were planning on scheduling company meetings at all hours of the day (although, technically, since we&rsquo;re in the same office I guess we&rsquo;re in a permanent meeting). But Calendar comes in really handy to put down big milestones, remind us to pay the rent, or keep track who we&rsquo;re having lunch with this week.</p>
<p>Calendar works out of the &ldquo;box&rdquo; without any extra set up. The only thing we did was to create a custom subdomain to access it through calendar.powerof2games.com, so we did the same trick as for our mail subdomain with the CNAME entry.</p>
<p>I can even share the Power of Two Calendar with my personal Google Calendar account and see all my events combined in a single place. My whole life in a single web page. Very handy!</p>
<h2 id="extras">Extras</h2>
<p>But wait, there&rsquo;s more. We&rsquo;re not always working at the office at the same time. Sometimes we&rsquo;ll work from home for a few hours in the morning before walking down to the office, or maybe I&rsquo;ll do some work from <a href="http://www.estreetcafe.com/index.jsp">E Street</a> late in the evening with an oatmeal chocolate chip cookie and some live music. At those times, it&rsquo;s very helpful to be within easy reach of communication, and since we&rsquo;re using Gmail, we get Gmail chat for free.</p>
<h2 id="documents">Documents</h2>
<p>I&rsquo;m usually very hesitant of &ldquo;integrated solutions&rdquo;. I always prefer to be able to mix and match programs, components, or whatever instead of going the route of vendor lock-in. And the truth is that the different Google components are totally optional, but it&rsquo;s curious that we&rsquo;re biting, hook, line, and sinker all the way into Google&rsquo;s office suite.</p>
<p>I was thinking we would end up using <a href="http://www.openoffice.org/">OpenOffice.org</a>, which is a great Microsoft Office clone. But we gave a try to Google Documents and Spreadsheets and we were totally impressed.</p>
<p>Not only has Google Documents reached point as far as features and user interface that they&rsquo;re usable for real-world situations, but they offer a lot more functionality.</p>
<ul>
<li>
<p>It&rsquo;s a web-based app, so we can edit the documents from any computer with web access.</p>
</li>
<li>
<p>We can collaborate on the same document at the same time, which came in very handy when we were both working on the Sony Developer Program application document.</p>
</li>
<li>
<p>Because it&rsquo;s a Google product, you can search through the contents of all your documents and spreadsheets very easily.</p>
</li>
<li>
<p>Tagging and sorting. You can tag any document with any set of labels and then sort or filter by them. I&rsquo;m glad the days of hierarchical trees for organizing information are coming to an end.</p>
</li>
<li>
<p>Exporting to a variety of formats (MS Office, pdf, etc) comes in very handy when we need to send a document to somebody else who is not using Google.</p>
</li>
</ul>
<p>There are only a few things we wish it did differently, like being able to upload a pdf document (even if it&rsquo;s just in read-only mode for archiving and searching purposes). The other odd quirk is that we can&rsquo;t make all documents and spreadsheets shared by default between the two of us. Instead, we need to explicitly share them. Oh well. I guess they have bigger companies than us in mind. I don&rsquo;t blame them.</p>
<p>It&rsquo;s very encouraging to see these applications grow and get better week after week. Just a few months ago, Google Spreadsheets couldn&rsquo;t do plots, but they added that functionality since then. They&rsquo;ve also improved the whole front end with the tagging and listing of documents.</p>
<h2 id="voice-communication">Voice communication</h2>
<p>How the times have changed. When we started Power of Two Games, we didn&rsquo;t even bother with a phone. Even though we ended up contracting a DSL Internet connection and getting a voice phone line would have been extremely easy, we simply didn&rsquo;t need it. We were simply using our cell phones for the few times when email communication or chat wasn&rsquo;t good enough.</p>
<p>But as we started outsourcing art and talking to console manufacturers, we started having the need to do voice conferences and calling internationally. After a couple, very uncomfortable, conference calls using the speakerphone on our cellphone, we decided that we really had to look for a better solution.</p>
<p>For once, Google didn&rsquo;t have the solution for us (although wait a couple of years and see). I have been using <a href="http://www.skype.com/">Skype</a> to call internationally for quite a while with great results, so it was natural that we would look at it as our first option. Again, we were pleasantly surprised: not only could we make very inexpensive international calls (with great voice quality), but for a small yearly fee we can get <a href="http://www.skype.com/products/skypein/">SkypeIn</a> and have anybody call us from a regular phone.</p>
<h2 id="conclusion">Conclusion</h2>
<p>We&rsquo;re extremely pleased with how Google Apps and Skype have been working for us so far. They fit our needs perfectly and the cost is right. We were able to set things up in about a morning and never have to fuss with it again. How good is that?</p>
<p>I really don&rsquo;t see why Google Apps wouldn&rsquo;t work for a larger company. But companies seem to be stuck in the Exchange/Microsoft Office (or some other heavyweight and expensive server solution) choice. I wonder if there&rsquo;s a good reason for that other than inertia.</p>
<p>We&rsquo;re certainly happy to have these services available for free and being about to spend our time and money in what really matters: Creating a kick-ass game and getting it out the door.</p>
<p><strong>Notes</strong></p>
<p>[1] There are some things where going rock-bottom cheap doesn&rsquo;t make any sense though. The $7 desktop speakers we bought online were quite the surprise. I wasn&rsquo;t expecting top quality sound, but they sounded like those two way radios that security guards use. I didn&rsquo;t even know they made speakers that bad! Also, we have &ldquo;splurged&rdquo; on 24&quot; LCD monitors and comfortable chairs (and even so, always trying to find the cheapest price point for what we want), because those things make a world of difference when you&rsquo;re using them many hours every day.</p>]]></content:encoded></item><item><title>Prototyping for Fun And Profit</title><link>https://gamesfromwithin.com/prototyping-for-fun-and-profit/</link><pubDate>Tue, 08 May 2007 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/prototyping-for-fun-and-profit/</guid><description>&lt;p&gt;So here we are, ready to start development of our first game. We have the time, the resources, and the game idea itself. Where do we start?&lt;/p&gt;
&lt;p&gt;Since both Charles and I are tech guys, we knew we could implement our game idea without any problem and make it sing and dance at a silky-smooth 60 fps. But would it be fun? Now that we have these brand-new designer hats, finding that always elusive fun factor is a big concern. The idea of waiting for a couple of months before we could tell if our game idea was fun seemed too risky, so we tackled that problem first and head-on by prototyping.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://gamesfromwithin.com/prototyping-for-fun-and-profit/images/stick_1.png" title="stick_1"&gt;We could start at the bottom, write some low-level input handling, some graphics rendering, a basic &lt;a href="https://gamesfromwithin.com/optimizing-the-content-pipeline/" title="asset pipeline"&gt;asset&lt;/a&gt; &lt;a href="https://gamesfromwithin.com/optimizing-the-content-pipeline/" title="asset pipeline"&gt;pipeline&lt;/a&gt;, and all the other usual suspects. The problem is that, even if we try to keep things as simple as possible, it would still be several weeks or even months before we can actually start implementing the game itself. And even when we do, we&amp;rsquo;ll always be running up against incomplete technology and having to spend time fleshing it out as we try to make a game come out of the other end.&lt;/p&gt;
&lt;p&gt;Instead, we decided to start with a prototype. This isn&amp;rsquo;t supposed to be a &amp;ldquo;prototype&amp;rdquo; that eventually morphs into a shipping game, or a prototype that uses the same technology as the production code, or even a prototype that&amp;rsquo;s used to impress the big-wigs to squeeze some money out of them (ha!). No, all that stuff detracts from the ultimate goal of our prototype. Our approach was very similar to what &lt;a href="http://chrishecker.com/Homepage" title="Chris Hecker"&gt;Chris Hecker&lt;/a&gt; and &lt;a href="http://www.slackworks.com/%7Ecog/" title="Chaim Gingold"&gt;Chaim Gingold&lt;/a&gt; described in their &lt;a href="http://www.d6.com/users/checker/gdc06-AdvancedPrototyping.ppt" title="GDC presentation"&gt;GDC presentation&lt;/a&gt;. We had the need to answer one very specific question: &amp;ldquo;Is our game idea fun?&amp;rdquo; And we wanted the answer as quickly and cheaply as possible. Everything else was secondary.&lt;/p&gt;</description><content:encoded><![CDATA[<p>So here we are, ready to start development of our first game. We have the time, the resources, and the game idea itself. Where do we start?</p>
<p>Since both Charles and I are tech guys, we knew we could implement our game idea without any problem and make it sing and dance at a silky-smooth 60 fps. But would it be fun? Now that we have these brand-new designer hats, finding that always elusive fun factor is a big concern. The idea of waiting for a couple of months before we could tell if our game idea was fun seemed too risky, so we tackled that problem first and head-on by prototyping.</p>
<p><img loading="lazy" src="/prototyping-for-fun-and-profit/images/stick_1.png" title="stick_1">We could start at the bottom, write some low-level input handling, some graphics rendering, a basic <a href="/optimizing-the-content-pipeline/" title="asset pipeline">asset</a> <a href="/optimizing-the-content-pipeline/" title="asset pipeline">pipeline</a>, and all the other usual suspects. The problem is that, even if we try to keep things as simple as possible, it would still be several weeks or even months before we can actually start implementing the game itself. And even when we do, we&rsquo;ll always be running up against incomplete technology and having to spend time fleshing it out as we try to make a game come out of the other end.</p>
<p>Instead, we decided to start with a prototype. This isn&rsquo;t supposed to be a &ldquo;prototype&rdquo; that eventually morphs into a shipping game, or a prototype that uses the same technology as the production code, or even a prototype that&rsquo;s used to impress the big-wigs to squeeze some money out of them (ha!). No, all that stuff detracts from the ultimate goal of our prototype. Our approach was very similar to what <a href="http://chrishecker.com/Homepage" title="Chris Hecker">Chris Hecker</a> and <a href="http://www.slackworks.com/%7Ecog/" title="Chaim Gingold">Chaim Gingold</a> described in their <a href="http://www.d6.com/users/checker/gdc06-AdvancedPrototyping.ppt" title="GDC presentation">GDC presentation</a>. We had the need to answer one very specific question: &ldquo;Is our game idea fun?&rdquo; And we wanted the answer as quickly and cheaply as possible. Everything else was secondary.</p>
<p>Prototyping period</p>
<p>And so we dove into a prototyping frenzy. For our first day, we set up shop at the <a href="http://www.estreetcafe.com" title="E Street Cafe">E Street Cafe</a>. We opened up the place, took over a table, hooked up gamepads to our laptops, and hacked away furiously until late in the evening, fueled all the while by cappuccinos, gourmet tea, and pastries <a href="#%5B1%5D" title="[1]">[1]</a>. Yum! By the end of the day, we had the basics of the game implemented and even some of the more advanced features. Heck, we even thought it was kind of fun, but that&rsquo;s because we were tired and we had been staring at Charles&rsquo; horrible programmer art all day long. In all honesty, it really was a pretty sucky game, even if the enemy characters were wearing party hats. But hey, that was just end of day one.</p>
<p>Over the next few days, we had to take a break to deal with all the paperwork and logistics involved with setting up the new company and the office, but we resumed prototyping as soon as possible. The plan was to keep hammering away at the prototype until we saw it was clearly fun, or we decided it was hopeless and we had better think of something new (or go back and beg for our jobs back). Charles took it even further and swore not to shave his beard until the prototype was fun, much to his fiancee&rsquo;s delight (seriously, the only thing the ladies think is hotter than a game programmer is a bearded game programmer).</p>
<p>A week later, things weren&rsquo;t looking too hot. The game hadn&rsquo;t gotten much beyond what we had done the first day. Sure, we had a bunch of advanced features in, but it didn&rsquo;t really make it much more fun. Were we on the wrong path?</p>
<p>The major breakthroughs happened in the last few days. First of all, we removed a key feature that had been there since the very beginning. We really thought it was going to be key to the whole game, but it really made the game too easy and boring. As soon as we removed it, the feel of the game changed completely and things started to look up.</p>
<p>Then, as we were discussing some other advanced moves and features, the idea for a minor feature came up. Since the caffeine hadn&rsquo;t kicked in yet and I didn&rsquo;t have the energy to work on the next big feature, I implemented our little idea in about ten minutes. Charles saw it over my shoulder and he started laughing and begging me to check in the code. It was an instant hit! We ended up liking it so much that we decided to expand on with a few features, and before the end of the day, it&rsquo;s clear that it&rsquo;s going to become a main gameplay mechanic in the final game. That day we went home knowing we were nearing the end of the prototype face. Good thing because Charles&rsquo; beard was starting to look scary!</p>
<p><img loading="lazy" src="/prototyping-for-fun-and-profit/images/stick_2.png" title="stick_2"></p>
<p><em>We tried about seven different captions, but none of them did the sprite justice.</em></p>
<p>One more day of tweaking the prototype and we officially called it done. We knew we had gotten there when we tweaked a small feature, fired up the game to see how it felt, and then spent 10-15 minutes going crazy with the controller because we were having too much fun. Another good sign was when we would start playing and then yell at each other to look at the crazy things we had just accomplished.</p>
<p>Finally, Charles was able to shave. Thank God.</p>
<p>The prototype</p>
<p>The prototype process was supposed to be as quick and cheap as possible. None of the code written was intended to be kept or extended to go into production code, and performance wasn&rsquo;t an issue either. So, with that in mind, what did we use for developing our prototype?</p>
<p>C++ and <a href="http://www.talula.demon.co.uk/allegro/" title="Allegro">Allegro</a>. Yes, you read it right the first time. Let me say that again: C++ and Allegro.</p>
<p>With all the other choices available of higher-level languages and extensive game development libraries and frameworks, why on earth did we make that choice? Wouldn&rsquo;t Python with <a href="http://www.pygame.org" title="PyGame">PyGame</a> or C# and the <a href="http://msdn2.microsoft.com/en-us/directx/aa937794.aspx" title="Game Studio Express">Game Studio Express</a> have been better choices? The honest answer is that I don&rsquo;t think either one of those options would have allowed us to get the prototype done any faster for several reasons:</p>
<ul>
<li>
<p>Small scope. The scope and size of the prototype was quite small, so there wasn&rsquo;t much to be gained by using slightly higher-level language constructs or more complete libraries.</p>
</li>
<li>
<p>Allegro. Even though it might seem like an odd choice and be behind the times, it&rsquo;s precisely the old-school, fully procedural approach that makes Allegro so valuable. There are no frameworks, no enforced class hierarchies&hellip; heck, no classes or private members to get in the way. In Allegro, if you want to do something, you call the function and you&rsquo;re done. Exactly what we needed for the prototype. In retrospect, <a href="http://www.libsdl.org" title="SDL">SDL</a> might have been a better choice since it would have allowed us to use a DirectX surface and do video capture more easily. But Allegro worked like a charm and we have nothing but good things to say about that experience <a href="#%5B2%5D">[2]</a>.</p>
</li>
<li>
<p>Proficiency. Both Charles and I are quite proficient at C++, so even if another language gave slightly faster development time, we more than made up for it by being very familiar with C++ and its libraries. For the prototype we allowed ourselves to use STL recklessly and with wanton disregard for memory access patterns and spurious allocations.Â  We also didn&rsquo;t care about memory leaks at the end, so that helped get things up and running a lot faster.Â  Destructors?Â  Delete?Â  Free?Â  Cache coherency?Â  How do those equate to fun gameplay?!</p>
</li>
</ul>
<p>It&rsquo;s no secret that I&rsquo;m an avid advocate of <a href="http://www.gamesfromwithin.com/articles/cat_software_engineering.html" title="good software engineering practices for game development">good software engineering practices for game development</a>. As with anything, good software engineering practices have some very real and important benefits, but those benefits come with a cost. Because of the small scope of the prototype, and the fact that the code wasn&rsquo;t going to survive more than a week or two, we decided to throw any software engineering practice that would slow us down in the least straight out the window!Â  Forget about accessors and private scoping; skip any unit tests; bye bye factories, loose coupling, and proper physical dependency management. Welcome to hackfest, check your engineering discipline at the door!</p>
<p>One of the things that made the prototype very successful for us was to concentrate on a single gameplay mechanic. We didn&rsquo;t try to prototype the whole game, just the one bit we were most concerned about (and that was going to take 80% of the player&rsquo;s time and attention). That allowed us to deal with a small subset of the game and iterate on it very quickly without getting bogged down by creeping features or dealing with a larger scope.</p>
<p>The prototype shamelessly used the worst programmer art imaginable (Charles + MS Paint == &hellip; you can imagine [edit: Charles] TOTALLY AWESOME SWEET). Yes, it looked horrible, but if the game was so much fun with those graphics, just imagine how it&rsquo;s going to blow people away whenever we add some real art and animations.</p>
<p>Lessons learned</p>
<p>The most valuable lesson we learned was the value of constantly asking ourselves the questions &ldquo;Is this fun?&rdquo; and &ldquo;What can I do now to make it more fun?&ldquo;Â  That was actually really crucial. Having such a specific (even if subjective and nebulous) goal allowed us to remain in the right path. Sometimes it was tempting to add feature X or Y, but when we realized that it wouldn&rsquo;t make the game any more fun, we quickly dropped it and moved to something else.</p>
<p>It&rsquo;s important not to over-intellectualize the idea of &ldquo;fun&rdquo;, though. Sure, most of the fun comes from the choices the player makes and what happens as a result of those choices (even if the choice is to mash the buttons). But don&rsquo;t underestimate the value of &ldquo;fun&rdquo; in having cool, flashy things on the screen, or to have the character jump with a nice ramp-up curve and land with some squishiness to give it that &ldquo;just right&rdquo; feel.</p>
<p>It was also very helpful to run the prototype by somebody else towards the end to make sure we weren&rsquo;t finding it fun because we were simply delirious. Clearly, it has to be someone you can trust and who can understand what the prototype represents and not be put off by the stick figures. It was great to get confirmation from an outside source that it really was getting to be fun. We also got a bunch of feedback that made it a much tighter experience. A lot of it was pretty obvious, but we were too close to the game to be able to see it by ourselves.</p>
<p>As with most prototypes, it&rsquo;s always very tempting to not throw it away and continue hammering at it until it looks like something that could be shipped. We didn&rsquo;t really have a choice because of the technologies we went with (allegro is a fully cpu-based renderer), but we could feel the call of the dark side. It really was a good thing that we didn&rsquo;t even try. Towards the end, the terrible hacked code we&rsquo;d written was starting to slow our productivity. Code that bad builds up an &ldquo;engineering debt&rdquo; that you have to pay off sooner or later or you hit a wall.Â  Our particular wall came in the form of extending a pre-existing player action in what seemed like a trivial way.Â  Something like this would have literally taken about 5 minutes at the beginning of the prototype, but by the point we were at it would have taken closer to an hour. Heck, even having to go on for another week would have started to be painful. So in a way, the prototype came with a built-in self-destruct mechanism, which is a good thing because it discouraged us to continue working on it for too long.</p>
<p>Using existing technology is definitely the way to go. That way there&rsquo;s very little &ldquo;wasted&rdquo; time getting up to speed. The fact that we were able to get most of the core mechanics of the game in the first day goes to show how useful is to hit the ground running instead of getting bogged down in how to load bitmaps or create a window.</p>
<p>Additionally, the procedural, non &ldquo;framework-y&rdquo;, non-object oriented approach of the API we chose made it much easier to bend to our will and make it work the way *we* wanted, and not the way somebody decided for us ahead of time. The fewer restrictions your prototyping API has, the easier it will be to do all the crazy things that come to mind during the prototyping phase.</p>
<p>The game</p>
<p>Unfortunately, we can&rsquo;t really talk about the game right now. Just rest assured that we&rsquo;re working on it at full steam and we&rsquo;ll announce some details as soon as we can. Clearly, we&rsquo;re not going to release the prototype since it has a good chance of scaring away any potential publishers in its current state. But if one day the game sells tons of units, maybe we&rsquo;ll release the prototype as a &ldquo;behind the scenes&rdquo; feature so other people can have a glimpse at how things got started and they can laugh at our artistic skills.</p>
<p>Conclusion</p>
<p>There you have it. Now at least we can be confident that the game is going to be pretty fun. Sure, there are lots of aspects of the game that we haven&rsquo;t prototyped, but we consider those to be lower risk and we&rsquo;ll figure them as we go along. At least the core mechanic has proven to be fun. Now it&rsquo;s just a matter of writing the production code and implementing it all. That simple. What could possibly go wrong? ;-)</p>
<p>[1] Money saving tip #1 for starving startups: If you have to pay for a 24-hour Internet connection in a coffee shop and you need to have several computers with Internet access, connect them with an ethernet cable and share the Internet connection from one of them. Ta-dah! :-)</p>
<p>[2] Actually, I&rsquo;ve been wanting to create a movie of the prototype in action, but I haven&rsquo;t been able to. It seems that <a href="http://www.fraps.com" title="Fraps">Fraps</a> doesn&rsquo;t work because it&rsquo;s not using a DirectX surface, and saving each frame is too slow. Anybody has any suggestions? Don&rsquo;t get your hopes up though, we&rsquo;re not uploading a movie of the prototype any time soon, we&rsquo;re just saving it to show our grandchildren one day.</p>]]></content:encoded></item><item><title>Bringing Back The Dream</title><link>https://gamesfromwithin.com/bringing-back-the-dream/</link><pubDate>Thu, 17 Aug 2006 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/bringing-back-the-dream/</guid><description>&lt;p&gt;A lot of people have a particular moment or experience that defined their future. It can be anything: reading a particular book, traveling through a different country, meeting somebody special, or going through a very painful (or happy) experience. For me, the future crystallized on a Fall afternoon in 1985, when I sat in front of an 8-bit computer at a friend&amp;rsquo;s house. It was the beginning of a long personal journey.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A lot of people have a particular moment or experience that defined their future. It can be anything: reading a particular book, traveling through a different country, meeting somebody special, or going through a very painful (or happy) experience. For me, the future crystallized on a Fall afternoon in 1985, when I sat in front of an 8-bit computer at a friend&rsquo;s house. It was the beginning of a long personal journey.</p>
<p>The computer was laughably primitive by today&rsquo;s standards: <a href="http://en.wikipedia.org/wiki/Zilog_Z80">Z80</a> 4MHz CPU with 64KB of RAM. What made <a href="http://en.wikipedia.org/wiki/Amstrad_CPC">it stand out from other computers</a> at the time was a whopping 16 simultaneous colors (as long as you gave up half your horizontal resolution), three-channel square wave sound generation, and 3â€ floppy disks. Cell phones these days are hundreds of times more powerful than that computer. Heck, the chip inside your microwave oven is probably more powerful!</p>
<p>What was it that caused love at first sight with that computer? Impressive as they were at the time, it wasn&rsquo;t the technical specs that attracted me. It wasn&rsquo;t the <a href="http://www.cpcgamereviews.com/">silly games</a> either, even though <a href="http://tacgr.emuunlim.com/downloads/filedetail.php?recid=829">those were fun for a few days</a>. It was being able to give commands to the machine and have it execute them immediately.</p>
<p>The computer booted directly into a Basic interpreter. I started experimenting with a few PRINT statements, then moved to FOR loops, getting input and solving algebra problems as if by magic. I spent endless hours typing game listings that came in magazines (usually with a few printing errors, which made them so much more fun to get working correctly). I experimented with graphics, sounds, and animations.</p>
<p><img alt="Amstrad CPC" loading="lazy" src="/bringing-back-the-dream/images/amstrad.jpg"> Before I knew it, the Basic interpreter was too slow and bloated and I had to graduate to assembly. Programming became a bit slower (especially since for some reason I could only save the assembly onto tapes, not disks), but the programs became thousands of times faster. I was finally able to draw sprites without annoying flickering, use all available memory, and even overwrite part of the ROM jump table to squeeze in a few extra KB.</p>
<p>I was hooked.</p>
<p>That experience totally changed the rest of my life. It caused me to study computer engineering and computer science, and eventually to write games professionally (much to my parents&rsquo; dismay).</p>
<p>If that little, primitive computer had that effect on me, today&rsquo;s dazzling multimedia computers with broadband Internet connection must have a hundred times that effect on today&rsquo;s children, right? Quite the opposite.</p>
<p>Today&rsquo;s computers might be a lot more powerful, but they&rsquo;re also a lot more complicated. Windows is very large and intimidating to a newcomer. It doesn&rsquo;t exactly scream â€œplay with me, experiment!â€. Instead, it is a very closed system. It discourages experimentation, and you&rsquo;re in constant fear of disturbing any of the overly complex configurations (like the registry or system dlls), not to even mention dealing with viruses and other malware. Linux is much more transparent, but it&rsquo;s still far from an inviting system to play and experiment with for newcomers to computers.</p>
<p>Another problem with modern computers is the lack of a programming language out of the box. Things are actually a bit better now than they were a few years ago. Microsoft offers a free express edition of <a href="http://msdn.microsoft.com/vstudio/express/">Visual Studio</a>. <a href="http://www.python.org/">Python</a> and <a href="http://www.ruby-lang.org/en/">other scripting languages</a> are also free downloads, and they also <a href="http://www.pygame.org/">have libraries for game development</a>. Unfortunately none of those tools come pre-installed, which makes it hard to get started and even harder to share your results with other people. Also, a lot of free development tools and environments today are geared towards GUI programming, which is very different from the free-form, take-control-of-the-machine approach that you need not just for games, but to really learn about the machine. There really aren&rsquo;t many better ways to permanently scare people away from programming than showing them <a href="http://msdn.microsoft.com/vstudio/previous/2003/posters/posterfiles/Namespaces_Selected_Classes_X0910395pst_a_OL.pdf">something like this</a>.</p>
<p>Web development is a bit better because it tends to be simpler, and once you have a web server set up, it&rsquo;s easy to show the results to anybody with an Internet connection (which I hope is everybody these days). Unfortunately it&rsquo;s not particularly well suited for something like games with the exception of things like <a href="http://www.adobe.com/products/flash/flashpro/">Flash</a>.</p>
<p>Although I&rsquo;m sure that part of it is nostalgia, I&rsquo;m clearly not the only one who feels this way. <a href="http://www.internetnews.com/ent-news/article.php/3520606">Computer science enrollment has been dropping dramatically in recent years</a> and there seems to be a lack of interest in learning more about these machines that surround us, beyond how to use a browser and how to share videos with friends.</p>
<p>Really, when I look at things this way, I feel bad for kids growing up today. They&rsquo;re missing out on a huge source of enjoyment that I had growing up as a kid. Of course, today there are other new frontiers to explore, and they have the Internet with all the new social aspects, but it&rsquo;s not the same.</p>
<p>So, is the dream dead?</p>
<p>I have often wondered, isn&rsquo;t there a platform out there that is more like the 8-bit computers were in their day? The closest parallel today is game consoles, except that they&rsquo;re very closed and proprietary and they&rsquo;re only intended to play games. Sony started making some progress along these lines with the <a href="http://en.wikipedia.org/wiki/Net_Yaroze">Yaroze</a> program for PSX and <a href="http://playstation2-linux.com/">Linux for the Playstation 2</a>. Unfortunately neither program was particularly successful for a variety of reasons, but it was a start.</p>
<p><img alt="Xbox 360" loading="lazy" src="/bringing-back-the-dream/images/xbox.jpg"> A couple of days ago, in the keynote for GameFest, Microsoft announced that they&rsquo;re taking things further on the Xbox 360 with <a href="http://www.microsoft.com/presspass/press/2006/aug06/08-13xnagamestudiopr.mspx">Game Studio Express</a>. They&rsquo;re planning to open it up and allow everybody to develop games for it. Even better, the code will be mostly common between Windows and the Xbox 360, so it will be possible to do a lot of development on the PC and then move it over to the 360 relatively painlessly. How cool will it be for kids to write their own games running on the Xbox 360 and be able to show them off in their friends&rsquo; living room?</p>
<p>It seems that the only language available will be C#. At first I was disappointed as I was hoping it would work with C++. Then I realized it wasn&rsquo;t such a bad idea. If anything, it would be better if it were something simpler, more like <a href="http://darkbasic.thegamecreators.com/">Dark Basic</a>, that people with very little programming experience can quickly start messing around with. Game Studio Express is supposed to include several tools and APIs that allow you to program things at a really high level, so that might be good enough.</p>
<p>I&rsquo;m very curious about the details, though. For instance, are we going to be able to get our hands dirty and write as much C# as we want, or are we going to be limited to a very strict framework? Is the link between the PC and the 360 something that they&rsquo;re going to expose? In other words, will we be able to create other tools that use that functionality to create new types of content?</p>
<p>A really important question is whether anybody will be able to play content created by users, or will they have to have some special payment-based subscription. Having to pay to develop for the 360 is not ideal, but I don&rsquo;t see it as an unsurmountable barrier. However, if users have to pay and be part of the developer program just to be able to play some user-generated content, that would come close to killing its usefulness. I hope that Microsoft learns some lessons from <a href="http://www.youtube.com/">YouTube</a> and <a href="http://video.google.com/">Google Video</a> and realize that the lower the barriers for people to browse the content, the more successful it is going to make the product. People have been able to share videos for a long time already, but it involved downloading them, getting a player that could decode them, and playing them back. Now it&rsquo;s as simple as clicking on a link, and that&rsquo;s why it has finally reached critical mass.</p>
<p>I&rsquo;m definitely keeping a very close eye on this project, and I&rsquo;ll try to give it a test drive as soon as I get a chance. It&rsquo;s a bit ironic that with dozens of multi-million AAA titles out there, the reason I might end up buying an Xbox 360 is the chance to do play around with some sprites on the screen and re-create a bit of the old 8-bit days. The dream might indeed be back.</p>]]></content:encoded></item><item><title>Fundamentally Agile</title><link>https://gamesfromwithin.com/fundamentally-agile/</link><pubDate>Tue, 08 Aug 2006 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/fundamentally-agile/</guid><description>&lt;p&gt;In the past, I&amp;rsquo;ve given presentations about agile game development to two distinct groups of people: game developers without much exposure to agile development, and agile developers who were unfamiliar with game development. This morning I realized how interesting it was to explain the goals and reasons behind agile development to someone completely outside those circles.&lt;/p&gt;</description><content:encoded><![CDATA[<p>In the past, I&rsquo;ve given presentations about agile game development to two distinct groups of people: game developers without much exposure to agile development, and agile developers who were unfamiliar with game development. This morning I realized how interesting it was to explain the goals and reasons behind agile development to someone completely outside those circles.</p>
<p>Today I had lunch with an old friend. Even though he&rsquo;s not a programmer, he&rsquo;s enough of a tech-head that our conversation eventually turned towards agile development. In the past, I&rsquo;ve given presentations about agile game development to two distinct groups of people: game developers without much exposure to agile development, and agile developers who were unfamiliar with game development. This morning I realized how interesting it was to explain the goals and reasons behind agile development to someone completely outside those circles. It forced me to go back to basics and think about the fundamentals of a topic I&rsquo;ve been so involved in that I&rsquo;d stopped thinking about in those terms..</p>
<p>What exactly is the key concept behind agile development? One possible definition is â€œa set of techniques and procedures with minimal overhead that allow us to make sound, just-in-time decisions.â€ <a href="#ref1">[1]</a></p>
<p>There are several important parts to that definition:</p>
<ul>
<li><strong>Decisions</strong>: It&rsquo;s not about the code, or the team, or the tests. It&rsquo;s about decisions. The ultimate goal is to deliver a useful product, but agile development helps us to make the decisions along the way. What do we create next? How do we want this thing to look? What features do we have to ship with?</li>
<li><strong>Just-in-time</strong>: Maybe the agile community has a better term for this, but the concept strongly reminded me of the just-in-time compiling strategy of Java interpreters. Basically, agile methods will delay decisions until the last moment they have to be made. Not only does this help avoiding design paralysis and having to make too many decisions early on, but it also means that a lot of decisions will never have to be made because things changed from the original expectations.</li>
<li><strong>Sound</strong>: I originally left this one out, but I realized that an 8-ball can make just-in-time decisions with the best. It&rsquo;s making sound ones that is difficult. Whenever a decision needs to be made, agile teams will draw on all the information they&rsquo;ve acquired up until then.. Not only will they know more about market trends and competitors&rsquo; products, but they&rsquo;ll also know about their own team strengths, technology limitations, or the shortcomings of past implementations. That&rsquo;s a lot more information that they would have had available at the beginning of the project, during the traditional waterfall planning phase.</li>
<li><strong>Minimal overhead</strong>: Agile processes are, by definition, very light. The goal is to create a valuable product, not the process itself. Agile techniques introduce the minimal amount of overhead to achieve their purpose.</li>
</ul>
<p>My friend was very curious about this approach, since it&rsquo;s quite different from the normal way of working he&rsquo;s used to in his company. He had a very insightful question: â€œDon&rsquo;t you end up doing a lot of re-work?â€. And the answer is, yes, absolutely. However, it&rsquo;s not as wasteful as it sounds. It&rsquo;s actually quite an efficient approach for a lot of projects.</p>
<p>Let&rsquo;s visualize the progress made in a project as a path on a 2D surface. The amount of work is the length of the path. The progress is how far from the starting point you&rsquo;ve gone, and the direction represents different approaches, designs, or implementations. An ideal project would look like this:</p>
<p><img alt="Ideal project" loading="lazy" src="/fundamentally-agile/images/chart00.png"></p>
<p>The project starts, knows exactly where it&rsquo;s going, and progresses in a straight line. Euclid would agree: You can&rsquo;t be more efficient than by taking the straight line between two points.</p>
<p>This diagram can be used to represent any scale: from the whole project spanning several years, to how a particular feature is implemented in a couple of weeks, or how a class is implemented in one morning. The same principles apply in all cases.</p>
<p>As a comparison, I suppose a <a href="http://en.wikipedia.org/wiki/Death_march_(software_development)">death march project</a> would look more like this:</p>
<p><img alt="Death march project" loading="lazy" src="/fundamentally-agile/images/chart01.png"></p>
<p>You are constantly doing work, but you aren&rsquo;t getting any closer to your destination. The project eventually gets canned, or development stops somewhere and it gets patched up the best it can and shipped to unsuspecting customers.</p>
<p>You might hope that an agile project looks more like this:</p>
<p><img alt="Possible agile" loading="lazy" src="/fundamentally-agile/images/chart02.png"></p>
<p>A project like that implies that some changes happened during development, but while always making steady progress. That would be nice, but in practice it often doesn&rsquo;t work that way. When you change your plans or even some implementation, you often end up with some amount of rework:</p>
<p><img alt="Agile with rework" loading="lazy" src="/fundamentally-agile/images/chart03.png"></p>
<p>You can see all the rework by the zigzags going in and out indicating varying levels of progress. I believe this rework is inevitable (and maybe even desirable) in agile projects. It happens at a low level, like changing interfaces to a class and having up update all the hundred tests you wrote that relied on that interface. But it also happens at a higher level, when you realize that a game feature isn&rsquo;t as fun as you thought and you drop it in favor of another one that could be more promising.</p>
<p>From the above diagrams, agile development really looks inefficient. Clearly, we have traveled a much longer path to reach our destination (work done). But agile development can actually do better. How can we be more efficient than traveling in a straight line without resorting to strange relativistic warped space?</p>
<p>The diagram doesn&rsquo;t tell the whole picture. Remember that agile development relies on just-in-time decisions. That includes the final goal: As we&rsquo;re working towards that goal, we might see other, better or easier-to-reach ones. As a matter of fact, this is something that happens most of the time. In that case, the picture looks quite different:</p>
<p><img alt="Real agile" loading="lazy" src="/fundamentally-agile/images/chart04.png"></p>
<p>Now the amount of work done is less than it was in the ideal first case! And we might have a better solution to boot. Who says you can&rsquo;t have your cake and eat it too?</p>
<p>With this in mind, are there some cases in which it is better not to use agile development? Clearly. If you know things won&rsquo;t change and you have a clear idea of how to reach your final goal, then go for it. Agile development won&rsquo;t help much there. I have yet to see a project that worked that way. Maybe a sports game that ships year after year, or another simple port to a mobile platform. But most projects I&rsquo;ve seen have such a high level of chaos and uncertainty due to all sorts of external factors that they could all greatly benefit from an agile approach.</p>
<p>This can be visualized very well by mapping the characteristics of a project in terms of requirements vs. technology. Projects that fit agile development well fall anywhere in the complicated to anarchy zone (a fair amount of technology uncertainty and requirements disagreement). On the other hand, projects in the lower left corner, which are very well understood and are very certain, would benefit the least from an agile approach. <a href="#ref2">[2]</a></p>
<p><img alt="Uncertainty vs. agreement" loading="lazy" src="/fundamentally-agile/images/certainty.png"></p>
<p>I don&rsquo;t usually bash agile development because I truly believe it&rsquo;s a great way to do development, especially for games. But how would an agile development project gone bad look?</p>
<p><img alt="Agile gone bad" loading="lazy" src="/fundamentally-agile/images/chart05.png"></p>
<p>Here there was a huge amount of rework without having any significant impact in the project. The project ended up very near the original goal (a bit further actually), but it spent most of its time thrashing around. You could argue that maybe some of that was exploring different solutions, but it&rsquo;s probably not a sign of a good project anyway.</p>
<p>This brings up a good point: With agile development, it&rsquo;s important to let go of the control-freak mindset. It&rsquo;s good to have an idea of what your ultimate goal is, but it should never take precedence over what you discover along the way.</p>
<p>I see this frequently in people who have just learned the mechanics of test-driven development: they go through the cycle correctly, writing a test, coding, and then refactoring. But they&rsquo;re still implementing the design they had in their head when they started instead of letting the tests dictate how the design should look. Often they get quite frustrated because they can&rsquo;t figure out how to test things. This also applies at a larger scale. If a feature isn&rsquo;t giving you good results, maybe it should be dropped or significantly changed.</p>
<p>This is one of the reasons I try to do my best not to talk about things as concrete as classes or functions during early discussions about some feature we will implement. I find that doing so tends to solidify those concepts too much and I tend to be much more likely to follow them instead of letting design evolve from what we learned during its implementation. So now instead, I prefer to talk about more abstract concepts like operations, modules, or data flow.</p>
<p>Whether you&rsquo;re an agile developer or not, it&rsquo;s always important to step back and question what you&rsquo;re doing and how you&rsquo;re doing it. Think about it in the context of your projects and needs, and re-evaluate it accordingly. Sometimes you&rsquo;ll be surprised what new insights you achieve by stepping back and looking at the fundamentals of something you&rsquo;re intimately familiar with. Just make sure you don&rsquo;t bore your friends with too much technobabble.</p>
<hr>
<ol>
<li>Scott Ambler has <a href="http://www.agilemodeling.com/essays/agileSoftwareDevelopment.htm">a very good, much more detailed definition of agile development</a> that describes more the practices rather than the goals.</li>
<li>Diagram adapted from <a href="http://agilegamedevelopment.com/GDC2006/gdc2006_ClintonKeith_0323.ppt">Clinton Keith&rsquo;s Agile Game Development GDC 2006 presentation</a></li>
</ol>]]></content:encoded></item><item><title>A Whirlwind Tour Through GDC 2006</title><link>https://gamesfromwithin.com/a-whirlwind-tour-through-gdc-2006/</link><pubDate>Thu, 06 Apr 2006 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/a-whirlwind-tour-through-gdc-2006/</guid><description>&lt;p&gt;Spring was supposed to be the season of flowers, new leaves, and good weather returning. Here in San Diego we don&amp;rsquo;t get much of that, or rather, we get it all year around. So Spring can really sneak up on you, and before you realize it, it&amp;rsquo;s already gone. Spring also seems to be the season for game-development conferences and travel: just a few weeks apart we get Sony&amp;rsquo;s conference, Microsoft&amp;rsquo;s, and, of course, &lt;a href="http://gdconf.com/"&gt;GDC&lt;/a&gt;. I&amp;rsquo;m not even going to count &lt;a href="http://www.dicesummit.org/"&gt;Dice&lt;/a&gt; and &lt;a href="http://www.e3expo.com/"&gt;E3&lt;/a&gt;, also happening around the same time.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Spring was supposed to be the season of flowers, new leaves, and good weather returning. Here in San Diego we don&rsquo;t get much of that, or rather, we get it all year around. So Spring can really sneak up on you, and before you realize it, it&rsquo;s already gone. Spring also seems to be the season for game-development conferences and travel: just a few weeks apart we get Sony&rsquo;s conference, Microsoft&rsquo;s, and, of course, <a href="http://gdconf.com/">GDC</a>. I&rsquo;m not even going to count <a href="http://www.dicesummit.org/">Dice</a> and <a href="http://www.e3expo.com/">E3</a>, also happening around the same time.</p>
<p>With all that going on, I realized I never got around to writing my impressions about GDC. It really was a great conference with some very good highlights. My travel is far from over, and I&rsquo;m heading out to the airport to catch my plane to London in a couple of hours, but until then, here is my quick take on this year&rsquo;s GDC.</p>
<p>This year I decided to come for the tutorials happening two days before the main conference. The first day I bounced between â€œAdvanced Visual Effects with OpenGLâ€ and â€œSoftware Engineering Issues in Multiplayer Games.â€</p>
<p>The OpenGL tutorial was exactly what you would expect: lots of material from previous years and a few good bits of information. The first thing I was happy to learn is that Microsoft changed their decision on how OpenGL will be implemented in <a href="http://www.microsoft.com/Windowsvista/">Vista</a>. It will no longer be a layer on top of DirectX; instead it will be a first-class citizen in its own right. Now, I&rsquo;m not an OpenGL fan. Up until recently I never had to work much with it, and now that I have, I admit that I like the Direct3D API much better (I&rsquo;m just not a fan of implicit global states). But I&rsquo;m very glad to see that OpenGL is going to be treated correctly in Vista and given the opportunity to compete with Direct3D.</p>
<p>I was also pleasantly surprised by the tools NVidia is releasing for OpenGL development. <a href="http://developer.nvidia.com/page/home.html">NVPerfKit</a> is a bit like Pix for DirectX; combined with gDebugger, it starts making OpenGL a lot more attractive. They&rsquo;re supposed to release version 2.0 soon, but I didn&rsquo;t find it on their web site. It&rsquo;s really interesting how much NVidia is pushing OpenGL lately. At one point it felt that it was over for OpenGL, but it really has been making a comeback in the last couple of years. Now if they can only improve Cg&hellip;</p>
<p>The tutorial &ldquo;Software Engineering Issues in Multiplayer Games&rdquo; managed to surprise me, and I wish I had spent longer there than I did. It really was focused on the software engineering aspects, rather than on the multiplayer part of it. Lots of good information and war stories of large-scale game development.</p>
<p>Tuesday I spent it exclusively in the Direct3D tutorial. The biggest new thing was DirectX 10, with several talks focused on that. Apart from the new cool tech features (such as the stream out feature or the geometry shaders), DirectX 10 is quite a departure from earlier versions of the API. A couple of things make me scratch my head in puzzlement. DirectX 10 supposedly won&rsquo;t have any caps to query anymore. Hardware is either DirectX 10 compliant or it isn&rsquo;t. That&rsquo;s great news for developers. However, I also learned that DirectX 10 is going to be tied to the Vista operating system, and new versions of DirectX will only be released as part of new versions of Windows. Unless I&rsquo;m missing something, that means that hardware won&rsquo;t have an opportunity to change and grow while running on Vista. That would be horrible for hardware manufacturers, but at least they have OpenGL to show their new features. Or maybe it means that Microsoft is planning on doing a yearly operating system release. It will be interesting to see how it plays out.</p>
<p>The best session on Tuesday was clearly Natalya Tatarchuk&rsquo;s <a href="http://www.ati.com/developer/techpapers.html#gdc06">talk</a> on the <a href="http://www.ati.com/developer/demos/rx1800.html">Toy Shop demo</a>. She spent a full hour dissecting the demo, covering every rendering trick and effect they used. Considering how impressive and packed the demo is, it was clear that she could have spent a full day talking about it. Some effects are awesome, like their smeared rain reflections on the road, but it was funny to see how they clearly spent quite a bit of time doing things that are completely lost, like diffraction on the light that goes through the droplets on the store window. In any case, if you haven&rsquo;t seen the demo, <a href="http://www.ati.com/developer/demos/rx1800.html">download it right now</a>.</p>
<p>Wednesday was the start of the main GDC sessions. To kick things off, <a href="http://www.mungosmash.com/Author.php">Sean</a> and I gave <a href="/backwards-is-forward-making-better-games-with-test-driven-development/">our talk on test-driven development</a>. I was really surprised at how packed the room was and how well received it was, judging by all the questions and positive comments. It&rsquo;s great to see that other people are also very interested in TDD and are thinking about applying to it game development.</p>
<p>The next-generation animation panel was pretty interesting as an overview of what could be coming down the pipe for animation. I was already familiar with most of the content except for <a href="http://mrl.nyu.edu/~perlin/">Ken Perlin</a>&rsquo;s new foot-placement work, but it was a great overview anyway. I&rsquo;ve been quite excited about data-driven animation for a couple of years, and <a href="http://www.cs.wisc.edu/~kovar/">Lucas Kovar</a>&rsquo;s work is very promising. I think the only thing holding that technique back from being applied to games is the memory requirements, but I would love to spend some time trying to make it practical. <a href="http://www.cs.ucr.edu/~vbz/">Victor Zordan</a>&rsquo;s work is also very promising, combining dynamics with data from motion capture, which would be great for games (using ragdolls to predict and blend into falling animations for example).</p>
<p>Thursday was definitely the big day (for sessions, although that&rsquo;s always the biggest day for parties too). The day started with the excellent session on &ldquo;Advanced Prototyping&rdquo; by <a href="http://www.d6.com/users/checker/">Chris Hecker</a> and <a href="http://www.slackworks.com/~cog/">Chaim Gingold</a>. I really can&rsquo;t say enough good things about it: it was packed with interesting, non-obvious information, it was very well presented and full of energy (it&rsquo;s Chris we&rsquo;re talking about, so of course it is!), and extremely motivational. They did a top-notch job preparing for the presentation and it showed. The pair had a very interesting presentation style that felt almost like a conversation between them two, and it worked very well. It was hands-down the best session of GDC for me. The talk covered things like why you want to prototype, what constitutes a good prototype, how you go about prototyping things, what to prototype and what to leave out, how to put the results together, etc, etc.</p>
<p>I don&rsquo;t really understand why it was classified under the game design track. It really was more of a programming, production, or just all-around session. Even so, apparently the session was full and they had to turn people away. I really hope that they recorded it on video and they make it available online.</p>
<p>At one point they described what they considered to be a good codebase for prototyping. The funny thing is, I completely agree with every point they brought up, but for me those are characteristics I want in <strong>any</strong> codebase, not just one for prototyping. They are all things I value very much: ability to change, flexible, code vs. content, use of scripting, etc. In particular, the comment of frameworks vs. toolsets really hit the mark. That&rsquo;s something I&rsquo;ve been pitching for a while, but I really consider frameworks to be fundamentally broken for the type of development I want to do. Instead, I want a set of tools (functions, classes, whatever) that I can put together in any way I want instead of being constrained to one predefined structure (even if it has hundreds of callbacks, like MFC).</p>
<p>I think I was the only person in the packed Civic Auditorium left cold by the Nintendo keynote. Yes, it&rsquo;s great to have <a href="http://en.wikipedia.org/wiki/Satoru_Iwata">Satoru Iwata</a> give a GDC keynote, but I really didn&rsquo;t connect with his speaking style or his message. I found it content-free and not very engaging (it didn&rsquo;t help any that I was stuck in a corner of the top balconyâ€”apparently there was a screen in the middle of the stage that I was not able to see that explained a lot of his strange comments).</p>
<p>On the other hand, <a href="http://en.wikipedia.org/wiki/Will_Wright">Will Wright</a>&rsquo;s keynote was just the bomb. Somehow every year he manages to deliver amazing talk after amazing talk. I knew I really wanted to hear his session, so I chose to stay in the auditorium instead of going out again to get a <a href="http://www.nintendo.com/gamemini?gameid=tYVqJgro-KG6QL_mMbXFoQTkQIzgi9nU">free DS game</a> and have to wait through that whole line. Good choice! I was able to get the best seat in the house this time around.</p>
<p>Will&rsquo;s keynote cannot really be described in one paragraph. People have asked me what it was about, and I&rsquo;m left without words. The point is not what it was about, it was the whole experience! It&rsquo;s like being 12 years old again and going to a summer blockbuster that hits you from the beginning and doesn&rsquo;t let you go for the next two hours. I left the auditorium dazzled and super-motivated. Isn&rsquo;t that enough?</p>
<p>On the surface, the talk was about how he goes about researching new projects, interleaved with what he learned about astrobiology for the development of <a href="http://www.spore.com/">Spore</a>. You can try getting more of an idea what it was about <a href="http://www.gamedev.net/columns/events/gdc2006/article.asp?id=485">here</a> and <a href="http://www.kotaku.com/gaming/will-wright/gdc-06-liveblogging-will-wright-162561.php">here</a> (and a <a href="http://www.kotaku.com/gaming/keynote/index.php">short video here</a>). That&rsquo;s another talk I hope GDC puts online very soon.</p>
<p>I have to admit, that after Will&rsquo;s keynote, the rest of GDC was fairly anticlimactic. Maybe next time they should leave it for the last day to build up the grand finale. The only session that I attended that really stands out was Tim Moss&rsquo; <em>God of War</em> talk. I was expecting something a bit different, but it turned out to be a mini-postmortem of <em>God of War</em>. In particular, he talked about how they were organized, what their priorities were, and how they went about solving problems. I found it very interesting on many different levels, but the most interesting part was that they do things very differently to how I would go about doing them (or how we&rsquo;re doing them at work right now). They also have a very different set of constraints: they have a very small number of very senior programmers, so they do anything they can to minimize using their time. They end up developing very general solutions, while right now I would advocate for the very specific solutions. It&rsquo;s clear that their approach worked very well for them, so it&rsquo;s great to see how different teams can tackle different problems in a variety of ways.</p>
<p>One pattern I noticed in this year&rsquo;s GDC is that, for technical talks, the more general the talk, the more I enjoyed it. As soon as they got bogged down in details, they became much less effective. A lot of it has to do with the dry nature of the topics, and the fact that I can get all those details from a well-written paper. On the other hand, the more general talks (advanced prototyping, Will&rsquo;s keynote, or the <em>God of War</em> one) were all very motivational and inspirational. In the end of the day, that&rsquo;s what GDC is about for me: inspiration and socializing. And this year&rsquo;s GDC was a huge success by that measure.</p>]]></content:encoded></item><item><title>UnitTest++ v1.0 Released</title><link>https://gamesfromwithin.com/unittest-v10-released/</link><pubDate>Sun, 19 Mar 2006 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/unittest-v10-released/</guid><description>&lt;p&gt;We grabbed the best features of each framework and created what we think it&amp;rsquo;s the best C++ unit-testing framework out there (for our needs anyway). We took the results and put them up in Sourceforge under a veryunrestrictive license, and that&amp;rsquo;s how UnitTest++ was born.&lt;/p&gt;</description><content:encoded><![CDATA[<p>We grabbed the best features of each framework and created what we think it&rsquo;s the best C++ unit-testing framework out there (for our needs anyway). We took the results and put them up in Sourceforge under a veryunrestrictive license, and that&rsquo;s how UnitTest++ was born.</p>
<p>I had been using a modified version of CppUnitLite for quite a while, slowly fixing the parts in need of mending, and adding new functionality as it became needed. Eventually I released most of those changes as CppUnitLite2, and I thought that would be the end of that. It turns out that was just the beginning.</p>
<p>Shortly after that, several people started emailing me with new functionality, fixes, patches, suggestions, etc. At the same time, <a href="http://cnicholson.net/">Charles Nicholson</a> was starting to get quite a bit of response as well for his own testing framework, sometimes with similar fixes and suggestions.</p>
<p>If this was going to grow to be a real project, developing over time, supporting users&rsquo; needs, and accepting code contributions, clearly it would make sense to join forces. And that&rsquo;s exactly what we did. We grabbed the best features of each framework and created what we think it&rsquo;s the best C++ unit-testing framework out there (for our needs anyway).</p>
<p>We took the results and put them up in <a href="http://sourceforge.net/projects/unittest-cpp/">Sourceforge</a> under a <a href="http://en.wikipedia.org/wiki/MIT_License">very unrestrictive license</a>, and that&rsquo;s how <a href="http://unittest-cpp.sourceforge.net/">UnitTest++</a> was born.</p>
<p>Our ultimate goal is to apply test-driven development to game development. All of the existing frameworks fell short in one area or another. Specifically, the driving forces behind the design of UnitTest++ are:</p>
<ul>
<li>Portability. As game developers, we need to write tests for a variety of platforms, most of which are not supported by normal software packages (all the game consoles). So the ability to easily port the framework to a new platform was very important.</li>
<li>Simplicity. The simpler the framework, the easier it is to add new features or adapt it to meet new needs, especially in very limited platforms.</li>
<li>Development speed. Writing and running tests should be as fast and straightforward as possible. We&rsquo;re going to be running many tests hundreds of times per day, so running the tests should be fast and the results well integrated with the workflow.</li>
</ul>
<p>UnitTest++ is a fully featured testing framework, with many of the features you may expect from Xunit-style frameworks such as fixtures and reporting. Additionally, here are some of the specific features that make UnitTest++ unique:</p>
<ul>
<li>Minimal work required to create a new test. For TDD development, we write lots and lots of tests, so creating a new test should be as quick and painless as possible. UnitTest++ does not require explicit test registrations, and creating new tests requires minimal work.</li>
<li>Good assert and crash handling. When automated tests are executed, it&rsquo;s very important not to hang the process or abort the tests any time the program crashes or an assert fails. UnitTest++ will catch and report exceptions as failed tests and print a lot of information about them. It will translate signals to exceptions as well as be able to catch invalid memory accesses and other problems.</li>
<li>Minimal footprint and minimal reliance on heavy libraries. When you intend to run tests on a <a href="http://www.research.ibm.com/cell/SPU.html">Cell SPU</a> with a measly 256 KB of RAM, you really want to be as lean and mean as possible. UnitTest++ is very lightweight, and it will get even lighter weight once strstream is replaced.</li>
<li>No dynamic memory allocations done by the framework, which makes it much easier to track memory leaks and generally more attractive for embedded systems.</li>
<li>Multiplatform support. Right now it supports Win32, Linux, and Mac OS X out of the â€œbox,â€ and other platforms will probably work without any changes. The source code makes use of platform-specific functions whenever necessary, so it is easy to hook up special timers, allocators, or reporters for specific platforms. The code comes with a makefile as well as with project and solution files for Visual Studio 2003 and 2005.</li>
<li>Full set of unit tests for itself. UnitTest++ was TDD&rsquo;d from the ground up, including some of the ugly macros (imagine how much fun it was bending the framework to test itself that way!). It goes without saying, all the tests are included with the source code, so you can go totally wild with them :-)</li>
</ul>
<p>This was just the first release. UnitTest++ is ready for full production work, but we already have plans beyond this release. This is a peek at some of the features we have in mind for upcoming versions:</p>
<ul>
<li>Out-of-the-box support for game console platforms (Xbox 360, PS3 PPU and SPU, and Nintendo Revolution). Of course, this is dependent on us getting permission from the console manufacturers to release some code that works with their SDK.</li>
<li>Ability to trade some features (such as rich check reporting) for some extra memory. In some platforms, like Cell SPUs, you really need to go barebones.</li>
<li>Suites to group tests together.</li>
<li>Different reporters (HTML, GUIs, etc). Don&rsquo;t worry, all those modules will be optional and well separated, so they won&rsquo;t affect the simplicity of the framework.</li>
<li>Per-test timings. Maybe the ability to flag some tests as not exceeding a certain amount of time, or just failing any test that goes over a threshold.</li>
<li>Built-in memory leak detection.</li>
</ul>
<p>So that&rsquo;s it. <a href="http://sourceforge.net/project/showfiles.php?group_id=158151">Download the source code</a> and give it a try. We welcome any comments and suggestions (best channels would be through the <a href="https://lists.sourceforge.net/lists/listinfo/unittest-cpp-devel">project mailing list</a> or comments here). We hope you find it useful and that it makes your TDDing even more productive.</p>]]></content:encoded></item><item><title>Backwards Is Forward: Making Better Games with Test-Driven Development</title><link>https://gamesfromwithin.com/backwards-is-forward-making-better-games-with-test-driven-development/</link><pubDate>Mon, 13 Mar 2006 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/backwards-is-forward-making-better-games-with-test-driven-development/</guid><description>&lt;p&gt;We have all experienced how development slows down to a crawl towards the end of a project. We have seen first-hand the difficulty of squashing insidious many-headed bugs. We have wrestled with somebody else&amp;rsquo;s code, just to give up or fully re-write it in despair. We have sat in frustration, unable to do any work for several hours while the game build is broken. Code can get too complex for its own good.&lt;/p&gt;
&lt;p&gt;See how doing something so apparently backwards as writing unit tests before any code can help with all those problems.&lt;/p&gt;</description><content:encoded><![CDATA[<p>We have all experienced how development slows down to a crawl towards the end of a project. We have seen first-hand the difficulty of squashing insidious many-headed bugs. We have wrestled with somebody else&rsquo;s code, just to give up or fully re-write it in despair. We have sat in frustration, unable to do any work for several hours while the game build is broken. Code can get too complex for its own good.</p>
<p>See how doing something so apparently backwards as writing unit tests before any code can help with all those problems.</p>
<p>This paper will be presented at the 2006 Game Developers Conference</p>
<p>Noel Llopis and Sean Houghton High Moon Studios</p>
<p><a href="http://www.convexhull.com/articles/tdd_gdc06.pdf">Printer-friendly format</a>. <a href="http://www.convexhull.com/articles/tdd_gdc06_slides.pdf">Presentation slides</a>. <a href="http://www.convexhull.com/articles/tdd_example.zip">Sample code from presentation</a>.</p>
<p>The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. Frederick P. Brooks, Jr.</p>
<h3 id="1-introduction">1. Introduction</h3>
<p>Part of the appeal of programming is that, as Brooks describes, it allows us to build ornate castles in the air, where our imagination is the only limit. As our target platforms increase in power and memory, our castles become larger and more intricate.</p>
<p>However, it&rsquo;s the same facility to weave code out of thin air that can become our greatest danger. Code has a tendency to grow beyond initial expectations, quickly surpassing our capacity to fully understand it. Our castles in the air can quickly become snowballs that are too large to be moved and shaped to fit our needs.</p>
<p>We have all experienced how development slows down to a crawl towards the end of a project. We have seen first-hand the difficulty of squashing insidious many-headed bugs. We have wrestled with somebody else&rsquo;s code, just to give up or fully re-write it in despair. We have sat in frustration, unable to do any work for several hours while the game build is broken. We have seen countless hours of work go up in smoke as code is thrown away and started from scratch for the next project.</p>
<p>Code can get too complex for its own good. Milestone pressures, a fluctuating game industry, growing teams and budgets, and the breakneck pace of hardware change don&rsquo;t help an already difficult situation.</p>
<p>This is where test-driven development comes in.</p>
<h3 id="2-what-is-test-driven-development">2. What is test-driven development?</h3>
<p>Let&rsquo;s start by looking at the traditional programming process. Once you decide to implement a specific piece of functionality, you break the problem down mentally into smaller problems, and you start implementing each of them. You write code, and you compile it to know whether things are going well. After a while, you might have written enough code that you can run the game and try to see if the feature works. Maybe you run through a level, checking that feature and making sure nothing else looks obviously broken, or maybe you even step in the debugger to make sure your code is getting called and doing what it&rsquo;s supposed do. Once you&rsquo;re happy with it, you check it into source control and move on to another task.</p>
<p>Test-driven development (TDD) turns the programming process around: As before, you break down a problem mentally into smaller problems (or at least a single smaller problem), but now you write a unit test for that small feature, see it fail (since you still haven&rsquo;t implemented anything), and then write the code to make that test pass. Then you repeat the process with another, very small piece of functionality that will get you closer to the full feature you&rsquo;re trying to implement. The cycles are very short, perhaps only a minute or two.</p>
<p>Let&rsquo;s have a more detailed look at the TDD cycle:</p>
<ul>
<li>Write a single unit test for a very small piece of functionality.</li>
<li>Run it and see it fail (in C++, it&rsquo;s likely that it won&rsquo;t even compile).</li>
<li>Write the simplest amount of code that will make the test compile and pass.</li>
<li>Refactor the code and/or tests. Run tests and see them pass.</li>
</ul>
<p>A <em>unit test</em> is a test that verifies a single, small behavior of the system (also called a developer test). Specifically, in this context, each unit test deals with something almost trivially small, which can probably be done in less than a minute. For example, it can test that a health pack doesn&rsquo;t add more health past the player&rsquo;s maximum, or it can test that a particular effect disables depth writes. We&rsquo;ll see an example of a simple test in the next section.</p>
<p>How does TDD help us deal with the complexity of software, and, more specifically, how does it solve some of the problems listed in the introduction? These are the benefits, listed roughly in our order of importance:</p>
<p><strong>Better code design</strong></p>
<p>What is the first thing you do when writing some code with TDD? You are forced to use that code in a test. That simple fact makes it so all code is created with the user of the code in mind, not the implementation details. The resulting code is much easier to work with as a result, and it directly solves the problems it was intended to fix. Also, because the code was first created by testing it in isolation from the rest of the code, you will end up with a much more modular, simpler design.</p>
<p><strong>Safety net</strong></p>
<p>With TDD, just about every bit of code has some associated tests with it. That means you can be merciless about refactoring your code, and you can still be confident that it will work if all the tests continue to run. Even though we find refactoring to be an extremely important part of the development process, the safety net goes way beyond refactoring. You can confidently apply obscure performance optimizations to squeeze that last bit of performance out of the hardware and know that nothing is broken. Similarly, changing functionality or adding new feature towards the end of the development cycle suddenly becomes a lot less risky and scary.</p>
<p><strong>Instant feedback</strong></p>
<p>The unit tests provide you with instant feedback up to several times per minute. If at any point you thought tests should be passing and they aren&rsquo;t, you know something has gone wrong: not an hour ago, not ten minutes ago, but sometime in the last minute. In the worst case, you can just revert your changes and start over. This is quite subjective, but the constant feedback has a surprising morale-boosting effect. No problem seems too large as long as you&rsquo;re taking small steps in its direction and getting feedback that you&rsquo;re in the correct track. For some of us, TDD has rekindled the same joy of programming that we discovered in the 8-bit computers we cut our teeth on.</p>
<p><strong>Documentation</strong></p>
<p>What&rsquo;s worse than uncommented code? Code with outdated comments. We all know how easy it is for comments to get out of date, yet there is very little we can do about it. The unit tests created through TDD serve as a very effective form of documentation. You can browse through them to see what kind of use a class is intended to have, you can look up a particular test to see what kind of assumptions a function makes about its parameters, or you can even comment out some code that makes no sense and see what tests break to give an idea of what it does. The best thing about unit tests as documentation: they can never get out of date. We have found that in codebases that are developed with TDD, comments have almost disappeared, being used only to explain why something was done in a particular way, or to document what paper an algorithm we implemented came from.</p>
<p>One thing that should be clear and is important to stress is that TDD is not just writing unit tests. TDD is a development methodology, not a testing one. That&rsquo;s why TDD&rsquo;s benefits deal with better code design and structure, ease of refactoring, etc, and not with correctness. TDD ensures that your code does whatever you wanted it to do, not that it does it correctly.</p>
<h3 id="3-implementing-tdd">3. Implementing TDD</h3>
<p>Let&rsquo;s put TDD in practice by following the normal practice and writing our first test. Let&rsquo;s assume we already have a game up and running, and our task is to implement health powerups. The very first thing we want to implement is that if the pl ayer walks over a health powerup, he receives some amount of health. That&rsquo;s actually even more complicated than what we want for our small testing steps, so let&rsquo;s start with an even simpler test that requires the least amount of effort: if we have a player and a powerup, and the player isn&rsquo;t anywhere near the powerup, his amount of health doesn&rsquo;t change. Simple, right?</p>
<p>Ideally, how would we like to test that? Probably by writing some code like this:</p>
<pre tabindex="0"><code>World world; 
const initialHealth = 60; 
Player player(initialHealth); 
world.Add(&amp;player, Transform(AxisY, 0, Vector3(10,0,10))); 
HealthPowerup powerup; 
world.Add(&amp;powerup, Transform(AxisY, 0, Vector3(-10,0,20))); 
world.Update(0.1f); 
CHECK_EQUAL(initialHealth, player.GetHealth());
</code></pre><p>And that&rsquo;s exactly what the test will look like, only we&rsquo;ll have to surround it with a macro to take care of all the bookkeeping and to give it a descriptive name. Our full test looks like this:</p>
<pre tabindex="0"><code> 
TEST (PlayersHealthDoesNotIncreaseWhileFarFromHealthPowerup) 
{ 
    World world; 
    const initialHealth = 60; 
    Player player(initialHealth); 
    world.Add(&amp;player, Transform(AxisY, 0, Vector3(10,0,10))); 
    HealthPowerup powerup; 
    world.Add(&amp;powerup, Transform(AxisY, 0, Vector3(-10,0,20))); 
    world.Update(0.1f); CHECK_EQUAL(initialHealth, player.GetHealth()); 
}
</code></pre><p>The macros <code>TEST</code> and <code>CHECK_EQUAL</code> are part of a unit testing framework. The framework is intended to make the task for writing and running unit tests as simple as possible. As you can see, it can&rsquo;t get much easier than that. There are a variety of freely-available unit-test frameworks for C++ and other languages. We recommend UnitTest++, which is a lightweight C++ unit-test framework that supports multiple platforms, is easy to adapt and port, and was created after using TDD in games for several years.</p>
<p>Now we compile this code and we get the following output:</p>
<pre tabindex="0"><code> 
Running unit tests... 
1 tests run There were no test failures. 
Test time: 0 seconds.
</code></pre><p>The <code>CHECK_EQUAL</code> macro is the part that performs the actual check, and it takes as parameters the expected value and the actual value. If they are different, it will mark the test as failed, and output a message with as much information as possible. As a bonus, UnitTest++ formats the failed test message so it can be parsed by Visual Studio and it is easy to navigate to the location of the test.</p>
<p>The reason we have macros like <code>CHECK_EQUAL</code> is that unit tests need to be fully automated. There should be no need for visual inspection or reading some text. The test program should know whether any tests failed or not without any ambiguity, that way it can be easily integrated into the build process.</p>
<h3 id="4-how-to-test">4. How to test</h3>
<p>When writing unit tests, there are three main ways of testing your code:</p>
<p><strong>Return value</strong></p>
<p>Make a function call, and check the return value. This is the most direct way of testing, and it works great for functions that do computations and return the computed value. Because this is the easiest and most straightforward way of testing, we should use this approach whenever possible.</p>
<p>For example, a function called <code>GetNearestEnemy()</code> would be a perfect candidate to be tested this way. We can easily set up a world with a couple of enemies, call that function, and verify that it returns the enemy entity we expected.</p>
<p>Beware of testing functions that return boolean results indicating if the function failed or succeeded. You really want to test that the function does things correctly, not just that it reports it did them.</p>
<p><img alt="Return value" loading="lazy" src="/backwards-is-forward-making-better-games-with-test-driven-development/images/test1.jpg"></p>
<p><strong>Object state</strong></p>
<p>Make a function call, then check that the state of the object or some part of the system has changed correctly. This tests that state changes directly, so it&rsquo;s also a very straightforward form of testing.</p>
<p>For example, we could send an event of nearby noise to an AI in â€œidleâ€ state and check that its state changes to â€œalertâ€ in response.</p>
<p>Sometimes it might force you to expose some state that would otherwise be private, but if it&rsquo;s something that you need to test from the user point of view, then making it public is probably not a bad idea anyway. It might lead to larger interfaces than absolutely necessary, but it also sometimes shows that a class really should be split into two, and one of the classes should contain the other one.</p>
<p><img alt="Return value" loading="lazy" src="/backwards-is-forward-making-better-games-with-test-driven-development/images/test2.jpg"></p>
<p><strong>Object interaction</strong></p>
<p>This is the trickiest aspect to test. Here we make a function call, and we want to test that the object under test did a sequence of actions with other objects. We don&rsquo;t really care about state, just that a certain number of function calls happened. The most common testing pattern for this situation is a <em>mock object</em>. A mock object is an object that implements the interface of another object, but its only purpose is to help with the test. For example, a mock object could record what functions were called and what values were passed, or could be set up to return a set of fixed values when one of its functions is called.</p>
<p>Because this is the most complex form of testing, we recommend using it only when the other two forms of testing are not possible. Using mock objects frequently could be an indication that the code relies too much on heavy objects with complex interactions instead of many, loosely-coupled, simpler objects.</p>
<p>A good situation for using a mock object could be testing HUD rendering. We want to verify that the HUD elements are rendered in a specific order, so we create a mock for the rendering canvas which will keep an ordered list of the elements that get passed to it. We pass the mocked rendering canvas to the HUD renderer and make the render call. Then we can examine that the list in our mocked canvas matches our expectations.</p>
<p><img alt="Return value" loading="lazy" src="/backwards-is-forward-making-better-games-with-test-driven-development/images/test3.jpg"></p>
<h3 id="5-best-practices">5. Best practices</h3>
<p>This is a set of best practices we have found to be particularly important for all of our development with TDD.</p>
<p><strong>Run tests frequently</strong></p>
<p>Being able to write tests easily is a requirement for successfully rolling out TDD. Nobody wants to spend extra time writing unit tests when they can be implementing the features that are due for this milestone. But even more importantly, tests should run very frequently, and a failed test should be treated the same way as a failed build.</p>
<p>At High Moon, every library has a separate test project that creates an executable that links with the library and runs all the tests. We have hooked up running the executable itself as the post-build step in Visual Studio (or as the last command in a make file). That means that making any changes to the library or tests and triggering a compile will also run all the tests. Additionally, since the test executable returns a value with the number of failed tests, a failing test will return a non-zero value, which is interpreted by the build chain as a failed build. This makes it so everybody is running unit tests for all code all the time, which greatly improves the build stability.</p>
<p>In addition to running tests locally, the build server also runs all the unit tests at the same time it does code builds. In our case, since the tests are a postbuild step, there was nothing special we had to do in the build server, and a failed test would be reported just as code that didn&rsquo;t compile correctly.</p>
<p><strong>Test only code under test</strong></p>
<p>This is a key practice for writing good unit tests. The most important reason to minimize the amount of code involved in a test is to keep things simple. Ideally, when something breaks, you want only a small number of tests failing so you can quickly pinpoint the problem. If some tests involve a large amount of the codebase, they will constantly break for unrelated reasons.</p>
<p>Also, if you are able to use the code under test with a minimal amount of other code or libraries, it means you are creating very modular, self-contained code, which will help with the overall design. Finally, another very good reason to avoid involving extra code is that tests that only work on a small set of code are typically much faster than tests that involve large systems and complex initialization/shutdown sequences.</p>
<p>Continuing with the health powerup example, notice that the test involved a <code>World</code> object, a <code>Player</code> object, and a <code>HealthPowerup</code> object. There was no graphics system initialization, databases, etc. The <code>World</code> object can be a very lightweight container for game entities without any other dependencies. Try setting something like that in your current engine and you might be surprised by how many implicit dependencies you find in different parts of the engine.</p>
<p>A test that involves a lot of code across many different systems is usually referred to as a <em>functional test</em>(also called a <em>customer test</em>). Functional tests are extremely useful, especially if they are fully automated, but they fill a very different role than unit tests.</p>
<p><strong>Keep tests simple</strong></p>
<p>This is related to the previous best practice. You want a test to check one thing and only one thing; that way, when something breaks, it&rsquo;s immediately clear what went wrong.</p>
<p>A good start is to label each test clearly with a name that describes exactly what the test is supposed to do. For example, a test named <code>PlayerHealth</code> is not very helpful. A much better name would be <code>PlayerHealthGoesUpWhenRunningOverHealthPowerup</code>.</p>
<p>Keeping each unit test to just a handful of lines makes it much easier to understand at a glance. In our case, it is unusual to have unit tests that are more than 15 lines long. Needing to write overly long unit tests is usually a sign that the test is involving too much code and could probably be re-written in a better way.</p>
<p>We also found that limiting each unit test to a single check statement or two resulted in tests that were the easiest to understand. Sometimes that means you&rsquo;ll have to write some duplicate setup code between two tests, but it&rsquo;s a small price to pay to keep the tests as simple as possible.</p>
<p>Whenever you have some common code in two or more tests, you can use a fixture. A fixture is a set of common code that is executed before and after each test that uses that fixture. Using fixtures can cut down tremendously on the amount of test code you have to write. Any decent unit test framework should support fixtures, so use them whenever they&rsquo;re needed.</p>
<p><strong>Keep tests independent</strong></p>
<p>Unit tests should be completely independent of each other. Creating an object in a test and reusing it in a different test is asking for trouble for the same reasons as we discussed earlier: when a test fails, you want to be able to zero in on the failing test and the problem that is causing it to fail. Having tests depend on each other will cause chains of failing tests, making it difficult to track the problem down to the source.</p>
<p><strong>Keep tests very fast</strong></p>
<p>The unit tests we write are compiled and executed as a postbuild step. We have hundreds or thousands of tests per library, so that means they have to run blazingly fast or they&rsquo;ll get in the way. If unit tests are only dealing with the minimum amount of code, they should be able to run really fast. That means they shouldn&rsquo;t be talking to the hardware, they shouldn&rsquo;t be initializing and shutting down expensive systems, and they most definitely should not be doing any file I/O.</p>
<p>All our unit tests are timed (another feature of UnitTest++), and the overall time for the test run is printed after it runs. As a general rule, whenever a set of unit tests goes over two seconds, it means something is wrong and we try to fix it (even if a unit test takes a full ms, which is a huge amount for a unit test, you can still run 1000 of them in a single second).</p>
<h3 id="6-tdd-and-game-development">6. TDD and game development</h3>
<p>Applying TDD to game development has its own unique challenges that are not usually discussed in the TDD literature.</p>
<p><strong>Different platforms</strong></p>
<p>Most game developers today need to develop for a variety of platforms: PCs (Windows, Macs, or Linux), game consoles, handhelds, etc. Even though at High Moon we develop console games, we use Windows as our primary development environment because of the good development tools and the fast iteration time. That means we always have a version of our engine and tools that runs under Windows, which makes running unit tests very easy and convenient.</p>
<p>We also wanted to run the unit tests in each platform we develop for, but we had to make a few changes to compensate for the shortcomings of those platforms. The minimum support that we needed was the ability to run an executable through the command line and capture the output and, ideally, the return code. Surprisingly, none of the game console environments we develop for supports that simple operation, so we were forced to write a small set of programs using the system API to do exactly that.</p>
<p>After we wrote those small utility programs, we were able to run unit tests on the consoles just like we did under Windows. The main difference was that running any program on the consoles had a noticeable startup time delay. It&rsquo;s a matter of just a few seconds, but it was too long to run the unit tests automatically as a postbuild step after every compilation. Besides, we don&rsquo;t yet have one dev kit for every developer station, so we couldn&rsquo;t count on always having a target platform available. Because of that, our unit tests on platforms other than Windows are only executed manually, and by the build server. It is not ideal, but the large majority of the problems show up in the Windows tests, so as long as those continue being run all the time, we catch most problems on time.</p>
<p><strong>Graphics, middleware, and other APIs</strong></p>
<p>Probably the biggest barrier that people see to doing unit testing and TDD with games is how to deal with graphics. It&rsquo;s certainly not the textbook-perfect example you&rsquo;ll read about in TDD books, but it&rsquo;s certainly possible.</p>
<p>The first thing to realize is that graphics are just part of a game. It is common sense and a good software engineering practice to keep all the graphics-related code in one library or module, and make the rest of the game independent of the platform graphics API and hardware. Once we had that organization, we were able to test any part of the game or engine without having to worry about graphics.</p>
<p>Ideally, we wanted to develop the graphics renderer library with TDD as well, and there&rsquo;s no way to avoid dealing with platform-specific graphics calls. We tried three different approaches, from most involved to least involved:</p>
<ul>
<li><strong>Catch all graphics function calls</strong>. We inserted a layer between the graphics renderer and the graphics API that exactly mimicked the platform API. That way we could make any graphics API calls that we needed without having to worry about the underlying hardware. As a bonus, that layer could report which functions were called and with what parameters. This approach made for extremely thorough tests. The testing layer could be removed in the final build and the functions would call directly into the graphics API so there would be no performance penalties. However, it was quite labor-intensive, especially for the Direct3D API because it uses classes and not just plain functions like OpenGL.</li>
<li><strong>Check for state</strong>. Another approach is to actually work on the graphics hardware and check that things are working correctly by querying the graphics AP I state. For example, rendering a certain mesh should set a specific vertex declaration. This approach is much simpler, but there were some things we couldn&rsquo;t test. For example, we could render a mesh, but we wouldn&rsquo;t be able to find out how many triangles were sent to the hardware. Also, since OpenGL is so state-based, it was important for most functions to clean up after themselves, so it was often very hard to check for any state. On platforms in which the internals of the graphics API are more open, you might be able to examine more states by looking at the graphics command buffer.</li>
<li><strong>Isolate graphics calls</strong>. When all else fails, this is a useful technique for dealing with calls into external APIs. Isolate an API function call or a group of API function calls into a single function, and test that your function is called at the right time. The function that calls into the graphics API itself won&rsquo;t be tested, but all it does it make some straight calls. Remember, what we really want to test is that our code behaves correctly, not that the graphics API works as documented.</li>
</ul>
<p>We started with the first approach, wrapping the API as we were using it, but the amount of extra work we had to do to wrap complex APIs like Direct3D and OpenGL quickly became overwhelming. Maybe if we were working on a commercial graphics rendering middleware it would be worth the effort. For us, after doing that for a few weeks, we realized that the benefits we were deriving from it weren&rsquo;t worth the time we were spending. It was also discouraging us from using new API functions just because they hadn&rsquo;t been wrapped before.</p>
<p>In the end, we ended up settling for a combination for the second and third approaches: testing the state whenever possible, and isolating the calls the rest of the time. One of the drawbacks of this approach is that we&rsquo;re working directly with the hardware, so tests actually do initialize and shutdown the graphics system every time (except for those platforms out there that can only initialize the graphics system once), so they can be more time consuming. On the positive side, because the tests are exercising the graphics API and hardware directly, we catch things that the first approach wouldn&rsquo;t have caught (for example, sending incorrect parameters to a function).</p>
<p>The same three approaches can be used for any middleware or external API. The important thing to remember is to make sure you&rsquo;re testing your code, not the API itself. Keeping that in mind helps to write true unit tests and not functional tests for the API.</p>
<p><img alt="Mocks" loading="lazy" src="/backwards-is-forward-making-better-games-with-test-driven-development/images/mock.jpg"> A good example of this approach is how we wrote our input system with TDD. The input system deals with getting input values from gamepads and other controllers. Even though at first glance it might seem like the whole system is about making system calls to poll the data, there is a lot of common code that is totally platform independent: button mappings, edge detection, filtering, plugging/unplugging controllers, etc.</p>
<p>In our system, we have an interface named <code>GameController</code> with a Sample() function. Each platform implements a platform-specific version of the <code>GameController</code> (for example <code>D3DController</code>) and does the raw sampling of all buttons and axis through platform-specific API calls. That part is fully untested. The rest of the input system works through the <code>GameController</code> interface, but for all the tests we provide a <code>MockGameController()</code> which allows us to control what input values we feed to the tests.</p>
<p>We are hoping that as TDD becomes more common in the games industry, middleware providers will make their APIs more TDD friendly and even ship with their unit tests.</p>
<p><strong>Third-party game engines</strong></p>
<p>If dealing with APIs was not straightforward, working with a full third-party game engine that was not developed with TDD is even more challenging. After all, an API is just a list of classes or functions, and you have a lot of control over how and when they get called. Working with a full game engine, you might end up writing a small module that is fully surrounded by the engine code. If the engine was not developed with TDD, it can be very difficult to use your code in isolation or figure out how to break things up so they can be tested.</p>
<p>At High Moon, we are working on several projects with the Unreal Engine 3, and we&rsquo;re using TDD on them. Even though the engine is not TDD-friendly at all, we still find more benefit from doing TDD with it. Imagine then how useful TDD can be on a full engine developed with TDD from the start.</p>
<p>The most important thing to do in this situation is to separate the code we write as much as possible from the engine code. Not only does this allow us to unit-test our code in isolation, but we also keep future merges with Epic&rsquo;s codebase as simple as possible. However, that severely limits the amount of large-scale refactorings we can do to keep things as testable as possible, so it&rsquo;s a tough trade-off..</p>
<p>One unique aspect of the Unreal Engine is that it makes heavy use of its scripting language, UnrealScript. Because a lot of the high-level game engine is written in UnrealScript, we had little choice but to use it to write most of the game code. The first thing we had to do was to create a unit-testing framework for UnrealScript. The resulting framework is called UnUnit and is freely available for download through UDN (Unreal Developer Network). Several companies working with the Unreal Engine are currently using UnUnit for their game projects.</p>
<p>UnrealScript is a surprisingly good language for unit testing. By default, all functions are virtual, so overriding behaviors and creating mocks is simpler than C++. Also, compilation is very fast, which keeps iteration times low (large, badly organized C++ codebases can take a long time to link). All of that makes TDD with UnrealScript not just possible, but very effective.</p>
<p><strong>Randomness and games</strong></p>
<p>Most games involve a fair amount of randomness: the next footstep sound you play can be any one of a set of sounds, the next particle emitted has a random speed between a minimum and a maximum, etc. As a general rule, you want to remove the randomness from your tests. A few times we caught ourselves starting to write a unit test that called a function many times in a loop and then averaged the result, but that&rsquo;s totally the wrong way to go. Unit tests are supposed to be simple and fast, so any loops in a test are usually very suspect.</p>
<p>A better approach is to separate the random decision from the code that uses it. For example, instead of just having a <code>PlayFootstep()</code> function that takes care of computing a random footstep and then playing it, we can break it into int <code>ComputeNextFootstep()</code> which is just a random function call, and a <code>PlayFootstep(int index)</code>, which we can now test very easily.</p>
<p>Another approach is to take control over the random number generator at the beginning of the test and rig the output so we know what sequence of numbers is going to come up. We can do this either by mocking the random number generator object or by setting some global state on the random number generator, depending on how it is implemented. Then tests can count on a specific sequence of numbers being generated and check the results accordingly.</p>
<p><strong>High-level game scripts</strong></p>
<p>How far is it worth taking TDD? Should TDD be used for every single line of code? How about game-specific script code? The answer depends on your priorities and game.</p>
<p>As a general rule, we find that if any other part of the game is going to depend on the code we are writing, then it&rsquo;s probably worth doing it with TDD and having a full set of unit tests for it. Otherwise, if it&rsquo;s a one-shot deal with the highest-level code, then it&rsquo;s probably fine without TDD. Also, code at that level is often writ ten by designers in a game-specific scripting language, so TDD might not be a viable option.</p>
<p>An example of some code that we would not use TDD for is trigger code: when the player goes around the corner, wake up two AIs and trigger a different background music.</p>
<p>Functional tests are a great complement to unit tests, so it&rsquo;s important not to forget about them. Automated functional tests can be extremely useful catching high-level problems, gathering performance and memory utilization data, and removing some of the mechanical testing from QA and letting them concentrate on issues such as gameplay balance and flow.</p>
<h3 id="7-lessons-learned">7. Lessons learned</h3>
<p><strong>Design and TDD</strong></p>
<p>One of the most important benefits we get from TDD is the better code design that it creates. For this to happen, it&rsquo;s important to let the tests guide the code and not the other way around. It can be disconcerting to always be looking only a few minutes into the future and implementing the â€œsimplest thing that could possibly work,â€ but it really works. The key to working with TDD is to realize that refactoring is an integral part of the development process and should happen regularly every few tests. Good design will come up through those refactorings as needed by the tests we have written and the code we have implemented.</p>
<p>Does this mean you shouldn&rsquo;t do any design ahead of time? That depends on your situation and experience, and the type of code you&rsquo;re writing. In general, the less known or more likely to change something is, the less design we do. If you&rsquo;re working on the 10th iteration of a well-known sports game franchise, for a known platform, and you know exactly what you&rsquo;re going to do, up front design can be more beneficial.</p>
<p>In our case, we prefer to discuss very rough concepts of where we expect something to go, what it should do in the future, and maybe some very, very rough organizational structure. In general, we prefer not to even think of classes or draw UML diagrams on whiteboards before starting, because such discussions can then lead implementation too much. We prefer to let the tests guide us, and if at some point we&rsquo;re going away from what we had in mind at the beginning, we can stop to reconsider if we&rsquo;re heading in the right direction. Most of the time we are, and we simply hadn&rsquo;t thought things through enough at the beginning (or thought through them too much and we simply didn&rsquo;t need that level of flexibility).</p>
<p><strong>TDD and high-level code</strong></p>
<p>One of the questions we had when we jumped into TDD is whether it was going to hold for high-level code. We had seen in practice from previous projects that we can certainly do TDD to create low-level and intermediate-level libraries (math, collision, messaging, etc). But would it really work for high-level code that would build on low-level code?</p>
<p>The answer is an unconditional yes. We have developed a full codebase doing TDD from the start, and we had no difficulty writing high-level code with TDD. Things like character state machines, game flow, or specific game entities were done through TDD without any problems, and greatly benefited from the TDD approach.</p>
<p>Two tips that helped us apply TDD to high-level code:</p>
<ul>
<li>Keep tests as true unit tests. When working on high-level code, it can be tempting to let tests degenerate into functional tests that involve the whole game engine. Don&rsquo;t do that. Even if it takes a few more minutes to make an enemy character testable in isolation, it is well worth it in the long run.</li>
<li>Keep the engine architecture as flat as possible. This is a general good practice, but it is more so with TDD. Clearly, avoid having your engine as one big, intertwined module. But even if it&rsquo;s broken down into libraries or modules, keep them as independent of each other as possible instead of as one long list of dependencies. For example, there&rsquo;s no reason the AI module needs to know anything about graphics or sound, but it will need to know about a world representation and have access to the messaging system.</li>
</ul>
<p><strong>Tests as a measure of progress</strong></p>
<p>Software developers have been struggling for a long time to find a good measure of progress or work done. Some projects use code line counts to determine progress, others use features completed, while others just look at the number of hours spent at the office. Clearly, none of those approaches are ideal.</p>
<p>We have found that counting the number of unit tests is a really good measure of progress. Especially when tests are developed through TDD, they deal less with corner cases and more with program features. If a library has 500 tests associated with it, we can say that it&rsquo;s roughly half as complex as a library with 1000 tests.</p>
<p>As an added benefit, people tend to behave based on how they think they are being measured. So if this is made clear, people will be much more likely to be strict about applying TDD and not falling back on writing code without tests. In our groups, we have a test chart, which is updated every day and shows the total count of tests. If tests aren&rsquo;t going up, or they&rsquo;re going up more slowly than other times, we know something is wrong and we&rsquo;re not making much progress.</p>
<p><strong>Build stability</strong></p>
<p>As we expected, having almost full code coverage with unit tests greatly improves the code stability. Broken builds happen much less frequently, and they&rsquo;re usually caused by a missing file or a different platform not compiling correctly. What was a pleasant surprise is that broken builds are much easier to fix. By following our best practices for unit tests, it becomes really obvious when something breaks, and we can usually check in a fix right away. Builds are rarely broken for more than a few minutes at a time, which can completely change how you organize your code in source control.</p>
<p><strong>Amount of code</strong></p>
<p>It will probably come as no surprise to anybody that writing code with TDD results in more code being written. Sometimes the test code is as large as the code under test itself. Even though this can initially sound like a scary proposition, it really isn&rsquo;t a problem. The extra code does not take significantly longer to write initially, and it allows us to move a lot faster once we have accumulated more code and we need to refactor or optimize the code in any way.</p>
<p>Just because we have twice as much code it doesn&rsquo;t mean we have twice the complexity. Quite the contrary. The test code has been written so it&rsquo;s extremely simple, so its complexity is minimal. Its only job is to check the non-test code, so it&rsquo;s keeping an eye out for us, helping us, and letting us know when something breaks. Additionally, the TDD approach results in much simpler, decoupled code. Overall, the complexity of the codebase is greatly reduced with TDD.</p>
<p>A good analogy to TDD is scaffolding in a building construction. It&rsquo;s not something you&rsquo;re going to deliver to your customer, but it&rsquo;s an absolute necessity, it needs some time commitment to set it up, and you wouldn&rsquo;t dream of doing any complex building without it.</p>
<p><strong>Development speed</strong></p>
<p>This is the million-dollar question: Does TDD slow development? We&rsquo;re not doing TDD because it&rsquo;s a â€œgoodâ€ thing to do, but because we want to ship a better-quality product faster and cheaper than we did before. If TDD doesn&rsquo;t help with this, then there&rsquo;s very little point to it (other than keeping programmers happy).</p>
<p>As with other aspects of software development, it is difficult to make an objective study and measure exactly the effects of TDD versus a control group. Things change too much from project to project and team to team. Still, some initial studies have some interesting initial findings (<a href="http://collaboration.csc.ncsu.edu/laurie/Papers/TDDpaperv8.pdf)">http://collaboration.csc.ncsu.edu/laurie/Papers/TDDpaperv8.pdf)</a>, even if the study was not very rigorous and had a very small sample.</p>
<p>Our experience is that TDD, like any other new development technique, slows development down at the beginning while the team is learning it and becoming familiar with it. Th is can take as long as a couple of months. Once the team is over the hump, and given the right tools and development environment, the impact of TDD on development speed is minimal.</p>
<p>It is possible to simply write code faster than it is to write the tests first, but as soon as that code needs to be refactored, debugged, used by somebody else, or simply gets more complex, any time savings quickly disappear. The larger the team and the more complex the problem, the more TDD saves time in the long run. It&rsquo;s very important to not fall for the temptation of skipping TDD for a very short-term gain (aka milestone of the month).</p>
<p>Ideally, TDD and refactoring can flatten out the classical cost-of-change over time curve into something like this. Notice the trade-off between slightly slower short-term speed vs. massive gains later on.</p>
<p><img alt="Cost of change" loading="lazy" src="/backwards-is-forward-making-better-games-with-test-driven-development/images/costofchange.png"></p>
<p><strong>Adopting TDD</strong></p>
<p>We started with TDD by first trying it with a small group on a separate project. In our particular case, not only were we doing TDD, but we were doing all the extreme programming practices (pair programming, continuous integration, collective code ownership, etc). When doing this, it can be extremely useful to have somebody on board with previous TDD experience who can help guide the process, set up the environment, and avoid common early mistakes.</p>
<p>Applying it on a small scale initially was very useful in many different ways. It let the team become more comfortable with TDD and get to the point where they are as productive as they were before. It also makes any bad practices apparent early on and they can be dealt with before rolling it out (making overly complex tests or functional, rather than unit tests).</p>
<p>It also had the effect of creating new evangelists for the new technique. Members of that team were then moved on to other teams, where they became the resident TDD expert.</p>
<p>TDD fits best with other agile development practices. Having an agile mindset fits very well with the idea of finding the design through tests. Pair programming can be extremely helpful, especially at the beginning while rolling out TDD and getting everybody on board. Pair programing also has the added advantage of making programmers less likely to skip writing tests, which can be a common reaction early on.</p>
<p>If you&rsquo;re interested in applying TDD but you don&rsquo;t have a commitment from your manager or lead, it is possible to start doing it on the side on your assigned tasks. The most important thing is to make sure your tests run automatically (remember the postbuild trick). Slowly, other people might see how useful the tests are, or how much easier it is to refactor that code, and eventually the time might be right to roll out TDD.</p>
<p>A few people can have a hard time switching over to the TDD mentality, but to take full advantage of TDD, it is best to let the design emerge from the tests and the refactoring rather than trying to plan everything up front. It is very interesting to note though, that most programmers at High Moon quickly accepted TDD, and soon became very enthusiastic about it and started using it in all their code, including their home projects.</p>
<p>There is no doubt that the best situation to roll out TDD is with a fresh new codebase. Not everybody has that luxury, so it is important to learn how to apply TDD even with an existing legacy codebase. Michael Feathers&rsquo; book <em>Working Effectively with Legacy Code</em>, explains exactly that situation and gives some very good guidelines on how to go about unit testing with a codebase without existing unit tests. Sometimes it just takes a little bit of refactoring of the existing code and it becomes a lot easier to add new tests.</p>
<h3 id="8-conclusion">8. Conclusion</h3>
<p>Test-driven development can be a very effective development technique. We have successfully applied it to game development in a variety of situations, and we&rsquo;re convinced of the many benefits it has provided us. Right now, the idea of writing code without writing tests first feels quite alien to most of us, and we treat TDD like the scaffolding in building construction: a necessary tool that will not be shipped to the customer but that helps tremendously during development.</p>
<h3 id="9-resources">9. Resources</h3>
<p>This is required reading before you start doing any TDD:</p>
<ul>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0321146530/ref=nosim/gamesfromwith-20">Beck, Kent, <em>Test Driven Development: By Example.</em> Addison-Wesley, 2002</a></li>
</ul>
<p>These other books will also come in handy:</p>
<ul>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0201485672/ref=nosim/gamesfromwith-20">Fowler, Martin, <em>Refactoring: Improving the Design of Existing Code.</em> Addison-Wesley, 1999</a></li>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0131016490/ref=nosim/gamesfromwith-20">Astels, David, <em>Test Driven Development: A Practical Guide.</em> Prentice Hall, 2003</a></li>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0321278658/ref=nosim/gamesfromwith-20">Beck, Kent, and Cynthia Andres, <em>Extreme Programming Explained: Embrace Change (2nd Edition)</em>, Addison-Wesley, 2004</a></li>
</ul>
<p>Very useful mailinglists and web sites:</p>
<ul>
<li><a href="http://www.testdriven.com/">TestDriven.com</a></li>
<li><a href="http://groups.yahoo.com/group/testdrivendevelopment">TDD mailing list</a></li>
</ul>
<p>Resources dealing with TDD and agile game development:</p>
<ul>
<li><a href="/">Noel&rsquo;s blog, Games from Within</a></li>
<li><a href="http://www.agilegamedevelopment.com/blog.html">Clinton Keith&rsquo;s blog, Agile Game Development</a></li>
</ul>
<p>C++ unit-testing frameworks:</p>
<ul>
<li><a href="http://unittest-cpp.sourceforge.net/">UnitTest++</a>. A C++ unit-testing framework designed with game development in mind.</li>
<li><a href="http://cppunit.sourceforge.net/cppunit-wiki">CppUnit</a></li>
<li><a href="/exploring-the-c-unit-testing-framework-jungle/">Comparison of C++ unit-test frameworks</a></li>
</ul>]]></content:encoded></item><item><title>A Day in the Life</title><link>https://gamesfromwithin.com/a-day-in-the-life/</link><pubDate>Mon, 06 Feb 2006 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/a-day-in-the-life/</guid><description>&lt;p&gt;&lt;a href="http://highmoonstudios.com/"&gt;High Moon Studios&lt;/a&gt; is an unusual company in the games industry. We&amp;rsquo;re applying agile methodologies for all of our development. My team in particular is using both Scrum (an agile management methodology) and Extreme Programming (an agile engineering methodology). And yes, that means we&amp;rsquo;re doing pair programming, test-driven development, and all the other often controversial practices. I expect that in a few years, these practices will be a lot more common than they are today.&lt;/p&gt;</description><content:encoded><![CDATA[<p><a href="http://highmoonstudios.com/">High Moon Studios</a> is an unusual company in the games industry. We&rsquo;re applying agile methodologies for all of our development. My team in particular is using both Scrum (an agile management methodology) and Extreme Programming (an agile engineering methodology). And yes, that means we&rsquo;re doing pair programming, test-driven development, and all the other often controversial practices. I expect that in a few years, these practices will be a lot more common than they are today.</p>
<p>This article was first published in the 2005 Career Guide issue of Game Developer Magazine.</p>
<p>I lead the R&amp;D team here, and my team&rsquo;s primary responsibility is to come up with the technology that game teams use for different projects. Nowadays, that means putting a lot of middleware programs through their paces and choosing the ones that suit our needs. But it also means getting down and dirty and writing a lot of code for our engine and tools.</p>
<p>With that in mind, come on and follow me through a typical workday.</p>
<p><strong>8:10 AM</strong></p>
<p>I roll in to work on my bicycle like I do every day. Even though I&rsquo;m an early bird, Jim, a programmer in my team, arrived a few minutes earlier and is already at his desk.</p>
<p>I quickly catch up with my email. I also notice that the PCLint pass on our codebase last night caught a couple of minor warnings, so I quickly fix those and check them in.</p>
<p><strong>8:20 AM</strong></p>
<p>Today is Tuesday and our two-week iteration ends on Friday. An iteration consists of a fixed period (usually two weeks in our case) during which the team commits to deliver a set of functionality described through customer stories. The customer (in our case the other internal teams in our company) creates and prioritizes a set of stories. My team then breaks down those stories into tasks and estimates how long they will take to complete (tasks vary between 1 and 8 hours).</p>
<p>Jim and I walk over to the &ldquo;war room&rdquo; (the room with all the task cards corresponding to user stories pinned to the wall) and we choose the task that reads &ldquo;Blend ragdoll and animation,&rdquo; which is part of the user story listed as &ldquo;Throwing a rigid body at a character and seeing a hit reaction.&rdquo; The task was originally estimated at 3 hours, but now that we know that the ragdoll system is a bit more complicated than we thought, we re-estimate it at 4 hours.</p>
<p><strong>8:23 AM</strong></p>
<p>In addition to our own personal desk areas, we have pair-programming stations in the R&amp;D lab, with two monitors, two keyboards, two mice, two chairs, and plenty of room for two people. All production code is written by pairs of programmers. We grab a station and start working on the task.</p>
<p>Since we&rsquo;re using test-driven development, we first write a very simple unit test for what we want to do, and only then write the code to make it pass. In this case, our first test checks that we create a blender object without inputs and that it produces no output. Then we write the blender class and make the test pass. It&rsquo;s a tiny step, but it&rsquo;s a step in the right direction. The whole cycle of write test, write code to make test pass, refactor, takes only 5-10 minutes, and we do it over and over.</p>
<p><strong>8:39 AM</strong></p>
<p>We have implemented a small amount of functionality, and all the code builds and all tests pass, so we check it in source control. This is called continuous integration, and it requires that programmers work on the latest version in source control and check in their own changes many times throughout the day.</p>
<p><strong>8:50 AM</strong></p>
<p>Other people from the team roll in, grab other pair programming stations, and start going at it. On their way in we have a quick chat and find out what we&rsquo;re all working on.</p>
<p><img alt="Work hard&hellip;" loading="lazy" src="/a-day-in-the-life/images/highmoon1.jpg"> Work hard&hellip;</p>
<p><strong>9:37 AM</strong></p>
<p>I overhear Joel and Gary discussing how they&rsquo;re going to test something that requires updating the physics simulations. I just did that a couple of days ago so I jump in the discussion. It turns out they need to do something that is almost the same as what I already did, so I point them to what I wrote and they will modify it to suit their needs.</p>
<p><strong>10:05 AM</strong></p>
<p>Things are moving along very nicely. We&rsquo;ve checked in four times already this morning. When a pair gets really going, they might check in as many as 20 or more times in a single day. At this rate we might be done sooner than the four hours we had estimated.</p>
<p><strong>10:14 AM</strong></p>
<p>We have the daily Scrum meeting at 10:15, so we head over to the war room. Scrum meetings are very short, standup meetings with the whole team (eight people plus Brian, our producer). We quickly go around the room discussing what people are doing to get everybody up to speed.</p>
<p><strong>10:23 AM</strong></p>
<p>During the meeting the topic of how we&rsquo;re loading physics assets came up. So we return to the pair programming area and have a quick discussion with everybody involved. We draw some quick UML charts on a whiteboard, think about how the data is going to be passed around, and after ten minutes we reach an agreement and go back to work on our tasks.</p>
<p><strong>11:15 AM</strong></p>
<p>We got the blending working correctly. All the unit tests pass, although we haven&rsquo;t implemented it in the demo yet. There&rsquo;s another task card for that. We check the code in right away. The code definitely can stand to improve in a few places because we were just concentrating on getting things working, so we spend some time refactoring. We have lots of unit tests, so we&rsquo;re confident our refactoring isn&rsquo;t introducing any bugs.</p>
<p><strong>11:56 AM</strong></p>
<p>The code is now in a much better state. We check it in and wait a few minutes for the build server to report that everything built correctly and all tests passed. During that time we talk about what the next task should be.</p>
<p><strong>12:05 PM</strong></p>
<p>We have nice shoulder-high surf today, so I&rsquo;m going out surfing at lunch with several of my teammates. If it&rsquo;s not surfing, it&rsquo;s a basketball game, cycling, running, or even yoga. If all else fails, there&rsquo;s always a game of <em>Guild Wars</em> with the rest of the High Moon clan.</p>
<p><strong>1:10 PM</strong></p>
<p>Back at my desk I eat a quick lunch while I catch up on my email (which I haven&rsquo;t read since this morning because I&rsquo;ve been at the pair programming station). I read an email from a middleware developer in response to one of our queries earlier in the day and fire back a quick response.</p>
<p><strong>1:25 PM</strong></p>
<p>Sean stops by my desk. He&rsquo;s ready to go back to work, but the programmer he was pairing with in the morning got pulled to work on some last-minute issues with <em>Darkwatch</em>, which is about to go gold and has priority over anything we&rsquo;re doing.</p>
<p>Sean quickly brings me up to speed on what they had been working on that morning, which was to display the exact memory usage for our physics system. I remember them mentioning that in this morning&rsquo;s Scrum meeting. I also worked on the physics system last week, so I&rsquo;m pretty familiar with the code. In a couple of minutes we&rsquo;re already making progress.</p>
<p><img alt="&hellip;rock hard" loading="lazy" src="/a-day-in-the-life/images/highmoon2.jpg"> &hellip; rock hard :-)</p>
<p><strong>2:07 PM</strong></p>
<p>After writing several unit tests and implementing some functionality, we&rsquo;re ready to add the memory display to the demo program. A couple of minutes later, we have a display in the demo indicating how much memory the physics system is using, and we see it go up and down as we add and remove rigid bodies from the demo.</p>
<p>But something is wrong. When we remove rigid bodies, the memory doesn&rsquo;t come down to the same level it was before. We exit the demo and we see a long memory leak dump. First things first, we check in our changes, and then we dive in and look for the code that is leaking memory. It&rsquo;s probably not caused by the code we just wrote, but we have &ldquo;collective code ownership,&rdquo; which means that everybody is expected to fix anything that needs fixing anywhere.</p>
<p><strong>2:12 PM</strong></p>
<p>The build just broke! The build server detected a failed build and notified us through a system tray application. I bring up the latest build log and I see that one of the unit tests failed in release mode. Tyson, who is sitting at the station next to ours, says &ldquo;Oh yeah, I know what that is. I&rsquo;ll fix it right now.&rdquo; In less than 30 seconds he makes the change, and checks it in. A few minutes later, the build system reports a passing build and everything is back to normal.</p>
<p><strong>2:17 PM</strong></p>
<p>We found the memory leak. It was a misuse of reference counting. We first wrote a unit test that showed it failing, and then we fixed in the physics library. We check in our code.</p>
<p><strong>2:18 PM</strong></p>
<p>We go to the war room and grab the next task. This one has to do with being able to expose different variables and functions on the demo to tweak them through a GUI. We sign up for the task and start working on it.</p>
<p><strong>3:43 PM</strong></p>
<p>We&rsquo;re totally in the zone. We&rsquo;ve been writing tests and code like crazy and this task is going really well. We&rsquo;ve done three check-ins for this task alone in the last hour.</p>
<p><strong>4:12 PM</strong></p>
<p>Another pair is discussing how to handle errors for some particular case. This is an important topic and it should be done consistently across all the code, so we have a quick discussion about it involving most of the team. Five minutes later we&rsquo;ve made a decision and we all resume working on what we were doing before.</p>
<p><strong>5:40 PM</strong></p>
<p>We do our last check in for the day. We&rsquo;re almost done with the task, but not quite there yet. Even though we could stay another hour and try to finish it, we&rsquo;re both quite tired by now and we&rsquo;re starting to not think as clearly and make some mistakes. We can wrap this up tomorrow morning as soon as we get in. The important part is that we got to a state where we could check in.</p>
<p>We have a rule that says nobody can check in code and leave. You have to wait for the build server to build the code successfully and pass all the tests. We keep build times short, so that usually means hanging around an extra 4-5 minutes. If anything breaks, you need to fix it or revert what you did, but there&rsquo;s no excuse to leave with a broken build.</p>
<p>While I&rsquo;m waiting for the build server to finish, I check the pile of email that accumulated in my inbox during the day.</p>
<p><strong>5:44 PM</strong></p>
<p>After a few minutes we get the green go ahead from the build server. Today was a pretty productive day, and at this pace we will definitely complete all the user stories by Friday. The demo we&rsquo;re putting together is also starting to look very cool.</p>
<p>One of the things that agile development, and especially pair programming, does is to make each day very intense. There are no little breaks to read email, check a web site, or just goof around. We get a lot accomplished in a work day, but we can&rsquo;t keep that pace for a long time, so it&rsquo;s important to call it quits and go home. That leaves me with time at home to read technical books, prototype different ideas, or work on side projects in addition to unwinding, spending time with my family, and enjoying other hobbies.</p>
<p>I hop on my bike and head home with a big smile on my face.</p>]]></content:encoded></item><item><title>CppUnitLite2 1.1</title><link>https://gamesfromwithin.com/cppunitlite2-11/</link><pubDate>Sun, 18 Dec 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/cppunitlite2-11/</guid><description>&lt;p&gt;At this point, we have been using CppUnitLite2 for a year at High Moon Studios doing test-driven development on Windows, Xbox 360, and some PS3. It has been used to unit test libraries of an engine, pipeline tools, GUI applications, and production game code.&lt;/p&gt;</description><content:encoded><![CDATA[<p>At this point, we have been using CppUnitLite2 for a year at High Moon Studios doing test-driven development on Windows, Xbox 360, and some PS3. It has been used to unit test libraries of an engine, pipeline tools, GUI applications, and production game code.</p>
<p><a href="/wp-content/uploads/bin/CppUnitLite2_1_1.tar.gz"><img alt="icon" loading="lazy" src="/cppunitlite2-11/images/script.png">CppUnitLite2_1_1.tar.gz</a></p>
<p>About a year ago, I wrote <a href="/exploring-the-c-unit-testing-framework-jungle/">an article comparing unit test frameworks</a> that went to become one of the most popular in this site. The article concluded with the recommendation of one of the less well known frameworks: CxxTest.</p>
<p>Shortly after writing that article, it came time to roll out test-driven development at work. Interestingly, once I weighted in all the requirements, I ended up not following my own advice. Instead, I decided to go with a customized version of CppUnitLite, which was listed in the article as the second choice. The idea of an extremely simple unit testing framework was too attractive to pass up in an environment where we have to support a large variety of environments and target platforms.</p>
<p>At this point, we have been using CppUnitLite2 for a year at <a href="http://www.highmoonstudios.com/">High Moon Studios</a> to do TDD on Windows, Xbox 360, and some PS3 (we even have a stripped-down version that runs on a <a href="http://cell.scei.co.jp/e_download.html">PS3 SPU</a>). It has been used to unit test libraries of an engine, pipeline tools, GUI applications, and production game code.</p>
<p>CppUnitLite2 was originally released along with my article a year ago. It was a heavily modified version of the original CppUnitLite by Michael Feathers. This version introduces the changes we made at work as different issues came up and we needed more functionality from the framework. In particular, <a href="http://www.tilander.org/jim/">Jim Tilander</a> and <a href="http://cnicholson.net/content.php?id=1">Charles Nicholson</a> were responsible for a lot of those changes. By now, I doubt there&rsquo;s a single line left from the original code. Additionally, CppUnitLite2 itself has a set of tests using itself in an interestingly recursive way.</p>
<h3 id="whats-new">What&rsquo;s new</h3>
<p><strong>Fixtures created and destroyed around each test.</strong></p>
<p>I can&rsquo;t believe that the original version of CppUnitLite2 didn&rsquo;t have this feature. It was the biggest glaring problem with the framework (I even pointed it out in the article). Each fixture used to be created at static initialization time, which, apart from being a really bad idea, caused a lot of objects to be created and live in memory at the same time. Considering that some of those objects would initialize/shutdown some important game systems, we clearly needed to manage their lifetime a bit better.</p>
<p>The test macro was changed to register a temporary test with the TestRegistry, which in turn will create the fixture at execution time. Now fixtures and tests are created just before each test, and destroyed right after, just as you would expect from any sane framework.</p>
<p>For those masochists out there, here&rsquo;s the ugly macro for a test with fixture in all its glory. Notice how the TestRegistrar registers the dummy test class that we created as part of the macro.</p>
<pre tabindex="0"><code> #define TEST_F(fixture, test_name)                                                      \ struct fixture##test_name : public fixture {                                        \ fixture##test_name(const char * name_) : m_name(name_) {}                       \ void test_name(TestResult&amp; result_);                                            \ const char * m_name;                                                            \ };                                                                                  \ class fixture##test_name##Test : public Test                                        \ {                                                                                   \ public:                                                                         \ fixture##test_name##Test ()                                                 \ : Test (#test_name &#34;Test&#34;, __FILE__, __LINE__) {}                       \ protected:                                                                      \ virtual void RunTest (TestResult&amp; result_);                                 \ } fixture##test_name##Instance;                                                     \ TestRegistrar fixture##test_name##_registrar (&amp;fixture##test_name##Instance);       \ void fixture##test_name##Test::RunTest (TestResult&amp; result_) {                      \ fixture##test_name mt(m_name);                                                  \ mt.test_name(result_);                                                          \ }                                                                                   \ void fixture ## test_name::test_name(TestResult&amp; result_)
</code></pre><p><strong>Improved check statements</strong></p>
<p>Another one of the major weaknesses of CppUnitLite as it stood was the check statements. You needed to have a custom check macro for each data type you cared to check. The generic CHECK_EQUAL macro will now work on any data type as long as it can be compared with operator == and output to a stream.</p>
<p>This version of CppUnitLite2 also includes some special macros to check arrays with one and two dimensions. Again, this works on any data type that supports operator == and operator[]. It came it very handy for checking equality of vectors and matrices in a game engine. For example, the following code checks that two matrices are equal:</p>
<p>CHECK_ARRAY2D_CLOSE (m1, m2, 4, 3, kEpsilon);</p>
<p>Ironically, in some heavily restricted environments (like the PS3 cell processors), we can&rsquo;t use streams, so in that case we&rsquo;re forced to go back to the old specialized check macros.</p>
<p><strong>Invariant statements in checks</strong></p>
<p>Another really annoying feature of the previous version of CppUnitLite2 was that the code in a check statement was called multiple times, which could cause strange side effects.</p>
<p>Consider the following code:</p>
<p>CHECK_EQUAL (FunctionWithSideEffects1(), FunctionWithSideEffects1());</p>
<p>The way the check statement was expanded out, both those functions could be evaluated multiple times. If the functions had side effects, they would be executed several times, causing unexpected results (for example, the check could fail but the printed result could be different). The fix wasn&rsquo;t trivial because we couldn&rsquo;t save off the value of each statement because they could be of any type and we have no way of finding the type from within the macro.</p>
<p>The check macro now expands out to a templated function, which is able to evaluate both statements only once and work with the saved value to avoid any surprising side effects.</p>
<p><strong>Optional fixture initialization</strong></p>
<p>As we continued hammering on the unit test framework for all our development, one clear pattern appeared that wasn&rsquo;t handled by the framework: Being able to create fixtures with parameters defined in the test. For example, the fixture might do ten different steps, but we want to set a particular value in one of those steps, and by the time control reaches the test code itself it&rsquo;s too late.</p>
<p>We started getting around that by creating different fixtures, and then by inhereting from other fixtures and changing some parameters. Both of those solutions were less than ideal (lots of code duplication and added complexity). Things got out of hand when we made the fixtures a templated class on a value, and created them by specifying the value as part of the texture name. Now it was a pain to debug and things were even less clear.</p>
<p>So we finally implemented it natively in CppUnitLite2 as fixtures with initialization parameters. We introduced a new macro, TEST_FP (test with fixture and parameters), which takes any parameters you want to pass to the fixture constuctor.</p>
<p>Now you can declare tests like this:</p>
<p>TEST_FP (VectorFixture, VectorFixture(10), MyTest) { }</p>
<p>We should prob ably simplify that to avoid repeating the fixture name, but that works fine for now.</p>
<p><strong>Include cleanup</strong></p>
<p>The original version of CppUnitLite was pretty casual about what headers it included. Unfortunately, that means that all test code were automatically exposed to a variety of standard headers, whether you wanted it or not. This version is a lot more strict, and the only header that will get pulled in from using it will be iosfwd, which is even a fairly lightweight one.</p>
<p><strong>Memory allocations</strong></p>
<p>We have very strict memory allocation wrappers around our tests, and if any memory leaks, it is reported as a failed test. Since checking for memory allocations is very platform specific, it is left out of the framework (although it could be added pretty easily in the platform-specific sections). In any case, some of the static-initialization time allocations were confusing the memory tracker, so we removed them completely. All it means is that we use an array to register tests instead of a std::vector and we cap the maximum number of tests to a fixed amount. If you need more than the default 5000 tests, go right ahead and add a few zeros.</p>
<p><strong>New license</strong></p>
<p>Previous versions of CppUnitLite were not released with an explicit license. To make things clear, I explicitly added the license text for the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a> with an added restriction. The MIT license allows you to use the code in any project, commercial or otherwise, without any restrictions. The added restriction to the license prohibits its use in any military applications or projects with any military funding.</p>
<h3 id="ratings">Ratings</h3>
<p>How does this release of the CppUnitLite2 compare with respect to my initial set of features I used to rate the different unit tests frameworks?</p>
<ul>
<li><strong>Minimal amount of work needed to add new tests.</strong> Nothing has changed there. Still passes with flying colors.</li>
<li><strong>Easy to modify and port.</strong> That has always been the strong suite of this framework.</li>
<li><strong>Supports setup/teardown steps (fixtures).</strong> Much improved now by creating them correctly around each test.</li>
<li><strong>Handles exceptions and crashes well.</strong> No changes there. Still one of the best I&rsquo;ve seen.</li>
<li><strong>Good assert functionality.</strong> The check macros have been much improved to match the best frameworks out there.</li>
<li><strong>Supports different outputs.</strong> Yup. Still there.</li>
<li><strong>Supports suites.</strong> It still doesn&rsquo;t. It just shows that I really haven&rsquo;t needed this feature yet.</li>
</ul>
<h3 id="future-work">Future work</h3>
<p>So, what&rsquo;s next for CppUnitLite2? It&rsquo;s really quite usable right now, but I could see a few changes happening in the next year, and maybe a few others will come up and surprise me.</p>
<p>Test registration is based on static initialization of global variables, which is not very reliable across compliers. For example, if you try to put the tests in a static library, MSVC will strip out the registration code leaving you with no tests. To get around that, we could introduce a custom build step in a scripting language that would generate a simple file with explicit registration of tests. This could also be used to collect tests from many different libraries into a single executable.</p>
<p>A couple of times it would have been convenient to have parameterized tests (I think that&rsquo;s the correct term for it). Basically, to have tests that could run with different data. Something like this:</p>
<pre tabindex="0"><code> TEST_PARAM(MyCustomTest, int a, int b) { CHECK (something); CHECK(something else); CHECK(yadda yadda); }  TEST(MyTest) { CALL_TEST(MyCustomTest, 10, 5); } TEST(MyTest) { CALL_TEST(MyCustomTest, 12, 7); }
</code></pre><p>The key point is that a test fails in the parameterized test, it should report the error correctly indicating where it came from.</p>
<p>This is actually pretty easy to implement with a couple of macros. We simply haven&rsquo;t needed it more than a couple of times, so we haven&rsquo;t bothered yet. But I imagine next time we run up against this we&rsquo;ll bite the bullet and implement it.</p>
<h3 id="wrap-up">Wrap-up</h3>
<p>Charles had so much fun working with this framework, he decided to write his own from scratch. He made <a href="http://cnicholson.net/content.php?id=52">it available on his web site</a>, so go check it out.</p>
<p>Thanks to High Moon Studios for being open and letting us release the changes we made and share them back with everybody. If you end up using the framework and you make any changes, drop me an email and I&rsquo;ll add them for the next release.</p>]]></content:encoded></item><item><title>Are We There Yet? SlickEdit's C++ Refactoring</title><link>https://gamesfromwithin.com/are-we-there-yet-slickedits-c-refactoring/</link><pubDate>Tue, 11 Oct 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/are-we-there-yet-slickedits-c-refactoring/</guid><description>&lt;p&gt;Jumbo shrimp. Instant classic. Military intelligence. C++ refactoring browser. Spot the pattern yet? Up until recently, there have been more sightings of &lt;a href="http://www.lochness.co.uk/livecam/"&gt;Nessy&lt;/a&gt; and &lt;a href="http://www.unmuseum.org/bigfoot.htm"&gt;Bigfoot&lt;/a&gt; than of working C++ refactoring browsers. After months of using refactoring intensively in C++, my fingers are screaming for mercy and threatening me with repetitive stress syndrome. Fortunately, things seem to be changing a bit. I recently learned of &lt;a href="http://www.slickedit.com/"&gt;SlickEdit&lt;/a&gt;&amp;rsquo;s support for C++ refactoring, so I couldn&amp;rsquo;t resist taking it for a test drive.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Jumbo shrimp. Instant classic. Military intelligence. C++ refactoring browser. Spot the pattern yet? Up until recently, there have been more sightings of <a href="http://www.lochness.co.uk/livecam/">Nessy</a> and <a href="http://www.unmuseum.org/bigfoot.htm">Bigfoot</a> than of working C++ refactoring browsers. After months of using refactoring intensively in C++, my fingers are screaming for mercy and threatening me with repetitive stress syndrome. Fortunately, things seem to be changing a bit. I recently learned of <a href="http://www.slickedit.com/">SlickEdit</a>&rsquo;s support for C++ refactoring, so I couldn&rsquo;t resist taking it for a test drive.</p>
<p><a href="http://www.nobugs.org/developer/parsingcpp/">C++ refactoring is hard</a>. There&rsquo;s no doubt about that. Just parsing C++ is hard, as I quickly found out when <a href="/physical-structure-and-c-part-2-build-times/%20">I wrote some scripts a couple of years ago</a> to analyze the structure of a C++ program. Even with the help of Doxygen pre-processing, my analysis was full of holes and exceptions. Writing a robust program to correctly interpret and modify the structure of a C++ program is a nightmare come true.</p>
<p>Frankly, I had pretty much given up all hope of every having good automated refactoring tools for C++. My best hope was that new language designers keep refactoring in mind as a primary goal of their languages, so at least we&rsquo;ll have those tools in whatever language we&rsquo;re programming with in ten years.</p>
<p>So along comes SlickEdit version 10 with great promises of C++ refactoring. Surprisingly enough, that&rsquo;s just one small bullet point completely hidden by a bunch of bullet-point items of no great interest or uniqueness (smart line selections? keyboard emulation? what year is this, 1992?). As a matter of fact, refactoring isn&rsquo;t even mentioned in SlickEdit&rsquo;s &ldquo;<a href="http://www.slickedit.com/content/view/353/217/">cool features</a>&rdquo; web page! That&rsquo;s not an auspicious beginning.</p>
<p>Fortunately, things get better. The installation for the Linux demo version of SlickEdit v10 worked without a hitch. The refactoring actions feature prominently in the Tools menu and the right-click context menu. I loaded a small project I was working on (just a handful of classes-nothing big) and started applying them one at the time.</p>
<h4 id="rename">Rename</h4>
<p><img alt="nessy" loading="lazy" src="/are-we-there-yet-slickedits-c-refactoring/images/nessy.jpg"> This is the big one. If I can only have one refactoring, I&rsquo;ll take this one. Being able to rename variables, functions, and classes takes care of 75% of the refactorings I do. A tool that could reliably do that would be a major productivity boost (reliably being the key word there).</p>
<p>How does SlickEdit&rsquo;s rename work? Member variables were a dream to rename. But frankly, I can usually do that with &ldquo;replace in file&rdquo; and doing one edit in the header file, so that&rsquo;s not very challenging. Still, good start.</p>
<p>Trying to rename member functions was not quite as successful. Sometimes it would work like a charm, and rename the function in the cpp file, the header file, and everywhere else it was called from. Sometimes however, it would look at my code and proclaim that there was nothing to rename. Nothing? I had just right clicked on top of the function to rename! Some other times it would rename the function in a couple of classes and totally miss where it was being used.</p>
<p>After some experimentation, it turns out that &ldquo;Quick Rename&rdquo; (which supposedly is not nearly as robust) worked time and time again without a single problem. That&rsquo;s good I guess, but it left me with a very uneasy feeling.</p>
<p>Thumbs up for the user interface for refactoring too. As soon as you enter your refactoring and your parameters, you are presented with a list of the files that will be modified and a diff of each of them, so you can cancel the operation if something went horribly wrong. It certainly makes you feel a lot more in control.</p>
<h4 id="extract-method">Extract method</h4>
<p>This is a fairly common refactoring. I actually thought it would be fairly complicated, but in every test I did, SlickEdit handled it admirably. The tricky part is to figure out what arguments the new function needs to take, and every time it figured it out correctly. You even get an option to name the new function and tweak the arguments it takes before applying the refactoring. Again, great user interface.</p>
<p>My only quibble with this refactoring is that the new methods are all made public. Uh? Would it have been so difficult to give us an option? If anything, I have just moved code from a member function to another member function in that class. By default it should be private, not public. Oh well, I just have to move one line. But it&rsquo;s a bit annoying to have to tweak the header file by hand.</p>
<h4 id="modify-parameter-list">Modify parameter list</h4>
<p>Another big one. Sometimes it&rsquo;s quite painful to add a new parameter to a function that is called from dozens or hundreds of tests. So much so that it really discourages us from doing the &ldquo;right&rdquo; thing and is tempting to create a new function instead. Sometimes, after the second time you need to add a new parameter, we just create a struct with the parameters that the function takes and save some pain in the future. Not a particularly elegant solution, so this refactoring tool would come in very handy.</p>
<p>Unfortunately this one completely failed for me. Most of the time, trying to add a new parameter to a function would just come back and tell me there&rsquo;s nothing to do. Same thing with rearranging the order of parameters. At best, once I got it to actually add the new parameter, it only changed the function and the header file, not the calling code. Doh!</p>
<h4 id="misc-inheritance-chain-refactorings">Misc inheritance chain refactorings</h4>
<p>SlickEdit has a set of refactorings intended to do operations in the inheritance chain: push down, pull up, extract super class, etc. I don&rsquo;t work with big inheritance chains these days, so they&rsquo;re not very useful to me and I didn&rsquo;t test them at all. Actually, now that I think about it, the only inheritance I use are interfaces and mock objects. Then again, I suspect this would be extremely handy for manipulating legacy code (like some currently popular game engines).</p>
<h4 id="extract-class">Extract class</h4>
<p>This seems like a really large refactoring. Extracting a whole class out of a set of code? Rename didn&rsquo;t work consistently, and modify parameter list didn&rsquo;t work at all. I certainly wouldn&rsquo;t want to try something of this magnitude. Let&rsquo;s get the other ones working before we jump on this one.</p>
<h4 id="convert-local-to-field">Convert local to field</h4>
<p>This one seems marginally useful, and it&rsquo;s not something I do in a regular basis. All it does is to prepend an m_ to the variable and add it to the header file. What if you don&rsquo;t prefix your member variables with m_? Is there a way to turn that off? Also, the new member variable wasn&rsquo;t added to the constructor(s) initialization list.</p>
<h4 id="move-method">Move method</h4>
<p>At first I thought that it was a totally pointless refactoring since it&rsquo;s describing as moving a method from one class to another (I can&rsquo;t remember when was the last time I did that). But it turns out it can be quite useful to move a non-member function into a class. That&rsquo;s something I do sometimes when a helper function in an anonymous namespace starts needing more and more state from the object that uses it, and eventually it becomes clear that it wants to be a member function.</p>
<p>Move method will make it a static member function, and then you can follow that up with Convert static method to instance method and voila.</p>
<h4 id="encapsulate-field">Encapsulate field</h4>
<p>I&rsquo;m sure some people will rave about this one, but I&rsquo;m not too thrilled about it. It creates set/get methods of a member variable. Frankly, I don&rsquo;t like set/get methods. I think that, most of the time, they&rsquo;re a smell of bad design. I&rsquo;m not sure I want to make it any easier for people to create them, so I would be happier without this refactoring tool at all. Besides, what&rsquo;s with making them inline by default? At least give us an option to put them in the cpp file.</p>
<h4 id="replace-literal-with-declared-constant">Replace literal with declared constant</h4>
<p>This one takes a literal (magic number/string) and replaces with with a constant or a define. Now we&rsquo;re really reaching the bottom of the barrel. Is it really faster to navigate a three-level menu to select this than to do it by hand? It&rsquo;s good that you get an option to create the new constant as const, static const, or an evil #define, but it doesn&rsquo;t place it in an anonymous namespace, even if one already exists in that compilation unit.</p>
<h4 id="create-standard-methods">Create standard methods</h4>
<p>This one will add a constructor, destructor, copy constructor, and assignment operator to the class. At first I thought it wasn&rsquo;t a big deal. I already have macros that do that for new classes. Then I realized you can do this with an existing class, and it will take care of assigning all member variables. That&rsquo;s pretty cool, but of limited practical use. I haven&rsquo;t had to go back to many existing classes and add assignment operators. Still, I could see how it could be useful.</p>
<p><img alt="yeti" loading="lazy" src="/are-we-there-yet-slickedits-c-refactoring/images/bigfoot.jpg"> All in all, SlickEdit managed to impress me because I wasn&rsquo;t really expecting functional C++ refactorings. On the other hand, it is clearly far from being robust enough to be relied upon for production work. Maybe the next version? For me, they just need to fix the rename and I&rsquo;m almost there.</p>
<p>One cool aspect of SlickEdit is its powerful scripting language, where it has access to all the commands you can do from the menu. That means that I can write a script that, as part of what it does, kicks off some refactoring step. That&rsquo;s extremely useful to adapt the refactorings to my own environment. One thing I didn&rsquo;t see is whether the script language has access to the logical structure of the C++ program or whether it&rsquo;s just limited to calling the refactoring function. It would be great to have more control and be able to create custom refactorings.</p>
<p>SlickEdit is a bit puzzling because it parses all the header files during each refactoring. And by all, I mean all. Not just the ones in your projects, but all the standard include files that you might have included. I don&rsquo;t really understand why it does that. I&rsquo;m clearly not going to change standard header files, so I think that limiting a refactoring only to files that are presently loaded in the project would be good. With my toy projects with a handful of classes, the refactorings were very fast (a second or two), but I fear how it might scale to a large project. Next time they have an improved version I&rsquo;ll have to load it up with a large codebase and see how it fares.</p>
<p>It seems as if refactoring tools for C++ are just around the corner, but still tantalizingly out of reach. At this point I&rsquo;m not ready to switch to SlickEdit based on the strength of its refactoring tools alone, although I&rsquo;m still going to take a closer look at it. Right now I would prefer a standalone command-line refactoring tool that could be easily integrated in any environment. Anybody knows of any other decent C++ refactoring tools?</p>]]></content:encoded></item><item><title>Asserting Oneself</title><link>https://gamesfromwithin.com/asserting-oneself/</link><pubDate>Mon, 03 Oct 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/asserting-oneself/</guid><description>&lt;p&gt;I&amp;rsquo;ve been following the discussion on &lt;a href="http://www.lenholgate.com/archives/000500.html"&gt;the evils of assert&lt;/a&gt; started by &lt;a href="http://www.lenholgate.com/"&gt;Len Holgate&lt;/a&gt;. Poor old assert was &lt;a href="http://lapthorn.net/index.php?id=87"&gt;getting beaten up&lt;/a&gt; from &lt;a href="http://sleeksoft.co.uk/public/techblog/articles/20050926_1.html"&gt;every side&lt;/a&gt;, so I&amp;rsquo;m going to have to step forward and defend it.&lt;/p&gt;
&lt;p&gt;Yes, I do find assert useful. Yes, I&amp;rsquo;m doing full-out test-driven development. Yes, I&amp;rsquo;m a hardcore C++ programmer.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;ve been following the discussion on <a href="http://www.lenholgate.com/archives/000500.html">the evils of assert</a> started by <a href="http://www.lenholgate.com/">Len Holgate</a>. Poor old assert was <a href="http://lapthorn.net/index.php?id=87">getting beaten up</a> from <a href="http://sleeksoft.co.uk/public/techblog/articles/20050926_1.html">every side</a>, so I&rsquo;m going to have to step forward and defend it.</p>
<p>Yes, I do find assert useful. Yes, I&rsquo;m doing full-out test-driven development. Yes, I&rsquo;m a hardcore C++ programmer.</p>
<p>Before we even get started, let me recap what I see as the main reasons to use assert.</p>
<ul>
<li>Detect a program error or bug right away. The sooner the better. There&rsquo;s nothing more frustrating than trying to track down bugs that occurred several function calls away, especially if they&rsquo;ve unwound the stack and started a new series of calls. Even worse are errors that propagate and don&rsquo;t become apparent until several frames later.Example: Creating a new character from a spwan point during gameplay should always work, so asserting on the pointer returned by the factory is a good idea.</li>
<li>Document a decision, limitation, or assumption of particular functions. Nothing like calling a function and getting an assert right away to realize that&rsquo;s not the way it was intended to be used.Example: A function that takes a pointer that can never be NULL and we don&rsquo;t want to take a reference (maybe because the object is going to store and keep ownership of the pointer).</li>
<li>Catch bad situations that will soon lead to trouble.Example: Asserting that the matrix passed to a rotate function is orthonormal. Everything will work fine for a little while if it isn&rsquo;t, but soon things will degenerate if errors keep accumulating.</li>
</ul>
<p><img alt="stop" loading="lazy" src="/asserting-oneself/images/stop.jpg"> One key point about the use of assert is that it&rsquo;s a message from the programmers to the programmers and nobody else. The idea is that whatever caused that assert is a top priority and should be fixed right away. An end user should never see an assert message because a) they don&rsquo;t care and b) it means their program is toast.</p>
<p>This distinction between programming errors and &ldquo;user&rdquo; errors is particularly important in game development. User errors are anything that a user of the tools or game could cause just by using it. In our case that includes the content creators (designers and artists). The last thing we want to do is stop everything just because they typed the wrong file, or tried to load an old version of a model. Those errors need to be caught and dealt with. They are expected.</p>
<p>Programming errors are the ones that can only be caused by something done by a programmer in the code. As an example, in game development we constantly have functions that look like this: void Something::Update(float deltaTimeInSec). Unless you have a simulation system that can go both forwards and backwards, trying to call that function with negative seconds is nonsensical. An assert there tells the programmer that something either went horribly wrong, or they&rsquo;re trying to use Update in a way it wasn&rsquo;t intended. Clearly, no user of the program will ever be able to call Update with a negative time value just by using the program. So in this case, I do want to assert and have that fixed right away.</p>
<p>With that out of the way, let&rsquo;s look at Len&rsquo;s <a href="http://www.lenholgate.com/archives/000525.html">five major complaints about assert</a>. Let&rsquo;s take them one at the time.</p>
<h4 id="1-the-check-will-go-away-in-a-release-build">1. The check will go away in a release build.</h4>
<p>From my point of view, an assert is a way to tell a programmer (probably even myself in the future) that something has gone completely wrong. If an assert ever goes off, it&rsquo;s a bug in the code and a programmer needs to fix it.</p>
<p>So what if asserts go away in release builds? We&rsquo;re writing &ldquo;shrink-wrapped&rdquo; software, so that&rsquo;s a good thing because there will be no programmers around with their handy debugger to fix the problem. If a user ever manages to come up with a way to cause the code to get in a bad state, then all we can do is pray. Especially in the case of console games, trying to capture traces and exception reports is not going to help anybody.</p>
<h4 id="2-the-assert-is-covering-poor-design">2. The assert is covering poor design.</h4>
<p>I think this is really the crux of the discussion. Is assert really just a crutch for &ldquo;poor design&rdquo;? If you define good design as creating bullet-proof code that will work under <strong>any</strong> circumstance then it&rsquo;s probably right. But you know, my job is not to write bullet-proof code. My job is to write whatever needs to be written to satisfy our customer stories every two weeks, and eventually ship a game with it.</p>
<p>This is very much in the agile development mindset. I&rsquo;m not going to try to bomb-proof a piece of code for all foreseeable uses in the future. I&rsquo;ll make sure it does what it needs to do now and leave it at that. Under this view, asserts are post-it notes saying &ldquo;This code doesn&rsquo;t even handle this situation. You either screwed up, or you better update the code to deal with it.&rdquo;</p>
<p>Let&rsquo;s go back to the Update() function. What are our options to make it work without assert?</p>
<ul>
<li>Implement Update() to go backwards in time as well as forwards. That will easily more than double development effort for something that will have no effect in the final product (unless you&rsquo;re implementing a mechanic like <a href="http://www.amazon.com/exec/obidos/tg/detail/-/B00009ZVHY/ref=nosim/gamesfromwith-20">Sands of Time</a>, although I suspect that not even that game had a negative-time update).</li>
<li>Make it physically impossible to pass negative numbers into the Update function. We could create a delta time class that cannot be manipulated in any other way than to have positive values. While this is clearly possible, I feel it&rsquo;s a tradeoff between simplicity and &ldquo;bullet-proofness.&rdquo; I&rsquo;ll take simplicity any day of the week for most situations.</li>
<li>Have the update function check for negative values and return a failing value. That would be fine except that now everywhere we call Update we need to check for return values. Did you notice that Update(), the way it was declared, returned no values at all? That&rsquo;s a function that is supposed to work and never fail. What if an Update() function fails? What do we do next? Quietly move on to the next one, or try to fix the system in some way? I&rsquo;d rather slap the programmer with an assert and have him fix it right away than quietly continue to work while things are not working as expected.</li>
</ul>
<p>So I see it more as a tradeoff between simplicity, time, and robustness. There&rsquo;s no single correct answer, and it will depend on your particular situation. If you&rsquo;re writing flight-control software, to hell with simplicity and time constraints, and go for 100% robustness and throw a few redundant systems for good measure in case of cosmic rays interfering with the hardware. In my case, turnaround time and simplicity trump absolute robustness.</p>
<p>Also, I admit this might not work in every environment. It works for us because we&rsquo;re the only users of our own code. When something isn&rsquo;t good enough, we make it good enough. That&rsquo;s very different from writing a generic library for thousands of users to apply in their production code.</p>
<h4 id="3-the-assert-makes-it-very-hard-to-write-a-unit-test-for-the-failure-condition">3. The assert makes it very hard to write a unit test for the failure condition.</h4>
<p>I don&rsquo;t understand where this comes from. Maybe with a crappy unit-test framework it&rsquo;s a problem, but the unit-test framework I use deals with assertions just like any other exception, and fails the current test case. If your unit test framework barfs when your code tries to access an invalid pointer, you really need to look into getting a better one (I keep meaning to put up my version one of these days).</p>
<p>You should be able to hook up assert to anything you want (by using a custom assert or any other way you want). So the test runner first hooks up a special assert handler that throws a particular exception. Not only does this let us fail a test if an exception is triggered, but it even allows us to write tests to check that asserts are thrown. For example, I could write something like this:</p>
<pre tabindex="0"><code> TEST (UpdateWithNegativeTimeAsserts) { Whatever stuff; CHECK_ASSERT(stuff.Update(-0.1f)); }
</code></pre><h4 id="4-if-the-object-is-running-without-a-user-interface-then-the-asserts-dialog-box-may-cause-issues">4. If the object is running without a user interface, then the assert&rsquo;s dialog box may cause issues.</h4>
<p><img alt="oops" loading="lazy" src="/asserting-oneself/images/sign.jpg"> What dialog box? Maybe I&rsquo;ve been doing game development too long, but every single project I&rsquo;ve worked on has had a custom assert macro that gives us a lot more control than the standard one. Seriously, are people calling the standard assert() everywhere? No wonder they have issues.</p>
<p><a href="http://www.amazon.com/exec/obidos/tg/detail/-/1584500492/ref=nosim/gamesfromwith-20"><em>Game Programming Gems 1</em></a> had a great introduction to using custom asserts by <a href="http://www.aiwisdom.com/home_webmaster.html">Steve Rabin</a> with lots of great ideas (<a href="http://www.starforge.co.uk/free-linux.shtml">here&rsquo;s an implementation</a> based on his article). At the very least, you should be able to have full control of what you want the assert to do. A lot of the time that will simply be _asm int 3, but many other times you want to throw an exception, write out a log, send out an email, update a database, or even put up a dialog box to allow the user to bypass it. As a side note, I actually hate the option of continuing after an assert and I would never allow it in my own implementation. Assert means dead. Kaput. Done.</p>
<p>A custom assert takes five minutes to set up and will pay back in gold-pressed latinum in no time.</p>
<h4 id="5-the-assert-is-really-just-an-exploding-comment">5. The assert is really just an &ldquo;exploding comment.&rdquo;</h4>
<p>Yes, that&rsquo;s completely true. It&rsquo;s more like a programmer yelling in your ear &ldquo;YOU JUST SCREWED UP!&rdquo; But then again, that&rsquo;s one of the things that make unit tests so great. They&rsquo;re like comments that complain every time you change the behavior of the system in a way that violates what the tests are checking. Those are the best kind of &ldquo;comments.&rdquo;</p>
<p>That takes care of Len&rsquo;s objections. Clearly, I don&rsquo;t see any of them being an issue other than the second one, which is a matter of tradeoffs. Having said all that, I do use asserts less than I did before I used TDD. Unit tests take care of some of the things I would have checked with asserts in the past (did this loop really iterate over all the members that needed to be updated?), but unit tests still can&rsquo;t protect against misuse of functions or simply unexpected situations.</p>
<p>So no, I&rsquo;m not willing to give up on assert any time soon. It might be an ugly, rusty, oversized tool, but it still has a very definite spot in my toolbox.</p>]]></content:encoded></item><item><title>The Quest for the Perfect Build System (Part 2)</title><link>https://gamesfromwithin.com/the-quest-for-the-perfect-build-system-part-2/</link><pubDate>Tue, 20 Sep 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-quest-for-the-perfect-build-system-part-2/</guid><description>&lt;p&gt;A couple of months ago I looked at &lt;a href="https://gamesfromwithin.com/the-quest-for-the-perfect-build-system/"&gt;various build systems&lt;/a&gt; in the hopes of finding an ideal one for C++ development. In particular, the most important criteria I was using was iteration time for incremental builds. Jam was the clear winner and things looked good.&lt;/p&gt;
&lt;p&gt;Fast-forward a few months and one aborted attempt at implementing that build system, and there are now more unanswered questions than answers. It turns out that Jam and its successors were far from the perfect solution I had envisioned, so I was back to square one. I took this opportunity to look into all the build systems I had left out of the first article, plus all the ones that other people asked me about since then, to come up with a much more comprehensive evaluation.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A couple of months ago I looked at <a href="/the-quest-for-the-perfect-build-system/">various build systems</a> in the hopes of finding an ideal one for C++ development. In particular, the most important criteria I was using was iteration time for incremental builds. Jam was the clear winner and things looked good.</p>
<p>Fast-forward a few months and one aborted attempt at implementing that build system, and there are now more unanswered questions than answers. It turns out that Jam and its successors were far from the perfect solution I had envisioned, so I was back to square one. I took this opportunity to look into all the build systems I had left out of the first article, plus all the ones that other people asked me about since then, to come up with a much more comprehensive evaluation.</p>
<h3 id="the-contenders">The Contenders</h3>
<h4 id="jam">Jam</h4>
<p>Since <a href="http://www.perforce.com/jam/jam.html">Jam</a> is the culprit that caused this second go-around, I figured I would start with it. What&rsquo;s wrong with Jam? Isn&rsquo;t it the fastest kid on the block? It still is the fastest, but when it comes to supporting new platforms or adding new settings to builds, it&rsquo;s not the most straightforward of all systems.</p>
<p>Jam is a bit too complex for my tastes. Even after sitting for a while with the <a href="http://www.perforce.com/perforce/conf2001/wingerd/WPLaura.pdf">Jam tutorial</a> (which is a horrible introduction, by the way), reading the <a href="http://public.perforce.com/public/jam/src/Jam.html">skimpy documentation</a> many times, and playing around with some sample Jam files, it was still very difficult to create non-trivial Jam files. At that point, my best allies were the <a href="http://public.perforce.com/public/jam/src/Jambase.html">Jambase and Jamrules</a> files themselves. When it came time to start adding support for features such as precompiled headers, different build configurations, or Xbox 360 support, things got a lot harder very quickly.</p>
<p>Jam is a bit of a puzzle. Out of the &ldquo;box&rdquo; it claims to be able to have platform-independent Jam files, and that&rsquo;s the source of the problem, because it makes it a lot harder to support new platforms. In my case, since I&rsquo;m targeting a very specific set of platforms, I would much rather specify each build rule myself and have a simple, clean set, instead of a monster set of rules that applies to everything.</p>
<p>At the same time, Jam doesn&rsquo;t support some really basic features, such as spaces in filenames. Not like I advocate having spaces in filenames, mind you, but that&rsquo;s an unfortunate reality of the setup of many Windows computers. Yes, I know I can patch it, but this is where the next, and biggest, problem of Jam comes in.</p>
<p>Jam is dead.</p>
<p>Yes, Jam is completely dead. The <a href="http://maillist.perforce.com/mailman/listinfo/jamming">Jamming mailing list</a> has less traffic than a side road in Siberia during the winter. My attempts at asking there for help went completely unanswered (except for one kind soul who emailed me privately, apparently too embarrassed to post to a dead mailing list).</p>
<p>The fact that the latest official version of Jam dates back to 2002 should have been a good tipoff, but somehow I didn&rsquo;t catch on to that at first. The nail in the coffin was when I asked where the latest set of patches, or the latest unofficial version of Jam, was located and nobody, *nobody*, answered.</p>
<p>So where is everybody who developed and used Jam? Oh, they must have gone to one of Jam&rsquo;s successors, like BoostBuild. That&rsquo;s good, right? Right?&hellip;</p>
<h4 id="boostbuild-v2">BoostBuild v2</h4>
<p><a href="http://www.boost.org/tools/build/v2/">BoostBuild v2</a> is promising on paper. It builds on top of Jam to add several much-needed features such as multiple configurations, correct filename parsing, etc. Or at least so it seems.</p>
<p>As soon as I start digging into it it&rsquo;s very clear that <a href="http://www.boost.org/doc/html/bbv2.html">BoostBuild is much more complex than Jam</a>. It&rsquo;s not like Jam was a walk in the park, but BoostBuild is close to unacceptable. I&rsquo;ll take a Makefile any day of the week. Still, I would be willing to overlook that, bury myself deep in the documentation, and learn the system inside out if BoostBuild lived up to expectations: Jam speed with more features.</p>
<p>Unfortunately it doesn&rsquo;t. It doesn&rsquo;t just fall short either, it misses by several miles and destroys a friendly nearby town in the process. BoostBuild was the slowest of all the build systems I tested. Slower even than Scons! Talk about taking something small and fast and turning it into a slow, lumbering beast.</p>
<p>On the up side, I won&rsquo;t have to spend months learning the overly complex system. I had to find a silver lining somewhere, right?</p>
<p>Is <a href="http://www.boost.org/tools/build/v1/build_system.htm">BoostBuild v1</a> any better? It could be. But frankly, after my experience with v2 I wasn&rsquo;t in the mood to go check it out. Besides, it sounds like they&rsquo;re going to phase it out. If I want a fast, dead build system, I&rsquo;ll choose plain Jam.</p>
<h4 id="microsoft-visual-studio-2005">Microsoft Visual Studio 2005</h4>
<p><img alt="pyramids" loading="lazy" src="/the-quest-for-the-perfect-build-system-part-2/images/pyramids.jpg"> I had heard (from the comments in the previous articles and other posts on the internet) that <a href="http://msdn.microsoft.com/vstudio/">Visual Studio 2005</a> had an improved build system. Even though it seems that C++ is getting the shaft and not being rolled in the <a href="http://lab.msdn.microsoft.com/vs2005/teams/msbuild/default.aspx">MSBuild</a> system for this release, apparently it was still improved somewhat. Since a beta version of Visual Studio 2005 fell in my lap at the GameFest conference earlier this year, I decided to give it a try.</p>
<p>Incremental build times were definitely improved, although they are still far from Jam times. The one-second delay for each project is reduced to a bit less than half a second. Better for sure, but I don&rsquo;t see why it can&rsquo;t be faster. Still, that&rsquo;s getting in the range of being more usable.</p>
<p>One interesting addition is that, by default, Visual Studio 2005 will use multiple threads to compile C++ code. That will be a very welcome addition for full builds. Now I really need a quad-processor machine for our build server.</p>
<h4 id="vcbuild">VCBuild</h4>
<p>MSBuild, the Ant clone that Microsoft has been hailing as the next great thing to come, doesn&rsquo;t yet support C++ builds. It&rsquo;s a matter of priorities, I suppose. In the meanwhile, MSBuild will use the standalone <a href="http://www.gotdotnet.com/team/cplusplus/">VCBuild tool</a> to compile Visual Studio solutions.</p>
<p>VCBuild promises to be a lightweight, command-line version of devenv.com, ideally suited for build servers. Indeed, VCBuild had slightly better build times than MSVC2005, which is a huge improvement over 2003. That actually puts VCBuild as the fastest build system after Jam and Make.</p>
<p>At this point, I was interested enough to think about starting to use VCBuild for all of our command-line builds (at the server and the quick verification build before submitting code). Unfortunately, I immediately ran into a couple of problems. The first one is clearly listed in the Readme, so I knew it was coming: VCBuild will not add a dependent project to the link list like MSVC does. This is actually a <strong>good</strong> thing. I always hated that dependencies implied linking in Visual Studio. Unfortunately, since that&rsquo;s the default behavior, we are relying on it :-( It&rsquo;s easy to change, but it&rsquo;s just one small obstacle in the way.</p>
<p>The more serious problem was that VCBuild didn&rsquo;t seem to parse all the project settings correctly (warning levels for example), so it created very different results than a build with devenv.com.</p>
<p>Finally, I was disappointed to see that VCBuild does not support multiple processors. I had started thinking of VCBuild as a standalone MSVC2005 project compiler, but that&rsquo;s clearly not the case.</p>
<h4 id="fast-solution-build-msvc-plugin">Fast Solution Build MSVC plugin</h4>
<p>This one isn&rsquo;t really a standalone build system like the others covered in this article. However, it directly addresses the problem of speeding up Visual Studio builds, so it was worth including it in. In the past, I had very mixed experiences with it, but after hearing some really good things about it from some co-workers, I decided to give it a whirl.</p>
<p>As promised, <a href="http://www.workspacewhiz.com/FastSolutionBuild/FastSolutionBuildReadme.html">Fast Solution Build</a> does speed up incremental Visual Studio builds to speeds similar to Visual C++ 6.0. That is to say, doing an incremental build with no changes on a large solution takes about a second, which is really how it should be. This time around, I didn&rsquo;t have any problems with strangely broken builds or anything, so it seems pretty stable.</p>
<p>Unfortunately, Fast Solution Build is not without its set of problems. The first few problems are relatively minor. It doesn&rsquo;t seem to play well at all with C#. If I ever make the mistake of attempting a fast build on a C# project, Visual Studio will start a build and never end. The only way to get out of that state is to kill the process and restart Visual Studio. I guess I just need to train my fingers not to press F7 in C# projects.</p>
<p>The other problem is more of a user problem than anything related to the plugin. In spite of its name, Fast Solution Build, it does <strong>not</strong> build a solution, but it builds the selected project. That alone caused more problems than anything because most people are used to doing solution builds, not project builds. It&rsquo;s especially problematic if you want to have several unrelated projects build simultaneously (like in the case of unit tests projects and a game executable in addition to the libraries they depend on). More than once, we ended up checking in code that seemed to build fine, but broke when the server built the full solution.</p>
<p>The lack of a command-line interface also kills Fast Solution Build as a long-term solution. It might be OK while you&rsquo;re working with the IDE, but you can&rsquo;t use it for any command-line builds such as in the build server or for a quick sanity check we have before committing any code.</p>
<p>However, the biggest problem of all with Fast Solution Build is that it&rsquo;s just a plugin to Visual Studio, so you&rsquo;re left with many of the problems in Visual Studio itself, such as being hard to set up large solutions with lots of dependencies, having the visual representation mixed in with the real dependencies, suspect dependency checking (try deleting a file and then doing a build), or being tied to a single platform.</p>
<p>All in all, if you want a quick fix to your build times, Fast Solution Build is a good temporary band-aid provided you don&rsquo;t work with C# much and you don&rsquo;t have very complex solutions.</p>
<h4 id="scons">Scons</h4>
<p>As I was wrapping up the new measurements, I noticed the announcement in for the new version <a href="http://www.scons.org/">Scons</a> (0.96.91 pre-release). Since the last version was many moons ago, and since there was talk about improving Scons&rsquo; performance, I decided to give it a try.</p>
<p>The new version is indeed faster, but only by a tiny amount. Scons still lags far, far behind the curve in terms of performance. Unless the developers manage to squeeze performance improvements of several orders of magnitude, it&rsquo;ll remain unusable as a build system for fast iterations.</p>
<h4 id="ant">Ant</h4>
<p><img alt="skyscraper" loading="lazy" src="/the-quest-for-the-perfect-build-system-part-2/images/skyscraper.jpg"> <a href="http://ant.apache.org/">Ant</a> is one of the build systems I consciously left out of my first roundup. I had used it a bit in a build server, but I had the impression it was mostly intended as a &ldquo;build sequencer,&rdquo; with high-level actions like archiving files or emailing, and intended for full, nightly builds, rather for fast C++ incremental builds. It turns out that even though Ant was developed primarily with Java development in mind, it <a href="http://ant-contrib.sourceforge.net/cc.html">does have C++ support</a> through some of the extra <a href="http://ant-contrib.sourceforge.net/">contribution tasks</a>, with full dependency checking.</p>
<p>Another fact that put me off a bit from trying Ant was <a href="http://ant.apache.org/manual/using.html#example">its level of verbosity</a>. Writing XML files is anything but fun, and I much prefer the terseness of a Make file than the verbosity of an Ant file. Still, if a tool does the job well, I&rsquo;ll put up with a lot.</p>
<p>Ant&rsquo;s dependency checking was not bad, but not great either. Incremental build times with Ant were a bit worse then MSVS2005, but not by much. Frankly, that&rsquo;s faster than I expected with my initial preconceptions.</p>
<p>Full build times on Windows were blazingly fast. So much so, that I was convinced I had configured something wrong and I was only doing half the build. It turns out that everything was fine, but Ant will send all cpp files to be compiled to the compiler at once, whereas other build systems will process them one at a time. Under Linux with gcc, this doesn&rsquo;t make much of a difference, but in Windows using the MSVC compiler, it makes a huge difference. Other build systems should take note of that and take batching much more seriously.</p>
<h4 id="nant">Nant</h4>
<p><a href="http://nant.sourceforge.net/">Nant</a> is Ant&rsquo;s evil twin written with the .Net framework instead of Java. Frankly, I don&rsquo;t really see the point of Nant when Ant is already a mature project and runs in many more platforms. To make matters worse, the Nant developers decided to make their syntax different from Ant. Was that really necessary? If at least it were a straight Ant clone, it would be easier to migrate from one to the other. Personally, I would have preferred to see all that energy put into improving Ant instead of creating a .Net clone.</p>
<p>Having said that, one of the early surprises of Nant was <a href="http://nant.sourceforge.net/release/latest/help/tasks/cl.html">its native support for C++ compilation</a>. In Ant it was a custom task, here it works out of the box.</p>
<p>Nant also has a good set of <a href="http://nantcontrib.sourceforge.net/release/latest/help/tasks/index.html">extra contributed tasks</a>, including support for Perforce operations (although for a lot of the operations I wanted to do, I ended up having to fall back to command-line scripts because the tasks didn&rsquo;t have enough parameters or support for exactly what I wanted to do).</p>
<p>Another potentially interesting feature of Nant is <a href="http://nant.sourceforge.net/release/latest/help/tasks/solution.html">support for Visual Studio solution files</a>. This could be very useful because it would move the dependency checking out of Visual Studio and into Nant. Unfortunately, I tried running it on the solutions at work and it failed miserably. It seems that lots of compiler options are not parsed correctly, so it was impossible to build our existing solutions. I also suspect that C++ isn&rsquo;t their main target, so C++ project support is probably lagging behind C# and Visual Basic. Although I didn&rsquo;t try it, I imagine that Nant would choke at trying to build an Xbox 360 solution file.</p>
<p>Just for kicks, I tried running it on Linux with Mono, but apparently it only works with the Microsoft cl.exe compiler, not with gcc.</p>
<p>Build times were almost identical to those of Ant. Nant does very good batching as well, so full builds were blazingly fast, but incremental builds were only middle-of-the-road.</p>
<h4 id="rakerant">Rake/Rant</h4>
<p>I don&rsquo;t do any <a href="http://www.ruby-lang.org/en/">Ruby</a> development, so I had never heard of <a href="http://rake.rubyforge.org/">Rake</a> until Ivan-Assen Ivanov told me about it. In for a penny, in for a pound, so I went ahead and ran the tests on Rake as well.</p>
<p>Rake is a build system written in Ruby (and I assume mostly intended for Ruby users as well). Like Scons, it brings the full power and expressiveness of a scripting language (Ruby in this case) to the build script. It looks pretty simple and clean. The Ruby syntax is a bit strange at first sight, but it&rsquo;s easy to get used to (especially with lots of examples).</p>
<p>Unfortunately, Rake doesn&rsquo;t have C++ dependency checking built in. I could have probably cobbled something together with makedepend, but that would take more Ruby-foo than I&rsquo;m comfortable with.</p>
<p>Of course, all of this being open source, somebody, somewhere has had the same itch to scratch, and <a href="http://make.rubyforge.org/">Rant</a> was born. Apart from the cool name (after all, who doesn&rsquo;t like to write <a href="http://make.rubyforge.org/files/doc/rantfile_rdoc.html">Rantfiles</a>?), Rant looks very similar to Rake. Don&rsquo;t be fooled by their parallels to Make and [N]Ant. It&rsquo;s much more Make meets Scons in Rubyland than a derivative of Ant.</p>
<p>One feature of Rant that I really liked was the good support for error messages. If the Rantfile had a problem in it, it would correctly identify the problem and point me to it. After working with Ant/Nant, that was a welcome change.</p>
<p>The build times were a bit of a mixed bag. Full incremental builds were pretty good, definitely in the top third of the build systems I looked at. Unfortunately, building a single library without any changes was extremely slow. It seems that Rant had to do a lot of work before it could even look at an individual library. If it weren&rsquo;t because of that, I would be a lot more excited about it.</p>
<h4 id="make-and-msvc2003">Make and MSVC2003</h4>
<p>Nothing new in this front. For details, just read the <a href="/the-quest-for-the-perfect-build-system/">first article</a>. Everything there still applies.</p>
<h3 id="the-method">The Method</h3>
<p>I used the <a href="/the-quest-for-the-perfect-build-system/">same test case and hardware as the last time</a>. As a quick recap, the source code was made up of 50 static libraries with 100 classes each (2 files per class), 15 includes per cpp file to other files in that library, and 5 includes to files in other libraries.</p>
<p>The <a href="/wp-content/uploads/bin/generate_libs.zip">Python script</a> generates a tree with a full code base for every build system along with all the necessary build files. Whenever the build files for two platforms are different, two separate trees are created. Thanks to Jim Tilander to writing the Python scripts to generate the BoostBuild files.</p>
<p>The computer was a P4 2.8GHz CPU with 1GB of RAM and a 7200 rpm hard drive. The Linux distro was Mandrake Linux 10.2 with the 2.6 kernel and Windows XP (without any antivirus running&ndash;which makes a huge difference!).</p>
<p><a href="/wp-content/uploads/bin/generate_libs.zip"><img alt="icon" loading="lazy" src="/the-quest-for-the-perfect-build-system-part-2/images/script.png"> generate_libs.zip</a></p>
<h3 id="the-results">The Results</h3>
<p>Linux with gcc 3.4.1</p>
<table>
	<thead>
			<tr>
					<th>Build system</th>
					<th>Full build</th>
					<th>Incremental</th>
					<th>Incremental lib</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>GNU Make (3.80)</td>
					<td>2m 21s</td>
					<td>0m 2.4s</td>
					<td>0m 0.0s</td>
			</tr>
			<tr>
					<td>Jam (2.5)</td>
					<td>2m 42s</td>
					<td>0m 1.6s</td>
					<td>0m 0.1s</td>
			</tr>
			<tr>
					<td>BoostBuild v2 (3.1.10)</td>
					<td>3m 28s</td>
					<td>0m 46s</td>
					<td>0m 1.6s</td>
			</tr>
			<tr>
					<td>Scons (0.96.91 pre-release)</td>
					<td>5m 08s</td>
					<td>1m 06s</td>
					<td>0m 10.4s</td>
			</tr>
			<tr>
					<td>Ant (1.6.5)</td>
					<td>2m 8s</td>
					<td>0m 21s</td>
					<td>0m 1.7s</td>
			</tr>
			<tr>
					<td>Rant (0.4.4)</td>
					<td>2m 32s</td>
					<td>0m 10s</td>
					<td>0m 4.9s</td>
			</tr>
	</tbody>
</table>
<p><img alt="linux full builds" loading="lazy" src="/the-quest-for-the-perfect-build-system-part-2/images/linux_full.png"></p>
<p><img alt="linux inc builds" loading="lazy" src="/the-quest-for-the-perfect-build-system-part-2/images/linux_incremental.png"></p>
<p>Windows XP with MSVC 2003 compiler (except for the MSVC2005 run).</p>
<table>
	<thead>
			<tr>
					<th>Build system</th>
					<th>Full build</th>
					<th>Incremental</th>
					<th>Incremental lib</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Microsoft Visual Studio 2003</td>
					<td>7m 28s</td>
					<td>0m 54s</td>
					<td>0m 4s</td>
			</tr>
			<tr>
					<td>Microsoft Visual Studio 2003 + FastSolutionBuild</td>
					<td>7m 26s</td>
					<td>0m 1s</td>
					<td>0m 1s</td>
			</tr>
			<tr>
					<td>Microsoft Visual Studio 2005</td>
					<td>6m 46s</td>
					<td>0m 20s</td>
					<td>0m 3.5s</td>
			</tr>
			<tr>
					<td>VCBuild (7.10.3088.1)</td>
					<td>6m 56s</td>
					<td>0m 18s</td>
					<td>0m 0.5s</td>
			</tr>
			<tr>
					<td>Jam (2.5)</td>
					<td>6m 52s</td>
					<td>0m 3.1s</td>
					<td>0m 0.3s</td>
			</tr>
			<tr>
					<td>BoostBuild v2 (3.1.10)</td>
					<td>12m 03s</td>
					<td>0m 55s</td>
					<td>0m 2s</td>
			</tr>
			<tr>
					<td>Scons (0.96.91 pre-release)</td>
					<td>7m 52s</td>
					<td>0m 57s</td>
					<td>0m 7s</td>
			</tr>
			<tr>
					<td>Ant (1.6.5)</td>
					<td>3m 42s</td>
					<td>0m 33s</td>
					<td>0m 1.9s</td>
			</tr>
			<tr>
					<td>Nant (0.85)</td>
					<td>3m 24s</td>
					<td>0m 35s</td>
					<td>0m 1.4s</td>
			</tr>
			<tr>
					<td>Rant (0.4.4)</td>
					<td>5m 47s</td>
					<td>0m 25s</td>
					<td>0m 14s</td>
			</tr>
	</tbody>
</table>
<p><img alt="win full builds" loading="lazy" src="/the-quest-for-the-perfect-build-system-part-2/images/win_full.png"></p>
<p><img alt="win inc builds" loading="lazy" src="/the-quest-for-the-perfect-build-system-part-2/images/win_incremental.png"></p>
<p><em>Update:</em> Since several people asked, I timed Scons with MD5 checksum checking turned off in the hopes of getting a better time. I followed the advice described <a href="http://www.scons.org/cgi-bin/wiki/GoFastButton">here</a>. Just like last time, turning off MD5 checksum made it go <em>slower</em> if that makes any sense.</p>
<table>
	<thead>
			<tr>
					<th>Scons build (Linux)</th>
					<th>Incremental build time</th>
					<th>Difference</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Normal</td>
					<td>1m 06s</td>
					<td>--</td>
			</tr>
			<tr>
					<td>--max-drift=1</td>
					<td>1m 10s</td>
					<td>+5s</td>
			</tr>
			<tr>
					<td>--implicit-deps-unchanged</td>
					<td>0m 47s</td>
					<td>-19s</td>
			</tr>
			<tr>
					<td>--max-drift=1 &ndash;implicit-deps-unchanged</td>
					<td>0m 50s</td>
					<td>-16s</td>
			</tr>
	</tbody>
</table>
<p>Using the option to indicate unchanged dependencies made it go a bit faster, but that&rsquo;s not an option we can realistically use during development, since that would be changing constantly with the structure of our program. Still, the fact that without doing any dependency checking it&rsquo;s still taking 47 seconds. What is it doing??</p>
<p>With multiprocessor machines being so common these days, a good build system needs to support parallel execution of tasks in multiple processors. Surprisingly, not all of the build systems compared here support it. Of the usable build systems, only Make, Jam, and MSVC2005 actually support parallel builds.</p>
<table>
	<thead>
			<tr>
					<th>Build system</th>
					<th>Multiprocess builds</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>GNU Make</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td>Microsoft Visual Studio 2003</td>
					<td>No</td>
			</tr>
			<tr>
					<td>Microsoft Visual Studio 2005</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td>VCBuild</td>
					<td>No</td>
			</tr>
			<tr>
					<td>Jam</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td>BoostBuild v2</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td>Scons</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td>Ant</td>
					<td>No</td>
			</tr>
			<tr>
					<td>Nant</td>
					<td>No</td>
			</tr>
			<tr>
					<td>Rant</td>
					<td>No</td>
			</tr>
	</tbody>
</table>
<h3 id="conclusion">Conclusion</h3>
<p>Jam still remains the best-performing build system of all by quite a lot. Unfortunately, the total lack of support and community around it make it very difficult to recommend. There has been some talk recently in the <a href="http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com">sweng-gamedev</a> mailing list to do some work for build systems. Maybe we could take over the continued development of Jam. If that happened, I wouldn&rsquo;t hesitate to recommend it. Until then, unless you&rsquo;re a Jam expert or are willing to dig through user-created patches in the <a href="http://public.perforce.com/public/index.html">Perforce Public Depot</a>, Jam is not a realistic option.</p>
<p>MSVS2005 has improved a lot from 2003, and along with VCBuild, it&rsquo;s one of the best performing build systems under Windows for incremental links. Personally, I hate to be locked in to proprietary tools and single platforms, so I would opt for the next best systems, which are Ant/Nant. Pick your flavor of choice, they&rsquo;re about the same.</p>
<p>MSBuild can be promising, especially once Microsoft rolls out their <a href="http://www.microsoft.com/xna/3.7.2005.aspx">XNA Studio</a> extensions specifically designed for asset building. It&rsquo;ll only run in Windows, but at least they claimed that they&rsquo;re making it general enough you can use for building any type of assets, not just their own formats. That&rsquo;s definitely one to watch for the future.</p>
<p>If you&rsquo;re comfortable with Make files, it still remains as a great option for very fast builds. You&rsquo;ll probably want to wrap Make in a more comprehensive build system (such as Ant) for your build server, packaging builds, etc. But Make can be your everyday workhorse during development.</p>
<p>Whatever you do, stay far, far away from BoostBuild and Scons. Their performance is simply so horrible there&rsquo;s no excuse to use them unless build times are of no importance to you at all.</p>
<p>I remain hopeful that we might be able to resurrect Jam. If you&rsquo;re interested in contributing, contact me through email, comments on this page, or participate in the sweng-gamedev discussion directly</p>
<p><a href="/wp-content/uploads/bin/generate_libs.zip"><img alt="icon" loading="lazy" src="/the-quest-for-the-perfect-build-system-part-2/images/script.png"> generate_libs.zip</a></p>]]></content:encoded></item><item><title>SIGGRAPH 2005 Quick Take</title><link>https://gamesfromwithin.com/siggraph-2005-quick-take/</link><pubDate>Sun, 07 Aug 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/siggraph-2005-quick-take/</guid><description>&lt;p&gt;The SIGGRAPH conference continues to evolve with the times. Ten or fifteen years ago, it was very academically driven, solving problems that nobody had solved before just for the sake of doing something different or more realistic. Today, SIGGRAPH has a much more pragmatic character. Most solutions and techniques presented have been developed out of a need for movie rendering, model authoring and manipulation, or even real-time graphics applications. At the same time, SIGGRAPH has retained the same rigorous background that it always had, making it quite a change from what we&amp;rsquo;re used to in game development.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The SIGGRAPH conference continues to evolve with the times. Ten or fifteen years ago, it was very academically driven, solving problems that nobody had solved before just for the sake of doing something different or more realistic. Today, SIGGRAPH has a much more pragmatic character. Most solutions and techniques presented have been developed out of a need for movie rendering, model authoring and manipulation, or even real-time graphics applications. At the same time, SIGGRAPH has retained the same rigorous background that it always had, making it quite a change from what we&rsquo;re used to in game development.</p>
<p>Unfortunately, whereas for the last couple of years real-time applications, and games in particular, had a relatively strong presence in SIGGRAPH (at least compared to past conferences), this year they were nothing more than a blip on the radar. I really hope that SIGGRAPH can correct that and continue the trend they had been setting for the last couple of years and continue including some real-time and game content.</p>
<p>Even so, SIGGRAPH is a great conference to attend. Unlike GDC, you can&rsquo;t expect to apply what you learned in every session directly to your game. Most of the time, we&rsquo;re years away from even starting to consider most of the solutions presented. The true value of SIGGRAPH comes in the form of giving us a different perspective on graphics, explaining a different set of problems, and using a different set of tools to solve them. So what you&rsquo;re likely to walk away with are new ideas, different thoughts, and lots of excitement.</p>
<p>SIGGRAPH has a variety of session types: papers, sketches, panels, and courses. <a href="http://myweb.hinet.net/home7/hks/Papers2005/sig2005.html">Papers</a> are the more traditional sessions, in which a group of three or four papers are presented by their authors along with some videos of their results. The paper sessions range from outstanding to almost useless (usually when somebody simply repeats the formulas in the paper without offering a different perspective). Sketches are very interesting because they are early looks at some of the work in computer graphics. They often feel much more natural and fresh than the paper sessions.</p>
<p><img alt="perlin" loading="lazy" src="/siggraph-2005-quick-take/images/perlin.png"> This year I had the pleasure to attend what I considered to be the best paper presentation I&rsquo;ve ever seen: &ldquo;<a href="http://portal.acm.org/citation.cfm?id=1073204.1073264">Wavelet Noise&rdquo;</a> by Rob Cook and Tony DeRose. The paper was an attempt to improve on <a href="http://mrl.nyu.edu/~perlin/">Ken Perlin</a>&rsquo;s <a href="http://www.noisemachine.com/talk1/">classic noise function</a>. From the very start, they showed why it needed improving, and proposed a new function. It was all done in a very clear, intuitive way, showing very clear plots of the Fourier analysis of the different noise functions and why one was more desirable than the other. The best part of the presentation was when Rob Cook explained how, with only two weeks to go before the paper submission, they discovered a major flaw in their function, and how they desperately looked for solutions and finally found a good fix in the nick of time. The presentation had it all: a solid theoretical foundation, a good speaker, excellent visuals, and a touch of drama.</p>
<p>As an aside, it is interesting to see how different some paper presentations are from others, and what a huge difference the speaker makes. It seems that the more experienced the speakers are, the less they rely on formulas and equations, and instead they can just say what things are about in a more natural way, whereas most students tend to rely heavily on the math to carry their message. Coincidentally, I was reading <a href="http://www.amazon.com/exec/obidos/ASIN/0393316041/ref=nosim/gamesfromwith-20"><em>Surely You&rsquo;re Joking, Mr. Feynman!</em></a> on the train in my way back from SIGGRAPH. In one of the chapters Feynman reflects on his early experiences giving talks at conferences and reaches a similar conclusion.</p>
<p><img alt="fracture" loading="lazy" src="/siggraph-2005-quick-take/images/fracture.png"> A theme that was ever present in this SIGGRAPH was that of natural phenomena: fluid dynamics, deformable models, plants, etc. I particularly enjoyed the papers on deformable models (<a href="http://www.cs.ubc.ca/~rbridson/docs/zhu-SIGGRAPH05-sandfluid.pdf">&ldquo;Animating Sand as a Fluid&rdquo;</a>, <a href="http://graphics.stanford.edu/~fedkiw/papers/stanford2005-02.pdf">&ldquo;Coupling Water and Smoke to Thin Deformable and Rigid Shells&rdquo;</a>), and dynamics of solids, and in particular the <a href="http://www.cg.inf.ethz.ch/~pauly/publications_files/Pdfs/meshless.pdf">&ldquo;Meshless Animation of Fracturing Solids&rdquo;</a>. The implementation of those papers were still in the range of 20-30 seconds per frame, so there&rsquo;s a ways to go before we can implement them in a game, but they were very interesting nonetheless and might even result in some partial implementation relatively soon.</p>
<p>Interestingly, a lot of the implementations mentioned in this year&rsquo;s SIGGRAPH were done in Java. I thought that was really interesting because I kept assuming that most of them were done in C++. For something that is as computationally expensive as what they&rsquo;re working on, it seems like an odd choice of language. But on the other hand, if they value development time over performance, then it might be a good choice. It can also be a result of changes in the curriculum of universities over the last several years shifting towards Java.</p>
<p>The other set of extremely interesting presentations was on character animation. As in the past few years, data-driven character animation was well represented, and it seems like a great way of going forward in the future. Physically driven animation was also present, but I don&rsquo;t see it having much future on its own. It&rsquo;s the perfect complement to data-driven animation, but by itself, I don&rsquo;t see it creating good, stylized human motion any time soon. There is <a href="http://www.magix.ucla.edu/dance/">a group at UCLA</a> working on combining physically based human motion with kinematics-based techniques that looked quite promising.</p>
<p>One of the few game-related sessions was the one on believable AI-driven characters, in which panelists (mostly from EA) discussed the future of characters. The good news is that all the questions raised in the panel are the questions we&rsquo;ve been asking ourselves for a while, so the problem is real and other people are working on it. The bad news is that there were no real answers to the problem.</p>
<p><img alt="dive" loading="lazy" src="/siggraph-2005-quick-take/images/dive.png"> Another game-related session was titled &ldquo;Jump! Shout! Dance! Sing!&rdquo;, and dealt with alternative input devices for games. During the presentation, panelists showed some of the upcoming games that use new input devices (<a href="http://www.harmonixmusic.com/guitarhero.html">Guitar Hero</a>, <a href="http://ps2.ign.com/articles/615/615498p1.html">Karaoke Revolution Party</a>, which combines karaoke with the dance pad, and a Sony music game with a synth/DJ input device). I&rsquo;m a sucker for music games (like <a href="http://www.harmonixmusic.com/amplitude.html">Amplitude</a> or <a href="http://www.konami.com/gs/gameinfo.php?id=28">DDR</a>), so I loved seeing what&rsquo;s coming down the pipe.</p>
<p>Graphics hardware also had a big impact in SIGGRAPH, with lots of courses and presentations dealing with GPUs. Somehow, even though a lot of those talks were intended for real-time rendering, I found them a lot less interesting (it seems I can read plenty GPU tricks-du-jour in books or whitepapers).</p>
<p>A big draw for a lot of people for this year&rsquo;s SIGGRAPH was undoubtedly supposed to be George Lucas&rsquo; keynote. The room was certainly packed (I can&rsquo;t even estimate the number of people there&ndash;maybe 10,000?). I&rsquo;m sorry for everybody who was there with high hopes. After some interesting and insightful keynotes by some big names in past years (like Bruce Sterling in 2004), I also had high hopes. However, as soon as it started (after a loooong award ceremony where everybody patted themselves in the back) it was clear that Lucas only agreed to show up and answer questions for a while, without having prepared any speech or insightful comments. The most interesting thing to come out of it is that Lucas wants to see games that we can talk to and they talk back. Given how ubiquitous headsets are in consoles these days, that might happen sooner rather than later.</p>
<p>The <a href="http://www.SIGGRAPH.org/s2005/main.php?f=conference&amp;p=caf&amp;s=et&amp;PHPSESSID=4db69c9a7955283459d58edd7cb9a38f">Electronic Theater</a> had a lot of good stuff. It had fewer big blockbuster movie snippets than other years and more independent, really creative shorts. Some of them were an absolute blast. If you have a chance to see the Electronic Theater DVD, make sure you check it out.</p>
<p><img alt="straw" loading="lazy" src="/siggraph-2005-quick-take/images/straw.jpg"> The <a href="http://www.SIGGRAPH.org/s2005/main.php?f=conference&amp;p=etech">emerging technologies</a> area is getting wackier and wackier every year. This year&rsquo;s top contenders for the wackiest technologies were a <a href="http://www.SIGGRAPH.org/s2005/main.php?f=conference&amp;p=etech&amp;s=etech18">straw-drinking simulator</a> that gave you the feeling of drinking different drinks just by pushing air into your mouth, and <a href="http://www.SIGGRAPH.org/s2005/main.php?f=conference&amp;p=etech&amp;s=etech24">a device that allowed people to be remote-controlled</a> by altering their sense of balance. That last one looked somewhat disturbing so I didn&rsquo;t end up trying it on myself (but it was really fun watching other people bobbing around the floor).</p>
<p>All in all, SIGGRAPH was an excellent experience again. SIGGRAPH is a window into a different world, and as game developers, we can only benefit by trying to look through that window and even participate and share some of our own experiences.</p>]]></content:encoded></item><item><title>The Quest for the Perfect Build System</title><link>https://gamesfromwithin.com/the-quest-for-the-perfect-build-system/</link><pubDate>Mon, 06 Jun 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-quest-for-the-perfect-build-system/</guid><description>&lt;p&gt;First there were punch cards, and people somehow managed to write software. Then came interactive computing with mainframes and personal computers, and people wrote even more software and become even more productive. There is no doubt that our development environments today are light-years ahead of what the computer pioneers had half a century ago. Yet I constantly see projects suffer with horrible environments that force slow iteration cycles on programmers.&lt;/p&gt;</description><content:encoded><![CDATA[<p>First there were punch cards, and people somehow managed to write software. Then came interactive computing with mainframes and personal computers, and people wrote even more software and become even more productive. There is no doubt that our development environments today are light-years ahead of what the computer pioneers had half a century ago. Yet I constantly see projects suffer with horrible environments that force slow iteration cycles on programmers.</p>
<p>I define an iteration cycle as the time elapsed between making a trivial change and being able to see the results of that change. In particular I&rsquo;m concentrating on large-scale (around one million lines of code) C++ projects, which is representative of modern PC and console games today.</p>
<p>Of course, there&rsquo;s more to fast iteration than just the speed of the build system. How quickly you&rsquo;re able to get in the game and see the results is a big factor (another reason why I wouldn&rsquo;t want to live without unit tests). The <a href="/physical-structure-and-c-part-1-a-first-look/%20">physical dependencies</a> of your program are going to affect how quickly your code builds. And if you&rsquo;re always working with a full game executable that takes forever to link, your iteration times are going to be shot (yet another reason to use unit tests!).</p>
<p>But let&rsquo;s put that aside and concentrate on the build system itself.</p>
<p>Fast iteration is more than just about time and speed. It&rsquo;s also about how you feel about the code and what you dare do with it. When things are slow and painful, you&rsquo;re going to be a lot less likely to try new things, or fix one last thing to clean up the code, or refactor something out of a header file into its own module. Over time, this is going to accumulate into cruft, hacks, and unmaintainable code. It&rsquo;s also about not breaking up the <a href="http://c2.com/cgi/wiki?MentalStateCalledFlow">flow</a>, the mental state you&rsquo;re in while you&rsquo;re writing software. Interruptions of more than just a few seconds are much more detrimental than their time value alone.</p>
<p><img alt="construction" loading="lazy" src="/the-quest-for-the-perfect-build-system/images/construction_2.jpg"> When you add <a href="/stepping-through-the-looking-glass-test-driven-game-development-part-1/">test-driven development</a> to the mix, fast iteration becomes even more crucial. With test-driven development, you end up doing micro-cycles of modify-compile-test, sometimes several times per minute. Unless you have very fast build times, you&rsquo;re dead in the water.</p>
<p>Before we go any further, let&rsquo;s crunch a few numbers. It&rsquo;s not so much to show specific improvements, but to have as a reference point going forwards. Think about the project you&rsquo;re currently working on. How long does it take to build when you modify a single cpp file (or even no files at all)? I&rsquo;ve seen projects that took over two minutes to build, and anywhere between 30 seconds to one minute is fairly typical. Let&rsquo;s say 30 seconds for this example. How often do you need to do a build? It&rsquo;s not very fast, so maybe once every 5 minutes, 8 hours a day. That adds up to a staggering 48 minutes per day, or 10% of your full work day!</p>
<p>Now reduce the build time to two seconds instead. And to make things more interesting, let&rsquo;s do a build every two minutes. That adds up to be 8 minutes per day, and, most importantly, they feel like almost instant builds, so they don&rsquo;t bring you out of the flow state. That&rsquo;s what our goal should be for a build system.</p>
<h3 id="the-goals">The Goals</h3>
<p>As I started looking into different build systems (there are a lot of them out there!), I noticed that they have very different sets of goals, and a lot of them are fairly irrelevant to my particular needs.</p>
<p>As a game developer, I work with a varied, but limited number of platforms (most of which are not supported out of the box by build tools anyway). I&rsquo;m also not planning on releasing the source code any time soon to let players compile the game in any platform, so I have no need to have a build system that automatically detects all the correct settings and does the right thing for any possible platform.</p>
<p>Some other build systems had useless features built in, such as access to version control or the ability to send emails. I consider those type of tasks to be totally beyond what the core build system should do, and I prefer to have those features in a wrapper system that does build/test/deployment of builds by calling the build system itself.</p>
<p>So what exactly do I want in a build system?</p>
<ul>
<li>Super-fast incremental builds (around two seconds). This is the key to fast iteration and I want this at almost any cost.</li>
<li>Customizable. I&rsquo;m going to be using unusual compilers and environments. I want to be able to easily set my own rules and actions and not be tied to any particular platform or compiler.</li>
<li>Correctness. I want the build system to build the minimal amount of files and still do the right thing under most normal circumstances.</li>
<li>Multiprocessor support. I also care about the speed of a full build, and with multiprocessor machines finally becoming popular, using multiple processors is a great way to speed up build times.</li>
<li>Scalable. I want all the related source code to be tied to the same build system. I don&rsquo;t want to create a separate build file for every minor tool so they build at a reasonable speed. I&rsquo;d like to simply build any target and have the minimal amount of files rebuilt.</li>
</ul>
<h3 id="the-contenders">The Contenders</h3>
<p><strong>Visual Studio .NET</strong></p>
<p>Most game developers doing Windows or Xbox development will be familiar with this build system. I&rsquo;ve been stuck with it for many years, and while things were not great in Visual Studio 6.0 and earlier versions, it became decidedly unusable when it turned into &ldquo;.NET&rdquo;. I don&rsquo;t know what happened, but I suspect that in their effort to cram all those languages under a single IDE they crippled the C++ build system even more.</p>
<p>My main gripe is how slow Visual Studio .NET is when doing an incremental build on a solution with many projects. It&rsquo;s roughly a second per project. If you have 50 projects, there goes a full minute for nothing. That&rsquo;s simply unacceptable, so I&rsquo;ve always had to work around it by creating many solutions with the minimum amount of projects necessary, or keeping the dependencies in my head and forcing builds by hand. Alternatively you could throw all the code in a couple of projects instead of breaking it up into many different ones, but that&rsquo;s like jumping off a cliff to avoid being stung by a bee.</p>
<p>Because Visual Studio mixes the build system with the visual representation of the files, large solutions are not only slow to build, but are a positive pain to work with, making browsing the source code extremely difficult.</p>
<p>The problems with Visual Studio don&rsquo;t end there. The solution and project files are a pain to generate, they&rsquo;re full of magical GUIDs and references to the registry, and they&rsquo;re extremely verbose. The .NET framework offers an API to create those files, but the fact remains that they&rsquo;re much more complex to create than any of the other build systems.</p>
<p>If you don&rsquo;t generate the project files by hand, you soon enter configuration hell. Anybody who&rsquo;s had to make sweeping changes to lots of projects with multiple configurations through the IDE will know what a painful process I&rsquo;m talking about.</p>
<p>Some of my other complaints are not being able to easily set the build order for different projects (it appears to be determined by the order in which they appear in the solution file), or the fact that setting a dependency between two projects forces an implicit linking.</p>
<p>All in all, Visual Studio seems very well suited to small, toy projects. Projects with just a couple of libraries and a few thousand lines. Anything bigger than that and it becomes an exercise in frustration.</p>
<p>On the bright side, it is possible to use &ldquo;makefile projects&rdquo; in Visual Studio, which completely bypasses Visual Studio&rsquo;s own build system and simply calls an external command to build the project. Visual Studio also offers a command-line line interface, so at least it is possible to do builds from the command line without launching the IDE. Finally, there are some <a href="http://www.workspacewhiz.com/FastSolutionBuild/FastSolutionBuildReadme.html">third-party plug-ins</a> that can speed up the dependency checking, which can help with some of the problems (unfortunately, FastSolutionBuild doesn&rsquo;t seem to have a command-line interface, which renders it useless for my needs).</p>
<p>Other third-party add-ons like <a href="/how-incredible-is-incredibuild/">Incredibuild</a> claim to speed up full builds, but they do so at the expense of incremental build speed, which I consider much more important.</p>
<p><strong>Make</strong></p>
<p>Make is the granddaddy of all the build systems. With a distinguished history of over 20 years, it has certainly proved its worth in the real world by building hundreds of thousands of projects over the years.</p>
<p>But make is <a href="http://www.scons.org/cgi-bin/wiki/FromMakeToScons">far from perfect;</a> otherwise there would be no need for other build systems. However, things are not as bad as people make them out to be, especially with modern versions of make (<a href="http://www.gnu.org/software/make/">GNU make</a> for example). The lack of portability is not an issue for us because we can just trivially write a new makefile, or a variant, for every platform we support.</p>
<p>The claims about make not being scalable are more serious. The article <a href="http://www.canb.auug.org.au/~millerp/rmch/recu-make-cons-harm.html">&ldquo;Recursive Make Considered Harmful&rdquo;</a> certainly did much harm to make&rsquo;s reputation. Specifically, that paper claims that it&rsquo;s very hard to get the order of recursion right because using recursive make has no global project view. I think that&rsquo;s only true if you&rsquo;re dealing with self-modifying source code files or autogeneration of source code. If that&rsquo;s not the case, I can&rsquo;t see how the order of recursion can matter at all as long as the dependencies are met.</p>
<p>As for the claim that make is slow, let&rsquo;s put that off until we compare it to the other build systems.</p>
<p>Personally, I really like make. It&rsquo;s small, clean, and elegant. It does one thing and it does it very well. It&rsquo;s easy to extend and modify. At first I was surprised that make didn&rsquo;t do implicit dependency checking of C files (building a C file when an included header file changes), but it fits perfectly with the simplicity of make. It&rsquo;s just a dependency graph with actions. If you don&rsquo;t tell it about a rule, it won&rsquo;t know about it. Fortunately, we can use tools like <a href="http://www.xfree86.org/current/makedepend.1.html">makedepend</a> to generate the C dependencies with extreme ease.</p>
<p>One of my only gripes with main is the silly tab syntax. The fact that action commands have to be preceded by a tab character is awkward and out of place today, but it&rsquo;s a small quirk I&rsquo;m willing to adapt to. Fortunately gnu make&rsquo;s error messages are very clear and it even asks &ldquo;Did you forget to put a tab before the command?&rdquo;</p>
<p><strong>Jam</strong></p>
<p><img alt="construction" loading="lazy" src="/the-quest-for-the-perfect-build-system/images/construction_1.jpg"> <a href="http://www.perforce.com/jam/jam.html">Jam</a> was born an an improved make. It tried to keep all the good things about make and fix all the problems. And to a large extent, it succeeded.</p>
<p>Like make, Jam is small and easily portable. It deals better with inter-project dependencies by avoiding recursive Jam invocations (while still allowing individual sections to be built separately). The Jam language, even though it&rsquo;s still fairly restrictive, is more expressive than make and it&rsquo;s easier to write complex functionality.</p>
<p>One of the main differences from make is that Jam actually provides a fair amount of base functionality in its Jambase file. Jam out of the box knows about some of the most popular development environments and languages (including implicit dependency checking for C/C++ files), so it simplifies the build files for the simple cases. In the other cases, you can add your own rules and actions very easily.</p>
<p>I find it funny that while Jam fixes make&rsquo;s weird tab requirement, it adds its own &ldquo;space semicolon&rdquo; weird command terminator (although I know some programmers who think that &ldquo;space semicolon&rdquo; is the one and true way). Either way, it really doesn&rsquo;t matter since it&rsquo;s such a small thing.</p>
<p>Jam also has spawned some forks that add extra functionality but are fully backwards compatible: <a href="http://freetype.sourceforge.net/jam/">FTJam</a> and <a href="http://www.boost.org/tools/build/jam_src/">BoostJam</a>.</p>
<p><strong>Scons</strong></p>
<p><a href="http://www.scons.org/">Scons</a> has been hailed as the next step in the evolution of build systems. It is supposed to be a much improved make-like system, not only written in Python, but using Python as the language used to define the build itself. Python is a fully general, object-oriented language, so it&rsquo;s extremely expressive. It also has the advantage of being a well-established language with a great set of documentation, debuggers, and tools, which can make creating and debugging complex build scripts easier.</p>
<p>Scons also claims to be extremely accurate when it comes to determining what files need to be built. It doesn&rsquo;t rely in the time stamp for a file, but it uses the MD5 signature instead (a type of checksum approach). Another very intriguing feature I didn&rsquo;t get around to testing is the network cache of built object files.</p>
<p>Walking into this test I was a bit afraid of what I might find. I had read some reports of several people having problems with Scons performance on large data sets. However, the latest version (0.96.90), released just a couple of months ago, is supposed to have some performance improvements.</p>
<h3 id="the-method">The Method</h3>
<p>As a test, I decided to run each of the different build systems on the same codebase. Instead of using some real-world codebase, with its own set of quirks and problems (and the difficulty of easily building it with the different systems), I wrote <a href="/wp-content/uploads/bin/generate_libs.py">a script</a> to generate a simple C++ codebase. The code structure is based on what I expect to see in my own projects with many different projects. The physical dependencies in the generated codebase are extremely well contained, and header files never include other header files. Real code bases would have more complicated dependencies and would make the tendencies we see here even more exaggerated.</p>
<p>The specific parameters I used for this test were:</p>
<ul>
<li>50 static libraries</li>
<li>100 classes (2 files per class, .h and .cpp) per library</li>
<li>15 includes from that library in each class</li>
<li>5 includes from other libraries in each class</li>
</ul>
<p>This is by all accounts still a small or at most medium-sized codebase. A full game engine and tools can easily become much larger than this.</p>
<p>Thinking back, I really should have done the test with at least 100 libraries, not 50, because all my libraries have an extra associated project for unit tests. No big deal. I don&rsquo;t think it would have changed the results very much. The important thing was to get enough code to make measurements noticeable (if we just build 10 files every build system is going to be really snappy).</p>
<p>For each of the build systems, I measured three operations:</p>
<ul>
<li>Full rebuild. Compiling the full source code for the first time. I didn&rsquo;t expect this time to change much at all from build system to build system or even across platforms. I was quite wrong!</li>
<li>Incremental build: Doing another build without any changes. This is the really interesting measurement that will tell us a lot about potential for fast iteration.</li>
<li>Incremental build on a single library: Doing a build of a library without any changes.</li>
</ul>
<p>I did the measurements in both Linux (2.6 kernel) and Microsoft Windows XP for different systems. Clearly some build systems only run in one platform (Visual Studio). But I decided to run some of the other build systems under Windows as well to provide a more fair comparison.</p>
<p>The specific hardware I ran these tests in is not as important since all we&rsquo;re comparing are their relative merits. But for the curious it&rsquo;s a P4 2.8 GHz CPU with hyperthreading, 2GB of fast RAM, and a 7200 rpm EIDE hard drive. The most important part is that I had enough memory to prevent thrashing.</p>
<p>GNU make, Jam, and Scons all support parallel builds. While it won&rsquo;t speed up incremental builds any, this can reduce the time for full builds dramatically. Since this test was done in a single-CPU machine (and the primary measure was incremental builds), I restricted all the builds to use a single process.</p>
<h3 id="the-results">The Results</h3>
<table>
	<thead>
			<tr>
					<th>System</th>
					<th>Compiler</th>
					<th>Platform</th>
					<th>Full build</th>
					<th>Incremental</th>
					<th>Incremental lib</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Visual Studio</td>
					<td>VC++</td>
					<td>Windows XP</td>
					<td>7m 28s</td>
					<td>0m 54s</td>
					<td>0m 4s</td>
			</tr>
			<tr>
					<td>Make</td>
					<td>g++</td>
					<td>Linux</td>
					<td>2m 21s</td>
					<td>0m 2.4s</td>
					<td>0m 0.0s</td>
			</tr>
			<tr>
					<td>Jam</td>
					<td>g++</td>
					<td>Linux</td>
					<td>2m 42s</td>
					<td>0m 1.6s</td>
					<td>0m 0.1s</td>
			</tr>
			<tr>
					<td>Jam</td>
					<td>VC++</td>
					<td>Windows XP</td>
					<td>6m 52s</td>
					<td>0m 3.1s</td>
					<td>0m 0.3s</td>
			</tr>
			<tr>
					<td>Scons</td>
					<td>g++</td>
					<td>Linux</td>
					<td>5m 31s</td>
					<td>1m 02s</td>
					<td>0m 16s</td>
			</tr>
			<tr>
					<td>Scons</td>
					<td>VC++</td>
					<td>Windows XP</td>
					<td>8m 02s</td>
					<td>0m 55s</td>
					<td>0m 8s</td>
			</tr>
	</tbody>
</table>
<p>We can make lots of very interesting observations from this table.</p>
<p>First of all, it confirms what I had seen all along, that Visual Studio is horrible for incremental builds with many projects. My off-the-cuff estimate of one second per project ended up being extremely accurate (54 seconds for 50 projects). That&rsquo;s simply not acceptable for me.</p>
<p>As I feared, Scons, failed the fast iteration test as well. It actually ended up being slower than Visual Studio in all accounts, even for individual library rebuilds. It might do the &ldquo;right&rdquo; thing under all conditions, but frankly, that&rsquo;s not a price I&rsquo;m willing to pay to get absolutely correct results. I really don&rsquo;t think I encounter any situation in everyday work in which Scons would do the right thing and make or Jam wouldn&rsquo;t.</p>
<p>At this point, I was afraid that I just wasn&rsquo;t going to be able to get the type of iteration I wanted out of file-based, compiled languages. Fortunately that&rsquo;s not the case. Both make and Jam do a great job and fall in the range of what I consider acceptable (around a couple of seconds).</p>
<p>There are two interesting observations to be made about full build times from the chart above. First of all, Scons with g++ under Linux is twice as slow as Jam or make for a full rebuild. I find that extremely surprising. Although I guess that&rsquo;s the extra minute of dependency checking plus some extra overhead of its own. I tried some of the <a href="http://www.scons.org/cgi-bin/wiki/SconsRecipes">suggestions to get faster Scons builds</a> (by trading off accuracy for speed), but they just improved incremental build times by a couple of seconds. Clearly, Scons needs to do some catching up before it can play with the big boys.</p>
<p>The other one is comparing g++/Linux with VC++/Windows XP. Jam is over twice as slow with VC++/Windows XP than it is with g++ under Linux. Is it Windows XP or is it Visual C++? I don&rsquo;t know. It would be interesting to try the experiment with g++ or some other compiler under Windows and see if the times are reduced at all. I suspect the Windows file system might have something to do with that.</p>
<h3 id="conclusion">Conclusion</h3>
<p>This little experiment cleared up a lot of doubts for me. I&rsquo;m ready to ditch Visual Studio as a build system and replace it completely with Jam or make. Make is a simpler but Jam probably edges it out because it&rsquo;s a bit nicer, it doesn&rsquo;t have any recursive problems, and the default functionality is pretty handy. It&rsquo;s hard to go wrong with either one.</p>
<p>Since most programmers still expect to work from within the Visual Studio IDE, you can easily create a &ldquo;makefile&rdquo; project type and hook it up to the build system of your choice.</p>
<p>One interesting idea that came up during this research in the <a href="http://scons.tigris.org/servlets/SummarizeList?listName=users">Scons mailing list</a> is that of a background process that monitors which files change and updates dependency graphs on the fly. So whenever you initiate a build, all the work has already been done and the build can start right away. A variation on this idea that has been brought up in some TDD mailing lists is that of the build system not just computing dependencies in the background, but actually attempting to compile the code and run the unit tests in the background. If any of the tests fail, they can even be highlighted in the source code editor. Sort of like an on-the-fly, smart code checker on steroids.</p>
<p>Of course, we could also choose a language that has much smaller build times. I haven&rsquo;t worked on a large-scale C# project yet, but the small tools I&rsquo;ve created have impressed me with how fast the iteration can be. The same can be said for scripting languages such as Python or Lua. Unfortunately, we&rsquo;re stuck with C++ for the foreseeable future in game development, so we better learn to deal with it the best we can.</p>
<p>For now, I&rsquo;ll be happy to stick with Jam and two-second incremental builds. Let&rsquo;s start jamming!</p>
<p><a href="/wp-content/uploads/bin/generate_libs_py.txt"><img alt="icon" loading="lazy" src="/the-quest-for-the-perfect-build-system/images/script.png"> generate_libs.py</a></p>
]]></content:encoded></item><item><title>Book Review: Pair Programming Illuminated</title><link>https://gamesfromwithin.com/book-review-pair-programming-illuminated/</link><pubDate>Wed, 18 May 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/book-review-pair-programming-illuminated/</guid><description>&lt;p&gt;Pair programming really needs to be experienced to be fully appreciated. Just a few years ago, I loved my single office and I was completely against the idea of spending all my time programming with somebody else sitting at the same computer. Today I advocated using pair programming at work and I gladly gave up my office to work in a pair-programming lab alongside the whole team. Funny how things change.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Pair programming really needs to be experienced to be fully appreciated. Just a few years ago, I loved my single office and I was completely against the idea of spending all my time programming with somebody else sitting at the same computer. Today I advocated using pair programming at work and I gladly gave up my office to work in a pair-programming lab alongside the whole team. Funny how things change.</p>
<p><a href="http://www.amazon.com/Pair-Programming-Illuminated-Laurie-Williams/dp/0201745763%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201745763"><img loading="lazy" src="/book-review-pair-programming-illuminated/images/51TXKD0A6VL._SL160_.jpg"></a></p>
<p>For the last few months we&rsquo;ve been doing <a href="http://pairprogramming.com/">pair programming</a> <a href="http://highmoonstudios.com/index.cfm">at work</a>. And not just pair programming, but full extreme programming with test-driven development, continuous integration, collective code ownership, customer-driven stories, team co-location, etc. It has been a fascinating experience and it has been working out better than I even imagined.</p>
<p>I felt that all the extreme programming books I had read just touched on the subject but were light on the specifics. What&rsquo;s more, it&rsquo;s one thing to read about it, and something completely different to actually do it. Once we started doing it, there were some very basic questions that immediately popped up: What do we do with an odd number of people? How often should we rotate pairs? How are pairs formed? How often should we be switching drivers? Is it normal to be exhausted after several hours of pairing? etc, etc, etc. With questions like that in mind, I decided to pick up a copy of <em>Pair Programing Illuminated</em>. I was hoping it would provide me with the tips and experience of veteran pair-programmers and jump-start our experience.</p>
<p>Unfortunately, it failed in that respect.</p>
<p>Pair programming really needs to be experienced to be fully appreciated. Just a few years ago, I loved my single office and I was completely against the idea of spending all my time programming with somebody else sitting at the same computer. Today I advocated using pair programming at work and I gladly gave up my office to work in a pair-programming lab alongside the whole team. Funny how things change.</p>
<p>First I started to warm up to the idea by observing how useful it was to sit down with someone and work with them on a piece of code, either debugging it or working through the initial design. Then it finally hit me when I realized that most of the problems that we have as programmers are not due to lack of skill or technology, but rather to lack of communication. Two programmers who communicate well and work very closely with each other will get a lot further than two people who shut themselves in their office, refuse to talk, and are hostile about anybody touching their code. When you only have a couple of people, it might not matter. But as teams grow and we have eight, ten, or more programmers, then communication becomes a much bigger issue.</p>
<p><img alt="tandem" loading="lazy" src="/book-review-pair-programming-illuminated/images/tandem.jpg"> But pair programming goes much further then just increased communication. It spreads knowledge through the team like wildfire. And that knowledge is not just of the code you&rsquo;re writing, but also programming languages, design approaches, standards, tools, debugging techniques, etc.</p>
<p>Pair programming is also a key step towards having collective code ownership: code that everybody feels is his or her own and is willing to modify whenever it&rsquo;s necessary. I&rsquo;ve said it many times and I&rsquo;ll say it again: the quality of a code base is directly related to how easy it is to modify. The more people feel that they know what&rsquo;s going on, the more willing they will be to modify it whenever it&rsquo;s necessary (and it&rsquo;s much better to modify it in small steps than to take a huge hit and try to do a huge modification at once). The main ingredient of a healthy, easily modifiable codebase is unit tests, but that&rsquo;s a whole other story.</p>
<p>Another consequence of pair programming is the reduction of sloppy or bizarre or just plain wrong code. It&rsquo;s a lot harder for horrible code to happen when two people are at the computer writing something. Whenever the driver starts getting lazy and writing sloppy code, the other person immediately asks &ldquo;What the hell are you doing? Shouldn&rsquo;t we be doing this instead?&rdquo; That&rsquo;s usually enough to spur the driver into doing the right thing. Otherwise, he can always pass that keyboard and say &ldquo;Fine, you do it.&rdquo; I&rsquo;ve been on both the giving and the receiving end of that situation, and it really works. In the end, you end up with a much better code base.</p>
<p>Finally, a consequence of pair programming that should not be underestimated is that it really fosters team spirit. Sometimes it&rsquo;s hard to see that we&rsquo;re all in the same team working towards the same goal. Extreme programming helps a lot in this regard, but pair programming helps a huge amount to get close and personal with your teammates and get to know them a lot better.</p>
<p>All right, going back to the book, where does it fit in? It has a fairly narrow focus, but somehow it tries to appeal to many people. In the introduction, they claim they are targeting developers who are thinking of trying pair programming (or convincing their bosses to do so), developers currently doing it, managers, QA, and even educators! I&rsquo;m afraid that they over-reached a bit and spread themselves too thin on the ground.</p>
<p>The book is divided in four parts:</p>
<p><strong>Part 1: Benefits of pair programming and how to sell it to your bosses and organization.</strong> This is the best-developed part, and this is where the strength of the book really is. Unfortunately, that&rsquo;s not what I was looking for since we had already sold the idea of pair programming, but it could be useful for people hoping to roll it out in their organizations.</p>
<p><a href="http://www.cenqua.com/pairon/"><img alt="pairon" loading="lazy" src="/book-review-pair-programming-illuminated/images/pairon.jpg"></a> Of most interest are the studies that make a business case for pair programming and show how it really is not a wasteful use of resources. Just recently I was telling a friend how I was doing pair programming at work and his first comment was &ldquo;Wow! I can&rsquo;t imagine us doing that for budget/time-constraint reasons, but that sounds interesting.&rdquo; But the whole point of pair programming is that it&rsquo;s supposed to be better in the long run (and &ldquo;long run&rdquo; can be as short as a few months, and certainly less than one project cycle). This part will give you ammunition to debate this point.</p>
<p><strong>Part 2: Getting started.</strong> This is what I really wanted to read a whole book about. It covers some things like the work environment and pair rotation. Unfortunately, it&rsquo;s way too short and elementary. It covers a few of the basics and quickly moves on. This leaves the door wide open for another book on pair programming. If anybody knows of one that covers this topic, let me know.</p>
<p><strong>Part 3: Tips and tricks.</strong> This section is completely forgettable. The book spends almost 100 pages (out of a slim total 260 pages) discussing different pair personalities: introvert-extrovert, introvert-introvert, gender and race issues, etc. Frankly, I didn&rsquo;t get a single thing out of this section, which is very disappointing.</p>
<p><strong>Parts 4 and 5: Miscellaneous stuff and case studies.</strong> I guess the book had to be bulked up a bit more, so it dedicates a chapter to extreme programming (go read <em><a href="http://www.amazon.com/exec/obidos/ASIN/0321278658/ref=nosim/gamesfromwith-20">Extreme Programming Explained</a></em> instead) and another to <a href="http://collaboration.csc.ncsu.edu/laurie/Papers/dissertation.pdf">Collaborative Software Process</a>. Not much else of interest here either.</p>
<p>Given the lack of literature in pair programming, the book is definitely worth a quick read if you&rsquo;re thinking of rolling out pair programming in your company. Part 1 will give you some good arguments to discuss with your managers and ease their fears. Otherwise, if you&rsquo;re already doing pair programming there really isn&rsquo;t much of value. It&rsquo;s maybe worth a quick leafing through, but that&rsquo;s about it.</p>
<p>In any case, if you haven&rsquo;t tried pair programming, I really encourage you to give it a try. You don&rsquo;t need to make it a sanctioned activity in your company. As long as you have somebody else willing to try it, you can both try the experiment of doing pair programming with each other working on both your tasks. You might be surprised that you manage to do both sets of tasks in the same amount of time it would have taken before, but with better quality, and, most importantly, you had a really good time in the process.</p>]]></content:encoded></item><item><title>The Winds of Change</title><link>https://gamesfromwithin.com/the-winds-of-change/</link><pubDate>Sun, 08 May 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-winds-of-change/</guid><description>&lt;p&gt;E3 is just around the corner, so we can expect to finally get the official announcements of Microsoft&amp;rsquo;s next-generation console, and maybe even Sony&amp;rsquo;s. That will mark the official transition into the next generation. And this is not just another console generation transition. This time it&amp;rsquo;s bigger. Much bigger.&lt;/p&gt;</description><content:encoded><![CDATA[<p>E3 is just around the corner, so we can expect to finally get the official announcements of Microsoft&rsquo;s next-generation console, and maybe even Sony&rsquo;s. That will mark the official transition into the next generation. And this is not just another console generation transition. This time it&rsquo;s bigger. Much bigger.</p>
<p>The underlying current at this year&rsquo;s GDC was the transition to the next generation of platforms. The change was in the air. It wasn&rsquo;t just the topic of the talks, but it was also underlying the questions asked, the technologies shown in the expo, and even the conversations at lunch. It influenced every activity and message. If it wasn&rsquo;t because of what was said, it was because of what was left out, or what was put on hold &ldquo;for a few more months.&rdquo;</p>
<p>E3 is just around the corner, so we can expect to finally get the official announcements of Microsoft&rsquo;s next-generation console, and maybe even Sony&rsquo;s. That will mark the official transition into the next generation.</p>
<p><img alt="tornado" loading="lazy" src="/the-winds-of-change/images/tornado_warning.png"> And this is not just another console generation transition. This time it&rsquo;s bigger. Much bigger. Certainly much bigger than the PSX to PS2 console transition we went through five years ago. Maybe even of the same caliber as the transition from 2D to 3D that we saw 10 years ago. The changes that are about to happen affect more than the hardware we develop for. They&rsquo;re going to affect how we develop games, how we organize ourselves, how we sell games, what type of games we make, and even how we think about games. Winds of change indeed.</p>
<p>These are the major changes I see coming.</p>
<h3 id="content-generation">Content generation</h3>
<p>As the consoles become more powerful, we can create much more detailed environments, and players are going to expect that. Whereas it took someone a day to create a <em>Doom 1</em> level that was roughly in a shippable state, now it takes someone several weeks to create just some of the geometry that is in a room in one of those levels. The team sizes, especially on the content creation side, are going to balloon, and soon teams numbering in the hundreds are going to be commonplace.</p>
<p>Large volumes of content aren&rsquo;t just going to affect team sizes. We&rsquo;re already struggling to deal with the amount of content we&rsquo;re generating today, so we better get ready for the demands of tomorrow. A smooth, fast, robust, and efficient asset pipeline is going to be of prime importance. Probably more so than fancy tech and clever algorithms. The games that are going to stand out from the crowd from the point of view of visuals and polish are the ones with really good asset pipelines that allowed their content creators to iterate over and over and come up with something very close to what they were thinking. Tech-centered teams might have some impressive algorithms under the hood, but the resulting product is going to pale in comparison to their competitors.</p>
<p>The whole topic of asset pipelines is very dear to my heart. I previously wrote about the <a href="http://www.convexhull.com/articles/gdmag_content_pipeline.pdf"><em>MechAssault</em> asset pipeline</a>, and I&rsquo;ve changed my mind about several things since then. Adding the demands of next-generation content is going to make this topic even hotter.</p>
<p>From a technical point of view, we also have to consider the rebirth of procedural content. This is something we had considered in the previous console generation (and quickly dismissed), but this time it&rsquo;s going to make much more of an impact. In a machine that can render a gorgeous scene that fully fits in memory, we&rsquo;re going to need to have either an amazing streaming system, or great procedural content creation (or both!). Will Wright drove this point home in his talk about his new game, <a href="http://www.gamingsteve.com/archives/2005/03/pictures_of_wil.php"><em>Spore</em></a>.</p>
<p>Alternatively, maybe we&rsquo;ll see a more clear distinction in what paths games take. Some games are trying to follow movies in the experience they offer: they are short (8-10 hours or less), full of new content, and giving players totally new experiences throughout the game. These are what I call &ldquo;interactive experiences.&rdquo; Then we have the &ldquo;real&rdquo; games, or toys. These are not a content showcase, but a game, with some rules and some variations, and lots of interaction with the player. This is the category of <em>Sim City</em>, <em>Amplitude</em>, or even sports or driving games. Games like <em>Grand Theft Auto</em> fall in an intermediate category because they straddle both types of games (mostly a toy sandbox with a story bolted on top). The point is, the more difficult or labor-intensive content creation becomes, the more we&rsquo;re going to see this divide.</p>
<h3 id="development-model">Development model</h3>
<p>Next-generation games are going to need large number of people during production, but pre-production will still require only a small number of people. That&rsquo;s the case today, but this trend will be exaggerated further.</p>
<p>Up until now, small companies with only one or two projects at once just put up with it and didn&rsquo;t fully take advantage of everybody during pre-production. But will they be able to keep doing that now when they need to staff up to 100 people per project during production? If they staff up, how are they going to continue in business between projects? Does everybody need to grow to a size of 200-300 people to have multiple projects going on at once and smooth out the production spike needs?</p>
<p><img alt="Hollywood" loading="lazy" src="/the-winds-of-change/images/hollywood.jpg"> One alternative that has been banded about for the last couple of years is the movie industry model. Game companies could do pre-production with a small number of people, and then assemble a team just for the duration of one project. There are some among us (<a href="http://pc.gamespy.com/articles/608/608237p1.html">especially from the UK</a>) who will say that that&rsquo;s already happening, just unofficially, with companies regularly laying people off after a game ships (see recent <a href="http://www.thehollywoodreporter.com/thr/columns/video_games_display.jsp?vnu_content_id=1000884458">Oddworld</a> news after completing <a href="http://www.amazon.com/exec/obidos/ASIN/B0006I5I58/ref=nosim/gamesfromwith-20"><em>Stranger&rsquo;s Wrath</em></a>).</p>
<p>Personally, I really dread this development model. Not only does it mean that we&rsquo;ll lack a stable paycheck (and probably have even more emphasis on crunch periods), but it also means that the industry is going to cluster around a few central locations. In the US that will most certainly be Los Angeles, San Francisco, and maybe one other city. This is necessary to have a readily available talent pool, but it&rsquo;s really a bummer for those of us who&rsquo;d like to live elsewhere. Not like there are many companies in remote locations, but today you can choose to work in places like <a href="http://firaxis.com/">Maryland</a>, <a href="http://www.epicgames.com/">North Carolina</a>, <a href="http://cyberlore.com/">Western Massachusetts</a>, or <a href="http://www.gearboxsoftware.com/">Texas</a>. Tomorrow we might not have that luxury.</p>
<p>Outsourcing went from being something that other industries talked about a few years ago, to something that we now accept as fairly common for art resources or cinematics. Outsourcing is a great way of flattening the curve of necessary resources, so I fully expect it to become the norm. Anything that can be outsourced will be. And a few things that can&rsquo;t be will also be outsourced. For now that means cinematics, static geometry, some animations, music and some sound, and maybe some level layout.</p>
<p>Is outsourcing going to affect programming? I don&rsquo;t think so right now. The closest thing we have to outsourcing is middleware, which is also a trend that is going to continue to grow. Especially if companies want to hit the ground running for a large production project, it makes total sense to use as much middleware as possible. Just look at how many developers are flocking to the Unreal Engine 3. It&rsquo;s a very good set of technology and Epic managed to position itself in the right place at the right time (i.e. console generation transition).</p>
<h3 id="multiprocessors">Multiprocessors</h3>
<p>This is undoubtedly going to be the biggest architecture change we&rsquo;ve seen in a long while: multiple processors.</p>
<p>We all know that writing threaded programs is difficult. But this is something that goes beyond making your program thread-safe; it&rsquo;s going to be a whole lot more than that. We have to deal with not just splitting the game into parallelizable parts, but we have to make sure those parts don&rsquo;t interfere with each other, and that they access main memory in a controlled, efficient way. The gap between CPU and memory speeds continues to widen, and adding multiple processors to the mix isn&rsquo;t going to help any. Games that ignore memory access patterns are going to crawl along in next-generation hardware.</p>
<p><a href="http://research.scea.com/research/html/CellGDC05/index.html">Sony&rsquo;s PS3 is going to take things even further</a>. It&rsquo;s going to use a <a href="http://arstechnica.com/articles/paedia/cpu/cell-1.ars">cell processor</a> with multiple cores, but each of the cores only has access to a very small amount of local memory. Not exactly the everyday programming model of the hardware we&rsquo;re used to.</p>
<p>To be able to take full advantage of the new hardware, we&rsquo;re going to have to change how we think about our programs. Take a snapshot of your game engine architecture, tilt your head 90 degrees, and that&rsquo;s more how it&rsquo;s going to look now. <a href="http://www.cmpevents.com/GD05/a.asp?option=C&amp;V=11&amp;SessID=4678&amp;Mgt=0&amp;RVid=0">Data-driven architectures</a> and service-oriented systems are going to dominate this new landscape.</p>
<p>Fortunately this is not just a bizarre architectural decision that console manufacturers pulled out of a hat. They are just leading the way as far as future architectures. More and more multiprocessors are becoming the norm on PCs, and both Intel and AMD have been <a href="http://www.amd.com/us-en/assets/content_type/DownloadableAssets/MC_Whitepaper_vFINAL.pdf">busy at work for several years to take advantage of this trend</a>. When you can&rsquo;t make your processors faster, cheaper, and smaller, you need to start thinking of different directions to continue improving performance. Herb Sutter <a href="http://www.gotw.ca/publications/concurrency-ddj.htm">has been talking about it for a while now</a> and he also sees it the inevitable future. So, as a programmer, don&rsquo;t be afraid to dive in and get comfortable with this architecture. Multiprocessors are here to stay, and it&rsquo;s going to be a valuable skill in the future.</p>
<h3 id="online-focus">Online focus</h3>
<p>It seems that everybody is talking online this, online that. Especially <a href="http://www.gamespot.com/news/2005/03/09/news_6120142.html">Microsoft</a>. Personally, I&rsquo;m a bit scared (and skeptical) of this trend. Even though I enjoy the occasional multiplayer game (and I&rsquo;m enjoying <a href="http://www.amazon.com/exec/obidos/ASIN/B0002BJQDY/ref=nosim/gamesfromwith-20/102-6548099-6063309"><em>Guild Wars</em></a> quite a bit right now), I certainly don&rsquo;t want to make all my gaming experience be multiplayer. I do enjoy playing against the AI, or against somebody else sitting on my couch. I certainly don&rsquo;t want to wait 10 or even 5 minutes to get everybody together before we can start a game, and I most certainly don&rsquo;t want to hear eight-year-olds yelling while I&rsquo;m trying to unwind by playing a quick game in the evening. I don&rsquo;t want that on a PC game, and certainly not on a console game, which is supposed to provide a quick gaming experience.</p>
<p>I think the PC went through that phase about five years ago, when online gaming was new and exciting and every game had to have an online component, but it has reached a more mature position now. In the console realm, online play is still pretty new, so it keeps being pushed as a big marketing point. Xbox Live was apparently a big hit (certainly much bigger than I predicted back when it was announced), but it&rsquo;s still only a tiny fraction of the market. Console manufacturers and publishers seem to think that broadband penetration is what&rsquo;s preventing more people from jumping online. Have they considered that maybe most people don&rsquo;t want to play online?</p>
<p>It always amazes me to see games whose multiplayer component is a completely different game from the single player one. They are two totally different experiences duct-taped together in one package, and usually one (or both) suffers for it. Wouldn&rsquo;t it have been better to spend the resources in one of those areas and do it well? For example, the <em>Grand Theft Auto</em> series got it right. Sure, they could have done multiplayer with capture the flag, conquest modes, etc, but that&rsquo;s not what the game is about.</p>
<p>So please, let&rsquo;s not get drawn in by the hype and let&rsquo;s keep the single player alive.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Times really are a-changing. The potential changes to the development model scare me. I hope things are not as grim as they seem right now and small game developers can stay afloat and not have to move to California to survive. On the other hand, I&rsquo;m genuinely excited about the new technical challenges and figuring out how they&rsquo;re going to affect the way we develop software. Bring on those multiprocessor machines!</p>]]></content:encoded></item><item><title>The Care and Feeding of Pre-Compiled Headers</title><link>https://gamesfromwithin.com/the-care-and-feeding-of-pre-compiled-headers/</link><pubDate>Wed, 27 Apr 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/the-care-and-feeding-of-pre-compiled-headers/</guid><description>&lt;p&gt;The great majority of the literature on warfare concentrates on topics such as formations, maneuvers, equipment, and training. What they often leave out is the importance of the supply lines. The most cunningly devised plan will be worthless in the long term if your supply lines fail.&lt;/p&gt;
&lt;p&gt;The same can be said for large-scale C++ development. Most of the books and articles out there deal with class hierarchies, object-oriented design, and mind-bending template tricks. However, when it comes down to it, a solid physical structure and good code layout will go a long way towards making all programmers productive. When the milestones near and the pressure piles on, a badly structured C++ codebase is likely to be as fatal as the cold, Russian winter was to Napoleon&amp;rsquo;s army.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The great majority of the literature on warfare concentrates on topics such as formations, maneuvers, equipment, and training. What they often leave out is the importance of the supply lines. The most cunningly devised plan will be worthless in the long term if your supply lines fail.</p>
<p>The same can be said for large-scale C++ development. Most of the books and articles out there deal with class hierarchies, object-oriented design, and mind-bending template tricks. However, when it comes down to it, a solid physical structure and good code layout will go a long way towards making all programmers productive. When the milestones near and the pressure piles on, a badly structured C++ codebase is likely to be as fatal as the cold, Russian winter was to Napoleon&rsquo;s army.</p>
<p>I&rsquo;ve already written before about how important the physical layout of a codebase can be (<a href="/physical-structure-and-c-part-1-a-first-look/%20">[1]</a> and <a href="/physical-structure-and-c-part-2-build-times/%20">[2]</a>), so I&rsquo;m not going to go over it again. This is going to be about how to use one of the many tools at our disposal to make working with a large codebase more bearable: pre-compiled headers.</p>
<h3 id="benefits-and-drawbacks">Benefits and drawbacks</h3>
<p>The only benefit of pre-compiled headers is build speed. Nothing more, nothing less. But we&rsquo;re not talking about a measly 10-15% build speed improvement. Pre-compiled headers can easily improve build times by an order of magnitude or more depending on your code structure. Clearly, it&rsquo;s a technique worth exploring.</p>
<p>The major benefit is when doing full rebuilds, but it can also help when building individual files. So it will help with the bane of the C++ programmer: iteration time (it won&rsquo;t do anything to help with link times, though).</p>
<p>What&rsquo;s not to like about pre-compiled headers? Several things, it turns out:</p>
<ul>
<li>Using a single set of pre-compiled headers exposes more symbols than necessary for many modules. That can lead to increased physical and logical dependencies.</li>
<li>Modifying a header that is part of the pre-compiled headers set will trigger a full rebuild.</li>
<li>Pre-compiled headers are not supported in every environment (although these days most compilers seem to support them to some extent).</li>
<li>Bloated pre-compiled headers can slow things down. This drawback is only from hearsay and minor anecdotal personal evidence. It sort of makes sense (with the pre-compiled header file getting huge), but I would like to see some hard data. Has anybody measured this?</li>
</ul>
<p>What&rsquo;s the best way to deal with the drawbacks in order to be able to take full advantage of the super-speedy compile times?</p>
<h3 id="how-do-pre-compiled-headers-work">How do pre-compiled headers work?</h3>
<p><img alt="canon" loading="lazy" src="/the-care-and-feeding-of-pre-compiled-headers/images/napoleon-canon.jpg"> A C++ compiler operates on one compilation unit (cpp file) at the time. For each file, it applies the pre-preprocessor (which takes care of doing all the includes and &ldquo;baking&rdquo; them into the cpp file itself), and then it compiles the module itself. Move on to the next cpp file, rinse and repeat. Clearly, if several files include the same set of expensive header files (large and/or including many other header files in turn), the compiler will be doing a lot of duplicated effort.</p>
<p>The simplest way to think of pre-compiled headers is as a cache for header files. The compiler can analyze a set of headers once, compile them, and then have the results ready for any module that needs them.</p>
<p>I won&rsquo;t get into the specifics on how to set up pre-compiled headers; that&rsquo;s very environment-specific. You might want to start with Bruce Dawson&rsquo;s great article on <a href="http://www.cygnus-software.com/papers/precompiledheaders.html">pre-compiled headers on Visual C++</a>, or the GNU documentation on <a href="http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html">pre-compiled headers with gcc</a>.</p>
<p>In very general terms, you need to specify one file (here we&rsquo;ll call it PreCompiled.h) as containing the pre-compiled headers. Anything included in that file will then become part of the pre-compiled headers cache. Then, you just need to make sure to include PreCompiled.h in each module you want to use the pre-compiled headers from. One word of warning: Visual C++ ignores all lines in the cpp file before #include &ldquo;PreCompiled.h&rdquo;, so it&rsquo;s a good habit to make sure that&rsquo;s the first line of code in each file.</p>
<h3 id="organizing-your-code">Organizing your code</h3>
<p>Unless you&rsquo;re dealing with very small code bases, you should really split up your code into multiple libraries. Not only will you get the most benefit from pre-compiled headers that way, but you&rsquo;ll reap <a href="/simple-is-beautiful/">a variety of other benefits</a>. Then set up each library with one set of pre-compiled headers.</p>
<p>The big question now is, what should go in the pre-compiled headers? You can put anything you want, really. But by observing a few simple guidelines, you can maximize your build times, which is what this is all about.</p>
<ul>
<li>Add &ldquo;expensive&rdquo; includes to the pre-compiled header file. &ldquo;Expensive&rdquo; headers are the ones that cause a cascade of other includes. Including these every time you compile a file can be quite time consuming. Some of the usual suspects are windows.h, STL headers, single includes for whole APIs, etc.</li>
<li>Add headers that are included from many different files, even if they&rsquo;re not very expensive. A header file that is included from 50 different files is almost as bad as a header file that is included once but causes 50 includes of its own. Actually, a simple file that is included in many cpp files is preferable to an expensive one included only once because recompiling one of those many cpp files is going to be fast even if the file is not in the pre-compiled headers, so iteration is still relatively fast.</li>
<li>Don&rsquo;t put any headers from the library itself in the pre-compiled headers. The only exception to this is if you have a header in your library that happens to be included everywhere (which is probably a sign that something is wrong anyway). Otherwise, every time you modify a header that was included in the pre-compiled headers file, you&rsquo;ll cause a full rebuild.</li>
</ul>
<p>So clearly, the best candidates to add to the pre-compiled header list are expensive includes that happen many times. Those are the ones that are going to get us the big speedup in build times.</p>
<p>At the same time, we don&rsquo;t want to blindly add every header used by our library. That will make regenerating the pre-compiled headers slightly slower, but, most importantly, will cause all the symbols in those headers to be available to the whole library, which is something undesirable if we&rsquo;re trying to keep dependencies to a minimum. There&rsquo;s also the potential issue of pre-compiled header bloat, but I need to confirm that.</p>
<p>Since those guidelines can be applied automatically, I decided to write <a href="/wp-content/uploads/bin/list_precomp.py">a script to report the headers that would most benefit from being in the pre-compiled headers</a> for a particular project. Instead of trying to parse the C++ code and find the chains of includes (which is not that hard but requires dealing with include paths, define statements, and almost implementing the full C pre-processor), the script uses the output of building the project with the option to show all includes (-H with gcc, /showincludes in Visual C++). The includes are conveniently formatted with indentation corresponding to the level at which they were included, so it&rsquo;s very easy for the script to determine which includes are expensive.</p>
<p>The script also accepts a string to ignore all includes which include that string in their path. That way you can easily eliminate includes from the library itself from being recommended to be part of the pre-compiled headers. Unfortunately, gcc outputs the relative path that was used to get to the include, which makes it harder to filter out specific libraries and might result in the same header being included in different ways. To prevent that, you might want to process the output first and automatically change all the paths to be absolute instead of relative (the script can&rsquo;t do it because there are no guarantees you&rsquo;re running it on the same platform as the build, let alone in the same directory of the same machine).</p>
<p>Right now the script can parse the output created from gcc and Visual C++, but it should be really easy to extend to any other compiler just by changing the regular expressions it uses to parse the include outputs.</p>
<p>As an example, I ran it the script on the output of building one of the libraries in our game engine at High Moon. These are the results:</p>
<pre tabindex="0"><code> Counting includes in includes.txt
 Cpp files:  38 (Header file, score, times included, includes caused by the header)
 (&#39;file1.h&#39;, 11590, 190, 60)
 (&#39;file2.h&#39;, 532, 532, 0)
 (&#39;file3.h&#39;, 401, 401, 0)
 (&#39;file4.h&#39;, 384, 4, 95)
 (&#39;file5.h&#39;, 330, 33, 9)
 (&#39;file6.h&#39;, 319, 11, 28)
 (&#39;file7.h&#39;, 228, 228, 0)
 (&#39;file8.h&#39;, 155, 155, 0)
 (&#39;file9.h&#39;, 151, 151, 0)
 (&#39;file10.h&#39;, 105, 35, 2)
 (&#39;file11.h&#39;, 105, 105, 0)
 (&#39;file12.h&#39;, 101, 101, 0)
</code></pre><p>Each include file is reported with a score, the number of times it is included in the program, and the number of other includes it causes. The score is the most important value about each file, which is simply the product of the number of times a file is included and the number of includes that file causes (plus one to take itself into account). So the higher the score, the more expensive an include is.</p>
<p>Interestingly, at the top of the list we have an extremely expensive include that should absolutely be added to the pre-compiled header list. That alone should make a significant positive impact in build times. The rest of the top files listed could be added, although their impact would be much lower.</p>
<p>As another example, I ran the script on the results of building my current mp3 player, <a href="http://amarok.kde.org/">Amarok</a>.</p>
<pre tabindex="0"><code> Counting includes in /usr/local/src/amarok-1.2.3/amarok/src/out.txt
 Cpp files:  764 (Header file, score, times included, includes caused by the header)
 (&#39;/usr/lib/qt3//include/qglobal.h&#39;, 46620, 630, 73)
 (&#39;/usr/lib/qt3//include/qmap.h&#39;, 3740, 110, 33)
 (&#39;/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/3.4.1/vector&#39;, 3182, 37, 85)
 (&#39;/usr/lib/qt3//include/qstring.h&#39;, 2900, 116, 24)
 (&#39;/usr/include/kconfigskeleton.h&#39;, 2280, 30, 75)
 (&#39;/usr/include/klineedit.h&#39;, 1955, 17, 114)
 (&#39;/usr/lib/qt3//include/qobject.h&#39;, 1605, 107, 14)
 (&#39;/usr/include/kapplication.h&#39;, 850, 34, 24)
 (&#39;/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/include/stddef.h&#39;, 808, 808, 0)
 (&#39;/usr/lib/qt3//include/qwinexport.h&#39;, 784, 784, 0)
 (&#39;/usr/lib/qt3//include/qptrlist.h&#39;, 560, 112, 4)
 (&#39;/usr/include/sys/types.h&#39;, 546, 42, 12)
 (&#39;/usr/local/include/taglib/taglib.h&#39;, 432, 6, 71)
 (&#39;/usr/lib/qt3//include/qnamespace.h&#39;, 420, 84, 4)
 (&#39;/usr/include/kaction.h&#39;, 396, 22, 17)
 (&#39;/usr/include/kguiitem.h&#39;, 216, 27, 7)
 (&#39;/usr/include/kdirlister.h&#39;, 189, 9, 20)
 (&#39;/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/include/limits.h&#39;, 184, 184, 0)
 (&#39;/usr/include/kfiledialog.h&#39;, 182, 7, 25)
 (&#39;/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/3.4.1/fstream&#39;, 176, 4, 43)
 (&#39;/usr/include/klistview.h&#39;, 161, 23, 6)
 (&#39;/usr/include/kactioncollection.h&#39;, 156, 13, 11)
 (&#39;/usr/include/kdiroperator.h&#39;, 144, 3, 47)
 (&#39;/usr/include/time.h&#39;, 143, 143, 0)
 (&#39;/usr/include/kpopupmenu.h&#39;, 143, 13, 10)
 (&#39;/usr/include/bits/wordsize.h&#39;, 142, 142, 0)
 (&#39;/usr/lib/qt3//include/qdir.h&#39;, 140, 28, 4)
 (&#39;/usr/lib/qt3//include/private/qucomextra_p.h&#39;, 129, 43, 2)
 (&#39;/usr/lib/qt3//include/qmetaobject.h&#39;, 129, 43, 2)
 (&#39;/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/3.4.1/iostream&#39;, 126, 3, 41)
</code></pre><p>This is a larger project than the previous example (764 cpp files), so the potential gains in build time are also much higher. The top 10 headers are all included in many files as well as quite expensive, so they would all be great candidates to add to a pre-compiled header list. Considering that it took about 10 minutes to build on my 3GHz machine, I&rsquo;d say it would definitely benefit from some judicious use of pre-compiled headers.</p>
<h3 id="multiplatform-development">Multiplatform development</h3>
<p>A lot of C++ compilers support pre-compiled headers nowadays (gcc, Visual C++, and Codewarrior for sure). Unfortunately, there are still compilers and platforms out there without pre-compiled header support that we need to deal with.</p>
<p>Usually, the code will build the same in a platform without pre-compiled header support, but it will be much, much slower because not only do we not have the caching effect of pre-compiled headers, but we&rsquo;re also including more headers in every compilation unit as part of the PreCompiled.h file. So if we&rsquo;re not careful, all the build speedups we gained using pre-compiled headers are going to come back and slow down builds in platforms without pre-compiled header support by a huge factor.</p>
<p>The best way to deal with this is to be able to turn on the pre-compiled headers on and off. For example, your pre-compiled header file might look like this:</p>
<pre tabindex="0"><code> #ifdef USE_PRECOMPILED_HEADERS
 #include &lt;string&gt;
 #include &lt;sstream&gt;
 #include &lt;iostream&gt;
 #endif
</code></pre><p>For platforms without pre-compiled header support, just don&rsquo;t define USE_PRECOMPILED_HEADERS. Clearly, for this to work every cpp file needs to include all the header files it needs to, independently of whether they&rsquo;ve been included in PreCompiled.h or not. This is not a bad habit to get in anyway, because it makes dependencies more explicit and it doesn&rsquo;t slow the build down any (because all those header files are already in the pre-compiled headers, so they&rsquo;re free).</p>
<p>Having the ability to turn it on and off also allows us to do builds sometimes without relying on pre-compiled headers. This might be useful if we want to verify that files can compile on their own or if we want to generate lists of includes to feed to the script described earlier to find good candidates for adding to the pre-compiled header list.</p>
<h3 id="maintenance">Maintenance</h3>
<p>Pre-compiled headers are mostly fire and forget. You set them up once with the big offenders and leave them be. However, the more a library changes, the more it might benefit from an update of the pre-compiled headers. Whenever a library feels like it&rsquo;s building slowly, you should see if there are any obvious headers that should be added to the pre-compiled header list.</p>
<p>That&rsquo;s one reason I like to display the build times for each library (in my case, I like to include unit test times as well). It&rsquo;s too easy to let a library build more and more slowly over time without ever realizing it. It&rsquo;s like the proverbial frogs taking a hot bath. But if you have hard data, you can see that the library is now taking 10 seconds to build, but last week it was only taking 6 seconds (yes, it doesn&rsquo;t seem like much, but when you have 50+ libraries it quickly adds up!). For bonus points, I want my automated build system to keep historical data of build times and display a plot over time, which will make zeroing in build slowdowns much easier.</p>
<p>If you&rsquo;re interested in maintaining compatibility with other platforms, I&rsquo;d recommend doing a build with pre-compiled header support turned off every so often (once a night or even once a week), and make sure everything works fine. While you&rsquo;re at it, take a pass at the code with <a href="http://www.gimpel.com/html/pcl.htm">PCLint</a>, and you&rsquo;ll be horrified at how many dangerous things you missed.</p>
<p>There really are almost no excuses not to use pre-compiled headers in a large C++ project. If you&rsquo;re not using them, you&rsquo;re doing yourself a disservice. And if you&rsquo;re already using them, you might be able to tweak them a bit and squeeze an extra 10-20% speedup out of your builds. Whatever you do, make sure to keep those build times low to have as fast an edit-build-run cycle as possible.</p>
<p><a href="/wp-content/uploads/bin/list_precomp_py.txt"><img alt="icon" loading="lazy" src="/the-care-and-feeding-of-pre-compiled-headers/images/script.png"> list_precomp.py</a></p>]]></content:encoded></item><item><title>GDC 2005: Generation Wrap-Up in San Francisco</title><link>https://gamesfromwithin.com/gdc-2005-generation-wrap-up-in-san-francisco/</link><pubDate>Wed, 13 Apr 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-2005-generation-wrap-up-in-san-francisco/</guid><description>&lt;p&gt;This year&amp;rsquo;s GDC, for a change of pace, was held in San Francisco. It was also the last GDC dealing mostly with the current generation of consoles. Yet again, GDC managed to live up to all expectations. I walked away totally exhausted, but at the same time energized and inspired and full of new ideas.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This year&rsquo;s GDC, for a change of pace, was held in San Francisco. It was also the last GDC dealing mostly with the current generation of consoles. Yet again, GDC managed to live up to all expectations. I walked away totally exhausted, but at the same time energized and inspired and full of new ideas.</p>
<p>It seems that this year&rsquo;s <a href="http://gdconf.com/">GDC</a> came and went and somehow I never got around to writing a quick report. Part of it was due to decompressing after a very exhausting event; part of it was catching up with things at work and all the stuff going with the change to <a href="http://highmoonstudios.com/">High Moon</a>; and part of it was just due to <a href="http://www.eliteracing.com/exec/elite/Carlsbad.cfm?publicationID=4">other commitments</a> (there, now you see what a terrible runner I am). But I figured it was better late than never, so here we go.</p>
<p>I first have to comment on the location. This year&rsquo;s GDC was in San Francisco instead of San Jose like it has been for many years. I went in with an open mind thinking that San Francisco would be pretty cool but that it would have the drawback that I wouldn&rsquo;t know my way around as well as in San Jose.</p>
<p><img alt="SF" loading="lazy" src="/gdc-2005-generation-wrap-up-in-san-francisco/images/sf.jpg"> In the end, however, I felt that San Jose was a much better location. I didn&rsquo;t particularly care for the area (Market and 4th through 6th Streets). Things felt very busy and spread out, and it didn&rsquo;t have the sense of community you got in San Jose. As soon as you step out of the conference center you become just another person in the street, but in San Jose, just about everybody walking around in the evening was a game developer. Fortunately, we&rsquo;re going back to San Jose next year. Yay! I missed not going to <a href="http://www.bellamia.com/">Bella Mia</a> this year (and I didn&rsquo;t even make it to <a href="http://www.thestinkingrose.com/sf/sf.htm">The Stinking Rose</a> as I had hoped to).</p>
<p>Clearly, the underlying theme of GDC 2005 was the console generation change. I started writing a few thoughts about it, but it&rsquo;s such a big topic that it deserves a whole article on itself. I&rsquo;ll put it up this weekend. For now suffice to say that it&rsquo;s going to be a huge change. The PSX to PS2 console change was nothing compared to this. Fasten your seatbelt because it&rsquo;s going to be one bumpy ride!</p>
<p>Interestingly, another subtle theme brought up in many talks, either directly or indirectly, was customizable gaming. Allowing players to play their own music, put their own pictures in the game, skin their interfaces, control how their characters evolve, choose the layout for their buildings, and create custom paint jobs for their cars. That&rsquo;s nothing new, especially in the PC world. We&rsquo;ve been doing that for years. Still, I think it&rsquo;s finally hit the big time and that&rsquo;s going to be a required feature going forward.</p>
<p>I have a friend who was playing <em>City of Heroes</em> last year. He thought the game was OK, but the part he had most fun with was actually playing around with the character creation setup. It really was amazing what you could do with your superhero characters. Maybe it was a bit too much to do before you even get attached to your character, but it certainly looked a lot more interesting than clearing another sewer of rats or beating yet another bad guy somewhere.</p>
<p>Personally, I never really cared much for game customization. Sure, it&rsquo;s fun to see your character change in an RPG, but I really couldn&rsquo;t care less how my car looked in <em>Need for Speed</em>, or whether I could choose the pants for my character in a third-person action game. I think this might be a generational thing though. I grew up with TV that you had to watch when things were on, and you didn&rsquo;t even have that much choice of what was on. Now kids expect to watch what they want whenever they want to.</p>
<p>The cell phone ringtone business is huge. Something like a one-billion-dollar business. That&rsquo;s just amazing when you consider how quickly it got there. So not only are people wanting to customize their gadgets, but they&rsquo;re willing to pay for it. Tattoos and custom clothing are also huge and that&rsquo;s one way people have of expressing themselves. Even though Allard&rsquo;s keynote was a horrible waste of time, that&rsquo;s the most interesting point he made (yes, I didn&rsquo;t get a free TV, was it that noticeable? I would have still thought it was a terrible keynote, though).</p>
<p>I definitely don&rsquo;t like the trend towards seeing games as services though. Call me old fashioned, but I like my game to be in a box (or hard drive; digital distribution is even better), and I like to know it&rsquo;s going to be there when I want to go back to it. The idea of games requiring internet connections, auto-updating themselves, and blurring the distinction between single and multiplayer totally puts me off as a player (although I admit it sounds like lots of fun from a technical point of view). Case in point: <em>Half Life 2</em> was at the top of my list of games to buy, but <a href="http://www.steampowered.com/">Steam</a> simply killed it for me.</p>
<p>The highlight of the show this year was again Will Wright&rsquo;s talk. I kept telling everybody to get there early, but it totally blew my mind when I saw a line coiling around the convention center a full twenty minutes before the start of the talk. I guess the organizers got caught by surprise also. Those who know me know I can&rsquo;t stand to wait in line. But this one was well worth it. The talk was simply indescribable. Will has the most understated way of giving a talk: he doesn&rsquo;t yell, gesticulate wildly, or resort to fancy multimedia or loud music with smoke machines on the stage. Yet somehow he manages to be extremely engaging and interesting from the very beginning. I said it before and I&rsquo;ll say it again: &ldquo;I&rsquo;ll go to any talk Will gives, even if it&rsquo;s about the most uninteresting subject imaginable. Somehow, he&rsquo;ll make it interesting.&rdquo;</p>
<p>And this year was no exception. He emphasized the importance of procedural content in this next generation, and to drive the point home, he showed a demo of his latest project, <a href="http://www.gamespy.com/articles/595/595975p1.html"><em>Spore</em></a>. I thought it was extremely cool that he looked into who has experience with procedural generation of content, came across the mod scene in Europe, and recruited a team of demo-makers to prototype his game.</p>
<p>Will also emphasized the importance of customizable content and also of leveraging the content created by other users in your own game (in this case automatically, without you having to download anything). We&rsquo;re going to see a lot more of that in the next few years.</p>
<p>Other than Will&rsquo;s, what were some of the outstanding sessions this year?</p>
<p>I totally loved the Bruce Oberg&rsquo;s <a href="http://www.oberg.org/gdc2005_bruce_oberg_final.zip">talk &ldquo;The Picture Worth a Thousand Bugs&rdquo;</a> about how they manage the game state for <em>Sly Cooper 2</em> at Sucker Punch. That&rsquo;s one of those areas that I&rsquo;ve never seen implemented correctly and it&rsquo;s always a big mess of spaghetti scripts and random code all over the place. Instead, they organized into a very clean and effective dag system, which allows them to visually display the state of the game and set up game flow in a very easy way, as well as fast-forward and rewind the game state for easier bug tracking. Go read his slides now.</p>
<p>Eric Malafeew&rsquo;s talk on &ldquo;Data-Driven Programming Made Easy&rdquo; was very interesting also. That&rsquo;s a topic I&rsquo;m very interested in because of all the architectural and system consequences that it has. It&rsquo;s great to learn about how other teams solve certain problems in their games. Besides, my wife and I are huge fans of <em>Amplitude</em>, so I had to find out more what&rsquo;s behind the scenes.</p>
<p>Some of the other really solid talks were the one on the &ldquo;<em>Age of Empires 3</em> Graphics Engine&rdquo; (they had eight full-time programmers on graphics alone!!), and Matt Noguchi&rsquo;s &ldquo;<em>Halo 2</em> Content Management&rdquo; talk (any self-respecting console game should have something very much like that, including data hotloading).</p>
<p>Finally, I also attended the <a href="http://www.igda.org/qol/events.php">IGDA Quality of Life Summit</a>. There was nothing new, but it contin ues to be very necessary to keep bringing that topic up and discussing it. It saddened me to see a room packed with over 300 people across the room attending the &ldquo;infomercial&rdquo; session on the Windows Developer Day, and have only about 50-60 people in the Quality of Life session. Still, that&rsquo;s a lot more than there were at the white paper unveiling last year, so at least it&rsquo;s a positive trend.</p>
<p><img alt="SF" loading="lazy" src="/gdc-2005-generation-wrap-up-in-san-francisco/images/mcconnell.jpg"> The summit included a panel of several game developers to discuss the issue of crunch time. I was hoping to get some heated discussion going, and it seemed it was going to be that way when David Perry and Julian Eggebrecht stated that game development is all about passion and that passionate people are going to crunch and that&rsquo;s how great games are made. Just as a point of reference, David was quoted in a magazine a few years ago saying &ldquo;Never trust a programmer with a tan&rdquo;. Then somebody in the audience confronted them by asking what measurements they took to verify that crunching in their past projects actually increased productivity instead of making things worse. From there on there was a lot of humming and hand waving and back pedaling to the point that the whole panel sort of agreed that crunching is not always good or necessary.</p>
<p>It was a pleasure to actually see <a href="http://www.stevemcconnell.com/">Steve McConnell</a> speaking at the summit. Sure, my perception was colored by the fact that I finally got to meet my hero face to face and even got to chat with him briefly after his session. The point of his talk is that by improving our development practices we can develop games for less money and with less need for overtime. Of course, even if we did, some people would argue that crunch time would not go away, which is very true. The causes of overtime run a lot deeper than that. Still, it&rsquo;s a necessary first step. My main regret is that very few people got to see him, but what he had to say was very applicable to the industry as a whole. It&rsquo;s also a great trend to look beyond the games industry for solutions to our problems. Kudos to IGDA (and Hank Howie from <a href="http://www.bluefang.com/">Blue Fang Games</a> in particular) for bringing Steve to GDC.</p>
<p>GDC lived up to all expectations yet another year. I walked away totally exhausted, but at the same time energized and inspired and full of new ideas. Now it&rsquo;s time to do some more research, put them to good use, and ship a great game with them. Don&rsquo;t forget to submit your own talk ideas for near year&rsquo;s GDC to give back to the community and contribute with your own experiences!</p>]]></content:encoded></item><item><title>Stepping Through the Looking Glass: Test-Driven Game Development (Part 3)</title><link>https://gamesfromwithin.com/stepping-through-the-looking-glass-test-driven-game-development-part-3/</link><pubDate>Mon, 07 Mar 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/stepping-through-the-looking-glass-test-driven-game-development-part-3/</guid><description>&lt;p&gt;After reading the first two parts of this article, you should have enough information to strike boldly and apply test-driven development to your projects. At first you&amp;rsquo;re likely to find that the road is somewhat rough and bumpy, though. How do you break up this module into something testable? How can you prevent your tests from becoming a burden to maintain? What exactly should you test?&lt;/p&gt;</description><content:encoded><![CDATA[<p>After reading the first two parts of this article, you should have enough information to strike boldly and apply test-driven development to your projects. At first you&rsquo;re likely to find that the road is somewhat rough and bumpy, though. How do you break up this module into something testable? How can you prevent your tests from becoming a burden to maintain? What exactly should you test?</p>
<p>This third and last part will cover some tips that should help smooth out the learning curve and make you more productive from the start. We&rsquo;ll also look at some of the consequences of applying TDD to a project and what kind of things you can expect on the other side of the looking glass.</p>
<h3 id="tips-from-the-trenches">Tips from the trenches</h3>
<p>When I started doing test-driven development, I was going through the motions, following the advice from <a href="http://www.amazon.com/exec/obidos/ASIN/0321146530/ref=nosim/gamesfromwith-20">Kent Beck&rsquo;s book</a>, and there was no doubt I was getting a lot of benefit in what I was doing. However, I recently looked back at the tests I was writing back then and I was a bit shocked. They&rsquo;re quite different from what I would write today. In particular, they were not very clean, maintainable tests. These are some tips that I wish I had known when I started out.</p>
<p><strong>Use fixtures extensively</strong></p>
<p>Using fixtures (objects that automatically set and destroy some state for you for every test), is a great way to keep tests small and to the point. All the setup and shutdown code gets refactored away into the fixture and the test can deal just with the things we&rsquo;re testing. They will also make the tests much easier to refactor later on (which, if you follow TDD, you will be doing extensively).</p>
<p>Make sure your unit test framework allows you to have fixtures and that you can create them as easily as possible.</p>
<p>The rule I follow for using fixtures is the following (very similar to other XP rules about refactoring): the first time I write a test that has some setup and teardown, I just put it in the test itself because it&rsquo;s the fastest way to get the test up and running. The second time I write a test that requires a similar setup and teardown, I also put it in the test, make the test pass, and then I consider whether to fold it into a fixture or not (depending on how extensive the setup code is). The third time I write a test that needs the same code, I also put it in the test first, but then I make a fixture right away.</p>
<p>I try to never refactor tests into a fixture while I have failing tests, though. First make the tests pass, then move common code into the fixture (which is part of the test refactoring step if you remember the first article).</p>
<p><strong>Keep your tests short and simple</strong></p>
<p><img alt="alice" loading="lazy" src="/stepping-through-the-looking-glass-test-driven-game-development-part-3/images/alice3.jpg"> This one is really important. Probably the most important of all the advice in this article. So if you&rsquo;re only going to take one thing away, make sure it&rsquo;s this one.</p>
<p>When developing using TDD, you will create as much test code as production code. Sometimes as much as one and a half times as much! That code isn&rsquo;t set in stone either. Quite the contrary, it&rsquo;s supposed to be your safety net, and you&rsquo;ll be changing it and moving it around as you create new code and refactor existing classes.</p>
<p>That means that test code should be very easy to change and refactor itself. It&rsquo;s like the scaffolding around a building. It&rsquo;s not enough to make it reach places and be secure. You have to make sure you can take it down and move it around as needed.</p>
<p><a href="/simple-is-beautiful/">I&rsquo;m a big fan of simple code</a>, but it&rsquo;s extremely important that your tests should be as simple as possible. The idea is that when a test fails, you want to know right away what failed. If the test itself is 100 lines long and is full of check statements and loops, you&rsquo;ll have to resort to the debugger to find out what went wrong.</p>
<p>How do we keep the tests as simple as possible?</p>
<ul>
<li>Keep tests extremely short. I try to keep my tests under about 10 lines. Preferably less. I want something I can look at and know at a glance what it does. My favorite tests are the ones that are one or two lines long.</li>
<li>Label your tests correctly. The name of your test should tell you what it does. Don&rsquo;t call your test TestHealth (what exactly does that do?). Instead, call it DamageLowersHealth.</li>
<li>Aim to have <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=35578">one CHECK statement per test</a>. The idea here is that you want to be testing only one thing at a time. If there&rsquo;s something else to test, even if it&rsquo;s with the same inputs, write a new test. Not everybody buys into this, but it has made a huge difference in the tests I write. When I started out doing TDD I was not shy about making more complex tests with multiple CHECKs. Then, when a test failed, it wasn&rsquo;t always immediate obvious what had gone wrong. Clearly to do this effectively you need to use fixtures as described in the previous item.</li>
</ul>
<p>Here&rsquo;s an example of what I consider a bad unit test:</p>
<pre tabindex="0"><code>// BAD UNIT TEST! 
TEST (TestArmor) 
{ 
    ArmorComponent armor(100, 10); 
    CHECK_EQUALS (100, armor.Amount()); 
    CHECK_EQUALS (10, armor.RechargeRate()); 
    armor.ApplyDamage(30); 
    CHECK_EQUALS (70, armor.Amount()); 
    armor.ApplyDamage(80); 
    CHECK_EQUALS (0, armor.Amount()); 
    armor.Update(1.0f); 
    CHECK_EQUALS (10, armor.Amount()); 
    armor.Update(10.0f); 
    CHECK_EQUALS (100, armor.Amount()); 
}
</code></pre><p>It actually doesn&rsquo;t look too bad, right? It&rsquo;s not too long a test, and it doesn&rsquo;t have any nasty loops. Still, it&rsquo;s a really bad unit test. Imagine you just made some changes to some other part of the system and the fifth CHECK statement fails. Can you look at it for a second and tell me what went wrong? Probably not. Heck, I don&rsquo;t even know what the test is doing by the test name! The test is far too complex. Here&rsquo;s how it should look instead:</p>
<pre tabindex="0"><code>class ArmorFixture 
{ 
public: 
    ArmorFixture() : armor(100, 10) {} 
    ArmorComponent armor; 
};  

TEST_F (ArmorFixture, ArmorHasCorrectInitialValue) 
{ 
    CHECK_EQUALS (100, armor.Amount()); 
} 

TEST_F (ArmorFixture, ArmorHasCorrectRechargeRate) 
{ 
    CHECK_EQUALS (10, armor.RechargeRate()); 
} 

TEST_F (ArmorFixture, DamageLowersArmorByCorrectAmount) 
{ 
    armor.ApplyDamage(30); 
    CHECK_EQUALS (70, armor.Amount()); 
} 

TEST_F (ArmorFixture, DamageDoesNotGoBelowZero) 
{ 
    armor.ApplyDamage(300); 
    CHECK_EQUALS (0, armor.Amount()); 
} 

TEST_F (ArmorFixture, UpdateRechargesArmorByCorrectAmount) 
{ 
    armor.ApplyDamage(50); 
    armor.Update(1.0f); 
    CHECK_EQUALS (60, armor.Amount()); 
} 

TEST_F (ArmorFixture, UpdateDoesNotRechargePastMax) 
{ 
    armor.ApplyDamage(50); 
    armor.Update(20.0f); 
    CHECK_EQUALS (100, armor.Amount()); 
}
</code></pre><p>If a test fails right now, it should be immediately obvious what went wrong. Also notice how the largest test is only three lines long. It&rsquo;s trivial enough to see what we&rsquo;re testing at a glance.</p>
<p><strong>Keep your tests fast</strong></p>
<p>&ldquo;Unit tests run fast. If they don&rsquo;t run fast, they aren&rsquo;t unit tests&rdquo; â€“ Michael Feathers, <a href="http://www.amazon.com/exec/obidos/ASIN/0131177052/ref%3Dnosim/gamesfromwith-20"><em>Working Effectively with Legacy Code</em></a>.</p>
<p>We&rsquo;re going to have lots of unit tests. Lots of them! Thousands upon thousands, so they&rsquo;d better run fast. Think about it. If your average test takes 100 ms, if we run 5000 of them that means it&rsquo;s going to take over 8 minutes to run them! An ideal unit test should take less than 1 ms, ideally around 1 micro second or so (so 5000 tests will take less than half a second, which is a bit more acceptable).</p>
<p>What does that mean?</p>
<ul>
<li>Forget about doing file operations in your unit tests. Or at least minimize them. You probably have a stream class, so anything that requires serialization should use memory instead. Besides, accessing the disk probably means keeping data files along with the unit tests, which makes them harder to keep up to date. Still, if you have to do it for a few tests, that&rsquo;s fine. Just don&rsquo;t make a habit out of it.</li>
<li>Don&rsquo;t initialize/shutdown expensive systems in your fixtures. If you absolutely need to have a system that&rsquo;s expensive to initialize, do it once per test project (and make sure you reset it to a default state after every test).</li>
<li>Work with one library at a time. Ideally, you should only be working with the code you&rsquo;re actively changing. Pull in the minimum number of libraries you need to develop those tests and keep your build times down to a minimum to have the fastest possible iteration times. You&rsquo;ll also only need to constantly run the tests for the library you&rsquo;re working on. Once you&rsquo;ve implemented a feature you can build the whole project and run all the unit tests for all the libraries to make sure everything else is still A-OK</li>
</ul>
<p>If the number of unit tests for a single library gets overwhelming, start thinking of breaking them into suites, so you can run a subset of them while developing. Personally, I haven&rsquo;t gotten there yet, but I like to keep my libraries small and simple also, so running a few thousand tests still keeps my incremental build times to about a second or less.</p>
<p><strong>Refactoring should be just that: refactoring</strong></p>
<p>Resist the temptation to add new functionality when you&rsquo;re supposed to be refactoring. It&rsquo;s very easy. I admit it. It&rsquo;s also too easy to sneak in a few changes here and there when nobody is looking (yet another reason why pair programming is great). But resist it.</p>
<p>If you decide that you should check that the index is within range, save that for the next test. What are you going to do if a pointer is NULL, return false? Write a test. So what if it&rsquo;s a trivial test? It&rsquo;s only going to take you 10 seconds to write it, so why not? That way you keep maximum code coverage and it&rsquo;s harder for things to slip between the cracks.</p>
<p>Refactoring should be just that: changing the format and structure of the program, but not its functionality.</p>
<p><strong>Bug - Test - Fix</strong></p>
<p>Pop quiz: A producer walks through the door and tells you there&rsquo;s a bug in the inventory code. Apparently if you add two similar objects, when you remove one from the inventory, the other one disappears. You immediately realize that you were searching based on object name, not on unique ID, and you can fix it in 30 seconds. What do you do?</p>
<p>Let me answer that by asking another question: Is fixing that bug a refactoring of code, or are you changing existing behavior? What does TDD say about changing behavior/adding features? Right. You got it. Write a test first.</p>
<p>Clearly, the current tests you have are not catching that situation, so go ahead and create a test that fails because it shows that situation:</p>
<pre tabindex="0"><code>TEST (RemovingOneOfTwoSimilarObjectsRemovesOnlyOne) 
{ 
    Inventory inv; 
    GameObject potion1(&#34;Health potion&#34;); 
    GameObject potion2(&#34;Health potion&#34;); 
    inv.Add(potion1); 
    inv.Add(potion2); 
    inv.Remove(potion1); 
    CHECK_EQUAL (1, inv.ItemCount()); 
}
</code></pre><p>Once you see that test fail, then you can go and implement the fix. Now the test should be passing and everybody is happy. Check in the code and the test and you&rsquo;ll make sure that bug never comes back. This is one of the best ways of keeping your codebase in good health. Let&rsquo;s call it preventative medicine.</p>
<p><strong>Classes and tests</strong></p>
<p>When writing tests, don&rsquo;t obsess about keeping a one-to-one correlation between classes and test files (which contain many tests, of course). That&rsquo;s the way tests will start out, but I find that sometimes I have too many tests checking fairly different things, so I end up putting them in different files, even though they&rsquo;re testing the same class.</p>
<p>Could that be a <a href="http://c2.com/cgi/wiki?CodeSmell">&ldquo;smell&rdquo;</a> that the class needs some refactoring and needs to be split? Perhaps. But sometimes it just feels right to separate the tests into logical groups that way without affecting the class. Don&rsquo;t worry about it. It&rsquo;s normal.</p>
<p><strong>Private stuff</strong></p>
<p>Should you test private methods and member variables? Not everybody agrees, but I would say no. Test the public interface. That&rsquo;s what you care about, after all.</p>
<p>However, I find very useful to have access to non-public library classes. Fortunately, I keep my tests as a subdirectory of the library, so in a way they&rsquo;re almost part of the library itself. I find that having access to classes that are not exposed outside of the library is very helpful to use as mock objects or to help with other parts of the test.</p>
<p><strong>Introducing TDD</strong></p>
<p>It&rsquo;s great if you&rsquo;re psyched about TDD and want to use it in your project. What about the rest of your team, though? How should you introduce TDD in your current project? You&rsquo;re not going to convert everybody overnight, so plan on doing it incrementally.</p>
<p>First, you can start doing it quietly by yourself. Nobody is stopping you from using TDD to develop the functionality you were going to do. Check in your test code as well, but make it so it&rsquo;s not built and executed every time your code is modified. Probably a few programmers are going to notice your tests being checked in and will be curious about it. This is your chance to start seeding the idea.</p>
<p>Next, you need to get the lead programmer involved and get him on board. You&rsquo;ll need to agree that those tests should always pass and checking in code that breaks them is not acceptable. At this point, make sure the tests are executed with every automated build, and even whenever somebody modifies the code under test. It&rsquo;s important that people see the tests as a good thing and understand what they&rsquo;re doing as opposed to being things that are getting in the way. If people start commenting out tests to prevent them from failing, you know they&rsquo;re not having the desired effect.</p>
<p>Finally, assuming that everything was successful and people recognize the tests as being useful, you might want to propose using TDD at the start of a new project, or for some specific tool or library. Make sure everybody is on board with the idea, get a few copies of Kent Beck&rsquo;s book, and help educate them with your experience.</p>
<h3 id="when-all-you-have-is-a-hammer">When all you have is a hammer&hellip;</h3>
<p>Don&rsquo;t let the novelty of TDD blind you. Even though I believe that TDD is a great technique that is widely applicable to most of the code we write, there are some cases when I would not recommend TDD. It&rsquo;s important to recognize that and know when not to use it. After all, TDD is supposed to help us. Whenever it gets in the way, or the benefits we reap don&rsquo;t outweigh the drawbacks, out with it!</p>
<ul>
<li><strong>Experimental code</strong>. If you&rsquo;re just experimenting, putting together a prototype, or doing anything that is going to be thrown away, then there&rsquo;s probably little benefit to using TDD. This is what XP calls &ldquo;spikes&rdquo;: short tasks with the intent of experimenting with something to learn more about how to proceed. There&rsquo;s very little reason to use TDD in this situation.</li>
<li><strong>High-level scripting code</strong>. Chances are your game has a scripting language. How about telling your designers to write tests for their code before they write the scripts? Yeah, right! Not only would that be an exercise in futility, but it wouldn&rsquo;t be that useful (unless your scripts extend to a fairly low level). Designer scripts, by definition, are probably changing all the time and no other parts of the code directly depend on them. They should probably be relatively simple, so writing unit tests for them is not all that important.</li>
<li><strong>Don&rsquo;t test hardwired data</strong>. This goes without saying, but don&rsquo;t test the specific data values in your tests. If you&rsquo;re writing a test for a grenade weapon that deals damage within a certain radius, don&rsquo;t hardwire the specific radius in your tests, because that&rsquo;s going to be constantly tweaked until the game ships. Check the radius in your test and check against that.</li>
<li><strong>Shaders</strong>. A couple of years ago that wasn&rsquo;t a big deal because shaders were so limited. Now they&rsquo;re starting to be quite complicated and general, so maybe starting to think about TDD wouldn&rsquo;t be a bad idea. If somebody out there is doing TDD with graphics shaders, please drop me an email. I&rsquo;d love to know more about how you&rsquo;re doing it and whether it&rsquo;s useful.</li>
<li><strong>Multithreaded code</strong>. TDD uses unit tests, which means it tests very small bits of functionality in isolation. The current emphasis on multithreaded code makes it so there will be things we can&rsquo;t easily test through TDD, especially dealing with thread interactions. I haven&rsquo;t had to deal with this yet, but I&rsquo;m sure it&rsquo;s going to come up. For now, I&rsquo;ll just ignore threading issues when I&rsquo;m writing unit tests and deal with it later.</li>
</ul>
<h3 id="gui-tools">GUI tools</h3>
<p>Can we apply TDD to GUI tools? And the more important question is, even if we can, should we? Absolutely!</p>
<p>A lot of the bulk of game development goes into tools and program plug-ins. Especially now, for this next generation of consoles coming up, I&rsquo;m convinced that the asset pipeline is going to play a key role in differentiating games from each other and making the ones with a really solid pipeline stand out from the rest. Not doing TDD on tools is going to exclude a good percentage of all code developed for a game, and one of the most important parts at that.</p>
<p>There&rsquo;s enough material here for a whole other article ( <a href="http://www.amazon.com/exec/obidos/ASIN/0321227328/ref=nosim/gamesfromwith-20">or even a whole book</a>). You can also refer to the <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/">Test First User Interfaces mailing list</a>.</p>
<p>The main idea is to separate the GUI from the logic. Unfortunately a lot of GUI development tools encourage you to write your logic right in the function that handles the button pressing. Resist that temptation. Put all the logic for your tool in a separate library, and hook it up to the GUI with the minimum amount of code. This is a bit like the &ldquo;humble dialog&rdquo; technique described by Michael Feathers.</p>
<p>Keeping that separation also makes it a lot easier to provide different interfaces to your code. Maybe you want to also have a command-line only version of the tool, or maybe you want to make it into a Windows service. All that is trivial if you&rsquo;ve completely separated your GUI from your logic.</p>
<h3 id="consequences-of-doing-tdd">Consequences of doing TDD</h3>
<p><strong>Amount of code</strong></p>
<p>You should expect the overall amount of code you write to increase, maybe by as much as 100% to 150%. That&rsquo;s a lot of code. It&rsquo;s all right, though. That&rsquo;s no ordinary code. It&rsquo;s code that is looking out for the other half of your code. It&rsquo;s not code that you have to worry about architecting and dealing with complex dependencies, or anything. It&rsquo;s extremely simple, and it&rsquo;s driven by the features you implement. There&rsquo;s just quite a bit of it.</p>
<p><strong>Development speed</strong></p>
<p>What does writing all that code do to your development speed? Doesn&rsquo;t it slow things down? Yes, it will. At first.</p>
<p>Whenever you start learning a new programming language, technique, or tool, it&rsquo;s normal for your productivity to drop temporarily. You&rsquo;ve spent years honing your skills on a different technique, so switching takes a while and you need some practice.</p>
<p>In my own experience with doing TDD in a not very TDD-friendly environment and with C++ and a game engine, I will admit that it took one or two months to get to the point where I felt I was as productive as before. That&rsquo;s a fair amount of time, so I don&rsquo;t recommend switching to doing TDD towards the end of a project. Wait until the beginning of the next project, or do it if you&rsquo;re not in the critical path and you think you can afford a small productivity hit.</p>
<p>Even before you reach the point where you&rsquo;re comfortable enough with TDD to develop at the same speed as before, you&rsquo;ll already be reaping all of the benefits that TDD provides (safety net, better design, documentation, etc, etc).</p>
<p>Here&rsquo;s the interesting part, though: I claim that once you&rsquo;re comfortable with TDD and you&rsquo;ve applied it to a large amount of code, your development speed will actually be <strong>faster</strong> than it would be without TDD. So not only you get all the other benefits, but things will go faster and more smoothly. How&rsquo;s that possible? You have to write all that extra code and that takes time!</p>
<p>Think of it as a snowball (or as a <a href="http://www.amazon.com/exec/obidos/ASIN/B0002Y2XXQ/ref=nosim/gamesfromwith-20">Katamari</a>). Doing development without TDD allows you to get going pretty quickly. You take a little snowball and run with it. But as you roll it on the snow, it keep growing and growing. At first it&rsquo;s not a big deal, but eventually it&rsquo;ll start to slow you down. Eventually it&rsquo;ll become a huge ball that takes several people just to move it a small amount. At that point, you better be ready to ship the game because it&rsquo;s not going much further.</p>
<p>Doing TDD, on the other hand, is like starting out with a medium size ball (say, a foot or two in diameter), but it&rsquo;ll never get significantly larger than that. You can happily keep rolling it around, adding features and changing things, and you&rsquo;ll still be as fast and flexible as you were the first day.</p>
<p>Of course, I have no hard data to back any of this other than my own personal experience. If anybody has seen some studies on the subject, please let me know so I can see if they agree with my observations.</p>
<p><strong>More interfaces</strong></p>
<p>In C++, the only (or at least, the easiest) way to use mock objects is to use virtual functions through an interface class. The more you use that technique, the more virtual functions you&rsquo;ll end up with, even if you didn&rsquo;t really need them for the production code itself.</p>
<p>A good example could be a graphics rendering library, which is just a light wrapper around the graphics hardware abstraction. If you know you&rsquo;re only going to use one type of graphics hardware, you don&rsquo;t really need an interface class and a lot of virtual functions. But if you want to insert a mock object there (which you probably will, to avoid using a real renderer in your tests), it&rsquo;ll force you to create unnecessary virtual functions.</p>
<p>Of course, many times, when you need a mock object, you also need to use polymorphism at runtime, so you needed those virtual functions anyway.</p>
<p>How much of a big deal is it? I&rsquo;d say for the most part it&rsquo;s not worth sweating it. Those are still fairly coarse functions, so having a virtual call isn&rsquo;t going to affect your frame rate very much at all. They certainly won&rsquo;t for higher-level code that is not called as frequently. If the extra virtual function calls are an issue, you can change those tests to check the state of the objects directly instead of using mock objects.</p>
<p>I hope you found this peek behind the looking glass useful. Hopefully it convinced you to give test-driven development an honest try. And at the very least, I hope that it made you think about how you develop software and question your assumptions. But don&rsquo;t worry, this is not the end: this is a topic I plan on revisiting in future articles. By now you should know your way into the looking glass. Feel free to step through any time you want.</p>]]></content:encoded></item><item><title>So Much to See, So Much to Do: Getting the Most out of GDC</title><link>https://gamesfromwithin.com/so-much-to-see-so-much-to-do-getting-the-most-out-of-gdc/</link><pubDate>Mon, 28 Feb 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/so-much-to-see-so-much-to-do-getting-the-most-out-of-gdc/</guid><description>&lt;p&gt;It&amp;rsquo;s that time of the year again: days are getting longer, the weather is slowly getting warmer, and a hint of change is in the air. That can only mean one thing: the &lt;a href="http://gdconf.com/"&gt;Game Developers Conference&lt;/a&gt; is approaching again! This article will help you navigate your way around GDC more successfully and help you get the most out of this year&amp;rsquo;s conference.&lt;/p&gt;</description><content:encoded><![CDATA[<p>It&rsquo;s that time of the year again: days are getting longer, the weather is slowly getting warmer, and a hint of change is in the air. That can only mean one thing: the <a href="http://gdconf.com/">Game Developers Conference</a> is approaching again! This article will help you navigate your way around GDC more successfully and help you get the most out of this year&rsquo;s conference.</p>
<p><img alt="gdc1" loading="lazy" src="/so-much-to-see-so-much-to-do-getting-the-most-out-of-gdc/images/gdc1.jpg"></p>
<p>GDC can be a little intimidating the first few times you attend. With well over 10,000 attendees and 30 simultaneous sessions at any given time, as well as keynotes, expo floors, roundtables, special events, and parties, it&rsquo;s natural if things feel a bit overwhelming at first. This article will help you navigate your way around GDC more successfully and help you get the most out of this year&rsquo;s conference.</p>
<h3 id="get-to-know-people">Get to know people</h3>
<p>GDC is all about the talks, the tech, and the expo, right? Bzzzz&hellip; Wrong! GDC is first and foremost a great place to meet new people in the industry, exchange ideas, talk about different topics, and network in general. My memories of past GDCs are not so much about specific technical details (those come and go pretty quickly), but are about people: people I met, presenters whose talk I went to see, old friends I ran into, etc. If you do only one thing at GDC this year, make sure you make an effort to meet new people. You won&rsquo;t regret it.</p>
<ul>
<li><strong>Talk to the person sitting next to you.</strong> I&rsquo;m serious. When you go to a talk and have a few minutes before the session starts, introduce yourself to the person sitting next to you. Chances are he (or she, although that&rsquo;s significantly less likely at GDC unfortunately) is interested in many of the same topics you are since you&rsquo;re both attending the same talk. He might have worked on some games you played, or the other way around. Don&rsquo;t do it just at the talks either; breakfast or lunch is another great opportunity, and so are parties or other special events.</li>
<li><strong>Bring business cards.</strong> Talking with new people is a start, but continuing to have some contact after GDC is over can be really valuable. Make sure to bring a good stack of business cards with you and hand them out to anybody you meet and talk with for a while. You never know where your next contact is coming from, and it&rsquo;s always good to know how to get in touch with the people you meet. If you don&rsquo;t have business cards, have some printed right away, even if you&rsquo;re a student or are currently out of work. It&rsquo;s not for appearances&rsquo; sake, it&rsquo;s just that it is much more convenient that having to write down people&rsquo;s email address on the spot.</li>
<li><strong>Vary your social circle.</strong> Going with coworkers or friends to GDC can be very rewarding. You all go through a similar experience, compare notes, etc. It can feel much more secure when you&rsquo;re thrown in such a chaotic environment. But make sure you vary your company a bit. If you just hang out with your coworkers all the time, you&rsquo;ll miss out on meeting lots of new people. Strike out on your own at least some of the time.</li>
</ul>
<h3 id="tutorials">Tutorials</h3>
<p>GDC traditionally opens up with two days of tutorials. These are day-long sessions on one topic. They are not part of the regular conference, and you need to register for those two days separately (or get a GigaPass).</p>
<ul>
<li><strong>Mix and match.</strong> Committing a full day to one thing is not something you want to do lightly. I find that I end up getting a lot more out of mixing and matching my tutorials. Tutorials usually start out with introductory material, and then get more advanced as the day goes on. So my usual strategy is to start with one I don&rsquo;t know much about, and then move to others for which I&rsquo;m only interested in the advanced topics. Sometimes I&rsquo;ll even go back and forth between two or three, switching at every break, trying to hit the parts that interest me the most.</li>
<li><strong>Warming up.</strong> The meat of the conference is the last three days. That&rsquo;s when everybody comes, the expo floor opens, and everything is moving at full steam. In comparison, the tutorial days are like a nice warm-up. There&rsquo;s only a fraction of the people, not many events, and things are less frantic in general. If this is your first time at GDC (and you or your company can afford the extra price tag), I would suggest coming to the tutorials at least once.</li>
</ul>
<h3 id="choosing-sessions">Choosing sessions</h3>
<p>If meeting people was the most important aspect of GDC, attending good sessions is the second one in the list for me. With so many simultaneous sessions going on over the last three days, it can be really challenging to decide what to attend. Unlike the tutorials, mixing and matching is not really an option because the sessions are usually only one hour long without any breaks. So, how do you go about choosing what sessions to attend?</p>
<ul>
<li><strong>Does it benefit from a presentation?</strong> It sounds like a silly question, but really think about it. Is the topic something that would benefit from a presentation? A presentation that is highly mathematical might be easier to parse offline just reading the paper at my own pace rather than having it forced into my brain in one hour. On the other hand, just reading the slides for a session about the speaker&rsquo;s experiences and anecdotes just won&rsquo;t cut it. Peeking at the slides or paper before the presentation sometimes gives you a good idea how much you&rsquo;ll get out of the session itself.</li>
<li><strong>Choosing the right depth.</strong> Usually that means the topic is something I don&rsquo;t know much about so I&rsquo;m looking to get a nice overview in a digested format to get me started, or it&rsquo;s an advanced topic and I&rsquo;m looking to get lots of tasty insights and an interesting question-and-answer section after the talk. If the talk is going to present a topic I&rsquo;m familiar with at an intermediate level, there&rsquo;s probably not much point in attending.</li>
<li><strong>Try something different.</strong> The first couple of times I attended GDC I made the mistake of sticking very closely to sessions that were directly relevant to my work. I think that was some misguided attempt to &ldquo;maximize&rdquo; what I got out of GDC since the company was sending me there. Sure, don&rsquo;t blow off all the relevant sessions, but make sure you find some time to explore other topics and even different tracks. If you&rsquo;re a programmer, go to a design or an art talk. If you&rsquo;re into graphics, you could spend all your waking time going from pixel shader session to fancy lighting model session and not see anything beyond that. Take a break and hit an AI session instead, or a networking one. I guarantee that you&rsquo;ll get a lot more than you think out of trying them.</li>
<li><strong>The speaker is very important.</strong> When you&rsquo;re reading a paper, all you care about are its contents, but a speaker will completely make or break the presentation. I have learned over the years to really pay attention to who the speakers are, what their experience is, and, most importantly, how well they can present things. If there&rsquo;s an interesting-sounding talk given by a speaker who totally butchered a presentation from another year, I&rsquo;m going to think hard about the alternatives and I&rsquo;ll consider getting the slides afterwards. On the other hand, there are some speakers whose talks I will unconditionally go to, since I know it&rsquo;s going to be an awesome experience. For example, I really don&rsquo;t care what the topic of Will Wright&rsquo;s session is; if he&rsquo;s talking, I&rsquo;ll be there. I&rsquo;ve attended enough of his talks to know he&rsquo;s an amazing speaker with really good insights. Besides, his presentations are perfect examples of ones you just can&rsquo;t get the same thing out of by looking at the slides.</li>
<li><strong>Create a schedule.</strong> Don&rsquo;t wing it. There are lots of choices to make and there isn&rsquo;t that much time (or places to sit down) in between sessions. I recommend deciding what talks you&rsquo;re going to go to ahead of time, preferably the night before. Lately at GDC, you get a fold-out schedule of the full conference, which is great for marking what sessions you&rsquo;re interested in and knowing at a glance where you&rsquo;re going next. Another schedule-making tip: decide what roundtables you want to go to, but don&rsquo;t add them to your schedule until the end. They&rsquo;re repeated three times (once each day), so you might be able to fit them in a slot when there isn&rsquo;t much else going on.</li>
<li><strong>Keep some backup.</strong> I don&rsquo;t really want to encourage people to come in and out of a session while it&rsquo;s going on, but there&rsquo;s also nothing worse that being stuck in a session that you know you&rsquo;re not going to get anything from it while there are all sorts of good sessions going on at the same time. If you&rsquo;re not too sure about a particular session, keep another one in mind. If things are not going anywhere in the first five minutes, make a beeline for your backup session. If you do that, please sit towards the back or near an exit row to avoid disturbing people when you leave. Since you selected your backup session ahead of time you&rsquo;ll waste no time selecting a new one and you&rsquo;ll be able to make it for most of the second session.</li>
</ul>
<p><img alt="gdc2" loading="lazy" src="/so-much-to-see-so-much-to-do-getting-the-most-out-of-gdc/images/gdc2.jpg"></p>
<h3 id="roundtables-and-keynotes">Roundtables and keynotes</h3>
<p>Roundtables and keynotes are the two most popular session formats after regular talks. Roundtables are small(ish) sessions with up to 40 or 50 people, in which the attendees engage in discussion on the roundtable topic. Keynotes are very large sessions of general interest, so they&rsquo;re usually scheduled in an auditorium or some other large theater-like venue.</p>
<ul>
<li><strong>Come prepared to talk.</strong> A roundtable is not a regular talk. Don&rsquo;t walk into a roundtable expecting to sit on a corner and learn from other people. Come prepared to talk, or at least with questions of your own. If you just sit there and listen to other people, you&rsquo;ll probably won&rsquo;t get as much out of it as you could and it&rsquo;ll be more boring for everybody. A good roundtable is a controlled, lively discussion where everybody participates, and can be much more rewarding than any regular talk.</li>
<li><strong>Continue the discussion.</strong> If you end up participating in an interesting discussion and you&rsquo;re still interested in the topic when the roundtable ends, don&rsquo;t let it die there. Go up to the moderator or the other participants who were part of the discussion, exchange business cards, meet up for lunch, or just say hi and perhaps continue some conversation through email.</li>
<li><strong>Don&rsquo;t get discouraged.</strong> The same way that a good roundtable can be the highlight of a conference, a badly-run one is an awful experience, with a couple of people shouting at each other and the discussion drifting all over the place without giving you a chance to participate. If that happens, don&rsquo;t get put off from roundtables permanently. Give another one a try sometime (maybe on a different topic). They really can be very rewarding.</li>
<li><strong>Go to the keynotes.</strong> Unless the topic is something you really, really don&rsquo;t care about, make a point of going to the keynotes. They are usually general and interesting enough that appeal to everybody. They are often given by fairly big names in the industry, so this is your chance to see them in person.</li>
</ul>
<h3 id="expo-floor">Expo floor</h3>
<p>The expo floor is open during the main three days of the conference. There you can see all the major companies involved in the industry trying to sell you software, hardware, books, services, or anything in between.</p>
<ul>
<li><strong>Give the expo a try.</strong> I have to admit that the expo is not one of my favorite parts of GDC, but it&rsquo;s still worth checking out every year. I particularly like browsing the small booths of unknown middleware companies, or of products I hadn&rsquo;t seen in person before. I don&rsquo;t really see much point in the big booths (NVidia, ATI, Microsoft, Sony), other than to say, &ldquo;we have a presence here.&rdquo; You will have plenty of time to visit the expo in between talks, after the sessions, or even during some of the breaks they make in the schedule specifically to let people visit the expo, so don&rsquo;t skip any sessions just to walk around the expo. It&rsquo;s usually not worth it.</li>
<li><strong>Swag hunt.</strong> If you&rsquo;re in the hunt for swag, the expo floor can be a fertile ground. In years past there was a never-ending supply of t-shirts. One year I walked away with 18 new t-shirts, and some of them were being literally thrown at me as I was walking by a booth. Now it seems that companies are tightening up and the t-shirt supply has dried up a lot, but there&rsquo;s still a lot of swag to be had if you&rsquo;re into that kind of thing.</li>
<li><strong>Job fair.</strong> I can&rsquo;t really say much about this. There are usually lots of companies there, but the booths seem to be mostly full of HR people, so it&rsquo;s not like you can walk up there and start talking with the developers and find out how things really are at the company. Their booths are usually so packed with candidates walking through and filling applications that I can&rsquo;t help but feel that your stuff is going to be thrown on a pile and will get lost in the shuffle. Is it really much better than submitting your application online? I&rsquo;m not quite so sure.</li>
</ul>
<h3 id="parties-and-events">Parties and events</h3>
<p>I&rsquo;ve heard of people who come to GDC and don&rsquo;t even get a pass. They just go for the parties and apparently they have a blast. Whatever floats their boat, but it seems like a monumental waste to me. Parties have their place (especially if, unlike me, you actually like to drink alcoholic drinks), but to me the real GDC happens during the day.</p>
<ul>
<li><strong>Look around for parties.</strong> There are many more than you probably know. Apart from the official parties, there are lots of invitation-only parties going on (usually all the big companies throw parties: Microsoft, Sony, EA, middleware providers, etc). Getting an invitation is usually just a matter of asking for one. Keep your eyes peeled and ears open and you&rsquo;ll hear about them. Worse comes to worst, just swing by their booth and ask them what you have to do to get a pass.</li>
<li><strong>Meet people.</strong> You can try and use the parties to meet more people, but the setting is less than ideal (dark rooms, loud music, and lots of drunk developers).</li>
<li><strong>Check out the events.</strong> Apart from being another great opportunity to meet new people, some of the events can be quite entertaining. <a href="http://gdconf.com/schedule/choiceawards.htm">The Game Developer Choice Awards</a> are the closest thing to Academy Awards for the games industry, so it can be an interesting event to go to. Besides, if you last all two hours, you get your GDC t-shirt at the end. <a href="http://gdconf.com/schedule/igf.htm">The Independent Games Festival</a> is always very interesting, and at the very least you should check out the games in the expo floor. It&rsquo;s amazing what some of the independent developers can do with a budget of exactly zero dollars. We can certainly learn a thing or two from them.</li>
</ul>
<h3 id="logistics">Logistics</h3>
<ul>
<li><strong>Hotel reservations.</strong> If you don&rsquo;t have a hotel reservation by now, you&rsquo;re in trouble. You usually need to book those months in advance (December is a good time to do thatâ€”make a note for next year). Your only option right now might be doubling up with someone else who already has a room and split the cost.</li>
<li><strong>Trip.</strong> I don&rsquo;t know why, but lots of people assume that the last day of the conference (Friday) is less interesting than the rest and leave early. Don&rsquo;t do that. There are enough interesting talks all around to last the full three days, and more if GDC lasted longer. Don&rsquo;t leave until Friday evening or Saturday morning.</li>
<li><strong>Location.</strong> By now I could give you great tips about San Jose, where to eat, what places to go to, which ones to avoid, but this year GDC moved to San Francisco, so that&rsquo;s totally new to me. I&rsquo;ll have to ask other people for advice instead.</li>
</ul>
<p>And that wraps it up. Make sure you get lots of rest and sleep before GDC. You&rsquo;ll need every ounce of energy for a very exhausting, but extremely interesting week. This is our industry&rsquo;s biggest event, and it only happens once a year, so make the most out of it. And remember, make an effort to meet new people and say hi if you see me :-)</p>
<p>Photos courtesy of the <a href="http://gdconf.com">Game Developers Conference</a>.</p>]]></content:encoded></item><item><title>Stepping Through the Looking Glass: Test-Driven Game Development (Part 2)</title><link>https://gamesfromwithin.com/stepping-through-the-looking-glass-test-driven-game-development-part-2/</link><pubDate>Sat, 26 Feb 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/stepping-through-the-looking-glass-test-driven-game-development-part-2/</guid><description>&lt;p&gt;Part 1 of this article provided just a glimpse of what was behind the looking glass. Now we&amp;rsquo;re ready to dive in all the way and look at how we can apply test-driven development to games. Be warned: the looking glass is very much one-way only. After you try this, you might become &lt;a href="http://c2.com/cgi/wiki?TestInfected"&gt;test infected&lt;/a&gt; and may never be able to go back and write code the way you&amp;rsquo;ve done up until now.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Part 1 of this article provided just a glimpse of what was behind the looking glass. Now we&rsquo;re ready to dive in all the way and look at how we can apply test-driven development to games. Be warned: the looking glass is very much one-way only. After you try this, you might become <a href="http://c2.com/cgi/wiki?TestInfected">test infected</a> and may never be able to go back and write code the way you&rsquo;ve done up until now.</p>
<h3 id="what-to-test">What to test</h3>
<p>By now you have a pretty good idea of what TDD is and how to apply it. But what exactly do we test? How do we go about testing it?</p>
<p>Depending on the code in question, I use one of three main approaches to test that the code is doing what it should.</p>
<p><strong>Check output</strong></p>
<p>This is the easy one. You make a function call, and check the result value. Everything you need to know is there at your fingertips.</p>
<pre tabindex="0"><code>TEST (TargetingCantLockOnObjectOutsideCone) 
{ 
    TargetingSystem targeting; 
    targeting.SetTransform(...); 
    Vector3 positionBehind (...); 
    CHECK (!targeting.CanLockOn(positionBehind)); 
}
</code></pre><p><strong>Check state</strong></p>
<p>In this situation, you&rsquo;re checking that a particular operation changes some state. You might get a success/failure return code, but that doesn&rsquo;t tell you enough (you still want to test that separately though). For example, applying a speed powerup to an entity returns true or false depending on whether the entity consumed that powerup, but we need to test that it did the right thing.</p>
<pre tabindex="0"><code>TEST (EntityDoesNotConsumesSpeedPowerupByDefault) 
{ 
    GameEntity entity; 
    SpeedPowerup powerup; 
    CHECK (!entity.Apply(powerup)); 
}  

TEST (EntityConsumesSpeedPowerup) 
{ 
    GameEntity entity; 
    entity.Accepts(SpeedPowerup); 
    SpeedPowerup powerup; 
    CHECK (entity.Apply(powerup)); 
}  

TEST (EntityConsumesSpeedPowerup) 
{ 
    GameEntity entity; 
    entity.Accepts(SpeedPowerup); 
    float oldSpeed = entity.GetSpeed(); 
    SpeedPowerup powerup; entity.Apply(powerup); 
    CHECK_CLOSE (oldSpeed + powerup.GetSpeedBoost(), entity.GetSpeed()); 
}
</code></pre><p>If I had to add a third test related to that, I would refactor the tests into a fixture. More on that in a minute.</p>
<p>What if the entity class didn&rsquo;t have a GetSpeed() method? Ideally you want to test things by using them the way you expect them to be used in the game. I suppose you could test the speed by the slightly roundabout method of letting the entity move for one frame and see the difference, but that&rsquo;s a bit too convoluted.</p>
<p>In a case like this, I&rsquo;d say that adding a GetSpeed() method is justified. You want to stay clear of always falling back into this pattern and littering your interfaces with GetXXX() methods though. Remember, testing is supposed to make your code more robust and easier to understand, not get in the way and complicate interfaces.</p>
<p>What if you ever come up against something that seems untestable? Hard-core TDDers will claim that if you can&rsquo;t test something, you shouldn&rsquo;t implement it. That&rsquo;s a sentiment I agree with, but I have encountered a just a handful of things over time that I considered too much of a pain to test and skipped the tests. I suspect the more experience once acquires with TDD, the less common that situation is. But in general, if you can&rsquo;t test it, then think about how to implement it in a different way. Chances are the new design is going to be better. It&rsquo;s yet another case of TDD in action affecting the final design.</p>
<p><strong>Check interaction between objects</strong></p>
<p>A lot of the code in a game is more than simple functions that return values or set states. In a complex game engine, objects communicate with each other, sending messages, calling methods, and performing a sequence of actions. Testing that is just as important as testing the individual state in an object.</p>
<p>To test interactions between objects, you use <em>mock objects</em>. Mock objects are objects that look like the regular object to the code, but are nothing more than a pretty face with testing code behind it for us to verify that things worked as expected. Most mock objects I work with are extremely simple, and are limited to increasing a counter when something happens, or storing a copy of some argument passed to a function.</p>
<p>One of the mock objects I end up using quite frequently is one to verify that object lifetimes are managed correctly. For example, imagine we have an entity system that uses components. The entity owns the components, so if the entity is ever destroyed, it should destroy all the components. How would we implement that? Pretty easy: in the destructor we write a loop that&hellip;. No, wrong answer. Before we write anything, we need to write a test for it. Something like this:</p>
<pre tabindex="0"><code>TEST (EntityDestroysComponents) 
{ 
    GameEntity entity; 
    entity.Add(new Component()); 
    delete entity; 
    // ??? How exactly do we test that the component was deleted? 
}
</code></pre><p>So we create an entity, we add a component, and we destroy the entity. How can we verify that the component was destroyed along with it? I suppose we could try to access the component we allocated and see if that memory is valid, but that&rsquo;s a really ugly and non-portable solution. It would be much cleaner to use a mock object: that simply keeps track of how many instances of that class are currently allocated.</p>
<pre tabindex="0"><code>class MockComponentDestruction : class Component 
{ 
public: 
    MockComponentDestruction() { ++s_instances; } 
    virtual ~MockComponentDestruction() { --s_instances; }  

    static int s_instances; 
};  

int MockComponentDestruction::s_instances = 0;
</code></pre><p>Now the test becomes quite trivial.</p>
<pre tabindex="0"><code>TEST (EntityDestroysComponents) 
{ 
    GameEntity entity; 
    entity.Add(new MockComponentDestruction()); 
    CHECK_EQUAL (1, MockComponentDestruction::s_instances); 
    delete entity; 
    CHECK_EQUAL (0, MockComponentDestruction::s_instances); 
}
</code></pre><h3 id="tdd-and-games">TDD and Games</h3>
<p>All right, how about about using TDD for game development? The great majority of the code in a game is code just like in any other type of application. You have objects that are doing some processing and communicating with other objects. We can test that very easily. So, what&rsquo;s different about games?</p>
<p><strong>Graphics</strong></p>
<p><img alt="looking glass" loading="lazy" src="/stepping-through-the-looking-glass-test-driven-game-development-part-2/images/alice_looking_glass_2.jpg"> There&rsquo;s a misconception that games are all about graphics. That&rsquo;s just plain wrong. It&rsquo;s true that games make heavy use of graphics, and games interact with the user primarily through the use of graphics (along with audio and force feedback). But the bulk of the code in a game is not doing low-level graphics operations. Instead, it&rsquo;s running AI, figuring out what things are visible this frame, sending objects down the pipeline, moving entities in the world, updating physics simulations, etc.</p>
<p>The best thing you can do is forget about low-level graphics. Wrap it up neatly at a really low level in a little library and push it aside. Then you can concentrate on testing everything that uses graphics instead of getting bogged down with the graphics themselves.</p>
<p>For example, we can easily develop through TDD the code that will determine what&rsquo;s in view given a camera in our world. We can also use TDD to come up with a solution to correctly sort the meshes sent to the graphics renderer to optimize performance. All those are higher-level operations that are not involved with the low-level graphics API or hardware, so nothing is stopping us from testing them.</p>
<p>But it is even possible to test fairly low-level operations. As an example, say you&rsquo;re about to send to the hardware an object that is lit with two point lights and a directional light, and you want to make sure the right shader is selected (or the right states are set). In this situation, you&rsquo;re making a function call (Render()), and you can either check the state of the graphics renderer directly, or you can insert a mock object between your code and the graphics API and detect that the correct functions were called.</p>
<p>To make the tests more effective, try to make sure you can run most of your game code without having to create a graphics device, initialize it, create a window, set a video mode, etc. Not only will that decouple your code from the graphics library (which is a good thing), but it will let you run the tests much more quickly and on a variety of platforms. Otherwise, any machine that runs the tests might be required to have DirectX 9.0c, a fancy graphics card, etc. If there&rsquo;s really no way around it, you can go ahead and do any graphics initialization at the beginning of the test run for the whole graphics library and shut it down when the tests complete, but ideally you shouldn&rsquo;t have to do that at all.</p>
<p>What about verifying that the right calls and data are sent to the graphics hardware? That&rsquo;s up to you. TDD is not a religion or an absolute mandate. It&rsquo;s a tool that I happen to think can be applied to most situations and give great results. If you&rsquo;re writing a driver for some hardware you should definitely do it. If you&rsquo;re writing graphics middleware, you might want to consider that too. Otherwise, it&rsquo;s really not worth it. If you&rsquo;ve tested everything up until the call where you just set the right render states and push the data down, you can safely trust the graphics hardware to do the rest.</p>
<p><strong>Middleware</strong></p>
<p>Middleware is a big topic in game development (<a href="http://www.cmpevents.com/GD05/a.asp?option=C&amp;V=11&amp;SessID=4703&amp;Mgt=0&amp;RVid=0">shameless plug</a>), and chances are good you&rsquo;re using some form of middleware in your projects. Maybe it&rsquo;s something as simple as <a href="http://www.radgametools.com/bnkmain.htm">Bink</a>, or something as complex as <a href="http://www.renderware.com/">RenderWare</a>. In any case, it is true that working with an external library (which may not even come with source code) makes things a bit more difficult.</p>
<p>You should treat middleware very much like what we did with graphics. Assume it works correctly, but test everything leading up to the interface with the middleware library.</p>
<p>The key idea is to remember that with TDD, you want to test that the code you&rsquo;re about to implement is doing the right thing. For example, imagine you&rsquo;re integrating some physics middleware into your engine. You might start with a simple test like this:</p>
<pre tabindex="0"><code>TEST (PhysicsObjectStaysAtRestWithNoForces) 
{ 
    PhysicsObject obj; 
    Vector3 oldPosition = obj.GetPosition(); 
    obj.Update(); 
    CHECK_EQUAL (oldPosition, obj.GetPosition()); 
}
</code></pre><p>Next you might want to check that if you apply a force it moves in the right direction. Then you check for friction, collisions, bouncing, deformation, etc. The fact that you&rsquo;re using an external middleware library to solve those problems should not matter as far as the tests are concerned.</p>
<p>Now let me get on my soapbox for a second. If you&rsquo;re a middleware provider, I hope you&rsquo;re using unit tests (and of course, I&rsquo;d recommend that they be developed before the code). If you do that, please, please, make sure you also release your unit tests to source code licensees. The unit tests will serve both as up-to-date documentation and as a safety net in case they make any changes. And who needs more safety nets than the people who didn&rsquo;t write the code in the first place?</p>
<p><strong>Hardware</strong></p>
<p>A lot of games are developed on a PC but run on different platforms (PS2, Xbox, Gamecube, custom arcade hardware, handhelds, etc). How do we test them? As much as possible, I would recommend trying to keep as much of the code as platform-independent as possible. Not only will it help with testing but it&rsquo;s probably a good business and engineering decision. At that point, you can test it just like any other code, hopefully in the same step as you build your code, without any delays.</p>
<p>Additionally, it&rsquo;s a good idea to run the unit tests on the target platforms themselves. This is something you could run more infrequently, such as right before you&rsquo;re about to check in code, and, of course, by the automated build machine itself. That way you&rsquo;ll catch any platform differences, like subtle changes introduced by different endianness, etc.</p>
<p><strong>Large amounts of data</strong></p>
<p>Of all the things that make game development different, this is probably one of the most unique ones. Games, and especially modern games, often use many gigabytes of data. What does that mean for unit testing and TDD?</p>
<p>Fortunately, not very much. These tests we&rsquo;re writing are unit tests. They test the functionality inside one small part of a class. They shouldn&rsquo;t have to deal with any data, and especially not with many gigabytes worth of it. They should test that the code does the right thing, period.</p>
<h3 id="lets-do-some-examples">Let&rsquo;s do some examples</h3>
<p>In case you&rsquo;re not fully convinced yet, let&rsquo;s run through some real-world examples. Thanks to Ivan-Assen Ivanov for providing the specific examples (taken out of some real-world tasks he had to work on).</p>
<p><strong>Example #1: Computing a passability grid</strong></p>
<p><em>Compute a passability grid for use by the pathfinder code. The passability values are computed based on terrain features such as slope, road textures, water depth, etc.</em></p>
<p>Where do we start? Before we start thinking of algorithms, let&rsquo;s just create a test that checks the obvious. I should be able to create an empty grid with some default values.</p>
<pre tabindex="0"><code>TEST (DefaultPassabilityGridIsPassable) 
{ 
    PassabilityGrid grid(1,1); 
    CHECK (grid.IsPassable(0,0)); 
}
</code></pre><p>Next I might want to try to do something about checking values out of range. It seems like a good idea to make all values outside the grid as non-passable.</p>
<pre tabindex="0"><code>TEST (ElementsJustOutsideGridAreNotPassable) 
{ 
    PassabilityGrid grid(1,1); 
    CHECK (!grid.IsPassable(-1,0)); 
    CHECK (!grid.IsPassable(1,0)); 
    CHECK (!grid.IsPassable(0,-1)); 
    CHECK (!grid.IsPassable(0,1)); 
    CHECK (!grid.IsPassable(1,1)); 
}
</code></pre><p>Notice the tests aren&rsquo;t even providing full coverage or anything. I simply sampled five points outside of the grid. If I ever find there&rsquo;s a bug there, I&rsquo;ll go back, write a specific test, see it fail, and then fix it. For now, this is good enough.</p>
<p>Next I would check that our tests work with a slightly larger grid since I could have easily hardwired a 1x1 grid in the grid class.</p>
<pre tabindex="0"><code>TEST (DefaultPassabilityGridIsPassableOnLargerGrid) 
{ 
    PassabilityGrid grid(2,3); 
    CHECK (grid.IsPassable(1,0)); 
    CHECK (grid.IsPassable(1,2)); 
}
</code></pre><p>What next? On a totally flat terrain without any roads, the resulting passability grid is uniform and the nodes are passable. By this time you&rsquo;ll probably already have a terrain class (which should have hopefully been developed using TDD), so I&rsquo;ll just assume we have a Terrain class.</p>
<pre tabindex="0"><code>TEST (EmptyTerrainCreatesUniformGrid) 
{ 
    Terrain terrain(2,2,Grass); 
    PassabilityGrid grid(terrain); 
    CHECK (grid.IsPassable(0,0)); 
    CHECK (grid.IsPassable(1,1)); 
}
</code></pre><p>Notice that we just created a new constructor for the PassabilityGrid. It wasn&rsquo;t part of a grand master plan or a fancy UML design. It simply felt like the right thing to do when using PassabilityGrids this way. That&rsquo;s the beauty of TDD: the code design follows the use of the code.</p>
<p>I think you see where this is heading. Next I would try creating a terrain with one mountain cell, and seeing that the corresponding grid node was impassable. Then create a road and see that those cells are more easily passable than others.</p>
<p><strong>Example #2: Creating a thin layer around audio library</strong></p>
<p><em>One particular feature of this layer, which is not simply reordering parameters and calling another function, is multi-sample sounds: when the sound engine receives an order to play &ldquo;UnitWalk&rdquo;, it chooses randomly with specific probabilities between UnitWalk1.wav, UnitWalk2.wav and UnitWalk3.wav; this mapping, along with probabilities and some other parameters needed by the sound system, comes from a bunch of XML files.</em></p>
<p>That&rsquo;s a pretty big task, so we need to break it down into something smaller just to even start thinking about it. If it&rsquo;s really a thin layer, it&rsquo;s possible that some functions might call directly into the audio library. Those I would just do without a test (whenever I needed them). For example, it&rsquo;s possible that our library might have an Initialize() call that simply calls SoundLibrary::Initialize(). That&rsquo;s fine. No tests there.</p>
<p>Let&rsquo;s concentrate on the mapping of sound events to specific sounds with specific probabilities. Where do we start? Reading XML files? Figuring out random numbers? No, let&rsquo;s take it from the top. Let&rsquo;s write a really simple test of a trivial case and make it pass. How about this?</p>
<pre tabindex="0"><code>TEST (SoundEventPlaysCorrectSoundFile) 
{ 
    GameSoundSystem soundSystem; 
    soundSystem.PlayEvent(&#34;UnitWalk&#34;); 
    CHECK_EQUAL (&#34;UnitWalk1.wav&#34;, soundSystem.GetLastSoundPlayed()); 
}
</code></pre><p>OK, that&rsquo;s not exactly a pretty-looking test, but it&rsquo;s a start. It gives us a rough guide of where to go. Forget about XML files and probabilities, or anything. I play an event, and I want to see a particular wav file played out the other end. How do I implement that? I hardcode a &ldquo;UnitWalk1.wav&rdquo; in the sound library, of course. Test passed. Yeah, I know, the horror! But it took 20 seconds and we made some progress (all tests are passing). Besides, we already started making decisions about how we want to be using this sound system, so we definitely made some progress.</p>
<p>One thing I don&rsquo;t like about that previous test is that it relies on the function GetLastSoundPlayed(). That&rsquo;s not a function that&rsquo;s necessary to work with the GameSoundSystem, and the only reason we introduced it was to help us test it. It&rsquo;s OK to do that from time to time, but I&rsquo;d rather keep my class interfaces as simple and uncluttered as possible. So instead, we&rsquo;ll go ahead and refactor that test to use a mock object representing the real system sound library that will collect the name of the last sound played.</p>
<pre tabindex="0"><code>class SoundSystemMock : class SoundSystem 
{ 
public: 
    virtual void PlaySound(const char * sound) { lastSoundPlayed(std::string(sound)); } 
    std::string lastSoundPlayed; 
};  

TEST (SoundEventPlaysCorrectSoundFile) 
{ 
    SoundSystemMock soundSystem; 
    GameSoundSystem gameSound(soundSystem); 
    gameSound.PlayEvent(&#34;UnitWalk&#34;); 
    CHECK_EQUAL (&#34;UnitWalk1.wav&#34;, soundSystem.lastSoundPlayed); 
}
</code></pre><p>This also has the advantage of allowing us to write all these tests without even having to play real sounds and without even linking with the real sound library.</p>
<p>Next. We probably want to play other sounds than UnitWalk1.wav, so let&rsquo;s write another test that will fail.</p>
<pre tabindex="0"><code>TEST (SoundEventPlaysCorrectSoundFile2) 
{ 
    SoundSystemMock soundSystem; 
    GameSoundSystem gameSound(soundSystem); 
    gameSound.PlayEvent(&#34;UnitFire&#34;); 
    CHECK_EQUAL (&#34;UnitFire1.wav&#34;, soundSystem.lastSoundPlayed); 
}
</code></pre><p>This will totally fail because we know that our sound system is playing &ldquo;UnitWalk1.wav&rdquo; no matter what the event is. Time to fix that. For that we probably want to add the concept of mapping. For now, let&rsquo;s just do a one-to-one mapping.</p>
<pre tabindex="0"><code>TEST (SoundEventPlaysCorrectSoundFile2) 
{ 
    SoundSystemMock soundSystem; 
    GameSoundSystem gameSound(soundSystem); 
    gameSound.MapEvent(&#34;UnitFire&#34;, &#34;UnitFire1.wav&#34;); 
    gameSound.PlayEvent(&#34;UnitFire&#34;); 
    CHECK_EQUAL (&#34;UnitFire1.wav&#34;, soundSystem.lastSoundPlayed); 
}
</code></pre><p>Everything is passing again. Now let&rsquo;s add some probabilities to it. This part gets a bit tricker because it involves some randomness. <a href="http://groups.yahoo.com/group/testdrivendevelopment/message/8192">Radomness is one of those tricky things when it comes to testing</a> because you don&rsquo;t want your results to change from run to run. You also don&rsquo;t want to get into the situation that you&rsquo;re running the same test multiple times to verify that you get the correct sound played 20% of the time.</p>
<p>At the same time, randomness plays an important part in game development, so it&rsquo;s crucial to know how to deal with it correctly. I decided to ask in the <a href="http://groups.yahoo.com/group/testdrivendevelopment/">testdrivendevelopment mailing list</a> <a href="http://groups.yahoo.com/group/testdrivendevelopment/message/8555">looking for some good insights</a>.The best solution seemed to be to move the randomness factor as an input. In the production code, that input will be filled by the game random number generator. In our tests, we can pass whatever value we want and we know what results we&rsquo;re going to get.</p>
<p>Here&rsquo;s the next test that includes some different probabilities of different sounds being played.</p>
<pre tabindex="0"><code>TEST (SoundEventWithProbabilities) 
{ 
    SoundSystemMock soundSystem; 
    GameSoundSystem gameSound(soundSystem); 
    gameSound.MapEvent(&#34;UnitFire&#34;, &#34;UnitFire1.wav&#34;, 0.2, &#34;UnitFire2.wav&#34;, 0.8); 
    gameSound.PlayEvent(&#34;UnitFire&#34;, 0.3); 
    CHECK_EQUAL (&#34;UnitFire2.wav&#34;, soundSystem.lastSoundPlayed); 
}
</code></pre><p>Unfortunately, I don&rsquo;t want the public interface of GameSoundSystem::PlayEvent() to take an event name and a number between 0 and 1. That&rsquo;s only for internal consumption and shouldn&rsquo;t be exposed through the interface. On the other hand, I really need that function to test it (and it cleans things up considerably from an implementation point of view). Here&rsquo;s a case where I think giving the test access to a private function is fine.</p>
<p>If you feel uncomfortable with that idea, you would have to create a new class that sits between the GameSoundSystem and the SoundSystem itself and takes care of doing the mapping. That class can have the number between 0 and 1 as part of its interface because it won&rsquo;t be exposed outside of the library. That might actually not be a bad idea since the mapping between events and sounds could be the full-time job for a class.</p>
<p>Just because the first implementation of the mapping of events could have been hardwired (after all, do the simplest thing that could possibly work), I would add another similar test with different values:</p>
<pre tabindex="0"><code>TEST (SoundEventWithProbabilities) 
{ 
    SoundSystemMock soundSystem; 
    GameSoundSystem gameSound(soundSystem); 
    gameSound.MapEvent(&#34;UnitFire&#34;, &#34;UnitFire1.wav&#34;, 0.2, &#34;UnitFire2.wav&#34;, 0.8); 
    gameSound.PlayEvent(&#34;UnitFire&#34;, 0.1); 
    CHECK_EQUAL (&#34;UnitFire1.wav&#34;, soundSystem.lastSoundPlayed); 
}
</code></pre><p>This also gives us the perfect opportunity to refactor the tests into a fixture by putting all common code there and simplifying the tests considerably:</p>
<pre tabindex="0"><code>class SoundEventFixture 
{ 
public: 
    SoundEventFixture() : gameSound(soundSystem) 
    { 
        gameSound.MapEvent(&#34;UnitFire&#34;, &#34;UnitFire1.wav&#34;, 0.2, &#34;UnitFire2.wav&#34;, 0.8); 
    } 
    SoundSystemMock soundSystem; 
    GameSoundSystem gameSound; 
};  

TEST_F (SoundEventFixture, FirstSoundPlays) 
{ 
    gameSound.PlayEvent(&#34;UnitFire&#34;, 0.1); 
    CHECK_EQUAL (&#34;UnitFire1.wav&#34;, soundSystem.lastSoundPlayed); 
} 

TEST_F (SoundEventFixture, FirstSoundPlays2) 
{ 
    gameSound.PlayEvent(&#34;UnitFire&#34;, 0.0); 
    CHECK_EQUAL (&#34;UnitFire1.wav&#34;, soundSystem.lastSoundPlayed); 
} 

TEST_F (SoundEventFixture, SecondSoundPlays) 
{ 
    gameSound.PlayEvent(&#34;UnitFire&#34;, 0.22); 
    CHECK_EQUAL (&#34;UnitFire2.wav&#34;, soundSystem.lastSoundPlayed); 
} 

TEST_F (SoundEventFixture, SecondSoundPlays2) 
{ 
    gameSound.PlayEvent(&#34;UnitFire&#34;, 1.0); 
    CHECK_EQUAL (&#34;UnitFire2.wav&#34;, soundSystem.lastSoundPlayed); 
}
</code></pre><p>I would then refactor the tests to come up with a better way to express the mapping between events and sounds than passing huge lists of parameters, check for valid probabilities (can&rsquo;t add up to anything different than 1.0), etc. We never got around to the XML part, but that&rsquo;s something totally orthogonal to this. First let&rsquo;s worry about getting the data to the object, then we can load that data in any way we want (but we&rsquo;ll test that too when we get to it, of course).</p>
<p>That&rsquo;s enough for one day. The next (and final!) part of this article will deal with specific tips for doing TDD that I found particularly useful, especially dealing with C++ and games. I&rsquo;ll also cover what are some of the immediate consequences you can expect from doing TDD, including build times, development speed, etc. In the meanwhile, get your unit-test framework ready and give it a whirl.</p>]]></content:encoded></item><item><title>Stepping Through the Looking Glass: Test-Driven Game Development (Part 1)</title><link>https://gamesfromwithin.com/stepping-through-the-looking-glass-test-driven-game-development-part-1/</link><pubDate>Sun, 20 Feb 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/stepping-through-the-looking-glass-test-driven-game-development-part-1/</guid><description>&lt;p&gt;If you&amp;rsquo;re a typical game developer, you probably don&amp;rsquo;t write any tests for the code you create. So how would you feel about not just writing tests, but creating them &lt;em&gt;before&lt;/em&gt; the code they are testing? What if I told you those tests don&amp;rsquo;t even verify that the code you write is correct? &amp;ldquo;It&amp;rsquo;s madness,&amp;rdquo; you might say; &amp;ldquo;it&amp;rsquo;s all backwards!&amp;rdquo; Not really. It all makes sense in its own way. Follow me through the looking glass and I&amp;rsquo;ll show you the wonderful upside-down world of test-driven development and how we can apply it to games.&lt;/p&gt;</description><content:encoded><![CDATA[<p>If you&rsquo;re a typical game developer, you probably don&rsquo;t write any tests for the code you create. So how would you feel about not just writing tests, but creating them <em>before</em> the code they are testing? What if I told you those tests don&rsquo;t even verify that the code you write is correct? &ldquo;It&rsquo;s madness,&rdquo; you might say; &ldquo;it&rsquo;s all backwards!&rdquo; Not really. It all makes sense in its own way. Follow me through the looking glass and I&rsquo;ll show you the wonderful upside-down world of test-driven development and how we can apply it to games.</p>
<h3 id="traditional-development">Traditional development</h3>
<p>Let&rsquo;s take a moment to think about how you write code without using test-driven development. You decide you need to implement some piece of functionality, you mentally break the problem into smaller problems, and you start working on each of them. While you write code, your only guide for whether you&rsquo;re heading in the right direction or not is whether your code continues to compile. Once you&rsquo;ve assembled a minimum number of those smaller subtasks, your program might even be able to run. So you fire up the game or tool and &ldquo;see&rdquo; if it works. If it&rsquo;s not obvious (or if it doesn&rsquo;t work at all), maybe you break in the debugger and try to step into the code you just wrote to make sure the program is doing what you intended. Once you see it do its thing, you happily commit it to version control and move on to some other task.</p>
<p>Does that more or less describe how you write code? You can replace any specific details in that paragraph, but in general that seems to sum up in my experience how most programmers approach writing code.</p>
<h3 id="what-is-test-driven-development">What is Test-Driven Development?</h3>
<p><img alt="looking glass" loading="lazy" src="/stepping-through-the-looking-glass-test-driven-game-development-part-1/images/alice_looking_glass_1.jpg"> The idea behind Test-Driven Development (TDD) is extremely simple: before you write a piece of functionality, you write a test for it. Only once you have that test, which should fail at first, do you actually implement the functionality and see the test pass.</p>
<p>I know it sounds like a backwards approach if you&rsquo;re not used to it, but it makes a lot more sense than it seems to at first. The thing to keep in mind is that you&rsquo;re not writing a bunch of tests first and then making them pass. You&rsquo;re just writing a single test for a very small bit of functionality that you can implement in a minute or two.</p>
<p>TDD development has a very well defined, short cycle, usually only taking a few minutes per cycle:</p>
<ul>
<li>Write a single test for a very small piece of functionality.</li>
<li>Run it and see it fail (or not even compile in C++).</li>
<li>Write code to make the test compile and pass.</li>
<li>Run the test and see it pass.</li>
<li>Refactor code. See test pass.</li>
<li>Refactor tests. See tests pass.</li>
</ul>
<p>Comparing it to the non-test-driven development approach, you&rsquo;re replacing all the mental checking and debugger stepping with code that verifies that your program does exactly what you intended it to do.</p>
<p>There really isn&rsquo;t much more to test-driven development than that. The devil, as they say, is in the details. You need to learn to effectively do that cycle over and over during your development, how to tackle the right task size, how to organize things so you can test them, how to write tests easily, how to make sure tests can be executed constantly, etc.</p>
<p>A very good starting point is Kent Beck&rsquo;s book <a href="http://www.amazon.com/exec/obidos/ASIN/0321146530/ref=nosim/gamesfromwith-20/102-6548099-6063309"><em>Test Driven Development</em></a>. He&rsquo;ll take you through an example and give you an idea of the kind of pacing and techniques you&rsquo;re likely to use. Don&rsquo;t be put off by the use of Java as their development language. Java is close enough to C++, and besides, it&rsquo;s not the language that&rsquo;s important, it&rsquo;s the concept.</p>
<h3 id="benefits-of-tdd">Benefits of TDD</h3>
<p>So, what exactly do you get by doing things apparently backwards? A lot, as it turns out.</p>
<p><strong>Safety net</strong></p>
<p>Developing your code using TDD means that every single piece of functionality you add will have a test coverage (or close to it anyway). If anything ever changes, you&rsquo;ll know right away. This is extremely important for many reasons.</p>
<p>Refactoring becomes a lot easier, so you can always keep your codebase healthy (I always like to say that the quality of a codebase is directly tied to how easy it is to changeâ€”if it ever becomes difficult or &ldquo;a pain&rdquo; to change, the quality is already on its way down and it&rsquo;s just going to get worse if untreated).</p>
<p>Making changes late in the project also becomes a lot easier, effectively flattening out the <a href="http://www.agilemodeling.com/essays/costOfChange.htm">change vs. cost curve</a>.</p>
<p><img alt="Traditional cost of change" loading="lazy" src="/stepping-through-the-looking-glass-test-driven-game-development-part-1/images/traditional_cost_of_change.png"></p>
<p>This means you can be making significant changes late in the project based on real playtest feedback or finding out what really works and what doesn&rsquo;t, and still be confident you&rsquo;re not breaking anything major. This alone can make the difference between a so-so and an outstanding game.</p>
<p>We all know about those dusty corners of codebases. You know, the places with all the cobwebs, and sometimes gnarled oak trees and a troll or two hiding in the shadows. The places no sane programmer dares approach, especially as a milestone looms over the horizon. TDD gives you the courage and the tools to dive in head first into any part of the code, even the scary parts, make any necessary changes, and walk away like a hero.</p>
<p><strong>Usable design</strong></p>
<p>Here&rsquo;s something that might come as a surprise: Code that you develop through TDD is going to end up looking very different from code you would have written otherwise. Why? After all, the only thing we&rsquo;re doing differently is writing the tests first. TDD is not a design paradigm or anything like that.</p>
<p>That&rsquo;s because with TDD, the first thing you&rsquo;re forced to do is to think about how you want to use your code. You don&rsquo;t start with a UML diagram, or a detailed class header file, or anything like that. You start by <strong>using</strong> the feature you&rsquo;re about to implement. You could call it &ldquo;extreme <a href="http://c2.com/cgi/wiki?DogFood">dog food eating.</a>&rdquo; You&rsquo;re going to be your first user of your code, and you&rsquo;re going to think about how to use it from the beginning.</p>
<p>What does that mean in practice? You&rsquo;ll find that it&rsquo;s very easy to create new objects of the classes you&rsquo;re designing. Most of the time you&rsquo;ll be able to create them on the stack and that will be it. It also means you won&rsquo;t have to have a complicated sequence of registration, creation, binding, yada, yada, yada. You create an object and it does what it&rsquo;s supposed to do.</p>
<p>Quick test: Think about your current game codebase. Could you write something like the following code?</p>
<pre tabindex="0"><code>#include &#34;GameEntity.h&#34;
int main()
{
    GameEntity entity(optional parameters);
    entity.DoSomething();
    return 0;
}
</code></pre><p>Chances are you can&rsquo;t. You probably need a world for the entity to live in. And the world needs to pull in physics and graphics, and initialize the video card, and the sound system, and the networking&hellip; Then you probably have to go through a complex creation procedure. Or maybe you can&rsquo;t even create an entity that way and you can only load it from disk along with some resources.</p>
<p>If simplicity is something important (<a href="/simple-is-beautiful/">and I clearly think so</a>), then TDD will help you tremendously.</p>
<p><strong>Modularity</strong></p>
<p>This is another side effect of having to eat your own dog food all the time and use the code you&rsquo;re about to write. You&rsquo;ll quickly see that testing code that depends on lots of other code is a nuisance that can be avoided most of the time. As a result, the code you write will be extremely modular. It&rsquo;ll be very easy to use an object in isolation from other classes or systems.</p>
<p>To draw on the earlier example, you will be able to create a game entity without a world, and certainly without expensive operations like initializing the graphics system and pulling in the rest of the codebase.</p>
<p>Modularity schodularity. Why should you care? There are the usual reasons: refactoring, reusing the code, adding new features later on, etc. But there are also much more practical ones. A highly modular codebase will compile much more quickly than one that has grown organically (without resorting to the likes of <a href="/how-incredible-is-incredibuild/">Incredibuild</a>). It&rsquo;ll also allow you to break it up into smaller, separate libraries which can be tested and linked separately (which means really fast iteration times instead of always having a 2-minute link step if you&rsquo;re dealing with the full codebase).</p>
<p><strong>Documentation</strong></p>
<p>What&rsquo;s wrong with comments in code? I used to be a big one for having a header on every class and every function, generating cute help files with Doxygen and all that, but I eventually gave up. When you&rsquo;re developing at a real-world pace, those pretty comments quickly fall by the wayside. Then you&rsquo;re left either with obvious comments (assign a to b!), outdated ones, or, even worse, incorrect ones.</p>
<p>The tests you write while doing TDD are the ideal low-level documentation for your code. For every feature, you have at least one example on how to use it correctly and how it&rsquo;s expected to be used. And the best part is that it can&rsquo;t <strong>ever</strong> get out of date.</p>
<p>Comments in code still have their place, but it should be very rare. You should still add comments explaining why you did something a certain way, or including the URL of the web page where you got certain algorithms or code snippets. Other than that, I believe documentation should come in the form of good class and function names and a comprehensive set of TDD-generated unit tests.</p>
<p><strong>WYGIWYM (What You Get Is What You Meant)</strong></p>
<p>When you&rsquo;re doing TDD, even though you&rsquo;re writing unit tests, you&rsquo;re not verifying that the algorithm you&rsquo;re implementing is correct. That&rsquo;s not the goal. What TDD gives you is the confidence that the code you just wrote does what you wanted it to do. If you meant to do the wrong thing, you&rsquo;ll only be testing that you did the wrong thing. TDD isn&rsquo;t going to help you in that respect (other than make you realize really early on that you&rsquo;re doing the wrong thing, since you&rsquo;re using your own code before you even write it). A bit more on this later on.</p>
<p><strong>Instant feedback</strong></p>
<p>When you write any code doing TDD, you get instant feedback. You write a test, build, run the tests, and you see them fail. Then you write the code, and you see the tests pass. You refactor a few things, and see the tests pass still. Instant feedback is part of the TDD cycle, and since the cycle is so short, you&rsquo;ll get feedback on how things are going every few minutes, or even several times per minute.</p>
<p>Apart from keeping you honest and showing that things are progressing in the right direction, this instant feedback can have a very curious effect on the mood of the programmer. I don&rsquo;t know exactly how to describe it, but I hadn&rsquo;t had as much fun programming in a long, long time. Somehow, TDD brought back the excitement and satisfaction I felt writing Basic programs on an <a href="http://andercheran.aiind.upv.es/~amstrad/">Amstrad CPC</a> twenty years ago.</p>
<p>I know that&rsquo;s a very subjective &ldquo;benefit&rdquo; of TDD, but it&rsquo;s one that can have a profound effect on the team and the overall productivity. Don&rsquo;t underestimate the power of a happy programmer!</p>
<h3 id="tdd-in-practice">TDD in practice</h3>
<p>Enough theory. I hope I have convinced you of the potential benefits and you&rsquo;re willing to give it a try. Let&rsquo;s get into the nitty-gritty details. How exactly do we go about doing TDD? I&rsquo;m assuming you&rsquo;re using C++ since that&rsquo;s the most-used language for game development today.</p>
<p><strong>Get a unit-testing framework.</strong></p>
<p>You need a unit-testing framework. The goal is to make writing a test as painless as possible. The easier it is to write a test, the less people will resist writing new tests. Since unit tests are at the core of TDD, the more streamlined the process the better.</p>
<p>I recently looked at some of <a href="/exploring-the-c-unit-testing-framework-jungle/">the most popular C++ unit-testing frameworks</a>. If you&rsquo;re just starting out, don&rsquo;t worry about the details. Use whatever is most convenient. I&rsquo;m currently using a modified version of CppUnitLite (which I&rsquo;m hoping to put up here in the next few days) just because it&rsquo;s so small, easy to use, and easy to modify and port.</p>
<p>With my current unit-testing framework, adding a new test is as easy as writing this:</p>
<pre tabindex="0"><code>TEST (MyFirstTest)
{
    CHECK_EQUAL (3, GetSomeValue());
}
</code></pre><p><strong>Put tests into a separate executable.</strong></p>
<p><img alt="file structure" loading="lazy" src="/stepping-through-the-looking-glass-test-driven-game-development-part-1/images/file_structure.png"> I recommend splitting your code into many separate libraries, each of them dealing with one specific subject: sound, networking, AI, scene management, physics, bitmaps, file IO, input, etc, etc. That&rsquo;s just a good practice whether you&rsquo;re doing TDD or not. Extra bonus points for managing dependencies between libraries correctly and avoiding cyclical dependencies.</p>
<p>For each library, create a new executable that contains the tests for that library. My preferred directory structure looks something like this, but feel free to organize it in any way you like</p>
<p>I definitely don&rsquo;t want my tests in the same file as the class they&rsquo;re testing. I try to keep the class as simple as possible, and that would just add clutter. Some people prefer to put the test files in the same directory as the files for the library itself. I like to keep them separate but nearby, especially because there&rsquo;s no one-to-one correspondence between library files and test files.</p>
<p><strong>Build and run tests often.</strong></p>
<p>Make sure to make the test executable dependent on the library it&rsquo;s testing (and linking with). As the final step of the build process, run the test itself. That way it&rsquo;ll be impossible to build a library without building the tests and running them. Since the tests should be very fast (taking less than a few seconds), this shouldn&rsquo;t get in the way of fast iteration.</p>
<p>Most unit-testing frameworks return by default the number of failed tests they encountered. Since calling that executable was part of the build process, if it returns anything other than zero, the build framework considers the build failed, which is exactly what you want. If you&rsquo;re using an IDE such as Visual Studio or KDevelop, you&rsquo;ll also get a nicely formatted error message that you can select and it&rsquo;ll go to the failing test. Tests have become an integral part of the build, and a failing test is treated just like a syntax error.</p>
<p>If you&rsquo;re using make files, just run the executable as your last step of the build rule:</p>
<pre tabindex="0"><code>test: 
    $(objects) ${COMPILER} -o test $(objects) ${LIBFLAGS} 
    ./test
</code></pre><p>With Scons, just use AddPostAction:</p>
<pre tabindex="0"><code>test = env.Program(&#39;test&#39;, list) 
env.AddPostAction(test, &#39;./test&#39;)
</code></pre><p>In Visual Studio, call $(TargetPath) as your PostBuild rule.</p>
<p>Make sure the test executables are built and run in your automated build machine as well. Do both debug and release, and if you can also run them in your target platforms (Xbox, PS2, or whatever), so much the better.</p>
<p><strong>Step size.</strong></p>
<p>Before letting you loose with the TDD tools in hand, it&rsquo;s important to talk about step size. Before you start a TDD cycle, you need to decide how much functionality you should tackle in that one cycle. It&rsquo;s extremely important that you start by taking baby steps. Don&rsquo;t worry about the fact that it looks silly or pointless. The point at first is to get comfortable with the cycle and to get the hang of it.</p>
<p>A full iteration of the TDD cycle should take just a few minutes (and sometimes less than a minute). If it takes significantly longer than that to get your tests running again (&gt;15 minutes), it probably means that you tried taking too big a step. If you find yourself in that situation with no obvious way to make the tests pass, you might even want to consider undoing what you did and starting again with an even simpler task.</p>
<p>The concept of step size is very important. Choosing the right step size is probably the hardest part of TDD, and it only comes with experience and tripping a few times. At the beginning, you should start with trivial steps and stick with it. Once you&rsquo;re totally comfortable with it, you can take steps a bit larger. But as soon as you find yourself with unexpected failing tests or taking too long before getting passing tests again, you should back off and take baby steps again for a while.</p>
<p>We&rsquo;ll see some specific examples of TDD in action in the second part of this article, which will show how you can take tiny steps.</p>
<h3 id="resources">Resources</h3>
<ul>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0321146530/ref=nosim/gamesfromwith-20/102-6548099-6063309"><em>Test Driven Development: By Example</em></a> by Kent Beck. The first book you should read.</li>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0131016490/ref=nosim/gamesfromwith-20/102-6548099-6063309"><em>Test Driven Development: A Practical Guide</em></a> by Dave Astels. If you are dying to read more.</li>
<li><a href="http://www.testdriven.com/modules/news/">TestDriven.com</a>. Good portal to test-driven topics.</li>
<li><a href="http://groups.yahoo.com/group/testdrivendevelopment/">testdrivendevelopment mailing list</a>.</li>
</ul>
<p>Now you should have a good idea of what TDD is and what&rsquo;s involved in actually doing it. But TDD is like riding a bicycle. You can read all you want about it, but eventually, you&rsquo;ll have to try it for yourself if you want to learn it. I hope this is enough information for you to go out and take it out for a quick spin.</p>
<p>The second part of this article will deal with how to applying TDD to game development (with specific examples) and will cover tips from the trenches and what you can expect when applying TDD to your projects.</p>]]></content:encoded></item><item><title>How Incredible Is Incredibuild?</title><link>https://gamesfromwithin.com/how-incredible-is-incredibuild/</link><pubDate>Sun, 06 Feb 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/how-incredible-is-incredibuild/</guid><description>&lt;p&gt;There is no doubt that &lt;a href="http://www.xoreax.com/"&gt;Xoreax&amp;rsquo;s Incredibuild&lt;/a&gt; will speed up most full builds of C++ projects using Microsoft Visual C++ to varying degrees. I&amp;rsquo;m not going to argue that. But is using Incredibuild in your project really a good idea?&lt;/p&gt;</description><content:encoded><![CDATA[<p>There is no doubt that <a href="http://www.xoreax.com/">Xoreax&rsquo;s Incredibuild</a> will speed up most full builds of C++ projects using Microsoft Visual C++ to varying degrees. I&rsquo;m not going to argue that. But is using Incredibuild in your project really a good idea?</p>
<p>Chances are that if you&rsquo;re reading this, you already know what <a href="http://www.xoreax.com/">Xoreax&rsquo;s Incredibuild</a> is. If not, here&rsquo;s the quick summary: Incredibuild is a distributed build system for Microsoft Visual C++ that recruits other machines in the network to parallelize your build; it claims build time reductions of up to 90%. There is no doubt that Incredibuild will speed up most full builds of C++ projects using Microsoft Visual C++ to varying degrees. I&rsquo;m not going to argue that. But is using Incredibuild in your project really a good idea?</p>
<p>Let&rsquo;s start with the positives. Incredibuild does work as advertised and can produce significant speed ups from distributing your build. It is well polished and it has clearly been tested in real-world application development. It has good load balancing, you won&rsquo;t notice your machine being used as a slave, it has the concept of backup coordinators, it minimizes network usage, etc, etc. It does have a few technical glitches, but I&rsquo;ll get to those later. All in all, it&rsquo;s pretty robust and well-thought-out product, and there are clearly <a href="http://www.xoreax.com/purchase_testimonials.htm">lots of people happy with it</a> (interestingly, the list includes many game developers).</p>
<p>So, what&rsquo;s not to like? When I started using Incredibuild last year, I was initially floored by the results. A project that would take 45 minutes to compile, would only take about 5-8 minutes with Incredibuild. Wow! That&rsquo;s what I call a â€œsignificantâ€ speedup!</p>
<p>However, the more I used it, the more it started getting in the way and the more it made me think about all the areas where it was lacking. Be warned that this doesn&rsquo;t pretend to be a rigorous review with objective data to back up what I&rsquo;m saying. These are the issues I&rsquo;ve encountered using Incredibuild without trying to become an expert at it. It&rsquo;s very likely that are ways around some of the things I&rsquo;m going to complain about. If so, feel free to let me know in the comments below. Maybe I&rsquo;ll change my mind and I&rsquo;ll become an Incredibuild fan after all.</p>
<h3 id="iteration-time">Iteration time</h3>
<p><img alt="tools" loading="lazy" src="/how-incredible-is-incredibuild/images/tools.jpg"> <strong>Slow incremental builds.</strong> I don&rsquo;t mean incremental linking (that comes next), I mean non-full builds, like the case where I change a single line in a cpp file and want to generate a new executable. I found that using Incredibuild for such builds is significantly slower than the regular build in MSVC (incidentally, <a href="http://www.xoreax.com/support_faq.htm#q6">this FAQ</a> claims exactly the opposite). I like to compile my code after every single change. Actually, I like to compile it and run all the tests after every single change. I&rsquo;ll often even do it while I&rsquo;m thinking. It&rsquo;s a (good) habit you get in after you&rsquo;ve been doing test-driven development for a while. Anything that slows down that cycle is a major impediment. So what if I do incremental builds with the regular MSVC build and just use Incredibuild for full rebuilds? Read on&hellip;</p>
<p><strong>Problems mixing and matching object files.</strong> Mixing and matching object files created by Incredibuild and MSVC seems to work&hellip; sometimes. I know in their <a href="http://www.xoreax.com/support_faq.htm">FAQ</a> they indicate a few changes you need to do to the debug information settings to prevent some errors. I&rsquo;m talking about bigger issues. As in, the executable generated is total garbage and crashes right away. Usually doing a full rebuild with Incredibuild fixes it (sit and wait 5-8 minutes). When this is caused just by changing a single cpp file, it gets old very quickly and you start questioning the benefits you&rsquo;re getting in the first place.</p>
<p>I found that I have similar problems matching object files with incremental linking turned on (this time in the form of errors during the build). The only way I&rsquo;ve managed to more or less reliably mix both types of object files is by turning off incremental linking completely. Of course, link times are often the bottleneck of the change-build-test cycle, being as high as a full minute or more when you&rsquo;re dealing with the whole game. Incremental linking, as long as you&rsquo;re only modifying the executable project, is really a god-send and can reduce a 1+ minute link time to just a couple of seconds. Again, turning it off to be able to use Incredibuild seems a step backwards.</p>
<p><strong>No edit and continue.</strong> I admit it, I&rsquo;ve never been a fan of edit and continue. But some people swear by it, and it&rsquo;s yet another feature you can&rsquo;t have turned on with Incredibuild. Interestingly, their FAQ fails to mention the words â€œincremental linkingâ€ or â€œedit and continueâ€ anywhere. (Actually, they had it under <a href="http://www.xoreax.com/support_knownissues.htm#ki02">&ldquo;known issues&rdquo;</a>).</p>
<h3 id="technical-issues">Technical issues</h3>
<p><strong>Tied to Microsoft Visual Studio.</strong> Are you developing for other platforms than Windows or Xbox? Are you using other compilers than Visual C++? Then you&rsquo;re out of luck. You&rsquo;ll have to come up with a totally different system to build your code for those platforms. You can&rsquo;t use the same build back end because Incredibuild is totally tied to MSVC. I don&rsquo;t know exactly why, I just hope they had a very good technical reason and it wasn&rsquo;t to get prettier integration with colorful progress graphics. At least it is possible to run Incredibuild from the command line (still using MSVC of course), which is essential for build machines. <strong>Update:</strong> msew just pointed out that <a href="http://www.xoreax.com/company_news022.htm">version 2.20 has beta support for the Inteal compiler</a>. Good to hear that.</p>
<p><strong>Uses Microsoft Visual Studio&rsquo;s build system.</strong> If I could rip one thing from Visual Studio, it would be the completely broken build system. I don&rsquo; t know what they were thinking when they built it, and I have a very hard time believing anybody at Microsoft uses it for complex projects. It seems a great quick way to get toy projects off the ground, but it doesn&rsquo;t scale well at all to large projects (very much like those GUI wizards, but people seem to put up with them anyway). In a real build system I want to have multiple targets (and combinations of those targets), I want to be able to enforce build order, I want to be able to choose <strong>not</strong> to link a project just because I make it dependent on another project, I want to be able to have over a hundred different projects in an environment and not bog down because of it, I want to be able to view and change build settings easily across projects. In other words, I want primarily something like make, Jam, or Scons. Fortunately, MSVC allows you to have makefile projects, but Incredibuild <a href="http://www.xoreax.com/support_faq.htm#q33">doesn&rsquo;t support them</a>. This is particularly important to me because I would like to use a common back end for all the different platforms, and I&rsquo;d love to have a single build file that I can use to build any project or platform combination.</p>
<p><strong>Failing to build correctly.</strong> Every so often, a build with Incredibuild will completely fail because some dependency check failed along the way (this seems to happen particularly when changing header files outside of the project itself, like middleware or other external APIs). To be fair, this seems to happen just as frequently in MSVC with regular builds using pre-compiled headers, so you probably can&rsquo;t blame Incredibuild for it. It certainly doesn&rsquo;t fix the problem though.</p>
<p><strong>Builds are done differently than local ones.</strong> I haven&rsquo;t investigated this one thoroughly, but Incredibuild uses slightly different rules than regular, local builds. As a result, it is possible to set up a build with custom rules that builds correctly in Incredibuild, but fails as a regular build. If you&rsquo;re trying to mix and match the two, that can&rsquo;t be good news. I think the source of the problem is that Incredibuild runs custom build rules locally as the first step of the build, and then distributes the rest. Regular local builds will call the custom build rule when they get to the file in question, so you can see how there&rsquo;s a slight potential for problems there (this, incidentally, is not idle nit picking, but happened in a real project).</p>
<h3 id="performance">Performance</h3>
<p><strong>Network issues can affect performance significantly.</strong> For a while, Incredibuild kept having all sorts of problems communicating across the network and was causing builds to either take forever or never complete (some slave machine would just never return a result or timeout). I don&rsquo;t know if that was caused by glitches in our network, too many people using it, or bugs in Incredibuild, but it was highly annoying. I suppose you&rsquo;re bound to have that happen in any distributed system, but I would expect them to always be able to fall back to local compilation and not take any longer than a non-distributed build.</p>
<p><strong>How much faster than a regular full build?</strong> This is the big question. I have seen with my own eyes that using Incredibuild on a project without physical insulation and carefully managed dependencies, and without precompiled headers, can make the build be many, many times faster. But how does it compare to a project that has been carefully managed, with well-thought-out precompiled headers? As an experiment, I retrofitted a large codebase to use precompiled headers. The awful physical dependencies were still there, and I&rsquo;m sure the precompiled headers were less than ideal. Still, build times went down from 45 minutes to something like 10 minutes. Incredibuild took 5-8 minutes in that same codebase. Throw a faster machine with multiple cores (the future of PCs), and a decent build system that can use multiple threads (not MSVC, go figure), and I think you can get similar build times without any of the drawbacks.</p>
<h3 id="architectural-issues">Architectural issues</h3>
<p>Here is one argument that cuts both ways.</p>
<p>Programmers will often try to avoid making changes that cause full rebuilds (to avoid spending 30+ minutes waiting for a result), but they end up doing it by hacking things in the wrong place: duplicating code, declaring externs by hand on the wrong file, etc. Ideally, you shouldn&rsquo;t have many files that can cause a full rebuild (if you do, you have a big problem), but if you need to make a change there, you really should do it. Incredibuild can ease the pain of a full rebuild and prevent the hack, leading to a cleaner codebase and architecture.</p>
<p>On the other hand, having Incredibuild around can cause developers to throw caution to the wind and think they don&rsquo;t have to worry about physical dependencies anymore. As a result, they end up with <a href="http://www.antipatterns.com/briefing/sld024.htm">the blob antipattern</a>. Ironically, after a few months of that, they&rsquo;ll probably end up with really slow build times again (because almost every file causes a full rebuild).</p>
<p>Is the time spent in managing and minimizing <a href="/physical-structure-and-c-part-1-a-first-look/%20">physical dependencies</a> worth it? Absolutely! Low physical dependencies also means low logical dependencies. Even if build times were instant, you would still be well advised to pay very close attention to dependencies and minimize them (not just for reuse or maintenance, but even during the development of the game, since it makes it much easier to refactor or change any part of your program).</p>
<h3 id="alternatives">Alternatives</h3>
<p>What are the alternatives to Incredibuild then? Are we stuck with really slow builds?</p>
<ul>
<li>Manage your physical dependencies. Be as careful as you can about them, and you&rsquo;ll be way on your way towards minimizing build times. Use the <a href="http://c2.com/cgi/wiki?PimplIdiom">pimpl idiom</a> in any header that is used extensively throughout the codebase.</li>
<li>Use precompiled headers. Stay away from that option of â€œautomatic precompiled headersâ€ in MSVC because it does more harm than good. Use <a href="http://www.cygnus-software.com/papers/precompiledheaders.html">Bruce Dawson&rsquo;s paper</a> as a starting point about precompiled headers. Also, precompiled headers are supported across the board for most popular C++ compilers: MSVC, gcc, Codewarrior, etc, so you can get a lot of benefits from a single approach.</li>
<li>Get a <strong>fast</strong> dual-core machine and use multiple threads to build. You can&rsquo;t do that with MSVC, but man, Jam and Scons can certainly do it. I stress the fast CPU part. In the past, I ran some tests, and, assuming you have enough memory, compilation time was not limited by disk space but by CPU speed. Once you start using multiple threads it&rsquo;ll put more stress on the disk so it&rsquo;ll probably be a good idea to get fast hard drives as well.</li>
<li><a href="http://distcc.samba.org/">distcc</a>. I admit I&rsquo;ve only tested distcc in toy sample projects, but it&rsquo;s exactly what I would like on paper: a fairly generic distributed build system. It comes with gcc support out of the â€œbox,â€ but it can be extended to support other compilers. It uses a very clean way of distributing the builds, by running the preprocessor locally and sending the output file to be compiled into an object file. I really don&rsquo;t know how it scales for a real-world project, but I&rsquo;d like to learn more about it.</li>
<li><a href="http://www.scons.org/">Scons</a>&rsquo; network cache. Scons can transparently cache object files on the network, so if you ever try to build a file that is already in the cache, you&rsquo;ll get it instantly. This can be a reasonable solution to avoiding full rebuilds after one person (or the build machine) has done it once.</li>
</ul>
<h3 id="conclusion">Conclusion</h3>
<p>If you&rsquo;re stuck with some legacy code that takes forever to compile, don&rsquo;t hesitate to get Incredibuild. It&rsquo;ll do wonders for your project and will cut down your build times by a huge amount. If you&rsquo;re developing on a new code base, or your build times are short already, I would recommend against using it. For the project I&rsquo;m starting now, we&rsquo;re starting without Incredibuild (even though we already have the licenses, so it&rsquo;s not a money issue) and we&rsquo;re carefully managing physical dependencies and using precompiled headers. If at some point it grows very large and we see benefits from Incredibuild, we might switch, but until then, we&rsquo;re a lot better off without it.</p>]]></content:encoded></item><item><title>Even More Experiments with Includes</title><link>https://gamesfromwithin.com/even-more-experiments-with-includes/</link><pubDate>Wed, 26 Jan 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/even-more-experiments-with-includes/</guid><description>&lt;p&gt;One aspect of the scientific process is publishing detailed experiment descriptions and results so that they can be independently verified by other scientists. That&amp;rsquo;s exactly what I decided to do after reading Kyle Wilson&amp;rsquo;s surprising results in his article &amp;ldquo;&lt;a href="http://gamearchitect.net/Articles/ExperimentsWithIncludes.html"&gt;Experiments with Includes&lt;/a&gt;.&amp;rdquo;&lt;/p&gt;</description><content:encoded><![CDATA[<p>One aspect of the scientific process is publishing detailed experiment descriptions and results so that they can be independently verified by other scientists. That&rsquo;s exactly what I decided to do after reading Kyle Wilson&rsquo;s surprising results in his article &ldquo;<a href="http://gamearchitect.net/Articles/ExperimentsWithIncludes.html">Experiments with Includes</a>.&rdquo;</p>
<p>Kyle found that using <a href="http://c2.com/cgi/wiki?RedundantIncludeGuards">internal include guards</a> was significantly slower than using #pragma once with the C++ compiler in Microsoft Visual Studio 2003 and 2005 beta. That just flies in the face of the <a href="/physical-structure-and-c-part-1-a-first-look/%20">measurements I had done before</a> and what <a href="http://sourceforge.net/mailarchive/message.php?msg_id=2704308">other people had reported</a>. How was it possible?</p>
<p>The first thing that struck me when looking at Kyle&rsquo;s results is that he&rsquo;s using an extremely pathological case: 200 header files, each of them including all 200 headers. Still, the point is to measure header include performance, so maybe that was fine. More on that later.</p>
<p>The first thing I did was to write a <a href="/wp-content/uploads/bin/generate_includes.py">quick script</a> to generate a set of header files and main file given some parameters. I took the chance to write in Python, which displaced Perl as my favorite scripting language a few months ago. The script will generate a certain number of header files, using either no guards, internal guards, external guards, or pragma statements. In order to be able to compile no guards (and to keep things a bit more realistic), I actually had each header file include all the header files with numbers higher than itself. Feel free to download the script and play with it if you want to run the measurements yourself.</p>
<p><img alt="jungle" loading="lazy" src="/even-more-experiments-with-includes/images/stopWatch.jpg"> Since I&rsquo;m running Linux at home, I first ran the experiment with gcc 3.4.1. First I tested no guards, but I had to keep it to a set of 20 header files to avoid taking forever with an astronomical number of includes (they really add up combinatorially!). As expected, even a 20x20 half-matrix of includes too a while to compile: 2+ minutes. The same set of headers with internal include guards was just a blip at 0.15s. So far, so good. That&rsquo;s what I expected.</p>
<p>Now I cranked things up to 200 headers like Kyle had done. Here comes the first surprise of the day: gcc blows up trying to parse that many includes. I get a â€œ#include nested too deeplyâ€ error. Digging through the <a href="http://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Invoking-GCC.html#Invoking%20GCC">gcc documentation</a> I wasn&rsquo;t able to find any way to increase that depth. That made me realize that having include chains of 200+ headers is completely unrealistic. I knew that it was artificially large, but it&rsquo;s probably so by an order of magnitude at least.</p>
<p>Still, just for the test, I decided to go ahead. It turns out it was choking very near the end, so doing a run with 195 headers worked just fine. The results were what I would have expected. A bit better actually, and certainly much better than the results Kyle saw in Visual Studio: all the runs (internal guards, external guards, and pragma) took about the same time (0.07 seconds), and each of them included exactly 195 headers. No more, no less. That&rsquo;s exactly how I would expect the compiler to behave.</p>
<p>gcc 3.4.1 (Linux with 2.6 kernel). 195 headers.</p>
<ul>
<li>Internal guards: 0.07s</li>
<li>External guards: 0.09s</li>
<li>Pragma directive: 0.07s</li>
</ul>
<p>At work, I&rsquo;m not as lucky, and I have to use Windows and Microsoft Visual Studio, so I ran the second set of tests there. The results confirmed what Kyle reported: The internal guards were very slow (14+ seconds), the external guards where blazingly fast (0.37 seconds), and the pragma directive was somewhere in between (9.6 seconds).</p>
<p>Microsoft Visual Studio 2003. 195 headers.</p>
<ul>
<li>Internal guards: 14.7s</li>
<li>External guards: 0.37s</li>
<li>Pragma directive: 9.57s</li>
</ul>
<p>I was pretty amazed to see that. It seems like a major flaw in the Visual C++ compiler, doesn&rsquo;t it?</p>
<p>To round out the tests, since I had the Metrowerks PS2 compiler handy, I decided to run the same set of tests with it. It turns out that it completely blew up, complaining of includes nested too deeply with the project with 195 headers. To my surprise, I had to lower the number of includes to 30 in order to be able to compile it at all. Anything over 30 would cause it to blow up.</p>
<p>That made me think again about the worst cases I would see in a typical project, and I realized that having over 30 includes deep at once is probably very, very rare, even if you&rsquo;re using STL or Boost, which make heavy use of header files.</p>
<p>Just for the sake of completeness, I decided to run the tests with just 30 includes and see if I could discern any patterns from the results. It turns out that Metrowerks is pretty slow overall, but at least the differences between the three approaches are minimal.</p>
<p>Metrowerks PS2 compiler v3.0. 30 headers.</p>
<ul>
<li>Internal guards: 0.60s</li>
<li>External guards: 0.46s</li>
<li>Pragma directive: 0.49s</li>
</ul>
<p>I ran the same set of tests with Visual Studio and it showed the external includes being the clear winner, but internal and pragmas being almost the same. I wonder if Visual C++ uses some dynamic algorithm that avoids having a fixed hard limit on include depth at the cost of runtime performance. I&rsquo;ll take a fixed depth and flawless behavior like gcc any day personally.</p>
<p>Microsoft Visual Studio 2003. 30 headers.</p>
<ul>
<li>Internal guards: 0.48s</li>
<li>External guards: 0.14s</li>
<li>Pragma directive: 0.41s</li>
</ul>
<p>gcc was so fast with such a tiny project that I couldn&rsquo;t reliably measure it. But if the 195 includes was taking 0.07 seconds, you can guess how fast it churned through just 30 header files.</p>
<h3 id="conclusion">Conclusion</h3>
<p>It does seem that Microsoft Visual Studio has some major problems with includes in pathological situations. On the other hand, it also seems that those situations are completely unrealistic and will never happen in a real code base. For a more realistic situation (30x30 half matrix), internal guards and pragmas are the same, and external guards have somewhat of an edge.</p>
<p>gcc behaved like a real champion by being super fast and efficient no matter what technique you threw at it. Way to go! The Microsoft compiler certainly could stand some improvement in that area.</p>
<p>Metrowerks was the slowest of the bunch, but it dealt with all the different techniques just fine for a relatively small set of tests.</p>
<p>Overall, there should be no real difference between using internal guards and pragma directives (which happily confirms some of the measurements we had done in real code bases). So stick with internal guards, which are standard and work on any compiler, but if adding a #pragma once directive surrounded by conditionals (because it&rsquo;s not standard and it&rsquo;s not supported in all the compilers) in addition to the internal guards would make you sleep better, go for it. External guards might have an edge with Visual Studio, but the pain and potential trouble of using external guards clearly outweighs any speed benefits gained by using them.</p>
<p><a href="/wp-content/uploads/bin/generate_includes.txt"><img alt="icon" loading="lazy" src="/even-more-experiments-with-includes/images/script.png"> generate_includes.py</a></p>]]></content:encoded></item><item><title>So You Want to Be a Game Programmer?</title><link>https://gamesfromwithin.com/so-you-want-to-be-a-game-programmer/</link><pubDate>Mon, 24 Jan 2005 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/so-you-want-to-be-a-game-programmer/</guid><description>&lt;p&gt;I often get email from people looking to get their first job in the game industry asking me for advice. What are companies looking for in candidates for entry-level programming positions? How come it&amp;rsquo;s so difficult to land a job? I can&amp;rsquo;t answer for the industry as a whole, but I can certainly tell you what I am looking for when trying to fill an entry-level programmer position.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I often get email from people looking to get their first job in the game industry asking me for advice. What are companies looking for in candidates for entry-level programming positions? How come it&rsquo;s so difficult to land a job? I can&rsquo;t answer for the industry as a whole, but I can certainly tell you what I am looking for when trying to fill an entry-level programmer position.</p>
<p>A few weeks ago, Joel <a href="http://joelonsoftware.com/articles/CollegeAdvice.html">wrote an article</a> with advice for college students looking to become programmers. It was good, solid advice overall, but it was a bit too general, and it didn&rsquo;t apply very well to the games industry. I often get email from people looking to get their first job in the game industry asking me for advice. What are companies looking for in candidates for entry-level programming positions? How come it&rsquo;s so difficult to land a job? I can&rsquo;t answer for the industry as a whole, but I can certainly tell you what I am looking for when trying to fill an entry-level programmer position.</p>
<p>Specifically, I&rsquo;m going to concentrate on the case of someone without any previous industry development experience applying to game companies for the first time, possibly straight out of college. At the end I&rsquo;ll touch on people switching industries with previous experience in other software industries. If you&rsquo;re already in the games industry, then you already have a pretty good idea how you got there, and that experience will carry you forward much more easily than someone trying to break in for the first time. Still, you should be able to meet all these requirements in spades for your next job interview, so you might want to read on anyway.</p>
<p>The type of job openings you&rsquo;ll be looking for are usually referred to as junior programmer, entry-level programmer, associate programmer, or something similar. Sometimes it&rsquo;ll be listed simply as programmer but they&rsquo;ll specify that previous experience is not required.</p>
<p>What exactly am I looking for, then, in an entry-level programmer candidate? Here is what I&rsquo;d like to see, roughly in order of importance.</p>
<h3 id="enthusiasm">Enthusiasm.</h3>
<p>Maybe this goes without saying, but I figured I would put it as my number one item. If you aren&rsquo;t extremely enthusiastic about developing games for the first time, you might as well look for something else. In a couple of years you&rsquo;ll be extremely disappointed and will be thinking of switching industries anyway.</p>
<p>How do you show this enthusiasm of yours? Working on a project of your own is an excellent way of convincing potential employers that you really care about this stuff. Write some small games, participate in some open-source projects, make some mods, do whatever you want, but work on some game-related projects. I would recommend working on several small projects, and then try to work on one larger one to get exposure to several areas and get experience working on a large code base.</p>
<p>Make sure to bring up those projects in your resume and put them on your web page (yes, we do check web pages and google for people before bringing them in for an interview). In a way, they&rsquo;re the closest thing you have to experience in the industry. Be ready to discuss your project, why you did things in certain ways, ask how other people deal with particular issues, etc.</p>
<h3 id="always-learning">Always learning.</h3>
<p><img alt="textbooks" loading="lazy" src="/so-you-want-to-be-a-game-programmer/images/textbooks.jpg"> You&rsquo;re about to finish your college education. If you think you&rsquo;re done learning, think again. You&rsquo;ve just finished the base that allows you to continue learning. Especially in this always-changing industry, you will always be learning new things: new platforms, new APIs, new languages, new approaches, new styles, new everything. Don&rsquo;t think for a moment you can learn a couple of things and then stick to them without learning anything new.</p>
<p>It&rsquo;s great to be confident in your skills, but if I catch a whiff that the candidate is set in his ways and is not interested in learning anything new, it&rsquo;s &ldquo;hasta la vista, baby.&rdquo;</p>
<p>So go out and learn new things. I always like to be reading a technical book on things directly applicable to what I do at work, and maybe some on things that are more off-the-wall. In addition, I recommend reading trade magazines (<a href="http://gdmag.com/"><em>Game Developer Magazine</em></a>, <a href="http://www.sdmagazine.com/"><em>Software Development</em></a>, <a href="http://cuj.com/">C/C++ Users Journal</a>, etc), conference journals (<a href="http://gdconf.com/">GDC</a>, <a href="http://www.siggraph.org/">Siggraph</a>, <a href="http://www.acm.org/">ACM</a>), web sites (<a href="http://gamasutra.com/">Gamasutra</a>, <a href="http://flipcode.com/">Flipcode</a>, <a href="http://www.gamedev.net/">GameDev.net</a>), mailing lists (<a href="http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list">gd-algorithms</a>, <a href="http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com">sweng-gamedev</a>, <a href="http://sourceforge.net/projects/gamedevlists/">gd-general</a>), and just about anything you can get your hands on. Don&rsquo;t be afraid to look at open source projects (<a href="http://nebuladevice.cubik.org/">Nebula Device</a>, <a href="http://crystal.sourceforge.net/">Crystal Space</a>), figure out how they do things, and even participate in their development.</p>
<p>The book <em><a href="http://www.amazon.com/exec/obidos/ASIN/020161622X/ref=nosim/gamesfromwith-20">The Pragmatic Programmer</a></em> recommends learning one new computer language every year. It might be a bit of overkill, but it&rsquo;s certainly not a bad idea. Even if you&rsquo;re not planning on using <a href="http://www.smalltalk.org/">Smalltalk</a> or <a href="http://www.ruby-lang.org/">Ruby</a>, it can only broaden your skillset and give you new perspectives on things. Learn about garbage collection, dynamic languages, etc. Of course, make sure you have the basics covered and you have a good grasp of C and C++ before you branch into other languages.</p>
<h3 id="plays-games">Plays games.</h3>
<p>Doh! If you&rsquo;re going to be developing games, you better play games on a regular basis. You don&rsquo;t have to be a hardcore player, but you should enjoy playing some games. Be ready to discuss your tastes in games, what you&rsquo;re played recently, why you liked them, etc. It&rsquo;s not like you&rsquo;re going to be designing the games (after all, you&rsquo;re applying for a programming position), but it&rsquo;s good to have an idea of what you&rsquo;re aiming for when you&rsquo;re creating a game. Also, the more you enjoy playing games, the more of a reason you have to actually want to work on them.</p>
<p>In my time in the industry, I&rsquo;ve only known one programmer who didn&rsquo;t play any games (and he was extremely talented to boot), but he was certainly the exception to the rule. If you don&rsquo;t like games, you better have a really good reason as you why you want to get in this business.</p>
<h3 id="skills">Skills.</h3>
<p>Ah, yes. It finally had to come up. As an entry-level programmer, you&rsquo;re expected to learn a lot on the job, but you need certain skills to be useful and productive from the very beginning. Hobbyist game programmers obsess about DirectX and OpenGL. That&rsquo;s fine, but don&rsquo;t worry too much about it. You&rsquo;re not going to see a single line of those APIs unless you&rsquo;re hired as a graphics specialist (unlikely for a junior-level position). The specific skills will depend on the exact job and company, but these are pretty universal given what typical junior programmers get to work on.</p>
<ul>
<li>Fluent in C++. Most game development (for PCs and game consoles) these days is done in C++, so you&rsquo;d better be comfortable with the language. Knowing the syntax and compiling â€œHello worldâ€ isn&rsquo;t good enough. A class in college isn&rsquo;t going to cut it either. The ideal candidate will have at least read <em><a href="http://www.amazon.com/exec/obidos/ASIN/0201924889/ref=nosim/gamesfromwith-20">Effective C++</a></em> and will have used C++ in some significant projects (either your own projects, or in some term projects at school). You should be able to discuss the order in which destructors are called for classes with inheritance, when you need to provide a copy constructor, or what const-correctness is and why is it a good idea. If not, hit the books right away.</li>
<li>Basic 3D linear algebra. As an entry-level programmer, you&rsquo;ll most likely work extensively on high-level game code at first. To do things effectively, you&rsquo;ll need a good understanding of the fundamentals of 3D linear algebra. Make sure you know your dot and cross products, how to calculate them, but, most importantly, what they represent and when you should use them. You should be comfortable with relative coordinate systems, and matrices as transforms (I don&rsquo;t care if you know the formula for a rotation matrix, just that you know how to use it). Calculating if an object in the world is within a certain distance from the player, and within a certain angle of its aiming direction, should be close to second nature. Review your linear algebra books from college or check out <em><a href="http://www.amazon.com/exec/obidos/ASIN/1584502770/ref=nosim/gamesfromwith-20">Mathematics for 3D Game Programming and Computer Graphics</a></em></li>
<li>Software engineering. This is not a requirement for total entry-level positions, but it&rsquo;s certainly a nice bonus. Unfortunately it&rsquo;s not often emphasized (or even taught) in many schools, but being familiar with good software engineering practices is very important. Learn all you can about good object-oriented design, design patterns, encapsulation, unit testing, physical insulation, etc. There&rsquo;s more to programming than knowing a language or API. This is difficult for people straight out of college, but it&rsquo;s a huge bonus when you have it. Internships could help with this, but they&rsquo;re not nearly as crucial for me as Joel says. I&rsquo;d rather see an impressive set of home projects than a couple of summers working at IBM or Sun (on one hand I see a guy with lots of internal drive, and another one that needs to be told what to do and needs guidance). Having both would be awesome.</li>
<li>Tools. I certainly don&rsquo;t expect new programmers to be familiar with the exact tools we happen to use. However, the ideal candidate should be familiar with version control, should know how to use a debugger, etc.</li>
</ul>
<h3 id="ability-to-get-things-done">Ability to get things done.</h3>
<p>As an entry-level programmer, you&rsquo;re going to be thrown in the water and you&rsquo;re going to have to figure out a lot of things by yourself. Sure, you&rsquo;ll hopefully get some supervision, and people will be able to answer a lot of your questions and work with you. But you&rsquo;ll be expected to tackle something, learn about it, and get it done.</p>
<p>Here&rsquo;s one that I completely agree with Joel: Make sure you get a degree, and do the best job you can with it. Sure, a degree doesn&rsquo;t measure many things, but getting a good GPA means that you were able to stick with something for four years, even when things got tough or when you had to do things that you didn&rsquo;t feel like working on. Working in games is not all fun (even if it&rsquo;s all games), so making sure that people are not easily discouraged and can get things done is very important.</p>
<p>Another way of showing that is, as I said earlier, by working on projects on your spare time. That shows someone who went to the effort of creating something while learning something new. It doesn&rsquo;t have to be a super-polished, finished game, but it should be more than a couple of classes that compile without errors and print â€œOKâ€.</p>
<h3 id="well-rounded-education">Well-rounded education.</h3>
<p>Knowing things outside of games is a good thing (knowing the detailed history of the <em>Star Wars</em> universe doesn&rsquo;t really count). Taking and doing well in classes in a variety of topics in college is a good start. You may think that your South American archaeology class will never be of any relevance, but you&rsquo;ll be surprised how things you learn there will come in useful in the most unexpected ways.</p>
<p>Make sure you do something beyond games. Take up a hobby of something totally unrelated. Some of the best candidates are art enthusiasts, practice sports seriously, are into oriental philosophy, or play the viola. I always ask about people&rsquo;s hobbies during an interview. Usually the weaker candidates won&rsquo;t have any hobbies or their only hobby is playing computer games.</p>
<p>I really think that if you&rsquo;re going to dedicate yourself professionally to games, you need to have some interests in other areas. Also, being familiar with wildly different subjects allows people to approach problems from a completely different angle and come up with very creative solutions. Don&rsquo;t discount the importance of a well-rounded education.</p>
<p>One thing you should not worry about at this point is specialization. If you have one in mind, that&rsquo;s fine, and share it with your employer so you can plan a way to get there. But keep in mind that at first, breadth is more important than depth. It&rsquo;ll be much better for you to learn as much as possible about game development in general. The brightest graphics guru who only knows about graphics will not be half as effective as he could be if he had broader experience developing games.</p>
<p>However, one specialty you can jump straight into is tools. Learn the APIs. Write some tools. Create an editor for an existing game. However, don&rsquo;t think of tools as a temporary thing to pay your dues. Tools are an extremely important part of game development, now more than ever, so <a href="http://www.gamasutra.com/gdc2004/features/20040324/moar_01.shtml">you can make a full career as a tools programmer</a>.</p>
<p>How about people from other software industries with some years of experience? There&rsquo;s a certain bias against them in the industry. On one hand, they&rsquo;re not considered to have the right &ldquo;experience,&rdquo; and then they ask for too much money because they have several years in development already. You can bring a lot of experience, and a lot of it will be different. That&rsquo;s very valuable, but the company needs to see that. Play that angle in your resume/interview. Explain how your skills can be invaluable to the company (and that also shows you&rsquo;re familiar with the development process). Doing a game-related project on the side can go a long way to convince a company that your heart is in the right place.</p>
<p>If you only take one thing away from this article, this should be it: Always be looking to learn new things. Always read new books. Always try new things. Always be willing to listen to and try a different approach. Someone like that will quickly gain a huge amount of experience and become an invaluable member of the team, but the converse (someone with lots of experience not willing to learn anything new) is nearly useless in a rapidly-changing field.</p>
<p>Having said all that, I&rsquo;m afraid we&rsquo;re not currently looking for any entry-level positions at <a href="http://sammystudios.com/">Sammy Studios</a>. We might be hiring again this summer, so check back then. In the meanwhile, hit the books and sharpen up those skills.</p>]]></content:encoded></item><item><title>Book Review: Waltzing with Bears</title><link>https://gamesfromwithin.com/book-review-waltzing-with-bears/</link><pubDate>Fri, 31 Dec 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/book-review-waltzing-with-bears/</guid><description>&lt;p&gt;Exactly a year ago today, I put up &lt;a href="https://gamesfromwithin.com/book-review-slack-getting-past-burnout-busywork-and-the-myth-of-total-efficiency/"&gt;the first article on Games from Within&lt;/a&gt;. It was a review of Tom DeMarco&amp;rsquo;s book &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0767907698/ref=nosim/gamesfromwith-20"&gt;&lt;em&gt;Slack&lt;/em&gt;&lt;/a&gt;. I thought it would make for a nice, symmetrical bookend to wrap the year up with a review for another book by DeMarco: &lt;em&gt;Waltzing with Bears&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;As the subtitle indicates, &lt;em&gt;Waltzing with Bears&lt;/em&gt; deals with managing risk in software development projects. Managing risk, not reducing risk, or removing risk. Do you think that low risk or even no risk is a good thing? Think again. One of the central points of the book is that a project with no risk is not worth doing. Yes, you read that correctly. Intrigued? Go and read the book right now.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Exactly a year ago today, I put up <a href="/book-review-slack-getting-past-burnout-busywork-and-the-myth-of-total-efficiency/">the first article on Games from Within</a>. It was a review of Tom DeMarco&rsquo;s book <a href="http://www.amazon.com/exec/obidos/ASIN/0767907698/ref=nosim/gamesfromwith-20"><em>Slack</em></a>. I thought it would make for a nice, symmetrical bookend to wrap the year up with a review for another book by DeMarco: <em>Waltzing with Bears</em>.</p>
<p>As the subtitle indicates, <em>Waltzing with Bears</em> deals with managing risk in software development projects. Managing risk, not reducing risk, or removing risk. Do you think that low risk or even no risk is a good thing? Think again. One of the central points of the book is that a project with no risk is not worth doing. Yes, you read that correctly. Intrigued? Go and read the book right now.</p>
<p><a href="http://www.amazon.com/Waltzing-Bears-Managing-Software-Projects/dp/0932633609%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0932633609"><img loading="lazy" src="/book-review-waltzing-with-bears/images/51-rl+HulCL._SL500_.jpg"></a></p>
<p>I have to admit that the idea caught me by surprise as well. Maybe because I was used to the high-risk environment of game development, I always thought the best thing you could do for a project was to minimize the risk. But, as the authors point out, a project with no risk is not worth doing. It&rsquo;s not going to enrich you in any way, and anybody can do it anyway. Their point is that risk and benefits are tied together. A project with a certain amount of risk will come with a certain amount of benefits.</p>
<p>Now that I&rsquo;ve gotten quite a bit into playing poker, I see it very much like the analysis of expectation in poker. You want to bet when there&rsquo;s a positive expected value, that is, when the potential benefits you&rsquo;ll get from the bet outweigh the potential loss of money. As with poker, you can choose little risk and little benefit situations, or you can aim for high risk but huge potential payoffs (especially in no-limit poker). What you want to avoid are dead-end situations with high risk and very little payoff.</p>
<p>In particular, the authors single out <a href="http://www.yourdon.com/books/coolbooks/notes/dmsummary.html">death march projects</a> as being of extremely low value.</p>
<p>On a death march, unflinching sacrifice from each and every project member is absolutely required. The project demands abandonment of personal life, tons of overtime, Saturdays and Sundays in the office, estrangement from family, and so on. Nothing less than total dedication to the project can be accepted.</p>
<p>Sounds strangely familiar, doesn&rsquo;t it? The book then goes on to say:</p>
<p>In our experience, the one common characteristic among death-march projects is low expected value. They are projects aimed at putting out products of monumental insignificance. The only real justification for the death march is that with value so minuscule, doing the project at normal cost would clearly result in costs that are greater than benefits. Only with heroic effort can one hope to make the pig fly.</p>
<p>Next time you&rsquo;re deep into your third 60+ hour week in a row, think about those statements again and try to look at the big picture of your project in a new light. That just adds more fuel to the fire to <a href="/all-work-no-play-makes-jack-a-dull-game-developer-part-1/">my arguments against extended overtime and death march projects in general</a>.</p>
<p>There are some things you need to watch out for if you&rsquo;re going to start directly managing risk in your organization. The biggest problem you might encounter is that to manage risk you need to be brutally honest about the current situation of the project and possible negative outcomes. In a company where risk management is not a usual activity, it may come across as being overly negative, and you might scare away developers or even upper management. It can be particularly dangerous to do in a company with a very macho, â€œcan-doâ€ attitude (also described in the book as testosterone-based decision making), which is unfortunately <a href="http://www.gamesfromwithin.com/articles/0405/000023.html">all too familiar in the games industry</a>.</p>
<p>One of the tools used throughout the book to describe projects and risks is probability curves. This emphasizes how things are not black and white. You don&rsquo;t necessarily answer the question â€œwhen is the project going to be completed?â€ with a firm date, but with a probability curve. Looking at it tells you how likely the project is of being completed by a particular date (assuming the analysis was done correctly). The more â€œnoiseâ€ and uncertainty there is in the project, the wider the curve is going to be. Unfortunately, it seems that it&rsquo;s describing the games industry to a T again, because we tend to have a lot of uncertainty in our projects with moving technology targets and a somewhat whimsical market.</p>
<p>Another very interesting observation brought up in <em>Waltzing with Bears</em> is the concept of â€œearly delivery.â€ Of all the games you worked on, how many of them were delivered early? Yeah, that&rsquo;s what I figured. Same thing with me. Not a single one. Early delivery is seen as somewhat of a taboo. As if you didn&rsquo;t work hard enough or you could have done a better job otherwise. So clearly, companies will never deliver a project earlier than the commit date. At best, they&rsquo;ll do it by the exact deadline. At worst, the project will slip. As long as the two only possible outcomes are â€œon timeâ€ or â€œlate,â€ then projects are very likely to keep being late. That&rsquo;s some food for thought.</p>
<p>Later in the book, in the chapter about risk mitigation strategies, the authors make one very astute observation that I&rsquo;ve seen repeated over and over in the projects I&rsquo;ve worked on: projects that finish late are almost always projects that started too late. Truer words were never spoken. There are often very good reasons why a project can&rsquo;t get started when it should (helping out another project, lack of funding, etc), but those weeks or months lost early on would be precious towards the end.</p>
<p>Perhaps it&rsquo;s because I have a hopeless <a href="http://c2.com/cgi/wiki?BreadthFirstLearning">breadth-first personality</a>, but I hate when books try to cover every single insignificant detail from the very beginning before giving you the big picture. I would much rather get a couple of passes, each building on what I learned in the previous one. That&rsquo;s exactly what <em>Waltzing with Bears</em> does, with the first 50 pages dealing with an introduction and motivation to risk management, and the remaining 140 pages covering the same material in more depth and giving it a more advanced treatment. More books should learn from that organization.</p>
<p>Just go ahead and read the book and then pass it on to your manager. It&rsquo;s short and well worth the read. The important thing is that somebody in your project should be actively managing risk and balancing how much risk you take versus what the potential benefits will be. Otherwise you might run into some very ugly situations that might lead to the cancellation of the project itself.</p>
<p>May 2005 be everything you hope for, and may your projects be managed wisely, with just the right amount of risk. Happy holidays to everybody!</p>]]></content:encoded></item><item><title>Exploring the C++ Unit Testing Framework Jungle</title><link>https://gamesfromwithin.com/exploring-the-c-unit-testing-framework-jungle/</link><pubDate>Wed, 29 Dec 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/exploring-the-c-unit-testing-framework-jungle/</guid><description>&lt;p&gt;&lt;strong&gt;Update (Apr 2010):&lt;/strong&gt; It&amp;rsquo;s been quite a few years since I originally did this comparison. Since then, &lt;a href="http://cnicholson.net/"&gt;Charles Nicholson&lt;/a&gt; and I created &lt;a href="http://unittest-cpp.sourceforge.net/"&gt;Unit Test++&lt;/a&gt;, a C/C++ unit-testing framework that addresses most of my requirements and wish-list items. It&amp;rsquo;s designed to be a light-weight, high-performance testing framework, particularly aimed at games and odd platforms with limited functionality. It&amp;rsquo;s definitely my framework of choice and I haven&amp;rsquo;t looked at new ones in several years because it fits my needs so well. I definitely encourage you to check it out.&lt;/p&gt;
&lt;p&gt;-&amp;mdash;&amp;mdash;&amp;mdash;&lt;/p&gt;
&lt;p&gt;One of the topics I&amp;rsquo;ve been meaning to get to for quite a while is the applicability of test-driven development in games. Every time the topic comes up in conversations or mailing lists, everybody is always very curious about it and they immediately want to know more. I will get to that soon. I promise!&lt;/p&gt;
&lt;p&gt;In the meanwhile I&amp;rsquo;m now in the situation that I need to choose a unit-testing framework to roll out for my team at work. So, before I get to talk about how to use &lt;a href="http://www.testdriven.com/modules/news/"&gt;test-driven development&lt;/a&gt; in games, or the value of unit testing, or anything like that, we dive deep into a detailed comparison of existing C++ unit-testing frameworks. Hang on tight. It&amp;rsquo;s going to be a long and bumpy ride with a plot twist at the end.&lt;/p&gt;</description><content:encoded><![CDATA[<p><strong>Update (Apr 2010):</strong> It&rsquo;s been quite a few years since I originally did this comparison. Since then, <a href="http://cnicholson.net/">Charles Nicholson</a> and I created <a href="http://unittest-cpp.sourceforge.net/">Unit Test++</a>, a C/C++ unit-testing framework that addresses most of my requirements and wish-list items. It&rsquo;s designed to be a light-weight, high-performance testing framework, particularly aimed at games and odd platforms with limited functionality. It&rsquo;s definitely my framework of choice and I haven&rsquo;t looked at new ones in several years because it fits my needs so well. I definitely encourage you to check it out.</p>
<p>-&mdash;&mdash;&mdash;</p>
<p>One of the topics I&rsquo;ve been meaning to get to for quite a while is the applicability of test-driven development in games. Every time the topic comes up in conversations or mailing lists, everybody is always very curious about it and they immediately want to know more. I will get to that soon. I promise!</p>
<p>In the meanwhile I&rsquo;m now in the situation that I need to choose a unit-testing framework to roll out for my team at work. So, before I get to talk about how to use <a href="http://www.testdriven.com/modules/news/">test-driven development</a> in games, or the value of unit testing, or anything like that, we dive deep into a detailed comparison of existing C++ unit-testing frameworks. Hang on tight. It&rsquo;s going to be a long and bumpy ride with a plot twist at the end.</p>
<p>If you just want to read about a specific framework, you can go directly there:</p>
<ul>
<li><a href="#cppunit">CppUnit</a></li>
<li><a href="#boost">Boost.Test</a></li>
<li><a href="#cppunitlite">CppUnitLite</a></li>
<li><a href="#nanocppunit">NanoCppUnit</a></li>
<li><a href="#unitpp">Unit++</a></li>
<li><a href="#cxxtest">CxxTest</a></li>
</ul>
<p><strong>Overview</strong></p>
<p><img alt="jungle" loading="lazy" src="/exploring-the-c-unit-testing-framework-jungle/images/jungle_tikal.jpg"> How do we choose a <a href="http://c2.com/cgi/wiki?TestingFramework">unit-testing framework</a>? It depends on what we&rsquo;re going to do with it and how we&rsquo;re going to use it. If I used Java for most of my work, the choice would be easy since <a href="http://www.junit.org/index.htm">JUnit</a> seems to be the framework of choice for those working with Java. I don&rsquo;t hear them arguing over frameworks or proposing new ones very frequently, so it must be pretty good.</p>
<p>Unfortunately that&rsquo;s not the case with C++. We have our XUnit family member, CppUnit, but we&rsquo;re clearly not happy with that. We have more unit-testing frameworks than you can shake a stick at. And a lot of teams end up writing their own from scratch. Why is that? Is C++ so inadequate for unit testing that we have trouble fitting the XUnit approach in the language? Not like it&rsquo;s a bad thing, mind you. Diversity is good. Otherwise I would be stuck writing this under Windows and you would be stuck reading it with Internet Explorer. In any case, I&rsquo;m clearly not the first one who&rsquo;s asked this question. <a href="http://c2.com/cgi/wiki?WhySoManyCplusplusTestFrameworks">This page</a> tries to answer the question, and comes up with some very plausible answers: differences in compilers, platforms, and programming styles. C++ is not exactly a clean, fully supported language, with one coding standard.</p>
<p>A good way to start is to create a list of features that are important given the type of work I expect to be doing. In particular, I want to be doing test-driven development (TDD), which means I&rsquo;m going to be constantly writing and running many small tests. It&rsquo;s going to be used for game development, so I&rsquo;d like to run the tests in a variety of different platforms (PC, Xbox, PS2, next-generation consoles, etc). It should also fit my own personal TDD style (many tests, heavy use of fixtures, etc).</p>
<p>The following list summarizes the features I would like in a unit-testing framework in order of importance. I&rsquo;ll evaluate each framework on the basis of these features. Thanks to <a href="http://fancy.org/">Tom Plunket</a> for providing a slightly different view on the topic that helped me to re-evaluate the relative importance of the different features.</p>
<ol>
<li><strong>Minimal amount of work needed to add new tests</strong>. I&rsquo;m going to be doing this all the time, so I don&rsquo;t want to do a lot of typing, and I especially don&rsquo;t want to do any duplicated typing. The shorter and easier it is to write, the easier it&rsquo;ll be to refactor, which is crucial when you&rsquo;re doing TDD.</li>
<li><strong>Easy to modify and port.</strong> It should have no dependencies with non-standard libraries, and it shouldn&rsquo;t rely on â€œexoticâ€ C++ features if possible (RTTI, exception handling, etc). Some of the compilers we have to use for console development are not exactly cutting edge. To verify this one, I created a set of unit tests using each library under Linux with g++. Since most of the tests are written with Windows and Visual Studio in mind, it&rsquo;s not a bad initial test.</li>
<li><strong>Supports setup/teardown steps (<a href="http://c2.com/cgi/wiki?TestFixture">fixtures</a>).</strong> I&rsquo;ve adopted the style recommended by David Astels in his book <a href="http://www.amazon.com/exec/obidos/ASIN/0131016490/ref=nosim/gamesfromwith-20">Test Driven Development: A Practical Guide</a> about using only one assertion per test. It really makes tests a lot easier to understand and maintain, but it requires heavy use of fixtures. A framework without them is ruled out immediately. Bonus points for frameworks that let me declare objects used in the fixture on the stack (and still get created right before the test) as opposed to having to allocate them dynamically.</li>
<li><strong>Handles exceptions and crashes well.</strong> We don&rsquo;t want the tests to stop just because some code that was executed accessed some invalid memory location or had a division by zero. The unit-testing framework should report the exception and as much information about it as possible. It should also be possible to run it again and have the debugger break at the place where the exception was triggered.</li>
<li><strong>Good assert functionality.</strong> Failing assert statements should print the content of the variables that were compared. It should also provide a good set of assert statements for doing â€œalmost equalityâ€ (absolutely necessary for floats), less than, more than, etc. Bonus points for providing ways to check whether exceptions were or were not thrown.</li>
<li><strong>Supports different outputs.</strong> By default, I&rsquo;d like to have a format that can be understood and parsed by IDEs like Visual Studio or <a href="http://www.kdevelop.org/">KDevelop</a>, so it&rsquo;s easy to navigate to any test failures as if they were syntax errors. But I&rsquo;d also like to have ways to display different outputs (more detailed ones, shorter ones, parsing-friendly ones, etc).</li>
<li><strong>Supports <a href="http://c2.com/cgi/wiki?TestSuite">suites</a>.</strong> It&rsquo;s kind of funny that this is so low in my priority list when it&rsquo;s usually listed as a prominent feature in most frameworks. Frankly, I&rsquo;ve had very little need for this in the past. It&rsquo;s nice, yes, but I end up having many libraries, each of them with its own set of tests, so I hardly ever need this. Still, it certainly would be nice to have around in case it starts getting slow to run the unit tests at some point.</li>
</ol>
<p>Bonus: Timing support. Both for total running time of tests, and for individual ones. I like to keep an eye on my running times. Not for performance reasons, but to prevent them from getting out of hand. I prefer to keep running time to under 3-4 seconds (it&rsquo;s the only way to be able to run them very frequently). Ideally, I&rsquo;d also like to see a warning printed if any single test goes over a certain amount of time.</p>
<p>Easy of installation was not considered a priority; after all, I only have to go through that onceâ€”it&rsquo;s creating new tests that I&rsquo;m going to be doing all day long. Non-commercial-friendly licenses (like GPL or LGPL) are also not much of an issue because the unit test framework is not something we&rsquo;re going to link to the executable we ship, so they don&rsquo;t really impose any restrictions on the final product.</p>
<p>Incidentally, during my research for this article, I found that other people have compiled <a href="http://c2.com/cgi/wiki?ConsiderationsForAndComparisonOfCplusplusTestFrameworks">lists of what they wish for in C++ unit-testing frameworks</a>. It&rsquo;s interesting to contrast that article with this one and make a note of the differences and similarities between what we&rsquo;d like to see in a unit test framework.</p>
<p><strong>Ideal Framework</strong></p>
<p>Before I start going over each of the major (and a few minor) C++ unit-testing frameworks, I decided I would apply the philosophy behind test-driven development to this analysis and start by thinking what I would like to have. So I decided to write the set of sample tests in some ideal unit-testing framework without regard for language constrains or anything. In the ideal world, this is what I would like my unit tests to be like.</p>
<p>The simplest possible test should be trivial to create. Just one line to declare the test and then the test body itself:</p>
<pre tabindex="0"><code>TEST (SimplestTest)
{
  Â  float someNum = 2.00001f;
   Â ASSERT_CLOSE (someNum, 2.0f);
}
</code></pre><p>A test with fixtures is going to be a bit more complicated, but it should still be really easy to set up:</p>
<pre tabindex="0"><code>SETUP (FixtureTestSuite)
{
    float someNum = 2.0f;
    std::string str = &#34;Hello&#34;;
    MyClass someObject(&#34;somename&#34;);
    someObject.doSomethng();
}

TEARDOWN (FixtureTestSuite)
{
    someObject.doSomethingElse();
}

TEST (FixtureTestSuite, Test1)
{
    ASSERT_CLOSE (someNum, 2.0f); someNum = 0.0f;
}

TEST (FixtureTestSuite, Test2)
{
    ASSERT_CLOSE (someNum, 2.0f);
}

TEST (FixtureTestSuite, Test3)
{
    ASSERT_EQUAL(str, &#34;Hello&#34;);
}
</code></pre><p>The first thing to point out about this set of tests is that there is a minimum amount of code spent in anything other than the tests themselves. The simplest possible test takes a couple of lines and needs no support other than a main file that runs all the tests. Setting up a fixture with setup/teardown calls should also be totally trivial. I don&rsquo;t want to inherit from any classes, override any functions, or anything. Just write the setup step and move on.</p>
<p>Look at the setup function again. The variables that are going to be used in the tests are not dynamically created. Instead, they appear to be declared on the stack and used directly there. Additionally, I should point out that those objects should only be created right before each test, and not before all tests start. How exactly are the tests going to use them? I don&rsquo;t know, but that&rsquo;s what I would like to use. That&rsquo;s why this is an ideal framework.</p>
<p>Now let&rsquo;s contrast it to six real unit-testing frameworks that have to worry about actually compiling and running. For each of the frameworks I look at the list of wanted features and I try to implement the two tests I implemented with this ideal framework. <a href="/wp-content/uploads/bin/unit_test_frameworks.tar.gz">Here is the source code for all the examples</a>.</p>
<p>CppUnit is probably the most widely used unit-testing framework in C++, so it&rsquo;s going to be a good reference to compare other unit tests against. I had used CppUnit three or four of years ago and my impressions back then were less than favorable. I remember the code being a mess laced with MFC, the examples all tangled up with the framework, and the silly GUI bar tightly coupled with the software. I even ended up creating a patch to provide console-only output and removed MFC dependencies. So this time I approached it with a bit of apprehension to say the least.</p>
<p>I have to admit that CppUnit has come a long way since then. I was expecting the worst, but this time I found it much easier to use and configure. It&rsquo;s still not perfect, but it&rsquo;s much, much better than it used to. The documentation is pretty decent, but you&rsquo;ll have to end up digging deep into the module descriptions to even find out that some functionality is available.</p>
<ol>
<li><strong>Minimal amount of work needed to add new tests</strong>. This is one of the major downfalls of CppUnit, and, ironically, it&rsquo;s the highest-rated feature I was looking for. CppUnit requires quite a bit of work for the simplest possible test.</li>
</ol>
<pre tabindex="0"><code>// Simplest possible test with CppUnit
#include &lt;cppunit/extensions/HelperMacros.h&gt;
class SimplestCase : public CPPUNIT_NS::TestFixture
{
    CPPUNIT_TEST_SUITE( SimplestCase );
    CPPUNIT_TEST( MyTest );
    CPPUNIT_TEST_SUITE_END();
protected:
    void MyTest();
};

CPPUNIT_TEST_SUITE_REGISTRATION( SimplestCase );  

void SimplestCase::MyTest()
{
    float fnum = 2.00001f;
    CPPUNIT_ASSERT_DOUBLES_EQUAL( fnum, 2.0f, 0.0005 );
}
</code></pre><ol start="3">
<li><strong>Easy to modify and port.</strong> It gets mixed marks on this one. On one hand, it runs under Windows and Linux, and the functionality is reasonably well modularized (results, runners, outputs, etc). On the other hand, CppUnit still requires RTTI, the STL, and (I think) exception handling. It&rsquo;s not the end of the world to require that, but it could be problematic if you want to link against libraries that have no RTTI enabled, or if you don&rsquo;t want to pull in the STL.</li>
<li><strong>Supports fixtures.</strong> Yes. If you want the objects to be created before each test, they need to be dynamically allocated in the setup() function though, so no bonus there.</li>
</ol>
<pre tabindex="0"><code>#include &lt;cppunit/extensions/HelperMacros.h&gt;
#include &#34;MyTestClass.h&#34;
class FixtureTest : public CPPUNIT_NS::TestFixture
{
    CPPUNIT_TEST_SUITE( FixtureTest );
    CPPUNIT_TEST( Test1 );
    CPPUNIT_TEST( Test2 );
    CPPUNIT_TEST( Test3 );
    CPPUNIT_TEST_SUITE_END();
protected:
    float someValue;
    std::string str;
    MyTestClass myObject;
public:
    void setUp();
protected:
    void Test1();
    void Test2();
    void Test3();
};

CPPUNIT_TEST_SUITE_REGISTRATION( FixtureTest );  

void FixtureTest::setUp()
{
    someValue = 2.0;
    str = &#34;Hello&#34;;
}  

void FixtureTest::Test1()
{
    CPPUNIT_ASSERT_DOUBLES_EQUAL( someValue, 2.0f, 0.005f );
    someValue = 0;
    //System exceptions cause CppUnit to stop dead on its tracks
    //myObject.UseBadPointer();
    // A regular exception works nicely though myObject.ThrowException();
}

void FixtureTest::Test2()
{
    CPPUNIT_ASSERT_DOUBLES_EQUAL( someValue, 2.0f, 0.005f );
    CPPUNIT_ASSERT_EQUAL (str, std::string(&#34;Hello&#34;));
}

void FixtureTest::Test3()
{
    // This also causes it to stop completely
    //myObject.DivideByZero();
    // Unfortunately, it looks like the framework creates 3 instances of MyTestClass
    // right at the beginning instead of doing it on demand for each test. We would
    // have to do it dynamically in the setup/teardown steps ourselves.
    CPPUNIT_ASSERT_EQUAL (1, myObject.s_currentInstances);
    CPPUNIT_ASSERT_EQUAL (3, myObject.s_instancesCreated);
    CPPUNIT_ASSERT_EQUAL (1, myObject.s_maxSimultaneousInstances);
}
</code></pre><ol start="6">
<li><strong>Handles exceptions and crashes well.</strong> Yes. It uses the concept of â€œprotectorsâ€ which are wrappers around tests. The default one attempts to catch all exceptions (and identify some of them). You can write your own custom protectors and push them on the stack to combine them with the ones already there. It didn&rsquo;t catch system exceptions under Linux, but it would have been trivial to add with a new protector. I don&rsquo;t think it had a way to easily turn off exception handling and let the debugger break where the exception happened though (no define or command-line parameter).</li>
<li><strong>Good assert functionality.</strong> Pretty decent. It has the minimum set of of assert statements, including one for comparing floating-point numbers. It&rsquo;s missing asserts for less than, greater than, etc. The contents of the variables compared are printed to a stream if the assert fails, giving you as much information as possible about the failed test.</li>
<li><strong>Supports different outputs.</strong> Yes. Has very-well defined functionality for â€œoutputtersâ€ (which display the results of the tests), as well as â€œlistenersâ€ (which get notified while the tests are happening). It comes with an IDE-friendly output that is perfect for integrating with Visual Studio. Also supports GUI progress bars and the like.</li>
<li><strong>Supports suites.</strong> Yes.</li>
</ol>
<p>Overall, CppUnit is frustrating because it&rsquo;s almost exactly what I want, except for my most wanted feature. I really can&rsquo;t believe that it takes so much typing (and duplicated typing at that) to add new tests. Other than that, the main complaint is the need for RTTI or exceptions, and the relative complexity of the source code, which could make it challenging to port to different platforms.</p>
<p><strong>Update:</strong> <em>I&rsquo;ve revised my comments and ratings of the Boost.Test framework in light of the comments from Gennadiy Rozental pointing out how easy it is to add fixtures in boost.</em></p>
<p>I&rsquo;m a big fan of Boost, but I have to admit that it wasn&rsquo;t until about a year ago that I even learned that Boost was providing a unit testing library. Clearly, I had to check it out.</p>
<p>The first surprise is that Boost.Test isn&rsquo;t exclusively a unit-testing framework. It also pretends to be a bunch of other things related to testing. Nothing terribly wrong with that, but to me is the first sign of a â€œsmell.â€ The other surprise is that it wasn&rsquo;t really based on the XUnit family. Hmmm&hellip; In that case, it had better provide some outstanding functionality.</p>
<p>The documentation was top notch. Some of the best I saw for any testing framework. The concepts were clearly explained, and had lots of simple examples to demonstrate different features. Interestingly, from the docs I saw that Boost.Test was designed to support some things that I would consider bad practices such as dependencies between tests, or long tests.</p>
<ol>
<li><strong>Minimal amount of work needed to add new tests</strong>. Almost. Boost.Test requires really minimal work to add new tests. It&rsquo;s very much like the ideal testing framework described earlier. Unfortunately, adding tests that are part of a suite requires more typing and explicit registration of each test.</li>
</ol>
<pre tabindex="0"><code>#include &lt;boost/test/auto_unit_test.hpp&gt;
#include &lt;boost/test/floating_point_comparison.hpp&gt;  

BOOST_AUTO_UNIT_TEST (MyFirstTest)
{
    float fnum = 2.00001f;
    BOOST_CHECK_CLOSE(fnum, 2.f, 1e-3);
}
</code></pre><ol start="3">
<li><strong>Easy to modify and port.</strong> It gets mixed marks on this one, for the same reasons as CppUnit. Being part of the Boost libraries, portability is something that they take very seriously. It worked flawlessly under Linux (better than most frameworks). But I question how easy it is to actually get inside the source code and start making modifications. It also happens to pull into quite a few supporting headers from other Boost libraries, so it&rsquo;s not exactly small and self-contained.</li>
<li><strong>Supports fixtures.</strong> Boost.Test eschews the setup/teardown structure of NUnit tests in favor of plain C++ constructors/destructors. At first this threw me off for a loop. After years of being used to setup/teardown, and a fairly complex suite setup, I didn&rsquo;t see the obvious ways of using fixtures with composition.Now that I&rsquo;ve tried it this way I&rsquo;ve come to like it almost better than setup/teardown fixtures. One of the great advantages of this approach is that you don&rsquo;t need to create fixture objects dynamically, and instead you can put the whole fixture on the stack.On the downside, it&rsquo;s annoying to have to refer to the variables in the fixture through the object name. It would be great if they could somehow magically appear in the same scope as the test case itself. Also, it would have been a bit cleaner if the fixture could have been setup on the stack by the BOOST_AUTO_UNIT_TEST macro instead of having to explicitely put it on the stack for every test case.</li>
</ol>
<pre tabindex="0"><code>#include &lt;boost/test/auto_unit_test.hpp&gt;
#include &lt;boost/test/floating_point_comparison.hpp&gt;
#include &#34;MyTestClass.h&#34;  

struct MyFixture
{
    MyFixture()
    {
        someValue = 2.0;
        str = &#34;Hello&#34;;
    }
    float someValue;
    std::string str;
    MyTestClass myObject;
};

BOOST_AUTO_UNIT_TEST (TestCase1)
{
    MyFixture f;
    BOOST_CHECK_CLOSE (f.someValue, 2.0f, 0.005f);
    f.someValue = 13;
}  

BOOST_AUTO_UNIT_TEST (TestCase2)
{
    MyFixture f;
    BOOST_CHECK_EQUAL (f.str, std::string(&#34;Hello&#34;));
    BOOST_CHECK_CLOSE (f.someValue, 2.0f, 0.005f);
    // Boost deals with this OK and reports the problem
    //f.myObject.UseBadPointer();
    // Same with this
    //myObject.DivideByZero();
}  

BOOST_AUTO_UNIT_TEST (TestCase3)
{
    MyFixture f;
    BOOST_CHECK_EQUAL (1, f.myObject.s_currentInstances);
    BOOST_CHECK_EQUAL (3, f.myObject.s_instancesCreated);
    BOOST_CHECK_EQUAL (1, f.myObject.s_maxSimultaneousInstances);
}
</code></pre><ol start="6">
<li><strong>Handles exceptions and crashes well.</strong> This is one of the aspects where Boost.Test is head and shoulders above all the competition. Not only does it handle exceptions correctly, but it prints some information about them, it catches Linux system exceptions, and it even has a command-line argument that disables exception handling, which allows you to catch the problem in your debugger on a second run. I really couldn&rsquo;t ask for much more.</li>
<li><strong>Good assert functionality.</strong> Yes. Has assert statements for just about any operation you want (equality, closeness, less than, greater than, bitwise equal, etc). It even has support for checking whether exceptions were thrown. The assert statements correctly print out the contents of the variables being checked. Top marks on this one.</li>
<li><strong>Supports different outputs.</strong> Probably, but it&rsquo;s not exactly trivial to change. At least the default output is IDE friendly. I suspect I would need to dig deeper into the unit_test_log_formatter, but I certainly didn&rsquo;t see a variety of preset output types that I could just plug in.</li>
<li><strong>Supports suites.</strong> Yes, but with a big catch. Unless I&rsquo;m missing something (which is very possible at this point&ndash;if so make sure to let me know), creating a suite requires a bunch of fairly verbose statements and also requires modifying the test runner itself in main. Have a look at the example below. Couldn&rsquo;t that have been simplified to the extreme? It&rsquo;s not a big deal as this is my least-wanted requirement, but I wish I could label all the test cases in one file as part of a suite with a simple macro at the beginning of the file. Another minor shortcoming is the lack of setup/teardown steps for whole suites, which could come in really handy (especially if suite creation were streamlined).</li>
</ol>
<pre tabindex="0"><code>#include &lt;boost/test/unit_test.hpp&gt;
#include &lt;boost/test/floating_point_comparison.hpp&gt;
using boost::unit_test::test_suite;   

struct MyTest
{
    void TestCase1()
    {
        float fnum = 2.00001f;
        BOOST_CHECK_CLOSE(fnum, 2.f, 1e-3);
    }

    void TestCase2()
    {}
};

test_suite * GetSuite1()
{
    test_suite * suite  = BOOST_TEST_SUITE(&#34;my_test_suite&#34;);
    boost::shared_ptr instance( new MyTest() );
    suite-&gt;add (BOOST_CLASS_TEST_CASE( &amp;MyTest::TestCase1, instance ));
    suite-&gt;add (BOOST_CLASS_TEST_CASE( &amp;MyTest::TestCase2, instance ));
    return suite;
}
</code></pre><pre tabindex="0"><code>#include &lt;boost/test/auto_unit_test.hpp&gt;
using boost::unit_test::test_suite; 

extern test_suite * GetSuite1();  

boost::unit_test::test_suite* init_unit_test_suite( int /* argc */, char* /* argv */ [] )
{
    test_suite * test = BOOST_TEST_SUITE(&#34;Master test suite&#34;);
    test-&gt;add( boost::unit_test::ut_detail::auto_unit_test_suite() );
    test-&gt;add(GetSuite1());
    return test;
}
</code></pre><p>Boost.Test is a library with a huge amount of potential. It has great support for exception handling and advanced assert statements. It also has other fairly unique functionality such as support for checking for infinite loops, and different levels of logging. On the other hand, it&rsquo;s very verbose to add new tests that are part of a suite, and it might be a bit heavy weight for game console environments.</p>
<p>CppUnitLite has a funny story behind it. <a href="http://www.objectmentor.com/aboutUs/bios/Michael%20Feathers">Michael Feathers</a>, the original author of CppUnit, got fed up with the complexity of CppUnit and how it didn&rsquo;t fit everyone&rsquo;s needs, so we wrote the ultra-light weight framework CppUnitLite. It is as light on the features as it is on complexity and size, but his philosophy was to let people customize it to deal with whatever they need.</p>
<p>Indeed, CppUnitLite is only a handful of files and it probably adds up to about 200 lines of very clear, easy to understand and modify code. To be fair, in this comparison I actually used a version of CppUnitLite I modified a couple of years ago (download it along with all <a href="/wp-content/uploads/bin/unit_test_frameworks.tar.gz">the sample code</a>) to add some features I needed (fixtures, exception handling, different outputs). I figured it was definitely in the spirit that CppUnitLite was intended, and if nothing else, it can show what can be accomplished by just a few minutes of work with the source code.</p>
<p>On the other hand, CppUnitLite doesn&rsquo;t have any documentation to speak of. Heck, it doesn&rsquo;t even have a web site of its own, which I&rsquo;m sure is not helping the adoption rate by other developers.</p>
<ol>
<li><strong>Minimal amount of work needed to add new tests</strong>. Absolutely! Of all the unit-test frameworks, this is the one that comes closest to the ideal. On the other hand, it could be the fact that I&rsquo;ve used CppUnitLite the most and I&rsquo;m biased. In any way, it really fits my idea of minimum amount of work required to set up a simple test or even one with a fixture (although that could be made even better).</li>
</ol>
<pre tabindex="0"><code>#include &#34;lib/TestHarness.h&#34;  

TEST (Whatever,MyTest)
{
    float fnum = 2.00001f;
    CHECK_DOUBLES_EQUAL (fnum, 2.0f);
}
</code></pre><ol start="3">
<li>
<p><strong>Easy to modify and port.</strong> Definitely. Again, it gets best of the class award in this category. No other unit-test framework comes close to being this simple, easy to modify and port, and at the same time having reasonably well separated functionality. The original version of CppUnitLite even had a special lightweight string class to avoid dependencies on STL. In my modified version I changed it to use std::string since that&rsquo;s what I use in most of my projects, but the change took under one minute to do. Also, using it under Linux was absolutely trivial, even though I had only used it under Windows before.</p>
</li>
<li>
<p><strong>Supports fixtures.</strong> This is where the original CppUnitLite starts running into trouble. It&rsquo;s so lightweight that it doesn&rsquo;t have room for many features. This was an absolute must for me, so I went ahead and added it. I&rsquo;m sure it could be improved to make it so adding a fixture requires even less typing, but it&rsquo;s functional as it stands. Unfortunately, it suffers from the problem that objects need to be created dynamically if we want them to be created right before each test. To be fair though, every single unit-test framework in this evaluation has that requirement. Oh well.</p>
</li>
</ol>
<pre tabindex="0"><code>#include &#34;lib/TestHarness.h&#34;
#include &#34;MyTestClass.h&#34;   

class MyFixtureSetup : public TestSetup
{
public:
    void setup()
    {
        someValue = 2.0;
        str = &#34;Hello&#34;;
    }
    void teardown()
    {}
protected:
    float someValue;
    std::string str;
    MyTestClass myObject;
};   

TESTWITHSETUP (MyFixture,Test1)
{
    CHECK_DOUBLES_EQUAL (someValue, 2.0f);
    someValue = 0;
    // CppUnitLite doesn&#39;t handle system exceptions very well either
    //myObject.UseBadPointer();
    // A regular exception works nicely though myObject.ThrowException();
}  

TESTWITHSETUP (MyFixture,Test2)
{
    CHECK_DOUBLES_EQUAL (someValue, 2.0f);
    CHECK_STRINGS_EQUAL (str, std::string(&#34;Hello&#34;));
}   

TESTWITHSETUP (MyFixture,Test3)
{
    // Unfortunately, it looks like the framework creates 3 instances of MyTestClass
    // right at the beginning instead of doing it on demand for each test. We would
    // have to do it dynamically in the setup/teardown steps ourselves.
    CHECK_LONGS_EQUAL (1, myObject.s_currentInstances);
    CHECK_LONGS_EQUAL (3, myObject.s_instancesCreated);
    CHECK_LONGS_EQUAL (1, myObject.s_maxSimultaneousInstances);
}
</code></pre><ol start="6">
<li>
<p><strong>Handles exceptions and crashes well.</strong> The original CppUnitLite didn&rsquo;t handle them at all. I added minor support for this (just an optional try/catch). To run the tests without exception support it requires recompiling the tests with a special define turned on, so it&rsquo;s not at slick as the command-line argument that Boost.Test features.</p>
</li>
<li>
<p><strong>Good assert functionality.</strong> Here is where CppUnitLite really shows its age. The assert macros are definitely the worst of the lot. They don&rsquo;t use a stream to print out the contents of their variables, so we need custom macros for each object type you want to use. It comes with support for doubles, longs, and strings, but anything else you need to add by hand. Also, it doesn&rsquo;t have any checks for anything other than equality (or closeness in the case of floating-point numbers).</p>
</li>
<li>
<p><strong>Supports different outputs.</strong> Again, the original only had one type of output. But it was very well isolated and it was trivial to add more.</p>
</li>
<li>
<p><strong>Supports suites.</strong> Probably the only framework that doesn&rsquo;t support suites. I never really needed them, but they would probably be very easy to add on a per-file basis.</p>
</li>
</ol>
<p>CppUnitLite is as barebones as it gets, but with a few modifications it hits the mark in all the important categories. If it had better support for assert statements, it would come very close to my ideal framework. Still, it&rsquo;s a worthy candidate for the final crown.</p>
<p>I had never heard of NanoCppUnit until <a href="http://c2.com/cgi/wiki?PhlIp">Phlip</a> brought it up. From reading the feature list, it really appeared to be everything that I wanted CppUnitLite to be, except that it was better and ready to work out of the box.</p>
<p>The first point against NanoCppUnit is the awful â€œpackagingâ€ of the framework. If you thought that CppUnitLite was bad (not having a web page of its own), well, at least you could download it as a zip file. For NanoCppUnit you actually have to copy and paste the five files that make up the framework from a web page. I&rsquo;m not kidding. That makes for some â€œlovelyâ€ formatting issues I might add. The documentation found in the web page wasn&rsquo;t exactly very useful either.</p>
<p>In any case, I continued my quest to get a simple test program up and running with NanoCppUnit. Out of the box (or out of the web page, rather) it&rsquo;s clearly aimed only at Windows platforms. I thought it would be trivial to fix, but changing it required more time than I thought at first (I personally gave up when I started getting errors buried three macros deep into some assert statement). Unlike CppUnitLite, the source code is not very well structured at all, full of ugly macros everywhere, making it not trivial to add new features like new output types. Unless I&rsquo;m totally mistaken, it even looks like it has sample code inside the test framework itself. Eventually I had to give up on running it under Linux, so my comments here are just best guesses by looking at the source code.</p>
<ol>
<li><strong>Minimal amount of work needed to add new tests</strong>. I think so. I&rsquo;m not sure it&rsquo;s possible to create a standalone test that is part of a global suite, but at least creating a suite doesn&rsquo;t require manual registration of every test. This is (probably) the simplest possible test with NanoCppUnit.</li>
</ol>
<pre tabindex="0"><code>struct MySuite:  TestCase { };  

TEST_(MySuite, MyTest)
{
    float fnum = 2.00001f;
    CPPUNIT_ASSERT_DOUBLES_EQUAL(fnum, 2.0f, 0.0001);
}
</code></pre><ol start="3">
<li><strong>Easy to modify and port.</strong> Not really. Windows dependencies run deeper than it seems on the surface. The code is small, but it&rsquo;s messy enough that it&rsquo;s a pain to work with. I&rsquo;m sure it can be ported with a bit of effort though since it&rsquo;s so small.</li>
<li><strong>Supports fixtures.</strong> Yes. Setup and teardown calls very similar to the modified version of CppUnitLite.</li>
<li><strong>Handles exceptions and crashes well.</strong> No idea since I wasn&rsquo;t able to run it. I see some try/catch statements in the code, but no way to turn them on or off. Probably no better than CppUnitLite.</li>
<li><strong>Supports different outputs.</strong> Not really. Everything is hardwired to use a stream that sends its contents to OutputDebugString() in Windows. I think the default output text is formatted to match the Visual Studio error format.</li>
<li><strong>Good assert functionality.</strong> Yes. Good range of assert statements, including floating point closeness, greater than, less than, etc.</li>
<li><strong>Supports suites.</strong> Yes. I don&rsquo;t know what&rsquo;s involved in just running a single suite though. Not a big deal either way.</li>
</ol>
<p>One of NanoCppUnit&rsquo;s unique features is regular expression support as part of its assert tests. That&rsquo;s very unusual, but I can see how it could come in handy. A few times in the past, I&rsquo;ve had to check that a certain line of code has some particular format, so I had to sscanf it, and then check on some of the contents. A regular expression check would have done the job nicely.</p>
<p>Unfortunately, NanoCppUnit doesn&rsquo;t really live up to the standards of other frameworks. Right now it feels too much as a work in progress, with too much missing functionality and not clearly structured code.</p>
<p>The further along we get in this evaluation, the less Xunit-like the frameworks become. Unit++&rsquo;s unique feature is that it pretends to be more C++-like than CppUnit. Wait a second, did I hear that right? More C++ like? Is that supposed to be a good thing? Looking back at my ideal test framework, it really isn&rsquo;t very much like C++ at all. Once I started thinking about that topic I realized that there really is no reason at all why the tests framework itself needs to be in C++. The tests you write need to be in the language of the code being tested, but all the wrapper code doesn&rsquo;t. That&rsquo;s a point that the next, and final, testing framework will drive home.</p>
<p>So, what does it mean to be more C++ like? No macros for a start. You create suites of tests by creating classes that derive from suite. That&rsquo;s the same thing we were doing in most other frameworks, really, but it was just happening behind the scenes. It really doesn&rsquo;t help me any to know that that is what I&rsquo;m doing, and I would certainly not call it a â€œfeature.â€ As a result, tests are more verbose than they could be.</p>
<p>The documentation is simply middle-of-the-road. It&rsquo;s there, but it&rsquo;s not particularly detailed and it doesn&rsquo;t come loaded with examples.</p>
<ol>
<li><strong>Minimal amount of work needed to add new tests</strong>. I&rsquo;m afraid it gets failing marks for this. It requires manual registration of tests, and every test needs to be part of a suite. This makes adding new tests tedious and error prone (by writing a new test and forgetting to register it). I don&rsquo;t know about you, but with all the C++ cruft, I look at the code below and it&rsquo;s not immediately obvious what it does until I&rsquo;ve scanned it a couple of times. The signal to noise ratio is pretty poor.</li>
</ol>
<pre tabindex="0"><code>#define __UNITPP #include &#34;unit++.h&#34;
using namespace unitpp;
namespace
{
    class Test : public suite
    {
        void test1()
        {
            float fnum = 2.00001f;
            assert_eq(&#34;Checking floats&#34;, fnum, 2.0f);
        }
    public:
        Test() : suite(&#34;MySuite&#34;)
        {
            add(&#34;test1&#34;, testcase(this, &#34;Simplest test&#34;, &amp;Test::test1));
            suite::main().add(&#34;demo&#34;, this);
        }
    }; 

    Test* theTest = new Test();
}
</code></pre><ol start="3">
<li><strong>Easy to modify and port.</strong> So-so. It needs the STL and it pulls in some stuff like iostreams (which I remember having distinct problems with when I was working with STLPort). On the other hand the source code is relatively small and self-contained so it&rsquo;s certainly doable to port and modify if you&rsquo;re willing to put in some time.</li>
<li><strong>Supports fixtures.</strong> Another framework that I just can&rsquo;t see how to do fixtures with. Like Boost.Test, it seems to think that using the constructor and destructor for each class is all you need. A quick search for fixture or setup or teardown in the documentation doesn&rsquo;t reveal anything. I don&rsquo;t know if I&rsquo;m totally missing something or if other people just write very different tests from me. I suppose I could create a new class for every fixture I want, put the setup in the constructor and the teardown in the destructor and inherit from it for every test case (and somehow figure out how to create an instance of that class and use it for each test run). It&rsquo;s probably possible, but it&rsquo;s not exactly trivial, is it? Again, the lack of fixtures puts this framework out of the running.</li>
<li><strong>Handles exceptions and crashes well.</strong> Average. It manages to catch regular exceptions without crashing, but that&rsquo;s about it. No system exceptions in Linux. No way to turn it off for debugging.</li>
<li><strong>Supports different outputs.</strong> I couldn&rsquo;t figure out how to do it from the documentation. There is probably a way to do it since it even supports GUI functionality , but it&rsquo;s not obvious (and there are no examples). Besides, by this point, having failed points 1 and 3, I wasn&rsquo;t really motivated to spend a while learning the framework. Incidentally, this is one of the few frameworks whose default text output is not formatted correctly for IDEs like KDevelop.</li>
<li><strong>Good assert functionality.</strong> It scrapes by with the minimum in this department. It provides equality and condition checks, but that&rsquo;s it. It doesn&rsquo;t even provide a float version of assert to check for â€œclose enough.â€ At least it prints the contents of the variables to a stream correctly.</li>
<li><strong>Supports suites.</strong> Yes, like most of them.</li>
</ol>
<p>Overall, Unit++ is not really a candidate. Perhaps it&rsquo;s because it&rsquo;s not intended for the type of testing I intend to use it for, but it doesn&rsquo;t offer anything new over other frameworks and it has a lot of drawbacks of its own. The lack of fixtures is simply unforgivable.</p>
<p>After looking into a framework that tried to be different from XUnit (Unit++), I wasn&rsquo;t particularly looking forward to evaluating possibly the wackiest one of them all, CxxTest. I had never heard of it until a few days ago, but I knew that it required using Perl along the way to generate some C++ code. My spider senses were tingling.</p>
<p>Boy was I wrong!! Within minutes of using CxxTest and reading through its great documentation (the best by far), I was completely convinced this was the way to go. This came as a complete surprise to me since I was ready to leave somewhat dissatisfied and pronounce a victor between CppUnit and CppUnitLite.</p>
<p>Let&rsquo;s start from the beginning. What&rsquo;s with the use of Perl and why is it different from CppUnit? Erez Volk, the author of CxxTest, had the unique insight that just because we&rsquo;re testing a C++ program, we don&rsquo;t need to rely on C++ for everything. Other languages, such as Java, are better suited to what we want to do in a unit-testing framework because they have good introspection (reflection) capabilities. C++ is quite lacking in that category, so we&rsquo;re forced to use kludges like manual registration of tests, ugly macros, etc. CxxTest gets around that by parsing our simple tests and generating a C++ test runner that calls directly into our tests. The result is simply brilliant. We get all the flexibility we need without the need for any ugly macros, exotic libraries, or fancy language features. As a matter of fact, CxxTest&rsquo;s requirements are as plain vanilla as you can get (other than being able to run Perl).</p>
<p>The code-generation step is also trivial to integrate into the regular build system. The wonderful documentation gives explicit step-by-step instructions on how to integrate it with make files, Visual Studio projects files, or <a href="http://www.dsmit.com/cons/">Cons</a>. Once you have it set up, you won&rsquo;t even remember there&rsquo;s anything out of the ordinary going on.</p>
<p>Let&rsquo;s see how it stacks up against the competition.</p>
<ol>
<li><strong>Minimal amount of work needed to add new tests</strong>. Very good. It&rsquo;s almost as simple as the best of them. If I could nit-pick, I would have wished for an even simpler way to create tests without the need to declare the class explicitly. Since we&rsquo;re doing processing with a Perl script, there&rsquo;s no reason we couldn&rsquo;t have taken it a step beyond that and used a syntax even closer to my ideal test framework.</li>
</ol>
<pre tabindex="0"><code>class SimplestTestSuite : public CxxTest::TestSuite
{
    public: void testMyTest()
    {
        float fnum = 2.00001f;
        TS_ASSERT_DELTA (fnum, 2.0f, 0.0001f);
    }
};
</code></pre><ol start="3">
<li><strong>Easy to modify and port.</strong> CxxUnit requires the simplest set of language features (no RTTI, no exception handling, no template functions, etc). It also doesn&rsquo;t require any external libraries. It is also distributed simply as a set of header files, so there&rsquo;s no need to compile into a separate library or anything like that. Functionality is pretty well broken down and separated in the original source code, so making modifications should be fairly straightforward.</li>
<li><strong>Supports fixtures.</strong> CxxUnit gets the â€œtop of its classâ€ label in this category. Not only does it support setup/teardown steps on a per-test level, but it also supports them at the suite and at the world (global) level. Creating fixtures is pretty straightforward and just requires inheriting from a class and creating as many functions as you want starting with the letters â€œtest.â€ To be really picky, I would have loved it if they had taken it a step further and, apart from simplifying the code a bit more, also inserted the setup and teardown code around the code for each test. That would have allowed us to work with those objects directly on the stack and their lifetime would have been managed correctly around each test. Oh well. Can&rsquo;t have everything.</li>
</ol>
<pre tabindex="0"><code>#include &#34;MyTestClass.h&#34;  

class FixtureSuite : public CxxTest::TestSuite
{
public:
    void setUp()
    {
        someValue = 2.0;
        str = &#34;Hello&#34;;
    } 

    void tearDown() {}  

    void test1()
    {
        TS_ASSERT_DELTA (someValue, 2.0f, 0.0001f);
        someValue = 13.0f;
        // A regular exception works nicely though myObject.ThrowException();
    } 

    void test2()
    {
        TS_ASSERT_DELTA (someValue, 2.0f, 0.0001f);
        TS_ASSERT_EQUALS (str, std::string(&#34;Hello&#34;));
    } 

    void test3()
    {
        //myObject.UseBadPointer();
        TS_ASSERT_EQUALS (1, myObject.s_currentInstances);
        TS_ASSERT_EQUALS (3, myObject.s_instancesCreated);
        TS_ASSERT_EQUALS (1, myObject.s_maxSimultaneousInstances);
    }  

    float someValue;
    std::string str;
    MyTestClass myObject;
};
</code></pre><ol start="6">
<li><strong>Handles exceptions and crashes well.</strong> Great support. It catches all exceptions and prints information about them formatted like any other error (no system exceptions under Linux though). You can easily re-run the tests with a command-line argument to the Perl script to avoid catching exceptions and catch them in the debugger instead. It also gives you a custom version of every assert macro that lets you catch the exceptions yourself in case you ever need to do that.</li>
<li><strong>Supports different outputs.</strong> Different outputs are supported by passing a parameter indicating which type of output you want to the Perl processing step. The default one (error-printer) was formatted correctly for IDE parsing, and you can use several others (including GUIs for those of you addicted to progress bars, a yes/no report, or a stdio one). Adding new output formatting sounds very straightforward and it&rsquo;s even covered in the documentation.</li>
<li><strong>Good assert functionality.</strong> Again, it gets â€œtop of its classâ€ for this one. It has a whole suite of very comprehensive assert functions, including ones for exception handling, checking predicates, and arbitrary relations. It even has a way to print out warnings which can be used to differentiate between two parts of the code calling the same test, or to print reminder â€œTODOâ€ messages to yourself.</li>
<li><strong>Supports suites.</strong> Yes. All tests are part of a suite.</li>
</ol>
<p>Another feature supported by CxxUnit that I haven&rsquo;t had time to look into is some support for <a href="http://www.mockobjects.com/FrontPage.html">mock objects</a>. Anybody doing TDD knows the value of mock objects when it comes to testing the interactions between a set of objects. Apparently CxxUnit allows you to override global functions with specific mock functions (it gives an example of overriding fopen()). I don&rsquo;t think it helps any with regular classes; for those you&rsquo;re on your own.</p>
<p>So, what&rsquo;s not to like in CxxTest? Not much, really. Other than wishing that the test syntax were a bit tighter, the only thing to watch out for is what happens with large projects. If you follow the examples in the documentation, it will create a single runner for all the tests you give it. This can be problematic if you&rsquo;re going to be having thousands of tests, and then making one small change in one of them causes a full recompilation of all your code.</p>
<p><strong>Update</strong>: After talking with Erez and re-checking the documentation, I realized this is already fully supported in CxxUnit. By default, when you generate a test runner, it adds a main function and some global variables, so linking with other similar runners gives all sorts of problems. However, it turns out you can generate a test runner with the &ndash;part argument, and it will leave out the main function and any other globals. You can then link together all the runners and have a single executable. I wonder if it would be worth going as far as creating a runner for every suite, or if it would be best to cluster suites together. Worth investigating at some point whenever I get enough tests to make a difference.</p>
<p><strong>Conclusion</strong></p>
<p>After going through all six C++ unit-testing frameworks, four stand out as reasonable candidates: CppUnit, Boost.Test, a modified CppUnitLite, and CxxTest.</p>
<p>Of the four, CxxTest is my new personal favorite. It fits very closely the requirements of my ideal framework by leveraging the power of an external scripting language. It&rsquo;s very usable straight out of the â€œboxâ€ and it provides some nifty advanced features and great assert functionality. It does require the use of a scripting language as part of the build process, so those unconfortable with that requirement, might want to look at one of the other three frameworks.</p>
<p>CppUnit is a solid, complete framework. It has come a long, long way in the last few years. The major drawbacks are the relative verbosity for adding new tests and fixtures, as well as the reliance on STL and some advanced language issues.</p>
<p>If what you need is absolute simplicity, you can do no wrong starting with CppUnitLite (or a modified version), and tweaking it to fit your needs. It&rsquo;s a well-structured, ultra-light framework with no external dependencies, so modifying it is extremely easy. Its main drawback is the lack of features and the primitive assert functionality.</p>
<p>If you&rsquo;re going to be working mostly on the PC, you don&rsquo;t expect to have to modify the framework itself, and you don&rsquo;t mind pulling in some additional Boost libraries, Boost.Test could be an excellent choice.</p>
<p>Should you roll your own unit-test framework? I know that Kent Beck recommends it in his book <a href="http://www.amazon.com/exec/obidos/ASIN/0321146530/ref=nosim/gamesfromwith-20"><em>Test-Driven Development: By Example</em></a>, and it might be a great learning experience, but I just can&rsquo;t recommend it. Just as it&rsquo;s probably good to write a linked-list and a stack data structure a few times but I wouldn&rsquo;t recommend actually doing that in production code instead of using the ones provided in the STL, I strongly recommend starting with one of the three unit-testing frameworks mentioned above. If you really feel the need to roll your own, grab CppUnitLite and get hacking.</p>
<p>Whichever one you choose, you can really do no wrong with one of those three frameworks. The most important thing is that you are writing unit tests, or, even better, doing test-driven development. To paraphrase Michael Feathers, code without unit tests is legacy code, and you don&rsquo;t want to be writing legacy code, do you?</p>
<p><a href="/wp-content/uploads/bin/unit_test_frameworks.tar.gz"><img alt="icon" loading="lazy" src="/exploring-the-c-unit-testing-framework-jungle/images/script.png"> unit_test_frameworks.tar.gz</a></p>]]></content:encoded></item><item><title>2004 GameTech Report: Game Tech Leadership Summit</title><link>https://gamesfromwithin.com/2004-gametech-report-game-tech-leadership-summit/</link><pubDate>Sun, 19 Dec 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/2004-gametech-report-game-tech-leadership-summit/</guid><description>&lt;p&gt;The GameTech Leadership Summit was the second part of this year&amp;rsquo;s &lt;a href="http://www.game-tech.com/"&gt;Game Tech Seminars&lt;/a&gt;. Underneath a somewhat confusing name, it really was an analysis of the tools and technology in games today.&lt;/p&gt;
&lt;p&gt;The first day is where the real meat of this second part was. It was a postmortem/analysis of the tech involved in some of the most successful games today (Halo 2, Half Life 2, The Sims 2, and Stranger) done by the tech lead (or someone close to that position) for each of the teams. Each of the talks was packed with information and some of them are freely available online, so I&amp;rsquo;m not even going to try to summarize the talks. Instead, this is going to be more of a highlight of things that caught my eye or I thought were particularly important.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The GameTech Leadership Summit was the second part of this year&rsquo;s <a href="http://www.game-tech.com/">Game Tech Seminars</a>. Underneath a somewhat confusing name, it really was an analysis of the tools and technology in games today.</p>
<p>The first day is where the real meat of this second part was. It was a postmortem/analysis of the tech involved in some of the most successful games today (Halo 2, Half Life 2, The Sims 2, and Stranger) done by the tech lead (or someone close to that position) for each of the teams. Each of the talks was packed with information and some of them are freely available online, so I&rsquo;m not even going to try to summarize the talks. Instead, this is going to be more of a highlight of things that caught my eye or I thought were particularly important.</p>
<p><img alt="gametech" loading="lazy" src="/2004-gametech-report-game-tech-leadership-summit/images/gametech_l.png"></p>
<p><strong>Jay Stelly on Half Life 2</strong></p>
<p>[amtap amazon:asin=B000ID1AKI]</p>
<p>Nobody is going to argue that the Half Life 2 development didn&rsquo;t have its share of problems: repeated delays, â€œSteamâ€ issues, etc. Still, there is no doubt that Half Life 2 is a great game and there&rsquo;s a lot to be learned from <a href="http://www.valvesoftware.com/">Valve</a>&rsquo;s approach.</p>
<p>One driving goal of the Half Life 2 tech was to design around the workflow. The technology should adapt to the way content creators want to work, and it shouldn&rsquo;t get in the way. This also means that the asset pipeline should let people iterate as much as possible with no dependencies on other people or parts of the game. It seems like an obvious statement, but I think a lot of companies are missing that. This is going to become extremely important for next generation consoles, and I predict that companies that don&rsquo;t completely adopt this paradigm will fall by the wayside.</p>
<p>One of the ways they went about designing around the workflow was to create a layered system with different levels of abstractions to represent their concepts. I really think that&rsquo;s the only way to go when building complex systems (otherwise we have the tall building with shaky foundations syndrome), but it just struck me how they were always reaching for a higher level of abstraction than I would have normally considered. Having that extra level of abstraction allows for better separation of content creation tasks.</p>
<p>For example, they could have left their sound system at the level of abstraction of sound emitters and listeners. Most games stop there. They went one level of abstraction higher and modeled sound environments, which include a collection of emitters, and sound processing parameters. Then each of the sound environments could be applied to particular locations in a level. This approach allows the sound designer and level designer to work in parallel, bringing their work together at any point they want while they&rsquo;re still iterating.</p>
<p>But workflow doesn&rsquo;t apply just to designers and artists. Programmers also do some work, you know? So, not surprisingly, another driving point of the Half Life 2 technology was to improve the programming environment. They had 14 programmers in their team, which starts to be a bit on the large side, so that was yet another motivation to go with a very layered system. Different programmers could concentrate on specific areas and not interfere with each other&rsquo;s work. They also made the distinction between system code (engine) and leaf code (game-specific code), which helped organize things. Interestingly, they went with a DLL-based approach to reduce link times, which often stop fast programmer iteration dead in its tracks.</p>
<p>One drawback of the extremely layered approach was that Half Life 2 was completely memory bound. Heavily abstracted and layered object-oriented systems usually have a memory access pattern that looks more random than lottery-winning numbers. That means they can kiss goodbye to a lot of cache consistency, and the program is going to be constantly stalling, waiting for data to come from main memory. This is a very serious problem, and since memory is going to continue getting slower relative to CPUs, it&rsquo;s something we&rsquo;re going to have to deal with.</p>
<p>Program performance was never a major driving force behind programming languages, and especially not nowadays, but it would be interesting to come up with a language that allowed for good modularization and design, but at the same time being extremely cache-friendly. On the other hand, scratch that thought. We have much bigger problems to solve with programming languages before we worry exclusively about cache performance.</p>
<p>Interestingly, general scripting didn&rsquo;t work for Valve very well. Instead, in the future they plan to go down the path of C++ program behavior, with data that can be easily changed from text files. As long as adding new C++ functionality can be done very quickly, and there&rsquo;s good communication between programmers and designers, there&rsquo;s no reason why that can&rsquo;t work.</p>
<p><strong>Chris Butcher on Halo 2</strong></p>
<p>[amtap amazon:asin=B00008J7NZ]</p>
<p>Chris started right away with a very insightful observation: The Halo games are really a world simulation, where the player is just another entity moving around the world. On the other hand, the Half Life games are more of a player-based simulation, where everything happens for the benefit of the player.</p>
<p>The whole Halo engine is based around the concept of â€œtags,â€ which is something that <a href="http://bungie.com/">Bungie</a> has used in most of their past games. Tags are just a hierarchy of variable-length block arrays, and each block is made out of basic data types. Tags describe the properties of a game object, as well as how meshes are represented. The part that surprised me is that tags are actually defined in the C code itself as opposed to being an external data representation that then gets processed and generates some C code (which would have been a much cleaner way to separate tools and engine).</p>
<p>The tag approach has lots of advantages. It has full introspection abilities and it can be used to easily load and save data. Also, because everything in the engine uses it, it means that if we have a generic tag editor, we can use it to change any of the data. They even go as far as seeing the level editor as a fancy, graphical editor for the tag system.</p>
<p>Because the tag system is hierarchical in nature, Bungie creates their entities by using composition instead of inheritance. In my opinion, this is totally the right way to go. You want an enemy to have a weapon, not to inherit from a HasWeapons class.</p>
<p>One thing I still can&rsquo;t really understand is why Bungie is using plain C for most of their game. Don&rsquo;t get me wrong. They can clearly produce great games that way, but it just seems that with C++ they could do it more easily or faster. I understand that right now they can pretty much save raw memory and load it straight back into the game, which would be very difficult to do with C++. Still, if that&rsquo;s the only benefit, I&rsquo;m sure it would be relatively easy to set up a system to do transparent serialization in C++ as well and reap all the benefits of the language.</p>
<p>As was the case for Half Life 2, they also spent considerable amount of time trying to improve the artist workflow. They use resource hotloading, automatically detect changed files, etc. So with a lot of resources, their artists can just re-export the asset and see it live in the game in a few seconds.</p>
<p>For memory allocation, they tried to minimize dynamic memory allocation at runtime (although they admit there are a few out there), but all allocations are bounded, which really is the only way to deal with a fixed-memory system like a game console. Apparently Havok is one of the exceptions to the rule since it doesn&rsquo;t make any hard guarantees on memory usage, so they had to treat it specially. Also, their world simulation is perfectly deterministic, which is great for repeating bugs. Their world view (rendering, sound, etc), however, is not deterministic.</p>
<p><strong>Charles Bloom on Stranger&rsquo;s Wrath</strong> (<a href="http://www.cbloom.com/3d/index.html">presentation notes</a>)</p>
<p>[amtap amazon:asin=B0006I5I58]</p>
<p>From the very beginning of the talk, <a href="http://cbloom.com/">Charles Bloom</a> adopted the underdog role and played it to perfection. He made it very clear that Stranger&rsquo;s Wrath was a very different project from Half Life 2 or Halo 2. Whereas we had just been told that the teams of Valve and Bungie were full of talented and experienced programmers, Charles claimed that <a href="http://oddworld.com/">Oddworld</a> had a much wider mix of talent, with many more weak links. In his words, not everybody can have the super programmers from Half Life 2 or Halo 2. That&rsquo;s a funny way to start, but it really drove a point home about how Stranger was perhaps the project that most people will be able to identify with.</p>
<p>So in that light, the Oddworld method relies a lot more on putting a lot of responsibility on the shoulders of their lead programmers. They&rsquo;re in charge of reviewing the code of other programmers, and making sure everybody stays productive. The philosophy behind code is that any code should be easily usable by everybody, regardless of their skill level. It also means that code needs to be robust, and should be hard to break or do wrong things with it.</p>
<p>This is a very interesting point. I totally agree with the idea of robust, defensive code, but for different reasons. I believe that&rsquo;s a good practice in general, even if your team is full of â€œsuper-programmers.â€ Later on down the line, it will be a lot easier to work with that code, or modify it, or anything. Using the excuse of â€œthe programmers in my team are really talentedâ€ to write brittle or badly encapsulated code is a really near-sighted attitude. I was glad to see that Charles <a href="http://cbloom.com/rants.html">later mentions in his â€œrantsâ€ page</a> (entry from 12-06-04) that he really thought that code robustness was a good quality in general, independent of your team composition or skills.</p>
<p>The same attitude applied not just to the code, but to the game engine and the tools themselves. They never wanted the game to go down and prevent people from working, so they always tried to cope in the best way possible with missing assets, incorrect data, etc. All great things to aim for in my opinion. I have applied similar rules in some of my past projects and they worked out great.</p>
<p>The differences between Halo 2 and Strangers didn&rsquo;t end there. Even though they&rsquo;re both somewhat similar games, both Xbox exclusive, they&rsquo;re as far apart as you can get from a technology point of view. Halo 2 tried to be as minimalistic as possible: it hardly used any C++, they avoided dynamic memory allocations as much as possible, etc. Stranger, on the other hand, embraced C++ and a lot of its advanced features: they used dynamic memory allocation, the STL, smart pointers, and even exceptions. Yes, exceptions! (They did turn them off for release, but they made good use of them during development as part of their defensive code style). So, in spite of all the differences, they still managed to make a game that rivals Halo 2 as far as the technology and pushing the Xbox to its limits.</p>
<p>Another area where Stranger is totally different from Halo 2 is how game entities are organized. In Halo 2 everything uses composition, which to me feels like the natural way of creating them. Stranger apparently makes heavy use of multiple inheritance to achieve the same effect. And not just multiple inheritance of abstract interfaces, but full blown classes with their own implementation. I&rsquo;m really surprised that the system worked well for them and I&rsquo;d definitely be curious to learn more about it.</p>
<p>From the asset pipeline point of view, Oddworld also uses hotloading of resources to see changes in the game in an almost instantaneous way. They also stressed the importance of build farms and distributing a lot of that processing.</p>
<p>Interestingly, Charles admitted that most of their data was generated by manipulating plain text files. No fancy GUI tools (other than Maya for level editing and layout). Just plain text files. I think people sometimes forget how easy it is to work with text files, and get all wrapped up into making fancy tools that end up limiting what they can do. Clearly, text files are going to need very strong validation to deal with all the errors that are introduced by typing things by hand. The only thing I didn&rsquo;t like is that apparently at Oddworld that validation happens at load time. I would have preferred it to happen as soon as the file is saved to give feedback right away to the creator.</p>
<p><strong>Andrew Willmott on The Sims 2</strong></p>
<p>[amtap amazon:asin=B00009WNZA]</p>
<p>This talk was a bit different from the others. First of all, the Sims 2 is a very different game from the ones presented so far. It was also clear that the talk was going to be different just from the emphasis in the title â€œShipping the Sims 2.â€ Andrew didn&rsquo;t go into tech details as heavily, but gave an overall overview of the project organization and statistics. This was by far the largest of all projects presented (it had 250+ people at the end!), but that&rsquo;s not so unusual for an <a href="http://www.ea.com">EA</a> project.</p>
<p>A lot of his talk dealt with the pressure they had to deal with, and the challenge of organizing so many people. Being the followup to the best-selling game The Sims couldn&rsquo;t have been easy, and throwing that many people at it at the wrong time could have made things close to impossible. The fact that the project slipped and Maxis was moved to a new location months before shipping certainly didn&rsquo;t help any!</p>
<p>One of the most interesting facts is that Them Sims 2 used a visual scripting language called Edith, and at the end, they all hated it and wanted to move away from it. That has been my experience as well with visual scripting languages. The only time visual scripting languages might be OK is if they generate a text-based script that you can then manipulate just like any other text. Otherwise, there are just too many disadvantages: difficult to copy/paste, can&rsquo;t grep anything, hard to do multi-script changes, hard to view history/differences in version control, etc. Andrew mentioned Lua as their likely scripting language of choice in the future.</p>
<p>Another interesting technical fact was that they made heavy use of scene graphs, but they were also very dissatisfied with them and they mostly got in the way of the game programmers. At one point I was a fan of light scene graphs, but I&rsquo;ve changed my mind in the last couple of years, and I also prefer to organize elements in much more specific containers (and keep the same element in multiple containers for different tasks).</p>
<p>As a really funny aside, The Sims 2 uses a technique I thought it was well dead and buried: dirty rectangles. I&rsquo;m not kidding. I thought I saw the last of those when I started using page flipping in the VGA days, but apparently it was useful, given their problems rendering so many objects in view. My hat&rsquo;s off to them for even thinking of it!</p>
<p>Like Stranger, The Sims 2 made heavy use of C++ as well, with dynamic memory allocations, STL, etc. That&rsquo;s not all that surprising since it&rsquo;s PC-only game, but it&rsquo;s still a good point of reference.</p>
<p><strong>The rest</strong></p>
<p>The last day was much weaker than the first one. I really wished we could have extended the first day to the full conference (either by looking at other games, or by digging deeper into some specific topics).</p>
<p>The one really worthwhile session that stood out from the others was <a href="http://www.caseytime.com/">Casey Muratori</a>&rsquo;s talk on â€œDesigning Reusable Code.â€ Coming from someone who wrote two versions of <a href="http://www.radgametools.com/gramain.htm">Granny</a>, it actually had some very interesting insights. It was clearly coming from the point of view of writing middleware (as opposed to writing reusable code to use in multiple games in the same company). The most important observation is that people will want to integrate your code in different ways. At first they just want a quick and dirty integration just to get it working. Later they&rsquo;ll want some more control to fine tune things. Finally, towards the end of the project, they&rsquo;ll want to take over a lot of the aspects of the code, such as loading and memory allocation.</p>
<p>To support that pattern of usage, Casey suggests having several levels of interface exposed. One high level interface that accomplishes the basic functionality with a single call, a more detailed one that requires more work on the part of the user, all the way down to the detailed functions. I absolutely agree with the overall principle, but I think Casey was suggesting taking it to the extreme, to the point that he was suggesting that just about every function should be made public and that loading something should be a matter of streaming the data into memory without any other function calls required. That&rsquo;s just a bit too extreme for my tastes. I also happen <a href="/simple-is-beautiful/">to value simplicity of interfaces very highly</a>, so there&rsquo;s the big question of how to organize those interfaces to make sure they don&rsquo;t seem more complicated than they really are.</p>
<p>Casey also argued that the best way to develop an interface was to use it before you actually implemented anything. Since that&rsquo;s exactly what one of the things that test-driven development accomplishes, that was music to my ears. I was also shocked when we had a show of hands to see who was doing test-driven development, and about 10-15 people from the audience raised their hands. Yay! I&rsquo;m glad to see I&rsquo;m not alone.</p>
<p>Another session worth mentioning was <a href="http://www.blueandorange.org">Brian Sharp</a>&rsquo;s talk on how to integrate a physics engine into a game. He brought up a bunch of really good points and anybody integrating a physics engine into their game for the first time would do well to track down the slides and read them carefully. Some of the points were obvious, but some were very interesting, such as how it affects the interactions between different programmers and designers, and what people might expect out of them.</p>
<p>The rest of the sessions ranged from simply OK, to a couple of pretty bad ones, that totally felt like a sponsored session where they were trying to sell their product. It was too bad that the conference ended on such a low note, after starting with the amazing first day (and the really good first two days).</p>
<p>I really hope they organize a similar conference for next year, but the key is going to be to come up focused, relevant topics. Personally, I&rsquo;d like to see one of the sessions concentrate on asset pipelines: both overviews of current projects, and specific techniques and organizations (use of databases, concurrent editing, integration of source control, etc). All in all, it was a great experience, though. The small size of the conference and the great speakers and attendees made it really unique, and gave me an opportunity to finally meet a lot of people I had only interacted with through mailing lists before.</p>]]></content:encoded></item><item><title>2004 GameTech Report: Creating Believable Characters</title><link>https://gamesfromwithin.com/2004-gametech-report-creating-believable-characters/</link><pubDate>Wed, 08 Dec 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/2004-gametech-report-creating-believable-characters/</guid><description>&lt;p&gt;They say good things come in small packages. That was certainly true of this year&amp;rsquo;s &lt;a href="http://www.game-tech.com/"&gt;Game Tech Seminars&lt;/a&gt;. It was a four-day intensive conference dealing with very specific topics (realistic characters and engine/tools technology) with a very impressive list of speakers. The best part though, was the attendees. There were only about 80 people total in the conference (due in no small part to the hefty price tag attached to the conference, I&amp;rsquo;m sure), and they were mostly tech leads or directors of technology of their companies. It was great to see lots of familiar faces, but also a lot of new ones I only knew through the Internet or not at all before. The great discussions following each session, or even over lunch or dinner were worth the price of admission alone.&lt;/p&gt;</description><content:encoded><![CDATA[<p>They say good things come in small packages. That was certainly true of this year&rsquo;s <a href="http://www.game-tech.com/">Game Tech Seminars</a>. It was a four-day intensive conference dealing with very specific topics (realistic characters and engine/tools technology) with a very impressive list of speakers. The best part though, was the attendees. There were only about 80 people total in the conference (due in no small part to the hefty price tag attached to the conference, I&rsquo;m sure), and they were mostly tech leads or directors of technology of their companies. It was great to see lots of familiar faces, but also a lot of new ones I only knew through the Internet or not at all before. The great discussions following each session, or even over lunch or dinner were worth the price of admission alone.</p>
<p><img alt="gametech" loading="lazy" src="/2004-gametech-report-creating-believable-characters/images/gametech_l.png"></p>
<p>I&rsquo;ve been saying for a while that the â€œnext frontierâ€ of game technology is going to be characters. Not fancy graphics. Not physics. Not online play. We can now create worlds that have exquisite lighting, fancy details, and complex environments. And we can do it in real time too. Sometimes you start to wonder if we&rsquo;re really approaching movie-level quality. Then a character walks in and that illusion is permanently destroyed: the feet slide as the character slows down, the animation pops as it transitions between different poses, the arm interpenetrates the table when he leans on it, the skin looks more like paper, and the hair look like it has been plastered down with super glue. In other words, the character has less charm than a zombie straight out of a B-horror movie.</p>
<p>It is no surprise then that the first two days of the GameTech seminars were dedicated to characters. It approached the problem from two different angles. First it examined how we can try to make better looking characters. Then it addressed the question of making them move in a more realistic way.</p>
<p>It started by covering some of the latest advances in hair and skin rendering from the Siggraph and special effects crowd. When we&rsquo;re talking about physically rendering and simulating each individual hair as a link of 10 or more jointed segments, you know we&rsquo;re way beyond what&rsquo;s currently possible in games. Still, it&rsquo;s a glimpse of where we&rsquo;re heading in a few years down the pipe. In the meanwhile, understanding the full simulation in detail might help us come up with shortcuts and tricks that look somewhat like the real thing.</p>
<p>The skin rendering part was much more down to earth. Even when it was approached from the movie production point of view, what they&rsquo;re doing is not as far from what could be possible soon. As a matter of fact, they are already way past the point of diminishing returns in regards to quality improvements. Some of the models for subsurface scattering presented only produced extremely subtle changes (I wouldn&rsquo;t even be able to call them improvements, although I&rsquo;m sure they look closer to the reference photographs).</p>
<p>ATI showed off <a href="http://ati.com/ruby/index.html">their newest Ruby demo</a>. I really was expecting more by way of character animation, but they had some pretty fancy lighting which used pre-computed lighting sampled at a bunch of points in the environment (along a couple of splines in the tunnel), and applied in real time to the moving characters. For skin rendering, they are just blurring the diffuse lighting to fake subsurface scattering. Interestingly, they&rsquo;re using a shader that does a Poisson disk filter, which seems to be popping up everywhere you look nowadays (depth of field, shadows, subsurface scattering,&hellip;). A few years ago, shiny bumpy things was the in thing. Now it&rsquo;s blurry diffuse effects.</p>
<p>The animation section is where things really started getting interesting. We all know that the days of pure pre-canned animation playback are numbered. So far we&rsquo;ve only been making attempts at correcting grab animations, or to plant the feet on the ground with IK. But there&rsquo;s more that we can do. Much more.</p>
<p><a href="http://www.cs.wisc.edu/~kovar/">Lucas Kovar</a> and <a href="http://www.cs.wisc.edu/~gleicher/">Michael Gleicher</a> presented some of their research in the area of data-driven character motion. The results were absolutely stunning. They approached the problem of creating new animations in a variety of ways, but they all had in common that they were creating new animations based on captured animation data. <a href="http://www.cs.wisc.edu/graphics/Gallery/Kovar/MoGraphs/">One approach</a> looked at a bunch of motion data and created animation trees from it with nearly seamless transitions. For anybody who has tried putting together a simple animation tree for a third-person game, that produced really amazing results (although they were also using really complex animation â€œtreesâ€).</p>
<p><a href="http://www.cs.wisc.edu/graphics/Gallery/Kovar/ParamMotion/">The parametrized motion project</a> was really impressive and I think has a lot of future in game development. It synthesized new animations based on existing similar animations. So out of a few walking, turning, and jumping cycles, it could generate a new set of animations to adapt themselves to the current game environment. It was also demonstrated with more complex animations like martial arts movements or even cartwheels. At the heart of this approach is the idea of match webs, which are a data structure used to find potential matches to similar animations. The applications to offline animation authoring are obvious, but I really think it&rsquo;s possible to apply it at runtime as well. They were able to show some impressive results with just a few animation data sets.</p>
<p><img alt="gametech" loading="lazy" src="/2004-gametech-report-creating-believable-characters/images/motion_families.jpg"></p>
<p>The next day, <a href="http://www.pseudointeractive.com/team_davidwu.shtml">David Wu</a> approached the problem of adapting animations to the environment by trying to solve the physical constraints. While it might be a reasonable approach to â€œfixâ€ animations or to make minor tweaks, it really didn&rsquo;t show the potential of the data-driven animation approach. The most interesting thing I got out of David&rsquo;s talk was his comment about how many game developers lack an understanding of what&rsquo;s going under the hood in middleware packages (especially for physics) and so they can&rsquo;t take full advantage of its capabilities. I don&rsquo;t think that&rsquo;s true for something like graphics or sound. I wonder if that means we haven&rsquo;t exposed the right interface to physics middleware packages. Or maybe physics is more complex and more tightly coupled to the rest of the game. David went on to present what he considers is going to be the future interface of physics (he compared it to the advances that computer graphics made once we all agreed on using the polygon as a basic primitive).</p>
<p>Finally, a third way of approaching animation synthesis was presented by <a href="http://users.ox.ac.uk/~quee0818/">Torsten Reil</a>, from <a href="http://www.naturalmotion.com/">Natural Motion</a>. He tackled the problem by using a set of controllers and running it through a set of genetic algorithms to develop the motion he wanted out of them. Unfortunately, it felt that he didn&rsquo;t want to get into many details when he was asked questions from the audience, probably because of patent issues and the fact that Natural Motion is selling a product based on that research. Because of that, it felt a bit like a sales pitch â€œLook at this cool tech. Now come buy our tool that does it all for you.â€ A lot of the demos showed used a combination of genetic algorithms to derive the controllers, plus some artist tweaking, and a few heuristics. Right now, this approach is limited to offline animation only. Still, it was very impressive to see the results of the genetic evolution of bipedal motion and hear what type of troubles they had to go through to generate them (they had to resort to using a stabilizing controller like training wheels on a bicycle to be able to past some of the local maxima that were preventing further evolution in the right direction).</p>
<p>Of the three approaches, I&rsquo;m really excited by the data-driven techniques. I really believe that we can start applying some of those techniques in games relatively soon (this next generation of consoles even). The big advantage it has is that it doesn&rsquo;t just generate a plain walking animation. You can feed it whatever type of specific type of animation you want: sneaking walk, female walk, big guy walk, etc. You can then adapt those type of animations to your game and get the style you wanted perfectly integrated in your game.</p>
<p>Finally, <a href="http://www.eelpi.gotdns.org/"></a><a href="http://www.eelpi.gotdns.org/">Tom Forsyth</a><a href="http://www.eelpi.gotdns.org/"></a>&rsquo;s talk on â€œHow to Walkâ€ was a very down to earth, practical and well illustrated. Basically, he started by saying that most games out there right now have terrible walk cycles. That&rsquo;s particularly a problem for third-person games, where the player is constantly seeing his avatar move around the world. It&rsquo;s a topic he&rsquo;s particularly well-qualified to talk about since he&rsquo;s currently developing <a href="http://www.radgametools.com/gramain.htm"></a><a href="http://www.radgametools.com/gramain.htm">Granny</a><a href="http://www.radgametools.com/gramain.htm"></a>. The key idea from his talk is that the animation should <strong>not</strong> drive the movement of the character in the world. It should always be the game that is moving the character, and the animation system should do its best to keep up and minimize artifacts (the only situation when this was not true is when moving the character up and down over a flight of stairs or some other discontinuity, or during cutscenes, when the player is not in control). He explained how to effectively blend animations (make sure they&rsquo;re synched), how to use leaning forwards, backwards, and to the sides when the character changes direction or speed, etc. He showed all these techniques with a neat little demo that will probably be bundled with the Granny SDK.</p>
<p>That was a lot of stuff for just two days! Every night my brain would be full, ready to explode, but it was really a great session. It was a great mix of current academic research projects, movie effects, and current application to games. But that wasn&rsquo;t the end. The next two days we would switch gears and cover engine and tools technology. I&rsquo;ll talk about those in the next article.</p>]]></content:encoded></item><item><title>All Work No Play, Makes Jack a Dull Game Developer (Part 2)</title><link>https://gamesfromwithin.com/all-work-no-play-makes-jack-a-dull-game-developer-part-2/</link><pubDate>Mon, 06 Dec 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/all-work-no-play-makes-jack-a-dull-game-developer-part-2/</guid><description>&lt;p&gt;â€œWanted: Young, skinny, wirey fellows not over 18. Must be expert riders willing to risk death daily. Orphans preferred. Wages $25 per week.â€ Pony Express advertisement, 1860.&lt;/p&gt;
&lt;p&gt;That would be a funny anachronism if it weren&amp;rsquo;t still so true. OK, so game companies are not asking potential candidates to risk death every day, but they surely are asking them to give up their lives to the company.&lt;/p&gt;</description><content:encoded><![CDATA[<p>â€œWanted: Young, skinny, wirey fellows not over 18. Must be expert riders willing to risk death daily. Orphans preferred. Wages $25 per week.â€ Pony Express advertisement, 1860.</p>
<p>That would be a funny anachronism if it weren&rsquo;t still so true. OK, so game companies are not asking potential candidates to risk death every day, but they surely are asking them to give up their lives to the company.</p>
<p>I really wish I had saved some of the truly horrible job listings that I have seen over the last few years to contrast it to the Pony Express one. Instead, the â€œbestâ€ one I was able to find on short notice was one with the following requirements:</p>
<p>â€œBe a self-starting, hard working individual capable of maintaining focus within a rigorous, deadline-driven production schedule. Have a passion for games.â€</p>
<p>In itself, there&rsquo;s nothing really wrong with those requirements. Heck, I consider myself to be a good fit based on that description. Unfortunately, this is more what the job listing is really looking for:</p>
<p>â€œBe a self-starting, hard working individual capable of maintaining focus in the face of massive crunch time and unrealistic milestones, and able to pull through with massive heroic efforts. Have a passion for games and nothing else, so you won&rsquo;t mind spending all your time at the office. Not over 25. Singles preferred.â€</p>
<p>In this second part I argue that long hours in game development are not only something that could be avoided, but that they&rsquo;re actually detrimental to the project.</p>
<p><strong>Are long hours inevitable?</strong></p>
<p>I want to start by debunking fourth myths:</p>
<p><strong>Myth #1:</strong> There are lots of young kids out there willing to take our jobs.</p>
<p>That&rsquo;s very true. However, most of those â€œkidsâ€ have no idea what the job is really about (hint, we&rsquo;re not playing games all day long), and they&rsquo;re hopelessly underqualified. So if a company decides to replace its staff with lots of young, inexperienced developers right out of college, well, that&rsquo;s their choice. I doubt they&rsquo;ll manage to create a decent game, and they surely won&rsquo;t be able to make a second game with the same staff after burning everybody out. Ironically, this comes after the announcement that EA made in response to ea_spouse&rsquo;s blog that they were planning to do 75% of their hires from developers straight out of college.</p>
<p>The modern version of this myth is offshore development. In some circles it has become quite a paranoia. It hasn&rsquo;t hit us hard in the games industry yet, although art is the area seeing most jobs going abroad. I don&rsquo;t want to get into an offshore debate here, but suffice to say that the jobs easiest to replace are those that can be done fairly mechanically, which are in turn the ones that can be done best during major crunch without a clear head.</p>
<p><strong>Myth #2:</strong> If you&rsquo;re getting paid enough, you should be willing to work any amount of time.</p>
<p>So maybe this one is actually true. If someone is willing to pay me enough in one year that so that I don&rsquo;t need to worry about money for the rest of my life, then sure, they can have my undivided attention 24/7 for a full 365 days. No questions asked. Most of the time though, we&rsquo;re just talking about a few measly tens of thousands of dollars extra. Good money to be sure, but it doesn&rsquo;t even come close to the value of spending time with my family, being outdoors, or just doing different activities.</p>
<p>So no, getting paid a good amount doesn&rsquo;t entitle the company to my full devotion.</p>
<p><strong>Myth #3:</strong> If the company pays for overtime, then everything is OK.</p>
<p>Paying for overtime might be a good start, not because of the money (see myth #2), but because it would discourage companies from applying crunch time at the drop of a hat. Maybe they would start looking into alternatives (cutting features, delaying the release, changing design, etc).</p>
<p>But the point is, even if all the extra time is payed for, it won&rsquo;t make people any more productive or make them do better-quality work. It&rsquo;ll just make it so some of them don&rsquo;t complaint so much. In the end though, most people would agree that receiving a lot of money and not having time to spend it is no way to live. It might be an OK short-term situation, but certainly not something to keep up indefinitely.</p>
<p><strong>Myth #4:</strong> We&rsquo;re doing games because we love it, so we have to put up with any hours.</p>
<p>It&rsquo;s true that most people are working in the games industry because they love what they do. Game development has been my hobby for as long as I can remember, and I&rsquo;m currently as close to my dream job as I&rsquo;m ever going to get. That doesn&rsquo;t mean it&rsquo;s not a job though. We&rsquo;re professionals working for a company and getting paid to do a specific job. In the same way, I love cycling but it doesn&rsquo;t mean I want to do it 12 hours a day every day (going out with the club on an hilly 80-mile Saturday ride is plenty, thank you :-)</p>
<p>At the same time, it doesn&rsquo;t mean that we&rsquo;re counting the minutes before we can punch out at 5PM. Sometimes what we&rsquo;re doing is fascinating and we want to spend some extra time. As long as people are still rested and motivated, that&rsquo;s great.</p>
<p>So I claim that there&rsquo;s nothing different about the games industry that makes long hours inevitable. The only remaining, and most important, question is whether long hours are actually useful and help ship a better product.</p>
<p><strong>Are long hours useful?</strong></p>
<p>I&rsquo;m convinced that developing the technology for a game is like running a marathon. I really think that the analogy carries very far. Notice also that I qualified it as applying to the development of the technology, not the game as a whole. Design and art have some of that touchy-feely creative mystique that can be very bursty. Heck, some of the best art in the history of humankind has been done while under the heavy influence of drugs and totally altered psychological states. So for all I know sleep deprivation actually helps. I&rsquo;m going to limit myself to talking about technology development, which is what I&rsquo;m familiar with.</p>
<p>Just like in a marathon, you start out a project knowing that you have to accomplish something (ship a game), in a rough timeframe (2-3 years, or whatever the plan is). It&rsquo;s true that in game development there are more unknowns and changes along the way (although there can be quite a few in a marathon as wellâ€”unexpected hills, cramps, dehydration, etc), but the same general principle applies.</p>
<p>The way game development seems to work is by snoozing through the initial gunshot. Instead of settling into an early even pace, we just doze off at the start line or do some stretching. Then, after a while, we start to leisurely walk down the course. We don&rsquo;t worry because we&rsquo;ve promised that we&rsquo;ll hit the first timed spot by minute 30. As the clock rolls around to minute 25, we realize that we aren&rsquo;t going to make it there by the time we promised at this pace, so we sprint for a couple of miles and manage to make it there in quite a heroic sprint. Mission accomplished for the moment. We sit down. Take a break. After all, we worked very hard. Then we repeat the same cycle, but each time less walking and more sprinting. Soon we start not meeting the times we wanted. Eventually, we&rsquo;re faced with a situation that in order to complete the race in the time we wanted, we would have to sprint like hell for the rest of the course. So we actually go ahead and try it (knowing perfectly well that we&rsquo;ve never been able to sprint like that for an extended period of time). Of course, we get really tired. We need to stop. We move back our estimates. We try it again. Eventually, if we&rsquo;re lucky, we manage to make it to the finish line. Much later than we had hoped for, but we&rsquo;re extremely proud of how much effort we put into it. â€œI gave it 120% percent in the last 5 miles, man!â€</p>
<p>OK, enough of that story. The point is that the best marathons are run at a very constant pace. People who go too slow (or too hard) early on end up paying for it in the end.</p>
<p><strong>Edit:</strong> This is actually funny in an embarrasing kind of way. I had originally linked <a href="http://zhurnal.net/ww/zw?MarathonGraphs">some great plots of Marathon running times</a> that were supposed to support my theory of a steady pace winning at the end. Unfortunately, I read them backwards and they really were not helping any :-) I chuck that one to the runner not being a top-level athlete.</p>
<p>The following plot instead shows the times of some of the top positions in the <a href="http://www.bostonmarathon.org/BostonMarathon/108thMarathon.asp">2004 Boston Marathon</a>. It&rsquo;s a much better example that the previous one because the data applies to top athletes and over the same course and the same day. The most important thing to notice is how constant the paces are. They&rsquo;re almost perfectly linear for runners 1, 8, and 15. Runner 21 on the other hand, is a good example of someone who was trying to push it too hard at the beginning and paid for it at the end. We&rsquo;re still talking about world-class runners, so the differences are minimal, but it illustrates the point nicely.</p>
<p><img alt="marathon" loading="lazy" src="/all-work-no-play-makes-jack-a-dull-game-developer-part-2/images/marathon_1.png"></p>
<p>Fine. So &ldquo;crunch time&rdquo; doesn&rsquo;t work for marathons, but what about for games? Does the snooze-and-sprint schedule pay off in game development?</p>
<p>From personal experience, I have to say the answer is absolutely not. I can totally feel how productivity starts dropping for me after 35-40 hours of work per week. There&rsquo;s still some value in working about 60 hours because I will get more work done than in just 40 hours, but only about 10-20% more because the amount of work completed doesn&rsquo;t scale linearly. After about 80-100 hours, productivity doesn&rsquo;t just get slower, but it actually starts going down. Mistakes, bad decisions, and lousy quality quickly overwhelm any benefits from the extra hours.</p>
<p>So, is working 60-hour weeks best from a company point of view? Not really. If I try to keep the same schedule a second week in a row, productivity is much lower, and it drops off much more quickly. By the third week, we&rsquo;re already in negative productivity territory after about 40-50 hours. The insane schedule from previous weeks takes its toll really quickly and it&rsquo;s clearly felt. This is a rough plot of productivity vs. work hours. Keep in mind that I pulled the numbers out of thin air and they&rsquo;re just based on personal experience.</p>
<p><img alt="marathon" loading="lazy" src="/all-work-no-play-makes-jack-a-dull-game-developer-part-2/images/hours_plot.png"></p>
<p>We also need to consider other consequences apart from pure productivity gains. We&rsquo;re not machines (I&rsquo;m not anyway). The third week in a row of crunch I&rsquo;m basically working at half efficiency, and I really dislike that. I can&rsquo;t think clearly. I see myself doing sloppy work. I just want to get done with stuff. All those things don&rsquo;t make me any happier to have to spend countless hours at the office and take a big bite out of morale.</p>
<p>Am I alone feeling this way? <a href="http://c2.com/cgi/wiki?FortyHourWeek">Apparently not</a>. <a href="http://c2.com/cgi/wiki?OverTime">Plenty of other people seem to agree</a>. It seems pretty well documented that productivity plummets very quickly after a certain amount of hours. <a href="http://c2.com/cgi/wiki?KentOnWardOnSustainablePace">This quote</a> from the c2 Wiki summarizes it all for me:</p>
<p>The story that brought work hours home to me was one Ward tells. The C++ team was working nights and weekends, the Smalltalk team went home (tired) at 5 and rested all weekend. Management wasn&rsquo;t happy with the results of either team, and pressured the Smalltalkers to work more hours. Ward&rsquo;s response, &ldquo;We would if it would help.&rdquo;</p>
<p>Similar conclusions were reached in studies quoted in Tom DeMarco&rsquo;s classic <a href="http://www.amazon.com/exec/obidos/ASIN/0932633439/ref=nosim/gamesfromwith-20"><em>Peopleware</em></a> and <a href="http://www.amazon.com/exec/obidos/ASIN/0767907698/ref=nosim/gamesfromwith-20"><em>Slack</em></a> books.</p>
<p>When I can work around 40 hours per week, I come in every day to work energized and looking forward to the day. I get tons accomplished. And when I get home, I actually spend quite a bit of time learning about related topics, working on different projects, or just letting my mind wander and do free associations. I tend to have most creative breakthroughs when I&rsquo;m relaxing and doing something unrelated to work: riding my bike, showering, or even falling asleep (never go to bed without a notebook on the nightstand!). None of that happens as soon as the work hours start to increase. It might be a very small short-term gain, but a large long-term loss.</p>
<p>In conclusion, a short, focused, period of crunch time to reach a particular goal is probably fine and can be used to good effect. Anything longer than a week or two, and it starts having very negative consequences. In any case, you also need to make sure people get good rest afterwards, otherwise they won&rsquo;t be able to go back to working at full efficiency.</p>
<p>Some people will argue that a two-week crunch every so often is good for the morale. I disagree with that. Who is going to be more proud of what they accomplished, the team who crunched for two weeks, or the one who didn&rsquo;t have to do any crunch at all and met the same goals?</p>
<p><strong>How to avoid long hours?</strong></p>
<p>All this should be completely common sense, but I&rsquo;ll reiterate here anyway.</p>
<ul>
<li>Don&rsquo;t assume long hours are inevitable. Do what you can to avoid them.</li>
<li>Don&rsquo;t waste time. Don&rsquo;t re-write things you don&rsquo;t have to. Don&rsquo;t spend half the day talking by the coffee machine. Don&rsquo;t play <em>Call of Duty</em> for 3 hours at lunch.</li>
<li>Don&rsquo;t procrastinate. An hour of work now is just as precious and valuable as an hour before going gold. Do what you have to do now.</li>
<li>Prioritize your tasks (or get your manager/boss/designer to prioritize them for you). Be ready to drop the least essential tasks if you start running out of time.</li>
<li>Work with a sense of urgency. Large amount of pressure are no good and they tend to paralyze people or make them work in fear and make mistakes. On the other hand, no pressure at all tends to encourage people to take detours, and spend forever to get something perfect (as opposed to good enough to do what it needs to do). A small amount of pressure is perfect to keep the pace up.</li>
<li>Use agile development. It&rsquo;s a great way to keep re-prioritizing your goals and hit moving targets.</li>
<li>Work hard for 40 hours. Play hard by going home at the end of the day. Maintain a <a href="http://c2.com/cgi/wiki?SustainablePace">sustainable pace</a>.</li>
</ul>
<p><strong>Conclusion</strong></p>
<p>The most important thing to keep in mind is not to do something you&rsquo;re not happy with. Game development is a fascinating activity, but it doesn&rsquo;t mean you have to give up the rest of your life to it. Anybody should be able to work in games and keep a reasonable life outside of work. If things are not reasonable at your company, bring up the subject and try to change it. Show them this article or some of the links mentioned here. If all fails, there are other companies out there that would be happy to have you.</p>]]></content:encoded></item><item><title>All Work No Play, Makes Jack a Dull Game Developer (Part 1)</title><link>https://gamesfromwithin.com/all-work-no-play-makes-jack-a-dull-game-developer-part-1/</link><pubDate>Sun, 05 Dec 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/all-work-no-play-makes-jack-a-dull-game-developer-part-1/</guid><description>&lt;p&gt;This article has been a long time coming. It should be abundantly clear from past articles I&amp;rsquo;ve written (and from my rants if you know me in person) that I feel very strongly about quality of life issues in the games industry. It pains me to see rampant overtime be commonplace, and the truly ironic part is, I&amp;rsquo;m convinced it doesn&amp;rsquo;t help the final game any. As a matter of fact, it probably makes people be less productive and makes the game suffer for it. Ah, but they crunched some impressive hours. They have something they can feel proud of.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This article has been a long time coming. It should be abundantly clear from past articles I&rsquo;ve written (and from my rants if you know me in person) that I feel very strongly about quality of life issues in the games industry. It pains me to see rampant overtime be commonplace, and the truly ironic part is, I&rsquo;m convinced it doesn&rsquo;t help the final game any. As a matter of fact, it probably makes people be less productive and makes the game suffer for it. Ah, but they crunched some impressive hours. They have something they can feel proud of.</p>
<p>In the meanwhile, people are finally starting to wake up and say enough is enough. As most people are probably already aware (after hitting Slashdot and all the major game news sites), a few days ago the brutally honest <a href="http://www.livejournal.com/users/ea_spouse/">blog entry from ea_spouse</a> caught everyone by surprise. To throw fuel in the fire, <a href="http://www.livejournal.com/users/joestraitiff/368.html">another great entry by EA ex-employee</a>, Joe Stratiff, quickly followed. Judging by the amount of attention they&rsquo;re getting, people are clearly very interested.</p>
<p>It has since then made it to the national news, hitting the New York Times, the San Francisco Mercury, and many other national newspapers. I suspect the effects of these developments will be felt for the new few months with other follow ups in Game Developer Magazine and GDC presentations. There is even talk of a game development union. Whatever the direct results, those blog entires already accomplished a lot: raising the awareness of the working conditions of the industry. Putting an ugly truth in front of people&rsquo;s faces.</p>
<p><strong>The state of the industry</strong></p>
<p>Those blog entries only dealt with EA. What about the rest of the games industry? EA is the major player in the games industry. They are the largest game development company, and they are one of the main publishers. In other words, they&rsquo;re the big bully in the playground. If they do something, chances are it&rsquo;s going to affect other people. Even worse, if they do something and it ends up being successful, other companies are quickly going to follow suit, or at least use it as a justification for their decisions.</p>
<p>But unfortunately rampant overtime and major crunch mode are not limited to EA. Most game development companies expect some level of crunch, usually about 65-80 hour weeks for up to a couple of months at the time. That&rsquo;s not a one-time crunch either, but repeated multiple times during the development cycle.. What is worse, a lot of companies operate in a constant â€œcrunchâ€ mode, with 60-hour weeks being the norm. You can get all the detailed stats and lots of insightful commentary from the <a href="http://www.igda.org/qol/whitepaper.php">IGDA quality of life whitepaper</a>.</p>
<p>As is often the case, variety is good, and variety within companies in the games industry means that it is possible to find different working conditions depending of where you go. There are four types of companies with respect to crunch mode:</p>
<ol>
<li>On one end of the spectrum, we have companies like EA that just require overtime as a matter of fact. To be fair, not all EA studios operate under that mode. Apparently the one mentioned in the blogs was the LA studio. Several people are reporting that the situation is very different in EA Canada for example.</li>
<li>Some others will only require overtime when the project is in trouble of not meeting a milestone or a delivery, but of course, to anybody know knows how projects are run, that means that the project is in crunch for most of its development cycle.</li>
<li>Going further away from that, we have companies that don&rsquo;t require overtime, although they certainly encourage it from their employees.</li>
<li>Finally, on the other extreme, some other companies either actively discourage people from working ridiculous hours, or they&rsquo;ll accept it if somebody really wants to do it, but won&rsquo;t encourage it in any way.</li>
</ol>
<p>If there is a silver lining to all this mess is the fact that this is bringing companies in the fourth category to the limelight. IGDA has identified several companies, including <a href="http://www.bluefang.com/">Blue Fang Games</a> and <a href="http://www.firaxis.com/">Firaxis</a>, as companies that respect their employees&rsquo; lives and actively try to avoid crunch or overtime. Blue Fang has even been proudly advertising that fact in their job listings. I can only hope that more companies will stand out and identify themselves as being in the same category.</p>
<p>Perhaps that&rsquo;s even something that IGDA can mediate, with game companies submitting their candidacy for the â€œquality of life IGDA seal of approvalâ€, and IGDA can then send someone to verify their claims and add them to a publicly-available list of companies that avoid extended crunch time and meet all the quality of life requirements.</p>
<p><img alt="Dali clock" loading="lazy" src="/all-work-no-play-makes-jack-a-dull-game-developer-part-1/images/dali_2.jpg"></p>
<p><strong>Finding a good company</strong></p>
<p>Unfortunately, even though companies like that exist, they&rsquo;re still far from the norm. You really have to dig deep to find companies in categories 3 and 4. Until IGDA creates an extended list, how do you go about finding one?</p>
<p>Word of mouth is a good approach. Network, find someone who knows someone who works there. Ask them about their work conditions, their typical work-week, how late people leave the office. You&rsquo;ll find that most people are extremely open about it. One thing to watch out for is information that is several levels removed: If the roommate of their friend&rsquo;s coworker had some bad things to say about a company, it might be greatly exaggerated by the time that information reaches you. Try to go with first-hand, or at most second-hand accounts.</p>
<p>Also, take anything that an ex-employee says with a grain of salt. Don&rsquo;t ignore it by any means, just don&rsquo;t base your whole decision on their opinion. People leave companies for all sorts of different reasons, and it often colors their opinion of the company as a whole.</p>
<p>If you don&rsquo;t know anybody who works there directly, try asking in some of the industry forums. For example, if you&rsquo;re already in the games industry, you might want to check out <a href="http://thechaosengine.com/">The Chaos Engine</a>. They have a whole forum called â€œAbout Company Xâ€ just for people to ask opinions about different companies. They have quite a large membership, so it&rsquo;s very likely you&rsquo;ll find someone who is currently working at that same company. But the usual dose of salt applies: The forum uses a semi-anonymous format, so anybody is free to say whatever they want without consequences.</p>
<p>Finally, assuming you liked what you heard so far about a company, you went ahead and applied there. If all went well and you got called in for an in-person interview, this is your time to be pro-active about it. You will meet a lot of people during the interview. They&rsquo;ll ask you a lot of questions, but they&rsquo;ll also let you ask a lot of questions as well (after all, interviews are a two-way street&ndash;you&rsquo;re trying to find out as much about them as they are about you). Make sure you come prepared with a lot of questions, but make sure that one or two of them are aimed to find out more about their crunch habits. Some good warm-up questions are â€œWhat is your typical work week?â€ or â€œWhat is the usual time for people to arrive to work and leave for home?â€. If you get fuzzy answers to that, or you suspect there&rsquo;s more than what they&rsquo;re saying, ask them straight out: â€œWhen was the last time you crunched?â€ â€œHow long was it and how many hours a week was it?â€.</p>
<p>Make sure you ask those questions to everybody you talk to. You&rsquo;ll be surprised how different people will answer the same questions sometimes. Don&rsquo;t be shy about asking those questions too. Any employer who thinks less of you for asking that probably won&rsquo;t try to avoid crunch time, so you probably didn&rsquo;t want to work there anyway.</p>
<p>I&rsquo;ve already noticed that people are asking about crunch time a lot more frequently during phone interviews since the whole EA Spouse blog hit the news. If nothing else, that is already doing some good to the industry.</p>
<p><strong>Why does it happen?</strong></p>
<p>So, why is crunch time rampant in this industry? Is there something inherent to games that requires bursts of activity? Some people will argue that games are a creative activity, just like movies, hit or miss, entertainment industry, yadda, yadda, yadda. That might be true for the design part, but there&rsquo;s no excuse in the engineering part.</p>
<p>The ugly truth is that crunch is simply a self-fulfilling prophecy. It happens because people walk into game projects fully expecting to spend half of it crunching. That also means they can goof off for the first half. Call it procrastination. Call it human nature. Call it whatever you want, but that&rsquo;s really what happens. It&rsquo;s ingrained in the game industry culture due to its cottage industry roots. About 20-30 years ago, games were all about two kids spending crazy hours in somebody&rsquo;s basement. For some reason, the industry is having a hard time letting go of that image, and that&rsquo;s hurting everybody: the people suffering those hours, and the projects suffering those burned-out, tired people.</p>
<p>The worst part is that it really is so ingrained in the culture, that not only do people expect it, but they feel proud of it after it&rsquo;s done (if they forget about the 20 pounds they gained during that time, the fact that their kids are two years older than they remember, and that they need to go to the divorce court next Wednesday). I am disgusted every time I read a postmortem in <a href="http://gdmag.com/">Game Developer Magazine</a> or <a href="http://gamasutra.com/">Gamasutra</a> that lists â€œteam pulled together and worked insane hours during months on endâ€ under the â€œWhat Went Rightâ€ section.</p>
<p>As long as some people feel that way, it&rsquo;s very difficult to break out of that mode. It&rsquo;s very hard to walk out of the building when the rest of the team is in â€œheroâ€ crunch mode, even if you know you&rsquo;re not doing anybody a favor by staying more hours in the building. That&rsquo;s particularly true when it&rsquo;s your boss who thinks that crunch time is a natural part of the process and is essential to ship a quality game. Trying to keep sane hours can easily cost you raises, promotions, or even your job.</p>
<p>The million-dollar questions are, is crunch time really inevitable and does it really help a product? I&rsquo;ll tackle those with my unpopular opinions and theories in <a href="/all-work-no-play-makes-jack-a-dull-game-developer-part-2/">the second part of this article</a>.</p>]]></content:encoded></item><item><title>Book review: Effective STL</title><link>https://gamesfromwithin.com/book-review-effective-stl/</link><pubDate>Sat, 13 Nov 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/book-review-effective-stl/</guid><description>&lt;p&gt;Have you read &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0201924889/ref=nosim/gamesfromwith-20"&gt;&lt;em&gt;Effective C++&lt;/em&gt;&lt;/a&gt; also by Scott Meyers? No? Go buy it right now, read it, reread it, and then come back here. I guarantee that it will make a huge difference in the way you work.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Have you read <a href="http://www.amazon.com/exec/obidos/ASIN/0201924889/ref=nosim/gamesfromwith-20"><em>Effective C++</em></a> also by Scott Meyers? No? Go buy it right now, read it, reread it, and then come back here. I guarantee that it will make a huge difference in the way you work.</p>
<p>This review was first published in the January 2002 issue of Game Developer Magazine. <a href="http://www.convexhull.com/articles/gdmag_effective_stl.pdf">Printer-friendly format</a>.</p>
<p><a href="http://www.amazon.com/Effective-STL-Addison-Wesley-Professional-Computing/dp/0201749629%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201749629"><img loading="lazy" src="/book-review-effective-stl/images/41W3B0YFG8L._SL500_.jpg"></a></p>
<p>OK, welcome back. Here is the good news: <em>Effective STL</em> is to STL what <em>Effective C++</em> is to C++. It&rsquo;s equally great and it&rsquo;s written in the same light, conversational Scott Meyers style that makes reading it a pleasure. It assumes that you have basic knowledge of STL (and C++) and builds on that to show you how to use it effectively and avoid common pitfalls.</p>
<p>Those of you unfamiliar with STL must be wondering what it is and how is it useful for game development. STL stands for Standard Template Library: A library of generic data structures and algorithms that you can use across many compilers/platforms, including most of the current consoles. The library is implemented with templates so the resulting code will be quite efficient, possibly even more than your hand-coded structures and algorithms. Additionally, it has been implemented, tested, debugged and optimized by thousands of people, so it&rsquo;s code you can usually rely on. STL also empowers you by putting very powerful constructs at your fingertips. Maybe before you would have thrown a bunch of objects in an array and searched through them in linear time (does that sound familiar?), but now you can just as easily put them in a hash table and have constant-time access to them.</p>
<p><em>Effective STL</em> starts out with a fairly thorough discussion about containers (vector, list, map, etc) and iterators. It immediately goes beyond the typical description of the containers and their O(n) performance characteristics. Instead it deals with many real-world questions: Is the memory for the elements allocated contiguously? Are the iterators invalidated when the elements change? What the most efficient way of removing elements for a specific container? Those are not issues you&rsquo;ll see addressed in most STL books.</p>
<p>It then moves on to algorithms and functors. Just like with the containers, instead of listing all the available algorithms, it points out common mistakes and how to deal with them. For example, it will discuss the different ways of sorting elements, or how std::remove really works (and why it doesn&rsquo;t really remove anything).</p>
<p>The final chapters present more general, but very useful, information on the STL that will save you a few headaches along the way: When to use STL algorithms and when to use your own, style guidelines, or even how to deal with Microsoft&rsquo;s Visual C++ broken STL implementation and template support.</p>
<p>But STL is not perfect. Reading the book will give you some ideas of where STL is lacking, but it won&rsquo;t spell them out for you. Sometimes you&rsquo;ll need to read between the lines and think about how things will apply to game development. For example, memory allocation can be an issue, especially if you&rsquo;re developing for a console, so you&rsquo;ll probably want to end up writing your own allocators. The book has a brief couple of items discussing what you can and can&rsquo;t do with allocators, but not enough to write your own. You&rsquo;ll need to look elsewhere for that.</p>
<p>Another issue often brought up when dealing with STL is the difficulty debugging STL code, from cryptic multi-line error messages to the difficulty viewing the elements of a container in the debugger. The book will help you a bit by showing you how to â€œparseâ€ the intimidating error messages and directs you to some STL resources on the Internet.</p>
<p><em>Effective STL</em> works very well both as a book to read cover to cover and as a reference later on. It only uses source code where it has to; it won&rsquo;t bore you with pages and pages of pointless code. As a matter of fact, it won&rsquo;t bore you at all since it packs a lot of information in a mere 250 pages. Overall, you simply must read this book before you decide to use (or not to use) STL in your next game or tools. If you&rsquo;re already using STL, then it should already be on your bookshelf.</p>]]></content:encoded></item><item><title>2004 MontrÃ©al Game Summit Report</title><link>https://gamesfromwithin.com/2004-montreal-game-summit-report/</link><pubDate>Sun, 07 Nov 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/2004-montreal-game-summit-report/</guid><description>&lt;p&gt;What do &lt;a href="http://nwn.bioware.com/"&gt;Neverwinter Nights&lt;/a&gt;, &lt;a href="http://www.splintercell.com/"&gt;Splinter Cell&lt;/a&gt;, and &lt;a href="http://www.prince-of-persia.com/"&gt;Prince of Persia&lt;/a&gt; have in common? They were all developed in Canada. The latter two right in &lt;a href="http://www.montreal.com/"&gt;MontrÃ©al&lt;/a&gt;. Some of the giants of the game industry either originate, or have large studios in Canada as well: &lt;a href="http://www.ubisoft.com/"&gt;Ubi Soft&lt;/a&gt;, &lt;a href="http://www.ea.com/"&gt;Electronic Arts&lt;/a&gt;, &lt;a href="http://www.microids.com/"&gt;MicroÃ¯ds&lt;/a&gt;, &lt;a href="http://www.softimage.com/"&gt;Softimage&lt;/a&gt;, and &lt;a href="http://ati.com/"&gt;ATI&lt;/a&gt; among others. People might not realize it, but our friendly cousins in the North are quite influential in the games industry.&lt;/p&gt;</description><content:encoded><![CDATA[<p>What do <a href="http://nwn.bioware.com/">Neverwinter Nights</a>, <a href="http://www.splintercell.com/">Splinter Cell</a>, and <a href="http://www.prince-of-persia.com/">Prince of Persia</a> have in common? They were all developed in Canada. The latter two right in <a href="http://www.montreal.com/">MontrÃ©al</a>. Some of the giants of the game industry either originate, or have large studios in Canada as well: <a href="http://www.ubisoft.com/">Ubi Soft</a>, <a href="http://www.ea.com/">Electronic Arts</a>, <a href="http://www.microids.com/">MicroÃ¯ds</a>, <a href="http://www.softimage.com/">Softimage</a>, and <a href="http://ati.com/">ATI</a> among others. People might not realize it, but our friendly cousins in the North are quite influential in the games industry.</p>
<p><img alt="montreal2004" loading="lazy" src="/2004-montreal-game-summit-report/images/montreal_logo_l.jpg">The <a href="http://www.quebecregion.com/">QuÃ©bec</a> region (where MontrÃ©al is located) has some impressive statistics to boast about: over 40 companies involved in game development, and over 2000-full time employees (with the giant Ubi-Soft topping the charts with over 1000 employees alone).</p>
<p>Having said that, it shouldn&rsquo;t come as a surprise that the first <a href="http://www.montrealgamesummit.com/">MontrÃ©al Games Summit</a> was organized this year. It brought together some great speakers from both Canadian and US companies, and it attracted almost 600 attendees for the two days of its duration.</p>
<p>I attended to give a talk on agile game development, but I really enjoyed the rest of the sessions I got the chance to see. Overall, the conference had a feel of a mini-GDC, somewhat like the GDC roadtrips that they used to do years ago (what happened with those, by the way? They were great little events and had a much more personal feel to them since they brought together people local to the industry in each area).</p>
<p>Even though it was a quick in-and-out trip (red-eye flight in one day, late flight out the following day), I also got a chance to walk around the center of MontrÃ©al (and to practice my rusty French right away with an insistent taxi driver who spoke no English at all and wanted to know why Bush had been re-elected). Walking around MontrÃ©al, it was easy to think I was wandering around a city in France, especially in the old city section, around the Rue Saint-Paul and the Rue de la Commune. The city was really clean and walkable, and it was a real pleasure to stroll around in a chilly November morning.</p>
<p>The conference started with a keynote by Ray Muzyka on the organization of Bioware. I already knew a lot of what was covered from <a href="http://www.gamasutra.com/features/20020515/muzyka_01.htm">earlier presentations</a> <a href="http://www.gamasutra.com/gdc2004/features/20040324/moar_01.shtml">(and here)</a> and <a href="http://www.gamasutra.com/features/20021204/greig_01.htm">articles</a>, but it always strikes me that they really have their act together at Bioware. They clearly have some very sharp people running the business. It&rsquo;s interesting that they started the company without anybody having any previous industry experience (which goes to show that previous industry experience is not always necessary, and people can bring lots of new knowledge and experience from the outside).</p>
<p>I was also interested to learn that they use a matrix organization internally. On one axis they have individual projects, and on the other axis they have departments. They have clearly differentiated goals between departments (dealing with career growth and long-term plans) and the projects themselves (dealing with project-specific goals). They also continue having a lot of people per team, a trend they started with Baldur&rsquo;s Gate (having about 80 developers back in 1999) and that continues today with <a href="http://jade.bioware.com/">Jade Empire</a> having over 120. Whatever they do, they keep putting out quality title after quality title, and they only have a 3% yearly turnover rate, so they are clearly doing something right!</p>
<p><img alt="conference" loading="lazy" src="/2004-montreal-game-summit-report/images/montreal_pic.jpg"> I was pleasantly surprised to see that <a href="/agile-game-development-dealing-with-chaos-in-the-real-world/">my talk on agile game development</a> was completely packed. Even though it&rsquo;s not in widespread usage, people are clearly very curious about agile development in the games industry. It&rsquo;s also always one of the favorite topics that comes up in <a href="/gdc-2004-software-engineering-roundtable-summary-session-1/">the software engineering roundtables at GDC</a>. Maybe in a few years we&rsquo;ll start seeing some games shipped using agile methodologies from companies other than Sammy Studios.</p>
<p>That same afternoon there was an extremely interesting session on the AI of Full Spectrum Warrior by <a href="http://quinndunki.com/">Quinn Dunki</a>. She described some of the major goals of the AI development for Full Spectrum Warrior and how they went about doing it. She stressed the important of keeping things simple and the ease of debugging. To that end, they used simple, tried and true AI methods (mostly state machines), and completely avoided messaging systems, preferring to call functions directly and being able to stop the game at any time and look at the call stack. They also had some great visual debugging tools superimposed on the game to know what was going on with the AI at runtime. They also chose to avoid dynamic memory allocation (at least in the AI systems).</p>
<p>I totally agree with the idea of keeping things simple, but I think that code design and architecture considerations should come before debugging benefits. If something like a messaging system improves the architecture or maintainability, then I&rsquo;d rather use it and find some ways to improve debugging. Also, with heavy use of unit tests, debugging should become almost unnecessary. Still, she did present a compelling case for her argument.</p>
<p>One of the most interesting goals for Full Spectrum Warrior was that they wanted to have zero foot slide. If you don&rsquo;t know what that means, fire up any current 3D game with characters that move around and look closely at their feet. They&rsquo;ll range from slight sliding, to major skating over ice like crazy. In either case, they make human animations look obviously fake and it makes animations lose their â€œweightâ€. If you think that&rsquo;s a solved problem, fire up that game again. Turn the character around, transition between a walk and a run, stop suddenly. Chances are you will see feet slide all over the place. It&rsquo;s one of those problems that seems trivial until you start trying to solve it. Only then you realize how difficult it really is.</p>
<p>The character animation of Full Spectrum Warrior is outstanding, so even if they didn&rsquo;t reach their goal of 100% no foot slide, they still managed to do great job. Here&rsquo;s one scary fact she mentioned: The game had a total of about 60,000 animations (yes, that&rsquo;s the correct amount of zeros). Most of us don&rsquo;t even come within an order of magnitude of that. Just thinking of managing all those animations makes my head spin!</p>
<p>The following day I attended a session dealing with the use of <a href="http://www.fullspectrumwarrior.com/">Softimage</a> in the <a href="http://www.half-life2.com/">Half Life 2</a> asset pipeline. I was very impressed with some of the in-game sequences they showed us when the player gets to interact with other characters in the game. They had great tools to quickly set up a scene like that and all the interactions between the characters. It was particularly interesting how they imported specific assets or parts of a level into Softimage to create unique animations tailored to fit those assets. For example, animations where characters handle some objects or run over level obstacles were all created specifically for those assets. The results were very natural-looking animations that interacted with the environment almost to perfection. One fact that absolutely amazed me: Apparently they used no version control system for the assets of Half Life 2. I hope I misunderstood that! In any case, there&rsquo;s one game I can&rsquo;t wait to play.</p>
<p>Another keynote was supposed to deal with the making of <a href="http://www.xbox.com/en-US/halo2/">Halo 2</a>, by Michel Bastien, one of the producers from Bungie. Unfortunately, it got watered down to being the making of the cinematic sequences in Halo 2. Frankly, there was nothing new in that. They go through the usual different phases: scripts, storyboards, blocking shots, adding animations, lighting, music, etc. That&rsquo;s all pretty standard stuff. We were treated to a few minutes of Halo 2 running on the Xbox, but I suspect you had to be a Halo fan to appreciate it (I only managed to play the first one for about 20 minutes for some reason).</p>
<p>Finally, Mario Rodriguez, a test engineer from Microsoft, gave an interesting talk on optimizing the build system. The talk was actually a lot broader than it sounds. It dealt with issues such as how to improve build times (through precompiled headers, structuring of code, or distributed systems&ndash;a lot of which I covered in <a href="/physical-structure-and-c-part-2-build-times/%20">an earlier article</a>), running build verification tests, and distributing game assets to different people and machines, which, if you have 4 or 5 GB to pass around, it can be quite time consuming. Interestingly, they moved away from using xcopy to using a custom program and they&rsquo;re getting much better results (not to mention also having a lot more control).</p>
<p>On that note, one of the things that I want to research in the next few days is the use of <a href="http://www.scons.org/">Scons</a> as a code build system. It&rsquo;s written in Python (which means you extend it in Python instead of strange Make or Jam rules), it&rsquo;s correct (using data CRC instead of timestamps to determine when a file has changed), and, most interestingly, uses a network cache. If that works as I think it does, it might mean that developers can cut down build times by a huge amount if they sync to code that was used by the automated build machine for a build because the object files are already available in the network. If that&rsquo;s the case, I will consider very strongly making it the build backend for our future projects at Sammy Studios.</p>
<p>Overall, the conference was a hit. The location was great, the quality of the talks was comparable to GDC, and it really managed to put MontrÃ©al on the map from a game development perspective. It was a bit out of the way for those of us living in the West Coast, but it&rsquo;s really nice to have an industry event like this that is not based in California for a change. I hope it continues growing in upcoming years and attracts even more developers from the US.</p>]]></content:encoded></item><item><title>Agile Game Development: Dealing with Chaos in the Real World</title><link>https://gamesfromwithin.com/agile-game-development-dealing-with-chaos-in-the-real-world/</link><pubDate>Sun, 07 Nov 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/agile-game-development-dealing-with-chaos-in-the-real-world/</guid><description>&lt;p&gt;No plan survives first contact with the enemy. In game development, detailed milestones, complex schedules, and careful planning often go out the window as soon as the project starts. Agile development provides a set of techniques to steer the project in the right direction and embrace change. Is your game not shaping up to be as fun as you thought? Has a game come out with features that you must match to remain competitive? Has your code degenerated into an unmanageable mess?&lt;/p&gt;</description><content:encoded><![CDATA[<p>No plan survives first contact with the enemy. In game development, detailed milestones, complex schedules, and careful planning often go out the window as soon as the project starts. Agile development provides a set of techniques to steer the project in the right direction and embrace change. Is your game not shaping up to be as fun as you thought? Has a game come out with features that you must match to remain competitive? Has your code degenerated into an unmanageable mess?</p>
<p>This talk discusses how agile development can help in all those scenarios. In particular we look at methodologies like XP and Scrum, and techniques such as test-driven development and pair programming.</p>
<p><a href="http://convexhull.com/articles/agile_development_html">Slides from the MontrÃ©al Game Summit 2004 talk</a> <a href="http://convexhull.com/articles/agile_development.pdf">(pdf format)</a></p>]]></content:encoded></item><item><title>Optimizing the Content Pipeline</title><link>https://gamesfromwithin.com/optimizing-the-content-pipeline/</link><pubDate>Tue, 03 Aug 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/optimizing-the-content-pipeline/</guid><description>&lt;p&gt;A successful game needs to provide top-notch content, and the best way to provide it is to optimize the content pipeline so that artists and designers can create, preview, add, and tweak new assets as easily and rapidly as possible.&lt;/p&gt;</description><content:encoded><![CDATA[<p>A successful game needs to provide top-notch content, and the best way to provide it is to optimize the content pipeline so that artists and designers can create, preview, add, and tweak new assets as easily and rapidly as possible.</p>
<p>This article was first published in the April 2004 issue of Game Developer Magazine. <a href="http://www.convexhull.com/articles/gdmag_content_pipeline.pdf">Printer-friendly format</a>.</p>
<h3 id="introduction">Introduction</h3>
<p>After years of being almost completely technology-driven, the driving force behind games is finally swinging towards the game content itself: level design, models, sounds, story, cinematics, etc. Major technological leaps are not making enough of a difference to set games apart from each other. Game content will also continue getting larger and more complex. The amount of content going into AAA games seems to double every few years. Since there&rsquo;s no hardware upgrade for the artists and designers themselves, content doesn&rsquo;t get created any faster.</p>
<p>A successful game needs to provide top-notch content, and the best way to provide it is to optimize the content pipeline so that artists and designers can create, preview, add, and tweak new assets as easily and rapidly as possible.</p>
<p>The content pipeline is the path that all the game assets follow, from conception until they can be loaded in the game. Game assets include everything that is not code: models, textures, materials, sounds, animations, cinematics, scripts, etc. During their trip through the pipeline, assets might be converted, optimized, chopped to bits, or combined. In the end, the asset is in a format that will be shipped with the final version of the game.</p>
<p>The first issue to consider when defining the content pipeline is its efficiency. With large teams of artists and designers constantly creating and tweaking game content, the content pipeline becomes a critical path. A slight inefficiency in the pipeline, such as taking one full minute from the time a change is made to the time it can be seen in the game, can easily cost a company thousands of wasted man-hours during the course of a project. Alternatively, if the content creators don&rsquo;t preview their work as frequently, the overall quality of the game will suffer.</p>
<p>The other main point to consider is robustness. The content pipeline is the jugular vein of a project: if it breaks it can quickly kill the whole project. You can&rsquo;t afford to have 30 idle people waiting for the pipeline to be fixed, or working around it and consequently losing half their work. Whatever happens, the pipeline must always work correctly.</p>
<h3 id="birds-eye-view-of-the-pipeline">Bird&rsquo;s-Eye View of the Pipeline</h3>
<p>What does an asset pipeline look like? It depends on the project. On one extreme, in some projects the pipeline is minimal and informal: assets are exported from their tool and loaded directly in the game. While that might be sufficient for small games, it usually doesn&rsquo;t hold up well in large projects: Where are the files stored so multiple people can work on them? How are assets for multiple platforms dealt with? How can the format of the resources be changed easily? How can any extra processing be applied to them?</p>
<p>On the other end of the spectrum, pipelines can be very deep and elaborate. Adding a new asset to the game requires going to the pipeline guru and asking him to add the new content, causing turnaround time to suffer significantly.</p>
<p>This article presents a general pipeline that many different game projects can adopt and modify to fit their needs. It is fairly lightweight and provides a quick turnaround time, yet it allows for any number of expensive steps to be performed on the assets along the way. This is the pipeline that we&rsquo;re using at Day 1 Studios for our current Xbox project, MechAssault 2. A previous incarnation of this pipeline was used in MechAssault 1. This pipeline might be a good starting place if you&rsquo;re just beginning a new project, or you can try to adapt some of the ideas that make sense for your current situation.</p>
<p><img alt="Content pipeline" loading="lazy" src="/optimizing-the-content-pipeline/images/pipeline_1.png">Figure 1. A partial view of the MechAssault 2 content pipeline (only models and textures shown).</p>
<p>Figure 1 shows the pipeline for some of the major types of assets in MechAssault 2. The following sections describe in detail each of the pipeline stages.</p>
<h3 id="source-assets">Source Assets</h3>
<p>Source assets are those created by artists and designers, usually through some specialized tool (both in-house tools and off-the-shelf ones). A source asset is one that can be put into the pipeline and will be converted into the final asset without any human intervention. The key idea is that source assets should contain all the information necessary to add them to the game correctly. A material should have all its specular parameters specified, and a model should have all the flags in the weapon barrels so the game knows from what point to shoot projectiles. This is what will allow us to automate the pipeline later on.</p>
<p>The way source assets are created can vary significantly. Sometimes they are created through a set of different, very specialized tools (one for modeling, one for texture creation, one for specifying game information, one to lay out a level, etc). Other times, one large tool (often done as a plug-in in the model-editor program) can be used to create all the assets and export full levels.</p>
<p>Since the source assets contain all the information needed for the final assets in the game, we should treat them very carefully and protect them from being lost or accidentally overwritten. Using a version control program provides a centralized location for all assets, prevents people from overwriting each other&rsquo;s work, and keeps a history of previous versions of each asset. Keep in mind that source asset files can sometimes be as large as several hundred megabytes each, so make sure your version control program is up to it and can also deal well with binary files.</p>
<p>Pre-rendered movies and sound are also game assets, but they&rsquo;re often treated differently because of their huge size. They might have a slightly different path through the content pipeline: Maybe movies won&rsquo;t be kept under version control, or maybe they will but only the most recent version will be kept in the database.</p>
<h3 id="intermediate-assets">Intermediate Assets</h3>
<p>Intermediate assets are exported directly from the source assets, usually with the tool they were created with. This requires a bit more plug-in work in the form of exporters if you&rsquo;re dealing with off-the-shelf tools.</p>
<p>The intermediate assets are in a format that is very easy to read, parse, and extend without breaking backwards compatibility. These assets should contain all the information we could possibly want in the future, even if some of it gets discarded before the end. Loading performance is of no consequence at this point; we&rsquo;ll leave that up to the final assets.</p>
<p>Plain text files are the perfect match for our requirements. In addition, XML is a particularly attractive option to structure those text files, especially if we need to represent information hierarchically. Doing so will also provide us with a whole range of tools and APIs to edit, parse, and transform files with minimal effort. If XML files are overkill for your needs, you can still use a simpler format like INI files or even write your own with minimal effort.</p>
<p>What is the purpose of having this intermediate asset format?</p>
<p>The main reason to have it is to provide a buffer between the source assets and the final ones. Final assets are optimized to load blazingly fast, but as a result, their format will often change and render previous versions unusable. In an ideal world, we would be able to efficiently re-export all source assets automatically into the new final asset format. Unfortunately, we don&rsquo;t live in an ideal world, and that is often impractical. Many off-the-self tools used for modeling and texture creation are not easily and efficiently driven from the command line to batch re-export thousands of models at the time. The intermediate format is not likely to change much during the course of a project, so we can always use it as a starting point to generate our final assets.</p>
<p><img alt="MA2" loading="lazy" src="/optimizing-the-content-pipeline/images/pipeline_2.jpg"> Another reason for having this intermediate format is to defer some of the complex and time-consuming operations like mesh optimizations or lightmap generation until a later time instead of doing them at export time. Also, we often end up creating a set of final assets for each platform we&rsquo;re dealing with. Without the intermediate format, artists would have to export a set of assets for each platform, ensure they&rsquo;re in synch with each other, and wait while each set of assets is converted and optimized every time an asset is changed.</p>
<p>Last but not least, having an intermediate format provides an excellent point for debugging and experimentation for the programmers. Intermediate assets should be in a very easily readable format, so anybody can view the contents of the asset, and even make small modifications for testing and debugging purposes without having to re-export them.</p>
<p>For MechAssault 2 we&rsquo;re exporting full models into one XML file: all the hierarchy information, meshes, vertex data, and materials are included into one large XML file. One of those files for a detailed model can easily be 3-4 MBytes.</p>
<p>As much as plain text is a really nice format to work with, exporting textures into text format would be overkill. In the case of textures, we export them into 32-bit tiff files with custom information in the comments field containing any information artists specified from within Photoshop: bit-depth, dithering, mip-mapping options, etc. The advantage of this format is that all the image is still there since it&rsquo;s exported at full 32-bits (although soon we&rsquo;ll have to worry about larger color channels!), and images can be examined with any program that displays tiff files. Again, mip-mapping, changing bit depths, and dithering are not cheap operations we want to do at load time, but we&rsquo;ll postpone all that until later.</p>
<p>It can be very tempting to modify an intermediate asset directly for many reasons: a &ldquo;quick&rdquo; change right before a milestone, the change we&rsquo;re trying to make is not exposed through the plug-in of the tool, etc. We did exactly that in MechAssault 1 and ended up regretting it. We were too pressed for time to provide good plug-ins for our custom material types, so artists would modify material parameters on the intermediate assets directly. Those parameters would get overwritten next time somebody else re-exported the model and would have to be re-entered by hand. If you absolutely must modify intermediate assets, then consider providing full re-importing capabilities back into your source assets; however, this is usually not a trivial task. For MechAssault 2 we&rsquo;re sticking to only making changes in the source and providing much better plug-in support, and things are running much more smoothly.</p>
<p>Even though this intermediate format is very flexible, chances are there will come a time during a project when it will be necessary to break backwards compatibility. Don&rsquo;t fight it; get ready for it instead. Make sure you have versioning as part of the format, and that you can easily run a script through all exported intermediate assets and convert them to the new format. Since you hopefully chose an easily parsed format such as XML, the conversion process should be almost painless.</p>
<h3 id="final-assets">Final Assets</h3>
<p>The final assets have been highly optimized so they can be loaded and used as efficiently as possible in their target platform. The specific file format doesn&rsquo;t have to be particularly robust or withstand many format changes since the final assets will be regenerated many times a day. The number one goal here is speed. Ideally, this resource should be a direct memory image of what it&rsquo;ll be in when it&rsquo;s loaded in the game, so that it can be loaded straight without any parsing. The standard warnings about optimizations also apply here: don&rsquo;t blindly optimize everything, and spend your time in those assets where you&rsquo;ll get the most benefit.</p>
<p>If you&rsquo;re doing multiplatform development, you&rsquo;ll probably want to have one set of final assets for every platform. That way Xbox textures can be in their own format, and PS2 textures can be packed and formatted differently. At Day 1 Studios, even though we were only developing for the Xbox, we have two sets of resources: one for the Xbox, used in the game, and one for the PC, used in our PC-based tools.</p>
<p>The type of operations done at this stage range from quick ones such as simple format changes, to somewhat expensive ones such as mip-map generation, dithering, or compression, to really time-consuming ones such as lightmap generation and mesh optimizations. At this point we don&rsquo;t care too much about how long it takes to perform an operation, we just care about the final result and how optimized the final asset is. As a result of this step some assets could be split into different assets (for example, our model XML file is split into several smaller files containing vertex and index data), and sometimes multiple assets get combined into one larger asset (packing a set of textures into one larger texture).</p>
<p>At Day 1 Studios, this step is performed by a command-line conversion tool, which takes a set of intermediate assets and produces the final assets. The actual conversion happens through a set of conversion plug-ins implemented as DLLs, each of which takes care of converting a particular type of resource (identified by filename extension or a header on the file itself). Any resources not handled by the conversion plug-ins are just copied straight through without any modifications.</p>
<p>Be warned that doing a full resource conversion on all the assets of the game can be a very time-consuming operation. There can easily be hundreds of thousands of files, and each of them needs to be loaded, parsed, converted, and saved in the new format. This process can take up to several hours even with a fast CPU and a very fast hard drive. Minimizing this time will help with the overall turnaround time, so you might want to profile the conversion program to find any obvious bottlenecks. Other solutions include doing incremental conversions (only convert files that have changed since the last build), and doing distributed builds (have a farm of machines where each one takes care of converting a subset of the resources).</p>
<p>During this step we should also generate errors and warning messages as necessary. Sometimes an asset won&rsquo;t meet the requirements to be converted successfully (for example, a texture might be marked as needing mip-maps but it has dimensions that are not a power of two). It&rsquo;s much better to prevent invalid assets from making it this far down the pipeline by preventing them from being generated in the first place, but we should still be ready for them here. By keeping a log of all the failed conversions and all the warning messages, the art and design leads can quickly identify what the problems are and correct them for the next build.</p>
<p>If you have specific dependencies between resources that need to be enforced (for example, packing all the textures for a particular model together and the textures need to be converted before they&rsquo;re packed), you might want to use an existing dependency-management tool such as make or jam.</p>
<h3 id="catalog-files">Catalog Files</h3>
<p>The final step of the pipeline consists in packing all the loose final asset files into larger catalog files. A catalog file is nothing more than a large file containing other files inside, possibly along with their names and hierarchy information.</p>
<p>The advantage of using catalog files are pretty obvious: reduced number of open/close file operations, enforced physical proximity between files, easier and more efficient distribution of assets, faster directory parsing, etc. Surprisingly, not all modern games provide catalog files with their assets (you can usually tell who the guilty parties are by the outrageously long load or install times!).</p>
<p>Using a standard catalog file format (such as .zip, .cab, or even .wad) is very convenient because there are already-made tools to create, load, and view them. On the other hand, you might not have as much control over them as you want (for example, to enforce a specific file alignment or ordering for optimal seeking performance on a DVD).</p>
<p>In this step, the final assets for each platform are packaged into separate files. You might want to have separate catalog files for each level, or have sound and music on a separate catalog file from the rest of the assets. Those strategies will depend on how you need to load resources in your game. Once these catalog files are created, they can be copied onto the network and everybody can copy them locally to their machines or work with them directly from the network if there&rsquo;s enough bandwidth. The game and the tools should be able to read these files directly and load any of the resources inside transparently.</p>
<h3 id="the-fast-path">The Fast Path</h3>
<p><img alt="MA2" loading="lazy" src="/optimizing-the-content-pipeline/images/pipeline_3.jpg"> Unfortunately, the process we&rsquo;ve described so far isn&rsquo;t exactly speedy. To make a change and see it in the game, we need to go through the following steps: modify a source asset, export the intermediate one, check it in version control, kick off a resource conversion, and wait for a few hours until new catalog files are ready. That doesn&rsquo;t meet our earlier requirement of a fast turnaround time.</p>
<p>The solution is to provide a fast path into the tools and the game that bypasses all the time-consuming steps. In our case, we made it so both the tools and the game could load intermediate assets as well as the final assets (see Figure 1 again). All an artist has to do to see how their updated texture looks in the game is to export the intermediate asset, copy it on the directory where the game or tool expects to find it, and run the game. You can even provide a macro or a button that does all those steps at once, including launching the game to the correct level. The artists just make a change, push a button, and see their new assets in the game. It can&rsquo;t get much easier than that.</p>
<p>How exactly is the local file loaded instead of the one residing in the catalog? That&rsquo;s part of the magic of the file manager. As far as the tools and the game are concerned, they&rsquo;re just opening a file like any other. However, our file manager gives local files priority over catalog files so they override any similar entries in a catalog file. Whenever the game attempts to open that file, the file manager redirects it to the local file. Otherwise it loads it from the catalog as usual.</p>
<p>Since we designed the intermediate format so it was easy to parse and modify, but not fast to load, isn&rsquo;t that going to slow loading levels down to a crawl? It would if all the resources in the level were in the intermediate format. The idea is that only the assets that artists and designers are working with at the moment are going to be found locally in the intermediate format, so load times are only going to increase by a very small amount.</p>
<p>This approach also requires that the game and all the tools have code in them to load and parse assets in their intermediate formats. That is not a trivial amount of code, but chances are you&rsquo;ve already written it to make it part of your conversion tool. However, you might want to strip this code out of the final shipped game, so separate it cleanly and surround it with conditional compilation statements so it&rsquo;s easy to remove.</p>
<p>There is one important lesson we learned from using this fast load path: Make sure that your fast load path and your normal path (following the rest of the pipeline) both produce the same results; otherwise you&rsquo;ll have some very disconcerted artists who are not sure why their assets look different after they check them in. In our case, we were using one library for texture conversion in the slow path and a different one in the fast path. The results were often similar, but sometimes different enough to raise a few questions. Whenever possible, use the same code in both paths.</p>
<h3 id="putting-it-all-together">Putting It All Together</h3>
<p>Now that the whole pipeline is in place, we can finally start thinking about automating the process. It should be relatively straightforward to create a script to get the latest source or intermediate assets from source control, run the conversion process on all of them, and package them on the catalog files. Perl and Python are some good glue languages for that type of tasks. The most difficult aspect of the script is making it robust enough to deal with errors (network going down, version control server being down, etc), so take good care of that from the beginning. With such a script in place, we can run the resource build automatically once or twice a day, or on demand when new resources are needed.</p>
<p>The more we automate the content pipeline, the more important feedback becomes. People are not going to be watching every step of the pipeline, so we need to collect all the important information and deliver it to the people who care about it. In addition to gathering all errors and warnings, we might also want to collect other information, such as memory footprints, texture usage, or even some rough performance statistics. All that is best done as a final step to the resource build, running each of the levels in the game with the latest resource and executables. As a side benefit, it also serves as a very rough smoke test of the build.</p>
<p>Robustness was one of the goals of the pipeline from the very beginning. Part of it involves making sure that the conversion and packaging tools work flawlessly and report any errors correctly. The other part is making sure the game and the tools are never left in an unusable state because of bad resources. A good philosophy to maintain is that bad data should never break the game or tools; an artist or designer should never be able to crash the game. It might sound a bit radical, but it&rsquo;s worth aiming for that goal. Any engineering time spent towards this will be paid back many times over as soon as assets start being added to the game at full speed. When loading a level, take the time to report any loading or initialization errors, disable the entities that had problems, and move on. In addition to that, it&rsquo;s helpful to put some sort of ugly debugging model (a big pink lollipop in our case) in place of any entity that failed initialization.</p>
<h3 id="further-work-on-the-pipeline">Further Work on the Pipeline</h3>
<p>Turnaround time is very good already, but we&rsquo;d like to make it even shorter. We&rsquo;d like the game to detect that some assets have changed and load them on the fly. This can be particularly beneficial for games without discrete levels where reaching specific locations is a time-consuming task.</p>
<p>A full resource build for MechAssault 2 can take up to an hour and a half. We&rsquo;d like to further investigate the possibility of doing distributed builds. There are open-source, general frameworks for doing distributed operations that could be easily added to the process. We might also want to look into integration with the build systems such as Ant for added robustness.</p>
<p>Games are very different from each other and teams are organized differently, so content pipelines will vary significantly from project to project. It is important to identify the assets for a given game, what kind of operations will be done to them, who will be working on them, and at what stage of the development they will occur. Use whatever pipeline organization works best for your particular needs and automate as much of it as possible. The artists and designers in your team will thank you for it, and you&rsquo;ll end up with a much better game in the end.</p>]]></content:encoded></item><item><title>An Afternoon with Subversion</title><link>https://gamesfromwithin.com/an-afternoon-with-subversion/</link><pubDate>Tue, 13 Jul 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/an-afternoon-with-subversion/</guid><description>&lt;p&gt;This morning I woke up with an extremely sore throat. I could hardly talk at all and swallowing was quite painful. It looks like the cold bug that was going around finally got to me. I called in sick, stocked up on lots of fluids and cough drops, and cuddled by the side of my computer waiting for my body to fight off the cold. Since I wasn&amp;rsquo;t in the mood for a game or anything particularly creative, I decided to give &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; a whirl.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This morning I woke up with an extremely sore throat. I could hardly talk at all and swallowing was quite painful. It looks like the cold bug that was going around finally got to me. I called in sick, stocked up on lots of fluids and cough drops, and cuddled by the side of my computer waiting for my body to fight off the cold. Since I wasn&rsquo;t in the mood for a game or anything particularly creative, I decided to give <a href="http://subversion.tigris.org/">Subversion</a> a whirl.</p>
<p>Checking out Subversion had been on my list of things to do ever since it showed up on my radar, about a year ago. I also needed to decide on a version control system to use at home, so this was a perfect chance to finally try out Subversion. I could go the familiar route with <a href="http://perforce.com/">Perforce</a>, but, even though Perforce is a great product, the more I use it the more I run up against its limitations. Besides, I needed more than two clients for my home network, and I&rsquo;m not about to spend $750 per user.</p>
<p>Originally I had been planning on writing a grandiose article comparing all the major source control systems, highlighting their strengths, and making some recommendations on how they applied to game development. Fortunately, I quickly realized what a hugely ambitious project that was, and besides, <a href="http://better-scm.berlios.de/comparison/comparison.html">other people had already done most of the legwork</a> (<a href="http://www.dwheeler.com/essays/scm.html">and here</a>) for me. Not being one to waste my time with duplicated effort, I decided to scale back the scope of the project to just having a look at Subversion and comparing it to my experience with Perforce. Besides, my throat is killing me and I&rsquo;m low in energy, so I&rsquo;m taking it easy.</p>
<p>I went ahead and downloaded the latest version (1.0.5). I&rsquo;m using different flavors of Linux in my home network: <a href="http://www.debian.org/releases/stable/">Debian Woody</a> for the server, and <a href="http://www.mandrakelinux.com/en-us/">Mandrake 9.2</a> on the rest of the computers (3 others). Subversion runs on a variety of platforms: Linux, FreeBSD, Solaris, MacOS X, and even Windows. Not only that, but it has binaries for every Linux flavor out there, including my outdated Debian Woody. It certainly gets the compatibility checkmark.</p>
<p>I first tried to install Subversion by getting the tarball and compiling the source. It turns out that was a bit more complicated than I expected due to the dependencies on other libraries. Compiling the GUI <a href="http://rapidsvn.tigris.org/">RapidSVN</a> was even more problematic, requiring a particular directory structure with the original Subversion source code. Still, I eventually got both of them up and running. For the second computer, I just installed it with <a href="http://subversion.tigris.org/project_packages.html">RPMs</a> and I was done in a minute. Lesson learned.</p>
<p>I had the option to make the server run over Apache or as a standalone daemon. Since I didn&rsquo;t have Apache installed and I didn&rsquo;t want to mess with that, I went ahead with the standalone daemon and it worked like a charm &ldquo;out of the box.&rdquo; I just ran it with svnserve -d -n /var/lib/subversion/main and we were off.</p>
<p>One really big plus for Subversion is its documentation. Normally, you wouldn&rsquo;t think that open-source software would have great documentation, especially for software that claims not to be even beta yet. But in this case, Subversion exceeds all expectations, with a very clearly-written, <a href="http://svnbook.red-bean.com/">full online book</a>. It&rsquo;s actually even better than Perforce&rsquo;s documentation, and that&rsquo;s saying a lot.</p>
<p>So I went ahead and ran through the book&rsquo;s examples, familiarized myself with the workflow in Subversion (copy-modify-merge, similar to CVS, but quite different to Perforce or&ndash;gasp&ndash;Visual SourceSafe), and played around with branches and merging for a few hours.</p>
<p><img alt="subversion" loading="lazy" src="/an-afternoon-with-subversion/images/subversion_logo_hor-468x64.png"></p>
<h3 id="the-good-stuff">The Good Stuff</h3>
<p>A lot of the good stuff is apparent from a feature checklist: atomic operations, concept of changesets (changelists in Perforce parlance), good support of binary files, good command-line support, etc, etc. Then we get into things that don&rsquo;t always make it to the marketing checklist level, but are crucial in everyday work, as I learned the hard way over the years.</p>
<p>File renaming and moving are supported very well in Subversion. They&rsquo;re considered just another operation and are submitted along with any other changes. That&rsquo;s a really important feature for me because I like to do a lot of refactoring, and, as part of that, I end up renaming and moving files around a fair amount.</p>
<p>Creating new branches and working with them is a snap in Subversion. If you&rsquo;ve gone through the convoluted process of setting up a branch in Perforce, you&rsquo;ll know what I mean. In Subversion all you do is svn copy src dest and you&rsquo;re done. You have a branch of your files and it was a blazingly fast operation. Unfortunately branches are going to be the downfall of Subversion as it stands, but let&rsquo;s not get ahead of ourselves. We&rsquo;ll deal with the negatives in a moment.</p>
<p>Revisions are much more intuitive than in Perforce. Here we just have one global revision number, not one per file as well as a global one. For me, that makes a lot more sense. It also makes it very easy to roll back changes or recover deleted files.</p>
<p>I wasn&rsquo;t sure whether to include the GUI under the good stuff or the bad stuff. It&rsquo;s good because there is one available. Actually, there are <a href="http://subversion.tigris.org/project_links.html">many available</a>, and choice is always good. But it&rsquo;s not so good because they&rsquo;re clearly a work in progress and are not really at the level of the Perforce GUI. Still, they&rsquo;re functional. Also, they had the nice effect of encouraging me to use the command line and now I like it so much better that I doubt I&rsquo;ll go back to the GUI.</p>
<h3 id="the-bad-stuff">The Bad Stuff</h3>
<p>So far, everything looks really good. So, what&rsquo;s not to like? Subversion, like CVS, likes to use what I affectionately call &ldquo;file droppings&rdquo; to mark its territory. Instead of storing metadata somewhere else, Subversion adds .svn directories to every directory that you use as a workspace. Under Linux they aren&rsquo;t a big deal since you can&rsquo;t see them most of the time, but I just don&rsquo;t like the concept very much. I really like to keep my data separate from any computer-generated data.</p>
<p>I&rsquo;m still a bit uncomfortable with the whole copy-modify-merge workflow. Somehow, I always feel that I&rsquo;m going to forget to commit files or forget to add them to source control because I don&rsquo;t have to think about checking them out in the first place. It&rsquo;s completely a matter of getting used to it though, and I suspect I will like it better in the long run.</p>
<p>As I mentioned earlier, the RapidSVN GUI (which is the only one I tried) still has a long way to go. Right now it can only be described as having barebones functionality. Trying to do something as simple as diff&rsquo;ing two versions in the file history dialog is not supported, and it wouldn&rsquo;t display the history of a file after it was renamed. Oh well. Good thing the command-line is so good.</p>
<p>As of this version (1.0.5), one of the features Subversion is lacking is the ability to lock a file and prevent other people from modifying it. This is extremely important in the case of binary files (think of art assets, project schedules, or even Microsoft Word documents). The last thing you want to do is spend a while editing a binary file, commit it, and then find out that someone else made a change to it already. Good luck with that merge. Fortunately, that&rsquo;s one of the features high in the roadmap, and it&rsquo;s supposed to be coming around version 1.2.</p>
<p>The real ugly side of Subversion appears when you start using branches. One of the first things that caught my eye was that Subversion has no automatic conflict resolution of any kind. If you try to merge two files that have both been modified in different parts, Subversion will not attempt to merge them automatically for you. Instead, it generates three files and leaves it up to you to do the dirty work. That&rsquo;s quite a blow to productivity! When working with Perforce and making heavy use of branches, I rely on Perforce to resolve most of the conflicts in my files and I only have to deal with the ones that resulted in a real conflict. Fortunately, they&rsquo;re aware of that shortcoming and are planning on addressing it&hellip; sometime. Until then, I wouldn&rsquo;t really be able to recommend Subversion for production use. But wait, it gets worse&hellip; much worse.</p>
<p>Here&rsquo;s the real killer blow for me: Subversion doesn&rsquo;t keep track of what merges have been applied to a file. That&rsquo;s up to you to keep track of somehow. That means that for every file (or set of files), you have to know up to what revision they&rsquo;ve been integrated, and only pull in the changes from that revision on. Since it&rsquo;s hard to believe that a version control system could be lacking that functionality (I suppose I&rsquo;ve been spoiled by Perforce), here&rsquo;s an excerpt from the book itself:</p>
<p>Ideally, your version control system should prevent the double-application of changes to a branch. It should automatically remember which changes a branch has already received, and be able to list them for you. It should use this information to help automate merges as much as possible.</p>
<p>Unfortunately, Subversion is not such a system. Like CVS, Subversion 1.0 does not yet record any information about merge operations. When you commit local modifications, the repository has no idea whether those changes came from running <strong>svn merge</strong>, or from just hand-editing the files.</p>
<p>That really kills Subversion dead in its tracks for anybody making heavy use of branches (which is very tempting considering how easy it is to do in Subversion). Whenever they fix that, Subversion will be a real candidate though.</p>
<p>I also decided to try one of my current litmus tests for good handling of branching and merging: start with a file A in the main trunk, create a branch from it, modify the file both in the branch and in the main trunk in a way that no conflicts occur, then rename it to A_1 in the branch and attempt to merge back into main. Maybe I&rsquo;m dreaming, but I&rsquo;d like a good version control program to realize that file A has been modified and renamed, and apply both those changes to file A in main. Subversion falls short yet again by ignoring all changes done to file A in main and simply bringing over the changes from A_1. I didn&rsquo;t even get a warning of any kind. Not exactly refactoring friendly. But then again, Perforce fails this test as well, but at least it prints a warning to let you deal with the merge before giving up.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Does it mean that Subversion is useless at it stands? No, not at all. Actually, I&rsquo;ve decided it&rsquo;s the source control system I&rsquo;m going to use in my home network. I never use branches at home, so Subversion&rsquo;s limitations are not going to affect me. So let&rsquo;s continue waiting and let&rsquo;s keep an eye out for future Subversion improvements. The day automated conflict solving and improved merge are implemented, Perforce and other source control systems should start trembling in fear.</p>
<p><strong>Edit</strong>: Jonathan Blow brought up a very good point about another advantage of Subversion over Perforce or SourceSafe:</p>
<p>He writes: &ldquo;<em>Also, one awesome thing about subversion that didn&rsquo;t come up in your article is that it only needs the network for update and commit operations. The rest of your workflow is not affected at all&ndash;so if you want to add, delete, or whatever to files, you just do it, even if your network connection sucks, the cable is unplugged or you&rsquo;re on your laptop and don&rsquo;t have wifi right now. That has been great and it&rsquo;d be very difficult for me to go back to anything else.</em>&rdquo;</p>
<p>Personally, most of the time, when I&rsquo;m using Perforce at work, I don&rsquo;t really care whether my network connection is on or not. But I&rsquo;ve really wished for that feature every time I would do some work from home. It&rsquo;s <a href="http://www.perforce.com/perforce/technotes/note002.html">possible to work disconnected from Perforce</a>, but not exactly trivial. I suppose that&rsquo;s something inherent about the lock-modify-unlock workflow approach and it can&rsquo;t be helped.</p>
<p>Another good point that several people brought up is that branching in Perforce is not more complicated from Subversion. Sam Stafford, from Perforce, writes: &ldquo;<em>I just read through your Subversion writeup on Games from Within, and was curious about one particular point (I haven&rsquo;t used Subversion at all yet): How does &ldquo;svn copy src dest&rdquo; differ from &ldquo;p4 integ src dest&rdquo;?</em>&rdquo;.</p>
<p>I&rsquo;m partly to blame for that one. Usually, when I branch with Perforce, I use branchspecs, not filespecs, which require creating a new branchspec, adding the new tree in the client view, doing the initial integration, and checking-in the files. Not exactly trivial, especially not from the GUI. In the future I&rsquo;ll try filespec branching for less complicated branches.</p>]]></content:encoded></item><item><title>Simple Is Beautiful</title><link>https://gamesfromwithin.com/simple-is-beautiful/</link><pubDate>Thu, 17 Jun 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/simple-is-beautiful/</guid><description>&lt;p&gt;If you&amp;rsquo;ve read some of &lt;a href="https://gamesfromwithin.com/maintenance-the-hidden-cost-of-software/%20"&gt;my other articles&lt;/a&gt;, you know that I believe that the best code is no code at all. But what if you actually have to write some code? What then? This article deals with that question and shows the importance of simplicity.&lt;/p&gt;</description><content:encoded><![CDATA[<p>If you&rsquo;ve read some of <a href="/maintenance-the-hidden-cost-of-software/%20">my other articles</a>, you know that I believe that the best code is no code at all. But what if you actually have to write some code? What then? This article deals with that question and shows the importance of simplicity.</p>
<p>As I write this there are still a few cardboard boxes strewn across our home as we finish unpacking everything. My wife and I just finished a surprisingly painless cross-country move to <a href="http://www.sannet.gov/">sunny San Diego</a>. The town house we&rsquo;re moving into is definitely larger than our previous condo, but it wasn&rsquo;t until we had to pack everything, move it, and then unpack it that we realized how much stuff we had accumulated over the years. Yes, there was a reason for everything we had, but it was still a lot of stuff. Then we came to the realization that we prefer a more open, simpler environment with fewer pieces of furniture, fewer paintings covering the walls, and less clutter in general.</p>
<p>That is an interesting insight because it applies to many different things, including programming: There is a cost associated with having a complex, cluttered environment, whether it be the furniture in your house, your class hierarchy, or your build process. In particular it will create resistance to change, which can be in the form of a cross-country move, or a simple class refactoring.</p>
<h3 id="goals">Goals</h3>
<p>The ultimate reason to write code is to have the computer carry out a sequence of instructions. In our case, that sequence of instructions is a game or a tool to help create the game. It is tempting to think of the computer as the â€œaudienceâ€ for our program, but it is not a very good audience. It is way too forgiving, and as long as things compile, it&rsquo;ll be happy with anything you throw at it. We can do better than that.</p>
<p>We can still write code that is correct, but with people in mind as the primary audience. The usual reason for choosing people as your audience is that software development is a team effort, and it&rsquo;s very important that other people be able to understand and modify your code. True, but there&rsquo;s more to it than that. Even if you were the only person writing code, you should still write for people, not computers. Assuming it&rsquo;s more than a toy project, you will have to refactor your code as you learn new things about it. Probably not once, not twice, but many times over the course of the project&rsquo;s lifetime. You will have to keep it up to date, fix bugs, add new features, etc. I am convinced that refactoring (or lack thereof) is one of the major influences on code quality, and, as a consequence, product quality, so anything to help with that is extremely important in my book.</p>
<p>Lately, I&rsquo;ve been taking it a step further and thinking of my audience not just other programmers, but other people who are not programmers. If you manage to write some code that a non-programmer can more or less understand, then you know you&rsquo;re there. The code should be simple and self-explanatory enough that should be a breeze to refactor in the future.</p>
<p><img alt="links (c) freeimages.co.uk" loading="lazy" src="/simple-is-beautiful/images/abstractlinks_1.jpg"></p>
<p>But wait, as if ease of refactoring wasn&rsquo;t enough, there are more reasons for writing really simple code. <a href="http://www.cs.utexas.edu/users/EWD/">Edsger W. Dijkstra</a> in his lecture <a href="http://www.cs.utexas.edu/users/EWD/ewd03xx/EWD340.PDF">â€œThe Humble Programmerâ€</a> advocated the avoidance of clever tricks and urged programmers to be fully aware of the limitations of the human mind when writing programs.</p>
<p>&ldquo;The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.&rdquo;</p>
<p>Dijkstra&rsquo;s reason for keeping clever tricks away is not so much for ease of refactoring, but the quality of the program itself. Programmers are all too eager to tackle something too ambitious at once, without breaking it down into smaller, more understandable sub-problems, and, as a result, create a disastrous program that crashes often and doesn&rsquo;t even implement all the required features.</p>
<p>Today, this sounds like a surprisingly modern attitude. After all, it&rsquo;s right up the alley of agile development. But amazingly, this lecture took place in 1972. Talk about timeless advice (OK, OK, in the really short scale of computer history, not in the grand scheme of things).</p>
<p><a href="http://cm.bell-labs.com/cm/cs/who/bwk/">Brian Kernighan</a> had also something to contribute to the idea of writing simple code, but coming from a very different angle:</p>
<p>&ldquo;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&rdquo;</p>
<p>While I totally agree with the sentiment, I feel it is not as important as the other two reasons for aiming towards code simplicity. Frankly, if you use test-driven development and take steps of the correct size, you should hardly ever find yourself knee-deep in the debugger trying to make sense of your program. However, a decade or two ago that made a lot more sense, especially given that debuggers were less sophisticated then as well. Still, anything that encourages programmers to keep things simple is a step in the right direction. So if that convinces some people, so be it.</p>
<h3 id="attaining-simplicity">Attaining Simplicity</h3>
<p>Great. Simple is good. How do we write â€œsimpleâ€ code? That&rsquo;s not something they teach in school and it&rsquo;s not something that is pushed for in the workplace, so it&rsquo;s probably not something you&rsquo;re used to thinking about. The rest of the article will be a series of suggestions and techniques on how to make code as simple as possible. Specific examples are given in C++, but the general techniques should apply to most object-oriented languages.</p>
<p><strong>Avoid unnecessary language tricks.</strong></p>
<p>Listen to Dijkstra and go easy on â€œclever code.â€ If you feel the need to write a comment to explain to other people what that cute line of code you just wrote does, you should very strongly consider re-writing it so a comment is not necessary. I&rsquo;m not saying to avoid taking advantage of language features, just the ones that can be done in another, simpler way. For example, don&rsquo;t use a template when a non-templated implementation is perfectly fine. Don&rsquo;t rely on a clever arrangement of variables so they&rsquo;re initialized in the correct order even though the language standard says it should work.</p>
<p><strong>Avoid or postpone performance optimizations that obscure the meaning of the code for as long as possible.</strong></p>
<p>You&rsquo;re all familiar with the Donald Knuth quote: â€œPremature optimization is the root of all evil.â€ Programs have a way of twisting into evil, misshapen fiends when they&rsquo;re optimized, and they usually become much harder to refactor afterwards. Specifically in this case, I suggest avoiding (or delaying at least) optimizations that affect how simple or readable a section of code is. There are many ways to skin a cat, and there are also many ways to optimize a program. I find that there is often a way to optimize things that doesn&rsquo;t cause a major loss in code simplicity. But if that&rsquo;s not possible, at least defer that optimization as long as possible. Maybe you won&rsquo;t need it, and maybe the code will change before then and you&rsquo;ll save yourself a lot of rework.</p>
<p><strong>Functions should do one thing only.</strong></p>
<p>The secret to a good function is that it should do one thing and one thing only. Functions that follow that rule are usually quite small (at most 10-15 lines in C++) and their whole meaning can be easily understood at a glance. Because the function has only one purpose, refactoring becomes very easy: No need to worry about how changes in that function will affect other parts of the function, no pesky local variables reused in many parts of the function, etc.</p>
<p>Maybe this is a bit extreme, but ideally, functions should be so simple that I should be able to look at a function, delete it and re-write it from scratch without any difficulty.</p>
<p>I follow two guidelines to keep functions as simple as possible:</p>
<ul>
<li>If a function goes over 10 to 15 lines of code, I look at it really hard and try to split it. Chances are it&rsquo;s doing more than one thing.</li>
<li>If I ever feel the need to write an explanatory comment about what a few lines of code do, I move those lines into a function of their own and give it a name that explains what it does (usually the same as the what the comment would have been). By following this rule, the only comments in my code are the ones that explain *why* the code does things the way it does, and deal with higher-level such as the purpose of a class or a library.</li>
</ul>
<p><strong>Classes should do one thing only.</strong></p>
<p>This should come as no big surprise. If we want our functions to be small, simple, and just one thing, we also want the same qualities from our classes. When classes are left unchecked, they can easily grow into unmanageable blobs of many thousands of lines. The largest class I had the misfortune of encountering had a staggering 10,000 lines in it, and the problem was compounded by inheriting from another class with over 8,000 lines! As you can imagine, having to do any work near that class was quite a punishment.</p>
<p><img alt="links (c) freeimages.co.uk" loading="lazy" src="/simple-is-beautiful/images/abstractlinks_2.jpg"></p>
<p>Personally, I feel that C++ classes should ideally be no more than about 200-300 lines (remember, with virtually no other comments). Anything that goes beyond that, and I start thinking hard about what exactly the class does. If a class reaches 1000 lines, it&rsquo;s time to get the axe out.</p>
<p>One technique I&rsquo;ve been following to keep classes as simple as possible is to use the <a href="http://www.cuj.com/documents/s=8042/cuj0002meyers/">controversial suggestion</a> from <a href="http://www.aristeia.com/">Scott Meyers</a> on how to decide on the scope of a function. The quick summary is that functions should be pushed out of a class as much as possible: if a function can be implemented as a non-member function, then do it; if it can be a class static, make it so; otherwise, leave it as a member function.</p>
<p>One immediate consequence of following that advice is that a class is stripped of anything that is not essential. Helper functions (both public and private to the class) are pushed out, and the meaning of the class is made more clear. The second consequence is that refactoring is a lot easier. By using non-member functions in anonymous namespaces whenever possible, we avoid the need to edit any header files at all, which results in faster compile and iteration times. Also, since those functions are completely independent of the class, they&rsquo;re trivial to move around, promote to higher levels, etc. while member functions require some massaging to move around.</p>
<p>I&rsquo;m suggesting that we keep functions small, but also that we keep classes small. We&rsquo;re not going to end up with any less code than we would have before, but we&rsquo;re going to end up with many more classes scattered all over our program. We have pushed the complexity from the function and class level up to the program organization and architecture level. The next article in this series will deal with how to manage this newfound complexity, but here&rsquo;s a preview: Use hierarchies.</p>
<p><strong>Timings, logging, and error handling</strong></p>
<p>Ideally, I&rsquo;d like my code to be really small, simple, and to the point so its meaning is always clear and obvious. Unfortunately, in the real world, that&rsquo;s is not always possible. We can start with a very clean 5-line function, but then we add timings around it to get an idea of its performance, and logging statements to know what is going on, and error handling code to deal with the unexpected, and before we know it, we have a monster function whose meaning is lost in a mass of details.</p>
<p>What can we do about it? We could argue that timings should be done with non-intrusive methods such as using profilers, but that&rsquo;s not always possible or desirable. We often want very specific timings that only affect a particular section of the code (load times), or we want to continuously monitor performance of certain sections while the game is running. For example, we probably want to get an idea of how much time we&rsquo;re spending each frame on each of the major tasks: entity updates, AI calculations, physics, animation, rendering, sound, etc. We need to wrap each of those areas in timing statements. The more detailed we want those timings to be, the more junk we&rsquo;ll have to add to the code. We can try making that as clean as possible by using macros that only require one line, but it&rsquo;s still junk that obscures the meaning.</p>
<p>Logging doesn&rsquo;t even have a non-intrusive counterpart unless you want to automatically add prologue and epilogue code to every function (which would generate way too many messages and would affect performance too much). So we&rsquo;re stuck writing messages by hand to the log system.</p>
<p>Error handling at least as has the possibility of using exceptions, which add a lot less clutter than returning and checking error codes. Unfortunately, we have to deal with several real-world issues which often make exception-handling impractical. The first one is performance. As much as I hate bringing this up, exception handling can easily have a significant performance impact even in modern hardware. This is something that will hopefully go away in the near future as PC hardware and consoles become more powerful. The second problem is compiler support. Even today, some console manufacturers are admitting that exception-handling support in their compilers is not usable and we shouldn&rsquo;t rely on it. So much for that idea. Finally, and probably most importantly, is complexity and programmer knowledge. If you have read <a href="http://www.amazon.com/exec/obidos/ASIN/0201615622/ref=nosim/gamesfromwith-20">Exceptional C++</a> you how complicated it can be to write exception-safe code, and not every C++ programmer out there today is going to feel comfortable using exceptions. All of this is a vicious circle, because until programmers demand robust and efficient exception handling, compiler and system creators aren&rsquo;t going to provide them, which means a lot of programmers are not going to be exposed to them, etc, etc.</p>
<p>So, what great solutions do I have to this problem? None, I&rsquo;m afraid. This is where I&rsquo;d like to hear from some of you. How do <strong>you</strong> deal with timing, logging, and error handling in a way to minimize the clutter and leave your code as clear as possible? Email me and I&rsquo;ll edit this article or make a new one with any great solutions I receive.</p>
<h3 id="striking-a-balance">Striking a balance</h3>
<p>In the end, even if we have the best goals in mind about simplicity, we will be forced to make compromises. Error handling is one case. Another case is often performance. Sometimes, having many scattered functions can add up to a noticeable performance hit in some inner loop of a performance-critical section. In that case simplicity needs to give way to practicality and do whatever is necessary. Just make really sure that having many functions is the cause of the performance problems before you make any changes.</p>
<p>It is also important not to confuse code simplicity with algorithmic simplicity. Writing simple code doesn&rsquo;t mean that you have to use a silly bubble sort to order a list. Always choose the most appropriate algorithm for the task at hand, just implement it with the simplest possible code. Implementing it in a very simple way will also make possible to easily change it down the line with a more efficient algorithm.</p>
<p>The next article will deal with how to manage all the complexity we&rsquo;ve pushed up into the program structure. Until then, keep your functions short, your classes clean, and remember The Humble Programmer:</p>
<p>&ldquo;&hellip;We shall do a much better programming job, provided that we approach the task with a full appreciation of its tremendous difficulty, provided that we stick to modest and elegant programming languages, provided that we respect the intrinsic limitations of the human mind and approach the task as Very Humble Programmers. &quot;</p>]]></content:encoded></item><item><title>Cowboy Coders and the Hero Programmer Culture</title><link>https://gamesfromwithin.com/cowboy-coders-and-the-hero-programmer-culture/</link><pubDate>Fri, 14 May 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/cowboy-coders-and-the-hero-programmer-culture/</guid><description>&lt;p&gt;Yeee-haaa! Get your compiler and debugger ready and saddle up, pardner. We got some codin&amp;rsquo; to do.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Yeee-haaa! Get your compiler and debugger ready and saddle up, pardner. We got some codin&rsquo; to do.</p>
<h3 id="cowboy-coders">Cowboy coders</h3>
<p>There&rsquo;s no denying it: The games industry is full of cowboy coders. Sure, other industries have their share as well, but something about game development seems to attract them like flies to honey. Maybe it&rsquo;s living dangerously under the pressure of milestones, maybe it&rsquo;s being able to surf the bleeding edge of technology, and maybe it&rsquo;s because it&rsquo;s the last refuge left for the rogue programmer. Whatever the reason, chances are you&rsquo;ve worked with a cowboy coder or you&rsquo;re one yourself (although that&rsquo;s more doubtful if you&rsquo;re reading this of your own will).</p>
<p><img alt="cowboy" loading="lazy" src="/cowboy-coders-and-the-hero-programmer-culture/images/cowboy_1.png"> No, a cowboy coder doesn&rsquo;t live in a ranch in Texas and wear a funny hat. A <a href="http://c2.com/cgi/wiki?CowboyCoder">cowboy coder</a> is a certain type of programmer who prefers to work in isolation, sets his own rules, and usually dives straight into a problem without much thinking or design (hence the â€œshooting from the hipâ€ expression).</p>
<p>But not everything about the typical cowboy coder is negative. He is usually very talented; he knows it, and he makes sure everybody around him knows it too. He usually has very little respect for everybody around him, and he&rsquo;ll try to work by himself, with his own rules and schedules. He can sometimes do great feats and can handle some of the most complicated code in this side of the Mississipi. Just don&rsquo;t expect anybody else to touch his code. Not only will he be horrified by the thought, but nobody else has enough â€œskillzâ€ to be able to understand his beautiful code.</p>
<p>To him, speed is life. Getting things working as quickly as possible is all it matters, so he&rsquo;ll be able to really quickly put enormous amount of code together that actually do something. Just don&rsquo;t expect much in the way of maintainability, reliability, tests, standard-compliance or any of those boring things. It&rsquo;s working, so what&rsquo;s the problem, right?</p>
<p>Does it sound familiar yet? Unfortunately, I suspect it does.</p>
<h3 id="hero-culture">Hero culture</h3>
<p>So, why is the games industry so packed with cowboy coders? The analogy of flies and honey makes it sound too nice. I was going to use worms and rotting carcasses, but then I would really show my bias. I really need to step back a second. Are cowboy coders born or developed? It&rsquo;s the old nature vs. nurture question. I&rsquo;m going to stick my neck out and say it&rsquo;s 90% nurture in this case. There might be a certain predisposition based on personality or character, but it&rsquo;s mostly what the person is used to, what is comfortable doing, and what everybody lets him get away with.</p>
<p>Unfortunately, a predominant company culture in the games industry is the â€œ<a href="http://c2.com/cgi/wiki?HeroCulture">hero culture</a>,â€ which seems to be the perfect breeding ground for those cowboys out there. A hero culture is one that values individual displays of effort above anything else. It&rsquo;s a very human thing to do. Think about it, who got the poem written about him? The hero who rescued the princess from the clutches of the evil dragon in a bloody fight in front of the whole kingdom, or the one who quietly and efficiently destroyed the dragon eggs years before, ensuring many years of peace in the kingdom? Go figure. It&rsquo;s the same thing with many companies in the games industry. Individuals who are willing to commit body and soul to a project (or at least stay long enough in the office to appear to be doing lots of work) are the ones who get rewarded and promoted.</p>
<p>While some might argue that such a culture provides a healthy dose of commitment, team building, and competition, it usually has very different effects. A hero culture fosters too much of a â€œcan doâ€ attitude. It&rsquo;s a great thing to stay positive and be willing to do things. However, taking the â€œcan doâ€ attitude to the extreme leads to overcommitment and either to spectacular failures or an incredible victory against all odds (that happens to crash as soon as you look away, but it works, right?). Look at the track record of canceled, over time and over budget games, and then at how many shipped games that need patches and you can decide for yourself if that&rsquo;s a prevalent attitude in the industry.</p>
<p>One of the other consequences of a hero culture is the lack of progress visibility. A programmer takes on an impossible task and disappears in his cubicle for a few weeks. He spends there nights and weekends (but no mornings or early afternoons) and when asked he reports that he&rsquo;s 90% done. Only the day before the milestone is due he admits he&rsquo;s having some problems getting that last bit done. Before you know it the task really needs another three weeks to be completed. I&rsquo;m sure the publisher is going to appreciate such short notice.</p>
<p><img alt="cowboy" loading="lazy" src="/cowboy-coders-and-the-hero-programmer-culture/images/cowboy_2.png"> Tasks will also be consistently estimated (or guessed is more like it) way shorter than they should be because nobody is learning from past mistakes and everybody continues to provide ridiculous estimates. All of this leads to unrealistic expectations from the company, which gets passed along as promises to the publisher. From this to a canceled project is a very small step.</p>
<p>An interesting social dynamic created by this culture is that since the hero culture values individual effort above all else, it ends up preventing the team from gelling and working together. Instead, it remains a group of individuals more or less working on the same project. Sometimes less than more. Let&rsquo;s not even go into burn out, what it does to individuals, and the cost of staff turnover.</p>
<p>If things are really this terrible, how did we ever get anything accomplished in this industry? Here&rsquo;s the rub: A culture like that probably worked fine ten years ago. Actually, it might have been the ideal culture for a company then. Very small teams and small budgets. Dealing with complexity and large teams wasn&rsquo;t as much of an issue as conquering the technology and packing stuff into tiny amounts of memory. Priorities were different.</p>
<h3 id="the-future-and-now">The future and now</h3>
<p>What about now? Is that an acceptable culture? Are cowboy coders the ideal game developer? My personal answer is a resounding no (like you haven&rsquo;t guessed that by now). I really think that priorities have shifted and now there&rsquo;s no room in the industry for cowboy coders or the hero culture.</p>
<p>A recent <a href="http://gdmag.com/"><em>Game Developer Magazine</em></a> article about <a href="http://www.everquest.com/"><em>Everquest</em></a> had a very telling message. <em>Everquest</em>, by its nature, has to be always up, and there&rsquo;s no room for screw ups and heroics. Here&rsquo;s an excerpt from the article:</p>
<p>[&hellip;] our experience has been that a solid professional eight hours a day delivers you far greater productivity than someone who works 14 hours a day every day.</p>
<p>That sounds like they&rsquo;re choosing productivity over flash and individual effort and heroics. If we think of <em>Everquest</em> as the way many game projects are going to go in the future, that sounds like the death knell for cowboy coders.</p>
<p><a href="http://www.stevemcconnell.com/">Steve McConnell</a>, one of my favorite writers, has a great chapter in <a href="http://www.amazon.com/exec/obidos/ASIN/0321193679/ref=nosim/gamesfromwith-20"><em>After the Gold Rush</em></a> (the second edition is titled Professional Software Development) about programmer personalities and heroics. Fortunately, <a href="http://gamasutra.com/">Gamasutra</a> has that <a href="http://www.gamasutra.com/features/19991222/mcconnell_pfv.htm">chapter online</a>. In particular, the closing thoughts are quite revealing:</p>
<p>As the current cohort of software workers grows older, the present hero-based approach to software development may naturally give way to an approach that relies more on working smart than on working hard. Software workers will become increasingly interested in the practices that allow them to complete their projects as promised and still be home in time for dinner.</p>
<p>It really sounds like it&rsquo;s time to start thinking of different approaches to game development. Fortunately, some companies are already dealing with this, and hopefully that influence will slowly propagate to the rest of the industry.</p>
<p>What if you have such a talented cowboy coder that he&rsquo;s single-handedly moving the company forward? Someone as talented as, say, <a href="http://www.webdog.org/plans/1/">John Carmack</a>. Is that still something to be avoided? If he really, truly is that talented and the difference between his productivity and everybody else&rsquo;s is a factor of 100, then you&rsquo;d probably do well to keep him on the payroll. Watch out for the proverbial bus that leaves you without your superstar though. On the other hand, don&rsquo;t ask me to provide funding for a company with an unproven â€œsuperstarâ€ like that. I&rsquo;d rather take a solid team any day of the week.</p>
<p>In the end, it&rsquo;s time for all the cowboy coders to realize that their time is over. Civilization is advancing even towards the game industry and team-based cultures are needed. The cowboy way of life is no longer advantageous. They should either adapt to a modern development approach, or head towards the new frontier of handheld games and ride into the sunset towards the wild territories.</p>]]></content:encoded></item><item><title>Book review: The Career Programmer: Guerilla Tactics for an Imperfect World</title><link>https://gamesfromwithin.com/book-review-the-career-programmer-guerilla-tactics-for-an-imperfect-world/</link><pubDate>Wed, 21 Apr 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/book-review-the-career-programmer-guerilla-tactics-for-an-imperfect-world/</guid><description>&lt;p&gt;Even though I read a lot of technical books, either I must have pretty good instincts or the publishing quality bar is quite high, because I never read one I thought was totally worthless. Until now that is.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Even though I read a lot of technical books, either I must have pretty good instincts or the publishing quality bar is quite high, because I never read one I thought was totally worthless. Until now that is.</p>
<p><a href="http://www.amazon.com/Career-Programmer-Guerilla-Tactics-Imperfect/dp/1590596242%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1590596242"><img loading="lazy" src="images/51XFHP45EJL._SL500_.jpg"></a></p>
<p>I&rsquo;m not even sure where to begin. As soon as I try to put my thoughts together, a whole rush of negative points immediately comes up and prevents me from even organizing them in some sort of coherent way. I suppose I&rsquo;ll start with the easy part and share the only two useful bits of content that I was able to glean from the book:</p>
<ul>
<li>Logic doesn&rsquo;t prevail in the corporate world.</li>
<li>Programmers need to understand managers and managers need to understand programmers.</li>
</ul>
<p>Both of those are very valid points, and understanding them will help anyone developing software for company. There, no need to buy the book anymore. I&rsquo;ve just saved you $29.99 + tax, a few hours of your life, and medication costs from elevated blood pressure.</p>
<p>OK, now that we&rsquo;ve gotten that out of the way, why was this book a complete waste of time? The first problem is one of style. The author is probably a very entertaining speaker. He might even be a passable column writer. He has a light-hearted style and is ready to make a joke at moment&rsquo;s notice. I like jokes as much as the next guy. I also like chocolate fudge, but I would throw up if I were forced to eat several pounds straight for dinner. That&rsquo;s how this book feels.</p>
<p>The problem with the jokes is more than just a style issue. All the funny remarks and irrelevant (and mostly incomprehensible) jokes about chihuahuas are just a cover-up for the total lack of content. Reading a chapter of the book is like eating cotton candy: You go through the motions, it takes a while, but in the end you haven&rsquo;t really eaten anything.</p>
<p>Then there&rsquo;s the attitude. I think that&rsquo;s probably what most got to me. The author has a &ldquo;cowboy&rdquo; attitude that permeates the whole book. You know the type I&rsquo;m talking about. Coding is the coolest thing in the world, and, left to his own devices, he&rsquo;d just spend all day and all night in his office hammering away at the keyboard. His ideal vision of programmers is that of &ldquo;professional athletes and rock stars.&rdquo; He also naturally assumes that everybody reading the book feels the same way.</p>
<p>His distinct dislike of everything academic is very telling about the general attitude. He couldn&rsquo;t possibly learn anything of value from those ivory-tower mad scientists. He goes as far as to be totally disrespectful and referring to people as &ldquo;terminally educated&rdquo; and implying they&rsquo;re worthless in the workplace.</p>
<p>With that attitude he forges ahead and starts spewing horrible advice. Not a word on how to improve a project, not a word on how to deliver a better product. It&rsquo;s all about saving his butt and enjoying his coding. Everything else is secondary. He doesn&rsquo;t go beyond that and assumes everything will remain the way things are. For example, he takes for granted that you&rsquo;re going to spend most of your time in the debugger tracking down bugs. Hello, how about minimizing those bugs and taking steps towards catching them in other ways? I wonder if he&rsquo;s ever heard of unit tests, test-driven programming, or agile methodologies. There&rsquo;s certainly not a mention of them anywhere. Too busy coding I suppose.</p>
<p>As if things weren&rsquo;t bad enough, the overall message of the book is to try and put up with evil Corporate America, deal with it and do your coding job, and if things go bad, quit. Nothing wrong with quitting, but that seems to be the motto of the book. Not surprisingly, the author&rsquo;s biography lists his claim to fame being a consultant for a bunch of companies without any particular accomplishments. Just a string of failed projects after failed projects. No wonder he&rsquo;s burned out and jaded. Is this the guy we want to be taking advice from?</p>
<p>Finally, the most of the advice he gives is either outdated, ridiculous, or just plain wrong. He pretty much advocates a waterfall approach to development, and &ldquo;getting your requirements etched in stone&rdquo;. I really couldn&rsquo;t believe it when I saw it. I thought it was a joke. Maybe that works for consultants getting paid by the hour trying to make a fat check and do their coding undisturbed, but it doesn&rsquo;t work for those of us trying to create a good product. Or maybe that&rsquo;s a technique that works in corporate America? I think not.</p>
<p>The only saving qualities of the book were that it was relatively short (just a bit over 200 pages), so the pain didn&rsquo;t last for too long, and the fact that I actually had fun writing this review. This was the first book I read by this <a href="http://apress.com/">publisher (a! APress)</a>, so I&rsquo;m going to be very cautious with any of their other books in the future. Stay far away from this book unless you&rsquo;re masochistic or your idea of an ideal workplace is something like <a href="http://www.dvdtalk.com/reviews/read.php?ID=10343">The Office</a>.</p>]]></content:encoded></item><item><title>Postmortems: Looking Back, Looking Ahead</title><link>https://gamesfromwithin.com/postmortems-looking-back-looking-ahead/</link><pubDate>Mon, 12 Apr 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/postmortems-looking-back-looking-ahead/</guid><description>&lt;p&gt;When starting a project, it is always a good idea to reflect very critically on your past projects. Think about what went right, and especially what could have been done better, and come up with a plan of attack for the new project. That&amp;rsquo;s the idea behind &lt;a href="http://www.amazon.com/exec/obidos/ASIN/1578202140/ref=nosim/gamesfromwith-20"&gt;project postmortems&lt;/a&gt;. To adapt the popular saying, companies that do not conduct some form of postmortem are doomed to repeat the same mistakes.&lt;/p&gt;</description><content:encoded><![CDATA[<p>When starting a project, it is always a good idea to reflect very critically on your past projects. Think about what went right, and especially what could have been done better, and come up with a plan of attack for the new project. That&rsquo;s the idea behind <a href="http://www.amazon.com/exec/obidos/ASIN/1578202140/ref=nosim/gamesfromwith-20">project postmortems</a>. To adapt the popular saying, companies that do not conduct some form of postmortem are doomed to repeat the same mistakes.</p>
<p>However, that might not be enough. Every project is different; if they weren&rsquo;t, we&rsquo;d be all set, projects would run very smoothly, and I wouldn&rsquo;t be writing this. Even if you&rsquo;re just creating a sequel of a franchise game, you&rsquo;re still going to come across many different issues and challenges you did not encounter before.</p>
<p>This article attempts to extract some common patterns by looking at recent game postmortems. A later article will deal with how to choose the right development methodology for a particular game project given what we find here. This is not by any means intended to be a comprehensive summary of postmortems; rather, I&rsquo;m just looking at the issues listed under &ldquo;What went wrong&rdquo; and trying to look for interesting patterns.</p>
<table>
	<thead>
			<tr>
					<th>For a more comprehensive study of earlier postmortems, check out the great summary by Simon Larsen on <a href="http://www.blackwood.dk/postmortem/postmortem/index.html">Gamasutra.com Postmortems</a> and his related thesis <a href="http://www.blackwood.dk/postmortem/PDF/PlayingTheGame-IE.pdf">Playing the Game: Managing Game Development</a>. I don&rsquo;t agree with everything he says, but it&rsquo;s a very interesting work anyway. Just the fact that people are finally starting to ask some pointed questions about the overall state of the industry and why so many game development efforts are total disasters is very encouraging.  To gather data for this article, I looked through my back issues of <a href="http://gdmag.com/">Game Developer Magazine</a> starting with April 2004 all the way back to October 2002 (which is where Larsen&rsquo;s study left off). I excluded postmortems that dealt with subsets of the project (like tools, animation systems, sound systems, etc). Specifically, I selected 13 different postmortems:  - &ldquo;Z-Axis&rsquo;s <em>Aggressive Inline</em>&rdquo; by Randy Condon (October 2002) - <a href="http://www.gamasutra.com/features/20021204/greig_01.htm">&ldquo;BioWare&rsquo;s <em>Neverwinter Nights</em>&rdquo;</a> by Scott Grieg, Ray Muzyka, James Ohlen, Trent Oster, and Greg Zeschuk (November 2002) - &ldquo;Monolith&rsquo;s <em>No One Lives Forever 2</em>&rdquo; by Craig Hubbard (January 2003) - &ldquo;Lost Toys&rsquo; <em>Battle Engine Aquila</em>&rdquo; by Ben Carter (April 2003) - &ldquo;<a href="http://www.gamasutra.com/features/20030613/price_01.shtml">Insomniac Games&rsquo; <em>Ratchet &amp; Clank</em></a>&rdquo; by Ted Price (June 2003) - <a href="http://www.gamasutra.com/features/20030627/train_01.shtml">&ldquo;Big Huge Games&rsquo; <em>Rise of Nations</em>&rdquo;</a> by Tim Train and Brian Reynolds (July 2003) - &ldquo;Harmonixâ€™s <em>Amplitude</em>&rdquo; by Greg LoPiccolo &amp; Alex Rigopulos (August 2003) - &ldquo;<a href="http://www.gamasutra.com/features/20030910/rooke_01.shtml">Monolith&rsquo;s <em>TRON 2.0</em></a>&rdquo; by Frank Rooke (October 2003) - &ldquo;Relic Entertainment&rsquo;s <em>Homeworld 2</em>&rdquo; by Geoffrey Thomas, Stephane Morichere-Matte, and Joshua Mosqueira (November 2003) - &ldquo;Naughty Dog&rsquo;s <em>Jak II</em>&rdquo; by Daniel Arey (January 2004) - &ldquo;Totally Gamesâ€™ <em>Secret Weapons over Normandy</em>&rdquo; by Morgan Gray (February 2004) - &ldquo;Bizarre Creationsâ€™ <em>Project Gotham Racing 2</em>&rdquo; by Garrett Young, Mario Rodriguez, and Chris Pickford (March 2004) - &ldquo;Ubisoft&rsquo;s <em>Prince of Persia: The Sands of Time</em>&rdquo; by Yannis Mallat (April 2004)  One word of warning: This is not nearly enough samples to get any sort of representative idea of what the big problems affecting game development really are. It&rsquo;s also a very self-selected group of projects: not only did they choose to write a public postmortem, but all the projects actually managed to ship a game and were relatively successful.  However, what probably skews the results more than anything else is what the authors felt they could write in a public postmortem. Everybody had to be extremely cautious about what to say and how to say it, and I have no doubt that very important problems didn&rsquo;t even get mentioned. Who would dare publish something along the lines of &ldquo;our publisher had no clue what it was doing,&rdquo; or &ldquo;my boss is completely incompetent but we shipped the game in spite of him.&rdquo; Still, I&rsquo;m of the opinion that incomplete data is still better than no data at all in this case, so let&rsquo;s proceed.  ### Common patterns  <strong>Resources/time</strong>  It is a fact of this industry that, <a href="http://www.idsoftware.com/">id software</a> and a <a href="http://www.3drealms.com/duke4/">few others</a> notwithstanding, we all have very hard deadlines. Most games commit to shipping by a particular date (Christmas or the Thanksgiving weekend being a couple of industry favorites) and have to do everything in their power to deliver or risk being canceled. It&rsquo;s not surprising then that the number one problem listed in all the postmortems was that some features were not started until it was too late (<em>Prince of Persia</em>, <em>Project Gotham Racing 2</em>, <em>Tron 2.0</em>, <em>Ratchet and Clank</em>, <em>Battle Engine Aquila</em>, <em>No One Lives Forever 2</em>, <em>Neverwinter Nights</em>, and <em>Aggressive Inline</em>).  Just about every aspect of the game was brought up in this respect: technology, tools, design, art, etc. In some cases it meant those features fell short of expectations, but most of the time it severely affected other parts of the development. When crucial tools for content development or key technology pieces become available just a few months before the shipping date you know that something didn&rsquo;t go right.  Two other postmortems (<em>Homeworld 2</em> and <em>Frequency</em>) listed the flip side of the same situation: not enough resources. At least in that case they identified the lack of resources and tried to deal with it as opposed to just finding out that things were taking longer than expected.  That means that 10 out of 13 postmortems brought up a similar problem. I wouldn&rsquo;t be surprised if the other postmortems also felt the same problem but didn&rsquo;t write a specific item in the postmortem about it. This is clearly a big problem in the games industry. When managing a project, you have three variables to play with: time, resources, and features; pick any two. Unfortunately it seems that people like to pick all three and deliver in none of them instead.  <strong>Approval process</strong>  The next most common issue that was identified as having gone wrong was the lack of an effective internal approval process (<em>Prince of Persia</em>, <em>Homeworld 2</em>, <em>Tron 2.0</em>, <em>Frequency</em>, <em>Ratchet and Clank</em>, <em>Neverwinter Nights</em>, <em>Aggressive Inline</em>). Some of the obvious examples of this problem are sub-par content making it into the game, or technology that appeared to be finished but wasn&rsquo;t. But there were other manifestations of the same problem: feature creep that ruined the schedule, or overly ambitious designs that were not really feasible.  All those are signs that the project was working without sufficient visibility and feedback. If the planned game levels are too ambitious, it should become apparent right away, not two months before beta. If tools are not working as expected, it should be noted right away.  Closely tied to this problem was another common complaint: unnecessary rework. Several postmortems cited that as one of the causes for delayed schedules and massive overtime. When content was created on top of a piece of technology that had to be re-written, or based on some design that was changed, all that content had to be re-done from scratch. Nobody&rsquo;s going to get things right the first time around, but there&rsquo;s a not-so-fine line between useless rework and an iterative approach.  <strong>Content pipeline</strong>  So far I wasn&rsquo;t too surprised by the patterns that were emerging, but this one caught me totally by surprise. A large number of the postmortems were complaining about inadequacies in their content pipeline (<em>Prince of Persia</em>, <em>Project Gotham Racing 2</em>, <em>Secret Weapons Over Normandy</em>, <em>Jak 2</em>, <em>Ratchet and Clank</em>, <em>Battle Engine Aquila</em>).  The issues with the content pipeline ranged from not being able to deal with so many assets, iteration time being too long for the content creators, or not having a fully automated system all the way to the CD/DVD burning process.  Interestingly enough, I wasn&rsquo;t aware that other companies were struggling with this so much when I wrote the article &ldquo;Optimizing the Content Pipeline&rdquo; in the April 2004 issue of <em>Game Developer Magazine</em>. This is probably an area that will become more important in the near future and it would pay off for companies to explicitly define their content pipeline and streamline it as much as possible.  <strong>Large teams</strong>  Some projects clearly had trouble coordinating the efforts of their team members (<em>Prince of Persia</em>, <em>Project Gotham Racing 2</em>, <em>Jak 2</em>, <em>Neverwinter Nights</em>). Most often this was in the form of rework, as mentioned earlier. It seems that resources were often being put in areas before they were fully ready to go, or, alternatively, some areas didn&rsquo;t have enough resources before full production started.  Interestingly only one postmortem explicitly mentioned communication being an issue (<em>Battle Engine Aquila</em>). I would have expected that to be a much more common complaint. Either my experience is very different from those projects, or it was one of those taboo areas that people were not allowed to write about.  As a point of reference, these are the sizes of the development teams that brought up team coordination as an issue:  - <em>Prince of Persia</em>: 65 (peak, excluding testers) - <em>Project Gotham Racing 2</em>: 40 (core team), 102 (peak, including testers) - <em>Jak 2</em>: 48 (full time) - <em>Neverwinter Nights</em>: 75 (peak), 40 QA, 5 sound, 20 translators.  We can&rsquo;t compare those figures directly against each other (because they all count team size in slightly different ways), but clearly, those are some pretty heavy-weight teams. Most of the teams in the other postmortems were significantly smaller. Is this the way of the future? We better start getting used to it.  <strong>Crunch time</strong>  Why does this always come up when I write anything related to game development? It&rsquo;s a very important topic to me, but I&rsquo;ve tried putting it aside and only bringing it up a few times. Try as I might, it keeps rearing its ugly head every time someone in the room whispers the words &ldquo;game development&rdquo;.  Surprisingly, only a few postmortems clearly identified crunch time and employee burnout as a negative aspect they had to go through (<em>Secret Weapons Over Normandy</em>, and <em>No One Lives Forever 2</em>). However, most of the other postmortems acknowledged that there was a fair amount of crunch time involved. The really scary part is that it usually showed up in the &ldquo;what went right&rdquo; section, pointing out how dedicated the team was, or how macho they all were that they pulled through it.  Until the industry grows out of this basement coder mentality, we&rsquo;ll continue having the same problems. I&rsquo;ll spare you the lengthy rant and refer you to the wonderful job the <a href="http://igda.org/">IGDA</a> folks have done putting together the <a href="http://www.igda.org/qol/">Quality of Life Whitepaper</a>. Draw your own conclusions from that and think about who will be making games five years from now.  <strong>Other</strong>  The rest of the issues brought up in the postmortems varied quite a lot. Surprisingly, several projects had trouble with localization. I thought that was a solved problem by now, although it&rsquo;s probably a lot more complicated in dialogue- and movie-heavy games, or in games where sentences are created on the fly.  A few of the other issues mentioned included QA problems (either bad testing or not enough), being side-tracked by demos, have unexpected events come up in the middle of the development cycle, or not having a clear objective for where the game was heading.  One of the most insightful comments was brought up in the <em>Battle Engine Aquila</em> postmortem, where they pointed out that their engine was too flexible as a negative point. Having been there, I completely sympathize with that point. Even though it sounds like a great feature on paper, having a completely flexible engine also usually means not having an exceptional engine in any particular front. It also makes narrowing down the design constraints very difficult unless you have a very talented art and design team.  ### Notably absent  So far we&rsquo;ve seen what common points were identified as being problematic. Now let&rsquo;s have a look at all the interesting things that they didn&rsquo;t tell us about.  <strong>Technology/performance</strong>  Considering the amount of time, effort, and trouble that programmers go through coming up with the most clever algorithms, optimizing inner loops, and trying to out-do each other with fancy technology, hardly anybody mentioned technology or performance being an issue. The only mention in the postmortems was when multiplatform development was involved (<em>Secret Weapons Over Normandy</em>, <em>Battle Engine Aquila</em>).  Is it because people were too proud to say their technology let them down, didn&rsquo;t do what they wanted, and was generally too slow? Or was it because there is too much emphasis placed on technology and performance to start with? Maybe we should concentrate on making our tools crash less frequently and our content pipelines be more robust, and just accept a slightly lower particle count. It will probably make for a better game.  <strong>Team problems</strong>  Is this another taboo area that public postmortems can&rsquo;t touch? Probably. Only one postmortem mentioned having team problems (<em>No One Lives Forever 2</em>), and even then, it only referred to the hiring process and a few bad hires. Maybe everybody else had the perfect team where everybody got along great and worked together in perfect harmony. Suuuuure. I haven&rsquo;t seen anything even close that mythical beast though. I guess you can&rsquo;t call your boss&rsquo; wife ugly, but they could at least admit to some general problems.  <strong>Quality and bugs</strong>  Nobody complained at all about the quality of the code produced. They didn&rsquo;t complain much about bugs either (other than mentioning bad QA process). I&rsquo;m afraid this might be one of those things that the games industry takes for granted. I&rsquo;d like to think that good code quality leads to very few bugs, very little (if any) overtime, and to a much better overall game because features could be tested and experimented easily with until the last moment.  I&rsquo;m convinced that a step in the right direction is to use automation as much as possible to test everything as frequently as possible, from unit tests that get executed every time any code is compiled, gameplay balance tests, random tests looking for crashes, or tests verifying that all objectives can be completed.  ### What does it all mean?  By taking a step back and looking at the problems most of these games were facing, we can actually see the cause for all those problems: complexity.  I suspect that just a few years ago a lot of the problems would have been technical issues. Now we&rsquo;re past that. We&rsquo;re the whale that has difficulty breathing due to its own weight but we don&rsquo;t yet fully admit it.  Games are reaching a point of complexity where they require a huge team, which produces a huge amount of assets, needs to communicate and coordinate its efforts effectively, and create a great game in the end. Oh yeah, did I mention ship in time for Christmas?  <strong>Edit</strong>: Ken Williamson emailed me with feedback about this article and brought up an excellent point that I had managed to completely overlook: Publisher interference.  He writes: &ldquo;<em>The one thing I was surprised that didn&rsquo;t come up was Publisher interference. By that I mean unreasonable and often misguided demands by publishers during development which derail production schedules and directly result in the crazy hours - and inevitably the nasty crunch times - common to games. I like to call this the &ldquo;run faster&rdquo; factor. In my experience these demands are the single most damaging aspect of the monolithic publisher/developer paradigm which the games industry seems to have followed the movie and music industries into. Money realities aside, it&rsquo;s one of the reasons I think there just must be a better way to structure development.&rdquo;</em>  I completely agree with Ken that publisher interference is a big issue that most teams have to deal with. Changing requirements, feature creep, and trying to copy the latest successful chart-topper are all too common occurrences. Unfortunately, this also falls in the category of taboo subjects that can&rsquo;t be brought up in a postmortem. Companies have a hard enough time already securing funding and a publisher for their games, so they&rsquo;re not about to bite the hand that feeds them.</th>
					<th><img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2002-10.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2002-11.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-01.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-04.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-06.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-07.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-08.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-10.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-11.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2004-01.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2004-02.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2004-03.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2002-10.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2002-11.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-01.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-04.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-06.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-07.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-08.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-10.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2003-11.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2004-01.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2004-02.jpg"> <img alt="gdmag" loading="lazy" src="/postmortems-looking-back-looking-ahead/images/gdmag-2004-03.jpg"></th>
			</tr>
	</thead>
	<tbody>
	</tbody>
</table>]]></content:encoded></item><item><title>My Take on GDC 2004</title><link>https://gamesfromwithin.com/my-take-on-gdc-2004/</link><pubDate>Thu, 01 Apr 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/my-take-on-gdc-2004/</guid><description>&lt;p&gt;The days immediately following &lt;a href="http://gdconf.com/"&gt;GDC&lt;/a&gt; are always decidedly hectic. Not only do you need to play catch up with the life you left behind for a week, but you also try to get back all the hours of lost sleep between parties and red-eye flights, email all the people that you met (or missed seeing) at the conference, prepare &lt;a href="https://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-1/"&gt;roundtable summaries&lt;/a&gt; or put up session slides, and deal with all the emergencies that happened at the office while you were gone. With all that now safely behind me, it&amp;rsquo;s time to look back on this year&amp;rsquo;s GDC. What was hot and what was not? What were the underlying themes and trends of the conference?&lt;/p&gt;</description><content:encoded><![CDATA[<p>The days immediately following <a href="http://gdconf.com/">GDC</a> are always decidedly hectic. Not only do you need to play catch up with the life you left behind for a week, but you also try to get back all the hours of lost sleep between parties and red-eye flights, email all the people that you met (or missed seeing) at the conference, prepare <a href="/gdc-2004-software-engineering-roundtable-summary-session-1/">roundtable summaries</a> or put up session slides, and deal with all the emergencies that happened at the office while you were gone. With all that now safely behind me, it&rsquo;s time to look back on this year&rsquo;s GDC. What was hot and what was not? What were the underlying themes and trends of the conference?</p>
<p><img alt="gdc2004" loading="lazy" src="/my-take-on-gdc-2004/images/gdc2004.jpg">The full-day tutorials were a bit on the weak side this time around, but the &ldquo;Test Automation in Game Development&rdquo; done by a group of Microsoft test engineers more than made up for it. I found it to be a very well-paced session, covering things in enough (but not excruciating) detail and with lots of very solid information. The topics towards the end were particularly exciting, dealing with unifying all the testing strategies under one system, and doing data mining effectively with the unwieldy amount of results generated by so many automated tests.</p>
<p>The sessions in the last three days were all very strong. I felt there were more quality sessions in the topics that interested me than in previous years. Interestingly enough, I didn&rsquo;t go to many programming talks this year; for some reason, I ended up going mostly to game design and production talks, and enjoying most of them a great deal. The award for the most redundant talk of the show goes to the ones covering some form of real time <a href="http://www.cs.kuleuven.ac.be/~phil/GI/">global illumination</a>. Maybe it was just me, but it seemed the same talk was given by a different person with a slightly different title several times each day.</p>
<p><img alt="will" loading="lazy" src="/my-take-on-gdc-2004/images/gdc_will.jpg"> The highlight of the show without a trace of doubt was <a href="http://thesims.ea.com/us/will/gdc.html">Will Wright</a>&rsquo;s talk &ldquo;Triangulation: A Schizophrenic Approach to Game Design&rdquo;. After attending six GDCs, I have learned that there are some people that you simply have to go see. It doesn&rsquo;t matter whether they decide to give a talk about how their baby girl is learning to walk; you&rsquo;re guaranteed to have a great time and walk out of there with a lot of insights. Will&rsquo;s talks are like that. This time he described the process he uses for designing a game, how he approaches the problem from multiple angles, and how he treats it as an infinite tree of possibilities that needs to be culled through experimentation and instinct. Even his digression into the history of the Russian space program was highly entertaining and bizarrely relevant. But please, when you bring Will back next year, give him the Auditorium. There was no excuse to put him in a medium-sized room that was already overflowing 10 minutes before the talk.</p>
<p>Soren Johnson&rsquo;s talk from <a href="http://firaxis.com/">Firaxis</a> on &ldquo;The Civilization Series: How to Maintain a Successful Franchise&rdquo; probably gets the award for the best unexpected talk. I might have missed this session except for the fact that I met Soren the day before and there was nothing much going on at that same time slot (except for the fourth rehash of the global illumination talk), so I decided to give it a try. Boy, was I impressed! Soren had some very good insights on game franchises and how to think about them in terms of technological/gameplay innovation and release frequency. He then analyzed in detail two very successful franchises (<a href="http://www.microsoft.com/games/ageofmythology/norse_home.asp">Age of Empires</a> and <a href="http://www.blizzard.com/war3/">Warcraft</a>) and compared the decisions made for each of them. The talk finished up by presenting the <a href="http://firaxis.com/games_civ3.cfm">Civilization</a> franchise in terms of everything he described before, which wrapped things up in a very effective way. I can&rsquo;t wait for Civilization IV!</p>
<p>A very simple, yet effective and informative talk was <a href="http://www.blueandorange.org/">Brian Sharp</a>&rsquo;s session on &ldquo;The Physics-Sound System of Deus Ex: Invisible War and Thief 3&rdquo; (whoo-hoo, I made it to a programming talk for a change!). I really liked how he decided to approach the talk: Present an apparently simple problem (what sound do we play when two things collide), then start with simple solution and build on it as its deficiencies became apparent. He wrapped up the talk with a nice demo level with objects making all sorts of noise when they were being dropped on each other.</p>
<p><img alt="will" loading="lazy" src="/my-take-on-gdc-2004/images/gdc_carmack.jpg"> I had high hopes for <a href="http://www.webdog.org/plans/1/">John Carmack</a>&rsquo;s keynote. I met John a few years ago at the first <a href="http://www.techsem.com/gts2001/index.html">GDC Hardcore Technical Seminars</a> and I knew he was a reasonably good speaker and, most importantly, had great insights into the industry and future directions of the technology. Unfortunately I think this might have been a case where I was expecting too much and the keynote fell a bit flat in the end. He echoed a lot of the same things he mentioned back in 1999, such as the fact that graphics are getting better and better and other things need to catch up soon (especially physics and animation). He also expressed his concern about how more and more people are required every day to make a game, and he encouraged people to find alternate genres and different ideas that might be accomplished by a small team. I found it very funny when he lamented how Doom 3 was the first project he ever worked on where he didn&rsquo;t have full control over the source code and there were even a few source files he hadn&rsquo;t even opened. Welcome to our world, John!</p>
<p>A notable mention goes to the talk given by <a href="http://www.fact-index.com/i/iw/iwatani_toru.html">Toru Iwatani</a>, the creator of <a href="http://www.vanschip.com/puck-man/">Pac-Man</a>, &ldquo;The Secret of Pac-Man&rsquo;s Success: Making Fun First&rdquo;. It was very interesting learning what he was thinking when he created Pac-Man, and to get an insight into Japanese culture. The session was simultaneously translated and worked remarkably well. Besides, I even caught a few words in Japanese with what I&rsquo;ve been learning from <a href="http://www.amazon.com/exec/obidos/ASIN/B0000A2ZNX/ref=nosim/gamesfromwith-20">Shogun</a> :-).</p>
<p>Another interesting talk was the &ldquo;<a href="http://www.igda.org/">IGDA</a> <a href="http://www.igda.org/qol/">Quality of Life White Paper</a> Unveiling&rdquo; by Scott Bonds, Dustin Clingman, Hank Howie, FranÃ§ois Dominic LaramÃ©e, and Greg LoPiccolo. They are bringing strong proof about something I&rsquo;ve always felt very strongly about: The industry is really hurting because of the poor, non-sustainable work conditions. When people are working 60-70 hour weeks on a regular basis, they burn out. In the short term they won&rsquo;t do their best work; in the long term, they&rsquo;ll leave the company and eventually, the industry. The results from a recent <a href="http://www.gamasutra.com/features/20040211/olsen_01.shtml">Game Developer Magazine survey</a> were surprising: Over 60% of the people in the games industry have less than 5 years of experience. But when combined with the results of the IGDA survey, they&rsquo;re positively spine-chilling: 34% of the people are planning on leaving the industry in 5 years or less, and over 50% of them are planning on leaving in 10 years or less. Those are really scary numbers, and unless something is done about it, the industry is doomed to continue being stuck in its adolescent phase forever.</p>
<p>The best-talk-I-didn&rsquo;t-go-to award goes to &ldquo;Entertainment Experience First, Videogame Second: The Making of The Return of the King&rdquo; by Neil Young. I don&rsquo;t know what I was thinking when I chose to go to another (rather uninspiring) talk instead. To add insult to injury, I was actually in the room next door and I could hear the audience roaring with delight through the wall. I don&rsquo;t think the audio proceedings will cut it either considering it was the Visual Arts keynote. I&rsquo;m still kicking myself over that, so don&rsquo;t even think of mentioning it to me again.</p>
<p>Stepping back and looking at the sessions I attended, there were a couple very strong underlying themes. The first one is that the teams necessary to create a top game continue to get larger and larger. People are finally starting to realize that the development methods traditionally used throughout most of the industry are falling short and something needs to be done about it. It&rsquo;s probably no coincidence that the number of attendees to my <a href="/gdc-2004-software-engineering-roundtable-summary-session-1/">software engineering roundtables</a> has been increasing every year. Also, middleware is making its way into more of the talks, often as a side or secondary theme.</p>
<p>The other sub-theme apparent in many of the talks was a lament (or alarm, depending of the talk) about the lack of innovation in game design. Speakers were urging developers to think of new approaches and not try to compete with the big players in well-established genres. The only hope of spark was the downloadable game IGDA competition, where innovation is still alive and well. Hopefully we&rsquo;ll see more activity along those lines next year.</p>
<p>I&rsquo;ve never found the GDC expo floor to be particularly interesting. It&rsquo;s a great way to meet face to face with tool creators and middleware providers but not much else. It&rsquo;s not like I&rsquo;m going to purchase <a href="http://www.renderware.com/renderwarestudio.html">Renderware Studio</a> on an impulse buy, and it&rsquo;s not like I haven&rsquo;t read all the specs and seen demos of the tools I&rsquo;m interested in. Still, a few times you might come across some small company that had gone under your radar before. I didn&rsquo;t spend much time in the expo this year, but I got the impression that it was mostly the same faces from last year, no surprises there. However, the expo was always a chance to renew your t-shirt wardrobe. In years past, you would be literally bombarded by t-shirts being thrown at you by the vendors as you walked past their booth. You get a cool t-shirt (hopefully not in fat game developer standard xx-large size), and they get advertisement for a year. Not this time. Maybe the economy is down, maybe the industry is getting ready for another change with the next generation consoles looming on the horizon, but t-shirts were more scarce than hens&rsquo; teeth this time. Either things change next year, or I&rsquo;ll have to actually buy some t-shirts for the first time in years! :-)</p>
<p>Next year GDC will break with tradition and be hosted in San Francisco. I admit I was finally becoming fond of San Jose, but changing venues will have its own share of advantages. It would be fantastic if they decided to change locations every year like <a href="http://www.siggraph.org/">SIGGRAPH</a> and we ended up with a GDC on the East Coast once in a while. In the meantime, I can look forward to dinner at the <a href="http://www.thestinkingrose.com/sf/sf.htm">Stinking Rose</a> every night!</p>
<p>Images from <a href="http://www.gamedev.net/columns/events/gdc2004/">gamedev.net</a>.</p>]]></content:encoded></item><item><title>GDC 2004: Software Engineering Roundtable Summary - Session 1</title><link>https://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-1/</link><pubDate>Wed, 31 Mar 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-1/</guid><description>&lt;p&gt;This is the summary of the first session of my GDC 2004 roundtable: By the Books: Software Engineering in the Games Industry. Unlike other years, each session focused on different topics. This one starts with a general discussion of what we need software engineering for in the games industry and then looks into specific techniques that teams can adopt as part of their development process right away.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This is the summary of the first session of my GDC 2004 roundtable: By the Books: Software Engineering in the Games Industry. Unlike other years, each session focused on different topics. This one starts with a general discussion of what we need software engineering for in the games industry and then looks into specific techniques that teams can adopt as part of their development process right away.</p>
<p><img alt="gdc2004" loading="lazy" src="/gdc-2004-software-engineering-roundtable-summary-session-1/images/gdc2004.jpg">Session 1 | <a href="/gdc-2004-software-engineering-roundtable-summary-session-2/">Session 2</a> | <a href="/gdc-2004-software-engineering-roundtable-summary-session-3/">Session 3</a></p>
<h4 id="overview-and-attendance">Overview and Attendance</h4>
<p>Thanks again to everybody who attended the roundtables this year. All in all we had about 150 people show up (with the first two sessions being completely packed), which means the interest in software engineering continues to increase as projects get more complicated, and team sizes and budgets continue to increase.</p>
<p>We continued the trend from previous years and we had about 30-35% of managers and project leads. That&rsquo;s a good thing because for things to change management needs to get involved, and the sooner they do, the better.</p>
<p>The large majority of the attendees were working on PC and console games (surprisingly, about the same number of both), with very few handheld and web game representation.</p>
<p>C++ this year was the undisputed king of the programming languages (so much that I couldn&rsquo;t count the number of hands). There were only a handful of people using straight C, but a higher representation of Java and higher-level scripting languages like Python or Lua. Several people were starting to use C# for their tools development.</p>
<p>One new piece of data I collected this year was team size. I really wish I could compare this against previous years, but the results were very telling even by themselves. Specifically, I asked for the number of programmers in their teams. These are the results:</p>
<ul>
<li>1-5: 35%</li>
<li>6-10: 45%</li>
<li>10-20: 20%</li>
<li>&gt; 20: 0.05%</li>
</ul>
<p>All of the programmers who were working on a team of 20+ people were either from <a href="http://www.ea.com">Electronic Arts</a> or from outside of the games industry. Still, the numbers are pretty high already, and those are probably just signs of things to come. Even <a href="http://finger.planetquake.com/plan.asp?userid=johnc">John Carmack</a> lamented the increasing number of people required to make a game in his keynote speech.</p>
<h4 id="wednesday-24th-software-engineering-and-techniques">Wednesday 24th: Software Engineering and Techniques</h4>
<p>The session started with a discussion of how can software engineering help game development. Lots of reasons were brought up:</p>
<ul>
<li>Reducing risk</li>
<li>Reducing bugs</li>
<li>Helping with reuse</li>
<li>Easier multiplatform development</li>
<li>Repeatability</li>
<li>Reduce crunch time</li>
<li>Easier transfer between projects</li>
<li>Better support of their content teams</li>
</ul>
<p>All of those are reasons that will continue becoming more and more important in the near future.</p>
<p>A few people had concerns about over-engineering things and brought up the need to strike a middle ground. Even so, nobody admitted to doing too much engineering in their teams (although people did have over-engineered, or over-complicated, pieces of code).</p>
<p><strong>Coding standards</strong></p>
<p>About 75% of the attendees actually had coding standards in their companies (or, in some cases, multiple coding standards!). Only about half of them actually followed them, but most people who had a coding standard found them useful. The reasons given were that it was a good leveler by making the code more similar throughout the project, and that it saved programmer time and headaches.</p>
<p>However, not everybody was in favor of them, and certainly not everybody agreed on what they should cover and in what detail. Some people argued that a coding standard should only cover interfaces and not interfere with implementation details. Some found it difficult to maintain a standard when interfacing with third-party code or APIs. A good point that was brought up was that a coding standard shouldn&rsquo;t be too detailed</p>
<p><strong>Code ownership</strong></p>
<p>Participants identified three main types of code ownership:</p>
<ul>
<li>Team ownership: The whole team owns the code.</li>
<li>Loose code ownership: One or two people are mostly responsible for an area of code, but other people can still modify it.</li>
<li>Strict code ownership: Only one person can modify the code.</li>
</ul>
<p>Very few people had team code ownership (the few who did were doing pair programming). Most people either had loose or strict code ownership. The benefits of team code ownership are avoiding the &ldquo;hit-by-a-bus syndrome&rdquo; (where you might lose your most important programmer because of some unexpected turn of events), and spreading the knowledge of the system to everybody and making all the team members more valuable. The disadvantages were that sometimes people did not take responsibility for their own actions. Team code ownership requires a lot of communication and might work best in smaller teams (5-6 programmers).</p>
<p><strong>Code reviews</strong></p>
<p>About 20% of the participants had some form of code review in place, but the specifics varied a lot. Some people&rsquo;s reviews were just a quick look by someone else before the code was checked-in (code buddy). This was done more frequently around milestone time to avoid people checking in code that would break the build.</p>
<p>A few people had more formal processes in place, printing out the code, and reviewing it in more depth. However, a lot of people found this type of reviewing more tedious than it was worth, and it has the potential to quickly degenerate into pointing out formatting problems or allowing people to go off in tangents about their favorite language feature.</p>
<p>The question of what exactly was the purpose of the code review came up. It clearly doesn&rsquo;t help any with code design because the review happens after the code is written and working. The main reasons listed were bug prevention and avoiding horribly inefficient code.</p>
<p><strong>Automated builds</strong></p>
<p>About 40% of the participants had some sort of automated build system in place (way up from the 15-20% of last year!). Most of these automated builds were done by custom scripts in a high-level language such as Perl or Python. How and when the builds are done also varied a lot: some people had them triggered with each check-in, others had a machine building continuously, and others were simply doing nightly builds.</p>
<p>Some of the benefits claimed for automated builds were checking that the code could always compile and link, and easier version labeling and tracking. A lot of people, in addition to building the source code, were also doing asset builds. As an additional step, many people were doing some form of validation on their executables by loading a few levels or playing back some input (especially random input). People collected the results of the build by either sending emails or posting results on an internal web site.</p>
<p>Two points of caution were raised: A fast turnaround time was important, otherwise the QA and the engineering team could get out of synch and make bug fixing more difficult. The other point is that bad automation could be worse than no automation.</p>
<p><strong>UML</strong></p>
<p>Only a few people were using some form of UML (about 10%). Most of them were just using it in the initial stages of development to sketch out some ideas and discuss them, but then the models were quickly discarded and not kept up to date. Interestingly, some people were generating UML after the project was complete to pass it along to another team.</p>
<p>Only one person was using many of the UML features (sequence diagrams, use cases, etc), and everybody else was mostly using it for static class design. Several other people reported doing initial design just using &ldquo;boxes and lines&rdquo; instead of formal UML, which worked very well for their projects.</p>
<p>Some of the tools people were using were <a href="http://argouml.tigris.org/">ArgoUML</a>(free and open source), <a href="http://www.sparxsystems.com.au/">Enterprise Architect</a>, and <a href="http://web.tiscali.it/ggbhome/umlpad/umlpad.htm">UMLNotepad</a> (free, open source). Not exactly UML, but several people mentioned <a href="http://www.doxygen.org/">Doxygen</a> as a tool to generate some visual representation of the code, which was particularly useful to explore code without existing documentation.</p>
<p><strong>Previous GDC roundtables</strong></p>
<ul>
<li><a href="http://convexhull.com/sweng/GDC2003.html">GDC 2003. By the Books: Software Engineering in the Games Industry</a></li>
<li><a href="http://convexhull.com/sweng/GDC2002.html">GDC 2002. By the Books: Software Engineering in the Games Industry</a></li>
</ul>]]></content:encoded></item><item><title>GDC 2004: Software Engineering Roundtable Summary - Session 2</title><link>https://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-2/</link><pubDate>Wed, 31 Mar 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-2/</guid><description>&lt;p&gt;The second session of the GDC 2004 roundtable &amp;ldquo;By The Books: Software Engineering in the Games Industry&amp;rdquo; concentrated on processes and methodologies. In particular, we had a good look at agile development and how it can be applied to game development.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The second session of the GDC 2004 roundtable &ldquo;By The Books: Software Engineering in the Games Industry&rdquo; concentrated on processes and methodologies. In particular, we had a good look at agile development and how it can be applied to game development.</p>
<p><img alt="gdc2004" loading="lazy" src="/gdc-2004-software-engineering-roundtable-summary-session-2/images/gdc2004.jpg"><a href="/gdc-2004-software-engineering-roundtable-summary-session-1/">Session 1</a> | Session 2 | <a href="/gdc-2004-software-engineering-roundtable-summary-session-3/">Session 3</a></p>
<h4 id="thursday-25th-processes-and-methodologies">Thursday 25th: Processes and Methodologies</h4>
<p>From the initial discussions and show of hands it was clear the most people did not have one specific methodology that they followed during development. The majority of the participants admitted to using some sort of &ldquo;<a href="http://c2.com/cgi/wiki?CodeAndFix">code and fix</a>&rdquo; (or &ldquo;hack and slash&rdquo;, depending on the severity) approach. About 20% of the participants claimed to be using a more controlled iterative approach, while only about 6% were doing some form of agile development.</p>
<p>Agile development is a hot topic now and people seem very curious about how it can be adopted for game development since it seems to fit well with the chaotic and ever-changing nature of our industry. The rest of the session covered several aspects of agile development in detail.</p>
<p><strong>SCRUM</strong></p>
<p><a href="http://www.controlchaos.com/">SCRUM</a> is a specific agile development process (like its more famous cousin extreme programming). It is best described in the book <a href="http://www.amazon.com/exec/obidos/ASIN/0130676349/ref=nosim/gamesfromwith-20">Agile Software Development with SCRUM</a> by Ken Schawaber and Mike Beedle. SCRUM is not as radical a departure from traditional iterative development as extreme programming, so it might be easier to adopt for more conservative shops. SCRUM is currently being used at <a href="http://www.sammystudios.com/">Sammy Studios</a> with very positive results (but it has only been in place for slightly over a month). I&rsquo;m really looking forward to hearing from them next year to see how it worked once they have more experience with it.</p>
<p>Perhaps the most characteristic part of SCRUM is its emphasis on 30-day iterations (called sprints). Like other agile methodologies, it requires small tasks (4-16 hours long), task estimates from the programmers, and continuous re-evaluation and prioritization. Meetings are frequent but very quick (no sitting allowed!). Applied to game development, the priorities for the tasks should come from the designers and the producers.</p>
<p>SCRUM allows for very good project visibility by keeping track of what tasks are completed and which ones are left for each iteration. It also allows to measure the development velocity (how many hours of real programming are done each day), which is invaluable when making estimates and schedules for the next 30-day sprint.</p>
<p><strong>Test-driven development</strong></p>
<p><a href="http://c2.com/cgi/wiki?TestDrivenDevelopment">Test-driven development</a> is an integral part of many agile-development methodologies. For every feature, test-driven development requires that a unit test be written first before the feature is implemented. This is applied to all features of the program, and tests are refactored mercilessly as needed. Some good books on this subject are <a href="http://www.amazon.com/exec/obidos/ASIN/0321146530/ref=nosim/gamesfromwith-20">Test Driven Development: By Example</a> by Kent Beck, and <a href="http://www.amazon.com/exec/obidos/ASIN/0131016490/ref=nosim/gamesfromwith-20">Test Driven Development: A Practical Guide</a> by David Astels.</p>
<p>A surprisingly-high 18% of the participants were doing some form of test-driven development (especially considering that last year only a handful of people were doing any sort of unit testing at all).</p>
<p>The unit tests generated are a great form of regression tests for the code. Whenever anything breaks that has a unit test, you&rsquo;ll know it right away (assuming the unit tests are executed very frequently). A good rule is that whenever a bug is found, first a test must be written that shows the bug, and only then the bug is fixed. That ensures it won&rsquo;t pop up again accidentally. Other benefits of test-driven development is that it narrows down where to look for existing bugs, it serves as a form of documentation that can never get out of date, it helps tremendously with refactoring, and it forces a more modular design.</p>
<p>On the down side, it requires a large amount of &ldquo;extra&rdquo; code. People reported ratios anywhere from 1:1 to 2:1 of test code to application code. Some systems can be very difficult to test with unit tests, especially high-level systems or non-deterministic ones. Some people were using unit tests that compared the output of the renderer pixel by pixel with previous screenshots for some very specific rendering features.</p>
<p><strong>Extreme programming</strong></p>
<p>Two people in the roundtable were doing full <a href="http://www.extremeprogramming.org/">extreme programming</a>, but almost 20% of the people were using one or more features from extreme programming. The best introduction to extreme programming is the white book: <a href="http://www.amazon.com/exec/obidos/ASIN/0201616416/ref=nosim/gamesfromwith-20">Extreme Programming Explained: Embrace Change</a> by Kent Beck.</p>
<p><a href="http://www.pairprogramming.com/">Pair programming</a> is one of the most controversial extreme programming features. A lot of people were doing it but only at some specific times (like near a milestone). One participant tried doing full pair programming for a small tool project and reported very positive results with it. Some of the advantages listed for pair programming was dissemination of knowledge, and training of junior developers. Interestingly, someone pointed out that pairing an experienced developer with a junior one was often a great combination because you would get the stability of the experienced developer but the fresh ideas and perspectives of the junior one. Just about everybody agreed that pair programming was much more useful than code reviews, which are often too late to do anything about any code problems. Also, pairing with another person could force developers to concentrate for longer periods of time without checking their email, answering the phone, or browsing the web.</p>
<p>Of course, not everybody likes pair programming. Some people feel they can be more productive by themselves, and especially if they are not comfortable with the other person or they think in totally different ways. The final output of two people pairing won&rsquo;t be 2x the amount of code, but it&rsquo;s supposed to be more than 2x as reliable (which means less maintenance and bugs down the road).</p>
<p>One interesting question was how to convince management to adopt extreme programming. The best answer was to make sure you don&rsquo;t use the words extreme programming (and certainly don&rsquo;t write it eXtreme programming or you&rsquo;ll be doomed! :-) ). Talk about what specific processes you want to put in place, or even talk about agile development instead. Another view was to start applying some of the techniques of extreme programming without direct management approval, such as test-driven development, refactoring, or pair programming. Showing management a cost-analysis study comparing extreme programming and plain code-and-fix could be another, more direct approach.</p>
<p><strong>Office layout</strong></p>
<p>Extreme programming promotes an open-office environment (the bullpen environment). The possible noise and distractions are supposed to make up for the increase in communication. The participants were clearly divided. Some of them found such an environment very useful (to the point of putting the computers on desks with wheels to arrange things in whichever way made more sense for that particular project), but others wanted to have the peace and quiet of a single office that allows them to concentrate and be productive. Some of the people who had an open environment also had private offices where people could go sometimes when they needed to concentrate more. Finally, nobody seemed to like cubicles very much. They&rsquo;re almost the worst of both worlds: noisy, but not as open to communication as a fully open environment.</p>
<p><strong>Previous GDC roundtables</strong></p>
<ul>
<li><a href="http://convexhull.com/sweng/GDC2003.html">GDC 2003. By the Books: Software Engineering in the Games Industry</a></li>
<li><a href="http://convexhull.com/sweng/GDC2002.html">GDC 2002. By the Books: Software Engineering in the Games Industry</a></li>
</ul>]]></content:encoded></item><item><title>GDC 2004: Software Engineering Roundtable Summary - Session 3</title><link>https://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-3/</link><pubDate>Wed, 31 Mar 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-3/</guid><description>&lt;p&gt;It is true that no tools are necessary to apply good software engineering techniques, but they can often be a big help. The third and last session of &amp;ldquo;By the Books: Software Engineering in the Games Industry&amp;rdquo; concentrated exclusively on languages and tools, and participants shared their favorite tools and warned others about potential duds.&lt;/p&gt;</description><content:encoded><![CDATA[<p>It is true that no tools are necessary to apply good software engineering techniques, but they can often be a big help. The third and last session of &ldquo;By the Books: Software Engineering in the Games Industry&rdquo; concentrated exclusively on languages and tools, and participants shared their favorite tools and warned others about potential duds.</p>
<p><img alt="gdc2004" loading="lazy" src="/gdc-2004-software-engineering-roundtable-summary-session-3/images/gdc2004.jpg"><a href="/gdc-2004-software-engineering-roundtable-summary-session-1/">Session 1</a> | <a href="/gdc-2004-software-engineering-roundtable-summary-session-2/">Session 2</a> | Session 3</p>
<h4 id="friday-26th-languages-and-tools">Friday 26th: Languages and Tools</h4>
<p>The vast majority of game developers seem to be using C++. Some reasons cited for using other languages were better integration with their environment (especially for Java and mobile gaming), faster development time with a higher-level language, or the availability of a refactoring browser. C# this year had several people using it for tools development. Some people claimed very positive experiences, but others said that doing managed C++ wrappers around their C++ code was much too cumbersome.</p>
<p><strong>GUI-development APIs</strong></p>
<p>Most people using C++ were also using MFC for building GUI tools. Some of the other GUI APIs mentioned were <a href="http://www.trolltech.com/">Qt</a>, <a href="http://www.borland.com/bcppbuilder/">Borland Builder</a>, <a href="http://www.fox-toolkit.org/">Fox Toolkit</a>, <a href="http://www.perltk.org/">Perl with Tk</a> and Python with <a href="http://www.wxpython.org/">wxPython</a>.</p>
<p><strong>Asset management</strong></p>
<p>The tools people were using for asset management were:</p>
<ul>
<li><a href="http://msdn.microsoft.com/ssafe/">Visual SourceSafe</a>: 40%. Horror stories of constant database corruptions, but it seemed to work (more or less).</li>
<li><a href="http://www.alienbrain.com/">Alienbrain</a>: 40%. People weren&rsquo;t thrilled with it. Felt too heavy weight. Only good if you use some of the more advanced features.</li>
<li><a href="http://www.cvshome.org/">CVS</a>: 8%. They were using a small amount of data.</li>
<li><a href="http://www.perforce.com/">Perforce</a>: 5%. Artists were happily using the default GUI without any trouble.</li>
<li>No management at all: 5%. Considering switching to an asset management system.</li>
</ul>
<p>The amount of data people had in their asset management systems varied between 2GB all the way up to 20 GB. One handheld developer only had 300 KB of assets total. Ah, the old times!</p>
<p><strong>Source code version control</strong></p>
<p>The breakdown for source code was very different than for asset management.</p>
<ul>
<li><a href="http://www.perforce.com/">Perforce</a>: 40%. Most people here were using branching.</li>
<li><a href="http://msdn.microsoft.com/ssafe/">Visual SourceSafe</a>: 36%. Hardly anybody used branching (not a surprise).</li>
<li><a href="http://www.cvshome.org/">CVS</a>: 20%. Tortoise GUI apparently is very good, although several people were using it through the command line only.</li>
<li><a href="http://www.accurev.com/">Accurev</a>: 4%. An interesting two-step check-in is the main difference of this tool.</li>
</ul>
<p>Unfortunately, nobody was using <a href="http://subversion.tigris.org/">Subversion</a>, but several people had looked into it in the past. They just released version 1.0 so hopefully next year someone will have tried it.</p>
<p><strong>Documentation</strong></p>
<p><a href="http://www.doxygen.org/">Doxygen</a> was mentioned as a good documentation tool. It creates documents from specially-marked comments in the source code as well as the structure of the source code itself. However, not many people referred to the documents that were generated for the code they were working on. It seems that Doxygen&rsquo;s primary use was to explore other people&rsquo;s code or a third-party API.</p>
<p>Nearly 50% of the participants were using some version of <a href="http://c2.com/cgi/wiki">Wiki</a> in their development, which is much more than in previous years. People were using it for design documents, coding standards, and tool documentation. Some were even using it with their artists and designers, so it&rsquo;s not limited to programmers only.</p>
<p>The main advantage of Wiki are that it is a permanent but interactive collaborative medium, so it has more structure than an email thread and it stays there permanently. It makes bringing new people in the team much easier. Some of the most popular Wikis are: <a href="http://c2.com/">Wiki</a> (the original), <a href="http://twiki.org/">TWiki</a>, <a href="http://www.openwiki.com/">OpenWiki</a>, <a href="http://www.moin-moin.com/">MoinMoin</a>, and of course, <a href="http://scrum.minty.org/">ScrumWiki</a> gets a special mention.</p>
<p>A participant found a plugin for Microsoft Word to create chm (help) files very useful to go from Word documents to online help for the tool. Some other people used <a href="http://www.macromedia.com/software/robohelp/">Robohelp</a> to create the help files instead.</p>
<p>Some of the tools mentioned to explore the relationships between classes were:</p>
<ul>
<li><a href="http://www.scitools.com/ucpp.html">Understand C++</a></li>
<li><a href="http://www.borland.com/together/">TogetherC++</a></li>
<li><a href="http://www-306.ibm.com/software/awdtools/developer/rose/features/">Rational Rose code analyzer</a></li>
</ul>
<p>Finally, a simple yet very effective tool was a simple whiteboard plus a cheap digital camera to capture the output and put it up on an internal web site (either that, or the fancy whiteboards with built-in printer).</p>
<p><strong>Bug Tracking</strong></p>
<p>The majority of the participants were using a bug-tracking program. Some of the ones mentioned were:</p>
<ul>
<li><a href="http://www.bugzilla.org/">Bugzilla</a>: Ugly but effective and free. Hard to convince management though.</li>
<li><a href="http://www.fogcreek.com/FogBUGZ/">FogBugz</a>: Simple, lightweight, but limited reports.</li>
<li><a href="http://mantisbt.sourceforge.net/">Mantis</a></li>
<li>Plain databases</li>
<li>Many publisher-specific bug-tracking</li>
</ul>
<p>Some teams reported having conflicts between their own internal bug-tracking system and what the publisher wanted. Some people ended up duplicating entries on both, or only starting to use the publisher one after code complete.</p>
<p><strong>Testing</strong></p>
<p>Many people were doing unit tests this year. Most of them were using some form of XUnit (<a href="http://cppunit.sourceforge.net/">CppUnit</a>, <a href="http://www.junit.org/">JUnit</a>, or <a href="http://www.nunit.org/">NUnit</a> mostly). A few people were using <a href="http://c2.com/cgi/wiki?CppUnitLite">CppUnitLite</a> or another, lightweight custom unit-testing framework.</p>
<p>Several teams did some sort of higher-level test on their games. All of these tests were driven with custom scripts in Perl, Python, or some other high-level language. Some of the tests were done with scripting languages internal to the game itself. Some people were playing back input (including random input, aka, the monkey), and some were even using doing networking tests as part of their automated testing.</p>
<p><strong>Previous GDC roundtables</strong></p>
<ul>
<li><a href="http://convexhull.com/sweng/GDC2003.html">GDC 2003. By the Books: Software Engineering in the Games Industry</a></li>
<li><a href="http://convexhull.com/sweng/GDC2002.html">GDC 2002. By the Books: Software Engineering in the Games Industry</a></li>
</ul>]]></content:encoded></item><item><title>If I Had a Hammer...</title><link>https://gamesfromwithin.com/if-i-had-a-hammer/</link><pubDate>Fri, 19 Mar 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/if-i-had-a-hammer/</guid><description>&lt;p&gt;The sun is shining, the air is warm, leaves are finally coming out. Spring is here. Time to put on my rose-colored glasses and do some armchair quarterbacking. I often find myself saying &amp;ldquo;If I owned a game company I would make sure to do such and such,&amp;rdquo; so here we go.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The sun is shining, the air is warm, leaves are finally coming out. Spring is here. Time to put on my rose-colored glasses and do some armchair quarterbacking. I often find myself saying &ldquo;If I owned a game company I would make sure to do such and such,&rdquo; so here we go.</p>
<p>Be warned, this information is not organized in any particular way, it&rsquo;s not comprehensive of all aspects of running a company, they&rsquo;re not particularly popular views, and there might be some very good reasons why they&rsquo;ll never work. But I can always dream. So without further ado&hellip;</p>
<p><strong>Going &lsquo;round and &lsquo;round with the prototype.</strong></p>
<p>It&rsquo;s unclear whether software development can ever be as much of a rigorous engineering discipline as other fields, but game development is definitely not an exact science. Quite far from it actually. In the end, a game needs to entertain. Even if you&rsquo;re going for a tried and true, formulaic approach, you still can&rsquo;t guarantee you&rsquo;ll have something fun in the end (not like it stops anybody from publishing games anyway, just like bad summer action flicks).</p>
<p>Unless you&rsquo;re aiming from the start to make another tired, derivative game, you really can&rsquo;t schedule and predict when you&rsquo;ll have a good game in your hands. Yes, you can follow existing conventions. Yes, you can build on previous games. But in the end, you won&rsquo;t know whether you have a fun game until you finally see it and see how people react to it. The last time you want to be asking yourself whether your game is fun is at the end of a $10 million project when your publisher is breathing down your neck to nail down the release date.</p>
<p>I would like my company to start a project by doing a gameplay prototype. Forget about technology (for the moment). Forget about doing a massive design document bible (forever). Start with a vision. Something that fits in a couple of paragraphs and everybody understands. Take whatever technology you have around (or <a href="http://www.renderware.com/">license something</a>, or <a href="http://crystal.sourceforge.net/">grab an open source engine</a>, or even <a href="http://www.unrealtournament.com/">use a popular game and mod it</a>), and show me that the game we&rsquo;re thinking of doing is fun. I don&rsquo;t care if it looks pretty. White cubes and pink spheres might be good enough. Reusing the models from the last game is also perfectly fine. Just show me it&rsquo;s fun.</p>
<p><img alt="tulips (c) freeimages.co.uk" loading="lazy" src="/if-i-had-a-hammer/images/tulips.jpg"> You won&rsquo;t get it right the first time, or the second, or the third. But eventually the magic will start happening and something will come into focus. You will have to bring new people often to try out those ideas and see how they react everybody involved in the project is too close to the prototype to have an objective opinion. Good game designers will be able to come up with good ideas in a reasonable amount of time. Other people might stumble for months without coming up with a single good idea that is not a straight rip off from another game. That&rsquo;s what separates the truly creative designers from the hacks out there.</p>
<p>Of course, that&rsquo;s easier said than done (I warned you, all this is armchair quarterbacking). Even some of the most respected designers like <a href="http://web.archive.org/web/20020202112400/www.firaxis.com/dinosaurs/diary/page.cfm">Sid Meier have problems coming up with good game ideas</a>. But you know what? I have a huge amount of respect for someone who actually goes through the process and after a while decides that he couldn&rsquo;t find any great game ideas there. Most people would have moved along with some half-baked idea that tries to copy the latest best-seller.</p>
<p>Unfortunately, this will only work if you have enough money to fund this phase without a schedulable ending and if you can manage to convince your publisher that your game with colored blobs is really fun and is going to outsell everything out there. That&rsquo;s one tough job since publishers seem to care more about technology buzzwords and screenshots than anything else.</p>
<p><strong>One vision to rule them all&hellip;</strong></p>
<p>You&rsquo;ve heard of <a href="http://www.gamasutra.com/features/19991210/birdwell_01.htm">teams where everybody has an equal voice</a>. You&rsquo;ve also heard that too many cooks spoil the broth and about the quality of designs by committee.</p>
<p>Sure, it&rsquo;s possible to make (or stumble into) a game in any way, but I really believe the best way to go about it is to have one person responsible for the vision of the game. That&rsquo;s not necessarily the person who came up with the idea. Maybe someone else suggested it, maybe the publisher contracted it. In any case, the lead game designer should hold on to that vision and have final say on how the game should be. He can (should) take input from everybody, but ideas should be filtered and processed before they make it into the game. Doing so ensures that the game never loses track of what it&rsquo;s supposed to do, what adds value, and what makes it even more fun for the final user.</p>
<p>It might sound like a cool job, but trust me, a lead designer in that position will be under fire from everywhere. Everybody wants their own pet feature in the game. People will get mad when their ideas are shut down, and will disagree with the choices made. It is extremely important that the lead designer have a very strong personality and be someone who can convince everybody that the game is moving in the right direction. Communication is key. If people are aware of the vision and they know the reasons why ideas make it into the game or why they&rsquo;re rejected, they&rsquo;re a lot more likely to be understanding and continue to be highly motivated.</p>
<p><strong>Separation of powers.</strong></p>
<p>Starting in ancient Greece, people realized that having all the power concentrated on one person or governing body was a recipe for trouble. The <a href="http://www.usconstitution.net/consttop_sepp.html">United States has three separate powers</a>: executive, legislative, and judiciary. Many other countries all over the world have similar divisions. Why go to the trouble of such an arrangement? The different powers might end up working against each other, and they&rsquo;ll certainly be more inefficient than having them all combined into a single governing body. The short answer to that is <a href="http://www.bartleby.com/59/13/powertendsto.html">absolute power corrupts absolutely</a>.</p>
<p>It is the same with game development. It is too easy to let personal feelings and interests conflict with the good of the overall project, intentionally or not. That&rsquo;s why I believe that an ideal arrangement for a game company also needs a division of powers. In its simplest form, I see three leads: design, art, and engineering. They each have ultimate responsibility for their departments. With this arrangement, you also prevent the engineering lead from going around telling the artists to make their textures brighter because he likes it better that way (don&rsquo;t laugh, things like this have happened). That&rsquo;s the responsibility of the art lead. As an additional balance, to prevent things that make no sense early on it might be useful to make it so two leads can always veto another one (Design lead: I want to have 100,000 orcs coming over the hill at once. Engineering lead: No way, not unless they&rsquo;re one particle each. Art lead: No way, that would look like crap. Out with that idea. Happy ending: Engineering lead: How about we make impostors for the back and give you 100 orcs coming over the hill? The effect will be very similar).</p>
<p>Finally, to complete the hierarchy, on top of them is a producer, who has ultimate veto power about anything, but who has absolutely no input in the game at all. That last concept is key. The producer is in such a powerful position, that he should have zero input into the game itself. He should coordinate development, interface with the publisher, guide the project based on constraints, but have no design input at all. Repeat after me: a producer should never be a designer; a designer should never be a producer. Combining those two positions in a single person can cause too many conflicts of interest (not to mention that it&rsquo;s way more work than a single person can take on and still do a good job with it).</p>
<p>Disclaimer: I&rsquo;ve never seen such an arrangement, so I probably don&rsquo;t know what I&rsquo;m talking about. It sounds really good in paper, although there&rsquo;s the potential for continuous deadlocks if team members don&rsquo;t know how to work with each other and feel very differently about the project. Clearly, if the producer starts vetoing things for personal reasons, he should be kicked out and promptly replaced with someone who does the job properly.</p>
<p><strong>Making the most out of technology.</strong></p>
<p>Putting together the technology behind a game is a huge amount of work. Trust me, that&rsquo;s what I do for a living. The funny thing is though, there&rsquo;s nothing inherently unique in 99% of that code. Most of it is a matter of organizing things correctly and streamlining the way content finds its way into the game.</p>
<p>Creating all that technology is a large chunk of the total development cost for a game, so it seems wasteful to create it over and over again for every new title. Even re-using some of it still requires a lot of extra work. To make matters worse, the technology and the tools are not usually the primary concern during the development of a game, so when the project is over you&rsquo;re left with a set of half-implemented technology with barely-working tools that were just good enough to finish the previous project but are not up for much else.</p>
<p>Personally, I love working on game technology, so I suspect I&rsquo;d want my company to concentrate on that. However, I would make sure we&rsquo;re not wasting our time. I would set up the game technology project totally separate from the game projects, and then I would try to have two or three simultaneous games in development leveraging our in-house technology. Either that, or take the <a href="http://www.idsoftware.com/">id Software</a> and <a href="http://unreal.epicgames.com/">Epic Software</a> approach and just make one game to showcase our technology and then license it to other companies.</p>
<p>If technology wasn&rsquo;t my thing, then the choice would be clear: license it. With mature game engines such as <a href="http://www.renderware.com/">Renderware</a> or <a href="http://www.ndl.com/">Gamebryo</a> there&rsquo;s very little excuse not to do that. Yes, price is an issue, but think how much it would cost you to make and maintain a similar set of technology internally.</p>
<p><strong>No overtime allowed.</strong></p>
<p><img alt="sun (c) freeimages.co.uk" loading="lazy" src="/if-i-had-a-hammer/images/sun.jpg"> The game industry grew out of a cottage industry made out of teenagers working in their bedrooms. Now it&rsquo;s a full-blown industry with huge budgets, but some of the same old attitudes still prevail. There&rsquo;s a very strong sentiment in the game industry that developers should only care about their projects and should spend all their waking (and sleeping sometimes) time at the office. Looking through <a href="http://www.amazon.com/exec/obidos/ASIN/1578202140/ref=nosim/gamesfromwith-20">postmortems</a> (and <a href="http://www.google.com/custom?q=postmortem&amp;sa=Search&amp;cof=T:#000000;LW:552;L:http://www.gamasutra.com/db_area/images/layout/gama2001logo2-yellow.gif;LC:%23880000;LH:60;BGC:%23FFFFCC;AH:center;VLC:%23808080;GL:0;AWFID:28617e3f266be034;&amp;sitesearch=gamasutra.com">this</a>) in <a href="http://gamasutra.com/">Gamasutra</a> and <a href="http://www.gdmag.com/homepage.htm">Game Developer Magazine</a> shows to what extent this attitude is rooted in the industry when half the postmortems boast in their positive aspects how they worked insane hours but the team pulled through to deliver the goods.</p>
<p>Some call it heroics. I call it <a href="http://c2.com/cgi/wiki?CowboyCoding">cowboy coding</a> and <a href="http://www.amazon.com/exec/obidos/ASIN/013143635X/ref=nosim/gamesfromwith-20">death march</a>. <a href="http://www.amazon.com/exec/obidos/ASIN/0932633439/ref=nosim/gamesfromwith-20">Studies have shown</a> that after about 50 hours of work in a week, the amount of work done actually decreases. Not only are getting people tired, they make mistakes, and they need to fix the problems they cause, but the longer they spend in the office, the more work time they have to dedicate to do other things: step out to the bank to deposit a check, stop by the post office to get a package, etc. Number of hours in the building != amount of productivity.</p>
<p>Fortunately, there are a few companies in the industry that are aware that people want to have lives outside their work and encourage (or allow) employees to work 40-hour weeks. Maybe people in high places are starting to realize that happy, rested employees are a lot more productive than stressed, burned-out ones (who also quit as soon as the project is over and need to be replaced).</p>
<p>I would like to try an experiment with my company: Not only would employees be encouraged to work 40-hour weeks, they&rsquo;d be required not to work more. The catch is that people are expected to put in a serious eight hours of work every day. No screwing around, no checking the web, no wasting your time <a href="/physical-structure-and-c-part-2-build-times/%20">waiting for builds to complete</a>. There&rsquo;s nothing better than leaving work itching to come back the next day rather than leaving exhausted and hoping to forget all about it as soon as possible. If you&rsquo;re dying to do more, work on your own project, contribute to open source software, read a technical book, or learn about something completely different. It&rsquo;ll all come back and be useful in the end, the employee will be much happier and relaxed, and the company will have great employee retention. Workaholics need not apply.</p>
<p>Very rarely (that&rsquo;s the idea anyway) we might need to speed something up to meet a deadline or make up for some lost time. Under those circumstances the company would ask people to put in overtime with the condition that for every hour they put in, they get two hours off in the very near future. That&rsquo;s a good way of making sure the company doesn&rsquo;t overuse overtime. I&rsquo;m sure I&rsquo;ll write more about this in the future.</p>
<p><strong>The good of the many outweighs the good of the one.</strong></p>
<p>There is a lot more to a successful game development team than a group of talented individuals. You could fill one room with superstars and you&rsquo;ll be almost guaranteed to get a failing project asphyxiated by huge egos.</p>
<p>Putting together an effective team is a very delicate matter. While a lot of people put emphasis on technical knowledge and experience, I&rsquo;m convinced that the most important requisite is the ability to work well with others. It&rsquo;s no good to hire a superstar if nobody can work with him. I&rsquo;d rather hire an less talented programmer who can interface very well with everybody and is eager to learn and participate in the project.</p>
<p>People can pick up technical knowledge and experience pretty quickly if they are eager to learn, but moody <a href="http://c2.com/cgi/wiki?PrimaDonna">prima donnas</a> don&rsquo;t change their ways very often, and drive away everybody around them.</p>
<p><strong>Totally driven&hellip; by data.</strong></p>
<p>This probably goes without saying, but I&rsquo;d want the games created by my company to be totally data-driven. We don&rsquo;t hire programmers based on their good looks, and we don&rsquo;t hire them based on their design sensibilities either (at least, I wouldn&rsquo;t in my company). So they shouldn&rsquo;t be creating the game. That&rsquo;s up to the designers and, to a smaller degree, the artists. They&rsquo;re the creative vision behind the game (it doesn&rsquo;t mean that programmers can&rsquo;t be creative, just creative in other areas).</p>
<p>That means that the content creators should be able to put together a game by themselves, without programmer intervention. To accomplish that, we need to be totally data-driven. Ideally, <a href="http://www.gamasutra.com/features/19991207/chey_01.htm">whole new games can be created by changing the data</a> (which includes data definitions, scripts, sounds, art, etc). Any game-specific behaviors should be coded through the use of scripts or something similar that can be changed quickly without recompilations and requires no large-scale architecting. Those scripts can be created by technical designers (or designer/programmers if you prefer to call them that way) instead of using technology engineers whose strengths lie elsewhere.</p>
<p>This data-driven view fits very well with the earlier idea of separating the technology as much as possible and have multiple projects use it, or even license it to other companies so they can create their own games.</p>
<p>There are plenty of other things that I&rsquo;d like to ideally do on my own company, but most of them are common sense and they&rsquo;re not very games-specific: quality above flashiness, taking care of employees, fostering a positive company culture, etc, etc. Some of them, like using agile development or releasing the source code to all technology are probably better left for another time. Unfortunately, as I said earlier, I doubt I&rsquo;ll ever own my own company where I can call the shots this way. Perhaps a more realistic article would be one on how to find your ideal company when you show up for an interview. Until then, enjoy the Spring weather.</p>]]></content:encoded></item><item><title>Physical Structure and C++ - Part 2: Build Times</title><link>https://gamesfromwithin.com/physical-structure-and-c-part-2-build-times/</link><pubDate>Wed, 10 Mar 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/physical-structure-and-c-part-2-build-times/</guid><description>&lt;p&gt;For small projects, we can blissfully code away without paying any attention to physical structure and we won&amp;rsquo;t be any worse off for it. However, as a project grows, it reaches a critical point where build times become unbearably slow. This article looks into the reasons for such slow build times and explores some techniques to speed things up.&lt;/p&gt;</description><content:encoded><![CDATA[<p>For small projects, we can blissfully code away without paying any attention to physical structure and we won&rsquo;t be any worse off for it. However, as a project grows, it reaches a critical point where build times become unbearably slow. This article looks into the reasons for such slow build times and explores some techniques to speed things up.</p>
<p>You know one of the reasons I refuse to live near most cities in the US? Traffic. I&rsquo;m not talking about the &ldquo;this road is crowded&rdquo; type of traffic that lets you zip along at a good speed, or even about the &ldquo;I can&rsquo;t get out of my lane because this is so packed&rdquo; type of traffic that moves slowly along. No, I&rsquo;ve come to accept and deal with that. It&rsquo;s the &ldquo;we might as well get out of the car and enjoy the sunshine because we aren&rsquo;t moving&rdquo; type of traffic that I can&rsquo;t stand. Amazingly enough, it seems to happen around most major cities in the US during rush hour, and sometimes this &ldquo;rush hour&rdquo; stretches from 7AM until 8PM. It&rsquo;s a bad sign when car manufacturers have advertisements telling you how much more comfortable you&rsquo;ll be in their car when you&rsquo;re stuck in traffic. Under those conditions it can easily take over an hour just to cover a distance of 3 or 4 miles.</p>
<p>Other than pointing out that you&rsquo;re much better off walking, cycling, or using public transportation, what&rsquo;s the point of all this and how does it relate to the physical structure of a program? There are some things that just don&rsquo;t scale well. They appear to work perfectly fine for a small number of units, but as soon as a certain threshold is reached, things seem to bog down and eventually collapse under their own weight. Just adding more lanes doesn&rsquo;t appear to solve the problem either, judging by the number of clogged-up 5-lane highways everywhere. Sometimes, you need to take a step back and deal with the problem in a different way. Either that, or buy a nice music system and enjoy your time in traffic.</p>
<p>We might not have much of a say over how traffic should be dealt with where we live, but we certainly have a lot of choices when it comes down to structuring our C++ source code. For small projects, we can blissfully code away without paying any attention to physical structure and we won&rsquo;t be any worse off for it. However, as a project grows, it reaches a critical point, and compilation times start getting slower and slower, to the point where tiny changes could make you wish you were stuck in traffic instead of staring powerlessly at your monitor. Adding a faster CPU, more memory, or a better hard drive can help make things faster, but is usually not a good long-term solution.</p>
<h3 id="build-types">Build Types</h3>
<p>We are usually concerned with the time for two types of builds:</p>
<ul>
<li>Full builds. In this case we care about the time it takes to build the whole project from scratch, starting from a totally clean build. This situation comes about when we just want to use the result of the build of a project we&rsquo;re not actively modifying. For example, an automated build machine will most likely be doing full builds of the game, so the turnaround time before a build is ready will depend on the full build time. Another example might be if you need to link your code with a library for which you have the source code.</li>
<li>Minimal builds. Once we have done a full build on a project, we then make a very small change to its source code and build it again. That&rsquo;s the time for a minimal build. This is what you really care about when you&rsquo;re actively working on a project, making modifications and compiling constantly. Ideally, building the project after a small change should require very little time This allows for very fast turnaround time for debugging, or even to get feedback from the compiler on silly syntax errors we just typed.</li>
</ul>
<p>Improving the physical structure of a program often reduces the time of both types of builds. Unfortunately things don&rsquo;t always work out so neatly and there are times where some changes will make one type of build faster and the other slower. Understanding what affects each compilation time allows us to optimize our compilation strategy and strike a balance that fits our needs.</p>
<p>Clearly, the time for both types of builds depends on the number of files and the complexity of those files. Both types of builds are also affected by the number of files each file depends on (the number of #include statements in each file). However, as we&rsquo;ll see in a moment, in the case of a full build there is the chance of caching the includes of some files and reusing them for other files.</p>
<p>There is something very different about minimal builds. Their build time is usually dominated by the number of files that depend on the modified files. In the worst situation, every file will depend on the file that changed and a full build will be triggered. In the ideal case, only the file with the changes itself will be compiled and no other files will have been affected. In one case the build could take less than a second, and in the other it could easily take multiple hours.</p>
<p>The rest of this article will look at different techniques to reduce build times and how they affect each of those two build types.</p>
<h3 id="counting-includes">Counting Includes</h3>
<p>It is easy to underestimate how quickly include statements can compound. If file A includes file B, and file B includes file C and D, every time someone includes file A they&rsquo;re including three other files for the ride. Add a few more levels of inclusion with header files including many other header files, and you have a recipe for disaster (or for really long build times at least).</p>
<p>As an experiment, I added one more feature to <a href="/wp-content/uploads/bin/analyze_includes.txt">the script I wrote last week</a>. The script analyzes a set of source code files and determines how many times each file is included by other files in a recursive way. So, in our trivial example above, file C will be reported as being included twice (once by B directly, and once by A indirectly). I then decided to test it on the source code for a high-level game library (I&rsquo;m not going to be any more specific since it wasn&rsquo;t particularly good code and it had a pretty hideous physical structure). I wouldn&rsquo;t be surprised if it&rsquo;s not very different from the level of complexity of a lot of game code out there. As a point of reference, the library was composed of 300 cpp files and 312 header files.</p>
<p>Before I ran the script, I tried to guess how many times the most included file in the whole library was included by other files. My guess was around 600 times, just because I knew that the physical structure of that code wasn&rsquo;t pretty. I figured maybe almost half the files included that one header file, and a few others included it indirectly. Boy was I wrong! Here are the shocking results:</p>
<table>
	<thead>
			<tr>
					<th>Top included files</th>
					<th></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>file1.h</td>
					<td>10777</td>
			</tr>
			<tr>
					<td>file2.h</td>
					<td>3683</td>
			</tr>
			<tr>
					<td>file3.h</td>
					<td>1438</td>
			</tr>
			<tr>
					<td>file4.h</td>
					<td>940</td>
			</tr>
			<tr>
					<td>file5.h</td>
					<td>859</td>
			</tr>
	</tbody>
</table>
<p>That means that during the course of a full build for those 300 cpp files, one header file could be included over 10,000 times! No wonder this particular library seemed to take a long time to compile. Notice that the other top files quickly drop to being included around 800 times each (which is still even higher than my initial estimate).</p>
<p>As a comparison, I tried running that same script on another, much smaller library, but also one with a much better physical structure and many fewer dependencies between files. This second library was only made up of 33 cpp files and 39 header files. The most included file was only included a total of 23 times (with the second one being included less than 10 times). So, having the number of classes grow by a factor of 10, caused the number of includes to grow by a factor of 1000. Clearly not a very scalable situation.</p>
<p>Things aren&rsquo;t quite that bad though. Header files typically have a set of include guards in them, to prevent the compiler from adding duplicate symbols if it encounters the same header file multiple times during the compilation of one cpp file. This is what include guards look like:</p>
<p>// SomeFile.h</p>
<p>#ifndef SOMEFILE_H_ #define SOMEFILE_H_</p>
<p>// Normal code goes here, even other #include statements if necessary</p>
<p>#endif</p>
<p>With every header file having include guards around it, I turned on the /showincludes switch in Visual C++ and performed a full build. The total number of includes during the course of building the 300 classes in the library was an astounding 15,264. Better than the worst-case-scenario we calculated earlier, but still tremendously high.</p>
<p>Apparently some C++ compilers try to optimize this situation by automatically caching header files and avoiding hitting the disk to reload them over and over. Unfortunately, there is very little hard data about that, and you&rsquo;re always at the mercy of your current compiler writer. Was that true for Visual Studio .NET 2003?</p>
<p><img alt="hourglass" loading="lazy" src="/physical-structure-and-c-part-2-build-times/images/hourglass_2.jpg"></p>
<h3 id="redundant-guards">Redundant Guards</h3>
<p>To test if I could speed up the compilation any, I added redundant include guards to the whole library. Redundant include guards are like the regular include guards, but they are placed around the actual #include statement. I first saw them mentioned in the book <a href="http://www.amazon.com/exec/obidos/ASIN/0201633620/ref=nosim/gamesfromwith-20">Large Scale C++ Software Design by John Lakos</a> (written in 1996), but popular wisdom claims that they are unnecessary with modern compilers. Well, time to test that.</p>
<p>This is what redundant include guards look like:</p>
<p>// Somefile.cpp</p>
<p>#ifndef SOMEFILE_H_ #include &ldquo;SomeFile.h&rdquo; #endif #ifndef SOMEOTHERFILE_H_ #include &ldquo;SomeOtherFile.h&rdquo; #endif</p>
<p>//&hellip;</p>
<p>I wrote <a href="/wp-content/uploads/bin/add_external_guards.txt">a quick script</a> to add redundant guards to all the source code and did a full build again. The number of includes reported by the compiler went down to 10,568 (from over 15,000). That means that there were about 5,000 redundant includes in a full build. However, the overall build time didn&rsquo;t change at all.</p>
<p><strong>Result</strong>: Zero. Apparently Visual Studio .NET 2003 (and probably most of the major compilers) does a pretty good job caching those includes by itself.</p>
<p><strong>Recommendation</strong>: Stay away from redundant include guards. I never liked having the including files know about the internal define, and if the guard ever changes it can easily break things. Besides, the code looks a lot messier and unreadable. It might have been worth it if we could define #include to expand to a redundant guard automatically, but I don&rsquo;t think that&rsquo;s possible with the standard C preprocessor.</p>
<h3 id="pragma-once">#pragma once</h3>
<p>Just in case, I decided to test another strategy and see if I obtained similar results. Instead of using redundant include guards, I added the #pragma once preprocessor directive to all header files. Visual C++ will treat files with that directive differently and it&rsquo;ll make sure that those files are only included once per compilation unit. In other words, it accomplishes the same thing as the external guards, just in a non-portable way. Here&rsquo;s <a href="/wp-content/uploads/bin/add_pragma_once.txt">another really simple script</a> to add #pragma once to all the header files.</p>
<p><strong>Result</strong>: No difference. Just as with redundant include guards, it seems that the compiler was smart enough already to optimize that case.</p>
<p><strong>Recommendation</strong>: Don&rsquo;t bother with it. It&rsquo;s a non-standard construct that doesn&rsquo;t get any apparent benefit. If you still feel compelled to use it, at least wrap it up with #ifdef checks for the correct version of Visual Studio.</p>
<h3 id="precompiled-headers">Precompiled Headers</h3>
<p>During a full build, every cpp file is treated as a separate compilation unit. For each of those files, all the necessary includes are pulled in, parsed, and compiled. If you look at all the includes during a full build, you&rsquo;re bound to find a lot of common headers that get included over and over for every compilation unit. Those are usually headers for other libraries that the code relies on, such as STL, boost, or even platform-specific headers like windows.h or DirectX headers. They are usually also particularly expensive headers to include because they tend to include many other header files in turn.</p>
<p>From our findings in the previous two sections, it is clear that some compilers cache the headers encountered for each compilation unit. However, they don&rsquo;t do anything about duplicated headers found across multiple cpp files, and that&rsquo;s where precompiled headers come in.</p>
<p>When using precompiled headers, we can flag a set of headers as being part of the precompiled set. The compiler will then process them all at once and save those results. Every compilation unit will then automatically include all the headers that were part of the precompiled set at the very beginning, but at a much lower cost than parsing them from scratch every time.</p>
<p>The catch is that if any of the contents of the precompiled headers changes, a full rebuild is necessary to compile the program again. This means that we should only add headers that are included very often throughout our project but that don&rsquo;t change frequently. Perfect candidates are the ones we mentioned earlier: STL headers, boost, and any other big external APIs. I always prefer not to include any headers from the project itself, although if you have a header that is included in every file, you might as well include it in the precompiled set (or, even better, change it so it&rsquo;s not included everywhere and improve the physical structure).</p>
<p>The gains from using precompiled headers are quite dramatic. The game library we mentioned in an earlier section took over 14 minutes to compile without pre-compiled headers, but only 2:30 when using them. Those are huge savings! Minimal rebuilds are also improved because we avoid parsing some of the common headers for one file, but the results aren&rsquo;t as dramatic as for full builds.</p>
<p>Precompiled headers are not without their downside though. The first problem is that precompiled headers often end up forcing the inclusions of more headers than it is absolutely necessary to compile each individual file. Not every file needs <vector> or &lt;windows.h&gt; included, but since a fair amount of them do and those are considered expensive includes, they&rsquo;ll invariably end up in the precompiled header section. That means that any compilation unit taking advantage of precompiled headers will be forced to include those as well. Logically, the program is the same, but we have worsened the physical structure of the source code. In effect, we are trading extra physical dependencies between files for a faster compile time.</p>
<p>The second problem is that precompiled headers are not something you can rely on from compiler to compiler and platform to platform. The only compilers I&rsquo;m aware of that implement them are <a href="http://msdn.microsoft.com/visualc/">Microsoft&rsquo;s Visual C++</a> and <a href="http://www.metrowerks.com/MW/Develop/CodeWarrior.htm">Metrowerks&rsquo; CodeWarrior</a> (although I just did a Google search and apparently <a href="http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html">gcc also supports precompiled headers</a>--that&rsquo;s great news!). For the rest of us using different compilers, we&rsquo;re out of luck as far as this technique goes. Considering how important multi-platform development is becoming in the games industry (and elsewhere), this is a big blow against them.</p>
<p>Finally, by far the worst aspect of precompiled headers, is what happens when you combine the first two problems: Take a set of source code developed on a compiler where precompiled headers were available, and try to build it on a different platform. The code will compile since everything is standard C++, but it&rsquo;ll compile at a glacial pace. That&rsquo;s because every file is including a massive precompiled header file, and it is being parsed over and over for every compilation unit without taking advantage of any optimizations in the part of the compiler. If the code had been developed without precompiled headers in the first place, each file would only include those headers that it absolutely needs to compile, which would result in much faster compile times.</p>
<p>So earlier, when I said that the game library without precompiled headers took over 14 minutes to build, that&rsquo;s because it was written with precompiled headers in mind. Otherwise, I estimate it would only take about 5-6 minutes (still much longer than the 2:30 it took with precompiled headers).</p>
<p>Personally, I have never yet worked on a set of code that was developed to be compiled on multiple platforms and where some of them did not support precompiled headers. I suppose the best approach is to use #ifdefs to only include the precompiled headers in one platform and the minimal set of includes for the rest, but it seems like an extremely error-prone approach where programmers are going to be breaking the other platform&rsquo;s builds all the time. I&rsquo;d be interested to know how teams working in such an environment deal with it.</p>
<p><strong>Result</strong>: Huge gains both for full builds and minimal builds if your compiler supports them. Much worse physical structure.</p>
<p><strong>Recommendation</strong>: Definitely use them if you&rsquo;re only compiling in a platform that supports them. If you need to support multiple platforms, the gain is still too big to pass up. It probably is worth if you manage to separate the includes for precompiled headers with lots of #ifdefs and try to keep the physical structure sane for platforms that don&rsquo;t support them.</p>
<h3 id="single-compilation-unit">Single Compilation Unit</h3>
<p>This is an interesting trick that you won&rsquo;t find in most books. I first read about it in the <a href="http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com">sweng-gamedev mailing list</a> about a couple of years ago. Be warned, this is hackish and ugly, but people claimed really good results. I just had to find out for myself how it stacked up against the other techniques to reduce build times.</p>
<p>This technique involves having a single cpp file (compilation unit) that includes all the other cpp files in the project (yes, that&rsquo;s right, cpp files, not header files). To compile the project we just compile that one cpp file and nothing else. The contents of this file are simply #include statements including all the cpp files we&rsquo;re interested in. Something along these lines:</p>
<p>// everything.cpp</p>
<p>#include &ldquo;MyFile1.cpp&rdquo; #include &ldquo;MyFile2.cpp&rdquo; #include &ldquo;MyFile3.cpp&rdquo; //&hellip;.</p>
<p>As you can imagine by now, I wrote <a href="/wp-content/uploads/bin/create_everything.txt">a script to create that file</a> from a directory containing the source code for a project. I just created a file including all the cpp files in that directory, although a better way of doing it would be to parse the make (or project) file and only include those files that are actually part of the project. That way, as I discovered, you avoid including outdated files or files that are in that directory but are not part of the project.</p>
<p>I created this file (everything.cpp), compiled it and&hellip; get ready: The build time went down from 2:32 minutes to 43 seconds! That&rsquo;s a 72% decrease in build time!! Not only that, but the .lib file it created from that library went from 42MB down to 15MB, so it should help with link times down the line. People in the mailing list reported even better results with gcc than with Visual Studio.</p>
<p>What is the reason for such reduction in build times? I can only speculate. I suspect part of it is due to avoiding the overhead of starting and stopping the compiler for every compilation unit. However, the biggest win probably comes from the reduced number of included files. Because everything is one compilation unit, we only include every file once. The second time any other file attempts to include a particular header file, the compiler will have already cached it (and it&rsquo;ll have include guards so there&rsquo;s no need to parse anything). To test this theory, I again turned on the /showincludes switch. Indeed, the number of includes during a full build went down from 10,568 to 3,197. That&rsquo;s a 70% reduction of included files, which is, probably not coincidentally, the same reduction in build time.</p>
<p>One very interesting observation from this experiment is that build times are probably more dependent on the number of actual includes performed by the compiler than I thought at first. All the more reason to keep a really watchful eye on the physical structure of the program. The third part of this article will cover what architectural choices we can make to improve the physical structure and keep the overall number of includes down.</p>
<p>Unfortunately this method also has its share of problems. One of the biggest problems is that there is no such a thing as a minimal build anymore. Any modification to any file will cause a full rebuild. Of course, the full build takes a only a fraction of the time it took before, so this might not be much of an issue.</p>
<p>As with precompiled headers, we&rsquo;re adding a lot of physical dependencies between files. In this case, files will have a physical dependency with any files that were included before it in the everything.cpp file.</p>
<p>However, the most objectionable of all problems is that we can now run into naming conflicts. Before we assumed each cpp file was a separate compilation unit. Now they&rsquo;ve all been forcefully added to the same one. Any static variables or functions, or anything on an anonymous namespace will be available to every cpp file that comes after it on the large everything.cpp file. This means that there&rsquo;s potential for having conflicting symbols, which is one of the things that anonymous namespaces were supposed to solve in the first place. If you have decided to use this technique, you will want to keep everything as part of a separate namespace or part of the class itself and avoid global-scope symbols completely.</p>
<p><strong>Result</strong>: Huge improvement in full-build times, but minimal-build times become much worse. Potential for clashing of static and anonymous namespace symbols.</p>
<p><strong>Recommendation</strong>: The gains of this technique are simply huge so it would be a shame to ignore it. It is probably no good for regular builds, but you might want to have it as an option when you just care about doing full builds (automated build machine or building someone else&rsquo;s code). If so, make sure to wrap symbols in namespaces or classes.</p>
<p><a href="/wp-content/uploads/bin/analyze_includes.txt"><img alt="icon" loading="lazy" src="/physical-structure-and-c-part-2-build-times/images/script.png"> analyze_includes.pl</a> <a href="/wp-content/uploads/bin/add_external_guards.txt"><img alt="icon" loading="lazy" src="/physical-structure-and-c-part-2-build-times/images/script.png"> add_external_guards.pl</a> <a href="/wp-content/uploads/bin/add_pragma_once.txt"><img alt="icon" loading="lazy" src="/physical-structure-and-c-part-2-build-times/images/script.png"> add_pragma_once.pl</a> <a href="/wp-content/uploads/bin/create_everything.txt"><img alt="icon" loading="lazy" src="/physical-structure-and-c-part-2-build-times/images/script.png"> create_everything.pl</a></p>
<p>The next (and final, I promise) part of this article will look at architectural choices that can greatly influence build times as well as looking briefly at link times and see what we can do about them.</p>]]></content:encoded></item><item><title>Physical Structure and C++ - Part 1: A First Look</title><link>https://gamesfromwithin.com/physical-structure-and-c-part-1-a-first-look/</link><pubDate>Fri, 05 Mar 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/physical-structure-and-c-part-1-a-first-look/</guid><description>&lt;p&gt;The physical structure of a C++ program is very important yet it is often overlooked. This two-part article will attempt to explain why the physical structure of a program is so important, present some useful guidelines, and show its effect on compile times.&lt;/p&gt;</description><content:encoded><![CDATA[<p>The physical structure of a C++ program is very important yet it is often overlooked. This two-part article will attempt to explain why the physical structure of a program is so important, present some useful guidelines, and show its effect on compile times.</p>
<p>A few days ago, Tom Whittaker (a friend who is currently working at <a href="http://www.firaxis.com/">Firaxis</a>) emailed me with some surprising facts about the behavior of the #include directive in the C++ compiler of Visual Studio .NET. It turns out that in <a href="http://www.amazon.com/exec/obidos/ASIN/1584502274/ref=nosim/gamesfromwith-20">my book</a>, I hinted that compilers often optimize the include step for header files and so they don&rsquo;t pay the costs of opening a file and loading it. When Tom turned on the /showincludes flag on the compiler, he saw that the same file was repeatedly being included by the compiler, even if it had internal include guards. He ran several interesting tests and I&rsquo;ll add a link from here whenever he gets around to putting them up on his web site (hint, hint, Tom).</p>
<p>All of that made me think again about the physical structure of a C++ program, how important it is, and how often it is overlooked. This two-part article will attempt to explain why the physical structure of a program is so important, present some useful guidelines, and show its effect on compile times.</p>
<h4 id="physical-structure">Physical Structure</h4>
<p>We are all familiar with the logical structure of a program. It deals with classes and functions and namespaces and templates. That&rsquo;s what you learn about in school, and what you read about in most C++ books. Design patterns, object oriented programming, etc, etc, all deal with the logical structure of a program. And, truth be said, it really is the most interesting part.</p>
<p>The physical structure of a program deals with the files that make up its source code. The .cpp and .h files, how they include each other, how they&rsquo;re subdivided into directories, etc. While not as interesting and sexy as the logical structure, it is crucial to understand the consequences of the physical layout of a program for any real-world project of any significant size. That includes just about every modern PC and console game, but probably not handheld devices because of their small code size.</p>
<p>Because it&rsquo;s not a particularly hot topic, not many books talk about the physical structure of a program. The best book in the subject is <a href="http://www.amazon.com/exec/obidos/ASIN/0201633620/ref=nosim/gamesfromwith-20">Large Scale C++ Software Design by John Lakos</a>. No technical lead should work on a game without at least having read parts of that book. Yes, some of the advice is a little outdated by today&rsquo;s standards (it&rsquo;s an almost antique book in the computer world&ndash;almost 10 years!), and some parts are a bit long winded with detailed measurements. Skip those in your first read and you&rsquo;ll still get a lot of gems along the way. Every time I come back to that book I end up getting something new out of it. I haven&rsquo;t read it in about 3-4 years, so it&rsquo;s just about due for another read.</p>
<p><img alt="tangle (c) freeimages.co.uk" loading="lazy" src="/physical-structure-and-c-part-1-a-first-look/images/tangle.jpg"> A good physical structure will result in files without many dependencies to other files, and with files clearly grouped in cohesive modules or libraries. On the other hand, a bad physical structure is one where files are related to other files from all over the project, without clear delimitations or boundaries. This is a clear example of the <a href="http://www.antipatterns.com/briefing/sld024.htm">&ldquo;blob&rdquo; antipattern</a>. Unfortunately, if left unchecked, this is the type of physical structure that develops over time.</p>
<h4 id="benefits-of-a-good-physical-structure">Benefits of a Good Physical Structure</h4>
<p>Why would anybody care about the physical structure? After all, the things we care about when we&rsquo;re writing a program are that it does what it&rsquo;s supposed to do, and that it does it fast. That might be true for a demo, or a throwaway project, but for a large project, maintainability is also a very important requirement. It&rsquo;s no good to have a very efficient class if we can&rsquo;t change it, and it&rsquo;s also no good if iteration to test a change takes a long time.</p>
<p>The benefits of a good physical structure of a program are:</p>
<ul>
<li>Better logical structure. Usually, keeping an eye on the physical structure of a program results in a better logical structure. By reducing the dependencies between files, we will probably reduce dependencies between classes. It is often the case that unexpected connections will grow between classes and even different libraries if their header files are already included. Programmers won&rsquo;t have anything to remind them that they&rsquo;re just adding a new dependency when they decide to call some global function.One of my pet-peeves when programming for Windows is having windows.h included in every single .cpp file, either directly or indirectly. In the type of programs I write, most classes don&rsquo;t need anything in windows.h, yet it is forced down their throats. At one point I attempted to remove a global windows.h include in a library since it was supposedly not needed anywhere, just to have to give up because of the many unnecessary DWORD, BOOL, and screwed up min and max calls scattered everywhere on the source code.</li>
<li>Easier to refactor. If you think of each file as a little box literally connected with a string to all the other files it depends or is dependent on, the more of those strings there are, the harder it is to untangle it from the overall mess and separate it. It is the same thing with refactoring: The worse the physical structure, the harder it is to make any refactoring changes that involve separating or isolating sections (which, in my experience, it&rsquo;s one of the most crucial refactorings you have to do to prevent programs from growing into the â€œblobâ€ antipattern).</li>
<li>Easier to test. Not surprisingly, the more modular and independent the project is, the easier it becomes to write unit tests for it since each piece can be tested separately from the rest. Unit tests really benefit from having very few dependencies, so one of the many benefits reaped by doing test-first development is a very modular design with a logical and physical structure that has very few dependencies.</li>
<li>Faster compile times. This might come as a surprise to some people, but it is usually the most tangible and objective result of having a good (or bad!) physical structure. Usually, the worse the physical structure, the longer the compile times will be. Compile times are an issue for large projects. Even with the fastest machines today, full builds on large projects can easily take hours. More importantly, builds caused by changing just a file or two can trigger builds that last almost that long. Needless to say, having such a delay every time a change is made is not exactly encouraging programmers to test their work and iterate it to make it better. Part two of this article will look exclusively at compile times.</li>
</ul>
<h4 id="guidelines">Guidelines</h4>
<p>Here&rsquo;s a distilled set of guidelines from Lakos&rsquo; book that minimize the number of physical dependencies between files. I&rsquo;ve been using them for years and I&rsquo;ve always been really happy with the results.</p>
<ol>
<li>Every cpp file includes its own header file first. This is the most important guideline; everything else follows from here. The only exception to this rule are precompiled header includes in Visual Studio; those always have to be the first include in the file. More about precompiled headers in part two of this article.</li>
<li>A header file must include all the header files necessary to parse it. This goes hand in hand with the first guideline. I know some people try to never include header files within header files claiming efficiency or something along those lines. However, if a file must be included before a header file can be parsed, it has to be included somewhere. The advantage of including it directly in the header file is that we can always decide to pull in a header file we&rsquo;re interested in and we&rsquo;re guaranteed that it&rsquo;ll work as is. We don&rsquo;t have to play the &ldquo;guess what other headers you need&rdquo; game.</li>
<li>A header file should have the bare minimum number of header files necessary to parse it. The previous rule said you should have all the includes you need in a header file. This rule says you shouldn&rsquo;t have any more than you have to. Clearly, start by removing (or not adding in the first place) useless include statements. Then, use as many forward declarations as you can instead of includes. If all you have are references or pointers to a class, you don&rsquo;t need to include that class&rsquo; header file; a forward reference will do nicely and much more efficiently.</li>
</ol>
<p>One unfortunate aspect of those guidelines is that the compiler doesn&rsquo;t really care one way or another. As long as you provide enough includes, the compiler will happily churn away at the source code and come up with the desired object file. It is up to us to minimize the number of includes and to follow those rules. While it seems fairly straightforward at first (after all, it is only three rules), things get more complicated as soon as heavy refactoring starts. As you split classes, move functions, and consolidate functionality, there might be several unnecessary headers. The only quick way to verify whether they&rsquo;re needed or not is to, gulp, comment them out and try to compile the file.</p>
<p>This situation is more common in large files, which are the ones you&rsquo;re most likely going to be refactoring. If left unchecked, you&rsquo;ll soon be left with a myriad little tendrils connecting your file to the rest of the code without getting any benefit from it. Wouldn&rsquo;t it be great if there was an automated tool that would check that?</p>
<h4 id="automating-the-guidelines">Automating the Guidelines</h4>
<p>I did a quick search and I couldn&rsquo;t find any tools or scripts that did exactly what I wanted. I suppose that a massive C/C++ style-checker tool might look for some of those things (like redundant includes), but nothing jumped out. Most programs are more concerned with checking logical errors and constructs than looking at the physical structure. I started from <a href="http://www.aristeia.com/ddjpaper1_frames.html">Scott Meyers&rsquo; summary of major C++ checkers</a>. In particular I looked at <a href="http://www.abxsoft.com/codchk.htm">CodeCheck</a>, <a href="http://www.gimpel.com/html/lintinfo.htm">PC-Lint</a>, and <a href="http://www.parasoft.com/jsp/products/home.jsp?product=Wizard&amp;">CodeWizard</a>. I admit that I didn&rsquo;t look too deep into them, so maybe they also check for some of these guidelines, but it&rsquo;s certainly not their biggest selling point from reading their web sites.</p>
<p>As a quick challenge, I decided to try and write a quick script to check against those guidelines. Soon I realized that you can&rsquo;t really have the word &ldquo;quick&rdquo; in anything related to parsing C++. I was quickly reminded how ugly the language is, how many quirks it has, how much baggage it a carries around. Java looks mighty tempting sometimes.</p>
<p>I decided that if I was going to have a chance to do this, I would need to leverage other software to parse the source code for me and the script could work directly on the abstract representation of the program. Not exactly what I had in mind, but I stumbled on the XML and perlmod output generated by <a href="http://www.doxygen.org/">Doxygen</a>. I have been using Doxygen for years, but I always thought of it as a pretty documentation generator. I never realized what a powerful and robust C++ parser it was until now.</p>
<p>In a few hours I was able to put together a <a href="/wp-content/uploads/bin/analyze_includes.txt">quick Perl script</a> that hooks up to the <a href="http://www.stack.nl/~dimitri/doxygen/perlmod.html">perlmod</a> output of Doxygen that checked against those rules. Guideline #1 was the easiest one to check against. Really, you don&rsquo;t even need a fancy parser for that. Guideline #2 is already checked by the compiler (if you don&rsquo;t have enough includes, the program won&rsquo;t compile). Guideline #3 is the trickiest one. Still, the script makes a valiant effort and checks for the most common cases. It&rsquo;ll try to detect whether an include is not needed at all, or whether it can be replaced with a forward declaration.</p>
<p>However, the script is a conservative one and will not always detect that a header is necessary. It deals fine with simple constructs such as member variables, enums, references, and pointers. However it seems that Doxygen has very little knowledge of preprocessor directives, so it won&rsquo;t catch any #defines brought in from header files. Doxygen also seems very limited in how it deals with inline functions (probably because Doxygen is looking mostly at the logical rather than the physical structure of the program). It would probably be possible to deal with templates, but I didn&rsquo;t bother making it that far. The script also detects duplicate includes, both in header files and cpp files.</p>
<p>Even with all those limitations, the script can easily deal with about 80% of the cases in most of the code I work with on a regular basis. It was certainly insightful running it on the source code for some of the libraries I work with. I saw plenty of instances where headers could in fact be removed and the physical structure of the program improved. I would love to see a robust tool along these lines that could be ran quickly enough after each compile, or at least once a night in our automated build machine.</p>
<p><img alt="icon" loading="lazy" src="/physical-structure-and-c-part-1-a-first-look/images/script.png"> <a href="/wp-content/uploads/bin/analyze_includes.txt">analyze_includes.pl</a></p>
<p><a href="/?p=8%20">Part two of this article</a> will look at the consequences of physical structure on compile times, and what we can do to improve that.</p>]]></content:encoded></item><item><title>Maintenance, The Hidden Cost of Software</title><link>https://gamesfromwithin.com/maintenance-the-hidden-cost-of-software/</link><pubDate>Sat, 03 Jan 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/maintenance-the-hidden-cost-of-software/</guid><description>&lt;p&gt;&amp;ldquo;Maintenance? I never do maintenance!&amp;rdquo; I hear you say. &amp;ldquo;I&amp;rsquo;m a game programmer! A coder who lives on the bleeding edge and doesn&amp;rsquo;t have to bother with boring stuff like that. That&amp;rsquo;s for stuffy database programmers, not for me.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Have you ever tackled a problem that was supposed to be solved by writing some code in half an hour, but that code haunted you (or your coworkers, much to their chagrin I&amp;rsquo;m sure) for months or years to come? Then you have felt first hand the consequences of maintenance, the hidden cost of software.&lt;/p&gt;</description><content:encoded><![CDATA[<p>&ldquo;Maintenance? I never do maintenance!&rdquo; I hear you say. &ldquo;I&rsquo;m a game programmer! A coder who lives on the bleeding edge and doesn&rsquo;t have to bother with boring stuff like that. That&rsquo;s for stuffy database programmers, not for me.&rdquo;</p>
<p>Have you ever tackled a problem that was supposed to be solved by writing some code in half an hour, but that code haunted you (or your coworkers, much to their chagrin I&rsquo;m sure) for months or years to come? Then you have felt first hand the consequences of maintenance, the hidden cost of software.</p>
<p>The situation usually starts our very innocently. Maybe someone brings up an idea during a meeting, or maybe your lead asks you to estimate how long something will take, or maybe it&rsquo;s you who decides to implement a cool new feature you&rsquo;ve been itching to add to the game. In any case, you end up agreeing to taking a couple of hours to write some quick code that will solve that particular problem.</p>
<p>If someone expresses some doubts about whether it&rsquo;s worth doing it, you quickly answer â€œDon&rsquo;t worry. It&rsquo;ll only take me a couple of hours.â€ Famous last words.</p>
<p>Let&rsquo;s take it from the top. Unfortunately, nobody works at full efficiency. Once you take into account the other meeting scheduled for that morning, a co-worker coming over to talk about yesterday&rsquo;s football game, the obligatory mid-morning break to answer email and browse your favorite web site, and the time to synch to the latest code and do a full build while you get a fresh cup of coffee, we&rsquo;re talking at least four hours instead of two. No big deal, it&rsquo;s still really quick and it&rsquo;s definitely worth doing.</p>
<p>Of course, chances are the initial estimate of two hours was totally inaccurate. It just <em>felt</em> like a task that should take two hours: you just sit there, type away for two hours, and it&rsquo;s done. After all, you&rsquo;re a really good programmer and if you can deal with writing super-optimized [insert your favorite complex algorithm here] functions, then you can write that simple code three times over before breakfast. Software engineers are eternal optimists, especially as far as our own abilities is concerned. Once you sit down and start banging away at the keyboard (because it&rsquo;s so simple that you felt no need to do any thinking before start programming) you realize that it&rsquo;s going a bit slower than you thought, and the &ldquo;couple&rdquo; of hours quickly turn into four or five hours. Add the interruptions and other distractions we mentioned earlier to that, and we&rsquo;re talking a full work day taken up by that simple task. Maybe you even end up staying for an hour or two after work to finish the task. Professional pride; after all, you said it was going to be done in just a few hours. No big deal; it&rsquo;s just one day.</p>
<p>You come in the next morning with a big smile on your face ready to continue with the work you had to put aside before you started with this task. You&rsquo;re just wrapping your head around the code to figure out where you left it off a couple of days ago, when your lead walks in and tells you that the code you wrote yesterday doesn&rsquo;t exactly do what he had in mind. He wanted it to output things in columns instead of comma-delimited rows. Sigh. No problem. In an hour you give him the new version he wanted. We&rsquo;re up to 10 hours total. Let&rsquo;s keep counting.</p>
<p><img alt="coins (c) FreeFoto.com" loading="lazy" src="/maintenance-the-hidden-cost-of-software/images/falling_coins.jpg"> Life is good for a while and you manage to put that task behind you. It left a bad taste in your mouth somehow, but at least it&rsquo;s working and you&rsquo;re moving along. Then, one day, you&rsquo;re checking your list of assigned bugs and you see a high-priority bug. Something with that code you wrote is causing a tool to crash in all the designers&rsquo; machines with the latest release of the tools. Damn! You try to reproduce the problem in your machine so you can debug it, and, of course, it works (that&rsquo;s the curse of the programmers&rsquo; computers&ndash;your code will always work flawlessly there&hellip; except when you&rsquo;re trying to demo it someone). So you head over to the office of a designer, fiddle with it for a while until the crash happens again, hook it up with remote debugging, and eventually you see the obvious bug. Doh! Quick fix, new release of the tools. Another wasted morning. Without counting the time the designers were not able to work because of the crash, we&rsquo;re up to 14 hours.</p>
<p>Weeks later, the story repeats itself. This time it turns out your code is too slow. &ldquo;What do you mean too slow? It was very fast when I wrote it!&rdquo; Then your heart sinks when you see that you were testing it with a couple dozen objects, but the designers are applying it to a level with 50,000 objects, and your O(n^2) algorithm isn&rsquo;t cutting it anymore. This means you pretty much have to re-write it completely from scratch, but now you need to use a more complicated algorithm. This time it takes two full days to write, plus another day to figure out why the changes you made broke another tool that was using the same code. 38 hours so far.</p>
<p>Does the situation sound familiar yet? Maybe a little too painfully familiar? So we&rsquo;ll skip over the 4 hours that will take to keep up to date when somebody else changes an interface that your code uses (and nobody knew it did because you wrote it by yourself without discussing with with anybody), and the full day it took Bob to fix it when your code broke the build and you were out sick.</p>
<p>The point of this drawn-out example is that we all do maintenance, and a lot more than we&rsquo;d like to think. It is unfortunately rare for a piece of software to be written and to be left alone and untouched for years to come. You&rsquo;ll have to update it to reflect changes to the underlying libraries, you&rsquo;ll have to speed it up when its speed becomes critical, you&rsquo;ll have to make modifications to it to implement the new features the artists are asking for.</p>
<p>I&rsquo;d love to collect some statistics gathered from the source control program of a mature code base and see how often certain files are changed, what the hotspots are, and which projects are mostly left alone and never touched (and then learn something about what makes those files different). I&rsquo;m sure someone has already written a script to collect exactly that type of statistics, so if I get a chance I&rsquo;ll try it out and I&rsquo;ll make sure to report back here.</p>
<p>What can we learn from all this?</p>
<p>The first thing is that the cost of writing some software is a lot more than the initial time it&rsquo;s going to take a programmer to implement it. Depending on where and how that code is used, it could be many times that of the initial implementation cost. Unfortunately people (both programmers and managers) tend not to think of that when they&rsquo;re deciding what features to implement or whether to give the green light to a new tool.</p>
<p>What&rsquo;s the best way to reduce that cost? Having no software to maintain in the first place! The best code is no code at all. That&rsquo;s the easiest code to implement, debug, and maintain! If we can avoid writing something, and have no negative impact to the project, then we shouldn&rsquo;t write it. On the other hand, if having a programmer implement that feature is going to save artists and designers a huge amount of hours for the duration of the project, then we clearly should go ahead with it. We should simply be aware of the true cost of what we&rsquo;re doing.</p>
<p>Sometimes we won&rsquo;t know at the beginning whether we should implement something or not. If there is a chance that we don&rsquo;t want or need to implement a feature, it&rsquo;s probably worth our time to spend some time up front to decide whether we really need it. For instance, I was in charge of adding a texture caching system to our current game with the objective of reducing the amount of texture memory used and/or let us use more textures in a single level. I could have jumped straight into the task, coded some cool systems, optimized them, and had something acceptable by the end. Instead, I spent a couple of days running some tests: I measured the throughput from the disk while reading from a background thread and I wrote a really simple cache simulator running on the actual game data. By the end, it was clear that we were not going to get much benefit from texture caching unless we were willing to change how our levels were put together (which was not something we were willing to do at this stage of the project). Too bad that we couldn&rsquo;t get that feature, but better that, than having spent a long time to write a bunch of code that is going to complicate things and not get us much of a benefit.</p>
<p>If we have decided that we need to implement a feature, then we should aim for the simplest possible solution that will do what we want. There are many reasons for this (probably a topic for another article), but in general, the simpler a solution is, the easier and faster it is going to be to maintain. You just don&rsquo;t know what you&rsquo;ll need to do to that code in the future: maybe you&rsquo;ll need to make it faster, maybe you&rsquo;ll need to extend it, or maybe you&rsquo;ll be lucky and you&rsquo;ll just have to keep it up to date. Trying to optimize it early or make it very general before it&rsquo;s needed is going to be a waste of time now, and a waste of time when it comes time to maintain it, even if it makes you feel better about all the cool code you got to write.</p>
<p>Another interesting consequence of the cost of maintaining software is that the rate at which a team can write new code is going to decrease as the size of the code base increases. As more code is added, more time is spent maintaining existing code and making sure new code works well with existing code, and less time can be devoted to writing new code. This effect will be particularly noticeable in the first couple of years right after starting a project from scratch. At the beginning the project is a small, cute snowball that everybody understands. Development moves on at a really high pace and everybody&rsquo;s spirits are high. However, as the months go by, the result of that pace makes the snowball grow and grow. Eventually it will become frustrating how hard it has become to make a small change that before would have been a trivial task.</p>
<p>Some of this can be mitigated by maintaining a good architecture: keep modular, independent subsystems, reduce dependencies, etc. Still, even with a good system, the weight of all the existing code makes it more difficult to change or add code in the future.</p>
<p>Something that can help the burden of software maintenance is using third-party libraries as much as possible. When people make decisions to use third-party libraries, they&rsquo;re usually thinking of right now. They can pay X amount of money, and then have a programmer spend two weeks integrating those features into the game engine. What they might not realize is that they&rsquo;re also saving costs in the future. Those libraries are going to be debugged separately, they&rsquo;re going to be improved, and most importantly, they&rsquo;re going to be forcefully separated from the project itself, maximizing the independence between the two. Yes, you&rsquo;ll still have to retrofit your engine to make use of any interface changes of new versions of the libraries, but it&rsquo;s still a big win.</p>
<p>Finally, in this age where reusability is looked upon as the Holy Grail, this could be a surprising concept for some: Throwaway code can be your friend. Throwaway or temporary code completely liberates us from any maintenance costs. We just write a something, use it, and once it fulfills its objective, we throw it away never to be seen again (OK, it&rsquo;s fine to leave it in the dark depths of the version control program so we can refer to it if we ever need to). Perfect examples of throwaway candidates are quick scripts and tools to convert between file formats, or &ldquo;scaffolding&rdquo; code to help us get somewhere or help us get started while we wait for some other functionality to become available. It is very important to keep in mind what type of code we&rsquo;re dealing with when we&rsquo;re developing it though, and we should also clearly label it in some way so everybody knows it&rsquo;s throwaway. That way a class labeled <code>Tmp3DView</code> won&rsquo;t become deeply rooted in your tools, or will it?</p>]]></content:encoded></item><item><title>Must Read Books</title><link>https://gamesfromwithin.com/must-read-books/</link><pubDate>Thu, 01 Jan 2004 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/must-read-books/</guid><description>&lt;p&gt;Over the years I&amp;rsquo;ve read hundreds of technical books. Some of them had some great new ideas, others were great introductions to specific topics, and others had a knack for explaining some complex topic in a very easy to understand way. But in the end, which books had the most impact on me? If I had to go back and pick only a handful of books, which ones would I pick? This is that list.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Over the years I&rsquo;ve read hundreds of technical books. Some of them had some great new ideas, others were great introductions to specific topics, and others had a knack for explaining some complex topic in a very easy to understand way. But in the end, which books had the most impact on me? If I had to go back and pick only a handful of books, which ones would I pick? This is that list.</p>
<p>If there&rsquo;s a book here on a topic you&rsquo;re interested in and you haven&rsquo;t read it, don&rsquo;t think about it twice, buy it right away and bump it up to the top of your reading queue. You won&rsquo;t regret it.</p>
<p>On the flip side, feel free to recommend to me any books you feel very strongly that should be here. I make no guarantees, but if it&rsquo;s a total knock-out, maybe it&rsquo;ll make it to this list in a couple of weeks.</p>
<h3 id="project-management">Project management</h3>
<p><a href="http://www.amazon.com/Rapid-Development-Taming-Software-Schedules/dp/1556159005%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1556159005"><strong>Rapid Development by Steve McConnell</strong></a></p>
<p><a href="http://www.amazon.com/Rapid-Development-Taming-Software-Schedules/dp/1556159005%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1556159005"><img loading="lazy" src="images/41v%2BVkWVrML._SL160_.jpg"></a></p>
<p>Simply put, if you&rsquo;re a lead or manager for any project, you <strong>must</strong> read this book. Not doing that is simply irresponsible. This book is packed with no-nonsense advice on how to run a project. If almost 700 pages is a bit too much, you can start with the <a href="/ref=nosim/gamesfromwith-20">Software Project Survival Guide</a> also by McConnell. It covers the same ground but concentrates on the &ldquo;whats&rdquo; as opposed the &ldquo;whys&rdquo;.</p>
<p><a href="http://www.amazon.com/Slack-Getting-Burnout-Busywork-Efficiency/dp/0767907698%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0767907698"><strong>Slack : Getting Past Burnout, Busywork, and the Myth of Total Efficiency by Tom Demarco</strong></a></p>
<p><a href="http://www.amazon.com/Slack-Getting-Burnout-Busywork-Efficiency/dp/0767907698%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0767907698"><img loading="lazy" src="images/517NV85TBRL._SL160_.jpg"></a></p>
<p>A new look at what it means to be really efficient and why that&rsquo;s not the same thing as being really effective. Along the same lines of this book is the classic <a href="/ref=nosim/gamesfromwith-20">Peopleware</a>, by Tom Demarco and Timothy Lister. [<a href="/book-review-slack-getting-past-burnout-busywork-and-the-myth-of-total-efficiency/">Read the full review</a>]</p>
<p><a href="http://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0321278658%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0321278658"><strong>Extreme Programming Explained: Embrace Change by Kent Beck</strong></a></p>
<p><a href="http://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0321278658%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0321278658"><img loading="lazy" src="/must-read-books/images/51QXx561dIL._SL160_.jpg"></a> Even if you&rsquo;re not doing Extreme Programming, you should at least know what it is and why some people are so excited about it. Considering how unpredictable game development is and how much design, technology, and publisher preferences change from day to day in game development, any book that encourages us to &ldquo;embrace change&rdquo; is heading in the right direction.</p>
<h3 id="cstl">C++/STL</h3>
<p><a href="http://www.amazon.com/Effective-Specific-Addison-Wesley-Professional-Computing/dp/0321334876%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0321334876"><strong>Effective C++: 50 Specific Ways to Improve Your Programs and Design by Scott Meyers</strong></a></p>
<p><a href="http://www.amazon.com/Effective-Specific-Addison-Wesley-Professional-Computing/dp/0321334876%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0321334876"><img loading="lazy" src="/must-read-books/images/51WCFVFEB2L._SL160_.jpg"></a></p>
<p>After you&rsquo;ve put in a year or two of C++ under your belt, this book will singlehandedly catapult your C++ learning curve ahead by a couple of years. Once you&rsquo;ve memorized it you can move along to <a href="/ref=nosim/gamesfromwith-20">More Effective C++</a> (also by Scott Meyers, of course). Incidentally, Scott Meyers is probably one of the best technical writers I&rsquo;ve ever had the pleasure of reading, so you&rsquo;ll have a great time along the way as well.</p>
<p><a href="http://www.amazon.com/Effective-STL-Addison-Wesley-Professional-Computing/dp/0201749629%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201749629"><strong>Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers</strong></a></p>
<p><a href="http://www.amazon.com/Effective-STL-Addison-Wesley-Professional-Computing/dp/0201749629%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201749629"><img loading="lazy" src="/must-read-books/images/41W3B0YFG8L._SL160_.jpg"></a></p>
<p>Scott Meyers applied the same formula once again and came up with this book. Just like Effective C++, it highlights the major pitfalls, common idioms, and recommended techniques when working with STL. Again, this is not to learn the STL, but to take your skills to the next level.</p>
<p><a href="http://www.amazon.com/Large-Scale-Software-Addison-Wesley-Professional-Computing/dp/0201633620%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201633620"><strong>Large-Scale C++ Software Design by John Lakos</strong></a></p>
<p><a href="http://www.amazon.com/Large-Scale-Software-Addison-Wesley-Professional-Computing/dp/0201633620%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201633620"><img loading="lazy" src="/must-read-books/images/51HNJ7KBBAL._SL160_.jpg"></a></p>
<p>It&rsquo;s starting to get a bit outdated, but it&rsquo;s one of the few books that deals with the real-world issues of C++ development. Is your program starting to take too long to compile? Are you finding it hard to separate the different sections of your code base? Then you need to read this book. Warning: This is one heavy, slow-going book with lots and lots of content. Don&rsquo;t hesitate to put it down for a while and then come back to it. [<a href="/physical-structure-and-c-part-1-a-first-look/%20">Related article</a>]</p>
<h3 id="software-design">Software design</h3>
<p><a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201633612"><strong>Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides</strong></a></p>
<p><a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201633612"><img loading="lazy" src="/must-read-books/images/51Rs5KgdLTL._SL160_.jpg"></a></p>
<p>This book was an eye-opener for me when I first read it. It put a name to and helped consolidate and formalize many ideas that I already had in my head, as well as plant lots of new ones. This could easily be the book that has most influenced me in the last 10 years. It is also one of the ones that I regularly skim through and I always learn something new I had missed before.</p>
<h3 id="game-development">Game development</h3>
<p><a href="http://www.amazon.com/Game-Programming-Gems/dp/1584500492%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1584500492"><strong>Game Programming Gems edited by Mark DeLoura</strong></a></p>
<p><a href="http://www.amazon.com/Game-Programming-Gems/dp/1584500492%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1584500492"><img loading="lazy" src="/must-read-books/images/31seQH49q3L._SL160_.jpg"></a></p>
<p>Take equal parts of the best technical articles from Game Developer Magazine, the most interesting GDC presentations, and the cleverest tricks you read online, and you have an idea of what this book is all about. This is a collection of small articles written by professional game developers. It covers a large variety of topics, but you&rsquo;re guaranteed to find something directly relevant to whatever you&rsquo;re working on at the moment.</p>
<p><a href="http://www.amazon.com/Game-Programming-Gems/dp/1584500549%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1584500549"><strong>Game Programming Gems 2</strong> <strong>edited</strong> <strong>by Mark DeLoura</strong></a></p>
<p><a href="http://www.amazon.com/Game-Programming-Gems/dp/1584500549%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1584500549"><img loading="lazy" src="/must-read-books/images/51PKCXJAARL._SL160_.jpg"></a></p>
<p>More gem goodness.</p>
<p><a href="http://www.amazon.com/Game-Programming-Gems/dp/1584502339%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1584502339"><strong>Game Programming Gems 3</strong> <strong>edited</strong> <strong>by Dante Treglia</strong></a></p>
<p><a href="http://www.amazon.com/Game-Programming-Gems/dp/1584502339%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1584502339"><img loading="lazy" src="/must-read-books/images/51O1U3hannL._SL160_.jpg"></a></p>
<p>Another worthy addition to the Gems family. The bookshelf is starting to get full by now.</p>
<p><a href="http://www.amazon.com/Game-Programming-Gems/dp/1584502959%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1584502959"><strong>Game Programming Gems 4</strong> <strong>edited</strong> <strong>by Andrew Kirmse</strong></a></p>
<p><a href="http://www.amazon.com/Game-Programming-Gems/dp/1584502959%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1584502959"><img loading="lazy" src="/must-read-books/images/51NGaeQk-bL._SL160_.jpg"></a></p>
<p>And who said sequels are bad, uh? Besides, did you notice the really cool cover? ;-)</p>
<h3 id="computer-architecture">Computer architecture</h3>
<p><a href="http://www.amazon.com/Computer-Architecture-Fourth-Quantitative-Approach/dp/0123704901%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0123704901"><strong>Computer Architecture: A Quantitative Approach by John L. Hennessy, David A. Patterson, David Goldberg</strong></a></p>
<p><a href="http://www.amazon.com/Computer-Architecture-Fourth-Quantitative-Approach/dp/0123704901%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0123704901"><img loading="lazy" src="/must-read-books/images/517kQTy1i7L._SL160_.jpg"></a></p>
<p>If you&rsquo;re a typical, well-read game developer, I suspect you will have nodded your way down this list. You will have read, or at least heard of just about every book here. Until this one. This is not a typical recommendation in a game development book list. Why is it here? Perhaps is my computer engineering background, but I found this book simply fascinating when I first read it in college, and I&rsquo;ve referred to it often since then. If you want to get a good grasp on both the fundamentals and the details of CPUs, cache systems, or disk IO, this is the best book on the subject. Next time a console manufacturer says their system has an 8-way set associative L1 data cache with write-back, and no-write allocate, you&rsquo;ll know exactly what they mean.</p>
<h3 id="history">History</h3>
<p><a href="http://www.amazon.com/Hackers-Computer-Revolution-Steven-Levy/dp/0141000511%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0141000511"><strong>Hackers: Heroes of the Computer Revolution by Steven Levy</strong></a></p>
<p><a href="http://www.amazon.com/Hackers-Computer-Revolution-Steven-Levy/dp/0141000511%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0141000511"><img loading="lazy" src="images/51D-Ga9q%2B0L._SL160_.jpg"></a></p>
<p>OK, I admit it, I&rsquo;m a converted hacker. Even though I&rsquo;m now a big proponent of software engineering methods and a well-defined development process, I fell squarely in the third generation of hackers (the 80s) described in the book. This book just holds a very special spot in my heart as my dog-eared paperback copy can attest. Not only does Steven Levy manage to present a very complete history of software and game development following some exceptional individuals, but he manages to make it into an extremely gripping and entertaining book. No self-respecting geek should miss this one!</p>
<p><a href="http://www.amazon.com/Masters-Doom-Created-Transformed-Culture/dp/0812972155%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0812972155"><strong>Masters of Doom by David Kushner</strong></a></p>
<p><a href="http://www.amazon.com/Masters-Doom-Created-Transformed-Culture/dp/0812972155%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0812972155"><img loading="lazy" src="/must-read-books/images/519GF050MDL._SL160_.jpg"></a></p>
<p>This book is the spiritual successor of Levy&rsquo;s book. It picks up in the mid-eighties, just where Hackers left off, and it describes a new generation of hackers, this time concentrating on a smaller subset of people (John Carmack and John Romero, the founders of id). Be warned, this book is even harder to put down than Hackers and it&rsquo;ll have you questioning your life choices for weeks afterwards.</p>]]></content:encoded></item><item><title>Book review: Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency</title><link>https://gamesfromwithin.com/book-review-slack-getting-past-burnout-busywork-and-the-myth-of-total-efficiency/</link><pubDate>Tue, 30 Dec 2003 00:00:00 +0000</pubDate><guid>https://gamesfromwithin.com/book-review-slack-getting-past-burnout-busywork-and-the-myth-of-total-efficiency/</guid><description>&lt;p&gt;Here&amp;rsquo;s a book I wish every manager would read, especially the managers in charge of my project (pure self-interest in my part, I admit it). It&amp;rsquo;s short, focused, to the point, and it drives home a very powerful message: By being constantly busy working you&amp;rsquo;re probably hurting your project and your company.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Here&rsquo;s a book I wish every manager would read, especially the managers in charge of my project (pure self-interest in my part, I admit it). It&rsquo;s short, focused, to the point, and it drives home a very powerful message: By being constantly busy working you&rsquo;re probably hurting your project and your company.</p>
<p><a href="http://www.amazon.com/Slack-Getting-Burnout-Busywork-Efficiency/dp/0767907698%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0767907698"><img loading="lazy" src="images/517NV85TBRL._SL500_.jpg"></a></p>
<p>The whole book revolves around that idea, provides explanations, examples, and the consequences. It&rsquo;s also a very short book, just over 200 pages of large print and easy reading (intended to be read in a two-hour flight as the author put it), which is good considering it&rsquo;s aimed at busy managers. Ironically, the people who need to read the book most won&rsquo;t even know it exists or won&rsquo;t be able to make the time to read it. A while back, I forced a copy upon one of my managers and I said to him &ldquo;Here, you must read this.&rdquo; Supposedly he started reading it but never finished it. I don&rsquo;t think the book really did it for him (and he still has my copy, oh well).</p>
<p>So how can adding time that is not set aside for specific tasks, or â€œslackâ€, in the schedule of a manager or a lead or even a senior staff member help the project? Shouldn&rsquo;t everybody be grinding away with their noses down and fingers glued to their keyboards? When someone is working all the time, he&rsquo;s more <em>efficient</em> because he gets more units of work done in a fixed amount of time. However, he can be less <em>effective</em> than someone with slack into his schedule.</p>
<p>DeMarco very effectively argues that slack allows some very important things to happen. First of all, it allows an individual (and therefore the company) to react more quickly. The manager can take an hour right away and fix something that will benefit the whole team. Otherwise, he might not get around to doing it for another week or two, or after the milestone&hellip; or ever. The second benefit is that it allows people to stop and think about what they&rsquo;re doing, why they&rsquo;re doing it, and how they can do it better. In other words, it allows for constant process improvement.</p>
<p><a href="http://www.amazon.com/Peopleware-Productive-Projects-Teams-Second/dp/0932633439%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Dgamesfromwith-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0932633439"><img loading="lazy" src="/book-review-slack-getting-past-burnout-busywork-and-the-myth-of-total-efficiency/images/51MlUgcSICL._SL500_.jpg"></a> And if you&rsquo;re starting to think of making up slack time by putting in more hours, stop right there. Go read DeMarco&rsquo;s other book, <a href="http://www.amazon.com/exec/obidos/ASIN/0932633439/ref=nosim/gamesfromwith-20"><em>Peopleware</em></a>, before you get any bright ideas. The conclusion is that putting in more time beyond a certain amount doesn&rsquo;t make the project go any faster (but it makes your employees unhappier and go away a lot faster!). No, we&rsquo;re talking about true free time. It doesn&rsquo;t mean that people are going to be twiddling their thumbs during that time though. They&rsquo;ll be researching new ways of doing things, trying out new tools and techniques, reading new books (!!), learning a new language, or helping out with some emergency that came up.</p>
<p>Two gems from the book that are worth the price of admission by themselves:</p>
<p><em>The First Law of Bad Management</em> (actually from another source, but mentioned in the book): If something isn&rsquo;t working, do more of it.</p>
<p>Sounds ridiculous, doesn&rsquo;t it? Yet, how many times have we seen that happening all around us? &ldquo;We&rsquo;re putting all this overtime and we keep missing milestones. We must put more overtime!&rdquo; Next time things start heading south in your project, stop for a moment and think about this again. It won&rsquo;t feel so funny anymore.</p>
<p><em>The Second Law of Bad Management</em>: Put yourself in as your own utility infielder.</p>
<p>In other words, a manager shouldn&rsquo;t also be doing work for the project he&rsquo;s managing. Even though it feels very tempting, and there are even managers out there who pride themselves in it, it&rsquo;s usually a bad idea all around. It ties up the manager&rsquo;s time instead of having â€œslackâ€ time to react to any unexpected events. It also means that the work done by the manager isn&rsquo;t supervised by anybody other than himself. People in general, and programmers in particular, tend to be overly optimistic about their own work, so, without any external checks, that work could easily slip big time or quality can suffer. You need to have nerves of steel to tell your boss that he&rsquo;s writing crappy code and he shouldn&rsquo;t be doing it.</p>
<p>I&rsquo;ve seen this situation happen several in my time in the games industry, and never with a good ending. It&rsquo;s usually because managers are just programmers who have put in their years in the ranks and have been â€œupgradedâ€ to a management position. They claim they&rsquo;ll do 60% management and 40% programming. Buzzz! Wrong answer! Unless they&rsquo;re managing only one or two more people, that&rsquo;s not going to happen; they&rsquo;re going to do both jobs half way and neither one well.</p>
<p>The other very common situation is when a team member leaves half way through the project (a topic for another article) and the manager decides he&rsquo;s going do take up the job Bob was doing. Next thing you know, the manager is locked in his office doing Bob&rsquo;s work (poorly since he doesn&rsquo;t fully understand it and he&rsquo;s out of practice) and not managing the project as he should.</p>
<p>Even if you&rsquo;re not a manager, you can greatly benefit from reading the book. Maybe one day you&rsquo;ll be in charge of other programmers, and in the meanwhile you can take a copy and give it to your boss. Tell him what you want, but make him read the book. It&rsquo;s even really cheap, so you have no excuse not to buy a copy now. Just make sure you write your name in it; hopefully you will get your copy back.</p>]]></content:encoded></item></channel></rss>