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

<channel>
	<title>Games from Within &#187; Software engineering</title>
	<atom:link href="http://gamesfromwithin.com/category/software-engineering/feed" rel="self" type="application/rss+xml" />
	<link>http://gamesfromwithin.com</link>
	<description>Living the indie life</description>
	<lastBuildDate>Mon, 14 May 2012 16:06:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>The Const Nazi</title>
		<link>http://gamesfromwithin.com/the-const-nazi</link>
		<comments>http://gamesfromwithin.com/the-const-nazi#comments</comments>
		<pubDate>Thu, 15 Jul 2010 17:31:37 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[iDevBlogADay]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=996</guid>
		<description><![CDATA[Anybody who worked with me or saw any of my code, would know right away why they call me the Const Nazi. That&#8217;s because in my coding style, I make use of the keyword const everywhere. But instead of going &#8230; <a href="http://gamesfromwithin.com/the-const-nazi">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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&#8217;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&#8217;m going to let Hitler tell us how he really feels about it.</p>
<p><center><br />
<object id="player" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" name="player" width="640" height="375"><param name="movie" value="http://gamesfromwithin.com/wp-content/uploads/flvplayer/player.swf" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="flashvars" value="file=http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi.flv&#038;image=http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi_preview.jpg" /><embed type="application/x-shockwave-flash" id="player2" name="player2" src="http://gamesfromwithin.com/wp-content/uploads/flvplayer/player.swf" width="640" height="375" allowscriptaccess="always" allowfullscreen="true"	flashvars="file=http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi.flv&#038;image=http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi_preview.jpg" /><br />
</object></p>
<p><em>No Flash? Try the <a href="http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi.mov">QuickTime video version</a>.</em></p>
<p></center></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&#8217;t make any guarantees that values don&#8217;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&#8217;t, so const is pretty weak as far as promises go. It just says &#8220;I, the programmer, promise not to change this value on purpose (unless I&#8217;m truly desperate)&#8221;. 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>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&#8217;re going to use <em>const</em> just for one thing, this is the one to use. It&#8217;s invaluable glancing at a function signature and seeing which parameters are inputs and which ones are outputs.</p>
<pre>
void Detach(PhysicsObject&#038; physObj, int attachmentIndex, const HandleManager&#038; mgr);
</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&#8217;t prevent that from happening, but will remind the programmer that he&#8217;s changing the &#8220;contract&#8221; and needs to revisit all calling code and check assumptions.</p>
<h3>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&#8217;t changed.</p>
<pre>
const Vec2 newPos = AttachmentUtils::ApplySnap(physObj, unsnappedPos);
const Vec2 deltaPos = newPos - physObj.center;
physObj.center = newPos;
</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>
int index;
if (some condition)
	index = 0;
else
	index = 2;

DoSomethingWithIndex();
</pre>
<p>Not only does that take several lines not to do much, but index isn&#8217;t <em>const</em> (argh!). So every time I see index anywhere later on in that function, I&#8217;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>
const int index = (some condition) ? 0 : 2;
DoSomethingWithIndex();
</pre>
<p>Ahhhh&#8230; So much better!</p>
<h3>Const member variables</h3>
<p>This one doesn&#8217;t really apply to me anymore because I don&#8217;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&#8217;ll have some internal bit of data that is really not changing the &#8220;logical&#8221; state of an object, but it&#8217;s still modifying a variable (usually some caching or logging data). In that case, you&#8217;ll have to resort to the mutable keyword.</p>
<h3>Const value function parameters</h3>
<p><img class="alignright size-full wp-image-673" src="http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi.jpg" alt="const_nazi.jpg" border="0" width="320" height="206" />Apparently I&#8217;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&#8217;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&#8217;re just saying &#8220;I&#8217;m not going to modify that parameter in this function&#8221; so it makes the code easier to understand.</p>
<p>I&#8217;m actually all for this, but the only reason I&#8217;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&#8217;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&#8217;t copy and paste them or use other automated tools or scripts.</p>
<p><br/></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&#8217;t understand why they didn&#8217;t add it to the language. On something like Python or Perl I can understand because they&#8217;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&#8217;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&#8217;s why the call me the Const Nazi.</p>
<p><br/></p>
<p><i>This post is part of <a href="http://idevblogaday.com/">iDevBlogADay</a>, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the <a href="http://idevblogaday.com/">web site</a>, <a href="http://feeds.feedburner.com/idevblogaday">RSS feed</a>, or <a href="http://twitter.com/#search?q=%23idevblogaday">Twitter</a>.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/the-const-nazi/feed</wfw:commentRss>
		<slash:comments>40</slash:comments>
<enclosure url="http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi.mov" length="33794076" type="video/quicktime" />
<enclosure url="http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi.mov" length="33794076" type="video/quicktime" />
		</item>
		<item>
		<title>When Is It OK Not To TDD?</title>
		<link>http://gamesfromwithin.com/when-is-it-ok-not-to-tdd</link>
		<comments>http://gamesfromwithin.com/when-is-it-ok-not-to-tdd#comments</comments>
		<pubDate>Thu, 01 Jul 2010 18:52:23 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Software engineering]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=979</guid>
		<description><![CDATA[The basic principles of Test-Driven Development (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&#8217;s favorite TDD &#8230; <a href="http://gamesfromwithin.com/when-is-it-ok-not-to-tdd">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The basic principles of <a href="http://gamesfromwithin.com/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&#8217;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&#8217;m often asked from people trying to use TDD for the first time is &#8220;How can you possibly use TDD for high-level game code? It&#8217;s impossible!&#8221;.</p>
<h3>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. &#8220;Maybe it would be best to skip TDD, just for that part&#8221;.</p>
<p>Bad idea!</p>
<p><img class="alignright size-full wp-image-673" src="http://gamesfromwithin.com/wp-content/uploads/2010/07/tdd_cycle.jpg" alt="tdd_cycle.jpg" border="0" width="295" height="295" />By giving up on TDD for high-level code, you&#8217;ll be missing out on the main benefit of TDD: designing better code. I&#8217;ve said this many times, but it bears repeating: TDD is <b>not</b> a testing technique. It&#8217;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&#8217;s because TDD turns our weaknesses into advantages. We&#8217;re humans and we&#8217;re lazy. We don&#8217;t want to repeat ourselves constantly or write complex code. If we&#8217;re writing a test for some code we&#8217;ll write in the future, we&#8217;re going to create a very simple test. We&#8217;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&#8217;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&#8217;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&#8217;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&#8217;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&#8217;s a bit like const-correctness: You&#8217;re either in our out, and there&#8217;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&#8217;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>It&#8217;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&#8217;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. [...] However, there are other situations that seem much harder to test. Like the main loop in a game. According to Kent Beck&#8217;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&#8230; is. It exists to allow you to do certain other things, it doesn&#8217;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&#8217;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>
TEST(MainLoopExecutesCorrectNumberOfTimes)
{
    MainLoopState loopState;
    MainLoopUtils::Execute(loopState, 4);
    CHECK_EQUAL(4, loopState.frameCount);
}
</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&#8217;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&#8217;t bother. I did give it a good try at one point several years ago and I can say it <b>is</b> possible, but it&#8217;s a pain and you gain almost nothing from it. The main benefits is trusting that the library you&#8217;re using really does what it&#8217;s supposed to do, but it won&#8217;t affect much the design of your code. So what you&#8217;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&#8217;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><br/></p>
<p>Even though it seems to go against what I said in the previous section, TDD is not all or nothing. It&#8217;s not a religion. </p>
<p>When you&#8217;re starting out, I encourage you to push yourself to think how you could apply TDD to situations you don&#8217;t think are possible. Once you&#8217;re experienced enough, you&#8217;ll know when to say enough is enough, and use TDD only when it actually benefits you. At that point you&#8217;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&#8217;t ever let it get in the way of that.</p>
<p><br/></p>
<p><a name="1"></a>[1] That&#8217;s actually a horrible place to apply TDD. More on that in a second. </p>
<p><a name="2"></a>[2] Usable API, simple code, unit tests, documentation, safety net for refactoring among others.</p>
]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/when-is-it-ok-not-to-tdd/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>The Always-Evolving Coding Style</title>
		<link>http://gamesfromwithin.com/the-always-evolving-coding-style</link>
		<comments>http://gamesfromwithin.com/the-always-evolving-coding-style#comments</comments>
		<pubDate>Fri, 25 Jun 2010 00:06:22 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Data-oriented design]]></category>
		<category><![CDATA[iDevBlogADay]]></category>
		<category><![CDATA[Software engineering]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://gamesfromwithin.com/?p=933</guid>
		<description><![CDATA[This is my first entry into #iDevBlogADay. It all started very innocently with a suggestion from Miguel, but the ball got rolling pretty quickly. The idea is to have one independent iPhone game developer write a blog entry each day &#8230; <a href="http://gamesfromwithin.com/the-always-evolving-coding-style">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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&#8217;s starting to seem we might have multiples per day!</em></p>
<p>Check out the new sidebar with all the #iDevBlogADay blogs. We&#8217;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&#8217;t be surprised if this once-a-week minimum turns into multiple-times-a-week.</p>
<p>&nbsp;</p>
<p><img class="alignright size-full wp-image-673" src="http://gamesfromwithin.com/wp-content/uploads/2010/06/matrix.jpg" alt="matrix.jpg" width="280" height="210" border="0" />Every developer who&#8217;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&#8217;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&#8230; 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&#8217;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&#8217;s the accumulation of lots of little changes here and there that slowly shifts things around. It&#8217;s like the movement of the Earth&#8217;s magnetic pole: very slow, but changes radically over time (although maybe just a tad bit faster).</p>
<h3>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 &#8220;good practices&#8221;. A few weeks ago I released <a href="http://gamesfromwithin.com/opengl-and-uikit-demo">some sample source code</a> and it caused a bit of a stir because it was so unconventional. That&#8217;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&#8217;m not advocating this approach for everybody, and I&#8217;m certainly not saying it&#8217;s the perfect way to go. I know that in a couple of years from now, I&#8217;ll look back at the code I&#8217;m writing today and it will feel quaint and obsolete, just like the code I wrote during <a href="http://gamesfromwithin.com/office-tools-for-starving-startups">Power of Two Games</a> looks today. All I&#8217;m saying is that this is the style that fits <strong>me</strong> best <strong>today</strong>.</p>
<h3>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&#8217;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="http://gamesfromwithin.com/backwards-is-forward-making-better-games-with-test-driven-development">Test-Driven Development</a>.</li>
<li>I&#8217;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="http://gamesfromwithin.com/simple-is-beautiful">I love simplicity</a>. I try to achieve simplicity by considering every bit of code and thinking whether it&#8217;s absolutely necessary. I get rid of anything that&#8217;s not essential, or that&#8217;s not benefitting the project by at least two or three times as much as it&#8217;s complicating it.</p>
<h3>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>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);
}</pre>
<p>The first thing that stands out is that I&#8217;m using a struct and putting related functions in a namespace. It may seem that&#8217;s just a convoluted way of writing a class with member functions, but there&#8217;s more to it than that.</p>
<p>By keeping the data in a struct instead of a class, I&#8217;m gaining several advantages:</p>
<ul>
<li>I&#8217;m showing all the data there is and how big it is. Nothing is hidden.</li>
<li>I&#8217;m making it clear that it&#8217;s free of pointers and temporary variables.</li>
<li>I&#8217;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&#8217;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&#8217;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&#8217;s very little built-in defenses against misuse and screw-ups. That&#8217;s fine because that&#8217;s not a priority for me. Right now I&#8217;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&#8217;s one of the basic approaches of <a href="http://gamesfromwithin.com/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&#8217;s great for saving the game state in memory and restoring it later (which I&#8217;m using heavily in my current project). All it takes is this line of code:</p>
<pre>oldGameState = currentGameState</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&#8217;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&#8217;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>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&#8217;t mind the added latency.</p>
<p>There&#8217;s also the question of code reuse. It&#8217;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&#8217;re not using inheritance, you can&#8217;t use polymorphism. I&#8217;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>&nbsp;</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>
			<wfw:commentRss>http://gamesfromwithin.com/the-always-evolving-coding-style/feed</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>A Day in the Life</title>
		<link>http://gamesfromwithin.com/a-day-in-the-life</link>
		<comments>http://gamesfromwithin.com/a-day-in-the-life#comments</comments>
		<pubDate>Mon, 06 Feb 2006 00:43:06 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Agile development]]></category>
		<category><![CDATA[Project management]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=340</guid>
		<description><![CDATA[High Moon Studios is an unusual company in the games industry. We'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'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. <a href="http://gamesfromwithin.com/a-day-in-the-life">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://highmoonstudios.com/">High Moon Studios</a> is an unusual company in the games industry. We&#8217;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&#8217;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.<span id="more-49"></span></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&#8217;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&#8217;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 &#8220;war room&#8221; (the room with all the task cards corresponding to user stories pinned to the wall) and we choose the task that reads &#8220;Blend ragdoll and animation,&#8221; which is part of the user story listed as &#8220;Throwing a rigid body at a character and seeing a hit reaction.&#8221; 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&#8217;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&#8217;s a tiny step, but it&#8217;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&#8217;re all working on.</p>
<p align="center"><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/42_hms/highmoon1.jpg" alt="Work hard..." hspace="10" width="500" height="289" align="middle" /><br />
<span class="caption">Work hard&#8230;</span></p>
<p><strong>9:37 AM</strong></p>
<p>I overhear Joel and Gary discussing how they&#8217;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&#8217;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&#8217;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&#8217;t implemented it in the demo yet. There&#8217;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&#8217;re confident our refactoring isn&#8217;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&#8217;m going out surfing at lunch with several of my teammates. If it&#8217;s not surfing, it&#8217;s a basketball game, cycling, running, or even yoga. If all else fails, there&#8217;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&#8217;t read since this morning because I&#8217;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&#8217;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&#8217;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&#8217;s Scrum meeting. I also worked on the physics system last week, so I&#8217;m pretty familiar with the code. In a couple of minutes we&#8217;re already making progress.</p>
<p align="center"><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/42_hms/highmoon2.jpg" alt="...rock hard" hspace="10" width="500" height="282" align="middle" /><br />
<span class="caption">&#8230; rock hard <img src='http://gamesfromwithin.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </span></p>
<p><strong>2:07 PM</strong></p>
<p>After writing several unit tests and implementing some functionality, we&#8217;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&#8217;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&#8217;s probably not caused by the code we just wrote, but we have &#8220;collective code ownership,&#8221; 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 &#8220;Oh yeah, I know what that is. I&#8217;ll fix it right now.&#8221; 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&#8217;re totally in the zone. We&#8217;ve been writing tests and code like crazy and this task is going really well. We&#8217;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&#8217;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&#8217;re almost done with the task, but not quite there yet. Even though we could stay another hour and try to finish it, we&#8217;re both quite tired by now and we&#8217;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&#8217;s no excuse to leave with a broken build.</p>
<p>While I&#8217;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&#8217;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&#8217;t keep that pace for a long time, so it&#8217;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>
			<wfw:commentRss>http://gamesfromwithin.com/a-day-in-the-life/feed</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Agile Game Development: Dealing with Chaos in the Real World</title>
		<link>http://gamesfromwithin.com/agile-game-development-dealing-with-chaos-in-the-real-world</link>
		<comments>http://gamesfromwithin.com/agile-game-development-dealing-with-chaos-in-the-real-world#comments</comments>
		<pubDate>Sun, 07 Nov 2004 04:06:34 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Agile development]]></category>
		<category><![CDATA[Project management]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=309</guid>
		<description><![CDATA[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. <a href="http://gamesfromwithin.com/agile-game-development-dealing-with-chaos-in-the-real-world">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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><span id="more-20"></span></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>
			<wfw:commentRss>http://gamesfromwithin.com/agile-game-development-dealing-with-chaos-in-the-real-world/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Simple Is Beautiful</title>
		<link>http://gamesfromwithin.com/simple-is-beautiful</link>
		<comments>http://gamesfromwithin.com/simple-is-beautiful#comments</comments>
		<pubDate>Thu, 17 Jun 2004 08:34:55 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=304</guid>
		<description><![CDATA[If you've read some of my other articles, 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. <a href="http://gamesfromwithin.com/simple-is-beautiful">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve read some of <a href="http://www.gamesfromwithin.com/?p=6 ">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><span id="more-17"></span></p>
<p><!-- Simple Is Beautiful --></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&#8217;re moving into is definitely larger than our previous condo, but it wasn&#8217;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>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&#8217;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&#8217;s very important that other people be able to understand and modify your code. True, but there&#8217;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&#8217;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&#8217;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&#8217;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&#8217;re there. The code should be simple and self-explanatory enough that should be a breeze to refactor in the future.</p>
<p><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/abstractlinks_1.jpg" alt="links (c) freeimages.co.uk" hspace="20" vspace="10" width="240" height="180" align="right" /></p>
<p>But wait, as if ease of refactoring wasn&#8217;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>
<div class="quote">
<p>&#8220;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.&#8221;</p></div>
<p>Dijkstra&#8217;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&#8217;t even implement all the required features.</p>
<p>Today, this sounds like a surprisingly modern attitude. After all, it&#8217;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>
<div class="quote">
<p>&#8220;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.&#8221;</p></div>
<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>Attaining Simplicity</h3>
<p>Great. Simple is good. How do we write “simple” code? That&#8217;s not something they teach in school and it&#8217;s not something that is pushed for in the workplace, so it&#8217;s probably not something you&#8217;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&#8217;m not saying to avoid taking advantage of language features, just the ones that can be done in another, simpler way. For example, don&#8217;t use a template when a non-templated implementation is perfectly fine. Don&#8217;t rely on a clever arrangement of variables so they&#8217;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&#8217;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&#8217;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&#8217;t cause a major loss in code simplicity. But if that&#8217;s not possible, at least defer that optimization as long as possible. Maybe you won&#8217;t need it, and maybe the code will change before then and you&#8217;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&#8217;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 src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/abstractlinks_2.jpg" alt="links (c) freeimages.co.uk" hspace="20" vspace="10" width="240" height="180" align="left" /></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&#8217;s time to get the axe out.</p>
<p>One technique I&#8217;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&#8217;re trivial to move around, promote to higher levels, etc. while member functions require some massaging to move around.</p>
<p>I&#8217;m suggesting that we keep functions small, but also that we keep classes small. We&#8217;re not going to end up with any less code than we would have before, but we&#8217;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&#8217;s a preview: Use hierarchies.</p>
<p><strong>Timings, logging, and error handling</strong></p>
<p>Ideally, I&#8217;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&#8217;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&#8217;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&#8217;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&#8217;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&#8217;s still junk that obscures the meaning.</p>
<p>Logging doesn&#8217;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&#8217;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&#8217;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&#8217;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&#8217;m afraid. This is where I&#8217;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&#8217;ll edit this article or make a new one with any great solutions I receive.</p>
<h3>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&#8217;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&#8217;ve pushed up into the program structure. Until then, keep your functions short, your classes clean, and remember The Humble Programmer:</p>
<div class="quote">
<p>&#8220;&#8230;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. &#8220;</p></div>
]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/simple-is-beautiful/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GDC 2004: Software Engineering Roundtable Summary &#8211; Session 3</title>
		<link>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-3</link>
		<comments>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-3#comments</comments>
		<pubDate>Wed, 31 Mar 2004 04:07:34 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Conferences and events]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=297</guid>
		<description><![CDATA[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 &#8220;By the Books: Software Engineering in the Games Industry&#8221; concentrated exclusively on &#8230; <a href="http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-3">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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 &#8220;By the Books: Software Engineering in the Games Industry&#8221; concentrated exclusively on languages and tools, and participants shared their favorite tools and warned others about potential duds.</p>
<p><span id="more-12"></span></p>
<p><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/gdc2004.jpg" alt="gdc2004" width="439" height="194" /><a href="http://www.gamesfromwithin.com/?p=10">Session 1</a> | <a href="http://www.gamesfromwithin.com/?p=11">Session 2</a> | Session 3</p>
<h4>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&#8217;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&#8217;s primary use was to explore other people&#8217;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&#8217;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>
			<wfw:commentRss>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-3/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GDC 2004: Software Engineering Roundtable Summary &#8211; Session 2</title>
		<link>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-2</link>
		<comments>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-2#comments</comments>
		<pubDate>Wed, 31 Mar 2004 03:28:19 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Conferences and events]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=296</guid>
		<description><![CDATA[The second session of the GDC 2004 roundtable &#8220;By The Books: Software Engineering in the Games Industry&#8221; concentrated on processes and methodologies. In particular, we had a good look at agile development and how it can be applied to game &#8230; <a href="http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-2">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The second session of the GDC 2004 roundtable &#8220;By The Books: Software Engineering in the Games Industry&#8221; 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><span id="more-11"></span></p>
<p><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/gdc2004.jpg" alt="gdc2004" width="439" height="194" /><a href="http://www.gamesfromwithin.com/?p=10">Session 1</a> | Session 2 | <a href="http://www.gamesfromwithin.com/?p=12">Session 3</a></p>
<h4>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 &#8220;<a href="http://c2.com/cgi/wiki?CodeAndFix">code and fix</a>&#8221; (or &#8220;hack and slash&#8221;, 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&#8217;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&#8217;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&#8217;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 &#8220;extra&#8221; 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&#8217;t be 2x the amount of code, but it&#8217;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&#8217;t use the words extreme programming (and certainly don&#8217;t write it eXtreme programming or you&#8217;ll be doomed! <img src='http://gamesfromwithin.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ). 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&#8217;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>
			<wfw:commentRss>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GDC 2004: Software Engineering Roundtable Summary &#8211; Session 1</title>
		<link>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-1</link>
		<comments>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-1#comments</comments>
		<pubDate>Wed, 31 Mar 2004 02:54:31 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Conferences and events]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=295</guid>
		<description><![CDATA[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 &#8230; <a href="http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-1">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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><span id="more-10"></span></p>
<p><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/gdc2004.jpg" alt="gdc2004" width="439" height="194" />Session 1 | <a href="http://www.gamesfromwithin.com/?p=11">Session 2</a> | <a href="http://www.gamesfromwithin.com/?p=12">Session 3</a></p>
<h4>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&#8217;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&#8217;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>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&#8217;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 &#8220;hit-by-a-bus syndrome&#8221; (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&#8217;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&#8217;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 &#8220;boxes and lines&#8221; 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>
			<wfw:commentRss>http://gamesfromwithin.com/gdc-2004-software-engineering-roundtable-summary-session-1/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Physical Structure and C++ &#8211; Part 2: Build Times</title>
		<link>http://gamesfromwithin.com/physical-structure-and-c-part-2-build-times</link>
		<comments>http://gamesfromwithin.com/physical-structure-and-c-part-2-build-times#comments</comments>
		<pubDate>Wed, 10 Mar 2004 18:54:11 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=293</guid>
		<description><![CDATA[For small projects, we can blissfully code away without paying any attention to physical structure and we won&#8217;t be any worse off for it. However, as a project grows, it reaches a critical point where build times become unbearably slow. &#8230; <a href="http://gamesfromwithin.com/physical-structure-and-c-part-2-build-times">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For small projects, we can blissfully code away without paying any attention to physical structure and we won&#8217;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><span id="more-8"></span></p>
<p><!--Physical Structure - Part 2: Build Times--></p>
<p>You know one of the reasons I refuse to live near most cities in the US? Traffic. I&#8217;m not talking about the &#8220;this road is crowded&#8221; type of traffic that lets you zip along at a good speed, or even about the &#8220;I can&#8217;t get out of my lane because this is so packed&#8221; type of traffic that moves slowly along. No, I&#8217;ve come to accept and deal with that. It&#8217;s the &#8220;we might as well get out of the car and enjoy the sunshine because we aren&#8217;t moving&#8221; type of traffic that I can&#8217;t stand. Amazingly enough, it seems to happen around most major cities in the US during rush hour, and sometimes this &#8220;rush hour&#8221; stretches from 7AM until 8PM. It&#8217;s a bad sign when car manufacturers have advertisements telling you how much more comfortable you&#8217;ll be in their car when you&#8217;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&#8217;re much better off walking, cycling, or using public transportation, what&#8217;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&#8217;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&#8217;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&#8217;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>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&#8217;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&#8217;s the time for a minimal build. This is what you really care about when you&#8217;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&#8217;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&#8217;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>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&#8217;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="http://gamesfromwithin.com/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&#8217;m not going to be any more specific since it wasn&#8217;t particularly good code and it had a pretty hideous physical structure). I wouldn&#8217;t be surprised if it&#8217;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&#8217;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 border="0" cellpadding="0">
<thead>
<tr>
<th colspan="2">Top included files</th>
</tr>
</thead>
<tbody>
<tr>
<td>file1.h</td>
<td align="right">10777</td>
</tr>
<tr>
<td>file2.h</td>
<td align="right">3683</td>
</tr>
<tr>
<td>file3.h</td>
<td align="right">1438</td>
</tr>
<tr>
<td>file4.h</td>
<td align="right">940</td>
</tr>
<tr>
<td>file5.h</td>
<td align="right">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&#8217;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>
<div class="code">// SomeFile.h</p>
<p>#ifndef SOMEFILE_H_<br />
#define SOMEFILE_H_</p>
<p>// Normal code goes here, even other #include statements if necessary</p>
<p>#endif</p></div>
<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&#8217;re always at the mercy of your current compiler writer. Was that true for Visual Studio .NET 2003?</p>
<p><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/hourglass_2.jpg" alt="hourglass" width="449" height="230" /></p>
<h3>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 <span style="color: #000080;"><span style="text-decoration: underline;"><a href="http://www.amazon.com/exec/obidos/ASIN/0201633620/ref=nosim/gamesfromwith-20"> Large Scale C++ Software Design by John Lakos</a></span></span> (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>
<div class="code">// Somefile.cpp</p>
<p>#ifndef SOMEFILE_H_<br />
#include &#8220;SomeFile.h&#8221;<br />
#endif<br />
#ifndef SOMEOTHERFILE_H_<br />
#include &#8220;SomeOtherFile.h&#8221;<br />
#endif</p>
<p>//&#8230;</p></div>
<p>I wrote <a href="http://gamesfromwithin.com/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&#8217;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&#8217;t think that&#8217;s possible with the standard C preprocessor.</p>
<h3>#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&#8217;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&#8217;s <a href="http://gamesfromwithin.com/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&#8217;t bother with it. It&#8217;s a non-standard construct that doesn&#8217;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>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&#8217;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&#8217;t do anything about duplicated headers found across multiple cpp files, and that&#8217;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&#8217;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&#8217;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&#8217;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 &lt;vector&gt; or &lt;windows.h&gt; included, but since a fair amount of them do and those are considered expensive includes, they&#8217;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&#8217;m aware of that implement them are <span style="color: #000080;"><span style="text-decoration: underline;"><a href="http://msdn.microsoft.com/visualc/">Microsoft&#8217;s Visual C++</a></span></span> and <span style="color: #000080;"><span style="text-decoration: underline;"><a href="http://www.metrowerks.com/MW/Develop/CodeWarrior.htm">Metrowerks&#8217; CodeWarrior</a></span></span> (although I just did a Google search and apparently <span style="color: #000080;"><span style="text-decoration: underline;"><a href="http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html">gcc also supports precompiled headers</a></span></span>&#8211;that&#8217;s great news!). For the rest of us using different compilers, we&#8217;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&#8217;ll compile at a glacial pace. That&#8217;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&#8217;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&#8217;s builds all the time. I&#8217;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&#8217;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&#8217;t support them.</p>
<h3>Single Compilation Unit</h3>
<p>This is an interesting trick that you won&#8217;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&#8217;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&#8217;re interested in. Something along these lines:</p>
<div class="code">// everything.cpp</p>
<p>#include &#8220;MyFile1.cpp&#8221;<br />
#include &#8220;MyFile2.cpp&#8221;<br />
#include &#8220;MyFile3.cpp&#8221;<br />
//&#8230;.</p></div>
<p>As you can imagine by now, I wrote <a href="http://gamesfromwithin.com/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&#8230; get ready: The build time went down from 2:32 minutes to 43 seconds! That&#8217;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&#8217;ll have include guards so there&#8217;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&#8217;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&#8217;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&#8217;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&#8217;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&#8217;s code). If so, make sure to wrap symbols in namespaces or classes.</p>
<p><a href="http://gamesfromwithin.com/wp-content/uploads/bin/analyze_includes.txt"> <img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/script.png" border="0" alt="icon" width="20" height="22" /> analyze_includes.pl</a><br />
<a href="http://gamesfromwithin.com/wp-content/uploads/bin/add_external_guards.txt"> <img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/script.png" border="0" alt="icon" width="20" height="22" /> add_external_guards.pl</a><br />
<a href="http://gamesfromwithin.com/wp-content/uploads/bin/add_pragma_once.txt"> <img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/script.png" border="0" alt="icon" width="20" height="22" /> add_pragma_once.pl</a><br />
<a href="http://gamesfromwithin.com/wp-content/uploads/bin/create_everything.txt"> <img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/script.png" border="0" alt="icon" width="20" height="22" /> 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>
			<wfw:commentRss>http://gamesfromwithin.com/physical-structure-and-c-part-2-build-times/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Physical Structure and C++ &#8211; Part 1: A First Look</title>
		<link>http://gamesfromwithin.com/physical-structure-and-c-part-1-a-first-look</link>
		<comments>http://gamesfromwithin.com/physical-structure-and-c-part-1-a-first-look#comments</comments>
		<pubDate>Fri, 05 Mar 2004 22:52:27 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=291</guid>
		<description><![CDATA[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 &#8230; <a href="http://gamesfromwithin.com/physical-structure-and-c-part-1-a-first-look">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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><span id="more-7"></span></p>
<p><!-- Physical Structure and C++ - Part 1: A First Look --></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&#8217;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&#8217;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>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&#8217;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&#8217;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&#8217;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&#8217;s standards (it&#8217;s an almost antique book in the computer world&#8211;almost 10 years!), and some parts are a bit long winded with detailed measurements. Skip those in your first read and you&#8217;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&#8217;t read it in about 3-4 years, so it&#8217;s just about due for another read.</p>
<p><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/tangle.jpg" alt="tangle (c) freeimages.co.uk" hspace="20" vspace="10" width="240" height="224" align="right" /> 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">&#8220;blob&#8221; antipattern</a>. Unfortunately, if left unchecked, this is the type of physical structure that develops over time.</p>
<h4>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&#8217;re writing a program are that it does what it&#8217;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&#8217;s no good to have a very efficient class if we can&#8217;t change it, and it&#8217;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&#8217;t have anything to remind them that they&#8217;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&#8217;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&#8217;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>Guidelines</h4>
<p>Here&#8217;s a distilled set of guidelines from Lakos&#8217; book that minimize the number of physical dependencies between files. I&#8217;ve been using them for years and I&#8217;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&#8217;re interested in and we&#8217;re guaranteed that it&#8217;ll work as is. We don&#8217;t have to play the &#8220;guess what other headers you need&#8221; 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&#8217;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&#8217;t need to include that class&#8217; 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&#8217;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&#8217;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&#8217;re most likely going to be refactoring. If left unchecked, you&#8217;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&#8217;t it be great if there was an automated tool that would check that?</p>
<h4>Automating the Guidelines</h4>
<p>I did a quick search and I couldn&#8217;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&#8217; 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&#8217;t look too deep into them, so maybe they also check for some of these guidelines, but it&#8217;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&#8217;t really have the word &#8220;quick&#8221; 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="http://gamesfromwithin.com/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&#8217;t even need a fancy parser for that. Guideline #2 is already checked by the compiler (if you don&#8217;t have enough includes, the program won&#8217;t compile). Guideline #3 is the trickiest one. Still, the script makes a valiant effort and checks for the most common cases. It&#8217;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&#8217;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&#8217;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 src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/script.png" alt="icon" width="20" height="22" /> <a href="http://gamesfromwithin.com/wp-content/uploads/bin/analyze_includes.txt">analyze_includes.pl</a></p>
<p><a href="http://gamesfromwithin.com/?p=8 ">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>
			<wfw:commentRss>http://gamesfromwithin.com/physical-structure-and-c-part-1-a-first-look/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Maintenance, The Hidden Cost of Software</title>
		<link>http://gamesfromwithin.com/maintenance-the-hidden-cost-of-software</link>
		<comments>http://gamesfromwithin.com/maintenance-the-hidden-cost-of-software#comments</comments>
		<pubDate>Sat, 03 Jan 2004 03:52:33 +0000</pubDate>
		<dc:creator>Noel</dc:creator>
				<category><![CDATA[Software engineering]]></category>

		<guid isPermaLink="false">http://www.gamesfromwithin.dreamhosters.com/?p=289</guid>
		<description><![CDATA[&#8220;Maintenance? I never do maintenance!&#8221; I hear you say. &#8220;I&#8217;m a game programmer! A coder who lives on the bleeding edge and doesn&#8217;t have to bother with boring stuff like that. That&#8217;s for stuffy database programmers, not for me.&#8221; Have &#8230; <a href="http://gamesfromwithin.com/maintenance-the-hidden-cost-of-software">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>&#8220;Maintenance? I never do maintenance!&#8221; I hear you say. &#8220;I&#8217;m a game programmer! A coder who lives on the bleeding edge and doesn&#8217;t have to bother with boring stuff like that. That&#8217;s for stuffy database programmers, not for me.&#8221;</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&#8217;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><span id="more-6"></span></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&#8217;s you who decides to implement a cool new feature you&#8217;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&#8217;s worth doing it, you quickly answer “Don&#8217;t worry. It&#8217;ll only take me a couple of hours.” Famous last words.</p>
<p>Let&#8217;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&#8217;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&#8217;re talking at least four hours instead of two. No big deal, it&#8217;s still really quick and it&#8217;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&#8217;s done. After all, you&#8217;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&#8217;s so simple that you felt no need to do any thinking before start programming) you realize that it&#8217;s going a bit slower than you thought, and the &#8220;couple&#8221; of hours quickly turn into four or five hours. Add the interruptions and other distractions we mentioned earlier to that, and we&#8217;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&#8217;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&#8217;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&#8217;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&#8217;re up to 10 hours total. Let&#8217;s keep counting.</p>
<p><img src="http://www.gamesfromwithin.com/wp-content/uploads/old_images/falling_coins.jpg" alt="coins (c) FreeFoto.com" hspace="20" vspace="20" width="200" height="300" align="right" /> 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&#8217;s working and you&#8217;re moving along. Then, one day, you&#8217;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&#8217; 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&#8217;s the curse of the programmers&#8217; computers&#8211;your code will always work flawlessly there&#8230; except when you&#8217;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&#8217;re up to 14 hours.</p>
<p>Weeks later, the story repeats itself. This time it turns out your code is too slow. &#8220;What do you mean too slow? It was very fast when I wrote it!&#8221; 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&#8217;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&#8217;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&#8217;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&#8217;ll have to update it to reflect changes to the underlying libraries, you&#8217;ll have to speed it up when its speed becomes critical, you&#8217;ll have to make modifications to it to implement the new features the artists are asking for.</p>
<p>I&#8217;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&#8217;m sure someone has already written a script to collect exactly that type of statistics, so if I get a chance I&#8217;ll try it out and I&#8217;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&#8217;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&#8217;re deciding what features to implement or whether to give the green light to a new tool.</p>
<p>What&#8217;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&#8217;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&#8217;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&#8217;re doing.</p>
<p>Sometimes we won&#8217;t know at the beginning whether we should implement something or not. If there is a chance that we don&#8217;t want or need to implement a feature, it&#8217;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&#8217;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&#8217;t know what you&#8217;ll need to do to that code in the future: maybe you&#8217;ll need to make it faster, maybe you&#8217;ll need to extend it, or maybe you&#8217;ll be lucky and you&#8217;ll just have to keep it up to date. Trying to optimize it early or make it very general before it&#8217;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&#8217;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&#8217;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&#8217;re also saving costs in the future. Those libraries are going to be debugged separately, they&#8217;re going to be improved, and most importantly, they&#8217;re going to be forcefully separated from the project itself, maximizing the independence between the two. Yes, you&#8217;ll still have to retrofit your engine to make use of any interface changes of new versions of the libraries, but it&#8217;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&#8217;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 &#8220;scaffolding&#8221; 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&#8217;re dealing with when we&#8217;re developing it though, and we should also clearly label it in some way so everybody knows it&#8217;s throwaway. That way a class labeled <code>Tmp3DView</code> won&#8217;t become deeply rooted in your tools, or will it?</p>
]]></content:encoded>
			<wfw:commentRss>http://gamesfromwithin.com/maintenance-the-hidden-cost-of-software/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

