<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Pandemonium</title>
	<atom:link href="http://bittermanandy.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://bittermanandy.wordpress.com</link>
	<description>My game, XNA, game development, and the games industry</description>
	<lastBuildDate>Mon, 13 Apr 2009 15:38:53 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='bittermanandy.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/e770a86e6b333c1e95f72d9b161e5d7a?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Pandemonium</title>
		<link>http://bittermanandy.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://bittermanandy.wordpress.com/osd.xml" title="Pandemonium" />
		<item>
		<title>How not to render 3D graphics</title>
		<link>http://bittermanandy.wordpress.com/2009/04/13/how-not-to-render-3d-graphics/</link>
		<comments>http://bittermanandy.wordpress.com/2009/04/13/how-not-to-render-3d-graphics/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 15:38:53 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/2009/04/13/how-not-to-render-3d-graphics/</guid>
		<description><![CDATA[Heh. Just had to link this because I&#8217;ve been there too many times! I think I&#8217;ve probably encountered most of these:
http://dmalcolm.livejournal.com/2433.html
&#8230; with the addition of &#8220;you&#8217;re using XNA and have forgotten it&#8217;s a right-handed coordinate system&#8221;, thanks to Parm for reminding me of that one!
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=130&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Heh. Just had to link this because I&#8217;ve been there too many times! I think I&#8217;ve probably encountered most of these:</p>
<p>http://dmalcolm.livejournal.com/2433.html</p>
<p>&#8230; with the addition of &#8220;you&#8217;re using XNA and have forgotten it&#8217;s a right-handed coordinate system&#8221;, thanks to Parm for reminding me of that one!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/130/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=130&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2009/04/13/how-not-to-render-3d-graphics/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
		<item>
		<title>A View to a Thrill, Part One: Camera Concepts</title>
		<link>http://bittermanandy.wordpress.com/2009/04/10/a-view-to-a-thrill-part-one-camera-concepts/</link>
		<comments>http://bittermanandy.wordpress.com/2009/04/10/a-view-to-a-thrill-part-one-camera-concepts/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 19:19:52 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Games Development]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=126</guid>
		<description><![CDATA[I think it&#8217;s about time I wrote another article, don&#8217;t you?
The funny thing is that I&#8217;ve had a draft sitting half-completed for a few weeks now, and this isn&#8217;t it! In that draft, I&#8217;ve written about some nice (some may say, essential) features for your development tools, because that&#8217;s what I&#8217;ve been working on for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=126&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>I think it&#8217;s about time I wrote another article, don&#8217;t you?</p>
<p>The funny thing is that I&#8217;ve had a draft sitting half-completed for a few weeks now, and this isn&#8217;t it! In that draft, I&#8217;ve written about some nice (some may say, essential) features for your development tools, because that&#8217;s what I&#8217;ve been working on for Pandemonium lately. However, a <a href="http://forums.xna.com/forums/t/28925.aspx">post</a> on the <a href="http://forums.xna.com/forums/">XNA Creators Forums</a> the other day caught my eye, and reminded me of when I used to work on the in-game camera for <a href="http://www.xbox.com/en-US/games/k/kameo/">Kameo</a>, and then I put the disc in my 360 for old-times&#8217; sake, and that inspired me to start this mini-series on third person cameras, based on what I learned during the development of that game. (I&#8217;ll almost certainly finish the tools article next, then come back to this mini-series, and so on like that for a while, dipping in an out of each. Note that I don&#8217;t promise this mini-series will finish, or even progress, quickly! But over time, it should add up to have some pretty cool ideas).</p>
<p>Incidentally, for those of you who haven&#8217;t played it, you can almost certainly pick up Kameo in the bargain bin nowadays and it&#8217;s well worth a look. It&#8217;s not without its flaws (some of the adventure sequences are a bit dull and the story doesn&#8217;t always make complete sense), but it&#8217;s still one of the most vibrant and refreshing titles available on the Xbox 360. The combat sequences are pretty good fun, it&#8217;s got some really memorable bosses, a phenomenal <a href="http://www.amazon.co.uk/Kameo-Elements-Power-Steve-Burke/dp/B000BKSJ2K/ref=sr_1_1?ie=UTF8&amp;s=music&amp;qid=1239379363&amp;sr=8-1">soundtrack</a>, and (especially given that it was a launch title) it looks <a href="http://uk.xbox360.ign.com/dor/objects/490038/kameo-elements-of-power/images/kameo-elements-of-power-20050517092429146.html?page=mediaFull">very pretty</a> &#8211; I defy anyone not to watch dawn break over the <a href="http://uk.xbox360.ign.com/dor/objects/490038/kameo-elements-of-power/images/e3-2005-kameo-screen-20050517002126868.html?page=mediaFull">Enchanted Kingdom</a> and not go &#8220;wow&#8221;. It got some criticism at the time for being a bit short for the money, but by criminy it&#8217;s <a href="http://www.amazon.co.uk/Kameo-Elements-Power-Xbox-360/dp/B0000A1OU4/ref=sr_1_1?ie=UTF8&amp;s=videogames&amp;qid=1239379280&amp;sr=8-1">eight quid on Amazon</a> now! Probably even cheaper somewhere else. Get involved.</p>
<p><strong>The Very Beginning</strong></p>
<p>Anyway with that bit of blatant and shameless advertising out of the way, let&#8217;s talk cameras, starting at the very beginning. The camera is what shows the player what is going on in any 3D game. The player never sees it, and they can&#8217;t always control it, but without it you&#8217;d be stuck. It is exactly analogous to a movie camera &#8211; it&#8217;s there to show the audience (the player) what the actors (the player&#8217;s avatar and other in-game characters) are doing. Everything in the game world that you see on the screen, you see from the camera&#8217;s point of view.</p>
<p>The mapping from the 3D game world to your 2D television screen is called a projection; I won&#8217;t go too deeply into the maths just yet (and in fact in XNA, DirectX, OpenGL and other 3D SDKs, functions exist to perform much of the maths for you) but basically a projection transforms a 3D vector in world space to a 2D vector in screen space. Fundamentally speaking there are two types of projection (hence, two types of game camera).</p>
<p>An <em>Orthographic</em> camera performs a <a href="http://developer.apple.com/documentation/QuickTime/QD3D/qd3dcameras.6.htm">parallel projection</a>. Basically, this has the effect that something 2 metres tall 100 metres away, looks the same size on screen as something 2 metres tall 5 metres away, and the viewer can only tell which is closer by seeing which is drawn in front of the other. This is <a href="http://www.youtube.com/watch?v=GmU_q5xrnto">not how we are used to seeing the real world</a>, so isn&#8217;t much used in games nowadays. That said, the old <a href="http://members.chello.at/theodor.lauppert/games/sc_2000.htm">isometric games</a> show what an orthographic projection looks like (even if they&#8217;re not truly rendered in 3D), and it&#8217;s sometimes used for user interfaces, maps and such like. In fact &#8211; if you&#8217;ve ever used a 3D modelling tool like Max, Maya, Milkshape, Blender etc., you&#8217;ve almost certainly used an orthographic projection in the &#8220;side-on&#8221; or &#8220;top-down&#8221; views. I won&#8217;t go into too much detail about these here though; if you&#8217;re interested, look up Matrix.CreateOrthographic in the XNA documentation.</p>
<p>Much more common in games is the <em>Perspective </em>camera, and that&#8217;s the type of camera I&#8217;m going to concentrate on in this series. In this projection, items closer to the camera are drawn much larger than items the same size that are further away, which matches human eyesight.</p>
<p><strong>The Perspective Projection</strong></p>
<p>We need to know a certain amount of information in order to be able to perform the perspective transformation. First is the <em>field of view</em>. This value represents how wide an angle the camera can see, and by convention is usually given as the vertical angle &#8211; the <em>vertical field of view</em>, or sometimes abbreviated to <em>fovY</em>. (Some modelling tools use the horizontal field of view instead, so be careful). Next is the <em>aspect ratio</em>. Computer screens are rarely square, and never circular (like the human eye can see), so the aspect ratio gives the width of the projection compared to the height of the projection.</p>
<p>Deciding on what values to use will depend on your game, but as a starting point, consider that the human eye has something like a 150 degree vertical field of view, and an aspect ratio of something like 1.15, ie. you can see more horizontally than vertically. However &#8211; nobody ever sits so close to a computer screen that it fills their entire field of view, and the angle from your eye to the top and bottom of your monitor is usually something like 45 degrees, so that&#8217;s a good starting point for your field of view; and the aspect ratio is easy. If your monitor or television is &#8220;standard&#8221; 4:3, the aspect ratio is 4/3 = 1.3333, while if it&#8217;s &#8220;widescreen&#8221; 16:9, the aspect ratio is 16/9 = 1.7777, etc. (And therefore, if the camera view only fills part of the screen in your game, the aspect ratio will simply be the width of the view window divided by the height). We&#8217;ll talk more later about what effect changing these values has &#8211; you can get some desirable special effects, and some undesirable bugs, by altering them.</p>
<p><strong><em>Important note:</em></strong> I&#8217;ve used degrees for the field of view above, because that&#8217;s what most people are familiar with. Most 3D systems, including XNA, use radians for angles instead &#8211; and if you get funny results, it&#8217;s probably because you&#8217;re using the wrong units! You can use MathHelper.ToRadians to convert from degrees to radians, or some special values have predefined constants, for example 45 degrees is the same as MathHelper.PiOver4 radians.</p>
<p>There&#8217;s a couple more values needed for a perspective projection but, unlike field of view and aspect ratio, they don&#8217;t have a counterpart in the real world. Your eyes can see things right next to them, even touching them (I had a wasp walk over my eye, once &#8211; it was terrifying!) and, if nothing gets in the way and the light has time to get to you, infinitely far away as well. That gives an infinitely large range &#8211; and computers are very bad at handling infinity. To make life easier for the computer, we define a minimum and maximum distance &#8211; the <em>near clip</em> and <em>far clip</em> values &#8211; outside of which, we don&#8217;t want to draw anything. Choosing these values is very much game-dependent. In a game where a human is the main character, a near clip of 0.1 metres and a far clip of 1000 metres might be OK. In a game based around spaceships travelling light years in a few seconds, that wouldn&#8217;t work! Again, there is a relationship between the near clip and far clip distances that you don&#8217;t want to get wrong, and we&#8217;ll talk about that later.</p>
<p>I like to think of this as being like sitting in a dark room with one window. You sit in the room and look out. You can&#8217;t see anything in the room, it&#8217;s too dark (even if there&#8217;s something between you and the window &#8211; yeah, the analogy breaks a bit there) so the distance between you and the window is the near clip distance. Outside the room, you can only see things that pass behind the window &#8211; anything in the vertical field of view (the angle between your eyes and the top and bottom of the window) and the field of view modified by the aspect ratio (the ratio of the width of the window divided by the height. In your imagination, draw a line from your eye to the edges and corner of the window. Can you see that this would form a pyramid? Now extend the lines, out into the world beyond the window. Stop at your far clip distance. Now you have a really big pyramid. Take off the smaller pyramid (inside the room) and you&#8217;re left with a shape called a <em>frustum</em>, in this case, a <em>view frustum</em>. Everything inside this frustrum can be seen through the window &#8211; so everything in the view frustum in your game will be drawn to the screen. It looks a lot like the red shape shown here (based on original diagram <a href="http://www.cs.ucl.ac.uk/research/equator/papers/Documents2002/Jean-Daniel_Nahmias/Massive%20Model%20Rendering%20htm_files/image006.jpg">here</a>):</p>
<div id="attachment_128" class="wp-caption aligncenter" style="width: 563px"><img class="size-full wp-image-128" title="View Frustum" src="http://bittermanandy.files.wordpress.com/2009/04/image006.jpg?w=553&#038;h=288" alt="The view frustum of a perspective projection" width="553" height="288" /><p class="wp-caption-text">The view frustum of a perspective projection</p></div>
<p>(Note, I&#8217;ve not shown the horizontal field of view, it should be obvious. However, the maths to calculate it isn&#8217;t&#8230; it&#8217;s not fovY * aspectRatio, as you might guess. It&#8217;s actually 2 * atan( tan( fovY/2) * aspectRatio ), for reasons of geometry. Aren&#8217;t you glad you wondered, now?)</p>
<p>The maths to perform the projection from items in the frustum onto the screen is a bit complicated, luckily, it&#8217;s all done with Vector3&#8217;s and Matrix&#8217;s, and XNA provides a function to generate the <em>projection matrix</em> (which performs the transformations of your perspective projection): Matrix.CreatePerspectiveFieldOfView, which takes as arguments the field of view, aspect ratio, near clip, and far clip, exactly as just described.</p>
<p><strong>Defining the Camera View</strong></p>
<p>So now we know how a view frustum performs a projection to draw things in the game world, onto the screen. But which things? Or to put it another way: how do we position the view frustum to show what we want? Answer: by defining the position and orientation of the camera.</p>
<p>It&#8217;s pretty obvious what the position means. If it were a &#8220;real&#8221; camera, like in a movie, it&#8217;s the point in space where the camera (or perhaps more specifically, the camera lens) is. You just need to make sure you put it somewhere sensible so the player can see what&#8217;s going on. (How? We&#8217;ll get to that!)</p>
<p>The orientation is fairly straightforward too. It&#8217;s the direction the camera is looking in &#8211; this gives us the camera&#8217;s <em>forward vector</em>, literally, the direction you&#8217;d move in to make the camera go forward. Obviously, you&#8217;ll want this to point at whatever the player wants to see, and again, we&#8217;ll talk about how later&#8230; Of course, you can hold a camera upside down (and, if you&#8217;re making a flight sim, your planes can fly upside down!) so we also need to know which way up the camera is being held: the <em>up vector</em>. Finally, it&#8217;s sometimes useful to know the <em>right vector</em> &#8211; think of your head. Your eyes are looking in front of you (the forward vector), the top of your head is usually towards the ceiling, unless you&#8217;re doing yoga or something (the up vector), so the right vector is pointing out of your right ear. These three vectors are mutually orthogonal, which is a posh way of saying there&#8217;s ninety degrees (or MathHelper.PiOver2 radians!) between each of them. (See diagram <a href="http://www.petesqbsite.com/sections/express/issue2/3d/images/right.gif">here</a>).</p>
<p> The tricky bit comes in deciding how to represent the orientation. (It&#8217;s important to understand the following are all different <em>representations</em>, and for any given orientation, it&#8217;s possible to represent it in any of the following ways). We can either simply pick a point in space, and say &#8220;the camera is looking at this point&#8221; &#8211; this is the <em>target</em> or <em>look-at point</em>.</p>
<p>Or, we can assume that the &#8220;natural&#8221; orientation of a camera is for the forward vector to be looking down the Z axis (known as -Z, -Vector3.UnitZ, or Vector3.Forward &#8211; remember XNA uses a right-handed coordinate system!) and the up vector is directly upward (known as +Y, Vector3.UnitY, or Vector3.Up). Of course this implies that the right vector is along the X axis (+X, Vector3.UnitX, or Vector3.Right). From this &#8220;natural&#8221; orientation, we can rotate it &#8211; either using <a href="http://www.qfom.com.au/images/three_axes.gif">angle values</a> for yaw (rotating horizontally around the Y axis), pitch (rotating vertically around the X axis), and roll (rotating side to side around the Z axis), known as <em>Euler angles</em> (pronounced &#8220;oiler&#8221;), or by using a single Quaternion value. Each of these methods &#8211; Euler and Quaternion &#8211; have advantages and disadvantages (Euler is easy to understand, but can encounter issues in certain orientations that quaternions, to all intents and purposes, don&#8217;t) and which to use depends on your game. If you&#8217;re making a flight sim or other game in which the camera can roll a lot, use quaternions. Otherwise, either can be made to work, and Euler angles are certainly easier to conceptualise.</p>
<p>We can combine the position and orientation into a single v<em>iew matrix</em> for convenience, and no prizes for guessing that XNA makes it easy, via Matrix.CreateLookAt, Matrix.CreateFromYawPitchRoll, and Matrix.CreateFromQuaternion.</p>
<p>Our projection matrix and view matrix now tell us everything we need to know. When we went to draw something, we pass these matrices to the shader (sometimes along with the World matrix, which represents how the game world or object being drawn is transformed; in the case of the game world, it is usually Matrix.Identity) and it performs the complex transformation maths for us. Note that the projection matrix might not change much during gameplay, but that the view matrix might change in every frame that the camera moves.</p>
<p>So all that&#8217;s left is to work out where to put the camera, ie. what values to pass in, in order to get the appropriate view matrix. Should be easy! Right? Well&#8230; the number of games reviews where I&#8217;ve read &#8220;game X has a really bad camera&#8221;, and the fact I spent probably 40% of my time for three years coding Kameo&#8217;s camera (happily no reviews I saw complained about it), suggest it&#8217;s not that simple. (Don&#8217;t get too scared. Kameo had 11 player characters and over 20 camera modes. Your game will probably be a lot simpler!) So how can we decide where to position the camera?</p>
<p><strong>Deciding the Camera Position</strong></p>
<p>At a very high level, there are basically three ways to decide how to position and orientate the camera, and they arise from the way that in most cases, you either have something you want to look at, or somewhere you want to look from, or both. (If you have <em>neither</em>, and don&#8217;t know where you are or what you want to look at, well, good luck with that!).</p>
<p>First consider the case where you know where the camera is, but you don&#8217;t know what you want to look at, just a direction. The most obvious example of this is the first-person shooter. The camera is inside the player character&#8217;s head, and the player decides in which direction to look and move. Or, imagine a driving game or flight sim where the camera is placed inside the car or plane, looking out of the front window. This kind of camera is very simple: the position is known, and you can use Matrix.CreateFromYawPitchRoll (for example in a FPS) or Matrix.CreateFromQuaternion (for example in a flight-sim interior camera) to work out the rest of the view matrix.</p>
<p>Example: <a href="http://www.gamershell.com/static/screenshots/338/124589_full.jpg">Halo</a>.</p>
<p>Secondly, imagine you know where the camera is, and also know what to look at. An example might be a track-side camera in a racing game: it&#8217;s fixed in position, but as a car races past it turns to follow it. Or, imagine a security camera that follows the player (a bit like in Ico). It&#8217;s even easier if the camera is fixed in both position and orientation, like in the early Resident Evil games. Again, this kind of camera is very simple: the position is known, and you can use Matrix.CreateLookAt to work out the rest. (Of course, track-side cameras should have some inertia to follow the cars more naturally, and the camera in Ico has quite a few more complex features as well, but the basic functionality is very straightforward).</p>
<p>Example: <a href="http://blog.brokenfunction.com/wp-content/uploads/2006/11/ico-screenshot.jpg">Ico</a>.</p>
<p>The final category (and by far the most interesting) is where you know what you want to look at, but not the position you want to look at it <em>from</em>. Many game genres fall into this category.</p>
<p>Sometimes, it&#8217;s fairly easy to work out where the camera should be. In an arcade racing game, the obvious target is the player&#8217;s car; and the player will want to see where they are driving. So, you need to position the camera somewhere behind and above the car, looking somewhere in front of it. Of course, you&#8217;ll want the camera to follow the car as it turns, and if the player reverses into a wall you need to make sure the camera doesn&#8217;t go on the other side of the wall, but still, this is pretty straightforward. (An example from a non-racing game might include the early Tomb Raiders, and I think the Gears of War over-the-shoulder camera probably belongs here as well).</p>
<p>Example: <a href="http://regmedia.co.uk/2007/12/27/drink_campaign_big.jpg">Project Gotham Racing 4</a>.</p>
<p>Another example of this category is to be found in the RTS genre. Here, the camera looks at the units or terrain the player is interested in, but the player can control where it looks at them from. Assuming you position the camera high enough not to bump into buildings and trees, again, this is quite straightforward &#8211; store the look-at point and move it around the battlefield, then let the player control the angle they want to view it from, and position the camera a fixed distance in that direction.</p>
<p>Example: <a href="http://pcmedia.gamespy.com/pc/image/article/640/640099/age-of-empires-iii-20050808050509699-000.jpg">Age of Empires 3</a>.</p>
<p>So finally we come to the most interesting cameras of all, and the ones I will be concentrating on in this mini-series: the third-person camera. In games of this kind, the camera and the player are controlled independently. The camera must move around the game world, giving a good view of the player character, while moving around and among the terrain the player moves around and among. There are some very difficult (and hence interesting) problems to overcome &#8211; how do you stop the camera going through walls? How do you ensure there is always a good view of the player? To what extent should you let the player control the camera position &#8211; and even more importantly, to what extent should you <em>require</em> them to? Games with cameras like this include platformers, like Mario or Banjo Kazooie; parkour-style action games like Prince of Persia; and adventures or RPGs like Fable, or, of course, Kameo.</p>
<p>Check out <a href="http://media.teamxbox.com/games/ss/481/1089251603.jpg">this screenshot</a> of Kameo in action. She&#8217;s standing among the tall grass now, cheekily glancing back at the camera &#8211; but she could move in any direction and the camera would have to follow her. She could go for a swim, run around the tree, move right up to the edge of the cliff, go into the house; climb to the very top of the castle and jump off it. No matter what she does, the camera has to follow her, and show her doing it in a way the player can understand and react to. That&#8217;s not easy! But it <em>is</em> absolutely fascinating. I hope this series will demonstrate that, and you&#8217;ll find it entertaining and useful.</p>
<p>Anyway I&#8217;m moving house next week &#8211; so not sure when the next update will be &#8211; so, until next time, farewell from me&#8230;!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/126/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=126&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2009/04/10/a-view-to-a-thrill-part-one-camera-concepts/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>

		<media:content url="http://bittermanandy.files.wordpress.com/2009/04/image006.jpg" medium="image">
			<media:title type="html">View Frustum</media:title>
		</media:content>
	</item>
		<item>
		<title>Mean salary</title>
		<link>http://bittermanandy.wordpress.com/2009/02/09/mean-salary/</link>
		<comments>http://bittermanandy.wordpress.com/2009/02/09/mean-salary/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 13:06:26 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Games Industry]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=121</guid>
		<description><![CDATA[Just a quickie&#8230; interesting follow up to my recent article, which was followed by some comments about salaries in the games industry.
Develop have got their annual survey salary out, and list the following:
Average Yearly Salaries:
Lead Programmer &#8211; £41,250
Programmer &#8211; £25,810
Junior Programmer &#8211; £18,928
A few thoughts spring to mind:
1. Wow. Now I remember why I left [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=121&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Just a quickie&#8230; interesting follow up to my <a href="http://bittermanandy.wordpress.com/2008/12/10/the-masonic-handshake/">recent article</a>, which was followed by some comments about salaries in the games industry.</p>
<p><a href="http://www.developmag.com/">Develop</a> have got their annual survey salary out, and list the following:</p>
<p><strong>Average Yearly Salaries:</strong><br />
Lead Programmer &#8211; £41,250<br />
Programmer &#8211; £25,810<br />
Junior Programmer &#8211; £18,928</p>
<p>A few thoughts spring to mind:</p>
<p>1. Wow. Now I remember why I left the games industry.</p>
<p>2. £26K for a programmer is less than £29K for an artist or £27 for a junior audio engineer! That disagrees very strongly with my anecdotal experience. I don&#8217;t know of any artists or audio guys paid more than their programmer colleagues, and didn&#8217;t think that was the normal state of affairs at any games company anywhere. (Design is a tricky one. Junior designers get shafted, but lead designers / directors can make a fortune). Surprising.</p>
<p>3. £19K average for a junior programmer (implying many get less)? That&#8217;s appalling! I was paid £20K as a junior <em>seven years</em> ago! Also, the last company I was involved with hiring at, offered around £23K as standard for new junior hires.</p>
<p>I&#8217;m not going to say the Develop survey is wrong, because they&#8217;ve had a wide range of respondents whereas I&#8217;ve only got my own personal limited anecdotal experience to draw from. What I will say is, if those Develop figures are <em>right</em>, there&#8217;s a lot of people out there getting completely stitched up. They&#8217;d be earning a <em>lot</em> more in another industry. Is that worth giving up, in order to fulfil their childhood dream of making games for a living? That&#8217;s a question only they can answer. For a while, my answer was &#8220;yes&#8221;. Now, though, I stand my updated decision of making <em>software</em> for a living, and making <em>games </em>for fun.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/121/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=121&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2009/02/09/mean-salary/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
		<item>
		<title>It&#8217;s not the size that counts</title>
		<link>http://bittermanandy.wordpress.com/2009/01/22/118/</link>
		<comments>http://bittermanandy.wordpress.com/2009/01/22/118/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 21:37:17 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Games Development]]></category>
		<category><![CDATA[Games Industry]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=118</guid>
		<description><![CDATA[Indulge me as I walk down memory lane&#8230;
It was summer 2002 and I&#8217;d just landed my first professional job. (I&#8217;m still not sure how. I wasn&#8217;t very good back then. I like to think they saw that I&#8217;d become good, and I like to think I am good now. It might just have been luck!). [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=118&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Indulge me as I walk down memory lane&#8230;</p>
<p>It was summer 2002 and I&#8217;d just landed my first professional job. (I&#8217;m still not sure how. I wasn&#8217;t very good back then. I like to think they saw that I&#8217;d become good, and I like to think I am good now. It might just have been luck!). I&#8217;d spent some time in the RnD department, to learn the ropes, become familiar with devkits (console hardware with added stuff to enable game development), and understand a bit about how the shared game engine worked; and then the time came to move onto a game team, of which there were five or six to choose from. The choice wasn&#8217;t freely given. Each team had different needs, so the question was asked: what did I want to work on? What did I want to specialise in?</p>
<p>I didn&#8217;t really know how to answer that. I was vaguely aware of the division between systems programming and gameplay programming, and knew that I preferred the former (I actually think the latter is better solved by a good data-driven system and a good designer, though I have worked with gameplay programmers who produced excellent results); but which system? And how would my choice affect my working day?</p>
<p>Games teams on &#8220;AAA&#8221; titles nowadays can easily have several tens of programmers. Clearly, if they all worked on whatever they fancied from day to day it would be a disaster. Each programmer therefore gets designated an area of responsibility. Generally speaking, the programming lead and the most senior programmers determine the overall architecture of the game early in development (or it may be mandated by the engine, particularly if it is middleware), and the programming team splits into several sub-teams, each led by a senior programmer who reports to the lead programmer. Examples of roles in the team (in no particular order) include:</p>
<p><strong>Graphics:</strong> the celebrities of programming because they get to write code that produces awesome looking screenshots (or at least&#8230; code that lets the artists do so). Every time the publishers come for a visit, they&#8217;ll get led into the graphics programmers&#8217; office and shown all the latest particle-laden explosions on flashy HDTVs. Graphics programmers spend a lot of time writing shaders, optimising the renderer, and talking with artists.<br />
<strong>Networking:</strong> modern games are immensely complex and with multiplayer online being practically compulsory nowadays, every game will have network specialists. They tend to spend all their time trying to teach other programmers how to write code that doesn&#8217;t break the online mode, for example by sending 600KB packets every frame or updating something on the local client but not the game server. They usually look a bit stressed.<br />
<strong>Physics:</strong> even with middleware like Havok (or in XNA, JiglibX and the like) available, physics remains one of the most complicated things in a game because it affects just about everything else. One game I worked on had five physics programmers.<br />
<strong>AI: </strong>most games have enemies or some kind of non-player entity. While scripting and other designer-facing tools mean AI is not as hard-coded as it once was, someone&#8217;s got to write the code that interprets the scripts &#8211; that&#8217;s the job of the AI coder.<br />
<strong>Audio:</strong> given that the only two ways your game can influence the player is via the screen and the speakers, audio is half of every game. Unfortunately it&#8217;s the second half (because it doesn&#8217;t look good in screenshots) and all too often audio is neglected. Done well, it can turn a good game into a mind-shatteringly atmospheric epic. Audio coders spend a lot of time talking to the musicians and SFX engineers, and they&#8217;re usually slightly bitter that the graphics programmers get all the plaudits (and flashy HDTVs).<br />
<strong>Tools:</strong> there might be twenty programmers on a team, but there might be ten designers, fifty artists, and five audio engineers (as well as testers, producers, marketing, translators&#8230;). You can&#8217;t just give them a copy of Photoshop and Maya and tell them to get on with it. Every game needs specific tools that enables these people to get their assets into the game and tweaked until fun and in my experience, the better the tools the better the finished game.  Historically tools were DOS-based and unreliable; increasingly, they&#8217;re now written in C#/.NET and actually work more often than not. Tools programmers are the unsung heroes of the programming team. Their work is almost never seen by the public, but without them, the game itself won&#8217;t get seen by the public either.<br />
<strong>Systems:</strong> asset loading. The game camera. Multithreading. Save games. Text, and menus. Achievements. DVD file layout. TCR compliance (rules that the console makers require you to obey before your game can be released). Support for steering wheels, dance mats, webcams and chatpads. The build process (putting together versions of the game to give to artists, management and testing). A veritable pot pourri of tasks that no game can go without. Some of these tasks will be given to the most senior programmers because they&#8217;re critical to the game&#8217;s success. Others will be given to the most junior programmers because they&#8217;re relatively self-contained and can be developed in isolation. Most don&#8217;t get noticed, until you try to make a game without them!</p>
<p>There&#8217;s more, but that&#8217;s a good initial summary. (Just think &#8211; when you write an XNA game, you&#8217;re responsible for all of the above! Lucky XNA itself is <em>brilliant</em> at doing it loads of it for you). My first ever task on a game team was to write the game camera, and looking back I&#8217;m pretty proud of how it turned out. Very soon afterward I also took on the audio programming. Eventually, on that first game (I worked on it for three years &#8211; some were working on it for twice that), I was responsible for, or otherwise involved with, text and menus, localisation (making the game support other languages), asset loading, the build process, save games and TCR compliance. Later I&#8217;d work on asset optimisation and arranging files on the DVD, and probably some other stuff I&#8217;ve forgotten. So it became clear: my specialisation was that I was a Jack-of-all-trades. Hurrah!</p>
<p>With all these people working on different things, it&#8217;s critical that they don&#8217;t interfere with one another by writing over one another&#8217;s changes. This is achieved by use of a Source Control System. Basically, this keeps track of every code file and asset in the game, keeps records of how they change over time, and tries to ensure that if two people make changes at once, those changes are seamlessly merged together. Different teams use different products and approach this in different ways. Some examples using the codenames of games I worked on:</p>
<p><strong>Game Two</strong>: used CVS for source control. This is an horrific abomination that should be scourged from the earth. A coder would make all the changes he wanted, send out an email to the team saying &#8220;please don&#8217;t commit&#8221;, commit all the files he&#8217;d changed, and send another email saying &#8220;OK to commit&#8221;. Inevitably he&#8217;d have missed something so the next coder to update would have to come and ask him to fix the problem before they could continue. Worst of all, the artists couldn&#8217;t get anything into the game without giving it to a programmer to commit it for them. This was frustrating for everyone involved and meant that changes to a level, for example, could take two or three days to get into the game. Putting together a build was an eight hour manual process; all too often it wouldn&#8217;t start until 5pm the night before a deadline. I&#8217;m not completely sure how we managed to get the game finished, and I&#8217;m stunned that it turned out as good as it did despite everything. This is How Not To Do It.</p>
<p><strong>Pocket/Pikelet:</strong> an improvement in every area, these teams used Source Depot (basically the same as Perforce) for source control. No more emails to control who could commit &#8211; a tool that lived in every developer&#8217;s System Tray would lock out commits while someone was going through the process of updating, building the game, running the unit tests and committing. A separate build machine would then automatically update to that version, run the tests again and if they were passed make the build available to all the non-programmers &#8211; who, incidentally, had the tools available to do all their work without needing to go through a programmer. It was brilliant, broken builds and artist downtime were unheard of &#8211; the game was bulletproof throughout development. There was only one small problem. Updating, building, running unit tests and committing took half an hour or more. In a normal eight hour day, only sixteen programmers could do it &#8211; at most. With twenty programmers on the team, there&#8217;s an obvious problem and it got very frantic near deadlines &#8211; and leaving at least a day between committing meant that you&#8217;d commit too much at once, introducing bugs (which would fail the unit tests and delay your commit even longer). This was a problem, but in general this was the best system I&#8217;ve had the pleasure of working in.</p>
<p><strong>Polished Turd</strong> (not the real codename, just what I call it): again this used Perforce for source control, except this time without a formal commit queue like Pocket/Pikelet. The commit queue had originally been introduced to stop CVS from breaking everything, but Perforce is so much better than CVS that actually things rarely break even if you&#8217;re free and easy with committing. It meant that you could fix a bug, commit your changes, fix another bug, commit your changes, and iterate very rapidly through your work. You&#8217;d update over lunch and overnight, or when you noticed someone had committed something you need. If we&#8217;d only had the same team build system, unit tests, build suite, and artists tools from Pocket/Pikelet this would have been the ideal way of working. (Unfortunately all those things didn&#8217;t exist so the game was unstable, the artists couldn&#8217;t do their job, and every deadline was a mad scramble to put together get something vaguely playable that lasted more than five minutes between crashes).</p>
<p>Now, most people reading this will be hobbyists working in XNA on their own. At the moment, that applies to me too. However, I&#8217;m uncomfortably aware that the big blue blobs and soulless grey polygons that currently represent the actors and props in my game won&#8217;t inspire other people to play my game &#8211; and I&#8217;m closer to being autistic than artistic. So sooner or later, I&#8217;m going to need other team members to make models, textures, animations and sound for me. (Any volunteers?) And, while I&#8217;m currently planning to save all the coding duties for myself (with the XNA Framework itself and the multitude of excellent community libraries out there, this is a realisitic proposition in a non-trivial game for really the first time this side of about 1998) many of you will no doubt be thinking of forming small coding teams, to split the work among you. (I don&#8217;t blame you. Just look at the list above. Even a <em>simple</em> game has a lot to do&#8230;) So &#8211; how well does XNA support medium-to-large game teams? And what would such a team require?</p>
<p>Source control is absolutely essential the moment your team grows larger than one. And, with a team of one or two, there&#8217;s only one choice &#8211; Perforce, which is free for up to two users, and so good I use it even though no-one&#8217;s forcing me to. Unfortunately, as soon as your team size hits three people, it&#8217;s something like $700 a license. <em>Ouch</em>. Worth absolutely every penny and more if you&#8217;re a pro developer with your outgoings covered by a publisher, but out of reach of everyone else. I am told that Subversion is good for a free product, but I look at the lack of atomic changelists and <em>cringe</em>. Probably the next best if you can&#8217;t afford Perforce though. There&#8217;s nothing here that&#8217;s different for XNA than if you were using C++ or any other language.</p>
<p>It will be essential to have a configuration of your game that allows your artists to put their assets into the game without waiting for you to do it for them. The XNA content pipeline is a wonderful, wonderful thing of great beauty, but by default it is tied into Visual Studio &#8211; the content pipeline build occurs just before you run your game, and that&#8217;s it. An artist doesn&#8217;t want Visual Studio, and he doesn&#8217;t want to restart the game every time he changes a texture &#8211; he should be able to save off the texture file and see it change in-game. So you need to provide them with a version of the game that runs on its own (perhaps in a WinForm) and a tool that hooks into the content pipeline and will let them build assets while the game is running, notify the game, and the game then reloads that asset. This is pretty easy for assets that already exist in a content project, but the tool will need to support adding to the content project (hidden from the artist) and even creating new ones. All this needs to hook into your source control system without your artist needing to learn to type &#8220;p4 -d -a -q -z&#8221; or whatever.</p>
<p>The content pipeline causes a few other problems too. (Though don&#8217;t think for a second that I&#8217;m knocking it. What it does is amazing). Big games tend to generate thousands, even hundreds of thousands of assets &#8211; and in the content pipeline, each of those is a different file. People often don&#8217;t realise that opening a file, even from a hard drive, can sometimes take as long as a quarter of a second. That doesn&#8217;t sound like much until you multiply it by a hundred thousand. (You can very easily see this for yourself by using WinZip to zip up one large file of say 10MB, then compare it to zipping up a thousand files of 10KB each &#8211; I guarantee the latter will be much slower). To give an XNA-related example: Kameo, Pocket and Pikelet all used XACT, the same audio tool as provided with XNA (and which I&#8217;ve used very extensively). Pocket, in particular, had well over 200 soundbanks which all needed loading at startup. Even though they were only between just 1 and 4KB each, this took a long time to load from the DVD - so long that the 20 second load time mandated by Xbox 360 TCRs seemed an impossibility. The fix was pretty simple: we altered the build process to package all those soundbanks into a single file, loaded the file into memory, and loaded the soundbanks from that memory. Instantly the problem was solved. The same solution won&#8217;t work in XNA: there&#8217;s no method to load soundbanks from memory. It expects each soundbank as a separate file, and that&#8217;s that. A big game in XNA would really struggle under such restrictions. (Loading on a background thread won&#8217;t help, 20 seconds of disk access is 20 seconds of disk access and that&#8217;s that, though admittedly an XNA game would be on a hard drive not a DVD which helps a lot). You&#8217;d have to plan ahead very carefully &#8211; in terms of the game design, not just code; which is hard, because designers don&#8217;t understand arbitrary restrictions from code, and nor should they have to - to ensure that there was never a need to load so many individual files all at once.</p>
<p>With these caveats in mind I&#8217;m convinced a medium-to-large game can realistically be made in XNA. The &#8220;poor performance&#8221; of C# compared to C++ is for the most part a myth, though to get the absolute 100% optimum out of the hardware might require C++ &#8211; but you could get at least 95% of the way there with C#, and 98% of all games don&#8217;t need 100% performance. It&#8217;s unfortunate that the biggest win for hobbyists and small-team endeavours &#8211; the brilliant content pipeline &#8211; appears to be the biggest limiting factor for large teams. The issue of when and how assets are built, and how they can be rapidly iterated without restarting the game, is definitely solvable, though with a fair bit of coding effort; the fact that so much of the pipeline relies on a one asset, one file relationship is trickier. A hundred-thousand-asset game would need a hundred thousand files, and loading times would be horrific.</p>
<p>So really large games might not be easy in XNA. Happily (?) few large games nowadays are single platform, and since XNA is not available on PS3 and Gamecube, I don&#8217;t think many large teams will be evaluating XNA anyway. Medium teams, independents, and small hobbyist teams can definitely have a field day with it (though profitability of XBLCG at least has yet to be proven). Just remember that the limiting factor for such games is content, and put a lot of effort into making your artists&#8217; lives easy. If they can make a model, put it in your game, play with it, tweak it, play with it again, tweak it, play with it, and check it into source control, they&#8217;ll beg to be allowed to make more. If they have to send you the model and wait two days for you to send them a build with it in, they&#8217;ll give up within a week. Frankly &#8211; even if you&#8217;re working on your own, and doing all the code and art yourself, a little bit of work to make good tools will make your <em>own</em> life easier; and isn&#8217;t that what we all want?</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/118/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=118&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2009/01/22/118/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
		<item>
		<title>Any requests?</title>
		<link>http://bittermanandy.wordpress.com/2009/01/21/any-requests/</link>
		<comments>http://bittermanandy.wordpress.com/2009/01/21/any-requests/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 12:51:43 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Games Development]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=116</guid>
		<description><![CDATA[Wow, it seems like an age since I posted. I guess that&#8217;s because it is! Fable 2 took up far more of my time than I expected, I&#8217;ve barely touched Nuts and Bolts, and I still have to complete Tomb Raider and Prince of Persia before March, when Empire: Total War is released. This doesn&#8217;t [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=116&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Wow, it seems like an age since I posted. I guess that&#8217;s because it is! Fable 2 took up far more of my time than I expected, I&#8217;ve barely touched Nuts and Bolts, and I still have to complete Tomb Raider and Prince of Persia before March, when Empire: Total War is released. This doesn&#8217;t leave much time for any meaningful development on Pandemonium, though I have recently chucked together a few little prototypes of stuff I might one day make into fully-developed games.</p>
<p>Anyway I don&#8217;t know when it will be that I&#8217;ve done enough on Pandemonium to make an update worthwhile. But I don&#8217;t want to leave the blog stagnant, it&#8217;s still getting a fair number of hits every day and people must have expectations&#8230; so I&#8217;ll put the question out there: is there anything (preferably XNA-related) you want to read about? Check out the stuff I&#8217;ve already written to get an idea of the kinds of things I know. Clue: I&#8217;m not the man to ask about whizz-bang graphical effects, but if there&#8217;s anything else you&#8217;d like to see, just ask.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/116/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=116&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2009/01/21/any-requests/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
		<item>
		<title>The Masonic Handshake</title>
		<link>http://bittermanandy.wordpress.com/2008/12/10/the-masonic-handshake/</link>
		<comments>http://bittermanandy.wordpress.com/2008/12/10/the-masonic-handshake/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 22:43:32 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Games Industry]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=114</guid>
		<description><![CDATA[I&#8217;ve had a few people contact me to ask, &#8220;do you have any advice for how to get into the games industry?&#8221; Besides being ironic given that I&#8217;m no longer a part of the industry myself, this is a phrase that I really despise, because &#8211; well, I&#8217;ll get to that in a minute.
I&#8217;m going [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=114&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>I&#8217;ve had a few people contact me to ask, &#8220;do you have any advice for how to get into the games industry?&#8221; Besides being ironic given that I&#8217;m no longer a part of the industry myself, this is a phrase that I really despise, because &#8211; well, I&#8217;ll get to that in a minute.</p>
<p>I&#8217;m going to start by making a couple of assumptions. I&#8217;m going to assume that the the person asking the question is really asking, &#8220;how do I get a job as a games programmer?&#8221; The reason for this assumption is that it&#8217;s the only thing I can speak with any experience about. Modern games (at least, console and AAA PC games, which is what people usually mean by &#8220;the games industry&#8221;; casual or flash games, not so much) involve teams of tens or even hundreds, involving programmers, artists, designers, scriptwriters, musicians, testers, producers, marketing, and a whole bunch of other roles. I&#8217;ve worked with all of the above, but I&#8217;d be guessing if I tried to tell you how they ended up there.</p>
<p>The second assumption I&#8217;ll make is that working as a games programmer is something you really want. The pay is low, compared to non-games programming. The hours are longer (though this is starting change) and the respect from management lower. Most games &#8211; and hence, the games worked on by most <em>people</em> &#8211; aren&#8217;t the amazing high-quality AAA 96%-rated blockbusters like Half-Life 2 that we&#8217;d all love to be a part of; in fact, most of the work you do will be soul-destroying just like in any other job. If you&#8217;re lucky, you&#8217;ll get to work at a company that lets you leave at 5pm, in which case you will get to see the sun; but even if you don&#8217;t have to crunch you could easily go months without seeing those strange creatures they call &#8220;females&#8221;. In fact, for all these reasons and more, I no longer work in games myself. But be clear about this &#8211; I&#8217;m glad I did it (for about six years). Knowing you&#8217;re doing a job you love, and finally seeing your baby on the shelf at Game and hearing someone say &#8220;yeah I played that, it&#8217;s quite good actually&#8221;, is a buzz of fulfilment like no other. Decide for yourself whether the balance works for you. It did for me, for a long while.</p>
<p>Anyway, where was I? Oh yes &#8211; &#8220;getting into the games industry&#8221;. I <em>hate</em> that phrase. It suggests there&#8217;s something magical about it, as if you need to know a special password or shake hands with the interviewer in a particular way. The truth is that games have matured into an industry like any other and you&#8217;ll get a job programming games the same way you&#8217;d get <em>any other job</em>.</p>
<p>Let&#8217;s pretend I&#8217;m going for a job as an architect. Should I:</p>
<p>(a) spend all day looking at my favourite building, but not really bother about any others because they suck, take a course in Social Studies because you only have to go to three lectures a week, then wonder why architecture companies don&#8217;t even respond to my applications even when I put &#8220;&#8230;it&#8217;s what I&#8217;ve always wanted to do, and I&#8217;m a fast learner!&#8221; on my CV; or</p>
<p>(b) learn how to be an architect, get qualified, put together a portfolio, apply for jobs, and make sure I nail the interview?</p>
<p>Third assumption: you answered (b).</p>
<p><strong>Get Competent</strong></p>
<p>If you&#8217;re going to be a games programmer, you need to be a good programmer. Sounds obvious really. I&#8217;m tempted to say, &#8220;it&#8217;s that simple&#8221;, but of course it&#8217;s not. The thing is, if you&#8217;ve yet got a job as a professional programmer, you&#8217;re probably not aware (even if you think you are!) of what being a good programmer <em>means</em>. That&#8217;s OK. The good news is: no-one expects you to.</p>
<p>The simple fact of the matter is that learning to program well comes only with experience. And, if you don&#8217;t have QA teams tearing your work to shreds, or customer complaining your software crashes, you <em>may never realise</em> when you&#8217;re making mistakes. (Don&#8217;t let that stop you coding &#8211; a lot &#8211; in your spare time. Any experience is better than none). When I first began applying for jobs, I rated my coding skills as 8/10. Looking back, I was more like 2/10. I&#8217;m not sure I&#8217;m more than 7/10 now, more than six years later. That&#8217;s fine &#8211; companies looking to employ new hires only really expect 2/10. So why, you might wonder, bother putting any effort into learning to code at all? You&#8217;ll learn it all on the job, right? Wrong. Getting to 2/10 is <em>hard</em> (remember the default state is zero!). If you don&#8217;t understand pointers, if you can&#8217;t fix compiler errors and warnings, if you can&#8217;t identify and eliminates bugs in your own code and other peoples&#8217;, if you can&#8217;t make estimates about the performance of a given algorithm: either <em>learn that stuff</em> or <em>give up now</em>. No company will expect a new hire to be the finished product. But no company will hire someone who hasn&#8217;t bothered to learn what they need to know to do the job, either.</p>
<p>What language should you be programming in? I&#8217;d love to say C#, but I can&#8217;t. Not yet anyway, perhaps in a few years. Currently, most companies only use C# for tools (and some not even then). The overwhelming majority of games companies use C++, and most of the rest use C. (Or, mobile developers probably use Java?) A few devs are starting to use C#, but most don&#8217;t and sadly won&#8217;t. There are a few very good reasons for this, despite the fact that C++ is a dinosaur and C++0x is going to be at least ten years too late. The first very good reason is that companies currently have millions of lines of C++ and tens of C++ programmers, and they&#8217;re not about to throw either of those away just because someone like me claims C# is more productive. The second very good reason is that there is no C# compiler for PS3 or Wii &#8211; and that&#8217;s a winning argument for companies intending to make games for those platforms. So if you want to make games,  I recommend C# and XNA. But if you want to get a job as a games programmer, I&#8217;d be doing you a disservice to say anything other than to learn C++.</p>
<p>You should also have a passing familiarity with two or three other languages (even if only to know that &#8220;the major differences between C++ and &lt;language&gt; are&#8230;&#8221;), an understanding of computer science principles, and <em>above all</em>, the ability to work as part of a team, including with team members who are non-programmers.</p>
<p><strong>Get Qualified</strong></p>
<p>Already, I&#8217;m sure some of you out there are screaming at me about this. &#8220;You don&#8217;t need a degree to be a good programmer!&#8221; they&#8217;re shouting. That&#8217;s not in dispute. &#8220;Just because you have a piece of paper, doesn&#8217;t mean you are a good programmer!&#8221; they&#8217;re adding. Completely agree with that too. However, nowadays, if you don&#8217;t have a degree in some kind of computing-related field, you probably won&#8217;t get past the recruiter&#8217;s first cut. <em>Yes</em>, there are exceptions, but they are exceptional! You could take a gamble, but the odds are desperately slim and you&#8217;d be much better off getting a degree. (The only time I&#8217;d say that doesn&#8217;t apply is if you&#8217;ve already been working as a professional programmer for years, in which case, yes, experience counts at least as much as a degree. But for a school-leaver or graduate, a degree is, to all intents and purposes, essential).</p>
<p>But &#8211; a degree in Computer Science or similar traditional field, or a new-fangled degree in Computer Games Development, perhaps even from a games-specialist University? Well&#8230; I cannot deny my prejudice here. My degree was in Computer Science, and I learned things on that course that I don&#8217;t think I&#8217;d have learned on a games-specific course that since proved invaluable. There is also the consideration that, should things not turn out as you hope, a CompSci degree will get you a job in a non-games company. I&#8217;m not sure that a Games degree would do the same. Or, look at it another way: any company will hire someone with a CompSci degree, some companies won&#8217;t hire people with a Games degree. That may change over the years, in fact I expect it to, but again &#8211; play the odds!</p>
<p>I should mention that at least two excellent people I worked with had Games degrees, so I wouldn&#8217;t dismiss someone with a Games degree out of hand. But, I got the impression that they were brilliant <em>despite</em> their Games degree, not <em>because</em> of it. I&#8217;ve also seen a lot of applicants with Games degrees who were simply awful and had clearly been let down by their course. It&#8217;s up to you, in the end &#8211; a Games degree or a CompSci degree is entirely your choice, and either can be made to work - but I&#8217;d still suggest that, for now at least, the latter is the better option.</p>
<p><strong>Put Together a Portfolio</strong></p>
<p>So you&#8217;re a good programmer and you have a piece of paper to prove it. Excellent! Regrettably, companies will still need convincing. There&#8217;s only one way to do that &#8211; happily, it coincides with the first piece of advice, &#8220;get competent&#8221; &#8211; and that&#8217;s to write some code to show to a prospective employer. (Writing the code will help you become competent, and as you become more competent you will have better code to show to employers).</p>
<p>What kind of code? Well, you&#8217;ll need to show a few things really. First, a simple, yet complete, polished, and bug-free game. When I say &#8220;simple&#8221;, I mean something like Tetris &#8211; but when I say complete, I mean with menus, high-score tables, multiplayer, pause, an options screen&#8230; everything you get in a pro game. Bug-free should speak for itself&#8230; Secondly, you&#8217;ll need a more advanced game that may be incomplete but demonstrates more demanding problem-solving. It should involve two or preferably more of the following: 3D graphics, 3D audio, physics, networking, AI, data driven development, and save/load. Finally, you&#8217;ll need one game component (from the list above, or &#8220;something else&#8221;) that is highly polished and well developed and could be plugged into someone else&#8217;s game if they chose to use it, so should also be clearly documented with a sensible API.</p>
<p>You should provide this code with your application, either on CD if it&#8217;s by snail mail, or on a website  if your application is in electronic form. Provide your complete source code, and make crystal clear exactly which parts were written by you and which by someone else. Also provide the built versions of the software (on the CD, or as a separate download from the code) but remember that actually it&#8217;s the code that&#8217;s important &#8211; recruiters probably won&#8217;t run the game and certainly won&#8217;t play it for more than five minutes to check it doesn&#8217;t crash, but they will be interested in whether your code is well-written. Only ever show your latest, best code &#8211; quality beats quantity every time.</p>
<p><strong>Apply For Jobs</strong></p>
<p>First impressions count for a lot: make sure yours is positive. Ensure your CV and covering letter are polished, clear and professional. There&#8217;s a lot of websites with good advice which I won&#8217;t attempt to repeat here.</p>
<p>Where should you apply? Well, there&#8217;s a lot of options. Do some research (subscribe to Develop and Game Developer, and join Gamasutra, GameDev.net, GameDevMap.com and probably a bunch of other places), and try not to close too many doors. When I was a graduate, I applied to <em>forty</em> games companies. I got three interviews, one of which was cancelled the day before the interview itself, and one job offer, which became two a few months later, after I&#8217;d already started working for the first. (In contrast, when I started looking to leave Rare, just six applications garnered me six interviews and five job offers &#8211; that&#8217;s the power of experience!).</p>
<p>Remember that large companies (EA, Microsoft, Sony, Nintendo, etc) are more likely to recruit new hires than small companies, who may not be able to afford to employ someone who will, inevitably, not be very productive for at least the first six to twelve months. Bear in mind the corporate culture of such companies &#8211; though remember you might not be able to afford to be choosy. Medium-sized companies sometimes offer a less corporate culture while still hiring graduates; some are more noted for recruiting out of University than others, for example Rare, Blitz and Codemasters in the UK. (Again consider the implications. Are they hiring graduates because they are able to recognise untapped potential &#8211; which is a very good thing &#8211; or to get a cheap source of labour &#8211; which is a bad thing? You&#8217;ll need to work that out for yourself at the interview). Whatever happens, don&#8217;t apply blind. I&#8217;d encourage you to send lots of applications, but you do need to understand what you&#8217;re applying for and why, before you do.</p>
<p><strong>Ace The Interview</strong></p>
<p>Again, there&#8217;s plenty of websites that can teach good interview technique, so do some research. I can tell you that having done some interviews myself, there are many things I&#8217;d be looking for, but basically I&#8217;d be looking to answer these questions: (1) will they be any good at the job? (2) will they fit into the team? (3) would I want to work with them myself? Three yes-es and I&#8217;d make an offer, any no-s and I&#8217;d give a polite &#8220;no thanks&#8221;.</p>
<p>To answer (1), as a programmer, you should absolutely expect to be given a programming test at (or possibly before) an interview. I&#8217;ve taken a <em>lot</em> of these &#8211; erm, about twenty-eight altogether? &#8211; and they vary a lot. Some &#8211; the worst &#8211; ask you obscure questions about bizarre corner cases of C++ in an effort to find out what you don&#8217;t know (that the examiner does); others ask you to debug code and write some of your own, to find out what you do know and how well you know it. Most are written, some involve giving you a laptop with a game project on it and asking you to fix the bugs. Some involve general programming knowledge, others are strictly C++ only. Whatever happens, all you can do is your best, and if you&#8217;re competent, you&#8217;ll do well enough to pass.</p>
<p>(2) and (3) are much more up to you. Remember that they&#8217;re looking for someone who is competent and confident, but not arrogant. One of my favourite interview techniques is to say something the candidate should know is wrong. If they agree with me, they don&#8217;t know their stuff &#8211; no hire. If they quietly say nothing, they might know it&#8217;s wrong but aren&#8217;t confident &#8211; I&#8217;d try to give them the chance to show that, but it would leave a question mark. If they argue with me or (as one candidate did) call me stupid, it shows they might have trouble fitting into a team environment, especially with temperamental non-technical types &#8211; and I won&#8217;t be offering them a job. If, however, they calmly explain that I am mistaken, and in fact the truth is <em>this</em>, which they know because they once did <em>that</em> &#8211; well, that&#8217;s a model answer.</p>
<p>With all that said, there&#8217;s a couple of things you need to bear in mind. Firstly, the company has gone through potentially hundreds of CVs and code samples and chosen you as someone worth inviting to interview. They may have spoken to you on the phone, and they&#8217;ve certainly set aside time for one or (usually) more people to take time out from developing a game to interview you. They wouldn&#8217;t do that if they didn&#8217;t want you to do well. If you&#8217;ve been invited to an interview &#8211; when you get there, <em>relax</em>. The interviewers will <em>want</em> to hire you, or they wouldn&#8217;t have asked to meet you: you just need to convince them that they&#8217;ll be right to do so. Secondly &#8211; remember that in a sense you are interviewing them, too, and not just when they ask &#8220;do you have any questions for us?&#8221; You should try to get a sense of the working environment, see if you get on with the interviewers, and think deeply about whether, if an offer is forthcoming, you&#8217;d want to work there. I had five very good years at Rare and I have generally positive memories, but my second games job was a <em>big</em> mistake, the biggest of my life &#8211; one that I could have avoided if I&#8217;d been smarter. At some stage you&#8217;re going to have to take the plunge, but if there&#8217;s a nagging voice in your head saying &#8220;&#8230;are you sure?&#8221;, make sure you can answer &#8220;yes&#8221; before accepting the job.</p>
<p><strong>Getting In</strong></p>
<p>With that lot under your belt you&#8217;ll soon be getting hundreds of job offers. Good luck! Hopefully you&#8217;ll be able to choose a company that is right for you. Making games for a living is a lot of fun and I&#8217;m very glad I did it. One day, I may even go back &#8211; who knows what the future holds? If you&#8217;re visiting this blog chances are you already make XNA games as a hobby and, yes, there are few things better than being paid to do something you&#8217;d be doing for fun anyway. Just remember that ultimately it&#8217;s a job like any other and you&#8217;ll do fine.</p>
<p>Oh yeah- speaking of which - money! Again, do some research (principally in Develop and Game Developer magazines which have annual salary surveys) to find the range of starter salaries in your area. Last I was hiring in games, about 18 months ago, £23-25K was a decent offer for a graduate programmer in the UK (outside London). Unfortunately, as a graduate you&#8217;re unlikely to have much leverage to ask for more, but equally, don&#8217;t quietly let yourself get shafted just to take a job, any job. You should also consider working hours, benefits, location, company size and stability, and whether there is a career path. In what proportions? Well, that&#8217;s up to you!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/114/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=114&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2008/12/10/the-masonic-handshake/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
		<item>
		<title>Foundations</title>
		<link>http://bittermanandy.wordpress.com/2008/12/06/foundations/</link>
		<comments>http://bittermanandy.wordpress.com/2008/12/06/foundations/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 23:04:08 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Games Development]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=108</guid>
		<description><![CDATA[Wow, what a time. After having barely played a game all year, I spent weeks playing Fable 2 (very good, though could have been even better), and I&#8217;m about to get cracking on Banjo Kazooie: Nuts and Bolts (the last game I worked on before leaving Rare) and Banjo Kazooie XBLA. I&#8217;ll be getting Tomb Raider Underworld [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=108&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Wow, what a time. After having barely played a game all year, I spent weeks playing <a href="http://www.xbox.com/en-GB/games/splash/f/fable2/">Fable 2</a> (very good, though could have been even better), and I&#8217;m about to get cracking on <a href="http://banjo-kazooie.com/">Banjo Kazooie: Nuts and Bolts</a> (the last game I worked on before leaving Rare) and Banjo Kazooie XBLA. I&#8217;ll be getting <a href="http://www.tombraider.com/server.php?change=LandingPage">Tomb Raider Underworld</a> and the new <a href="http://prince-of-persia.uk.ubi.com/intro/">Prince of Persia</a> for Christmas, and sometime in January, I&#8217;ll be surrendering every waking moment to <a href="http://www.totalwar.com/">Empire: Total War</a> (seriously &#8211; I plan to take a week off work when it comes out). I&#8217;ve not so much as had a spare second to check out the games on Xbox Live Community Games, which probably makes me a terrible hypocrite who will be punished in the afterlife. Frankly it&#8217;s beyond a joke. I don&#8217;t even have enough time to play all of these games, all coming out within two months of each other &#8211; never mind time for my other hobbies!</p>
<p>Fortunately the other day I managed to squeeze in a few hours with XNA and spent the time fixing up a few odds and ends I&#8217;d been meaning to look at for a while. Specifically, I rearranged the structure of my engine and game code, for clarity and useability. It&#8217;s well worth emphasising a couple of points here: first, while I&#8217;ve built up this structure after a fair bit of experience with professional game engines and a lot of careful thought, there are undoubtedly other ways of doing it. I encourage you to hunt around, look at what others have done, and deeply consider what will work for you. Second, this is very much a work in progress. I will undoubtedly be tweaking things yet further as time goes by, and I&#8217;ve had to make a few decisions &#8220;blind&#8221; &#8211; I&#8217;m pretty sure they&#8217;re the right choices but it&#8217;s entirely possible I&#8217;ll reverse them later as experience dictates.</p>
<p>So. At the highest level, the XNA code I write is split into two general groups: engine code (shared code, usable by more than one game, written in such a way as to be reasonably general purpose without being so abstract as to be useless); and game code and assets (specific to one particular game, though sometimes code can start life here before being moved into the engine later). In an ideal world, all your code would exist in the engine, and there would be no game-specific code at all. Games would be differentiated only by their assets &#8211; the single executable built by the engine would search for an XML file or similar, that would define what other assets to load, and by a combination of scripting and data-driven design, the game would run with no unique code at all. Realistically, that&#8217;s not an achievable goal, and a game will always have game-specific code. The trick is to find a balance.</p>
<p>(First a plea. Don&#8217;t &#8220;write an engine&#8221;. The XNA Framework is so close to being an engine that such a task is pointless, and you&#8217;ll also find that no-one will use it &#8211; because you won&#8217;t have solved the problems you&#8217;d encounter if you wrote a <em>game</em>. Hobbyist DirectX programmers all set out to write an engine, and barely any of them ever complete a game. In fact, it wouldn&#8217;t be bad advice to write a game first, then only when it&#8217;s finished, go back and look at how it can be separated into engine and game code, ready for your next game).</p>
<p>Anyway, let&#8217;s have a look at the folder structure of the engine and the games in turn. You&#8217;ll want to store all your stuff in a single folder &#8211; mine are in Documents\Code\XNA &#8211; Visual Studio will encourage you to put everything under the Documents\Visual Studio 2008 folder, but that&#8217;s a really bad idea because when Visual Studio 2010 and XNA 4.0 come out you&#8217;ll just have to move everything, which apart from being generally inconvenient can be a royal pain if you&#8217;re using source control!</p>
<p><strong>Engine Folder Layout</strong></p>
<p>My engine is codenamed Kensei, and is therefore stored in the Kensei folder. Here, you will find the <em>Kensei.sln</em> Visual Studio solution file, as well as my <em>Kensei.</em><a href="http://bittermanandy.wordpress.com/2008/08/13/tools-of-the-trade-part-one-fxcop/"><em>FxCop</em></a> project (with <em>CustomDictionary.xml</em>) and a couple of handy batch files which I&#8217;ll come to in a minute. Everything else is stored in subfolders, corresponding to the code projects that are referenced in Kensei.sln (which in turn correspond to the assemblies that can be used by my games).</p>
<p><em>Kensei</em> &#8211; the &#8220;core&#8221; project containing the majority of the code I write. In here exists my audio engine, camera management code, handy <a href="http://bittermanandy.wordpress.com/2008/07/">development utility code</a>, <a href="http://bittermanandy.wordpress.com/2008/08/05/at-your-command/">command pattern</a> implementation, and everything else I&#8217;ll come up with as I add features. Each logical unit is stored in a subfolder of this folder, so for example my audio code exists in Documents\Code\XNA\Kensei\Kensei\Audio &#8211; but it&#8217;s all built together in a single C# project called Kensei. (I&#8217;ve worked on games where each logical module had its own project. It just meant we ended up with fifty-odd projects and fifty-odd assemblies where one would do. It might make it easier to keep things decoupled, but adds headaches via complexity, especially as C# makes circular references awkward or worse. Don&#8217;t bother).</p>
<p><em>Kensei.EmbeddedResources</em> &#8211; there are a few things in the Kensei engine that require specific assets. For example, Kensei.Dev uses a font for simple text and a shader for simple shape rendering. At first, these assets had to be copied into the content project of each game prototype I created but that quickly became a pain. The answer (as Shawn Hargreaves describes expertly) is <a href="http://blogs.msdn.com/shawnhar/archive/2007/06/12/embedding-content-as-resources.aspx">embedded resources</a>.</p>
<p><em>Kensei.Pipeline</em> and <em>Kensei.Pipeline.Runtime</em> &#8211; XNA makes working with assets an absolute dream and most non-trivial games will extend the content pipeline to support custom asset types. Kensei.Pipeline extends the content pipeline itself, while Kensei.Pipeline.Runtime acts as a bridge between the content pipeline and the game &#8211; again, Shawn <a href="http://blogs.msdn.com/shawnhar/archive/2008/11/24/content-pipeline-assemblies.aspx">explains in full</a>.</p>
<p><em>DebugContentBuild</em> &#8211; it&#8217;s an inevitable fact that all code has bugs, so I followed <a href="http://badcorporatelogo.spaces.live.com/blog/cns!43EB71B104A2D711!169.entry?_c=BlogPart">Stephen&#8217;s advice</a> and created a project that vastly simplifies the process of debugging my content pipeline extensions. Basically, running this project attaches to MSBuild.exe and runs the content pipeline on the assets in its content project &#8211; allowing me to step into my Kensei.Pipeline code and see where it&#8217;s going wrong.</p>
<p><em>(Other Code Projects)</em> &#8211; one of the things I love about the XNA community is the easy willingness with which people share their work. Make use of it! I don&#8217;t want to spend my hobby time reinventing the wheel or rewriting something someone else has already done perfectly well (unless, of course, it&#8217;s the main differentiating point of my game, or something I have a specific interest in doing or learning. Always in-source your USPs, but don&#8217;t even attempt to do <em>everything</em> yourself!). Therefore, my Kensei engine solution contains projects for <a href="http://www.codeplex.com/JigLibX">JigLibX</a>, the <a href="http://creators.xna.com/en-GB/utilities/curveeditor">Curve Editor Control</a>, and a few other public components, as well as code supplied with <a href="http://www.compman.co.uk/scripts/browse.asp?ref=835609">various</a> <a href="http://www.compman.co.uk/scripts/browse.asp?ref=870617">books I</a> <a href="http://www.compman.co.uk/scripts/browse.asp?ref=851495">own</a>. Which books should <em>you</em> own? <a href="http://bittermanandy.wordpress.com/2008/08/02/the-path-to-wisdom/">Start here</a>!</p>
<p><em>External</em> &#8211; of course, some code isn&#8217;t supplied with source, but as a standalone assembly. For example, I use <a href="http://www.perforce.com/">Perforce</a> for source control (accept no substitute! It&#8217;s the best there is, period &#8211; it&#8217;s so good, I use it <em>even though I don&#8217;t have to</em>, and I&#8217;ve not yet come across any other source control I&#8217;d say that about) and the rather wonderful <a href="http://p4dotnet.sourceforge.net/index.php/P4.Net_Overview">P4.NET</a> lets me write the ability to work with Perforce into my tools. This allows my game editor to automatically check out assets that I work on, for instance. This, and other such assemblies, are all stored in the External folder (with a handy text file so I don&#8217;t forget where I got them from&#8230;).</p>
<p>Now, with all these projects and assemblies floating about, each built into their own build directory, finding them from the individual games becomes awkward! It&#8217;s much easier when all the engine assemblies are in the same place. With this in mind, I wrote the following <em>PostBuild.bat</em> batch file. Every project in the solution runs this as a post-build step (details in the script itself). It copies the output files of the project into the <em>bin</em> folder, so when I create a new game, I only have to look in that one folder for all my references.</p>
<blockquote><p>@echo off<br />
rem &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
rem Run this script as a Post Build Step from every Kensei library to be<br />
rem used by a project or game outside of the Kensei solution.<br />
rem It will place all built files into solution\bin\platform\configuration.<br />
rem This will make them easier to find when adding references.<br />
rem &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
rem Post Build Step:<br />
rem<br />
rem call &#8220;$(SolutionDir)PostBuild.bat&#8221; &#8220;$(SolutionDir)&#8221; &#8220;$(PlatformName)&#8221; &#8220;$(ConfigurationName)&#8221; &#8220;$(TargetDir)&#8221; &#8220;$(TargetName)&#8221;<br />
rem &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>echo &#8212;- Post Build Copy &#8212;-<br />
echo Copying %4%5.* to %1bin\%2\%3&#8230;<br />
xcopy   %4%5.*   %1bin\%2\%3   /Y   /I   /F</p></blockquote>
<p>Finally, with all these assemblies floating around, it&#8217;s nice to be able to clear everything out and know that a build will start completely afresh. (Why does &#8220;Clean&#8221; do nothing on a C# project? Alright, Visual Studio handles C# a hundred times better than C++, but I still sometimes want to know that everything that isn&#8217;t a source file has been deleted). So I wrote a <em>CleanAll.Bat </em>(warning, use at your own risk, especially if you make use of folders named &#8216;obj&#8217; or &#8216;bin&#8217;):</p>
<blockquote><p>@echo off<br />
rem Script to completely start afresh without *anything* still hanging around from previous builds.<br />
rem This is useful to, for example, check what would happen if it was checked out on a clean machine.</p>
<p>echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
echo Delete Visual Studio local files<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>del /Q /S *.csproj.user<br />
del /Q /S /AH *.suo</p>
<p>echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo Delete intermediate and output files<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>FOR /R %%i IN (*) DO IF EXIST &#8220;%%i\..\obj&#8221; rmdir /Q /S &#8220;%%i\..\obj&#8221;<br />
FOR /R %%i IN (*) DO IF EXIST &#8220;%%i\..\bin&#8221; rmdir /Q /S &#8220;%%i\..\bin&#8221;</p>
<p>echo.</p></blockquote>
<p>That&#8217;s pretty much it for the Kensei engine (well, more or less, as you&#8217;ll see in a moment). After seven or eight years with playing around with Visual Studio and trying to arrange large game projects in a way that preserves my sanity, I&#8217;m pretty confident that this layout is the easiest to work with.</p>
<p><strong>Game Folder Layout</strong></p>
<p>The whole point of the above is to make creating new games prototypes quick and easy. I&#8217;ve got ten or twelve game ideas in my head right now, although Pandemonium remains my main focus, and every time I get a new one, I like to be able to spend one evening slapping something together that just works with a SpriteBatch (for 2D) or Kensei.Dev.Shapes (for 2D and 3D) without spending any time at all plugging the lower-level stuff together. So, all my games exist in the Documents\Code\XNA\Games folder, and reference assemblies in the Documents\Code\XNA\Kensei\bin and External folders. Taking Pandemonium as an example, Documents\Code\XNA\Games\Pandemonium contains (as you&#8217;ll have come to expect) the <em>Pandemonium.sln</em> Visual Studio solution, and the <em>Pandemonium.FxCop</em> file (and <em>CustomDictionary.xml</em>) as well. Then there are the following projects in the following folders &#8211; again you should be able to guess what they are, and they should be fairly self explanatory when read in combination with the above:</p>
<p><em>Pandemonium</em> &#8211; the game itself. Of course, the content project and all assets are stored in here too.<br />
<em>Pandemonium.Pipeline</em> &#8211; content pipeline extensions for the game.<br />
<em>Pandemonium.Pipeline.Runtime</em> &#8211; a bridge between the two.</p>
<p>It really is as simple as that, and if I were just writing a quick prototype there would probably only be the first one.</p>
<p><strong>Engine.Game</strong></p>
<p>There&#8217;s one project I didn&#8217;t mention above in the Kensei engine. I&#8217;ve only just started doing things this way, and although so far it&#8217;s working well I&#8217;m a little concerned it may prove inflexible in the long run. I&#8217;d encourage you to experiment with it &#8211; after all, if a particular game finds it hard work fitting into this model, just don&#8217;t use it. It will save you a lot of time on those games that work alright with it.</p>
<p>Basically, I&#8217;ve created a project named <em>Kensei.Game</em>, and it contains a single class, Kensei.Game, which derives from Microsoft.Xna.Framework.Game. (Unimaginative names, I&#8217;m afraid&#8230;) If you&#8217;re wondering why it&#8217;s a separate project and not part of the Kensei project, that&#8217;s because it uses code from all the different assemblies and it was easier to keep it apart than try to prevent them from referencing one another in a circular manner. The idea is, that all of my games can inherit from Kensei.Game instead of (more directly) Microsoft.Xna.Framework.Game, and Kensei.Game can handle all of the things that each individual game would have to do for themselves.</p>
<p>Allow me to provide an example. Kensei.Game provides the following (sealed!) implementation of the Draw method: </p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;">
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> This is called when the game should draw itself.</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;param name=&#8221;gameTime&#8221;&gt;</span><span style="color:green;">Provides a snapshot of timing values.</span><span style="color:gray;">&lt;/param&gt;</span></p>
<p style="margin:0;"><span style="color:blue;">protected</span> <span style="color:blue;">sealed</span> <span style="color:blue;">override</span> <span style="color:blue;">void</span> Draw( <span style="color:navy;">GameTime</span> gameTime )</p>
<p style="margin:0;">{</p>
<p style="margin:0;">    <span style="color:green;">// Prepare the game for drawing</span></p>
<p style="margin:0;"> </p>
<p style="margin:0;">    <span style="color:blue;">if</span> ( Kensei.Dev.<span style="color:navy;">Options</span>.GetOption( <span style="color:olive;">&#8220;Draw.Wireframe&#8221;</span> ) )</p>
<p style="margin:0;">    {</p>
<p style="margin:0;">        GraphicsDevice.RenderState.FillMode = <span style="color:#2b91af;">FillMode</span>.WireFrame;</p>
<p style="margin:0;">    }</p>
<p style="margin:0;"> </p>
<p style="margin:0;">    <span style="color:blue;">if</span> ( Kensei.Dev.<span style="color:navy;">Options</span>.GetOption( <span style="color:olive;">&#8220;Draw.CullModeNone&#8221;</span> ) )</p>
<p style="margin:0;">    {</p>
<p style="margin:0;">        GraphicsDevice.RenderState.CullMode = <span style="color:#2b91af;">CullMode</span>.None;</p>
<p style="margin:0;">    }</p>
<p style="margin:0;"> </p>
<p style="margin:0;">    <span style="color:#2b91af;">Color</span> clearColour = <span style="color:#2b91af;">Color</span>.Black;</p>
<p style="margin:0;"> </p>
<p style="margin:0;">    <span style="color:blue;">if</span> ( Kensei.Dev.<span style="color:navy;">Options</span>.GetOption( <span style="color:olive;">&#8220;Draw.CornflowerBlue&#8221;</span>, Kensei.Dev.<span style="color:navy;">Options</span>.<span style="color:#2b91af;">BehaviourIfNotPresent</span>.ReturnTrue ) )</p>
<p style="margin:0;">    {</p>
<p style="margin:0;">        clearColour = <span style="color:#2b91af;">Color</span>.CornflowerBlue;</p>
<p style="margin:0;">    }</p>
<p style="margin:0;"> </p>
<p style="margin:0;">    GraphicsDevice.Clear( <span style="color:#2b91af;">ClearOptions</span>.Target | <span style="color:#2b91af;">ClearOptions</span>.DepthBuffer, clearColour, <span style="color:red;">1.0f</span>, <span style="color:red;">0</span> );</p>
<p style="margin:0;"> </p>
<p style="margin:0;">    GraphicsDevice.RenderState.DepthBufferEnable = <span style="color:blue;">true</span>;</p>
<p style="margin:0;">    GraphicsDevice.RenderState.AlphaBlendEnable = <span style="color:blue;">false</span>;</p>
<p style="margin:0;">    GraphicsDevice.RenderState.AlphaTestEnable = <span style="color:blue;">false</span>;</p>
<p style="margin:0;"> </p>
<p style="margin:0;">    <span style="color:green;">// Perform game-specific drawing</span></p>
<p style="margin:0;"> </p>
<p style="margin:0;">    DrawGame( gameTime );</p>
<p style="margin:0;"> </p>
<p style="margin:0;">    <span style="color:green;">// Complete drawing</span></p>
<p style="margin:0;"> </p>
<p style="margin:0;">    Kensei.Dev.<span style="color:navy;">Manager</span>.Draw( GraphicsDevice,</p>
<p style="margin:0;">        WorldViewProjectionMatrix,</p>
<p style="margin:0;">        Window.ClientBounds.Width,</p>
<p style="margin:0;">        Window.ClientBounds.Height ); </p>
<p style="margin:0;">    <span style="color:blue;">base</span>.Draw( gameTime );</p>
<p style="margin:0;">}</p>
<p style="margin:0;"> </p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> This is called when the game should draw itself.</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;param name=&#8221;gameTime&#8221;&gt;</span><span style="color:green;">Provides a snapshot of timing values.</span><span style="color:gray;">&lt;/param&gt;</span></p>
<p style="margin:0;"><span style="color:blue;">protected</span> <span style="color:blue;">abstract</span> <span style="color:blue;">void</span> DrawGame( <span style="color:navy;">GameTime</span> gameTime );</p>
</div>
<p><!--EndFragment--></p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;"><!--EndFragment--></div>
<p>What this means is that each individual game I write has much, much less to do in it&#8217;s (abstract) DrawGame method. I can&#8217;t forget to call base.Draw, and I always get the benefits of the same Kensei.Dev options and Kensei.Dev.DevText and Kensei.Dev.Shapes drawing &#8211; completely for free. The DrawGame method in Pandemonium is simply this (admittedly, it&#8217;s very much work in progress and there&#8217;s not much to draw yet, but you should get the idea of how little code there is to write per-game, or per-game-state when it&#8217;s a little more developed):</p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;">
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> This is called when the game should draw itself.</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></p>
<p style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;param name=&#8221;gameTime&#8221;&gt;</span><span style="color:green;">Provides a snapshot of timing values.</span><span style="color:gray;">&lt;/param&gt;</span></p>
<p style="margin:0;"><span style="color:blue;">protected</span> <span style="color:blue;">override</span> <span style="color:blue;">void</span> DrawGame( <span style="color:navy;">GameTime</span> gameTime )</p>
<p style="margin:0;">{</p>
<p style="margin:0;">    m_background.Draw( m_camPosition, ViewMatrix, ProjectionMatrix );</p>
<p style="margin:0;">    m_angel.Draw( m_camPosition, ViewMatrix, ProjectionMatrix );</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment-->Update, Initialize and other methods are similarly simplified for the individual game, with as much complexity and common behaviour as is feasible moved into the engine.</p>
<p>Incidentally, when you have a base method that needs to do things before and/or after the derived method, I much prefer this pattern of having the base method (Draw here) as public, and have the base method call into protected virtual (or abstract) methods (DrawGame here). This is much superior than having a single protected function and relying on your more-derived class to remember to call the base version of the method. It&#8217;s too easy to forget, and too easy to get subtle bugs as a result! Of course, there is a cost. It may be, as I develop my games, that I discover I need to call some game-specific code after base.Draw (or base.Update, or what have you). That would become difficult or impossible in this pattern. If things turn out that way, I&#8217;ll have to change it. For now, I&#8217;m enjoying the simplicity of my game-specific methods. I can, quite literally, create a new XNA project, change the main class to inherit from Kensei.Game instead of Microsoft.Xna.Framework.Game, and I&#8217;ve got all the functionality of my Kensei engine instantly available. It&#8217;s very powerful.</p>
<p>(My original plan was going to be even more powerful; I&#8217;d create a simple project using Kensei.Game, and with all the necessary references to the Kensei\bin assemblies, and use that as the basis of a <a href="http://blogs.msdn.com/saraford/archive/2008/10/16/did-you-know-you-can-create-project-templates-336.aspx">Visual Studio Project Template</a>. Then, when creating a new project, I&#8217;d select &#8220;New&#8230; Kensei Game&#8221; instead of &#8220;New&#8230; Microsoft XNA Framework 3.0 Game&#8221;. It <em>nearly</em> worked! Everything was perfect, in fact, except that the Export Template wizard didn&#8217;t pick up the content project. That&#8217;s very unfortunate, and means I can&#8217;t use this trick as I&#8217;d wanted, but if anyone knows a way around it, please let me know.)</p>
<p>I think that&#8217;s enough for now. I hope what I&#8217;ve written makes sense, and gives you some ideas on how to structure your own engine and games, code and assets. I don&#8217;t claim for a second that this is the only way of doing it, and in fact if you&#8217;ve got some better ideas, I&#8217;d love to hear about them &#8211; leave a comment. This has been a fairly high-level view of the problem and my solution to it, and there are so many tradeoffs to be made at a lower level &#8211; something for a future article perhaps, though I&#8217;ve tried a number of different structures over the years, and have heard of still more without trying them out yet, and have yet to settle on a favourite. Something to experiment with, for sure. Anyway &#8211; let me know if this was useful to you.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/108/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/108/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/108/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/108/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/108/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=108&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2008/12/06/foundations/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
		<item>
		<title>Easy Upgrade</title>
		<link>http://bittermanandy.wordpress.com/2008/11/12/easy-upgrade/</link>
		<comments>http://bittermanandy.wordpress.com/2008/11/12/easy-upgrade/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 21:08:16 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=106</guid>
		<description><![CDATA[I was planning to spend the next couple of nights upgrading my Kensei engine and Pandemonium game to XNA 3.0, and making notes of the problems I encountered, so that I may write an article explaining how I overcame them and others may more easily overcome the same problems if they encounter them too.
Unfortunately, I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=106&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>I was planning to spend the next couple of nights upgrading my Kensei engine and Pandemonium game to XNA 3.0, and making notes of the problems I encountered, so that I may write an article explaining how I overcame them and others may more easily overcome the same problems if they encounter them too.</p>
<p>Unfortunately, I can&#8217;t do that &#8211; because if I did, the article would consist of the following: &#8220;It just worked&#8221;.</p>
<p>Yes, it really was as easy as loading up VS 2008 and loading my existing solutions into it. It took a few minutes, to be sure, but I only had to press OK a few times and everything worked. It was so easy that I didn&#8217;t believe it at first &#8211; I did a batch build of all projects, then a batch <em>re</em>build of all projects, then double checked all the references to ensure it really was using XNA 3.0 and hadn&#8217;t just <em>pretended</em> to upgrade from 2.0. But it was true &#8211; the upgrade really did take zero effort.</p>
<p>So I thought I&#8217;d kick things up a notch &#8211; bam! &#8211; and investigate what Microsoft had seen fit to provide us with in an area that was sorely lacking in 2.0: installation and distribution of my game on Windows. Please understand that this is only a preliminary look at what&#8217;s offered, and I might easily have missed some subtleties. Basically you&#8217;ve got three choices:</p>
<p><strong>Package as CCGame:</strong> this particular option seems to be quietly glossed over in the docs so I suspect it&#8217;s just a hangover from XNA 2.0. It&#8217;s got the same old drawbacks, in that the recipient has to have the XNA redistributable already installed, and it doesn&#8217;t offer any choice of installation location or creating shortcuts on the desktop or Start menu. However, on the plus side, the final output is a single compressed file. It&#8217;s much easier to give someone one file than several files and folders.</p>
<p><strong>Setup Project:</strong> assuming you have VS 2008 Professional or higher, you can now create a VS setup project that creates an MSI file. (Instructions are also provided to use a third party installer such as Wise, should you so desire). This would also create a single file, as well as giving total control over installation folders, shortcuts, the ability to show licensing agreements; but the downside is that it doesn&#8217;t automatically recognise content project files as dependencies, which would need to be added individually. There could be thousands of these in a typical game. Not going to happen. You&#8217;ll drive yourself mad trying to keep it in synch with your game. Personally I&#8217;ll be avoiding this option like the plague.</p>
<p><strong>ClickOnce:</strong> obviously the favoured choice at Microsoft, it&#8217;s got a lot of good things going for it. You can set version numbers (and make them update automatically), it installs the .NET and XNA prerequisites for you, you can massage which files get included and define download locations or whether to autorun the CD you burn it onto&#8230; brilliant. Plus you get all the expected shortcuts in the Start menu (but not the Vista Games folder, oddly). The downside? The final output isn&#8217;t a single file! It&#8217;s an exe, and a manifest, and a folder containing all your game files with the extensions changed to .deploy. I don&#8217;t really get what that&#8217;s supposed to save you. Sure, you can zip it up &#8211; but then your user has to open a zip file <em>and</em> run the right exe. You could just as easily zip your game from the bin folder and tell them to run the XNA installer separately, you&#8217;ve not saved anything.</p>
<p>Overall these options are a big leap forward from XNA 2.0 but I still wish they&#8217;d taken just one more step and either made ClickOnce create just one file, or made the Setup Project more intelligent. At least now there&#8217;s a better-than-evens chance that whoever you give your game to will be able to install and play it first time, but it&#8217;s still not quite as simple as it could be. It&#8217;s possible that I&#8217;m missing something, but where the upgrade from 2.0 to 3.0 was a perfectly smooth 10/10 experience, I&#8217;d still have to give the Windows distributable options no more than 8/10.</p>
<p>One thing I do like isn&#8217;t strictly an XNA feature at all, but C# 2008. Select View -&gt; Code Definition Window, and every time you select a symbol in your code (class, function, namespace, enum&#8230;) the window will update to show you the code definition of that symbol. It&#8217;s <em>priceless</em> and I officially love it. I&#8217;m looking forward to using all the other new features of the IDE and the language.</p>
<p>(Though bizarrely, the Open Containing Folder feature on the active item tab only worked the first time I used it, and never since. If anyone can tell me why I&#8217;d be very grateful as I&#8217;d use that all the time).</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/106/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=106&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2008/11/12/easy-upgrade/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
		<item>
		<title>Garbage, Part Two (Director&#8217;s Cut): oh, alright then</title>
		<link>http://bittermanandy.wordpress.com/2008/11/12/garbage-part-two-directors-cut-oh-alright-then/</link>
		<comments>http://bittermanandy.wordpress.com/2008/11/12/garbage-part-two-directors-cut-oh-alright-then/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 23:27:16 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Tools and Software Development]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=101</guid>
		<description><![CDATA[You twisted my arm.
Let&#8217;s very quickly go over what you should know already (remember, this isn&#8217;t necessarily a beginner&#8217;s guide to garbage, rather an attempt to explain why what you know about garbage is like it is, and what it means for your code):
1. Value types (ints, floats, and other in-built types, as well as [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=101&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>You twisted my arm.</p>
<p>Let&#8217;s very quickly go over what you should know already (remember, this isn&#8217;t necessarily a beginner&#8217;s guide to garbage, rather an attempt to explain why what you know about garbage is like it is, and what it means for your code):</p>
<p>1. Value types (ints, floats, and other in-built types, as well as any user-defined struct type, eg. Microsoft.Xna.Framework.Vector3 or a struct you define yourself) are created on the stack, so you don&#8217;t need to worry about garbage.</p>
<p>2. Reference types (any class) are created on the heap, so should be used carefully as they will be garbage collected, which can be bad for the frame rate of your game if it happens at an inconvenient time. Part one explains why, in more detail than you really need to know.</p>
<p>As you may be able to guess, it isn&#8217;t quite that simple.</p>
<p>First, it&#8217;s not completely accurate to say that value types are always created on the stack. They will be, if they are created within a function, but not if they are themselves a member of a class, in which case they will exist (as part of the class object) on the heap. It&#8217;s a minor and fairly obvious point but it&#8217;s important to be correct.</p>
<p>Second, it&#8217;s not completely accurate to say that value types never generate garbage. They can, of course, contain reference members, in which case creating a new struct object can indirectly create a new class object, which generates garbage exactly as though you&#8217;d created the class object yourself. It&#8217;s fair to say that this is a slightly unusual thing to do (I&#8217;m not sure I can think of an example?) but it&#8217;s entirely legal and something to watch out for.</p>
<p>Third, remember how I said value types are created on the stack unless they&#8217;re members of a class, and how that was a minor point? Actually it&#8217;s not that minor. Value types contained <em>within</em> reference types are allocated on the heap. For example, arrays <em>always</em> catch out new C#/XNA programmers:</p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;">
<p style="margin:0;"><span style="color:blue;">int</span> a = <span style="color:red;">0</span>;               <span style="color:green;">// System.Int is value type. Allocated on the stack</span></p>
<p style="margin:0;"><span style="color:blue;">int</span>[] b = <span style="color:blue;">new</span> <span style="color:blue;">int</span>[<span style="color:red;">5</span>];    <span style="color:green;">// Array is reference type! Allocated on the heap (garbage!)</span></p>
</div>
<p><!--EndFragment-->Slightly confusingly, passing value types by reference (using &#8216;ref&#8217; or &#8216;out&#8217;) does not &#8220;turn them into&#8221; reference types. It simply means that the object&#8217;s value can (or must, with &#8216;out&#8217;) be changed within the function and those changes are reflected in the original object that exists outside the function. It also means that no temporary object is created to act as the function parameter. For example, v1 below is a copy of another Vector3; creating a new object and copying onto it can be marginally slower than just passing by reference, as with v2, and the difference becomes more pronounced the larger the object. (Remember a reference is eight bytes in size in 32-bit code like XNA, so any struct eight bytes or smaller won&#8217;t benefit from passing by reference at all). For this reason, functions like Vector3.CatmullRom, that take many struct parameters, are provided in two flavours: one, which is more convenient to use, that takes (copies) the inputs by value and returns the result; and another, which is more performant, that takes the inputs by reference and the result is an out parameter. It&#8217;s a pattern you may want to use in your own code though 90% of the time you&#8217;ll just call the more convenient version.</p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;">
<p style="margin:0;"><span style="color:blue;">void</span> F( <span style="color:blue;">ref</span> <span style="color:blue;">int</span> a, <span style="color:blue;">out</span> <span style="color:blue;">int</span> b, <span style="color:#2b91af;">Vector3</span> v1, <span style="color:blue;">ref</span> <span style="color:#2b91af;">Vector3</span> v2 )</p>
<p style="margin:0;">{</p>
<p style="margin:0;">    a = <span style="color:red;">1</span>;        <span style="color:green;">// No garbage here</span></p>
<p style="margin:0;">    b = <span style="color:red;">2</span>;        <span style="color:green;">// Or here either</span></p>
<p style="margin:0;">    m_v1 = v1;    <span style="color:green;">// Or here&#8230; but v1 is a temporary</span></p>
<p style="margin:0;">    m_v2 = v2;    <span style="color:green;">// Or here&#8230; but v2 is passed by reference</span></p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment-->Of course, reference types are always passed by reference anyway (which means a function can always change them; that&#8217;s one thing I miss about C++: const!) so using the &#8216;ref&#8217; keyword for reference types is pointless, though legal. (FXCop rightly points out your mistake though).</p>
<p>There&#8217;s another difference between value and reference types &#8211; more specifically, between structs and classes &#8211; than simply where they live. Reference types can inherit from other reference types (and you therefore get inheritance, polymorphism, and all the other clever object-oriented stuff) while value types cannot inherit at all. And yet &#8211; you are probably aware that any and every type in C# is considered to ultimately derive from System.Object. You will undoubtedly have seen functions like this (particularly in .NET 1.x, before generics came along):</p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;">
<p style="margin:0;"><span style="color:blue;">void</span> G( <span style="color:blue;">object</span> obj )</p>
<p style="margin:0;">{</p>
<p style="margin:0;">    <span style="color:green;">// &#8230;</span></p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment-->If obj can be anything, including a value type, like an int, a float, or a Vector3 &#8211; but value types can&#8217;t derive from anything &#8211; how come you&#8217;re allowed to call G( 3 )? Well, when such a call is made, a temporary object which does derive from System.Object and is known as a &#8220;box&#8221; is created on the heap, and a copy of the value type object placed inside it. Putting the value type in the box is called &#8220;boxing&#8221;, and taking it back out (via a cast, or the &#8216;as&#8217; operator) is known as &#8220;unboxing&#8221;. Critically, the temporary box object is garbage. This means that using value types in functions or containers that rely on type System.Object generate garbage. As a result, boxing is probably the second most common cause of unexpected garbage. To avoid it, avoid using or writing functions or classes that use System.Object &#8211; <a href="http://www.compman.co.uk/scripts/browse.asp?ref=890983">prefer generics</a> instead &#8211; though you can still get caught out if you&#8217;re not careful, as my previous post on <a href="http://bittermanandy.wordpress.com/2008/08/16/tools-of-the-trade-part-two-reflector/">Reflector</a> showed.</p>
<p>So, usually, you will want to use reference types (classes) for your data that stays in memory for a significant amount of time. You&#8217;ll want to be careful with when you allocate it (remember, a garbage collection can only ever happen on an allocation). Value types (structs) are most useful for small, lightweight data. Think about Vector3 &#8211; it only contains three floats and has a handful of methods. The XNA team could have written an abstract base class Vector and specialised it with Vector2, Vector3, Vector4, and VectorN, but what a piece of over-engineering that would have been! More to the point, using vectors (very common objects in 3D games) would have generated masses of garbage. As a struct instead of a class, Vector3 is much more elegant &#8211; you can write things like SetPosition( new Vector3( 1.0f, 2.0f, 3.0f ) ), a thousand times a frame if you like, and know that there&#8217;s no chance of garbage. On the other hand, your main character object is bound to be of class type. It&#8217;s likely to derive from things (interfaces if not classes) and needs to be kept in memory, which means on the heap.</p>
<p>This also implies that if you have an object of class type, you should keep it around if you&#8217;re likely to be able to reuse it. For example, this kind of trick is useful all over the place:</p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;">
<p style="margin:0;"><span style="color:blue;">void</span> F1()</p>
<p style="margin:0;">{</p>
<p style="margin:0;">    <span style="color:navy;">MyClass</span> myObject = <span style="color:blue;">new</span> <span style="color:navy;">MyClass</span>( <span style="color:red;">5</span> );    <span style="color:green;">// Bad! Generates garbage every call!</span></p>
<p style="margin:0;">    myObject.DoSomething();</p>
<p style="margin:0;">}</p>
<p style="margin:0;"> </p>
<p style="margin:0;"><span style="color:blue;">static</span> <span style="color:navy;">MyClass</span> myStaticObject = <span style="color:blue;">new</span> <span style="color:navy;">MyClass</span>( <span style="color:red;">5</span> );</p>
<p style="margin:0;"> </p>
<p style="margin:0;"><span style="color:blue;">void</span> F2()</p>
<p style="margin:0;">{</p>
<p style="margin:0;">    myStaticObject.DoSomething();            <span style="color:green;">// Good! Does not generate garbage!</span></p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment-->Just a couple more things to think about, though I&#8217;m a bit short on space. Some types can be considered as &#8220;atomic&#8221;. Basically what that means is, that if they change, they become a different object. So a Vector3 is non-atomic &#8211; you can change v.X and you still have the same Vector3, just in a slightly different place. But if you have a user defined type PlayerDetails, and you change any of the fields, you&#8217;ve got a completely different &#8220;thing&#8221; to deal with:</p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;">
<p style="margin:0;"><span style="color:#2b91af;">PlayerDetails</span> player( <span style="color:olive;">&#8220;Andy&#8221;</span>, <span style="color:olive;">&#8220;Patrick&#8221;</span> );</p>
<p style="margin:0;">player.FirstName = <span style="color:olive;">&#8220;Fred&#8221;</span>;    <span style="color:green;">// Look out! Now &#8220;Fred Patrick&#8221;, that&#8217;s not right!</span></p>
<p style="margin:0;">player.LastName = <span style="color:olive;">&#8220;Bloggs&#8221;</span>;</p>
</div>
<p><!--EndFragment-->The player details for me are fundamentally a different &#8220;thing&#8221; to the player details for Fred Bloggs. (Language fails me slightly, here, and I&#8217;m also not sure I&#8217;ve picked a great example). Furthermore, if anything unexpected happens in the middle &#8211; the object gets viewed on another thread, or setting LastName throws an exception &#8211; the object can be seen in an invalid state. To prevent this, such atomic types should be <a href="http://www.compman.co.uk/scripts/browse.asp?ref=0321245660">immutable</a> (I&#8217;m just not going to stop linking to those books!), which means you can&#8217;t change any single field, and once an object has been created, it never changes. This is really good software engineering (it allows you to write more correct and more secure code) but can lead to surprising results:</p>
<div style="font-size:10pt;background:white;color:black;font-family:Courier New;">
<p style="margin:0;"><span style="color:blue;">string</span> message = <span style="color:olive;">&#8220;Player &#8220;</span>;</p>
<p style="margin:0;">message += playerNum.ToString();</p>
<p style="margin:0;">message += <span style="color:olive;">&#8221; wins by &#8220;</span>;</p>
<p style="margin:0;">message += points.ToString();</p>
<p style="margin:0;">message += <span style="color:olive;">&#8221; points!&#8221;</span>;</p>
</div>
<p><!--EndFragment-->That short code snipper generates not one, but <em>seven </em>objects: the final message object contains &#8220;Player 1 wins by 6 points!&#8221; for example, while the strings &#8220;Player &#8220;, &#8220;1&#8243;, &#8220;Player 1&#8243;, &#8220;Player 1 wins by &#8220;, &#8220;6&#8243;, and &#8220;Player 1 wins by 6&#8243; are all garbage! System.String is an immutable, atomic, reference type. This was absolutely the right choice by the .NET architects (strings in .NET are wondrous things of great beauty compared to strings in C++) but leads careless game programmers to watch helplessly as their frame rate plummets. Code like the above is probably the number one cause of unwanted garbage &#8211; watch out for it. If you must build strings piece by piece, use a StringBuilder object. (And, if you find yourself creating a type that is atomic and immutable, consider creating a non-atomic mutable MyTypeBuilder class to work with it).</p>
<p>I know what you&#8217;re thinking. &#8220;It would generate less garbage if you didn&#8217;t call playerNum.ToString() and points.ToString(), and just passed in playerNum and points!&#8221; Nice try, but no. System.String.operator+= works with System.Object types, and calls System.Object.ToString(). That means, if you passed playerNum into it, it would box playerNum <em>and</em> still generate the extra string &#8211; boxing and strings, the two worst garbage generators happening at once &#8211; you&#8217;ve made your garbage problem worse, not better!</p>
<p>There&#8217;s a lot to understand about garbage but I hope the last couple of articles have opened your eyes somewhat. I&#8217;ve approached it in a slightly unorthodox way &#8211; most writers will start with an article like this one, explaining the dos and don&#8217;ts, and probably never even cover the topics in the previous article which showed the whys and wherefores. Personally, I like to know what&#8217;s going on &#8220;under the hood&#8221;. You can memorise the rules relating to garbage and write good code, but until you understand the reasons behind the rules you might not write <em>brilliant</em> code. There is one important thing related to garbage I&#8217;ve not covered &#8211; that&#8217;s the Dispose pattern. <a href="http://www.compman.co.uk/scripts/browse.asp?ref=0321245660">This book</a> (there it is again!) explains what it is and how to implement it, much better than I can; the only thing it doesn&#8217;t really cover is the detail of how objects waiting for disposal relates back to the mechanics of garbage collection I covered in Part One, so I <em>might</em> go over that at some point but I&#8217;m not promising anything.</p>
<p>I hope this appeases those of you who wanted a follow-up to Part One, I misjudged what people wanted and apologise for that. There is one way to make sure it doesn&#8217;t happen again &#8211; your feedback is always welcome, let me know what&#8217;s useful, if anything wasn&#8217;t clear, and what you&#8217;d like me to write about in future (though I reserve the right to choose not to <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p><em>&#8220;There&#8217;s four and twenty million doors, on life&#8217;s endless corridor&#8221; &#8211; Oasis</em></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/101/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=101&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2008/11/12/garbage-part-two-directors-cut-oh-alright-then/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
		<item>
		<title>Garbage, Part Two: anticlimax</title>
		<link>http://bittermanandy.wordpress.com/2008/11/11/garbage-part-two-anticlimax/</link>
		<comments>http://bittermanandy.wordpress.com/2008/11/11/garbage-part-two-anticlimax/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 23:12:48 +0000</pubDate>
		<dc:creator>bittermanandy</dc:creator>
				<category><![CDATA[Tools and Software Development]]></category>

		<guid isPermaLink="false">http://bittermanandy.wordpress.com/?p=97</guid>
		<description><![CDATA[Oooooookaaaaaaaaaay, it seems that Part One wasn&#8217;t very interesting as nobody commented on it and not many people even read it. I personally think that the way C# manages garbage is fascinating and immensely clever. Perhaps I&#8217;m the only one!
So I was going to go into a similar level of detail for much more garbage-related stuff, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=97&subd=bittermanandy&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Oooooookaaaaaaaaaay, it seems that Part One wasn&#8217;t very interesting as nobody commented on it and not many people even read it. I personally think that the way C# manages garbage is fascinating and immensely clever. Perhaps I&#8217;m the only one!</p>
<p>So I was going to go into a similar level of detail for much more garbage-related stuff, and spread it out across three or four posts; but that seems a bit pointless given the previous response, a lot of effort for not much gain. I could instead write about it at a very high level, but you can find <a href="http://www.compman.co.uk/scripts/browse.asp?ref=0321245660">better</a> <a href="http://www.compman.co.uk/scripts/browse.asp?ref=890983">resources</a> elsewhere. Sorry&#8230; bit of a let-down this post. I&#8217;ll try to make up for it with the next one.</p>
<p>I&#8217;m planning to get what Pandemonium (such as it is so far) running on XNA 3.0 over the next few days, hopefully I&#8217;ll be able to write a bit about that. I&#8217;m looking forward to getting some actual gameplay up and running, not just the basic systems, which I intend to show as I go. I have a few other topic ideas too. Of course, if there&#8217;s anything you&#8217;d like me to cover, say the word. Check out the kind of things I&#8217;ve written about so far to see the kind of level I&#8217;m writing at (and for).</p>
<p>Back to normal good service soon&#8230;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bittermanandy.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bittermanandy.wordpress.com/97/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bittermanandy.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bittermanandy.wordpress.com/97/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bittermanandy.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bittermanandy.wordpress.com/97/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bittermanandy.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bittermanandy.wordpress.com/97/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bittermanandy.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bittermanandy.wordpress.com/97/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bittermanandy.wordpress.com&blog=4333506&post=97&subd=bittermanandy&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://bittermanandy.wordpress.com/2008/11/11/garbage-part-two-anticlimax/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/dcafbba93dc637c513c6cf8ae3d5ea2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bittermanandy</media:title>
		</media:content>
	</item>
	</channel>
</rss>