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

<channel>
	<title>Game Dev Without a Cause &#187; Robot Legions</title>
	<atom:link href="https://gamedevwithoutacause.com/?cat=16&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://gamedevwithoutacause.com</link>
	<description>Rob&#039;s Thoughts on Games, Game Dev, and Design - Temporary home of Skyboy Games</description>
	<lastBuildDate>Wed, 23 Jul 2014 09:18:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Show Me the Money: Robot Legions</title>
		<link>https://gamedevwithoutacause.com/?p=1853</link>
		<comments>https://gamedevwithoutacause.com/?p=1853#comments</comments>
		<pubDate>Tue, 26 Feb 2013 15:16:29 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XBLIG]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1853</guid>
		<description><![CDATA[Alrighty then, it&#8217;s been about 3 months since I released Robot Legions on Xbox Live Indie Games so I think it&#8217;s about time I came out about how it&#8217;s been selling. Before I get into the numbers, let me preface &#8230; <a href="https://gamedevwithoutacause.com/?p=1853">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/02/show-me-the-money.jpg"><img class="aligncenter size-full wp-image-1855" alt="That's Tom shouting those famous lines...show me the money" src="http://gamedevwithoutacause.com/wp-content/uploads/2013/02/show-me-the-money.jpg" width="500" height="282" /></a><br />
Alrighty then, it&#8217;s been about 3 months since I released <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">Robot Legions</a> on Xbox Live Indie Games so I think it&#8217;s about time I came out about how it&#8217;s been selling. Before I get into the numbers, let me preface by saying that I&#8217;m definitely not buying a private island any time soon. Hell, with these sort of numbers I&#8217;m not quitting my day job any time soon either. Which is fine because I rather like <a href="http://www.inis.jp/" target="_blank">my job</a>. (And we&#8217;re <a href="http://www.inis.jp/jobs/en/" target="_blank">hiring</a>. Nudge, nudge.)<br />
<span id="more-1853"></span></p>
<p>Okay, enough being coy. Money talk.<br />
Since Robot Legion&#8217;s November 28, 2012 release on Xbox Live Indie Games, I&#8217;ve had 2824 downloads of the trial with 751 purchases. At 70 cents a pop (the purchase price is $1 of which 30% goes to Microsoft), that comes out to $525.70 to date. That amount I then split with the <a href="http://sentrygames.com/" target="_blank">original creator</a> of Robot Legions.</p>
<p>Broken down by month, the numbers come out as follows:</p>
<table>
<tr>
<th>Date</th>
<th>Trials</th>
<th>Purchases</th>
</tr>
<tr>
<td>November 2012 (2 days)</td>
<td>601</td>
<td>71</td>
</tr>
<tr>
<td>December 2012</td>
<td>1460</td>
<td>412</td>
</tr>
<tr>
<td>January 2013</td>
<td>540</td>
<td>199</td>
</tr>
<tr>
<td>February 2013 (21 days)</td>
<td>223</td>
<td>69</td>
</tr>
</table>
<p>So, that&#8217;s not a lot of money, but then again I wasn&#8217;t really expecting that much. Of course, I wouldn&#8217;t mind making more money but I&#8217;m mostly thankful to have a hobby that doesn&#8217;t cost me money and allows me to keep my gamedev skills sharp.</p>
<p>Still, it is worth noting that the conversion rate (purchase over trials) for the game comes out to 26.59%. Compared to old-school shareware numbers (which generally had a conversion rate of &lt; 10%) that number is pretty good. For Xbox Live Indie Games however, that&#8217;s a fairly average number (and low compared to successful XBLIG titles.) The Xbox Live Indie Games market may be small but it is abnormally focused. The people who actually go there are primed to buy games and it shows in the conversion rates.</p>
<p>As a side note, my 2010 Xbox Live Indie Games release <a href="http://marketplace.xbox.com/en-US/Product/Legend-of-the-Rune-Lords/66acd000-77fe-1000-9115-d8025855054d" target="_blank">Legend of the Rune Lords</a> is pulling in around 25 purchases a month.  Since December 2011, it&#8217;s managed to total about 376 purchases.  So, the <a href="http://en.wikipedia.org/wiki/Long_tail" target="_blank">long tail</a> is there on XBLIG, it&#8217;s just really, really thin.</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1853</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#OneGameAMonth Status Report</title>
		<link>https://gamedevwithoutacause.com/?p=1818</link>
		<comments>https://gamedevwithoutacause.com/?p=1818#comments</comments>
		<pubDate>Tue, 12 Feb 2013 15:39:48 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XBLIG]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1818</guid>
		<description><![CDATA[It&#8217;s February and I&#8217;ve been at #OneGameAMonth for about 6 weeks now, so I thought it was about time to comment on how it&#8217;s going. Before that though, a few words about why I&#8217;m doing #OneGameAMonth (#1GAM for short) in &#8230; <a href="https://gamedevwithoutacause.com/?p=1818">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/02/logo-feb.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2013/02/logo-feb.png" alt="logo-feb" width="768" height="208" class="aligncenter size-full wp-image-1821" /></a><br />
It&#8217;s February and I&#8217;ve been at <a href="http://www.onegameamonth.com/" target="_blank">#OneGameAMonth</a> for about 6 weeks now, so I thought it was about time to comment on how it&#8217;s going.</p>
<p>Before that though, a few words about why I&#8217;m doing #OneGameAMonth (#1GAM for short) in the first place.  Here is the mission statement from my #OneGameAMonth <a href="http://www.onegameamonth.com/nobunagaota" target="_blank">profile</a> page:</p>
<blockquote><p>My biggest hope in joining #OneGameAMonth is to use it as a chance to challenge all my assumptions about how games should be made. By holding to the seemingly impossible goal of One Game a Month, I hope to find what I need to change (and what I&#8217;m unwilling to sacrifice) in order to make more, better games. Also, making friends and becoming AWESOME!</p></blockquote>
<p>My main goal is to challenge myself to approach game development in ways that I haven&#8217;t before.  So, this is how am I doing so far:<span id="more-1818"></span></p>
<p>For my first #OneGameAMonth project, I decided to start with an easy warm-up: an update of an existing game. In this case, an <a href="http://gamedevwithoutacause.com/?p=1759" title="New Update Out for Robot Legions on XBLIG!" target="_blank">update</a> for my latest XBLIG game, <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">Robot Legions</a>. Be sure to check it out to see how it went.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/Screenshot05.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/Screenshot05.jpg" alt="Screenshot05" width="1000" height="562" class="aligncenter size-full wp-image-1765" /></a></p>
<p>For my next trick, I&#8217;m going to try for a real challenge and make a new game.</p>
<p>Naturally, making a new game from scratch takes time so I&#8217;m leveraging as much of my previous projects as possible.  I&#8217;m even going so far as copying my last released game&#8217;s code wholesale and then replacing the parts I need to make my new game.  While I am spending some time cleaning up and excising code I don&#8217;t need, I expect this approach to pay dividends once I start having to implement menus and such.  If I can get away with just re-skinning and adjusting the flow of my previous title&#8217;s menu code, I can spend that much more time focused on the gameplay itself.</p>
<p>The other weapon in my time-saving arsenal is an almost single-minded focus on the game&#8217;s concept.  I want to do ONE THING with this game and that is replicate the feeling of an <a href="http://www.urbandictionary.com/define.php?term=Itano%20circus" target="_blank">Itano Circus</a>. The Itano Circus (or &#8220;Macross Missile Massacre&#8221;) refers to the wild flurries of missiles that occur in anime dogfights like those in Macross. Check out the video below if you want to see what I mean:<br />
<iframe width="584" height="438" src="http://www.youtube.com/embed/BzXfVgYCxWI?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>While making a game, it&#8217;s easy to have feature creep set in and blow the scope of the project.  As much as possible, I&#8217;m trying to stay aware of that phenomenon and stop myself went it starts to take place.  Whenever I have a new idea for the game, I ask myself: &#8220;Does this help the Itano Circus feel?&#8221;  If not, I cut it.  Then and there.</p>
<p>Here are screenshots of what I have so far.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/02/Itano_WIP01.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2013/02/Itano_WIP01.png" alt="Itano_WIP01" width="1280" height="720" class="aligncenter size-full wp-image-1837" /></a></p>
<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/02/Itano_WIP02.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2013/02/Itano_WIP02.png" alt="Itano_WIP02" width="1280" height="720" class="aligncenter size-full wp-image-1838" /></a><br />
(It&#8217;s probably not coincidental that every choice I make to bring out the Itano Circus-ness of the game seems to take it closer to <a href="http://www.youtube.com/watch?v=-IFIVFbR1fM" target="_blank">Afterburner II</a>. I imagine the creators of that game drew inspiration from many of the same sources I&#8217;m now using.)</p>
<p>So far, I&#8217;m managing to keep focused on my goal.  Hopefully I can keep it up and finish this game this month.  After all, I have a new project waiting for me next month because, well you know, #OneGameAMonth.</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1818</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Update Out for Robot Legions on XBLIG!</title>
		<link>https://gamedevwithoutacause.com/?p=1759</link>
		<comments>https://gamedevwithoutacause.com/?p=1759#comments</comments>
		<pubDate>Tue, 29 Jan 2013 14:10:26 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XBLIG]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1759</guid>
		<description><![CDATA[I&#8217;m proud to announce that the latest update for Robot Legions is now available on Xbox Live Indie Games. You can grab it from the Indie Games section of your Xbox 360 or over the web from this page. This &#8230; <a href="https://gamedevwithoutacause.com/?p=1759">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/RLV2.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/RLV2.jpg" alt="RLV2" width="444" height="358" class="aligncenter size-full wp-image-1762" /></a><br />
I&#8217;m proud to announce that the latest update for Robot Legions is now available on Xbox Live Indie Games. You can grab it from the Indie Games section of your Xbox 360 or over the web from this <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">page</a>. </p>
<p>This update improves upon the original with new graphical effects and an added ability for the player to toggle their firing modes.  Now you can switch between synced and alternating fire modes allowing you to choose between accuracy and rate-of-fire as best fits the situation.<span id="more-1759"></span></p>
<p>New visual effects in this version are bullet trails, smoke from explosions and a new vignette shader effect.  These new effects can be toggled on or off in the options menu for people who prefer the original look of the game.</p>
<p>Check out these screenshots for a taste of what the new Robot Legions has to offer:<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/Screenshot05.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/Screenshot05.jpg" alt="Screenshot05" width="1000" height="562" class="aligncenter size-full wp-image-1765" /></a></p>
<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/Screenshot06.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/Screenshot06.jpg" alt="Screenshot06" width="1000" height="562" class="aligncenter size-full wp-image-1766" /></a></p>
<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/Screenshot07.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2013/01/Screenshot07.jpg" alt="Screenshot07" width="1000" height="562" class="aligncenter size-full wp-image-1767" /></a></p>
<p>Robot Legions, <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">available now</a> on Xbox Live Indie Games.</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1759</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Easy Way to Break Your Save Data in XNA</title>
		<link>https://gamedevwithoutacause.com/?p=1675</link>
		<comments>https://gamedevwithoutacause.com/?p=1675#comments</comments>
		<pubDate>Tue, 25 Dec 2012 14:33:44 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1675</guid>
		<description><![CDATA[Late last week, I finally managed to pass an update for Robot Legions out onto the Xbox Live Marketplace. I wasn&#8217;t originally planning to release an update this early (I have some other features in-the-works for the &#8220;real&#8221; next update), &#8230; <a href="https://gamedevwithoutacause.com/?p=1675">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/broken-hard-disk.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/broken-hard-disk.jpg" alt="broken-hard-disk" width="449" height="300" class="aligncenter size-full wp-image-1679" /></a><br />
Late last week, I finally managed to pass an update for <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">Robot Legions</a> out onto the Xbox Live Marketplace. I wasn&#8217;t originally planning to release an update this early (I have some other features in-the-works for the &#8220;real&#8221; next update), but&#8230; I had a bug.  A nasty save data killing bug.</p>
<p>Yuck.</p>
<p>So, in the interest of helping other XNA devs out there, let me tell you about what I screwed up and how I fixed it.<span id="more-1675"></span></p>
<p>So, let&#8217;s get to the meat.  Let me show you how I screwed up my save data handling.</p>
<p>First, this is how I read my save data:</p>
<pre class="brush: c#">
// Deserialization
XmlSerializer s = new XmlSerializer(typeof(T));
if (container.FileExists(filename))
{
    TextReader r = new StreamReader(container.OpenFile(filename, FileMode.Open));
    saveDataItem = (T)s.Deserialize(r);
    r.Close();
}
container.Dispose();

</pre>
<p>And this is how I wrote it:</p>
<pre class="brush: c#">
// Serialization
XmlSerializer s = new XmlSerializer(saveDataItem.GetType());
TextWriter w = new StreamWriter(container.OpenFile(filename, FileMode.OpenOrCreate));
s.Serialize(w, saveDataItem);
w.Close();
</pre>
<p>See the bug?  Yeah, well, neither did I.  You see, there was this little problem with how I wrote my save data.  The code above would work in most cases, but if I wrote data that was shorter than the previous file&#8217;s save data, the old save data would only be partially overwritten.  Any bytes of the old save data not explicitly overwritten by the new save data would remain appended to the end of the new save data. Thus potentially turning data like this:</p>
<pre class="brush: xml">
&lt;RobotSaveData&gt;&lt;Cash&gt;12345&lt;/Cash&gt;&lt;/RobotSaveData&gt;
</pre>
<p>Into data like this:</p>
<pre class="brush: xml">
&lt;RobotSaveData&gt;&lt;Cash&gt;123&lt;/Cash&gt;&lt;/RobotSaveData&gt;a&gt;
</pre>
<p>And totally confounding the XML deserializer.  Voila! Broken save data and unhappy customers.  To top it off, as far as I can tell, this behavior doesn&#8217;t replicate on Windows, only on the Xbox 360.  You can imagine my consternation.</p>
<p>Enough about what went wrong.  Here&#8217;s how I went about fixing it.  I changed the way I opened a file for writing my save data:</p>
<pre class="brush: c#">
// Serialization
XmlSerializer s = new XmlSerializer(saveDataItem.GetType());
TextWriter w = new StreamWriter(
    container.FileExists(filename) ?
    container.OpenFile(filename, FileMode.Truncate) :
    container.OpenFile(filename, FileMode.Create)
);
s.Serialize(w, saveDataItem);
w.Close();
</pre>
<p>This big difference here is that I use FileMode.Truncate when opening the file for writing save data.  By doing this, I&#8217;m able to dispose of the old contents and completely overwrite them with my new save data.</p>
<p><strong>EDIT:</strong> I was recently informed by one of the fine members of the XBLIG community that simply using FileMode.Create when I open a file is sufficient for my purposes since it&#8217;s behavior when a file exists is the same as FileMode.Truncate.</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1675</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Robot Legions on YouTube Digest</title>
		<link>https://gamedevwithoutacause.com/?p=1649</link>
		<comments>https://gamedevwithoutacause.com/?p=1649#comments</comments>
		<pubDate>Tue, 11 Dec 2012 14:46:26 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XBLIG]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1649</guid>
		<description><![CDATA[A couple weeks ago, I released Robot Legions on Xbox Live Indie Games. It is available now for 80 Microsoft Points. I also released a trailer for the game: But wait, there&#8217;s more! I&#8217;m not the only one posting on &#8230; <a href="https://gamedevwithoutacause.com/?p=1649">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>A couple weeks ago, I released <a href="http://gamedevwithoutacause.com/?p=1625" title="Robot Legions has arrived on Xbox Live Indie Games!" target="_blank">Robot Legions</a> on Xbox Live Indie Games.  It is <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">available</a> now for 80 Microsoft Points.  I also released a trailer for the game:<br />
<iframe width="584" height="329" src="http://www.youtube.com/embed/TWJEvrROwYQ?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>But wait, there&#8217;s more!  I&#8217;m not the only one posting on YouTube about Robot Legions.  Here are a few picks from other folks talking about and playing Robot Legions on their Xbox 360s:<br />
<span id="more-1649"></span></p>
<p><strong>Lets Play Indie Games: Robot Legions XBLIG</strong> by <strong>SecretSuperHer0</strong>:<br />
<iframe width="584" height="329" src="http://www.youtube.com/embed/Fqe9I5YYtsk?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p><strong>Fun with 80 MSPs: Robot Legions (XBLA Indie Game)</strong> by <strong>pjdaddelgreis</strong>:<br />
<iframe width="584" height="329" src="http://www.youtube.com/embed/B_0gHd9V-iA?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p><strong>Robot Legions 20 Minute XBLIG Gameplay</strong> by <strong>aaronthesplazer</strong>:<br />
<iframe width="584" height="329" src="http://www.youtube.com/embed/i1YAsFxw-Os?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>Robot Legions on Xbox Live Indie Games: <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">Get it now</a>!</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1649</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Robot Legions has arrived on Xbox Live Indie Games!</title>
		<link>https://gamedevwithoutacause.com/?p=1625</link>
		<comments>https://gamedevwithoutacause.com/?p=1625#comments</comments>
		<pubDate>Tue, 04 Dec 2012 12:37:00 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XBLIG]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1625</guid>
		<description><![CDATA[I&#8217;m proud to announce that Robot Legions is now available on Xbox Live Indie Games. For the low, low price of 80 Microsoft Points ($1 US), you can play Robot Legions on your Xbox 360. Click here to see the &#8230; <a href="https://gamedevwithoutacause.com/?p=1625">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/RobotLegion-2012-12-02-03-05-14-01.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/RobotLegion-2012-12-02-03-05-14-01-1024x576.jpg" alt="" title="RobotLegion 2012-12-02 03-05-14-01" width="584" height="328" class="aligncenter size-large wp-image-1633" /></a><br />
I&#8217;m proud to announce that Robot Legions is <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">now available</a> on Xbox Live Indie Games.  For the low, low price of 80 Microsoft Points ($1 US), you can play Robot Legions on your Xbox 360.</p>
<p>Click <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">here</a> to see the Robot Legions product page on Xbox.com.<br />
<span id="more-1625"></span></p>
<p><strong>About Robot Legions</strong><br />
Blast your way through the legions of robots to liberate your homeplanet! Robot Legions is a twin-stick arena shooter that features several different enemy types, each with unique behavior. As players defeat enemies, they will collect cash that they can use to upgrade their defense and firepower. The game also features several special feats to accomplish for players who want an extra challenge.</p>
<p><strong>Screenshots</strong><br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/Screenshot01.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/Screenshot01.jpg" alt="" title="Screenshot01" width="1000" height="562" class="aligncenter size-full wp-image-1636" /></a></p>
<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/Screenshot02.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/Screenshot02.jpg" alt="" title="Screenshot02" width="1000" height="562" class="aligncenter size-full wp-image-1637" /></a></p>
<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/Screenshot03.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/Screenshot03.jpg" alt="" title="Screenshot03" width="1000" height="562" class="aligncenter size-full wp-image-1638" /></a></p>
<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/Screenshot04.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/12/Screenshot04.jpg" alt="" title="Screenshot04" width="1000" height="562" class="aligncenter size-full wp-image-1639" /></a></p>
<p><strong>Gameplay Movies</strong>(Courtesy of <a href="http://www.youtube.com/user/aaronthesplazer" target="_blank">AaronTheSplazer</a>)</p>
<p>A 5 minute video starting in the game&#8217;s free trial mode:<br />
<iframe width="584" height="329" src="http://www.youtube.com/embed/3HBGvgMV41Y?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>An extended 20 minute video of the full version of the game. You can see some of the enemy variety that shows up as you progress:<br />
<iframe width="584" height="329" src="http://www.youtube.com/embed/i1YAsFxw-Os?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>Robot Legions, available now on Xbox Live Indie Games.  Get it <a href="http://marketplace.xbox.com/en-US/Product/Robot-Legions/66acd000-77fe-1000-9115-d80258550c46" target="_blank">now</a>!</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1625</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using CLRProfiler to Take Out the Trash, Part 2</title>
		<link>https://gamedevwithoutacause.com/?p=1570</link>
		<comments>https://gamedevwithoutacause.com/?p=1570#comments</comments>
		<pubDate>Tue, 13 Nov 2012 14:22:39 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1570</guid>
		<description><![CDATA[In last week&#8217;s post, I described how I used CLRProfiler to identify a couple parts of my code that were producing garbage every frame. One related to equality comparisons with my ActorState struct and another involving System.Objects being produced when &#8230; <a href="https://gamedevwithoutacause.com/?p=1570">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/M-O__character_of_WALL.E_.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/M-O__character_of_WALL.E_.jpg" alt="" title="M-O_(_character_of_WALL.E_)" width="341" height="512" class="aligncenter size-full wp-image-1575" /></a><br />
In last week&#8217;s post, I described how I used CLRProfiler to identify a couple parts of my code that were producing garbage every frame. One related to equality comparisons with my ActorState struct and another involving System.Objects being produced when I called RuntimePropertyInfo.SetValue().  This time, I&#8217;ll talk about what I did to fix those two problems.<span id="more-1570"></span></p>
<p><b>Fixing Problem #1: Structs as Dictionary Keys</b><br />
So, according to the CLRProfiler, I&#8217;m creating ActorStates via Generic.ObjectEqualityComparer::Equals() during my ChooseTargetNode() function. Looking at that code, it simple looks like I&#8217;m checking against a Dictionary that uses ActorState as a key. A quick Google search turns up this <a href="http://www.xnawiki.com/index.php?title=Enumerations_as_Dictionary_Keys" target="_blank">tidbit on XNA Wikia</a>.  The article talks about how Enums cause memory allocations when used as keys in Dictionaries.  It&#8217;s fair to assume that structs would have similar behavior and cause garbage to be created when used by the Dictionary&#8217;s internal comparison functions.  Luckily, the fix for this is easy.  If a struct implements IEquatable, Dictionary won&#8217;t allocate instances of that struct during comparisons.  Since my ActorState struct already implemented comparison functions, I just needed to add IEquatable as a part of its declaration.</p>
<pre class="brush: c#">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EstrellaLib.Actor
{
    public struct ActorState : IEquatable&lt;ActorState&gt;
    {
        string _stateName;

        public ActorState(string stateName)
        {
            _stateName = stateName.ToUpperInvariant();
        }

        public string StateName
        {
            get
            {
                return _stateName;
            }
            set
            {
                _stateName = value.ToUpperInvariant();
            }
        }

        public override bool Equals(object obj)
        {
            if (obj is ActorState)
            {
                return this.Equals((ActorState)obj);
            }
            return false;
        }

        public bool Equals(ActorState p)
        {
            return _stateName == p._stateName;
        }

        public override int GetHashCode()
        {
            return _stateName.GetHashCode();
        }

        public static bool operator ==(ActorState lhs, ActorState rhs)
        {
            return lhs.Equals(rhs);
        }

        public static bool operator !=(ActorState lhs, ActorState rhs)
        {
            return !(lhs.Equals(rhs));
        }

        public static ActorState None = new ActorState(&quot;NONE&quot;);
    }
}
</pre>
<p>Once I did that, ActorState disappeared from my allocation list on a second CLRProfiler run.</p>
<p><b>Fixing Problem #2: Value Type Boxing with PropertyInfos</b><br />
While the boxing problem caused by my code is relatively straight-forward:</p>
<pre class="brush: c#">
        public override void ApplyToActor(Actor targetActor)
        {
            if (_targetProperty == null)
            {
                _targetProperty = targetActor.GetType().GetProperty(_targetName);
                _targetActor = targetActor;
            }
            System.Diagnostics.Debug.Assert(_targetActor == targetActor);

            //PropertyInfo.SetValue(object obj, object value, object[] index)&#039;s second parameter
            // causes any value types I pass to it to be boxed in a temporary System.Object
            _targetProperty.SetValue(targetActor, _targetValue, null);
        }
</pre>
<p>Fixing it, is not quite as easy as simply implementing a particular interface.  I need to find a way to avoid calling SetValue().  Thankfully, PropertyInfo provides a way for me to get a delegate for setting the properties value that is typed to the value I&#8217;m trying to set.  This means that, if I go through the setter delegate, I can avoid implicitly casting my value type to a System.Object and creating garbage.  With a bit of work, I modify my code and end up with something like this:</p>
<pre class="brush: c#">
        public override void ApplyToActor(Actor targetActor)
        {
            if (_targetActor == null)
            {
                PropertyInfo targetProperty = targetActor.GetType().GetProperty(_targetName);
                _targetActor = targetActor;

                MethodInfo setter = targetProperty.GetSetMethod();
                System.Diagnostics.Debug.Assert(setter != null);
                _propertySetter = (Action&lt;T&gt;)Delegate.CreateDelegate(typeof(Action&lt;T&gt;), targetActor, setter);
            }
            System.Diagnostics.Debug.Assert(_targetActor == targetActor);
            System.Diagnostics.Debug.Assert(_propertySetter != null);
            _propertySetter(_targetValue);
        }
</pre>
<p>It&#8217;s not as easy to read as the version using SetValue, but it doesn&#8217;t produce any garbage.  For a function that will be called multiple times a frame, it&#8217;s totally worth it.</p>
<p><b>Enjoying the Fruits of my Labor</b><br />
With my code changes in place, I fire up CLRProfiler again to make sure I get the expected effect.  The GC Timeline ends up looking something like this.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic08.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic08.png" alt="" title="CLRPic08" width="445" height="184" class="aligncenter size-full wp-image-1562" /></a></p>
<p>There we go!  A few GCs occurring when the game starts up, but once we get to the Title screen: nothing.  Just a flat plane of constant memory use.  My garbage collection problems are solved! At least in this part of the game.</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1570</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using CLRProfiler to Take Out the Trash, Part 1</title>
		<link>https://gamedevwithoutacause.com/?p=1541</link>
		<comments>https://gamedevwithoutacause.com/?p=1541#comments</comments>
		<pubDate>Tue, 06 Nov 2012 14:22:26 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1541</guid>
		<description><![CDATA[As cutesy as it may be, I&#8217;m growing rather fond of my garbage collection count display. I&#8217;m especially fond of it because it helped me find garbage collections occuring in places I never expected them to happen. Such as my &#8230; <a href="https://gamedevwithoutacause.com/?p=1541">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/wall-e.jpeg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/wall-e.jpeg" alt="" title="wall-e" width="450" height="333" class="aligncenter size-full wp-image-1542" /></a></p>
<p>As cutesy as it may be, I&#8217;m growing rather fond of my <a href="http://gamedevwithoutacause.com/?p=1523" title="Getting Cute with Performance Metrics (and Reducing Memory Usage too!)" target="_blank">garbage collection count display</a>.  I&#8217;m especially fond of it because it helped me find  garbage collections occuring in places I never expected them to happen.  Such as my title screen for example:<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/RobotLegion-2012-11-02-14-05-04-39.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/RobotLegion-2012-11-02-14-05-04-39-1024x576.jpg" alt="" title="RobotLegion 2012-11-02 14-05-04-39" width="584" height="328" class="aligncenter size-large wp-image-1547" /></a></p>
<p>Ack!  Look at all those garbage cans, I mean recycling bins (reduce, reuse, recycle, folks!)</p>
<p>That&#8217;s a lot of garbage collections for a &#8220;static&#8221; title screen.  Now, how to find out what&#8217;s causing all that garbage to be created&#8230; That&#8217;s where Microsoft&#8217;s <a href="http://www.microsoft.com/en-us/download/details.aspx?id=16273" target="_blank">CLRProfiler</a> comes into play.<span id="more-1541"></span></p>
<p><b>Running CLRProfiler</b><br />
CLRProfiler is a great tool for profiling your XNA game&#8217;s memory usage.  It can produce graphs and tables that tell you exactly when your game is allocating what classes.  It&#8217;s also a bit rough around the edges and hard to use.  Even installing it eschews the oh-so-common installer for a zip file (a rarity in Windows tools nowadays.)</p>
<p>So, once I get my hands on the tool, the first thing I have to do is get my game running with CLRProfiler.  Pressing the Start Application button seems like a good place to start, but first I need to set my working directory or else my game won&#8217;t be able to find its data while it&#8217;s being run. To do that, I click on File->Set Parameters then set the working directory to the directory where my game&#8217;s executable lives.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic01.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic01.png" alt="" title="CLRPic01" width="615" height="426" class="aligncenter size-full wp-image-1548" /></a></p>
<p>Next, to make sure I get all the information I need, I enable both Allocations and Calls in the Profile section. With those settings done, I&#8217;m ready to hit the Start Application button and select my game&#8217;s executable for profiling.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic02.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic02.png" alt="" title="CLRPic02" width="336" height="255" class="aligncenter size-full wp-image-1549" /></a></p>
<p><b>Diagnosing the Problem</b><br />
At this point, I let my game run to the title screen so I can gather data on memory applications.  After a few seconds, I shut down my game and let CLRProfiler chew on the data and present it to me.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic03.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic03.png" alt="" title="CLRPic03" width="885" height="541" class="aligncenter size-full wp-image-1550" /></a></p>
<p>Since I&#8217;m worried about garbage collection, I&#8217;ll take a look at the GC Timeline.  Clicking the &#8220;Time Line&#8221; button gives me a graph of memory at various GC generations like this one:<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic04.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic04-1024x660.png" alt="" title="CLRPic04" width="584" height="376" class="aligncenter size-large wp-image-1552" /></a></p>
<p>See that sawtooth pattern on the bottom timeline there?  Those are garbage collections.  Memory builds up until it hits a threshold then garbage collection kicks in and drops the total memory usage.  After that memory begins to build up again until it hits the threshold and triggers another collection and so on. Now that I know how I&#8217;m allocating memory, it&#8217;s time to find out what I&#8217;m allocating.  Box-selecting one of the sawtooths, I produce a report of what is in memory at that point.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic05.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic05-1024x667.png" alt="" title="CLRPic05" width="584" height="380" class="aligncenter size-large wp-image-1553" /></a></p>
<p>The list on the right shows me all objects instantiated during the period I box-selected. Lots of System.Objects and lots of ActorStates.  The ActorState structs are definitely being produced by my code and the System.Objects are probably being produced by the way I&#8217;m using .NET. Right-clicking on the list of allocated objects, I produce a graph of which function calls allocated which objects.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic06.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic06-1024x590.png" alt="" title="CLRPic06" width="584" height="336" class="aligncenter size-large wp-image-1554" /></a></p>
<p>All the way on the right are my System.Object and ActorState allocations.  Tracking back to the left, I can follow the function calls to find out where these allocations are happening.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic07.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/11/CLRPic07-1024x594.png" alt="" title="CLRPic07" width="584" height="338" class="aligncenter size-large wp-image-1555" /></a></p>
<p>Aha, looks like ActorStates are being allocated when they are being compared.  As for the System.Objects, it looks like my calls into the .NET&#8217;s Reflection code are responsible.  Considering that RuntimePropertyInfo.SetValue() takes a System.Object as a parameter and my code is generally passing in value types, this looks like a textbook case of boxing.</p>
<p>Now, thanks to CLRProfiler, I know where my garbage collection problems are coming from. Next week, I&#8217;ll go into what I can do to fix them.</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1541</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Cute with Performance Metrics (and Reducing Memory Usage too!)</title>
		<link>https://gamedevwithoutacause.com/?p=1523</link>
		<comments>https://gamedevwithoutacause.com/?p=1523#comments</comments>
		<pubDate>Tue, 30 Oct 2012 14:05:34 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1523</guid>
		<description><![CDATA[I&#8217;ve lamented before about how unfortunate it was that my frametime display allocated memory and would cause garbage collections to occur. Well, I found a simple solution for my memory allocation problem and, if I say so myself, it&#8217;s kind &#8230; <a href="https://gamedevwithoutacause.com/?p=1523">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/Unify-icon-elements.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/Unify-icon-elements.png" alt="" title="Unify-icon-elements" width="369" height="362" class="aligncenter size-full wp-image-1524" /></a><br />
I&#8217;ve lamented <a href="http://gamedevwithoutacause.com/?p=1442" title="Measuring Frametime Revisited" target="_blank">before</a> about how unfortunate it was that my frametime display allocated memory and would cause garbage collections to occur.  Well, I found a simple solution for my memory allocation problem and, if I say so myself, it&#8217;s kind of&#8230; cute.<span id="more-1523"></span></p>
<p>Okay, so enough being coy, what did I actually do?  Basically, I replaced my frametime and memory displays with icons.  I retain the original text-based display as an option when I need more detail, but most of the time, I can use the icon-based display to keep me aware of my basic performance profile.  You can see the new frametime display in action in this screenshot from work-in-progress Robot Legions (upper-left corner):<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/RL_PerfIcons.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/RL_PerfIcons-1024x576.jpg" alt="" title="RL_PerfIcons" width="584" height="328" class="aligncenter size-large wp-image-1538" /></a></p>
<p>There are 2 major elements to this new, memory-allocation-free frametime display. One is the stopwatch whose neighboring smiley face changes color and expression depending on how high the frametime is.  If my frametime grows to a level where I would start dropping frames, the face icon becomes an angry red.  The other element is the row of garbage cans (actually recycling bins because we&#8217;re eco-friendly around here) that show the number of recent garbage collections.  It&#8217;s not a lot of information but it&#8217;s just enough to let me know when I should start using my heavier-duty profiling tools to dig into a problem.</p>
<p>In case you want to use this sort of display in your own project, you can grab the icon spritesheet here.<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/PerfIconSheet.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/PerfIconSheet.png" alt="" title="PerfIconSheet" width="160" height="32" class="aligncenter size-full wp-image-1535" /></a></p>
<p>The icons are originally from the public domain <a href="http://tango.freedesktop.org/Tango_Icon_Library" target="_blank">Tango Icon Library</a>.  You can go there to find icons suitable for a variety of purposes.</p>
<p>The latest code for my frametime display code is below:</p>
<pre class="brush: c#">
#if DEBUG
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace EstrellaLib.Debug
{
    /// &lt;summary&gt;
    /// This is a game component that implements IUpdateable.
    /// &lt;/summary&gt;
    public class FrametimeCounterComponent : Microsoft.Xna.Framework.DrawableGameComponent
    {
        enum PerfIconType
        {
            Stopwatch,
            GarbageBin,
            HappyFace,
            NeutralFace,
            SadFace
        }

        Stopwatch FrametimeStopwatch;

        const int PERF_ICON_WIDTH = 32;
        Texture2D PerfIconSheet;
        SpriteFont FrametimeDisplayFont;
        SpriteBatch FrametimeDisplayBatch;

        bool ShowFrametimeText;

        public Vector2 FrametimeDisplayPosition;
        public Color FrametimeDisplayColor;

        const double FRAMETIME_DANGER_THRESHOLD = 1000.0f / 60.0f;      //If averaged frametime goes over this threshold...
        const float DANGER_COLOR_DISPLAY_SECONDS = 2.0f;                //... the frametime display will change color for this many seconds.
        
        float DangerTimer;
        public Color FrametimeDangerDisplayColor;
        float AveragedFrameTime;

        public bool ShowAveragedFrametime;

        WeakReference GcDetectionReference;
        long TotalMemoryKB;

        float RecentGarbageCollections;

        public FrametimeCounterComponent(Game game, bool showFrametimeText)
            : base(game)
        {
            ShowAveragedFrametime = true;
            FrametimeDisplayPosition = Vector2.One * 10.0f;
            FrametimeDisplayColor = Color.Green;
            FrametimeDangerDisplayColor = Color.Magenta;
            GcDetectionReference = new WeakReference(null);
            RecentGarbageCollections = 0;
            ShowFrametimeText = showFrametimeText;
        }

        /// &lt;summary&gt;
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// &lt;/summary&gt;
        public override void Initialize()
        {
            FrametimeStopwatch = new Stopwatch();
            FrametimeStopwatch.Start();
            base.Initialize();
        }

        protected override void LoadContent()
        {
            FrametimeDisplayBatch = new SpriteBatch(Game.GraphicsDevice);
            PerfIconSheet = Game.Content.Load&lt;Texture2D&gt;(&quot;Textures/PerfIconSheet&quot;);
            FrametimeDisplayFont = Game.Content.Load&lt;SpriteFont&gt;(&quot;Debug/Fonts/Default&quot;);
            base.LoadContent();
        }

        /// &lt;summary&gt;
        /// Allows the game component to update itself.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;gameTime&quot;&gt;Provides a snapshot of timing values.&lt;/param&gt;
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            float deltaSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds;
            TimeSpan frameTime = FrametimeStopwatch.Elapsed;
            FrametimeStopwatch.Reset();
            FrametimeStopwatch.Start();

            RecentGarbageCollections = MathHelper.Max(0.0f, RecentGarbageCollections - deltaSeconds * 0.1f);        //Subtract 1 RecentGC every 10 seconds
            if (!GcDetectionReference.IsAlive)
            {
                GcDetectionReference = new WeakReference(new Object());
                TotalMemoryKB = GC.GetTotalMemory(false) / 1024;
                RecentGarbageCollections+=1.0f;
            }
           

            AveragedFrameTime = AveragedFrameTime * 0.9f + (float)frameTime.TotalMilliseconds * 0.1f;
            DangerTimer = MathHelper.Clamp(DangerTimer - deltaSeconds, 0.0f, DANGER_COLOR_DISPLAY_SECONDS);
            if (AveragedFrameTime &gt; FRAMETIME_DANGER_THRESHOLD)
            {
                DangerTimer = DANGER_COLOR_DISPLAY_SECONDS;
            }

            int displayItemCount = 0;
            FrametimeDisplayBatch.Begin();
           
            if (ShowFrametimeText)
            {
                FrametimeDisplayBatch.DrawString(FrametimeDisplayFont, &quot;Frame Time: &quot; + (ShowAveragedFrametime ? AveragedFrameTime : frameTime.TotalMilliseconds) + &quot;ms&quot;, FrametimeDisplayPosition + Vector2.UnitY * (FrametimeDisplayFont.LineSpacing * displayItemCount++), DangerTimer &gt; 0.0f ? FrametimeDangerDisplayColor : FrametimeDisplayColor);
                FrametimeDisplayBatch.DrawString(FrametimeDisplayFont, &quot;Total Memory: &quot; + TotalMemoryKB + &quot;KB&quot;, FrametimeDisplayPosition + Vector2.UnitY * (FrametimeDisplayFont.LineSpacing * displayItemCount++), FrametimeDisplayColor);
                FrametimeDisplayBatch.DrawString(FrametimeDisplayFont, &quot;Recent GCs: &quot; + (int)RecentGarbageCollections, FrametimeDisplayPosition + Vector2.UnitY * (FrametimeDisplayFont.LineSpacing * displayItemCount++), FrametimeDisplayColor);
            }

            DrawIcon(PerfIconType.Stopwatch, FrametimeDisplayPosition + Vector2.UnitY * (FrametimeDisplayFont.LineSpacing * displayItemCount));
            DrawIcon(FrametimeToPerfIcon(ShowAveragedFrametime ? AveragedFrameTime : (float)frameTime.TotalMilliseconds), FrametimeDisplayPosition + Vector2.UnitX * PERF_ICON_WIDTH + Vector2.UnitY * (FrametimeDisplayFont.LineSpacing * displayItemCount));
            displayItemCount++;

            int garbageX = 0;
            int garbageY = 0;
            for (int i = 0; i &lt; (int)RecentGarbageCollections; ++i)
            {
                DrawIcon(PerfIconType.GarbageBin, FrametimeDisplayPosition + Vector2.UnitX * PERF_ICON_WIDTH * garbageX + Vector2.UnitY * (FrametimeDisplayFont.LineSpacing * displayItemCount) + Vector2.UnitY * (FrametimeDisplayFont.LineSpacing * garbageY));
                garbageX++;
                if (garbageX &gt; 10)
                {
                    garbageY++;
                    garbageX = 0;
                }
            }
            displayItemCount++;

            FrametimeDisplayBatch.End();

            base.Draw(gameTime);
        }

        private void DrawIcon(PerfIconType iconType, Vector2 position)
        {
            FrametimeDisplayBatch.Draw(PerfIconSheet, position, new Rectangle((int)iconType * PERF_ICON_WIDTH, 0, PERF_ICON_WIDTH, PERF_ICON_WIDTH), Color.White);
        }

        private PerfIconType FrametimeToPerfIcon(float frameTime)
        {
            if (frameTime &lt; FRAMETIME_DANGER_THRESHOLD * 0.75f )
            {
                return PerfIconType.HappyFace;
            }
            else if (frameTime &lt; FRAMETIME_DANGER_THRESHOLD * 1.5f)
            {
                return PerfIconType.NeutralFace;
            }

            return PerfIconType.SadFace;
        }
    }
}
#endif
</pre>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1523</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Announcing… Robot Legions for Xbox Live Indie Games</title>
		<link>https://gamedevwithoutacause.com/?p=1498</link>
		<comments>https://gamedevwithoutacause.com/?p=1498#comments</comments>
		<pubDate>Tue, 16 Oct 2012 14:09:25 +0000</pubDate>
		<dc:creator><![CDATA[Rob]]></dc:creator>
				<category><![CDATA[Robot Legions]]></category>
		<category><![CDATA[XBLIG]]></category>

		<guid isPermaLink="false">http://gamedevwithoutacause.com/?p=1498</guid>
		<description><![CDATA[After a brief stint in iOS development, I&#8217;m back to my Xbox Live Indie Games ways. For some games, you really need a physical controller in order for them to feel right. That feel is something I&#8217;ve really focused on &#8230; <a href="https://gamedevwithoutacause.com/?p=1498">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/logo.png"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/logo.png" alt="" title="logo" width="384" height="177" class="aligncenter size-full wp-image-1500" /></a><br />
After a brief stint in <a href="http://gamedevwithoutacause.com/?page_id=296" target="_blank">iOS development</a>, I&#8217;m back to my Xbox Live Indie Games ways.  For some games, you really need a physical controller in order for them to feel right.  That feel is something I&#8217;ve really focused on in my latest project.</p>
<p>Robot Legions is a new twin-stick arena shooter for the Xbox 360.  It features several different enemy types, each with unique behavior.  As players defeat enemies, they will collect cash that they can use to upgrade their defense and firepower.  The game also features several special feats to accomplish for players who want an extra challenge.<span id="more-1498"></span></p>
<p>This game is a port of the original Robot Legions flash game developed by <a href="http://sentrygames.com/" target="_blank">Sentry Games</a>.  Naturally, I&#8217;ll be updating the game a bit to take advantage of the Xbox 360&#8217;s horsepower.  If you&#8217;d like to play the original, you can find it <a href="http://www.kongregate.com/games/playvortex/robot-legions" target="_blank">here</a> on Kongregate. </p>
<p>As the XBLIG version of Robot Legions nears completion, I plan on posting it for play-testing on the Xbox Live Indie Games site.  If you happen to be a member, drop me a line and I will let you know once the game hits playtest.</p>
<p>So, yeah.<br />
Robot Legions.<br />
For Xbox Live Indie Games.<br />
Coming soon to an Xbox near you!<br />
<a href="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/Boxart.jpg"><img src="http://gamedevwithoutacause.com/wp-content/uploads/2012/10/Boxart.jpg" alt="" title="Boxart" width="584" height="700" class="aligncenter size-full wp-image-1503" /></a><br />
Boo-yah!</p>
]]></content:encoded>
			<wfw:commentRss>https://gamedevwithoutacause.com/?feed=rss2&#038;p=1498</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
