<?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>Milkstone Studios &#187; Development</title>
	<atom:link href="http://www.milkstonestudios.com/category/3_development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.milkstonestudios.com</link>
	<description>Independent Game Developers</description>
	<lastBuildDate>Sat, 28 Jan 2012 14:24:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Wool development time distribution</title>
		<link>http://www.milkstonestudios.com/2009/11/wool-development-time-distribution/</link>
		<comments>http://www.milkstonestudios.com/2009/11/wool-development-time-distribution/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 12:24:53 +0000</pubDate>
		<dc:creator>WaaghMan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Wool]]></category>

		<guid isPermaLink="false">http://www.milkstonestudios.com/?p=489</guid>
		<description><![CDATA[While developing Wool, we were measuring the time we spent working on each game part. We think it will be useful to us to help estimate better our future project development times, and the effort needed in each part of it. As you can see, most of the time spent went to Betatest, Level design [...]]]></description>
			<content:encoded><![CDATA[<p>While developing Wool, we were measuring the time we spent working on each game part. We think it will be useful to us to help estimate better our future project development times, and the effort needed in each part of it.</p>
<div id="attachment_490" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.milkstonestudios.com/wp-content/uploads/2009/11/wool-task-distribution.png"  rel="lightbox[roadtrip]"><img class="size-medium wp-image-490" title="Wool development time distribution" src="http://www.milkstonestudios.com/wp-content/uploads/2009/11/wool-task-distribution-300x220.png" alt="Wool development time distribution" width="300" height="220" /></a><p class="wp-caption-text">Wool development time distribution</p></div>
<p>As you can see, most of the time spent went to Betatest, Level design and Graphics Art. The only thing unexpected here was the time spent developing each level.  Despite having an editor that allowed us to design one complete level from scratch in around 15 minutes, the whole process took around 1.3 hours per level (Not including playtest). That is due to level redesigns, subtle modifcations, difficulty tuning, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.milkstonestudios.com/2009/11/wool-development-time-distribution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Little Racers networking decisions</title>
		<link>http://www.milkstonestudios.com/2009/04/little-racers-networking-decisions/</link>
		<comments>http://www.milkstonestudios.com/2009/04/little-racers-networking-decisions/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 13:33:55 +0000</pubDate>
		<dc:creator>WaaghMan</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.milkstonestudios.com/?p=250</guid>
		<description><![CDATA[Here are my decisions about the upcoming online mode of Little Racers. The multiplayer section will allow players to select whether they want to play on System Link or Xbox Live. After that, the player select screen is shown (this screen will only allow profiles able to play in the selected mode: Signed In for [...]]]></description>
			<content:encoded><![CDATA[<p>Here are my decisions about the upcoming online mode of Little Racers.</p>
<p>The multiplayer section will allow players to select whether they want to play on System Link or Xbox Live. After that, the player select screen is shown (this screen will only allow profiles able to play in the selected mode: Signed In for System Link game, and Live profiles for Xbox Live game.</p>
<p>After this screen, there are some menu options available:</p>
<ul>
<li><strong>Host public game</strong>: Equivalent to championship mode. Each player gets points for his position at race finish, plus one extra point if he manages to get the best lap time. This mode allows the host to set some parameters, such as lap number and car class. Everyone will be able to join the game, even at mid-championship (with the handicap that it implies).</li>
<li><strong>Host private game</strong>: Just like public game, but only friends of the host are allowed to join.</li>
<li><strong>Quick join</strong>: This option does a search for available games and, if one or more is found, it joins to the one that offers the best network conditions. If no game is found, a game with some fixed parameters (10 races, 12 max players, random car class, no handicap) is created.</li>
<li><strong>Find</strong>: This mode shows all created games with some info on the creation parameters, and allows the player to join one of them. I&#8217;m not implementing a search function since I don&#8217;t think there will be so many simultaneous games to make it necessary. If the online mode renders very successful and the need of  a search function arises, we&#8217;ll add it.</li>
</ul>
<p>And that&#8217;s the behaviour I&#8217;ve chosen to add for the LR online mode. I&#8217;d like to know your thoughts and suggestions about it. It&#8217;s probably too simple, other games such as Gears Of War 2 have more options and more complex quickjoin behaviour, etc. , but I think that for a game that won&#8217;t probably get more than 10 public games at the same time (that could mean around 120 players), it should be enough and there&#8217;s no need to make this section more complex.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.milkstonestudios.com/2009/04/little-racers-networking-decisions/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Developing an editor (Part 1)</title>
		<link>http://www.milkstonestudios.com/2009/04/developing-an-editor-part-1/</link>
		<comments>http://www.milkstonestudios.com/2009/04/developing-an-editor-part-1/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 07:33:06 +0000</pubDate>
		<dc:creator>Soy1Bonus</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.milkstonestudios.com/?p=222</guid>
		<description><![CDATA[While Waaghman is working very hard on the Little Racers patches and updates (yes, he&#8217;s working full time on the online mode), I&#8217;m coding some tools and editors four our next games. I already did some tools for another game that we started (and it probably won&#8217;t be finished) and it served me as a [...]]]></description>
			<content:encoded><![CDATA[<p>While <strong>Waaghman</strong> is working very hard on the <a href="http://www.milkstonestudios.com/little-racers/">Little Racers</a> patches and updates (yes, he&#8217;s working full time on the online mode), I&#8217;m coding some tools and editors four our next games.</p>
<p>I already did some tools for another game that we started (and it probably won&#8217;t be finished) and it served me as a learning experience. One of the most annoying things of it was the different kind of things formed that part of a level. We had tiles, but also random geometry, player locations and some other things. The code was becoming a real mess that growed on each new iteration.</p>
<p>This time I&#8217;m making a generic level editor, and trying to keep the code clean. The idea is simple: a level has a size, and it can contain layers (just like in photoshop). So you can have a layer which represents a tilemap, and another one that shows the player positions, and all of them are independent.</p>
<p>Right now, the basic framework is done, and I&#8217;ve got some layers working. Of course, it has been designed to load and save the levels to XML. Most of the layers that are missing are just modifications of the ones I made, so it shouldn&#8217;t take long (but if I&#8217;ve learned something through the years is that everything takes more time than expected).</p>
<div id="attachment_223" class="wp-caption aligncenter" style="width: 453px"><a href="http://www.milkstonestudios.com/wp-content/uploads/2009/04/milkeditor_shot1.gif"  rel="lightbox[roadtrip]"><img class="size-full wp-image-223" title="milkeditor_shot1" src="http://www.milkstonestudios.com/wp-content/uploads/2009/04/milkeditor_shot1.gif" alt="MilkEditor Work in Progress" width="443" height="296" /></a><p class="wp-caption-text">MilkEditor Work in Progress</p></div>
<p>I want the editor to be easily customizable, so it can load external layer-types through dlls, so we&#8217;ll be able to use the editor on different games without compiling the full thing. It wasn&#8217;t a high priority feature, but in C# it was done in less than half an hour.</p>
<p> I have to say that I haven&#8217;t had much problems while developing in Windows Forms. Usually, doing this kind of app is something boring, and you end up with lots of little hacks to make the layouts work as expected. But this time, there are tiny ugly things here and there, but everything is much more clean than usual, and I&#8217;m pretty proud of it. I&#8217;m actually enjoying developing this tool.</p>
<p>When I finish this, there are other more &#8216;in-depth&#8217; tools that I have to make. But those are really small apps to simplify some specific tasks. I&#8217;ll post about them when I have some new material to show. See you later!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.milkstonestudios.com/2009/04/developing-an-editor-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Creating 2D geometry from a line strip</title>
		<link>http://www.milkstonestudios.com/2009/03/creating-2d-geometry-from-a-line-strip/</link>
		<comments>http://www.milkstonestudios.com/2009/03/creating-2d-geometry-from-a-line-strip/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 21:45:30 +0000</pubDate>
		<dc:creator>WaaghMan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[XNA Programming]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://www.milkstonestudios.com/?p=119</guid>
		<description><![CDATA[During development of an old prototype that never saw the light, I found the need to create some 2D geometry from a set of points that form a line. After searching for any algorithm that could make what I needed, with no success, I decided to develop my own. The algorithm is very simple, it [...]]]></description>
			<content:encoded><![CDATA[<p>During development of an old prototype that never saw the light, I found the need to create some 2D geometry from a set of points that form a line.</p>
<p>After searching for any algorithm that could make what I needed, with no success, I decided to develop my own.</p>
<p>The algorithm is very simple, it just takes a rope and a width and creates a set of vertices tha form a TriangleStrip to be rendered on screen.</p>
<pre class="brush: csharp; ">

        /// &lt;summary&gt;
        /// Triangulates a line, returning a list of vertices that form a triangle strip
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;contour&quot;&gt;List of points that form the line&lt;/param&gt;
        /// &lt;param name=&quot;width&quot;&gt;Desired with of the geometry&lt;/param&gt;
        /// &lt;returns&gt;list of vertices that form a triangle strip&lt;/returns&gt;
        public static List&lt;Vector2&gt; Process(ReadOnlyCollection&lt;Vector2&gt; contour,float width)
        {
            List&lt;Vector2&gt; result = new List&lt;Vector2&gt;();
            Vector2 normal = Vector2.Zero ;
            // Generate vertices for each point in the line
            for (int i = 0; i &lt; contour.Count; i++)
            {
                // First and last are special cases, the normal is calculated right away
                if (i == contour.Count - 1)
                    normal = GameMath.Normal(contour[i] - contour[i - 1]);
                else if (i == 0)
                    normal = GameMath.Normal(contour[1] - contour[0]);
                else
                {
                    // For the rest of points, determine the normal as the middle angle between the direction of the previous and next segments.
                    Vector2 delta1 = contour[i] - contour[i - 1];
                    Vector2 delta2 = contour[i + 1] - contour[i];
                    if ((delta1.Length()!=0)&amp;amp;&amp;amp;(delta2.Length()!=0))
                    {
                        delta1.Normalize();
                        delta2.Normalize();
                        normal = GameMath.Normal(delta1 + delta2);
                    }

                }
                // Add two vertices to the vertex list
                result.Add(contour[i] - normal * width / 2f);
                result.Add(contour[i] + normal * width / 2f);
            }
            return result;

        }
        /// &lt;summary&gt;
        /// Returns one normal of the 2D vector
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;vector&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        public static Vector2 Normal(Vector2 line)
        {
            float x = line.X; float y = line.Y;
            Vector2 normal = new Vector2();
            if (x != 0)
            {
                normal.X = -y / x;
                normal.Y = 1 / (float)Math.Sqrt(normal.X * normal.X + 1);
                normal.Normalize();
            }
            else if (y != 0)
            {
                normal.Y = 0;
                normal.X = (line.Y&lt;0) ? 1 : -1;
            }
            else
            {
                normal.X = 1;
                normal.Y = 0;
            }
            if (x &lt; 0)
            {
                normal *= -1;
            }
            return normal;
        }
</pre>
<p>That code is well enough to generate a credible line in almost all situations. As for UVs, what I did was assign the even vertices the value (X,0) and odd vertices (X,1), where X is the distance elapsed since the line start.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.milkstonestudios.com/2009/03/creating-2d-geometry-from-a-line-strip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problems with System.Random</title>
		<link>http://www.milkstonestudios.com/2009/03/problems-with-systemrandom/</link>
		<comments>http://www.milkstonestudios.com/2009/03/problems-with-systemrandom/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 08:05:39 +0000</pubDate>
		<dc:creator>WaaghMan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[XNA Programming]]></category>
		<category><![CDATA[csharp]]></category>

		<guid isPermaLink="false">http://www.milkstonestudios.com/?p=69</guid>
		<description><![CDATA[Yesterday I ran a profiling tool (CLR Profiler) to see how Little Racers does with heap memory allocation, and found something strange: The log showed that class System.Random allocated around 88Mbytes of RAM during the whole execution. The reason of this is the way the particle system works: Each particle stores only a seed to [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I ran a profiling tool (CLR Profiler) to see how Little Racers does with heap memory allocation, and found something strange: The log showed that class System.Random allocated around 88Mbytes of RAM during the whole execution.</p>
<p>The reason of this is the way the particle system works: Each particle stores only a seed to generate its random values, and a new Random is generated with that seed each time it needs to be updated (that is, on every frame). So, if we&#8217;re showing 50 particles on a frame, we&#8217;re calling new Random(seed) 50 times.</p>
<p>With System.Random, there was no possible workaround since it doesn&#8217;t have a method available to set the seed without recreating everything. Also, it seems to do some hard work on creation, maybe allocating the N next random numbers, I don&#8217;t know.</p>
<p>Anyway, I found a nice replacement called <a href="http://www.codeproject.com/KB/cs/fastrandom.aspx">FastRandom</a>:  This class has the same interface that System.Random, so they can be easily interchanged. Also, it has a method to set the seed without having to recreate the class.</p>
<p>Anyway, I found a bug in the provided code, related with the methods Next(int) and Next(int,int) , it seems to store a double with the minimum value of an int and then multiply it by the desired range. It didn&#8217;t work for me, so I just replaced it with a modulus. Maybe it&#8217;s a little slower, but it works perfectly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.milkstonestudios.com/2009/03/problems-with-systemrandom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plain XML content in XNA Content Pipeline</title>
		<link>http://www.milkstonestudios.com/2009/03/plain-xml-content-in-xna-content-pipeline/</link>
		<comments>http://www.milkstonestudios.com/2009/03/plain-xml-content-in-xna-content-pipeline/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 22:26:35 +0000</pubDate>
		<dc:creator>WaaghMan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[XNA Programming]]></category>
		<category><![CDATA[content]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://ns355097.ovh.net/gamelicious/?p=45</guid>
		<description><![CDATA[During the first stages of Little Racers development, I found the need of parsing XML data during the game load. The XNA Content Pipeline system includes XML Parsing, but it uses it in a very particular way. I won&#8217;t go much further in the way XNA parses XML because, to be sincere, I&#8217;ve not tried [...]]]></description>
			<content:encoded><![CDATA[<p>During the first stages of Little Racers development, I found the need of parsing XML data during the game load. The XNA Content Pipeline system includes XML Parsing, but it uses it in a very particular way. I won&#8217;t go much further in the way XNA parses XML because, to be sincere, I&#8217;ve not tried it enough to test wether it&#8217;s good or not.<br />
My first impression was that it was too strict (probably due to optimization and type safe issues), moreover during parse I would need access to some data structures that only were available at runtime, so I preferred to store plain XML and parse it during game load.<br />
This can be done by extending the content pipeline and adding a new type. To do this we&#8217;ll need to add two new projects to our solution.</p>
<h1>XmlSource project</h1>
<p>The first project we&#8217;ll create is the one which has the class that stores our xml plain text. I&#8217;ve called it XmlSource.It will have two classes in total.</p>
<h2>XmlSource</h2>
<p>This class is a very simple one. It simply has a string with the xml plain text:</p>
<pre class="brush: csharp; ">

public class XmlSource
{
public XmlSource(string xmlCode)
{
this.xmlCode = xmlCode;
}

private string xmlCode;
public string XmlCode { get { return xmlCode; } }
}
</pre>
<h2>XmlSourceReader</h2>
<p>This class extends ContentTypeReader and simply creates an XmlSource instance from its binary representation. In our case, the binary representation wil be a simple string, so the read is straightforward.</p>
<pre class="brush: csharp; ">

public class XmlSourceReader : ContentTypeReader&lt;XmlSource&gt;
{
/// &lt;summary&gt;
/// Loads an imported shader.
/// &lt;/summary&gt;
protected override XmlSource Read(ContentReader input, XmlSource existingInstance)
{
string xmlData = input.ReadString();

return new XmlSource(xmlData);
}
}
</pre>
<p>With this, our first project is finished. This project is platform-independant (The Xbox needs to read the binary data) and will have to be referenced from every project that uses the XmlSource class, including the second project we&#8217;re making:</p>
<h1>XmlSourceImporter</h1>
<p>The second project(I called it XmlDocumentImporter) is a project of type &#8220;Content Pipeline Extension Library&#8221;. This project is referenced from the Content projects, and converts the source text file to binary data that will be saved in the .xnb files.</p>
<p>This project has 2 files:</p>
<h2>XmlSourceImporter.cs</h2>
<p>This file converts the XML source file into an XmlSource instance, that will be further converted into binary data</p>
<pre class="brush: csharp; ">

[ContentImporter(&quot;.xml&quot;, DisplayName = &quot;Xml Source Importer&quot;)]
class XmlSourceImporter : ContentImporter&lt;XmlSource&gt;
{
public override XmlSource Import(string filename, ContentImporterContext context)
{
string sourceCode = System.IO.File.ReadAllText(filename);
return new XmlSource(sourceCode);
}
}
</pre>
<h2>XmlSourceWriter.cs</h2>
<p>This file converts an XmlSource into binary data, as opposed to XmlSourceReader</p>
<pre class="brush: csharp; ">

[ContentTypeWriter]
class XmlSourceWriter : ContentTypeWriter&lt;XmlSource&gt;
{
protected override void Write(ContentWriter output, XmlSource value)
{
/*StringWriter sw=new StringWriter();
value.Save(sw);
string content = sw.ToString();*/
output.Write(value.XmlCode);
}
public override string GetRuntimeType(TargetPlatform targetPlatform)
{
return typeof(XmlDocument).AssemblyQualifiedName;
}
public override string GetRuntimeReader(TargetPlatform targetPlatform)
{
return typeof(XmlDocumentReader).AssemblyQualifiedName;
}
}
</pre>
<h1>Sample of use</h1>
<p>Once both projects set up (remember to add reference to XmlSourceImporter from the Content project), we can add .xml files to the content project. Under &#8220;Content importer&#8221;, we&#8217;ll need to select &#8220;Xml Source importer&#8221;, instead of the default XNA one.</p>
<p>Once done this, the program sould compile ok. Loading XML from the program now is very easy:</p>
<pre class="brush: csharp; ">

XmlSource xs = Content.Load&lt;XmlSource&gt;(AssetName);
XmlDocument xd = new XmlDocument();
xd.LoadXml(xs.XmlCode);
</pre>
<p>I know this can be a little confusing, i&#8217;ll upload some binaries if someone asks for them.</p>
<p>PS: Here they are: <a href="http://www.milkstonestudios.com/wp-content/uploads/2009/03/xmlsource.zip">Plain Xml Content Importer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.milkstonestudios.com/2009/03/plain-xml-content-in-xna-content-pipeline/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

