<?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>Scientific Ninja &#187; design</title>
	<atom:link href="http://scientificninja.com/tag/design/feed" rel="self" type="application/rss+xml" />
	<link>http://scientificninja.com</link>
	<description></description>
	<lastBuildDate>Tue, 27 Jul 2010 02:58:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Thoughts on SlimDX 2: Object Lifetime</title>
		<link>http://scientificninja.com/blog/thoughts-on-slimdx-2-object-lifetime</link>
		<comments>http://scientificninja.com/blog/thoughts-on-slimdx-2-object-lifetime#comments</comments>
		<pubDate>Wed, 31 Mar 2010 02:14:32 +0000</pubDate>
		<dc:creator>Josh Petrie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[com]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[slimdx]]></category>

		<guid isPermaLink="false">http://scientificninja.com/?p=866</guid>
		<description><![CDATA[This will likely be my last post on the subject of the major changes coming in SlimDX 2 for a little while. My last few posts have focused on issues we&#8217;re fairly certain will be relevant to the new API (as will this post) &#8212; but we don&#8217;t have everything planned out yet. We have [...]]]></description>
			<content:encoded><![CDATA[<p>This will likely be my last post on the subject of the major changes coming in SlimDX 2 for a little while. My last <a href="http://scientificninja.com/blog/thoughts-on-slimdx-2-interfaces">few</a> <a href="http://scientificninja.com/blog/thoughts-on-slimdx-2-assembly-design">posts</a> have focused on issues we&#8217;re fairly certain will be relevant to the new API (as will this post) &#8212; but we don&#8217;t have <em>everything</em> planned out yet. We have a few ideas we&#8217;d like to experiment with, but we&#8217;re going to have to take some time to prototype them and mess around before we can commit to any one solution. Indeed, there are even a few unanswered questions about the topic I&#8217;m going to talk about today.</p>

<p>That topic is how we&#8217;re not going to use IDisposable any longer.</p>

<p>More specifically, we&#8217;re not going to use it <em>as much</em>. Almost every SlimDX 1 object implements IDisposable, because IDisposable is all about cleaning up unmanaged resources and SlimDX objects are, for the most part, exactly that. But the sort of resources IDisposable is geared towards are those with very explicit lifetimes: you create it, do your thing, and then Dispose() of it. C# using-blocks allow you to implement this exact pattern for locally-held objects quite efficiently.</p>

<p>Long-time readers will recall that our IDisposable wrappers around COM objects have caused us a lot of trouble in the past, largely because the interface&#8217;s contract does not really jive with COM&#8217;s reference counting. To account for this, we implemented an object table based loosely on the same principles that the <a href="http://msdn.microsoft.com/en-us/library/8bwh56xe.aspx">.NET RCW</a> uses &#8212; specifically, we tried to maintain exactly one COM reference to any object known to SlimDX so that we could do the correct thing when Dispose() was called. This eventually led us to an overly-complicated system burdened with multiple creation code paths and inconsistent ownership semantics.</p>

<p>Our solution is to, essentially, side-step the issue entirely and just expose the reference counting directly. All SlimDX 2 objects that are backed by actual COM interfaces implement IComObject, which provides the familiar-looking methods AddReference() and Release(). For the trivial scenarios where you just want quick, scoped access to a COM object, we&#8217;ll be providing a simple IDisposable utility wrapper you can use in conjunction with a using-block to automatically drop the reference count when appropriate.</p>

<p>While it first might seem like this change is a step <em>backwards</em>, we think that it&#8217;s an improvement in the long run: it obviates the need for the exceedingly complex object ownership rules that existed with SlimDX 1 (which, we suspect, most of our users were getting wrong). Plus, it makes the SlimDX ownership semantics match those of the already-familiar native API.</p>
]]></content:encoded>
			<wfw:commentRss>http://scientificninja.com/blog/thoughts-on-slimdx-2-object-lifetime/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hargreaves on Breaking Changes</title>
		<link>http://scientificninja.com/blog/hargreaves-on-breaking-changes</link>
		<comments>http://scientificninja.com/blog/hargreaves-on-breaking-changes#comments</comments>
		<pubDate>Wed, 17 Mar 2010 05:19:02 +0000</pubDate>
		<dc:creator>Josh Petrie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[slimdx]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://scientificninja.com/?p=852</guid>
		<description><![CDATA[Shawn Hargreaves has been writing about the upcoming changes in XNA 4.0 (interesting stuff). The topic is obviously one that resonates with me given my own recent posts. I particularly enjoyed this post. Back in 2007, when SlimDX was a young API, we had the luxury of having very few serious users. When we realized [...]]]></description>
			<content:encoded><![CDATA[<p>Shawn Hargreaves has been writing about <a href="http://blogs.msdn.com/shawnhar/archive/2010/03/16/breaking-changes-in-xna-game-studio-4-0.aspx">the upcoming changes in XNA 4.0</a> (interesting stuff). The topic is obviously one that resonates with me given <a href="http://scientificninja.com/blog/thoughts-on-slimdx-2">my own</a> <a href="http://scientificninja.com/blog/thoughts-on-slimdx-2-interfaces">recent</a> <a href="http://scientificninja.com/blog/thoughts-on-slimdx-2-assembly-design">posts</a>.</p>

<p><a href="http://blogs.msdn.com/shawnhar/archive/2010/03/05/backward-compatibility.aspx">I particularly enjoyed this post</a>. Back in 2007, when SlimDX was a young API, we had the luxury of having very few serious users. When we realized we&#8217;d screwed something up, we just changed it, and it didn&#8217;t matter how much that change would impact a client code. There were no clients.</p>

<p>But now, three years later, that&#8217;s no longer the case. We have quite a few users; SlimDX has been used in commercially released <a href="http://www.arcengames.com/aiwar_features.php">games</a> and <a href="http://www.ventuz.com/">applications</a>, and helps power internal content production tools used by professional studios like <a href="http://zipperint.com/">Zipper Interactive</a>. We no longer have the luxury of implementing sweeping changes on a whim, no matter how correct they may be. We have practical realities to consider: providing sufficient advance warning and documentation. Developing upgrade paths. Transitioning deprecated versions of the API to &#8220;support mode&#8221; for an appropriate period of time.</p>

<p>I believe that breaking changes are for the best when they actually improve the overall health of the API. But they&#8217;re also pretty scary.</p>
]]></content:encoded>
			<wfw:commentRss>http://scientificninja.com/blog/hargreaves-on-breaking-changes/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Thoughts on SlimDX 2: Assembly Design</title>
		<link>http://scientificninja.com/blog/thoughts-on-slimdx-2-assembly-design</link>
		<comments>http://scientificninja.com/blog/thoughts-on-slimdx-2-assembly-design#comments</comments>
		<pubDate>Sun, 14 Mar 2010 18:12:53 +0000</pubDate>
		<dc:creator>Josh Petrie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[c++/cli]]></category>
		<category><![CDATA[clr]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[slimdx]]></category>

		<guid isPermaLink="false">http://scientificninja.com/?p=834</guid>
		<description><![CDATA[SlimDX 1 is contained in a single, monolithic C++/CLI assembly. SlimDX 2 is structured differently: it is split up into both public and private DLLs. The public DLL, which will be directly referenced by client code, is written in C# and contains the definitions for all the interfaces, enumerations, et cetera. The private DLL, written [...]]]></description>
			<content:encoded><![CDATA[<p>SlimDX 1 is contained in a single, monolithic C++/CLI assembly. SlimDX 2 is structured differently: it is split up into both public and private DLLs. The public DLL, which will be directly referenced by client code, is written in C# and contains the definitions for all the interfaces, enumerations, et cetera. The private DLL, written in C++/CLI, contains the interface implementations and all our internal machinery.</p>

<p>The primary motivation for organizing the library in this fashion was to eliminate the problems with building “Any CPU” applications using SlimDX.</p>

<p>Managed applications built in “Any CPU” mode are essentially asking the CLR to load them as processes most-appropriate to the host machine: if you’re running on the x64 architecture, you get a 64-bit process. On x86, you&#8217;d get a 32-bit process.</p>

<p>For native code, however, the target architecture needs to be decided at compile-time, which is why there are distinct 32-bit and 64-bit versions of the SlimDX assembly. Unfortunately, <a href="http://blogs.msdn.com/oldnewthing/archive/2008/10/20/9006720.aspx">you cannot load a 32-bit DLL into a 64-bit process</a>.</p>

<p>If you’re using the copies of SlimDX that our installer places in the GAC, you can avoid running afoul of this problem by editing your <code>.csproj</code>. If you’re a user who prefers to reference the SlimDX DLLs themselves, you are out of luck. You have to pick a specific version to reference, and you have to set the machine type of your project to match.</p>

<p>By using a two-part distribution, we can ship a public assembly configured for “Any CPU” use. This assembly can detect whether 32- or 64-bit code would be more appropriate and load the correct private implementation DLL into your process.</p>

<p>This approach also allows us to write more of SlimDX in C#, which is far more pleasant language to work with than C++/CLI, and has a much better toolchain.</p>

<p>It also lets us improve the health of the code we do need to write in C++/CLI. Because of a peculiarity in how templates (not generics) interact with managed types, the presence of a template type anywhere in a class hierarchy results in a complete lack of IntelliSense support for that class hierarchy&#8230; but there’s a lot of redundant boilerplate code in SlimDX, exactly the kind of code one would like to use templates to write just once. We had to compromise and use macros to provide that code for SlimDX 1.</p>

<p>However, with the split-assembly approach &#8212; along with with our adoption of interfaces &#8212; the classes “polluted” by templates exist entirely in the private assembly and are never exposed by their concrete types; the lack of IntelliSense becomes a non-issue.</p>

<p>There is one small downside, unfortunately. Since the implementation DLL is loaded manually, clients who reference and ship private copies of SlimDX (that is, anyone not using the GAC version) will need to add or link the SlimDX implementation DLLs (and PDBs) in their <code>.csproj</code> files in order to allow the build system to copy those files into the directory of the built application.</p>
]]></content:encoded>
			<wfw:commentRss>http://scientificninja.com/blog/thoughts-on-slimdx-2-assembly-design/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Thoughts on SlimDX 2: Interfaces</title>
		<link>http://scientificninja.com/blog/thoughts-on-slimdx-2-interfaces</link>
		<comments>http://scientificninja.com/blog/thoughts-on-slimdx-2-interfaces#comments</comments>
		<pubDate>Sun, 07 Mar 2010 05:32:43 +0000</pubDate>
		<dc:creator>Josh Petrie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[slimdx]]></category>

		<guid isPermaLink="false">http://scientificninja.com/?p=824</guid>
		<description><![CDATA[One of the biggest changes we&#8217;re going to make in SlimDX 2 concerns our use of interface types (specifically, our lack thereof). In the current version of SlimDX, the API consists almost entirely of concrete classes. However, there are advantages to exposing interfaces instead &#8212; improved testability of the public API and code depending on [...]]]></description>
			<content:encoded><![CDATA[<p>One of the biggest changes we&#8217;re going to make in SlimDX 2 concerns our use of interface types (specifically, our lack thereof). In the current version of SlimDX, the API consists almost entirely of concrete classes. However, there are advantages to exposing interfaces instead &#8212; improved testability of the public API and code depending on it, for example, as well as the potential for some back-end improvements to code health. There are two major main concerns involved in redesigning SlimDX to use interfaces:</p>

<p>The first is the question of how one initially obtains an interface. SlimDX 1 uses the constructors of its concrete objects to enable users to obtain new instances. Thus, in SlimDX 1 you would obtain a texture instance by doing new Texture2D( device, &#8230; ). This constructor will invoke the native ID3D10Device::CreateTexture(). In SlimDX 2, we&#8217;ll present a model that mirrors the native interface more closely, with an IDevice interface that demands a CreateTexture method.</p>

<p>To handle bootstrapping &#8212; obtaining that first interface &#8212; we&#8217;ll expose so-called &#8220;API objects&#8221; that will represent each of the primary subsystems SlimDX exposes to native code (for example, there will be a Direct3D10Api object that will let you obtain the initial D3D10 device interface. These API objects will also be a convenient location to present many of the native free functions. SlimDX doesn&#8217;t expose all of these now, and the ones it does provide are often tucked away, seldom-seen static members of one class or another.</p>

<p>The other half of the problem is translating those interfaces back into concrete, usable objects when they are passed back to SlimDX for one reason or another.</p>

<p>We <em>could</em> simply downcast the interface to the concrete type, but that relies on the assumption that such a cast would always succeed &#8212; and that isn&#8217;t true in general. SlimDX has always supported interoperation with other DirectX-wrapping managed libraries, and to make the assumption that our interfaces were only ever implemented by our own library would work against that.</p>

<p>Fortunately, as a result of that interoperability feature, we&#8217;ve had to have all of our objects expose their IUnknown or similar native pointer (wrapped up in a System.IntPtr). Thus, we can rely on an accessor for that pointer being available from the interfaces, and we can use that to obtain the actual interface we&#8217;re interested in working with in the SlimDX code.</p>
]]></content:encoded>
			<wfw:commentRss>http://scientificninja.com/blog/thoughts-on-slimdx-2-interfaces/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Thoughts on SlimDX 2</title>
		<link>http://scientificninja.com/blog/thoughts-on-slimdx-2</link>
		<comments>http://scientificninja.com/blog/thoughts-on-slimdx-2#comments</comments>
		<pubDate>Thu, 04 Mar 2010 02:30:43 +0000</pubDate>
		<dc:creator>Josh Petrie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[slimdx]]></category>

		<guid isPermaLink="false">http://scientificninja.com/?p=735</guid>
		<description><![CDATA[SlimDX is has become a pretty comprehensive API, but the fact still remains that it is a version-one iteration of the product, and like all version-one iterations, it has issues. In particular, some of the more insidious bugs and poorly-considered design decisions are starting to become increasingly more uncomfortable to deal with. Since no good [...]]]></description>
			<content:encoded><![CDATA[<p>SlimDX is has become a pretty comprehensive API, but the fact still remains that it is a version-one iteration of the product, and like all version-one iterations, it has issues. In particular, some of the more insidious bugs and poorly-considered design decisions are starting to become increasingly more uncomfortable to deal with. Since no good solutions exist for some of these problems that will preserve the existing public interface, we&#8217;ve been thinking about what a version-two iteration of SlimDX will look like. There are quite a few aspects of the API we&#8217;d like to improve for the next version, and over the next few days I&#8217;m going to talk about some of them.</p>
]]></content:encoded>
			<wfw:commentRss>http://scientificninja.com/blog/thoughts-on-slimdx-2/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rethinking the SlimDX Sample Framework</title>
		<link>http://scientificninja.com/blog/rethinking-the-slimdx-sample-framework</link>
		<comments>http://scientificninja.com/blog/rethinking-the-slimdx-sample-framework#comments</comments>
		<pubDate>Tue, 16 Jun 2009 11:55:39 +0000</pubDate>
		<dc:creator>Josh Petrie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[slimdx]]></category>

		<guid isPermaLink="false">http://jpetrie.webfactional.com/?p=21</guid>
		<description><![CDATA[The SlimDX sample situation is currently pretty disorganized: some of our samples are checked in to the Subversion repository, but others are just referenced from issues in our issue tracker. Not all the samples use our internal sample framework, either, and the framework itself has a few issues. But as SlimDX becomes more and more [...]]]></description>
			<content:encoded><![CDATA[<p>The SlimDX sample situation is currently pretty disorganized: some of our samples are checked in to the Subversion repository, but others are just referenced from issues in our <a href="http://code.google.com/p/slimdx/issues/list">issue tracker</a>. Not all the samples use our internal sample framework, either, and the framework itself has a few issues. But as SlimDX becomes more and more stable, and begins to really approach complete parity with the native APIs, we have an opportunity to revisit problems like this one and clean things up.</p>

<p>In the future, our intention is to create a firm split between official and community samples. Only the former will be checked into source control. The community samples will be hosted on <a href="http://slimdx.org/">our website</a> somewhere, and when warranted we will fold appropriate community samples into the official distribution, after appropriate modification. One of the things we want to ensure is that the official samples have a uniform style (to make them easy to follow and compare) and that they meet certain quality criteria.</p>

<p>The other thing we&#8217;re going to do is refactor the sample framework itself. The current framework feels like a &#8220;mini-XNA,&#8221; which has caused some users to adopt it as a more generalized &#8220;game&#8221; framework, which is problematic for us. We do not want to be in the business of writing &#8212; more importantly, of maintaining &#8212; anything resembling an <em>engine</em>. There are other projects out there that fit that bill; SlimDX is a lightweight wrapper, and we want to preserve its minimalist ideals even across aspects of the project that are not the core library itself.</p>

<p>The <em>sample</em> framework should be about making it easy for us to build <em>samples</em>. The native SDK uses a pretty robust sample framework, and we&#8217;ve seen that hamper it as an educational tool. When the sample is trying to demonstrate some concept or technique, it should demonstrate that in the language of the API itself. API calls should be used as often as is reasonable in order to demonstrate &#8216;<a href="http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html">the simplest thing that could work</a>,&#8217; which is usually what a user is looking at the sample code <em>for</em>.</p>

<p>Basically, we want a relative lack of abstraction. Users are just going to peel away the abstraction layers anyway, so we&#8217;d just be creating more work for them.</p>

<p>It&#8217;s still going to be a framework, though! We&#8217;re still going to wrap the creation of the primary window and the &#8216;game loop,&#8217; and we&#8217;ll provide extensibility points allowing a sample to customize the main phases of application execution: pre-initialization configuration, initialization and resource load, logic update, render update, and shutdown/cleanup. Simplifying such boilerplate code, code that is not directly related to the primary tasks one would use SlimDX for, is perfectly acceptable.</p>

<p>Similarly, we&#8217;ll probably wrap mesh loading (especially since there is no built-in method for creating <a href="http://msdn.microsoft.com/en-us/library/bb173897(VS.85).aspx">ID3DX10Mesh</a> objects from a file, and we&#8217;d like to use the same source assets when possible for homogeneity) and similar ancillary operations.</p>

<p>UI is another interesting issue. The native sample framework supports a simple collection of UI controls for tweaking parameters for a sample. I&#8217;d rather not implement (and thus maintain) a similar system in SlimDX, but the alternative of using Windows Forms controls means that tweaking won&#8217;t be available in samples running in fullscreen mode, which is a deal-breaker. So we&#8217;ll support a small set of basic controls useful for tweaking parameter values in the new framework as well.</p>

<p>These framework changes probably won&#8217;t make it into the next release (if indeed the next release is this month, as we suspect), but you should see them in the release immediately following that at the latest&#8230; as well as some other interesting changes. And of course, you can always live on the bleeding edge and work from <a href="http://code.google.com/p/slimdx/source/list">the head of our repository</a>.</p>

<p>In other SlimDX news, <a href="http://www.arcengames.com/">Arcen Games, LLC</a> recently released AI War: Fleet Command. I&#8217;ve posted about this on Twitter already, and SlimDX lead <a href="http://ventspace.wordpress.com/2009/06/15/highlight-ai-war/">Promit Roy has beaten me to the punch on a blog post</a>, but I&#8217;ll repeat it here for the benefit of other readers: AI War is the first game available for purchase that was built using SlimDX! This is <em>very</em> cool. Developer <a href="http://christophermpark.blogspot.com/2009/06/choosing-directx-platform-in-c.html">Chris Park has written about</a> his experience evaluating rendering solutions for C# projects, explaining how he ultimately chose SlimDX&#8230; head over and give his blog a read, and when you&#8217;re done, be sure to check out the game itself!</p>
]]></content:encoded>
			<wfw:commentRss>http://scientificninja.com/blog/rethinking-the-slimdx-sample-framework/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Write Games, Not Engines</title>
		<link>http://scientificninja.com/blog/write-games-not-engines</link>
		<comments>http://scientificninja.com/blog/write-games-not-engines#comments</comments>
		<pubDate>Thu, 30 Aug 2007 21:53:11 +0000</pubDate>
		<dc:creator>Josh Petrie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[good practice]]></category>

		<guid isPermaLink="false">http://jpetrie.webfactional.com/?p=8</guid>
		<description><![CDATA[To begin with, the term &#8220;engine&#8221; (specifically as it related to the game development world) has no strict definition. Therefore, in the interests of keeping everybody on the same page, I&#8217;ll define the term as I intend to use it in this article. An &#8220;engine&#8221; is a collection of robust, reusable software subsystems (possibly including [...]]]></description>
			<content:encoded><![CDATA[<p>To begin with, the term &#8220;engine&#8221; (specifically as it related to the game development world) has no strict definition. Therefore, in the interests of keeping everybody on the same page, I&#8217;ll define the term as I intend to use it in this article. An &#8220;engine&#8221; is a collection of robust, reusable software subsystems (possibly including both code libraries and tools) designed to facilitate the development of actual games by addressing specific requirements. The requirements tend to be broadly-defined: rendering, audio, physics, et cetera. Particularly ambitious engines that address multiple broad requirement groups tend be to known as &#8220;game engines&#8221; rather than just &#8220;graphics engines&#8221; or &#8220;physics engines.&#8221;</p>

<p>Now that that&#8217;s out of the way, let&#8217;s turn to the real issue: how to build engines, and more specifically, if you should even bother.</p>

<p>For any number of reasons, many neophyte game developers (and even some moderately experienced ones) seem to think that a game engine is a required, critical part of a game. They think that &#8212; in keeping with the mechanical analogy from which the term &#8220;engine&#8221; comes from in the first place &#8212; like a car, a game with no engine will simply not run. But that mechanical analogy starts to break down when you take it this far, because when you look at the reality of the situation, a game engine is about <em>reusable</em> components. Much like you can build a car with custom parts or generic ones, you can build a game with custom components or reusable ones. The fact that you must have an engine to build a non-trivial game is a fallacy, something perpetuated largely by people who don&#8217;t know any better.</p>

<p>Nonetheless, every so often comes the obligatory post on <a href="http://www.gamedev.net/community/forums">GDNet</a> by somebody who has decided its time for them to write <em>their</em> engine, so they can start making some <em>real</em> games. These posts usually consist of requests for resources about the engine design and development process, and in fact chances are that if you&#8217;re reading this, it&#8217;s because I caught you making just such a post and linked you here so that I could crush your dreams with a minimum of effort on my part.</p>

<p>So my advice to you, if you&#8217;re trying to write an engine, is: <em>Don&#8217;t</em>. No matter what your reasons are &#8212; it doesn&#8217;t matter if you&#8217;re writing an engine so you can write your dream game, or if you&#8217;re writing an engine because you think it will be a good learning experience, or any number of similar reasons. They&#8217;re all wastes of time. You can sit down and write a game without writing a pre-written engine, and in fact this is very often the better approach, regardless of why you want to write an engine. The entire development process goes <em>much</em> more smoothly if you are focused on writing a <em>game</em> instead: a game is much easier to identify requirements for, much narrower in focused, much more rewarding when finished, and much, much more useful.</p>

<p>Most hobby developers who &#8220;finish&#8221; an &#8220;engine&#8221; that was designed and built in isolation (with the goal of having an engine, not a game, upon completion) can&#8217;t ever actually use it, and neither can anybody else. Since the project didn&#8217;t have any goals, any boundaries, or any tangible applications, it essentially attempted to solve aspect of the chosen problem space and consequently failed miserably. These &#8220;engines&#8221; tend to be little more than an inconsistent and messy amalgamation of random functionality that isn&#8217;t terribly practical, robust or reusable. Furthermore, the actual viewable end product of these &#8220;engines&#8221; tend to be a cute little map (loaded from one of the popular BSP formats) you can run around in and observe some cute little models (also loaded from a popular model format) rendered with some fairly basic lighting effects (maybe some per-pixel normal mapping or parallax mapping). Maybe you might even see some collision detection or animation. These projects are just tech demos, and not particularly compelling ones at that. There is nothing to them, and they feel rather flimsy and inflexible.</p>

<p>The solution, even if you <em>really</em> want to make an engine, is to make a <em>game</em> instead. I can hear you crying out in protest from here, but just bear with me for a minute. The game does not have to be an epic production. It does not have to be GTA5, Quake 17, the next Elder Scrolls game, or a WoW-killer. It just has to be a <em>game</em>, with well-defined (and ideally well-thought-out) gameplay and well-defined developmental scope. A game is much easier to identify requirements for, as I&#8217;ve already mentioned, and it is also a practical application of those requirements. Once you have made one game, make another. Then another. Each time you start a new project, you should identify functionality that could be used and pull it out into a common library of base code. You&#8217;ll probably have to refactor some of your code to remove explicit dependencies on other code or data that is game specific, but this is a <em>good</em> thing. It will help you generalize what is generalizable in a way that you can still test the generalized functionality against your finished game and confirm that it still works (obviously you might have to modify some game-specific code to adapt to the increased generality, as well).</p>

<p>If you repeat this process long enough, after a few games you&#8217;ll have the beginnings of a solid collection of reusable functionality that has been <em>proven</em> to have practical applications. You&#8217;ll also have a set of far more interesting demonstration applications that could also double as test harnesses for your engine. This method of growing an engine (rather than manufacturing it from whole cloth) is superior because it helps you shape your goals, it forces you to actually <em>think</em> about the problems you will face and their practical implementations, it forces you to think about the separation between the domain-specific logic of the engine and the game. It makes you learn from your mistakes rather than pretend that mistakes cannot be made.</p>
]]></content:encoded>
			<wfw:commentRss>http://scientificninja.com/blog/write-games-not-engines/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Rewrite or Refactor</title>
		<link>http://scientificninja.com/blog/rewrite-or-refactor</link>
		<comments>http://scientificninja.com/blog/rewrite-or-refactor#comments</comments>
		<pubDate>Tue, 28 Aug 2007 21:48:16 +0000</pubDate>
		<dc:creator>Josh Petrie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[good practice]]></category>
		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://jpetrie.webfactional.com/?p=3</guid>
		<description><![CDATA[Often, inexperienced programmers will reach a point where they decide that their existing code base is fatally flawed in some way. Perhaps they&#8217;ve learned some new techniques that cannot be cleanly integrated into the code, perhaps they&#8217;ve stumbled across a requirement they cannot address, or perhaps they simply don&#8217;t like the naming conventions they used. [...]]]></description>
			<content:encoded><![CDATA[<p>Often, inexperienced programmers will reach a point where they decide that their existing code base is fatally flawed in some way. Perhaps they&#8217;ve learned some new techniques that cannot be cleanly integrated into the code, perhaps they&#8217;ve stumbled across a requirement they cannot address, or perhaps they simply don&#8217;t like the naming conventions they used.</p>

<p>Whatever the reason, the programmer will often decide that the solution is a complete re-write of her code base. &#8220;This time,&#8221; she says, &#8220;I&#8217;ll get the design right the first time! My new code will be better, cleaner, more robust, more generic, and overall more powerful and less buggy!&#8221;</p>

<p>Unfortunately, rewriting your code from scratch is very often a bad idea. A developer who is uncomfortable with the state of her code should <em>refactor</em> it, not <em>rewrite</em> it. The key difference between the two is that <a href="http://c2.com/cgi/wiki?WhatIsRefactoring">refactoring is about making many, usually small, iterative changes to the existing code</a> in order to make the old implementation conform to a new design. Ideally, one would preserve the ability for the code to compile, run, and/or be consumed by client code as much as possible, within reason (adopting a new design may, of course, involve breaking the public interface of the subsystem).</p>

<p>Why is refactoring better? Refactoring actually forces you to <em>think about</em> the problems. It forces you to look at the current design, the current problems you have with that design, and what you could do to address those problems. When you don&#8217;t think about the problem, and choose instead to nuke the entire subsystem from orbit and rebuild from scratch, you&#8217;re probably just going to make the same mistakes again; you&#8217;re rewrite will most likely be superficially different from the original (for example, you might have more consistent or different looking naming conventions), but nothing more. Refactoring allows you to learn from your mistakes. Rewriting just blissfully ignores your mistakes, all but ensuring history will repeat itself.</p>

<p>Refactoring is an important skill to master. In the real world, full-on rewrites of existing subsystems are almost never cost-effective, so refactoring ends up being the only real sane option.</p>
]]></content:encoded>
			<wfw:commentRss>http://scientificninja.com/blog/rewrite-or-refactor/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
