<?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>Lakehome Games</title>
	<atom:link href="http://lakehomegames.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://lakehomegames.com</link>
	<description>Indie Game Development and Sea Shanties</description>
	<lastBuildDate>Tue, 14 May 2013 04:05:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='lakehomegames.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/bb093723b2b1206d8275e37c5f2ddee6?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Lakehome Games</title>
		<link>http://lakehomegames.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://lakehomegames.com/osd.xml" title="Lakehome Games" />
	<atom:link rel='hub' href='http://lakehomegames.com/?pushpress=hub'/>
		<item>
		<title>Server Migration in Unity 4.0.1</title>
		<link>http://lakehomegames.com/2013/05/13/server-migration-in-unity-4-0-1/</link>
		<comments>http://lakehomegames.com/2013/05/13/server-migration-in-unity-4-0-1/#comments</comments>
		<pubDate>Tue, 14 May 2013 04:05:29 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=189</guid>
		<description><![CDATA[Sometimes in game development, it really is best to simply &#8220;build your own,&#8221; iterating out from core functionality to final product.  This is especially true when you are trying to accommodate a game mechanic that is not served well by existing code &#8230; <a href="http://lakehomegames.com/2013/05/13/server-migration-in-unity-4-0-1/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=189&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://lakehomegames.files.wordpress.com/2013/05/server_migration.png"><img class="aligncenter size-full wp-image-191" alt="server_migration" src="http://lakehomegames.files.wordpress.com/2013/05/server_migration.png?w=584"   /></a></p>
<p>Sometimes in game development, it really <strong>is</strong> best to simply &#8220;build your own,&#8221; iterating out from core functionality to final product.  This is especially true when you are trying to accommodate a game mechanic that is not served well by existing code bases.  Other times, a game engine or a piece of middleware will do everything you need it to do, and your only job is to simply integrate it correctly.  Unity Networking can be <strong>both</strong> these things &#8211; depending on what you are trying to accomplish.  I have heard the complaints about Unity&#8217;s networking model (and probably lodged quite a few myself); but I would also like to show that <strong>with a little extra work</strong>, you can extend the usefulness of Unity&#8217;s built-in networking to a much wider range of projects.</p>
<p>As you probably know by now, I have been writing a series of articles that demonstrate how Unity&#8217;s built-in networking can be used for peer-to-peer networking.  In my first article, I demonstrated <a href="http://www.gamasutra.com/blogs/DarrelCusey/20130221/187128/Unity_Networking_Sample_Using_One_NetworkView.php" target="_blank">how a single NetworkView could be used for each client</a> (instead of 1 NetworkView per client and per player).  In my second article, I demonstrated <a href="http://www.gamasutra.com/blogs/DarrelCusey/20130307/188088/Server_Discovery_in_Unity_401.php" target="_blank">how Server Discovery could be added</a> to this as well.  Building on this foundation, this third article will demonstrate how Server Migration can be achieved.</p>
<p>For those of you unfamiliar with Server Migration&#8230; the simplest explanation is that it simply allows your multiplayer game to keep running even when the server has left the game.  One way to accomplish this (and the route we took) is by seamlessly changing the role of a chosen client to the role of server, having all other clients re-connect, and then the game continues.</p>
<h2>Server Migration Goals</h2>
<p>Server Migration must accomplish two goals:</p>
<ol>
<li>It must use a server-choosing scheme that will result in the same server being chosen by all clients simultaneously.  That way each client knows whether it will continue to be a client or if its role has changed to the server.</li>
<li>It must guarantee that all clients have (or have access to) the same data that the server is using at any time to maintain game state should the server fail.</li>
</ol>
<p>If you haven&#8217;t grabbed the Unity package yet for this article yet, <a href="https://dl.dropboxusercontent.com/u/74664687/Samples/server_migration_sample_2013_05_12.unitypackage" target="_blank">go grab it from here</a>, open up the NetworkController and let&#8217;s walk through some of the more interesting points.</p>
<p>Let&#8217;s also use this process flow diagram to make things a little easier to follow:</p>
<p><a href="http://lakehomegames.files.wordpress.com/2013/05/server_migration_overview.png"><img class="aligncenter size-full wp-image-190" alt="server_migration_overview" src="http://lakehomegames.files.wordpress.com/2013/05/server_migration_overview.png?w=584&#038;h=528" width="584" height="528" /></a></p>
<p>&nbsp;</p>
<p>Let&#8217;s start with a brief overview of what&#8217;s happening here.  The Server Migration project is built on top of the Server Discovery project, so the Server Discovery pieces are not shown in the diagram above.  We&#8217;ll assume, though, that the client has found a server and successfully connected.  We&#8217;ll explain The Happy Path (left-hand side), and The Unhappy Path (right-hand side).</p>
<h2>The Happy Path</h2>
<p>Most of the time, the client (and server/client) is happily running through its Update() loop.  During that loop, though, we need to check to see if the game state has entered one of three special states: ServerStarting, ServerReconnecting or ServerAdding.</p>
<ul>
<li>ServerStarting happens when the server has disconnected and the local client has determined that it will be the new server.</li>
<li>ServerReconnecting happens when the server has disconnected and the local client has determined that it will not be the new server (it will stay in the client role).</li>
<li>ServerAdding happens when the client has first connected to a server, and it is waiting a short amount of time before requesting the complete players list.</li>
</ul>
<p>Each of these states includes a brief delay before they do their work and &#8220;back out&#8221; from that special state.  Technically speaking, it would be more robust to add an additional conversation between the client and server to let the server control when this transition happens.  I decided to leave those out, however, just to make it easier to see what&#8217;s going on &#8212; a simple time delay is sufficient for our needs.  Those cases follow this general pattern:</p>
<pre>case((int)State.serverstarting):
 if(Time.realtimeSinceStartup &gt; exitStateTime){
 statecontrol.PopState();
 StartServer();
 ListenForClients(statecontrol.GetLastGameName());
 }
 break;</pre>
<p>As you can see from the diagram, before &#8220;backing out&#8221; of these special states, the client performs a different set of actions for each state.  The PopState() function is useful for sending us back to &#8220;wherever we were&#8221; in the game because the special states can be entered at any time &#8212; even during states the represent GUI menu states.  <em>After all, if the server is going to fail, it doesn&#8217;t care if you are in the menu or not.</em></p>
<h2>The Unhappy Path</h2>
<p>Now that we&#8217;ve reviewed the management of these special states &#8212; let&#8217;s look at the right-hand side of the diagram which shows how those states are entered in the first place.  Before we do that, though, there are two subjects that we must cover&#8230;</p>
<h4><em>Synchronicity Fail</em></h4>
<p>From my testing, it appears as though the message dispatcher in Unity is completely independent of the Update() function loop.  In other words, they are asynchronous, or least neither relies upon execution of the other.  Don&#8217;t get me wrong, I&#8217;m not saying this is a Bad Thing.  However, we must take this into consideration because that means that it is extremely easy to get into a situation where we are generating an OnDisconnectedFromServer() over and over again &#8212; with no recourse for an Update() call to get out of it.  This can easily create an infinite loop.  Infinite loops are bad.</p>
<p>The same could be said for almost any built-in Unity message function &#8212; there is no guarantee that an Update() will get called in-between any two messages &#8212; or even get called at all.  Because of this, we need a way to &#8220;put a lock&#8221; on the messages so that we can deal with them and then prevent them from being called again until we specifically &#8220;unlock&#8221; them.  Those checks looks like this:</p>
<pre>int cs = statecontrol.GetState();
 if((cs==(int)State.serverstarting) | (cs==(int)State.serverreconnecting)) return;</pre>
<p>For this project, I only need this lock for the OnDisconnectedFromServer() message.  When this message is caught by this function, it <strong>guarantees</strong> that it will always push ServerStarting or ServerReconnecting onto the state stack.  I then check for either of these states at the top of the OnDisconnectedFromServer() function and make and early exit if that is the state we are in.  The Update() function will see these states, and after a short delay, will do the work required to exit those states and finally pop the states off the stack.</p>
<h4><em>The Deal with The NetworkPlayer Struct</em></h4>
<p>I really hope that someone is able to prove me wrong, about this &#8212; because it would sure be convenient to use the NetworkPlayer struct (&#8220;NPS&#8221; for short) to pass-around client data.  All my testing, however, can only lead me to one conclusion &#8212; Unity is hard-coded to prevent sending an NPS to a &#8220;third party.&#8221;  In other words, the client and the server for any given connection can freely pass that client or that server&#8217;s NPS back and forth &#8212; but one client&#8217;s NPS can&#8217;t be sent to another client.  Client A can never receive the NPS of client B.</p>
<p>If you think about it, this is a Good Thing because you probably don&#8217;t want to expose both your internal (NAT) and external (WAN) IP addresses and ports to a complete stranger (ie. another player in a game that you don&#8217;t even know).  I can see how maybe Unity did this on purpose &#8212; but it seems odd that they&#8217;d go out of their way to do so.  Perhaps RakNet did it for them though <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>In any case, it doesn&#8217;t really have that much effect on us &#8212; we&#8217;ll just send the information we need to send &#8220;manually.&#8221;  This amounts to little more than adding a couple of additional attributes to the JoinPlayer() signature and makes the code more self-documenting anyways :p</p>
<pre>[RPC]
 void JoinPlayer(string ip, int p, string g, Vector3 pos, NetworkViewID nv){
...
}</pre>
<h2>Back to the Unhappy Path</h2>
<p>OK&#8230; now that we&#8217;ve got those two discussion behind us, all we really need to cover is the function that is used on all clients to come to the same conclusion about who should be the next server.  It&#8217;s easy, actually &#8212; which just pick the client with the lowest GUID value.  Because all clients know the GUIDs of all other clients, they will all come to the same conclusion.  It also gives us a really good excuse for using LINQ &#8212; everyone wins:</p>
<pre>chosenServer = players.Aggregate((c, d) =&gt; Convert.ToUInt64(c.guid) &lt; Convert.ToUInt64(d.guid) ? c : d);</pre>
<h2>Returning to The Happy Path</h2>
<p>So, there we have it.  When the server disconnects, each client will independently come to the same conclusion about who will be the next server.  The client that has the lowest GUID value will start up a new server and start listening for connections.  The other clients will wait a small delay and then connect to the new server.  The new server will automatically re-associate the connecting clients with their existing game objects at their current locations, and the game continues <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I hope you enjoyed this article, as always thanks for reading!</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/189/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/189/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=189&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2013/05/13/server-migration-in-unity-4-0-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2013/05/server_migration.png" medium="image">
			<media:title type="html">server_migration</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2013/05/server_migration_overview.png" medium="image">
			<media:title type="html">server_migration_overview</media:title>
		</media:content>
	</item>
		<item>
		<title>Unity Networking &#8211; What I Really Think</title>
		<link>http://lakehomegames.com/2013/05/10/unity-networking-what-i-really-think/</link>
		<comments>http://lakehomegames.com/2013/05/10/unity-networking-what-i-really-think/#comments</comments>
		<pubDate>Fri, 10 May 2013 05:48:28 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=187</guid>
		<description><![CDATA[For reasons unknown to me, people will walk right up to me on the street and ask me things like this: &#8220;I&#8217;ve heard a lot of people complain about Unity networking.  I&#8217;ve been thinking about using a third-party solution.  Even &#8230; <a href="http://lakehomegames.com/2013/05/10/unity-networking-what-i-really-think/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=187&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>For reasons unknown to me, people will walk right up to me on the street and ask me things like this:</p>
<p><em>&#8220;I&#8217;ve heard a lot of people complain about Unity networking.  I&#8217;ve been thinking about using a third-party solution.  Even you have brought down some harsh criticism in some of your blog posts.  But, what do you really think about it?&#8221;</em></p>
<p>At that point, I&#8217;ll usually just pay my bus fair and look the bus driver straight in the eye and respond &#8220;Unity networking is preventing developers from swimming in lava &#8211; so, I think it&#8217;s a good thing.&#8221;  Of course, there&#8217;s a lot more to it than that &#8212; so, let&#8217;s jump right in&#8230;</p>
<h2>Good Vibrations</h2>
<p>It seems to me that the choice of using a simple client-server networking model in Unity was first and foremost nothing more than a good business decision.  <span style="font-style:inherit;line-height:1.625;">I think the vast majority of their <strong>customers</strong> will only ever need a simple client-server networking model.  Most won&#8217;t even need any multiplayer functionality at all (at least the ones who are successful won&#8217;t). Also, the vast majority of their <strong>customers</strong> would be at least somewhat familiar with the basic tenants of the client-server networking model. And with that familiarity comes a sense of ease&#8230; which leads to good will, positive word of mouth advertising, greater market share, and ultimately more sales.  I think Unity knew this was the case, so that&#8217;s why they kept it simple.</span></p>
<p><span style="font-style:inherit;line-height:1.625;">You may have noticed that I kept making customers bold above.  I did that so that you would keep in mind that Unity Technologies is a business &#8212; so they must make decisions that will keep their business running.  If you are using the free version of Unity, you should be extremely happy that Unity runs their business this way &#8212; it is only because their business model works that you have that free version at all.  </span></p>
<p>Implementing anything more than a simple client-server networking model (I&#8217;ll use MMO networking as an example throughout this post, but the argument holds true for any type of networking) would have been a monumental waste of time and energy.  The number of people that actually could use that technology would be tiny.  The number of developers that actually know how to use that technology AND wouldn&#8217;t just want to code it themselves would be infinitesimal.</p>
<p>If Unity <strong>had included</strong> MMO networking tools, they would have only succeeded in creating an unending stream of complaints from people who were not experienced in multiplayer networking.  The chorus of &#8220;it doesn&#8217;t work,&#8221; would have drowned out everything else &#8212; like for example the fact that &#8220;you aren&#8217;t doing it right.&#8221;  It was a good business decision, and that&#8217;s why you have a free copy &#8212; simple as that.</p>
<p><span style="color:#000000;font-weight:bold;font-style:inherit;line-height:1.625;">Judge Not</span></p>
<p>Let&#8217;s just think logically for a minute about who is complaining about Unity networking.  If someone is complaining then that must mean one of the following must be FALSE:</p>
<ul>
<li>The person complaining really MUST actually need that networking functionality for his/her game.</li>
<li>The person complaining MUST NOT know how to code that networking functionality themselves.</li>
</ul>
<p>That may seem a little harsh &#8212; but if you think about it for a little bit, you&#8217;ll see that these two statements can&#8217;t both be true for the same developer.  If someone says to you, &#8220;I want to build an MMO &#8211; it sucks that Unity doesn&#8217;t include MMO networking,&#8221; ask them if they have implemented (not just studied) all of the following in C++ (this is a shortened list):</p>
<ul>
<li>Latency Compensation</li>
<li>Movement Prediction (Interpolation, Extrapolation)</li>
<li>Dead-Reckoning, Splines, or other Message-Reduction techniques</li>
<li>Dynamic Server/Zone Partitioning</li>
<li>Server Migration</li>
<li>Player Migration and Hand-Off</li>
<li>Anti-Duping/Cloning code for above Migration functions</li>
<li>Active/Passive; Active/Active Servers and Lossless Failover</li>
<li>In-Memory Databases and Persistence Priority Considerations</li>
</ul>
<p>You can replace &#8220;MMO&#8221; above with &#8220;Peer-to-Peer Networking&#8221; or any other networking model and change the questions accordingly.  If the answers to any of these questions are &#8220;no&#8221; then that developer probably isn&#8217;t going to be implementing an MMO anytime soon.  I know, still harsh&#8230; but keep in mind that most businesses will not consider you an &#8220;expert&#8221; in any skill until you have at least 10,000 hours under you belt.  If you think about all the foundation knowledge required to just get to the point of programming simple Latency Compensation&#8230; well it&#8217;s staggering.  It&#8217;s amazing that people even get to that point in a single life.  Let&#8217;s use an example to elaborate further though&#8230;</p>
<p>If you were considering building a house, you probably wouldn&#8217;t hire someone who has never used a hammer or any other construction tools before.  You would probably also rank that person&#8217;s &#8220;house building probability&#8221; as near-to-zero.  Also, if you look at a professional carpenter, and you see that she is using a nail gun, you wouldn&#8217;t think to yourself, &#8220;well, if I just got a nail gun, I could build a house!&#8221;  That would be insane.</p>
<p>Just because you have the tool, doesn&#8217;t mean you can use it properly.  Using the same line of thinking, even if Unity did include all the tools that you needed to implement MMO networking, how many developers would actually be able to correctly implement them?  And if they <strong>did</strong> know how to correctly implement them, what are the chances that they would <strong>NOT</strong> want to just code it themselves?  See what I&#8217;m saying here &#8212; it&#8217;s incredibly unlikely that those two statements are true for the same developer.</p>
<p>When a carpenter uses a nail gun, it&#8217;s because she first learned how to use a hammer and has made the informed decision (from years of experience) that the nail gun is the better choice for this particular situation.  When a developer says to me, &#8220;well, I&#8217;ll just buy a bunch of third-party tools,&#8221; in my head I usually imagine a rookie carpenter swinging around a nail gun.  I&#8217;m not saying that&#8217;s the case for every developer &#8212; just the vast majority <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>The Tale of the Real</h2>
<p>Another comment I frequently read is that &#8220;Unity networking won&#8217;t work in a Real World case.&#8221;  This to me is the most preposterous statement of all.  What people should be asking is, &#8220;Will Unity networking do exactly what its documentation says it will do?&#8221; Yes, yes it will.  &#8221;Will Unity networking allow you to run a network game, where the performance of the game and the number of players it can support is <strong>directly proportional</strong> to the skill that you as a developer have put into its networking and game code?&#8221;  Yes, yes it will.</p>
<p>If you swing around a nail gun, you shouldn&#8217;t be surprised if people get their eyes shot out.  If you implement Unity networking in your program with very little effort, then you shouldn&#8217;t be surprised if you don&#8217;t get very good results.  For example, even if we stay strictly in the realm of using only Unity networking (and nothing in C# from .NET), have you considered:</p>
<ul>
<li>Does everything that moves need a Network View?</li>
<li>Do Network Views need to be Enabled all the time?</li>
<li>Is your object better off with reliable or unreliable Synchronization?</li>
<li>Does an object&#8217;s Network View really even need to observe its owner as it&#8217;s target?</li>
<li>Have you considered using a proxy target that has no animation data (or other types of data you don&#8217;t actually need)?</li>
<li>Then there is the whole area of RPCs &#8212; do you need Network Views at all?</li>
<li>What kind of information needs to be sent when and to whom?</li>
</ul>
<p>If you complain about Unity networking, but haven&#8217;t even considered any of the above&#8230; here, let me show you something&#8230; it&#8217;s called a hammer <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>So What Do I Really Think?</h2>
<p>I think Unity was very smart to include only a basic client-server networking model.  It was  a good business decision, and it kept developers from &#8220;swimming in lava&#8221; by trying to implement an MMO with no previous experience (which is again good for business).</p>
<p>HOWEVER, I will be the first to admit that Unity networking certainly has its limitations &#8212; but those limitations are pretty well documented.  All of its documentation states pretty clearly that it is designed for Client-Server networking.  It even goes as far as to &#8220;pull back the covers&#8221; on its internal network design (RakNet-based), and even points you to that documentation where you can read all about that middleware&#8217;s capabilities.  The Unity community echoes these capabilities on a regular basis as well, so you can&#8217;t exactly say how surprised you were when you tried to get 200 clients running off your laptop now can you?</p>
<p>That&#8217;s not to say these limitations can&#8217;t be overcome with a good understanding of networking and some clever code.  For me, Unity is a challenge &#8212; a puzzle box that I can shake and hear all kinds of wonderful things inside.  And every time I unlock a drawer of this proverbial puzzle box called Unity.. every time I find a false bottom or lift the lid of a hidden drawer &#8212; I find a little undocumented secret, a cleverly hidden constructor or some odd behavior.  And that&#8217;s when something snaps into place, and my understanding of the Why and the How of Unity expands.</p>
<p>And for me&#8230; that&#8217;s the best game there is <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/187/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=187&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2013/05/10/unity-networking-what-i-really-think/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>
	</item>
		<item>
		<title>Server Discovery in Unity 4.0.1</title>
		<link>http://lakehomegames.com/2013/03/07/server-discovery-in-unity-4-0-1/</link>
		<comments>http://lakehomegames.com/2013/03/07/server-discovery-in-unity-4-0-1/#comments</comments>
		<pubDate>Thu, 07 Mar 2013 19:00:49 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=179</guid>
		<description><![CDATA[This Unity Package can be downloaded here (updated): server_discovery_sample_2013_03_07.unitypackage For most developers, Unity truly goes out of its way to make things as easy as possible for game development.  For example, switching your camera type from perspective to orthographic takes &#8230; <a href="http://lakehomegames.com/2013/03/07/server-discovery-in-unity-4-0-1/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=179&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><strong>This Unity Package can be downloaded here (updated):</strong></p>
<p><a title="server_discovery_sample_2013_03_07.unitypackage" href="https://dl.dropbox.com/u/74664687/Samples/server_discovery_sample_2013_03_07.unitypackage" target="_blank">server_discovery_sample_2013_03_07.unitypackage</a></p>
<p>For most developers, Unity truly goes out of its way to make things as easy as possible for game development.  For example, switching your camera type from perspective to orthographic takes just a click of a button.  Switching lights from spot, to directional, to area; again, just a click of a button.  However, there are a few parts of Unity that, surprisingly, have no options whatsoever.  One of these parts is Unity&#8217;s networking design.  Unity is stubbornly Client-Server in its networking design.  There&#8217;s no drop-down box where you can switch it over to peer-to-peer networking &#8211; this is left as an exercise for the programmer.</p>
<p>A peer-to-peer system, though, can be developed on top of Unity&#8217;s existing client server networking framework by adding additional components that will allow the server to migrate among all networked clients.  Minimally, we&#8217;ll need to build 3 components: Shared State, Server Discovery and Server Migration.  In <a title="Unity FPS Networking Sample" href="http://lakehomegames.com/2012/12/05/unity-fps-networking-sample/" target="_blank">my previous article</a>, I described a simple FPS Networking Sample that could maintain state across all clients using a single NetworkView on each client.  <em><strong>An additional advantage</strong></em> to this system is that each client maintained the same information as the &#8220;server.&#8221;  Because of this, the Shared State requirement has already been met.  The clients are not sharing a <strong>lot</strong> of information (just the list of players and their locations and targets)&#8230; but for now, that&#8217;s sufficient.</p>
<p>In this article, I&#8217;ll tackle <strong>Server Discovery</strong> and finally demonstrate Server Migration in a follow-up article.  I&#8217;m going to review the most important parts of this solution, so if you haven&#8217;t already grabbed the Unity package above, you should do so now so you can follow along.  Let&#8217;s start with a process flow diagram&#8230;</p>
<p><a href="http://lakehomegames.files.wordpress.com/2013/03/server_discovery_overview.png"><img class="aligncenter size-full wp-image-180" alt="server_discovery_overview" src="http://lakehomegames.files.wordpress.com/2013/03/server_discovery_overview.png?w=584&#038;h=594" width="584" height="594" /></a></p>
<p>One of my design goals for this solution was to make it so that a client could easily switch over to become a server at any time.  Until we put in the last Server Migration piece, this is done manually by following these steps:</p>
<ol>
<li><strong><span style="line-height:15px;">Start a single-player game</span></strong></li>
<li><strong>Hit Escape</strong></li>
<li><strong>Select &#8220;Open to LAN&#8221;</strong></li>
</ol>
<p>Now your game will be available to others, but most importantly you are able to start a single player game <strong>without connecting to a server first</strong>.  If you look at a <strong>lot</strong> of other Unity Networking tutorials, this isn&#8217;t even possible.  A lot of other tutorials will use Network.Instantiate(), or else make it so that the client only instantiates a player upon the specific direction of the server. <em> So, how do we both instantiate at the direction of the server while not actually being connected to a sever?</em></p>
<p>Easy.  We fake it.  In the diagram above (highlighted in blue), <strong>FakeServerJoin()</strong> is always executed in any single player game.  This function will start a local server (which won&#8217;t actually be used at this point) and then use that local Unity server instance to allocate its own network view.  This is okay to do because (if we become a server later) any clients that connect to us will be drawing network views from the same view ID pool &#8212; so there&#8217;s no duplication of view IDs.</p>
<p>Also, notice how we create a new NetworkPlayer instance, just by calling its default constructor.  Normally, your NetworkPlayer instance is something that is created and populated &#8220;behind the scenes&#8221; for OnPlayerConnected().  Because we&#8217;re not actually connecting to a server here, OnPlayerConnected() will never get called.  But that&#8217;s okay because NetworkPlayer&#8217;s default constructor will create &#8220;good enough&#8221; default values that won&#8217;t interfere with any real network players that may connect to us later.  We just allocate a newtwork view, create a default NetworkPlayer instance, send it all along to the JoinPlayer() function, and <em>pretend these aren&#8217;t the droids we&#8217;re looking for&#8230; move along&#8230; move along</em>.</p>
<p>At any point now, we can open the game to the LAN and people can connect to us normally.</p>
<p>So, now let&#8217;s see what happens when we open the game to the LAN &#8212; this is where the real Server Discovery functions come into play.  You may have noticed that Unity doesn&#8217;t have a &#8220;Network.Broadcast()&#8221; function &#8212; and why would it?  It strictly adheres to a client-server networking model, after all.  It assumes that the client MUST know the IP address of the server.  <em>So, how do we communicate with a server when we don&#8217;t know its IP address (or even if there is a server out there to talk to)?</em></p>
<p>To accomplish that, the <strong>ListenServer()</strong> function (highlighted in red) has to do some lower-level networking work.  It has to create its own IPEndPoint, create a UdpClient, and create a UdpState.  These can all be done with just a single statement each &#8212; so, it&#8217;s not exactly re-inventing the wheel.</p>
<p>However, there are a couple things we need to be careful with.  First and foremost, we must use a random port every time this function is called.  In a given application session, you cannot create 2 UdPClients with the same IP address and same port.  Unity will complain about this and generate a runtime error.  You would see this error on the client if the client connected, dropped, and then tried to rejoin without restarting the application.  The client shouldn&#8217;t have to restart the application to re-join, so we have to solve for this limitation.</p>
<p><em><strong>Update:</strong>  I found out that you could actually use 0 for the port number as long as you preset the minPort and maxPort.  This might be a slight improvement as (supposedly) the same port will not be chosen if port 0 is used repeatedly.  If you are feeling adventurous, you may want to try that.</em></p>
<p>To get around this, we randomize the port on which we&#8217;re going to listen for server broadcast responses.  Because the server doesn&#8217;t know what port we&#8217;re listening on, we have to tell it what that port number is &#8212; we do this by sending our listening port number on the server&#8217;s known port (which it previously opened for listening for client broadcasts).</p>
<p>Let&#8217;s summarize before going further:</p>
<ul>
<li><span style="font-style:inherit;line-height:1.625;">Server open client listener on Known Port (15000)</span></li>
<li>Client opens a listener on a Random Port (15001 to 15999)</li>
<li>Client sends on Known Port to the server its chosen Random Port</li>
<li>Server responds to client on the client&#8217;s chosen Random Port</li>
</ul>
<p>Also notice that we are using a lot of asynchronous callbacks.  This is done both in the ListenServer() function and in the ListenForClients() function (highlighted in yellow).  This will (effectively) create a separate thread on which we can react when the conditions for the callback are met.  This is great for a client because it allows the client to still play locally while hosting a game and while the listener thread is independently listening for client join requests <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>It also completely sidesteps the whole &#8220;Connect is Blocking&#8221; problem (which we&#8217;re not even going to talk about here &#8212; that would be a whole separate article).  The BeginReceive(new AsyncCallback(ListenServerCallback), us1) function will call the function &#8220;ListenServerCallback&#8221; when a response is received back on our client&#8217;s chosen  Randomly Port number and operate completely on a separate thread.  For the server, the same thing happens with the BeginReceive(new AsyncCallback(ListenForClientsCallback), us1) function, but this time it calls the ListenForClients function when a client sends a message on the Known Port.</p>
<p>Note as well that just opening a listening port won&#8217;t (of course) cause a server to respond &#8212; so, we have to actually send a message to the server.  This is done with the <strong>FindServer()</strong> function.  We could send a message to the server something like, &#8220;Looking for Server Discovery server,&#8221; but that would be a waste.  The server needs to know the chosen Random Port on which we&#8217;re listening for responses, so we&#8217;ll send that instead.  Notice too that we specifically have to turn on the capability for the UdpClient to broadcast with &#8220;uc2.EnableBroadcast = true;&#8221; &#8212; it&#8217;s off by default.</p>
<p>The last point I wanted to discuss here is the need for a Thread.Sleep() function call.  This is needed so that those separate threads that have been started can get a chance to get some processing time.  This must be done any time an asynchronous function is used, so it&#8217;s just easiest to put this in the networkController&#8217;s Update() function.  The integer it accepts is the number of milliseconds to block the current thread &#8212; thereby allowing the listeners some time to check their buffers and execute the callbacks if any messages have been received.</p>
<p>So, that&#8217;s pretty much all there is to it.  Adding Server Discovery to Unity.  We&#8217;re now two-thirds of the way done to having a full peer-to-peer Unity client.</p>
<p>If you liked this article, please follow me on Twitter <a title="Follow @Tulrath on Twitter" href="https://twitter.com/tulrath" target="_blank">@Tulrath</a> to know first when the final part of this series is published.</p>
<p>As always, thanks for reading!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/179/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=179&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2013/03/07/server-discovery-in-unity-4-0-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2013/03/server_discovery_overview.png" medium="image">
			<media:title type="html">server_discovery_overview</media:title>
		</media:content>
	</item>
		<item>
		<title>Character Animator Needed</title>
		<link>http://lakehomegames.com/2013/02/16/character-animator-needed/</link>
		<comments>http://lakehomegames.com/2013/02/16/character-animator-needed/#comments</comments>
		<pubDate>Sun, 17 Feb 2013 05:34:47 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=173</guid>
		<description><![CDATA[Lakehome Games, LLC is looking for an exceptionally skilled 3D character animator residing in or around the Twin Cities metro area to join our project team. The ideal candidate has experience animating both human and non-human characters, including quadruped animations. A solid grasp &#8230; <a href="http://lakehomegames.com/2013/02/16/character-animator-needed/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=173&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Lakehome Games, LLC is looking for an exceptionally skilled <strong>3D character animator</strong> residing in or around the Twin Cities metro area to join our project team. The ideal candidate has experience animating both human and non-human characters, including quadruped animations. A solid grasp of the principles of body movement, follow-through, and other facets of 3D animation is essential. The animator must be well-versed in animation tools &#8212; 3DS Max, Maya, etc. The ideal candidate is self-motivated, works well independently and in teams, and has experience working in geographically-dispersed teams.</p>
<p>Additional pluses include:</p>
<ul>
<li>Familiarity with Unity3D and the use of an FBX-based asset pipeline</li>
<li>Familiarity with Macanim, re-targetting animations, and blend trees</li>
<li>Experience in FX and particle animation</li>
<li>Skills in one or more of the related character creation tasks &#8212; illustration, modeling, texturing, or rigging</li>
<li>A passion for, and experience with, Independent Game Development</li>
</ul>
<p>This is an unpaid position for a short (~6 month) commercial project with royalty options.</p>
<p>To find out more, please contact us here: <a title="Send mail to Lakehome Games, LLC" href="mailto://darrelcusey@lakehomegames.com" target="_blank">darrelcusey@lakehomegames.com</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/173/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/173/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=173&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2013/02/16/character-animator-needed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>
	</item>
		<item>
		<title>&#8220;Fire&#8221; Project</title>
		<link>http://lakehomegames.com/2013/02/04/fire-project/</link>
		<comments>http://lakehomegames.com/2013/02/04/fire-project/#comments</comments>
		<pubDate>Tue, 05 Feb 2013 04:55:09 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=169</guid>
		<description><![CDATA[A few screenshots from a project I&#8217;m going to call &#8220;Fire&#8221; for now.  We&#8217;re prototyping and having a great time! &#160;<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=169&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A few screenshots from a project I&#8217;m going to call &#8220;Fire&#8221; for now.  We&#8217;re prototyping and having a great time!</p>
<p><a href="http://lakehomegames.files.wordpress.com/2013/02/dwg_screenshot_2013_1_14.png"><img class="alignnone size-full wp-image-171" alt="dwg_screenshot_2013_1_14" src="http://lakehomegames.files.wordpress.com/2013/02/dwg_screenshot_2013_1_14.png?w=584"   /></a></p>
<p>&nbsp;</p>
<p><a href="http://lakehomegames.files.wordpress.com/2013/02/dwg_screenshot_2013_1_11.png"><img class="alignnone size-full wp-image-170" alt="dwg_screenshot_2013_1_11" src="http://lakehomegames.files.wordpress.com/2013/02/dwg_screenshot_2013_1_11.png?w=584&#038;h=490" width="584" height="490" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/169/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/169/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=169&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2013/02/04/fire-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2013/02/dwg_screenshot_2013_1_14.png" medium="image">
			<media:title type="html">dwg_screenshot_2013_1_14</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2013/02/dwg_screenshot_2013_1_11.png" medium="image">
			<media:title type="html">dwg_screenshot_2013_1_11</media:title>
		</media:content>
	</item>
		<item>
		<title>Fantasia Arks Concept Art 12/14</title>
		<link>http://lakehomegames.com/2012/12/14/fantasia-arks-concept-art-1214/</link>
		<comments>http://lakehomegames.com/2012/12/14/fantasia-arks-concept-art-1214/#comments</comments>
		<pubDate>Sat, 15 Dec 2012 04:10:56 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=164</guid>
		<description><![CDATA[&#160; &#160; Sean has provided some great new sketches of Reyth, the main protagonist of Fantasia Arks.  Here&#8217;s one of my favorites:<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=164&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Sean has provided some great new sketches of Reyth, the main protagonist of Fantasia Arks.  Here&#8217;s one of my favorites:</p>
<p><a href="http://lakehomegames.com/2012/12/14/fantasia-arks-concept-art-1214/reyth_late_night_sketch/" rel="attachment wp-att-165"><img class="alignnone size-full wp-image-165" alt="reyth_late_night_sketch" src="http://lakehomegames.files.wordpress.com/2012/12/reyth_late_night_sketch.jpg?w=584&#038;h=536" width="584" height="536" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/164/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=164&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2012/12/14/fantasia-arks-concept-art-1214/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2012/12/reyth_late_night_sketch.jpg" medium="image">
			<media:title type="html">reyth_late_night_sketch</media:title>
		</media:content>
	</item>
		<item>
		<title>Reflection and Name/Value Pairs</title>
		<link>http://lakehomegames.com/2012/12/14/160/</link>
		<comments>http://lakehomegames.com/2012/12/14/160/#comments</comments>
		<pubDate>Sat, 15 Dec 2012 03:47:41 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=160</guid>
		<description><![CDATA[Using Reflection in C# to create a class with a constructor that can set its properties from a delimited name/value pair string.  Just what it says: public class Creature {    public int version { get; private set; }   &#8230; <a href="http://lakehomegames.com/2012/12/14/160/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=160&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Using Reflection in C# to create a class with a constructor that can set its properties from a delimited name/value pair string.  Just what it says:</p>
<blockquote>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">public class Creature</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">{</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int version { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int guid { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public string name { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int health { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int status { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int skill1 { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int skill2 { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int skill3 { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int skill4 { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int ability { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int special { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public int type { get; private set; }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      </span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   // create a creature using a record string</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public Creature(string str)</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   {</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      </span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      char[] delims = new char[]{ &#8216;|&#8217;, &#8216;,&#8217; };</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      char[] assigns = new char[]{ &#8216;=&#8217; };</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      string[] pairs = str.Split(delims);</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      Type type = this.GetType();</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">        PropertyInfo[] properties = type.GetProperties();</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;"> </span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      foreach(string pair in pairs)</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      {</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">         string pairName = pair.Split(assigns)[0];</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">         string pairValue  = pair.Split(assigns)[1];</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">         </span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">         foreach(PropertyInfo propertyInfo in properties)</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">         {</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">            if(propertyInfo.Name == pairName)</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">            {</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">               this.SetProperty(propertyInfo, pairValue);</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">            }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">         }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">         </span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">      </span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   </span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">   public void SetProperty(PropertyInfo propertyInfo, object value)</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">    {</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">        switch(propertyInfo.PropertyType.Name)</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">        {</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">            case &#8220;Int32&#8243;:</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">                propertyInfo.SetValue(this, Convert.ToInt32(value), null);</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">                break;</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">            case &#8220;String&#8221;:</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">                propertyInfo.SetValue(this, value.ToString(), null);</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">                break;</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">        }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">    }</span></div>
<div><span style="font-family:'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;">}</span></div>
</blockquote>
<p>&#8230;creating an instance of the class with properties set to the values of a name/value pair string is this easy:</p>
<blockquote><p>Creature c = new Creature(&#8220;version=1|guid=1|name=red spider|health=10|skill1=1|skill2=2|type=1&#8243;);</p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/160/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=160&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2012/12/14/160/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>
	</item>
		<item>
		<title>World of Creatures &#8220;Pet Project&#8221;</title>
		<link>http://lakehomegames.com/2012/12/13/world-of-creatures-pet-project/</link>
		<comments>http://lakehomegames.com/2012/12/13/world-of-creatures-pet-project/#comments</comments>
		<pubDate>Thu, 13 Dec 2012 14:59:04 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=158</guid>
		<description><![CDATA[World of Creatures is a small top-down collecting/battling game that was designed by my 8-year old son. He is a big fan of Pokemon, and wanted to play a game without all the &#8220;bad parts&#8221; of Pokemon. Here&#8217;s just a &#8230; <a href="http://lakehomegames.com/2012/12/13/world-of-creatures-pet-project/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=158&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>World of Creatures is a small top-down collecting/battling game that was designed by my 8-year old son. He is a big fan of Pokemon, and wanted to play a game without all the &#8220;bad parts&#8221; of Pokemon. Here&#8217;s just a few of the changes he wanted to make (but the list is extensive!): 1) no forced trainer battles that you can&#8217;t run away from or just ignore; 2) you can always see what&#8217;s hiding in the tall grass so you can choose whether or not you want to battle/capture it; 3) no city gates that you can&#8217;t pass through until you beat the city&#8217;s gym leader; 4) gym leaders are always optional; 5) get rid of the &#8220;box&#8221; system, you can carry all your creatures with you all the time; 6) at the start of a battle, you can choose which creature to use instead of always automatically using the one at the top of the list&#8230; and the list goes on and on. This is a &#8220;side project&#8221; we&#8217;ve been working on together for about a month now. Just finished up the design and started coding the core systems.</p>
<span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='584' height='359' src='http://www.youtube.com/embed/svrVKih4wt8?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0'></iframe></span>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/158/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=158&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2012/12/13/world-of-creatures-pet-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>
	</item>
		<item>
		<title>Fantasia Arks Concept Art 12/7</title>
		<link>http://lakehomegames.com/2012/12/07/fantasia-arks-concept-art-127/</link>
		<comments>http://lakehomegames.com/2012/12/07/fantasia-arks-concept-art-127/#comments</comments>
		<pubDate>Sat, 08 Dec 2012 04:58:14 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=153</guid>
		<description><![CDATA[More great concept art from Sean &#8211; this time a Kytherian concept sketch<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=153&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>More great concept art from Sean &#8211; this time a Kytherian concept sketch</p>
<p><a href="http://lakehomegames.com/2012/12/07/fantasia-arks-concept-art-127/kytherian_concept/" rel="attachment wp-att-154"><img class="alignnone size-full wp-image-154" alt="kytherian_concept" src="http://lakehomegames.files.wordpress.com/2012/12/kytherian_concept.jpg?w=584"   /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/153/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=153&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2012/12/07/fantasia-arks-concept-art-127/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2012/12/kytherian_concept.jpg" medium="image">
			<media:title type="html">kytherian_concept</media:title>
		</media:content>
	</item>
		<item>
		<title>Unity FPS Networking Sample</title>
		<link>http://lakehomegames.com/2012/12/05/unity-fps-networking-sample/</link>
		<comments>http://lakehomegames.com/2012/12/05/unity-fps-networking-sample/#comments</comments>
		<pubDate>Thu, 06 Dec 2012 03:52:56 +0000</pubDate>
		<dc:creator>darrelcusey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lakehomegames.com/?p=144</guid>
		<description><![CDATA[This Unity Package can be downloaded here (updated):  fps_sample_2013_02_21.unitypackage Unity is a great tool for Indie developers, but there are parts of it that can really make you spin around in circles.  Networking is definitely one of those parts.  I &#8230; <a href="http://lakehomegames.com/2012/12/05/unity-fps-networking-sample/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=144&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://lakehomegames.com/2012/12/05/unity-fps-networking-sample/fps_sample_screenshot/" rel="attachment wp-att-146"><img class="alignnone size-full wp-image-146" alt="fps_sample_screenshot" src="http://lakehomegames.files.wordpress.com/2012/12/fps_sample_screenshot.png?w=584&#038;h=444" width="584" height="444" /></a></p>
<p><strong>This Unity Package can be downloaded here (updated):</strong>  <a title="Download from Dropbox" href="https://dl.dropbox.com/u/74664687/Samples/fps_sample_2013_02_21.unitypackage" target="_blank">fps_sample_2013_02_21.unitypackage</a></p>
<p><a title="Unity 3D" href="http://http://www.unity3d.com/" target="_blank">Unity</a> is a great tool for Indie developers, but there are parts of it that can really make you spin around in circles.  Networking is definitely one of those parts.  I set out to make a simple peer-to-peer FPS sample project with two goals in mind:</p>
<ol>
<li><span style="line-height:15px;">Make it as simple as possible</span></li>
<li>Avoid (as much as possible) the &#8220;exotic&#8221; Unity networking components</li>
</ol>
<p>The components I decided to avoid were NetworkViews, Network.Instantiate, and RemoveRPCs.  I picked these three because NetworkViews (even when set to &#8220;Unreliable&#8221;) can create a lot of unnecessary network traffic if they are not managed very carefully.  Network.Instantiate also generates so much network traffic that the game can pause and skip every time a new player joins.  And finally, RemoveRPCs <em>(RPC = &#8220;Remote Procedure Call&#8221;) </em>only works when you are using Network.Instantiate, so it goes out the window as well.  I really wanted to do this as a true peer-to-peer, but Unity&#8217;s built-in networking is geared strictly for client-server networking.</p>
<p><strong>Update:</strong>  I recently found a good way to do Server Discovery for the LAN, which I should really post soon.</p>
<p>So, what does that leave us with?  It leaves us with&#8230;</p>
<h1>FPS Sample Using a Single World NetworkView</h1>
<p>If you start digging through LOTS of other Unity Networking tutorials, they&#8217;ll follow the &#8220;standard route&#8221; of adding a NetworkView to your player prefab and then relying on Unity to decide when to send updates, and how much data will be sent.  Using this setup, EACH player will have its own chatty NetworkView sending out information to everyone else more or less continuously.</p>
<p>We&#8217;re not going to take the standard route.</p>
<p>However, we&#8217;re still going to need <em><strong>a single NetworkView</strong></em> because that&#8217;s the only way Unity can communicate over the network (since we don&#8217;t want to re-create the wheel and build our own Socket manager in .NET).  However, a single NetworkView component attached to an empty GameObject can be set to <strong>State Synchronization=OFF, </strong>and<strong> Observed=NONE</strong>.  This will allow us to send RPCs back and forth between client and server without all the overhead and without all the unnecessary complexity.</p>
<p>Which would leave us with something like this:</p>
<p><a href="http://lakehomegames.com/2012/12/05/unity-fps-networking-sample/fps_sample_overview/" rel="attachment wp-att-145"><img class="alignnone size-full wp-image-145" alt="fps_sample_overview" src="http://lakehomegames.files.wordpress.com/2012/12/fps_sample_overview.png?w=584"   /></a></p>
<p>At the same time, we still want a way to guarantee a unique ID is assigned to each player.  To do this, we could use any of .NET&#8217;s functions specifically designed for this task.  But if we did that, then we&#8217;d have to import at least another package &#8212; which isn&#8217;t really worth it just for one function.  A better option is to just use AllocateViewID() to get a unique object on the server even though our actual player object won&#8217;t have their own unique network views.  Yes, that&#8217;s totally cheating <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Having just a single NetworkView over which RPCs can be sent means there are a few extra responsibilities we have to take on:</p>
<ul>
<li><span style="line-height:15px;">Maintaining a dictionary between GameObjects and NetworkPlayer objects so that we can easily lookup one from the other.</span></li>
<li>Managing the creating and destruction of player objects on all clients (from the server) as players join or disconnect.</li>
<li>Devising a way for clients to be able to distinguish between messages that are meant for them and messages that are meant for other players</li>
</ul>
<p>To help explain how this is accomplished, let&#8217;s take a look at a process flow diagram.  Did I mention that I &lt;3 process flow diagrams.  I should probably mention that before we get to far into things and PFDs start flying all over the place.</p>
<p><a href="http://lakehomegames.com/2012/12/05/unity-fps-networking-sample/simple_fps/" rel="attachment wp-att-147"><img class="alignnone size-full wp-image-147" alt="simple_fps" src="http://lakehomegames.files.wordpress.com/2012/12/simple_fps.png?w=584"   /></a></p>
<p>If you haven&#8217;t done so already, grab the Unity package and open up the networkController script so you can follow along.</p>
<p>OK, let&#8217;s look at the important parts, starting with our first RPC in OnPlayerConnected()</p>
<pre>networkView.RPC("JoinPlayer", RPCMode.All, newViewID, Vector3.zero, p);</pre>
<p>In OnPlayerConnected(), we execute this RPC call to all connected clients using the server&#8217;s world networkView.  Notice that we are using RPCMode.All &#8211; which will send the JoinPlayer() RPC to all players and the server.  The player object must be created on all clients and the server, and this is the simplest way of accomplishing that.</p>
<p>Also, notice that the server AND the client is maintaining the HashTable of all players.  This is done in the JoinPlayer() RPC with this simple command:</p>
<pre>players.Add(p,newPlayer);</pre>
<p>&#8230;which is removed when a player disconnects with something very similar in the DisconnectPlayer() RPC:</p>
<pre>players.Remove(player);</pre>
<p>Now, in the JoinPlayer() RPC, we have this critical comparison:</p>
<pre>if(p.ipAddress==LocalAddress)</pre>
<p>In Start(), we determine the computer&#8217;s Local IP Address using Dns.GetHostEntry(Dns.GetHostName()) from .NET&#8217;s System.Net.Socket package and then use this to compare it against the NetworkPlayer structure&#8217;s &#8220;ipAddress&#8221; attribute that is being sent from the server.</p>
<p>Now, at this point, you&#8217;re probably asking, &#8220;well what about everyone else?&#8221;  After all, it&#8217;s all well and good that the player and server know about each  other now, but what if there are already players in the game?  How does the server tell the new player about existing players.  Before that can be done, the client must wait until it is fully connected to the server, which is why we wait until the client determines that it is connected before requesting the complete player list from the server.</p>
<p>We use the built-in function OnConnectedToServer() to get our timing just right, and then request the player list:</p>
<pre>void OnConnectedToServer()
{ 
   networkView.RPC("SendAllPlayers", RPCMode.Server);
}</pre>
<p>Because we use RPCMode.All in the original JoinPlayer() RPC, the server has instantiated a GameObject for every client that is joined.  To get a list of all players, the server only needs to run this code once every time a new player joins in the SendAllPlayers() function:</p>
<pre>GameObject[] goPlayers = GameObject.FindGameObjectsWithTag("Player");</pre>
<p>For each member of goPlayers, the server extracts the NetworkPlayer and the allocated NetworkViewID, and sends those on using more RPC calls to the JoinPlayer() function.  However, we make sure that we are NOT sending the requestor&#8217;s data back to them by doing this comparison:</p>
<pre>if(gonp.ToString() != info.sender.ToString())</pre>
<p>Because the allocated NetworkViewID is guaranteed unique within the server session, this is far more reliable than using RPCMode.Others (which, despite Unity&#8217;s claims to the contrary, actually DOES send a message back to the original sender).</p>
<p>The client ALSO checks the incoming NetworkPlayer data structure&#8217;s ipAddress against its own LocalAddress &#8212; but this is really just a cross-check to insure that no client can get a doppelganger <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>&#8230;because no one like doppelgangers.</p>
<p>So, that&#8217;s pretty much it, a complete FPS Networking Sample that only uses a single world NetworkView that generates minimal network traffic.</p>
<p><em>So is this the end of our peer-to-peer networking dream?</em>  Hmmm, you&#8217;ll notice that the Hashtable of all players is being maintained on all clients.  So, in reality, each client already knows everything the server knows.</p>
<p>If you are guessing that I&#8217;ve already thought of a way that any given client can:</p>
<ul>
<li>detect when the server disconnects,</li>
<li>using ipAddresses, determine if it should take the place of the server,</li>
<li>turn itself into the server,</li>
<li>and finally tell all the other clients that it is now the server&#8230;</li>
</ul>
<p>&#8230;well, if you&#8217;ve guessed all that, then you should really consider getting checked out to see if you are psychic or something <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><strong>To see what I&#8217;ve got so far, grab the Unity Package here:</strong>  <a title="Download from Dropbox" href="https://dl.dropbox.com/u/74664687/Samples/fps_sample_2013_02_21.unitypackage" target="_blank">fps_sample_2013_02_21.unitypackage</a></p>
<p>As always, thanks for reading!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lakehomegames.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lakehomegames.wordpress.com/144/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lakehomegames.com&#038;blog=34586732&#038;post=144&#038;subd=lakehomegames&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lakehomegames.com/2012/12/05/unity-fps-networking-sample/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/032e7de41fde68588d7d95ad94d5db07?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">darrelcusey</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2012/12/fps_sample_screenshot.png" medium="image">
			<media:title type="html">fps_sample_screenshot</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2012/12/fps_sample_overview.png" medium="image">
			<media:title type="html">fps_sample_overview</media:title>
		</media:content>

		<media:content url="http://lakehomegames.files.wordpress.com/2012/12/simple_fps.png" medium="image">
			<media:title type="html">simple_fps</media:title>
		</media:content>
	</item>
	</channel>
</rss>
