<?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>Writing Kode</title>
	<atom:link href="http://dirkkok.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://dirkkok.wordpress.com</link>
	<description></description>
	<lastBuildDate>Mon, 06 May 2013 04:33:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='dirkkok.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Writing Kode</title>
		<link>http://dirkkok.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://dirkkok.wordpress.com/osd.xml" title="Writing Kode" />
	<atom:link rel='hub' href='http://dirkkok.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Making the connection</title>
		<link>http://dirkkok.wordpress.com/2012/03/25/making-the-connection/</link>
		<comments>http://dirkkok.wordpress.com/2012/03/25/making-the-connection/#comments</comments>
		<pubDate>Sun, 25 Mar 2012 08:49:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[Unity3D]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=184</guid>
		<description><![CDATA[Making a connection using the Lidgren networking library in Unity3d proved a bit more involved than I anticipated. My first challenge was to set up a proper multiplayer debug environment. In a normal c# application you have full control of how you want to start your application. I like setting up two startup projects, one &#8230; <a href="http://dirkkok.wordpress.com/2012/03/25/making-the-connection/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=184&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Making a connection using the Lidgren networking library in Unity3d proved a bit more involved than I anticipated. My first challenge was to set up a proper multiplayer debug environment. </p>
<p>In a normal c# application you have full control of how you want to start your application. I like setting up two startup projects, one for the client and one for the server. This way I can do my client-server debugging in one environment and both the instances are launched at startup.</p>
<p>This proved to be a challenge in Unity. My first idea was to use a batch file to start two instances of unity with command-line arguments to distinguish between the client and the server. I found the custom command-line argument support to be lacking and didn’t pursue the idea any further.</p>
<p>I decided I would go the route of starting an instance of the game using the “Build &amp; Run” command and then to start the second instance through the editor. To make this work you have to enable the “Run in Background” option under Edit –&gt; Project Settings –&gt; Player.</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image7.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb7.png?w=460&#038;h=148" width="460" height="148" /></a></p>
<p>Without this setting enabled the non-focused instance would become unresponsive. I think Unity stops processing the Update methods when the window loses focus.</p>
<p>Next I needed some way to configure each instance as either the server or the client. I made use of a simple GUI with two buttons “Host Game” and “Join Game”. The nice thing about Unity is that is has GUI support out the box. </p>
<p><strong>NOTE:</strong> I am not 100% comfortable with how to best structure a solution yet. I can see that the GUI stuff can become messy really fast. </p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image8.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb8.png?w=319&#038;h=172" width="319" height="172" /></a></p>
<p>Now I had enough to launch either a client or server instance. The next step was to get the Lidgren-network-gen3 library working in the Unity environment. I have included the steps I followed for reference below:</p>
<p>Step 1: Get the source code from the <a href="http://code.google.com/p/lidgren-network-gen3/source/checkout" target="_blank">Google code repository</a>.</p>
<p>Step 2: Open the solution in MonoDevelop. I used MonoDevelop rather than Visual Studio since the Assembly needs to be compiled for Mono.</p>
<p>Step 3: Follow the instructions from the <a href="http://code.google.com/p/lidgren-network-gen3/wiki/Unity3D" target="_blank">wiki</a>.</p>
<p>I thought this would be enough, but the Lidgren networking library was upgraded to .NET 4 and would not work in Unity.</p>
<p>The error message I got was MissingMethodException for &#8216;System.Threading.Monitor.​Enter&#8217;. It would happen on my netPeer.Start() call.</p>
<p>After some googling I found the solution <a href="https://groups.google.com/forum/?fromgroups#!topic/lidgren-network-gen3/fXvC0nEVha8" target="_blank">here</a>.</p>
<p>Step 4: Set Lidgren project to build to .NET framework 3.5</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image9.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb9.png?w=439&#038;h=97" width="439" height="97" /></a></p>
<p>Step 5: Remove reference to Microsoft.CSharp assembly.</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image10.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb10.png?w=282&#038;h=140" width="282" height="140" /></a></p>
<p>Step 6: Rebuild the project.</p>
<p>Step 7: Copy the binaries into your Unity3d asset folder. (I put mine in a assets\lib folder).</p>
<p>Step 8: In Unity change the Player settings to use .NET 2 instead of the .NET 2 subset. (Edit –&gt; Project Settings –&gt; Player)</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image11.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb11.png?w=342&#038;h=172" width="342" height="172" /></a></p>
<p>With that done I was ready to make the connection. Using the code from the XNA multiplayer article series. I copied across the INetworkingManager, ClientNetworkingManager and ServerNetworkingManager code. </p>
<p>When the user clicks on the “Host Game” button I instantiate the ServerNetworkingManager and when the user clicks the “Join Game” button I instantiate the ClientNetworkingManager.</p>
<p>In the FixedUpdate() method I make the call to ProcessNetworkingMessages()</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image12.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb12.png?w=440&#038;h=202" width="440" height="202" /></a></p>
<p>In the above image you can see a screenshot of the server running in the Unity editor and the client running as a stand-alone instance.</p>
<p>For my next article I will cover getting the Asteroid synchronized across both instances.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/184/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/184/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=184&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/03/25/making-the-connection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb7.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb8.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb9.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb10.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb11.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb12.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Asteroid Manager</title>
		<link>http://dirkkok.wordpress.com/2012/03/14/asteroid-manager/</link>
		<comments>http://dirkkok.wordpress.com/2012/03/14/asteroid-manager/#comments</comments>
		<pubDate>Wed, 14 Mar 2012 16:30:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[Unity3D]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=168</guid>
		<description><![CDATA[I have been playing around with porting the asteroid manager to Unity. The code to get this right as per the previous post was very little. I had some issues with the coordinate system, but the guys from the Orthello framework were kind enough to explain things to me. To get started you need to &#8230; <a href="http://dirkkok.wordpress.com/2012/03/14/asteroid-manager/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=168&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I have been playing around with porting the asteroid manager to Unity. The code to get this right as per the previous post was very little. I had some issues with the coordinate system, but the guys from the <a href="http://www.wyrmtale.com/orthello" target="_blank">Orthello framework</a> were kind enough to explain things to me.</p>
<p>To get started you need to install the Orthello package from the Unity asset store. Then you drag the OTView object into your scene as follows. The OTView object handles things like the Orthographic camera (needed for 2D) and coordinate systems out the box.</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image1.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb1.png?w=407&#038;h=153" width="407" height="153" /></a></p>
<p>The asteroid manager is responsible for managing the asteroids within the game. As per the XNA example we are going to need an asteroid sprite. To create the sprite you drag the Orthello Sprite asset from the project hierarchy onto your scene. Since we want to control the creation and destruction of our sprites through code we will be using an asteroid “prototype” that will serve as a template. To use our new asteroid sprite as a prototype you drag it into the &quot;OT –&gt; Prototypes” folder in the scene hierarchy.</p>
<p>The first thing to do is to disable the asteroid sprite by unchecking the checkbox next to the sprite name as follows:</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image2.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb2.png?w=409&#038;h=97" width="409" height="97" /></a></p>
<p>The reason for disabling the prototype is quite subtle. Since we are creating all our asteroid sprite instances based on this prototype we don’t want to accidentally delete to prototype object itself. By disabling the sprite we can safely exclude it from our script processing.</p>
<p>The next thing we want to set is how the sprite behaves in terms of collisions.</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image3.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb3.png?w=410&#038;h=112" width="410" height="112" /></a></p>
<p>The depth property specifies the z-position of the object. The collidable property tells unity that the sprite will take part in collision detection. The RigidBody physics setting defines how the sprite should behave in terms of the physics calculations. I am using a Sphere collider type with the collision depth being at the same depth as the sprite and the collision size set to a size within the bounds of the sprite.</p>
<p>The asteroid animation is handled via animation and animation container objects which I will describe below. The properties on the Sprite class for animations are as follows.</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image4.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb4.png?w=410&#038;h=187" width="410" height="187" /></a></p>
<p>In the properties above I have indicated that the animation will loop, start playing when the game starts and will start at a random frame. Easy enough and replaces all the code we had in the sprite class for the XNA version.</p>
<p>To define the animation container you need to drag an Orthello SpriteSheet object onto your scene. Orthello supports sprite atlasses for various well known file formats, for now I decided to make use of a simple spritesheet. On the AnimationContainer you just created you need to specify the texture to use, the number of frames and the size of each frame.</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image5.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb5.png?w=409&#038;h=242" width="409" height="242" /></a></p>
<p>I specified the Texture by dragging it from the project assets onto the Texture property of the AnimationContainer.</p>
<p>Now that we have defined a container for our animations we need to create an animation for our asteroid sprite. This is done by dragging an Orthello Animation object from the project assets onto our scene. The next step is to define which frame sfrom the AnimationContainer to use for the Animation.</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image6.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb6.png?w=413&#038;h=185" width="413" height="185" /></a></p>
<p>Our asteroid animation will make use of one frameset (there is only one in my spritesheet) and will start at frame 0 and end with frame 19. You specify the container by dragging the AnimationContainer you created in the scene onto the container property of the Animation object.</p>
<p>The next step is to create a script for the Asteroid sprite. This script is really basic and all it does is to destroy the asteroid once it moves outside the bounds of the visible area.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3fb202ee-bd16-49aa-8144-60a746165144" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#008000;">// Update is called once per frame</span><br /> <span style="color:#0000ff;">void</span> Update()<br /> {<br />     <span style="color:#0000ff;">if</span> (sprite.outOfView)<br />     {<br />         OT.DestroyObject(sprite);<br />     }<br /> }</div>
</p></div>
</p></div>
<p>The script is attached to the asteroid sprite by dragging it onto the asteroid sprite prototype. When we create our asteroid sprites using the prototype as template the accompanying script will be created automatically.</p>
<p>Finally the AsteroidManager script will be used to create the asteroids and position them randomly on the game screen. I attached the AsteroidManager script to my MainCamera object.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d11d917a-738a-4782-a4f1-e78170f29129" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#008000;">// Update is called once per frame</span><br /> <span style="color:#0000ff;">void</span> Update()<br /> {<br />     <span style="color:#008000;">// only go one if Orthello is initialized</span><br />     <span style="color:#0000ff;">if</span> (!OT.isValid) <span style="color:#0000ff;">return</span>;</p>
<p>     <span style="color:#008000;">// We call the application initialization function from Update() once </span><br />     <span style="color:#008000;">// because we want to be sure that all Orthello objects have been started.</span><br />     <span style="color:#0000ff;">if</span> (!initialized)<br />     {<br />         Initialize();<br />         <span style="color:#0000ff;">return</span>;<br />     }<br />     <br />     <span style="color:#008000;">// If we have less than 15 objects within Orthello we will create a random asteroid</span><br />     <span style="color:#0000ff;">if</span> (OT.objectCount &lt;= 15)<br />         <span style="color:#0000ff;">this</span>.SpawnAsteroid();<br /> }</div>
</p></div>
</p></div>
<p>The Update method is responsible for initializing the asteroid manager and to spawn new asteroids if the current object count is less than 15.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2109a154-c56d-41c2-84b5-c5c01730d765" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#008000;">// application initialization</span><br /> <span style="color:#0000ff;">void</span> Initialize()<br /> {<br />     <span style="color:#008000;">// Create our object pool if we want.</span><br />     OT.objectPooling = <span style="color:#0000ff;">true</span>;<br />     <span style="color:#0000ff;">if</span> (OT.objectPooling)<br />         CreateObjectPools();<br />     <br />     <span style="color:#008000;">// set our initialization notifier &#8211; we only want to initialize once</span><br />     initialized = <span style="color:#0000ff;">true</span>;<br /> }</div>
</p></div>
</p></div>
<p>The Initialize method is used to switch on object pooling and to create the object pools.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1bd13750-44b2-4169-acb6-94afbd649fc0" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> SpawnAsteroid()<br /> {<br />     <span style="color:#008000;">// Create a new asteroid sprite based on the Asteroid protoype</span><br />     GameObject asteroid = OT.CreateObject(<span style="color:#a31515;">&quot;Asteroid&quot;</span>);<br />     <span style="color:#0000ff;">if</span> (asteroid != <span style="color:#0000ff;">null</span>)<br />     {<br />         <span style="color:#008000;">// activate the game object</span><br />         asteroid.gameObject.active = <span style="color:#0000ff;">true</span>;<br />         <span style="color:#008000;">// get a reference to the animating sprite of the asteroid</span><br />         <span style="color:#0000ff;">var</span> sprite = asteroid.GetComponent&lt;OTAnimatingSprite&gt;();<br />         <span style="color:#008000;">// set the depth</span><br />         sprite.depth = 100;<br />         <span style="color:#008000;">// the asteroids should not be influenced by gravity</span><br />         sprite.rigidbody.useGravity = <span style="color:#0000ff;">false</span>;<br />         <span style="color:#008000;">// give the sprite a random position and velocity</span><br />         <span style="color:#0000ff;">this</span>.SetRandomPositionAndVelocity(sprite, OT.view.worldRect);<br />     }<br /> }</div>
</p></div>
</p></div>
<p>In the above code we create a new GameObject instance based on the “Asteroid” prototype object. We then make sure the gameObject is active and get a reference to the AnimatedSprite object within the gameObject. The sprite is used to set the depth, position and physics settings.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:26735f39-8dcb-463f-8ed5-d1acb8cfacfd" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> SetRandomPositionAndVelocity(OTAnimatingSprite sprite, Rect screenRectangle)<br /> {<br />     sprite.rotation = Random.value * 360;<br />     <span style="color:#0000ff;">var</span> spawnDirection = (SpawnDirection)Random.Range(0, 3);<br />     <br />     <span style="color:#0000ff;">switch</span> (spawnDirection)<br />     {<br />         <br />         <span style="color:#0000ff;">case</span> SpawnDirection.Left:<br />             sprite.position = <span style="color:#0000ff;">new</span> Vector2(screenRectangle.xMin, (Random.value * Mathf.Abs(screenRectangle.height)) &#8211; Mathf.Abs (screenRectangle.yMax));<br />             sprite.rigidbody.velocity = <span style="color:#0000ff;">new</span> Vector3(Random.value * 50, (Random.value * 100) &#8211; 50);<br />             <span style="color:#0000ff;">break</span>;<br />         <span style="color:#0000ff;">case</span> SpawnDirection.Top:<br />             sprite.position = <span style="color:#0000ff;">new</span> Vector2((Random.value * Mathf.Abs(screenRectangle.width)) &#8211; Mathf.Abs(screenRectangle.xMin), screenRectangle.yMin);<br />             sprite.rigidbody.velocity = <span style="color:#0000ff;">new</span> Vector3((Random.value * 100) &#8211; 50, (Random.value * 50) &#8211; 50);<br />             <span style="color:#0000ff;">break</span>;<br />         <span style="color:#0000ff;">case</span> SpawnDirection.Right:<br />             sprite.position = <span style="color:#0000ff;">new</span> Vector2(screenRectangle.xMax, (Random.value * Mathf.Abs(screenRectangle.height)) &#8211; Mathf.Abs (screenRectangle.yMax));<br />             sprite.rigidbody.velocity = <span style="color:#0000ff;">new</span> Vector3((Random.value * 50) &#8211; 50, (Random.value * 100) &#8211; 50);<br />             <span style="color:#0000ff;">break</span>;<br />     }<br />     <br />     <span style="color:#0000ff;">var</span> normalizedVelocity = sprite.rigidbody.velocity.normalized;<br />     sprite.rigidbody.velocity = normalizedVelocity * 50;<br /> }</div>
</p></div>
</p></div>
<p>The SetRandomPositionAndVelocity method is very similar to the XNA version in terms of game logic.</p>
<p>The above was all that was required to get the AsteroidManager portion of the game up and running. I am very impressed with the Orthello framework and Unity as a game engine thus far.</p>
<p>Networking is going to have some challenges, but before I get there I am going to have to introduce GUI elements. The reason for this is that I haven’t found a good way to start two instances of unity with “client” and “server’ arguments as per my XNA example. If I can get that working then I won’t need a GUI to allow the user to specify whether the instance is running as server or client.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/168/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=168&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/03/14/asteroid-manager/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb2.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb3.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb4.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb5.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb6.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Trying out Unity3D</title>
		<link>http://dirkkok.wordpress.com/2012/03/08/trying-out-unity3d/</link>
		<comments>http://dirkkok.wordpress.com/2012/03/08/trying-out-unity3d/#comments</comments>
		<pubDate>Thu, 08 Mar 2012 16:21:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[Unity3D]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=154</guid>
		<description><![CDATA[While writing the ‘let’s make a multiplayer game’ article series I had quite a few request on some multiplayer articles using Unity3D. I have zero experience with Unity but I’ve always wanted to give it a bash. For my first project I am going to try and convert the Asteroids game from the multiplayer articles &#8230; <a href="http://dirkkok.wordpress.com/2012/03/08/trying-out-unity3d/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=154&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>While writing the ‘let’s make a multiplayer game’ article series I had quite a few request on some multiplayer articles using Unity3D. I have zero experience with Unity but I’ve always wanted to give it a bash. For my first project I am going to try and convert the Asteroids game from the multiplayer articles to use Unity. My next few posts will be on my experiences during this process.</p>
<p>Since the Asteroids game is a 2D game I am using the <a href="http://www.wyrmtale.com/orthello" target="_blank">Orthello 2D framework</a>. I have seen people write posts on using Lidgren for networking, but I don’t know if it is required as Unity already has some kind of networking implementation.</p>
<p>Using the Orthello example projects I was able to easily get the basic asteroids flying across the screen. </p>
<p><a href="http://dirkkok.files.wordpress.com/2012/03/image.png"><img style="display:inline;" title="image" alt="image" src="http://dirkkok.files.wordpress.com/2012/03/image_thumb.png?w=240&#038;h=144" width="240" height="144" /></a></p>
<p>I must confess that I’m finding it quite strange to move from a pure coding environment to a scripted environment. Although I’m writing code in c# I have no idea on what the best way is to structure the scripts, how to bootstrap the application, do abstraction and make other general programming decisions and tradeoffs.</p>
<p>The nice thing so far is that I only really needed to write the code to create the asteroids. Everything else is handled by Unity meaning that I can use the built-in physics and Sprite sheet functionality to render, animate and let the asteroids bounce off each other.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=154&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/03/08/trying-out-unity3d/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>

		<media:content url="http://dirkkok.files.wordpress.com/2012/03/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Let&#8217;s make a multiplayer game (part 9)</title>
		<link>http://dirkkok.wordpress.com/2012/03/02/lets-make-a-multiplayer-game-part-9/</link>
		<comments>http://dirkkok.wordpress.com/2012/03/02/lets-make-a-multiplayer-game-part-9/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 10:24:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=148</guid>
		<description><![CDATA[In this article I am going to cover the handling of enemy ships. The first thing to consider when adding a new piece of functionality to the game is where the responsibilities lie. Based on the classification discussed in article 5 we can classify the creation of enemies and enemy shots fired at the player &#8230; <a href="http://dirkkok.wordpress.com/2012/03/02/lets-make-a-multiplayer-game-part-9/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=148&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In this article I am going to cover the handling of enemy ships. The first thing to consider when adding a new piece of functionality to the game is where the responsibilities lie. Based on the classification discussed in <a href="http://dirkkok.wordpress.com/2012/02/24/lets-make-a-multiplayer-game-part-5/" target="_blank">article 5</a> we can classify the creation of enemies and enemy shots fired at the player as the responsibility of the server. All other enemy behaviour is handled on both the client and server side.</p>
<h4>Managing Enemies</h4>
<p>Adding enemies follows exactly the same pattern as the previous game logic. We define an Enemy class that inherits from the Sprite class. The Enemy class is responsible for handling enemy movement across the screen and the rendering of the enemy sprite. The EnemyManager class is responsible for the creation of enemies and whether an enemy has fired at the player. These activities happen on the server with the client-side merely adding enemies created on the server to the local list.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e991062d-af03-4574-9ecc-0c9b99aaff5d" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Update(<span style="color:#2b91af;">GameTime</span> gameTime)<br />         {<br />             <span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> x = <span style="color:#0000ff;">this</span>.enemies.Count &#8211; 1; x &gt;= 0; x&#8211;)<br />             {<br />                 <span style="color:#0000ff;">this</span>.enemies[x].Update(gameTime);<br />                 <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.enemies[x].IsActive == <span style="color:#0000ff;">false</span>)<br />                 {<br />                     <span style="color:#0000ff;">this</span>.enemies.RemoveAt(x);<br />                 }<br />                 <span style="color:#0000ff;">else</span><br />                 {<br />                     <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.isHost)<br />                     {<br />                         <span style="color:#0000ff;">if</span> ((<span style="color:#0000ff;">float</span>)<span style="color:#0000ff;">this</span>.randomNumberGenertor.Next(0, 1000) / 10 &lt;= <span style="color:#0000ff;">this</span>.shipShotChance)<br />                         {<br />                             <span style="color:#2b91af;">Vector2</span> fireLoc = <span style="color:#0000ff;">this</span>.enemies[x].SimulationState.Position;<br />                             fireLoc += <span style="color:#0000ff;">this</span>.gunOffset;</p>
<p>                             <span style="color:#2b91af;">Vector2</span> shotDirection =<br />                                 <span style="color:#0000ff;">this</span>.playerManager.Players.ToList()[<br />                                     <span style="color:#0000ff;">this</span>.randomNumberGenertor.Next(0, <span style="color:#0000ff;">this</span>.playerManager.Players.Count() - 1)].Center<br />                                 - fireLoc;<br />                             shotDirection.Normalize();</p>
<p>                             <span style="color:#0000ff;">this</span>.shotManager.FireShot(fireLoc, shotDirection, <span style="color:#0000ff;">this</span>.enemies[x].Id, <span style="color:#0000ff;">false</span>);<br />                         }<br />                     }<br />                 }<br />             }</p>
<p>             <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.isActive &amp;&amp; <span style="color:#0000ff;">this</span>.isHost)<br />             {<br />                 <span style="color:#0000ff;">this</span>.UpdateWaveSpawns();<br />             }<br />         }</div>
</p></div>
</p></div>
<p>In the above Update method of the EnemyManager class we loop through the enemy object instances and call their Update methods. If an enemy instance is no longer active (due to it moving out of the screen bounds or being destroyed) we remove it from the local list of enemies. </p>
<p><strong>Note:</strong> This happens on both the server and client side without any updates from the server to the client. this is due to the deterministic nature of the simulation.</p>
<p>Next only the server side will do a check to see if an enemy has fired at a randomly selected player. This code makes use of the ShotManager class to create the shot and to notify the client that a shot was fired.</p>
<p>Lastly, the server side will spawn a new wave of enemies based on the configured game timer. The UpdateWaveSpawns method makes use of the server-side SpawnEnemy method which will raise an event for the message to be sent to the client-side.</p>
<h4>Sending Messages</h4>
<p>As in the previous articles we attach an event handler to the EnemyManager class on the server-side as follows.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e94d118d-7837-406d-bf2d-39714ff3bd7d" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">this</span>.enemyManager = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">EnemyManager</span>(<br />     randomNumberGenerator, <span style="color:#0000ff;">this</span>.shotManager, <span style="color:#0000ff;">this</span>.playerManager, <span style="color:#0000ff;">this</span>.IsHost);<br /> <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.IsHost)<br /> {<br />     <span style="color:#0000ff;">this</span>.enemyManager.EnemySpawned +=<br />         (sender, e) =&gt; <span style="color:#0000ff;">this</span>.networkManager.SendMessage(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">EnemySpawnedMessage</span>(e.Enemy));<br /> }</div>
</p></div>
</p></div>
<p>In the above code we send the EnemySpawned game message to all the connected clients if the code is running as the server.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:02f717e5-a9f9-440a-b667-3fdeabe00f9e" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> <span style="color:#2b91af;">EnemySpawnedMessage</span> : <span style="color:#2b91af;">IGameMessage</span><br /> {<br />     <span style="color:#0000ff;">#region</span> Constructors and Destructors</p>
<p>     <span style="color:#0000ff;">public</span> EnemySpawnedMessage(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br />     {<br />         <span style="color:#0000ff;">this</span>.Decode(im);<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> EnemySpawnedMessage(<span style="color:#2b91af;">Enemy</span> enemy)<br />     {<br />         <span style="color:#0000ff;">this</span>.Id = enemy.Id;<br />         <span style="color:#0000ff;">this</span>.Position = enemy.SimulationState.Position;<br />         <span style="color:#0000ff;">this</span>.Velocity = enemy.SimulationState.Velocity;<br />         <span style="color:#0000ff;">this</span>.Rotation = enemy.SimulationState.Rotation;<br />         <span style="color:#0000ff;">this</span>.MessageTime = <span style="color:#2b91af;">NetTime</span>.Now;<br />         <span style="color:#0000ff;">this</span>.Path = enemy.Path;<br />     }</p>
<p>     <span style="color:#0000ff;">#endregion</span></p>
<p>     <span style="color:#0000ff;">#region</span> Public Properties</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">long</span> Id { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">double</span> MessageTime { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">GameMessageTypes</span> MessageType<br />     {<br />         <span style="color:#0000ff;">get</span><br />         {<br />             <span style="color:#0000ff;">return</span> <span style="color:#2b91af;">GameMessageTypes</span>.EnemySpawned;<br />         }<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">int</span> Path { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">Vector2</span> Position { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">float</span> Rotation { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">Vector2</span> Velocity { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">#endregion</span></p>
<p>     <span style="color:#0000ff;">#region</span> Public Methods and Operators</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Decode(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br />     {<br />         <span style="color:#0000ff;">this</span>.Id = im.ReadInt64();<br />         <span style="color:#0000ff;">this</span>.MessageTime = im.ReadDouble();<br />         <span style="color:#0000ff;">this</span>.Position = im.ReadVector2();<br />         <span style="color:#0000ff;">this</span>.Velocity = im.ReadVector2();<br />         <span style="color:#0000ff;">this</span>.Rotation = im.ReadSingle();<br />         <span style="color:#0000ff;">this</span>.Path = im.ReadInt32();<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Encode(<span style="color:#2b91af;">NetOutgoingMessage</span> om)<br />     {<br />         om.Write(<span style="color:#0000ff;">this</span>.Id);<br />         om.Write(<span style="color:#0000ff;">this</span>.MessageTime);<br />         om.Write(<span style="color:#0000ff;">this</span>.Position);<br />         om.Write(<span style="color:#0000ff;">this</span>.Velocity);<br />         om.Write(<span style="color:#0000ff;">this</span>.Rotation);<br />         om.Write(<span style="color:#0000ff;">this</span>.Path);<br />     }</p>
<p>     <span style="color:#0000ff;">#endregion</span><br /> }</div>
</p></div>
</p></div>
<p>The EnemySpawned game message follows exactly the same pattern as all the other game message classes. I am only including it to reinforce the pattern. There is nothing different in terms of multiplayer programming.</p>
<h4>Receiving Messages</h4>
<p>The receipt and processing of messages follows the same pattern as before and the ProcessNetworkMessages method is modified as follows.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:10911698-8d6c-4841-bd74-3be05e8800e7" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.Data:<br />     <span style="color:#0000ff;">var</span> gameMessageType = (<span style="color:#2b91af;">GameMessageTypes</span>)im.ReadByte();<br />     <span style="color:#0000ff;">switch</span> (gameMessageType)<br />     {<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.UpdateAsteroidState:<br />             <span style="color:#0000ff;">this</span>.HandleUpdateAsteroidStateMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.UpdatePlayerState:<br />             <span style="color:#0000ff;">this</span>.HandleUpdatePlayerStateMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.ShotFired:<br />             <span style="color:#0000ff;">this</span>.HandleShotFiredMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.EnemySpawned:<br />             <span style="color:#0000ff;">this</span>.HandleEnemySpawnedMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />     }</p>
<p>     <span style="color:#0000ff;">break</span>;</div>
</p></div>
</p></div>
<p>The HandleEnemySpawnedMessage method is used to create the enemy instance on the client-side.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5573d466-00c2-49fa-9bfa-e245280c4713" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> HandleEnemySpawnedMessage(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br /> {<br />     <span style="color:#0000ff;">var</span> message = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">EnemySpawnedMessage</span>(im);</p>
<p>     <span style="color:#0000ff;">var</span> timeDelay = (<span style="color:#0000ff;">float</span>)(<span style="color:#2b91af;">NetTime</span>.Now &#8211; im.SenderConnection.GetLocalTime(message.MessageTime));</p>
<p>     <span style="color:#2b91af;">Vector2</span> adjustedPosition = message.Position + (message.Velocity * timeDelay);</p>
<p>     <span style="color:#0000ff;">this</span>.enemyManager.SpawnEnemy(message.Id, message.Path, adjustedPosition, message.Velocity, message.Rotation);<br /> }</div>
</p></div>
</p></div>
<p>The above code makes use of the client-side version of the SpawnEnemy method on the EnemyManager. This is important since we don’t want to send game messages in this case.</p>
<p>We did not introduce any additional code to handle the enemies firing at the player. This is because we could reuse the ShotManager class introduced in the previous article.</p>
<p>The following video shows an example of the new enemy functionality in action.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:8d21f322-f9f0-45c6-a731-40c82f52fa47" class="wlWriterEditableSmartContent">
<div><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='448' height='252' src='http://www.youtube.com/embed/il2njHRmOVY?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;hd=1&#038;wmode=transparent' frameborder='0'></iframe></span></div>
<div style="width:448px;clear:both;font-size:.8em;">Asteroids with Enemies (200ms delay)</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/148/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=148&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/03/02/lets-make-a-multiplayer-game-part-9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>
	</item>
		<item>
		<title>Let&#8217;s make a multiplayer game (part 8)</title>
		<link>http://dirkkok.wordpress.com/2012/02/29/lets-make-a-multiplayer-game-part-8/</link>
		<comments>http://dirkkok.wordpress.com/2012/02/29/lets-make-a-multiplayer-game-part-8/#comments</comments>
		<pubDate>Wed, 29 Feb 2012 16:50:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=144</guid>
		<description><![CDATA[In the previous article we implemented smoothing of player movements on both the client and server side. In this article we will implement the functionality required to allow the player to fire shots. As per the previous articles the first class to implement is the Shot class. This class will represent a bullet flying across &#8230; <a href="http://dirkkok.wordpress.com/2012/02/29/lets-make-a-multiplayer-game-part-8/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=144&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In the previous article we implemented smoothing of player movements on both the client and server side. In this article we will implement the functionality required to allow the player to fire shots.</p>
<p>As per the previous articles the first class to implement is the Shot class. This class will represent a bullet flying across the screen and inherits from the Sprite base class. The Shot class has two additional properties as shown below.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8c47c823-859f-4c53-85d2-280a2abbf680" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">long</span> FiredById { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">set</span>; }</p>
<p> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">bool</span> FiredByPlayer { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">set</span>; }</div>
</p></div>
</p></div>
<p>The FiredById property is used to store the Id of the entity that fired the shot.</p>
<p>The FiredByPlayer property is used to indicate whether the player fired the shot. When we implement enemies this property will be false when an enemy ship fires at the player.</p>
<p>Shots are managed by the ShotManager class, meaning that the ShotManager is responsible for drawing all the shots and updating the movement of the shots. Shots are removed from the ShotManager when they move out of the screen bounds.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cfd56216-8817-4d3d-9e4a-ba19a9862a88" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#2b91af;">Shot</span> FireShot(<span style="color:#2b91af;">Vector2</span> position, <span style="color:#2b91af;">Vector2</span> velocity, <span style="color:#0000ff;">long</span> firedById, <span style="color:#0000ff;">bool</span> playerFired)<br /> {<br />     <span style="color:#2b91af;">Shot</span> shot = <span style="color:#0000ff;">this</span>.FireShot(<br />         <span style="color:#2b91af;">Interlocked</span>.Increment(<span style="color:#0000ff;">ref</span> shotIdCounter), position, velocity * <span style="color:#0000ff;">this</span>.shotSpeed, firedById, playerFired);<br />     <span style="color:#0000ff;">this</span>.OnShotFired(shot);<br />     <span style="color:#0000ff;">return</span> shot;<br /> }</div>
</p></div>
</p></div>
<p>The FireShot method is used to fire a shot and takes as input parameter the position from where the shot is fired and the velocity (direction and speed) of the shot. Additional meta data includes the Id of the entity that fired the shot and whether the firing entity is a player. The FireShot method raises an event that is handled by the Game class to notify the client or server (depending who is firing the shot) when a shot is fired.</p>
<h4>Sending Messages</h4>
<p>As per the previous articles we send messages by handling the events raised by the Manager type classes. In this case we handle the ShotFired event as follows.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:854e6d71-0067-466a-9e68-9b6ca36902f7" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"> <span style="color:#0000ff;">this</span>.soundManager = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">SoundManager</span>(randomNumberGenerator);<br /> <span style="color:#0000ff;">this</span>.shotManager = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">ShotManager</span>(<span style="color:#0000ff;">this</span>.resolutionManager, <span style="color:#0000ff;">this</span>.soundManager);<br /> <span style="color:#0000ff;">this</span>.shotManager.ShotFired += (sender, e) =&gt; <span style="color:#0000ff;">this</span>.networkManager.SendMessage(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">ShotFiredMessage</span>(e.Shot));</div>
</p></div>
</p></div>
<p>The ShotFired event is handled for both the client and the server.</p>
<p>The ShotFiredMessage is similar to the message classes defined previously.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1f357f5f-a734-4673-8cea-de6673474d4f" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;max-height:500px;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> <span style="color:#2b91af;">ShotFiredMessage</span> : <span style="color:#2b91af;">IGameMessage</span><br /> {<br />     <span style="color:#0000ff;">#region</span> Constructors and Destructors</p>
<p>     <span style="color:#0000ff;">public</span> ShotFiredMessage(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br />     {<br />         <span style="color:#0000ff;">this</span>.Decode(im);<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> ShotFiredMessage(<span style="color:#2b91af;">Shot</span> shot)<br />     {<br />         <span style="color:#0000ff;">this</span>.Id = shot.Id;<br />         <span style="color:#0000ff;">this</span>.Position = shot.SimulationState.Position;<br />         <span style="color:#0000ff;">this</span>.Velocity = shot.SimulationState.Velocity;<br />         <span style="color:#0000ff;">this</span>.FiredByPlayer = shot.FiredByPlayer;<br />         <span style="color:#0000ff;">this</span>.MessageTime = <span style="color:#2b91af;">NetTime</span>.Now;<br />         <span style="color:#0000ff;">this</span>.FiredById = shot.FiredById;<br />     }</p>
<p>     <span style="color:#0000ff;">#endregion</span></p>
<p>     <span style="color:#0000ff;">#region</span> Public Properties</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">long</span> FiredById { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">bool</span> FiredByPlayer { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">long</span> Id { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">double</span> MessageTime { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">GameMessageTypes</span> MessageType<br />     {<br />         <span style="color:#0000ff;">get</span><br />         {<br />             <span style="color:#0000ff;">return</span> <span style="color:#2b91af;">GameMessageTypes</span>.ShotFired;<br />         }<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">Vector2</span> Position { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">Vector2</span> Velocity { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">#endregion</span></p>
<p>     <span style="color:#0000ff;">#region</span> Public Methods and Operators</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Decode(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br />     {<br />         <span style="color:#0000ff;">this</span>.Id = im.ReadInt64();<br />         <span style="color:#0000ff;">this</span>.MessageTime = im.ReadDouble();<br />         <span style="color:#0000ff;">this</span>.Position = im.ReadVector2();<br />         <span style="color:#0000ff;">this</span>.Velocity = im.ReadVector2();<br />         <span style="color:#0000ff;">this</span>.FiredByPlayer = im.ReadBoolean();<br />         <span style="color:#0000ff;">this</span>.FiredById = im.ReadInt64();<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Encode(<span style="color:#2b91af;">NetOutgoingMessage</span> om)<br />     {<br />         om.Write(<span style="color:#0000ff;">this</span>.Id);<br />         om.Write(<span style="color:#0000ff;">this</span>.MessageTime);<br />         om.Write(<span style="color:#0000ff;">this</span>.Position);<br />         om.Write(<span style="color:#0000ff;">this</span>.Velocity);<br />         om.Write(<span style="color:#0000ff;">this</span>.FiredByPlayer);<br />         om.Write(<span style="color:#0000ff;">this</span>.FiredById);<br />     }</p>
<p>     <span style="color:#0000ff;">#endregion</span><br /> }</div>
</p></div>
</p></div>
<p>The above ShotFiredMessage is very similar to the other GameMessages we have defined thus far. In this case we have made provision for the FiredById and FiredByPlayer properties.</p>
<h4>Receiving Messages</h4>
<p>The ShotFiredMessage is handled using the same pattern as the previous message types. The ProcessNetworkMessages method in the game code is updated as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:80b0faba-b3f4-4560-94b5-eff56b2d2e1b" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.Data:<br />     <span style="color:#0000ff;">var</span> gameMessageType = (<span style="color:#2b91af;">GameMessageTypes</span>)im.ReadByte();<br />     <span style="color:#0000ff;">switch</span> (gameMessageType)<br />     {<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.UpdateAsteroidState:<br />             <span style="color:#0000ff;">this</span>.HandleUpdateAsteroidStateMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.UpdatePlayerState:<br />             <span style="color:#0000ff;">this</span>.HandleUpdatePlayerStateMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.ShotFired:<br />             <span style="color:#0000ff;">this</span>.HandleShotFiredMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />     }</p>
<p>     <span style="color:#0000ff;">break</span>;</div>
</p></div>
</p></div>
<p>With the HandleShotFired method implemented as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:57ba911d-a282-4eca-bec3-8288bf2d95e6" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> HandleShotFiredMessage(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br /> {<br />     <span style="color:#0000ff;">var</span> message = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">ShotFiredMessage</span>(im);</p>
<p>     <span style="color:#0000ff;">var</span> timeDelay = (<span style="color:#0000ff;">float</span>)(<span style="color:#2b91af;">NetTime</span>.Now &#8211; im.SenderConnection.GetLocalTime(message.MessageTime));</p>
<p>     <span style="color:#2b91af;">Vector2</span> adjustedPosition = message.Position + (message.Velocity * timeDelay);</p>
<p>     <span style="color:#0000ff;">this</span>.shotManager.FireShot(<br />         message.Id, adjustedPosition, message.Velocity, message.FiredById, message.FiredByPlayer);<br /> }</div>
</p></div>
</p></div>
<p>As before, we decode the game message into our ShotFiredMessage class. We calculate the time delay and update the position of the Shot taking into account any latency. We then call the FireShot message on the ShotManager class to add the shot to the collection of shots to be managed. </p>
<p><strong>Note:</strong> We are using the non event raising override of the FireShot method. This pattern is repeated in all the manager implementations. On each manager we have a version of the method that will raise the “create” or “update” event and a version that will add the object instance but not raise any events. The latter version is used when processing game network messages to update the local state in our manager classes.</p>
<p>By adding a few lines of code to the PlayerManager class we now have the player ship firing bullets on both the client and server.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:94e6e4f7-592a-4c0f-857f-0737bb3da4f0" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.inputManager.IsKeyDown(<span style="color:#2b91af;">Keys</span>.Space))<br /> {<br />     <span style="color:#0000ff;">this</span>.FireShot();<br /> }</div>
</p></div>
</p></div>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7837259c-aaec-408f-8e3a-5fbf89374ba7" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> FireShot()<br /> {<br />     <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.shotTimer.Stopwatch(200))<br />     {<br />         <span style="color:#0000ff;">this</span>.shotManager.FireShot(<br />             <span style="color:#0000ff;">this</span>.localPlayer.SimulationState.Position + <span style="color:#0000ff;">this</span>.gunOffset, <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">Vector2</span>(0, -1), <span style="color:#0000ff;">this</span>.localPlayer.Id, <span style="color:#0000ff;">true</span>);<br />     }<br /> }</div>
</p></div>
</p></div>
<p>The Update method will check if the Spacebar is pressed and call the FireShot method. We have limited the shots to be fired to fire every 200ms. Shots are fired from the SimulatedState position taking into account a GunOffset to set the initial position of the shot.</p>
<p>The video below shows an example of shots being fired by the client player instance and how the shots are displayed on the server-side.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:616dd436-0fb0-41c0-8f49-00930fc622fc" class="wlWriterEditableSmartContent">
<div><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='448' height='252' src='http://www.youtube.com/embed/nhYdrVDRQx4?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;hd=1&#038;wmode=transparent' frameborder='0'></iframe></span></div>
<div style="width:448px;clear:both;font-size:.8em;">Firing shots (200ms delay)</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/144/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/144/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=144&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/02/29/lets-make-a-multiplayer-game-part-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>
	</item>
		<item>
		<title>Let&#8217;s make a multiplayer game (part 7)</title>
		<link>http://dirkkok.wordpress.com/2012/02/26/lets-make-a-multiplayer-game-part-7/</link>
		<comments>http://dirkkok.wordpress.com/2012/02/26/lets-make-a-multiplayer-game-part-7/#comments</comments>
		<pubDate>Sun, 26 Feb 2012 09:32:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=141</guid>
		<description><![CDATA[In the previous article I demonstrated how latency impacts the smoothness of the gameplay experience. The deterministic part of the game simulation i.e. the asteroids are not affected as much due to the fact that their movement will follow a predictable course. The player movement however, is very unpredictable with the jittery effect being magnified &#8230; <a href="http://dirkkok.wordpress.com/2012/02/26/lets-make-a-multiplayer-game-part-7/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=141&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In the previous article I demonstrated how latency impacts the smoothness of the gameplay experience. The deterministic part of the game simulation i.e. the asteroids are not affected as much due to the fact that their movement will follow a predictable course. The player movement however, is very unpredictable with the jittery effect being magnified by frequent player movement changes. </p>
<p>The way to correct the snapping of networked entities is to make use of some kind of smoothing technique. The simplest of these is to make use of Linear Interpolation. Here are some links to articles I found useful. </p>
<p><a title="http://gafferongames.com/game-physics/networked-physics/" href="http://gafferongames.com/game-physics/networked-physics/">http://gafferongames.com/game-physics/networked-physics/</a>. This article is really good with a LOT of useful information in the comments section.</p>
<p>This <a href="http://www.gamasutra.com/view/feature/3230/dead_reckoning_latency_hiding_for_.php" target="_blank">Gamasutra</a> article contains a good general description of dead-reckoning.</p>
<p>The <a href="https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking" target="_blank">Source</a> engine articles from Valve are also really useful.</p>
<p>You will notice that this code makes use of the ideas from <a href="http://blogs.msdn.com/b/shawnhar/archive/2009/06/25/generic-network-prediction.aspx" target="_blank">Shawn Hargreaves’ Blog</a> entry. </p>
<p>In my previous articles I showed how I keep three versions of the EntityState (Position, Velocity, Rotation) for each of my sprites. The reason for this is so that we can separate the display state from the simulation state. The simulation state will be used for all game logic decisions such as collision detection. The display state will be used for rendering.</p>
<p>In order to perform linear interpolation we will be interpolating between the previous display state (where we last rendered) and the simulation state (where the object currently is). A linear interpolation requires the from state, to state and an interpolation factor. I’m sure there are sophisticated techniques for determining the interpolation factor. My calculation is based on the fact that by default XNA calls the update method 1000ms / 60 = every 16.67ms. I reasoned that I would like the display state to reach the simulation state after 200ms meaning I would need 200ms / 16.67ms = 12 updates to achieve it. The resulting interpolation factor is therefore 1 / 12.</p>
<p>The following code shows the Update method for all my sprites.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bc34f329-9ece-4a1f-9f42-4739718a4539" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">virtual</span> <span style="color:#0000ff;">void</span> Update(<span style="color:#2b91af;">GameTime</span> gameTime)<br /> {<br />     <span style="color:#0000ff;">var</span> elapsedSeconds = (<span style="color:#0000ff;">float</span>)gameTime.ElapsedGameTime.TotalSeconds;</p>
<p>     <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.frameTimer.Stopwatch(100))<br />     {<br />         <span style="color:#0000ff;">this</span>.currentFrameIndex = (<span style="color:#0000ff;">this</span>.currentFrameIndex + 1) % <span style="color:#0000ff;">this</span>.frames.Count;<br />     }</p>
<p>     <span style="color:#0000ff;">this</span>.SimulationState.Position += <span style="color:#0000ff;">this</span>.SimulationState.Velocity * elapsedSeconds;</p>
<p>     <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.EnableSmoothing)<br />     {<br />         <span style="color:#0000ff;">this</span>.PrevDisplayState.Position += <span style="color:#0000ff;">this</span>.PrevDisplayState.Velocity * elapsedSeconds;</p>
<p>         <span style="color:#0000ff;">this</span>.ApplySmoothing(1/12f);<br />     }<br />     <span style="color:#0000ff;">else</span><br />     {<br />         <span style="color:#0000ff;">this</span>.DisplayState = (<span style="color:#2b91af;">EntityState</span>)<span style="color:#0000ff;">this</span>.SimulationState.Clone();<br />     }<br /> }</div>
</p></div>
</p></div>
<p>First I get the elapsed seconds since the last update. This value is used to advance the sprite position by it’s velocity. </p>
<p>The FrameTimer code is just looping between the animation frames every 200ms.</p>
<p>Next we use the elapsed time to update the SimulationState of the entity.</p>
<p>If smoothing is <strong>disabled</strong> then the DisplayState is equal to the SimulationState.</p>
<p>When smoothing is <strong>enabled</strong> we need to apply smoothing. Firstly we update the previous display state position based on its velocity and the elapsed time. Then we apply the smoothing based on the interpolation factor as described above.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fe0481ce-a836-4599-985a-d5dd5cd538bb" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> ApplySmoothing(<span style="color:#0000ff;">float</span> delta)<br /> {<br />     <span style="color:#0000ff;">this</span>.DisplayState.Position = <span style="color:#2b91af;">Vector2</span>.Lerp(<br />         <span style="color:#0000ff;">this</span>.PrevDisplayState.Position, <span style="color:#0000ff;">this</span>.SimulationState.Position, delta);</p>
<p>     <span style="color:#0000ff;">this</span>.DisplayState.Velocity = <span style="color:#2b91af;">Vector2</span>.Lerp(<br />         <span style="color:#0000ff;">this</span>.PrevDisplayState.Velocity, <span style="color:#0000ff;">this</span>.SimulationState.Velocity, delta);</p>
<p>     <span style="color:#0000ff;">this</span>.DisplayState.Rotation = <span style="color:#2b91af;">MathHelper</span>.Lerp(<br />         <span style="color:#0000ff;">this</span>.PrevDisplayState.Rotation, <span style="color:#0000ff;">this</span>.SimulationState.Rotation, delta);</p>
<p>     <span style="color:#0000ff;">this</span>.PrevDisplayState = (<span style="color:#2b91af;">EntityState</span>)<span style="color:#0000ff;">this</span>.DisplayState.Clone();<br /> }</div>
</p></div>
</p></div>
<p>Using the Vector2.Lerp method our DisplayState values now become the interpolated value from the PrevDisplayState to the SimluationState according to the interpolation factor.</p>
<p>Lastly the PrevDisplayState is updated to the current DisplayState. The above code will enable a smooth linear interpolation of the DisplayState to the SimulationState within 200ms.</p>
<p>I have modified the Draw method to render the SimulationState when smoothing is enabled. This is purely for debugging purposes and will be disabled during actual gameplay.</p>
<p>The HandleUpdatePlayerStateMessage method in the game class is now as follows.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:60072f06-8298-4ae8-a4e8-27906cb3aa6e" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> HandleUpdatePlayerStateMessage(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br /> {<br />     <span style="color:#0000ff;">var</span> message = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">UpdatePlayerStateMessage</span>(im);</p>
<p>     <span style="color:#0000ff;">var</span> timeDelay = (<span style="color:#0000ff;">float</span>)(<span style="color:#2b91af;">NetTime</span>.Now &#8211; im.SenderConnection.GetLocalTime(message.MessageTime));</p>
<p>     <span style="color:#2b91af;">Player</span> player = <span style="color:#0000ff;">this</span>.playerManager.GetPlayer(message.Id) ??<br />                         <span style="color:#0000ff;">this</span>.playerManager.AddPlayer(message.Id, message.Position, message.Velocity, message.Rotation, <span style="color:#0000ff;">false</span>);</p>
<p>     player.EnableSmoothing = <span style="color:#0000ff;">true</span>;</p>
<p>     <span style="color:#0000ff;">if</span> (player.LastUpdateTime &lt; message.MessageTime)<br />     {<br />         player.SimulationState.Position = message.Position += (message.Velocity * timeDelay);<br />         player.SimulationState.Velocity = message.Velocity;<br />         player.SimulationState.Rotation = message.Rotation;</p>
<p>         player.LastUpdateTime = message.MessageTime;<br />     }<br /> }</div>
</p></div>
</p></div>
<p>No major changes, except for the fact that smoothing is now enabled. I had some code referencing the PrevDisplayState. This was a bug and has been removed.</p>
<p>I played around with the idea of ignoring LOCAL player state updates. The effect of is a 100% match between the DisplayState and SimulationState for the local player with no snapping. The only issue is that the player will never be updated with the server values which could lead to some inconsistencies. I did however, reduce the player update heartbeat to once per second, reasoning that I could tolerate local player adjustments in high latency conditions every second.</p>
<p>The following video shows the effects of enabling player smoothing.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:57149a0b-eb8f-40e5-8038-7acda95a23d8" class="wlWriterEditableSmartContent">
<div><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='448' height='252' src='http://www.youtube.com/embed/lq-FE9bgBdU?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;hd=1&#038;wmode=transparent' frameborder='0'></iframe></span></div>
<div style="width:448px;clear:both;font-size:.8em;">Smoothing Enabled (200ms latency)</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/141/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=141&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/02/26/lets-make-a-multiplayer-game-part-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>
	</item>
		<item>
		<title>Let&#8217;s make a multiplayer game (part 6)</title>
		<link>http://dirkkok.wordpress.com/2012/02/25/lets-make-a-multiplayer-game-part-6/</link>
		<comments>http://dirkkok.wordpress.com/2012/02/25/lets-make-a-multiplayer-game-part-6/#comments</comments>
		<pubDate>Sat, 25 Feb 2012 06:00:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=135</guid>
		<description><![CDATA[YIn this article I will cover controlling the player ship. Handling player input is more involved as it happens both on the server and all the connected clients. Our simulation will contain multiple players which will need to be updated and drawn, but can only be controlled on the instance they belong to. With that &#8230; <a href="http://dirkkok.wordpress.com/2012/02/25/lets-make-a-multiplayer-game-part-6/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=135&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>YIn this article I will cover controlling the player ship. Handling player input is more involved as it happens both on the server and all the connected clients. Our simulation will contain multiple players which will need to be updated and drawn, but can only be controlled on the instance they belong to. With that introduction I will jump into the player class.</p>
<h4>The Player Class</h4>
<p>The Player class inherits from our Sprite class and adds some properties needed to manage the player. These properties are related to game logic such as managing player lives and score and I will not cover them in this article.</p>
<h4>The Player Manager Class</h4>
<p>The PlayerManager class is responsible for updating the player objects, drawing the player objects, handling player input for the locally controlled player and sending notifications when the player state has changed. </p>
<p>The Update method is interesting from a multiplayer game programming perspective.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b3e87207-4cff-4888-94d6-0b94c78d8872" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Update(<span style="color:#2b91af;">GameTime</span> gameTime)<br /> {<br />     <span style="color:#0000ff;">if</span> ((<span style="color:#0000ff;">this</span>.localPlayer != <span style="color:#0000ff;">null</span>) &amp;&amp; (!<span style="color:#0000ff;">this</span>.localPlayer.IsDestroyed))<br />     {<br />         <span style="color:#0000ff;">var</span> velocityChanged = <span style="color:#0000ff;">this</span>.HandlePlayerMovement();</p>
<p>         <span style="color:#0000ff;">if</span> (velocityChanged)<br />         {<br />             <span style="color:#0000ff;">this</span>.OnPlayerStateChanged(<span style="color:#0000ff;">this</span>.localPlayer);<br />         }<br />     }</p>
<p>     <span style="color:#0000ff;">foreach</span> (<span style="color:#2b91af;">Player</span> player <span style="color:#0000ff;">in</span> <span style="color:#0000ff;">this</span>.Players)<br />     {<br />         player.Update(gameTime);</p>
<p>         <span style="color:#0000ff;">if</span> (!player.IsDestroyed)<br />         {<br />             <span style="color:#0000ff;">this</span>.ImposeMovementLimits(player);<br />         }<br />     }</p>
<p>     <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.isHost &amp;&amp; <span style="color:#0000ff;">this</span>.hearbeatTimer.Stopwatch(1000))<br />     {<br />         <span style="color:#0000ff;">foreach</span> (<span style="color:#0000ff;">var</span> player <span style="color:#0000ff;">in</span> <span style="color:#0000ff;">this</span>.Players)<br />         {<br />             <span style="color:#0000ff;">this</span>.OnPlayerStateChanged(player);<br />         }<br />     }<br /> }</div>
</p></div>
</p></div>
<p>Firstly we want to handle player input only for the local player and if the player is alive. My HandlePlayerMovement method basically checks the keyboard input and adjusts the Player velocity information based on the user input. The Player will move as long as the user presses a movement key. Releasing a movement key will cause the player to stop moving in that direction. From a networking perspective we don’t want to send movement messages for every update cycle. This would cause the server to process messages rather than actually processing the game logic.</p>
<p>We are more interested in sending changes in velocity and that is why the HandlePlayerMovement method returns true when there was a change in the player velocity vector. As per the previous articles we use an event to notify the game that there was a change in the EntityState of the player.</p>
<p>The next part is purely game logic where we process the movement of each of our players and limit the player movement to the bounds of the screen.</p>
<p>The last part of the Update method is where we send heartbeat updates to all the clients if we are the server instance of the game.</p>
<p>I had to add the concept of a LocalPlayer property to the PlayerManager class. This is how the PlayerManager knows which player instance should respond to user input.</p>
<h4>Creating the Player</h4>
<p>The next case to handle is when the player class is instantiated for both the client and the server. In the previous articles I mentioned that the Server is the only instance of the game that is allowed to manage the creation of game state objects. This holds true for players as well, the trick here is the timing of when player instances are created.</p>
<p>On the server side there is no difficulty. The server instance just creates a new player when the game starts and that’s the end of it. In this example I create the player instance in my LoadContent method as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:865c382d-b746-46ca-bded-94ecbd90f896" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.IsHost)<br /> {<br />     <span style="color:#0000ff;">this</span>.playerManager.AddPlayer(<span style="color:#0000ff;">true</span>);<br /> }</div>
</p></div>
</p></div>
<p>The true variable means the player is local to the current instance of the game.</p>
<p>For new clients connecting to the server we need to handle things differently. This is where the NetConnectionStatus.RespondedAwaitingApproval state comes in handy. When the server detects a new client connecting it adds a new player instance to the PlayerManager. The SenderConnection.Approve() method can send back a hail message to the connecting client. I am using this message to send back the newly created Player information to the client as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1c9b0b7b-3bc8-4ad2-a37d-e38778aa9a10" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetConnectionStatus</span>.RespondedAwaitingApproval:<br />     <span style="color:#2b91af;">NetOutgoingMessage</span> hailMessage = <span style="color:#0000ff;">this</span>.networkManager.CreateMessage();<br />     <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">UpdatePlayerStateMessage</span>(playerManager.AddPlayer(<span style="color:#0000ff;">false</span>)).Encode(hailMessage);<br />     im.SenderConnection.Approve(hailMessage);<br />     <span style="color:#0000ff;">break</span>;</div>
</p></div>
</p></div>
<p>On the client side we now decode the hail message on the NetConnectionStatus.Connected state and add it to the client-side PlayerManager as the local player.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:28cb91b2-c533-4b0b-9209-b86228d0307d" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">if</span> (!<span style="color:#0000ff;">this</span>.IsHost)<br /> {<br />     <span style="color:#0000ff;">var</span> message = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">UpdatePlayerStateMessage</span>(im.SenderConnection.RemoteHailMessage);<br />     <span style="color:#0000ff;">this</span>.playerManager.AddPlayer(message.Id, message.Position, message.Velocity, message.Rotation, <span style="color:#0000ff;">true</span>);<br />     <span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&quot;Connected to {</span><span style="color:#3cb371;">0}</span><span style="color:#a31515;">&quot;</span>, im.SenderEndpoint);<br /> }<br /> <span style="color:#0000ff;">else</span><br /> {<br />     <span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&quot;{</span><span style="color:#3cb371;">0}</span><span style="color:#a31515;"> Connected&quot;</span>, im.SenderEndpoint);<br /> }</div>
</p></div>
</p></div>
<p>This neatly allows us to create a new Player instance when a client connects and send back the Player instance information to the client to add as the local client player.</p>
<p>Now we have created new players on both sides and can look at sending and receiving messages.</p>
<h4>Sending Messages</h4>
<p>We send messages in exactly the same way as with the AsteroidManager class. Instead of the messages only coming from the server we now allow the client to also send update messages for changes in the player state.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6d605683-ca7e-4b23-961b-925a8b917378" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">this</span>.asteroidManager = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">AsteroidManager</span>(<span style="color:#0000ff;">this</span>.resolutionManager, randomNumberGenerator, <span style="color:#0000ff;">this</span>.IsHost);<br /> <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.IsHost)<br /> {<br />     <span style="color:#0000ff;">this</span>.asteroidManager.AsteroidStateChanged += (sender, e) =&gt; <span style="color:#0000ff;">this</span>.networkManager.SendMessage(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">UpdateAsteroidStateMessage</span>(e.Asteroid));<br /> }</p>
<p> <span style="color:#0000ff;">this</span>.playerManager = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">PlayerManager</span>(<span style="color:#0000ff;">this</span>.resolutionManager, randomNumberGenerator, <span style="color:#0000ff;">this</span>.inputManager, <span style="color:#0000ff;">this</span>.IsHost);<br /> <span style="color:#0000ff;">this</span>.playerManager.PlayerStateChanged += (sender, e) =&gt; <span style="color:#0000ff;">this</span>.networkManager.SendMessage(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">UpdatePlayerStateMessage</span>(e.Player));</div>
</p></div>
</p></div>
<p>The Initialize method now instantiates the PlayerManager and the PlayerStateChanged event is handled on both the client and the server.</p>
<p>The only additional change I had to implement was to complete the SendMessage implementation on the ClientNetworkManager as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5be33bc9-0732-40c1-a329-8611067e2206" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SendMessage(<span style="color:#2b91af;">IGameMessage</span> gameMessage)<br /> {<br />     <span style="color:#0000ff;">var</span> om = <span style="color:#0000ff;">this</span>.netClient.CreateMessage();<br />     om.Write((<span style="color:#0000ff;">byte</span>)gameMessage.MessageType);<br />     gameMessage.Encode(om);</p>
<p>     <span style="color:#0000ff;">this</span>.netClient.SendMessage(om, <span style="color:#2b91af;">NetDeliveryMethod</span>.ReliableUnordered);<br /> }</div>
</p></div>
</p></div>
<p>This implementation is almost exactly the same as the ServerNetworkManager class except that it uses the underlying NetClient class.</p>
<p>I am not going to cover the UpdatePlayerStateMessage since it is exactly the same at the UpdateAsteroidStateMessage previously covered.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:96f2d0b3-5c3d-4020-a9a7-6eda61fd6e1c" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SendMessage(<span style="color:#2b91af;">IGameMessage</span> gameMessage)<br /> {<br />     <span style="color:#0000ff;">var</span> om = <span style="color:#0000ff;">this</span>.netClient.CreateMessage();<br />     om.Write((<span style="color:#0000ff;">byte</span>)gameMessage.MessageType);<br />     gameMessage.Encode(om);</p>
<p>     <span style="color:#0000ff;">this</span>.netClient.SendMessage(om, <span style="color:#2b91af;">NetDeliveryMethod</span>.ReliableUnordered);<br /> }</div>
</p></div>
</p></div>
<p>To start receiving the UpdatePlayerStateMessages we need to add the appropraite case to our switch statement in the ProcessNetworkMessages method.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5d65db89-398c-476f-bbbe-4c770d7215e0" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.Data:<br />     <span style="color:#0000ff;">var</span> gameMessageType = (<span style="color:#2b91af;">GameMessageTypes</span>)im.ReadByte();<br />     <span style="color:#0000ff;">switch</span>(gameMessageType)<br />     {<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.UpdateAsteroidState:<br />             <span style="color:#0000ff;">this</span>.HandleUpdateAsteroidStateMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.UpdatePlayerState:<br />             <span style="color:#0000ff;">this</span>.HandleUpdatePlayerStateMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />     }<br />     <span style="color:#0000ff;">break</span>;</div>
</p></div>
</p></div>
<p>The HandleUpdatePlayerStateMessage implementation is as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:172ada32-c5c1-4a96-9433-b462ebe85ffa" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> HandleUpdatePlayerStateMessage(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br /> {<br />     <span style="color:#0000ff;">var</span> message = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">UpdatePlayerStateMessage</span>(im);</p>
<p>     <span style="color:#0000ff;">var</span> timeDelay = (<span style="color:#0000ff;">float</span>)(<span style="color:#2b91af;">NetTime</span>.Now &#8211; im.SenderConnection.GetLocalTime(message.MessageTime));</p>
<p>     <span style="color:#2b91af;">Player</span> player = <span style="color:#0000ff;">this</span>.playerManager.GetPlayer(message.Id) ??<br />                         <span style="color:#0000ff;">this</span>.playerManager.AddPlayer(message.Id, message.Position, message.Velocity, message.Rotation, <span style="color:#0000ff;">false</span>);</p>
<p>     <span style="color:#008000;">//player.EnableSmoothing = true;</span></p>
<p>     <span style="color:#0000ff;">if</span> (player.LastUpdateTime &lt; message.MessageTime)<br />     {<br />         player.PrevDisplayState = (<span style="color:#2b91af;">EntityState</span>)player.DisplayState.Clone();</p>
<p>         player.SimulationState.Position = message.Position += (message.Velocity * timeDelay);</p>
<p>         player.SimulationState.Velocity = message.Velocity;<br />         player.SimulationState.Rotation = message.Rotation;</p>
<p>         player.LastUpdateTime = message.MessageTime;<br />     }<br /> }</div>
</p></div>
</p></div>
<p>You will notice that it is exactly the same (or very similar) to the HandleUpdateAsteroidStateMessage. We could probably refactor this at a later stage. For the time being I will keep it separate to avoid confusion.</p>
<p>Notice that player.EnableSmoothing is commented out. With a simulated latency of 200ms you will immediately notice why we need a good smoothing solution.</p>
<p>In the following video I am controlling the client player. Notice how the player movement on the server-side is very jerky. This is due to the fact that the server is only receiving changes in the player position and velocity 200ms after they have actually happened causing the player to snap to the new position.</p>
<p>On the client-side you will notice the player periodically snap to a position. This is due to the heartbeat update from the server with the 200ms latency.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:d689e305-f7ef-48c7-be80-a797d2c3c7f4" class="wlWriterEditableSmartContent">
<div><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='448' height='252' src='http://www.youtube.com/embed/b4FIIzZ4E0I?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;hd=1&#038;wmode=transparent' frameborder='0'></iframe></span></div>
<div style="width:448px;clear:both;font-size:.8em;">Player movement with 200ms latency</div>
</div>
<p>In the next article I will cover some techniques in smoothing out the snapping effect caused by latency.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/135/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=135&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/02/25/lets-make-a-multiplayer-game-part-6/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>
	</item>
		<item>
		<title>Let&#8217;s make a multiplayer game (part 5)</title>
		<link>http://dirkkok.wordpress.com/2012/02/24/lets-make-a-multiplayer-game-part-5/</link>
		<comments>http://dirkkok.wordpress.com/2012/02/24/lets-make-a-multiplayer-game-part-5/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 05:30:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=132</guid>
		<description><![CDATA[At this point I am going to spend to time to recap on the concepts I covered in the previous articles. The game is designed to be a single entry point that can either operate in server mode or client mode. This is a design choice and not a requirement. The game has the following &#8230; <a href="http://dirkkok.wordpress.com/2012/02/24/lets-make-a-multiplayer-game-part-5/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=132&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>At this point I am going to spend to time to recap on the concepts I covered in the previous articles. </p>
<p>The game is designed to be a single entry point that can either operate in server mode or client mode. This is a design choice and not a requirement.</p>
<p>The game has the following common responsibilities in both server and client mode.</p>
<ul>
<li><strong>Update game objects</strong>. Each of our game objects have their own logic which needs to be processed. In this game it is typically the physics logic to allow the objects to move around the screen. </li>
<li><strong>Apply game logic</strong>. An example of game logic is the processing of collisions between game objects. This behaviour needs to be handled consistently on both the client and server to ensure the responsiveness of the game. </li>
<li><strong>Draw game objects</strong>. The game obviously needs to render the scene. </li>
</ul>
<p>When the game is running in client mode it is also responsible for the following.</p>
<ul>
<li><strong>Notify the Server of player actions</strong>. When the player performs an action we need to execute it on the client to provide immediate feedback. We also need to inform the server of the action so that it does not override the player state during the next update cycle. </li>
<li><strong>Respond to messages from the server</strong>. The client needs to respond to server messages to ensure that the client version of the simulation is synchronised with the server version. </li>
</ul>
<p>When the game is running in server mode it responsible for the following (in addition to the common elements).</p>
<ul>
<li><strong>Respond to messages from the client.</strong> The server needs to process messages received from the client. Here the server can override any invalid requests and the action will be reverted on the client.</li>
<li><strong>Notify clients of game object changes.</strong> The server needs to send out periodic state updates to all the clients. I call this the heartbeat update as it should happen at a regular time interval.</li>
<li><strong>Create game objects.</strong> The server is responsible for the game state, by not allowing clients to create objects we can be fairly confident of a synchronised simulation.</li>
<li><strong>Delete game objects.</strong> This is the inverse of creating objects again we do this on the server to ensure consistency.</li>
</ul>
<p>We encapsulate our game network messages in a message class that implements the following IGameMessage interface.</p>
<p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f1bf3541-9984-449f-8f6b-a4bcd60fcda6" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">interface</span> <span style="color:#2b91af;">IGameMessage</span><br /> {<br />     <span style="color:#2b91af;">GameMessageTypes</span> MessageType { <span style="color:#0000ff;">get</span>; }</p>
<p>     <span style="color:#0000ff;">void</span> Encode(<span style="color:#2b91af;">NetOutgoingMessage</span> om);</p>
<p>     <span style="color:#0000ff;">void</span> Decode(<span style="color:#2b91af;">NetIncomingMessage</span> im);<br /> }</div>
</p></div>
</p></div>
</p>
<p>The MessageType property is used to identify our game messages and should be the first byte sent and received for every game message.</p>
<p>The Encode and Decode methods should mirror each other exactly. This will eliminate a lot of errors that could occur when sending and receiving messages.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d3959e79-05f8-45cd-badf-05ced5fb0801" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Decode(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br /> {<br />     <span style="color:#0000ff;">this</span>.Id = im.ReadInt64();<br />     <span style="color:#0000ff;">this</span>.MessageTime = im.ReadDouble();<br />     <span style="color:#0000ff;">this</span>.Position = im.ReadVector2();<br />     <span style="color:#0000ff;">this</span>.Velocity = im.ReadVector2();<br />     <span style="color:#0000ff;">this</span>.Rotation = im.ReadSingle();<br /> }</p>
<p> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Encode(<span style="color:#2b91af;">NetOutgoingMessage</span> om)<br /> {<br />     om.Write(<span style="color:#0000ff;">this</span>.Id);<br />     om.Write(<span style="color:#0000ff;">this</span>.MessageTime);<br />     om.Write(<span style="color:#0000ff;">this</span>.Position);<br />     om.Write(<span style="color:#0000ff;">this</span>.Velocity);<br />     om.Write(<span style="color:#0000ff;">this</span>.Rotation);<br /> }</div>
</p></div>
</p></div>
<p>I recommend always sending the NetTime.Now value along with the game message as it is useful in determining the exact latency when the message is processed as well as filtering out of sequence messages.</p>
<p>I think that covers the main ideas I wanted to review. In the next article I will add the PlayerManager class which will allow us to control the player ship.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/132/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=132&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/02/24/lets-make-a-multiplayer-game-part-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>
	</item>
		<item>
		<title>Let&#8217;s make a multiplayer game (part 4)</title>
		<link>http://dirkkok.wordpress.com/2012/02/22/lets-make-a-multiplayer-game-part-4/</link>
		<comments>http://dirkkok.wordpress.com/2012/02/22/lets-make-a-multiplayer-game-part-4/#comments</comments>
		<pubDate>Wed, 22 Feb 2012 20:11:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=126</guid>
		<description><![CDATA[In this article I will demonstrate how to get some asteroids flying around the screen synchronized on both the client and server. The Asteroid Class Each of our asteroids are represented by an Asteroid class which inherits from a general Sprite class. I’m not going to cover the Sprite class in detail but would like &#8230; <a href="http://dirkkok.wordpress.com/2012/02/22/lets-make-a-multiplayer-game-part-4/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=126&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In this article I will demonstrate how to get some asteroids flying around the screen synchronized on both the client and server.</p>
<h4>The Asteroid Class</h4>
<p>Each of our asteroids are represented by an Asteroid class which inherits from a general Sprite class. I’m not going to cover the Sprite class in detail but would like to highlight the areas that are relevant for networking.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9a0eeb9d-885e-43d6-9a8a-5a7a01820227" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">double</span> LastUpdateTime { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p> <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">EntityState</span> PrevDisplayState { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p> <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">EntityState</span> SimulationState { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p> <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">EntityState</span> DisplayState { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">bool</span> EnableSmoothing { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</div>
</p></div>
</p></div>
<p>The LastUpdateTime property is used to check when last a particular sprite was updated. I use this to make sure I don’t process old messages out of sequence. You will notice that in this example game I make use of the ReliableUnordered NetDeliveryMethod. This means that the Lidgren library guarantees message delivery but not the sequence in which the messages will be delivered.</p>
<p>The PrevDisplayState property is used to store the last rendered EntityState values. This is used during the smoothing of the drawing which I will cover in more detail in a later article.</p>
<p>The SimulationState property is used to store the current simulation state of the entity. This means the real values used by the simulation i.e. the actual position, velocity and rotation.</p>
<p>The DisplayState property is used to store the current rendered EntityState values. If smoothing is disabled then the DisplayState will equal the SimulationState i.e. we have not made any adjustments to how we render the EntityState between frames.</p>
<p>The EnableSmoothing property is used to determine if we should smooth the rendering of the sprite between frames. The smoothing is done from the PrevDisplayState to the SimulationState.</p>
<p>The EntityState class stores the Position (Vector2), Velocity (Vector2) and Rotation (float) of our sprite.</p>
<p>You can see how the Draw and Update methods makes use of the DisplayState and SimulationState properties respectively.</p>
<h4>The Asteroid Manager Class</h4>
<p>This game architecture makes use of Manager classes to control objects of the same type. You will see an AsteroidManager, PlayerManager, EnemyManager, ShotManager, CollisionManager, etc. </p>
<p>Each manager class is responsible for loading its own content, creating it’s objects, drawing the objects and updating the objects. Now in the previous articles I mentioned that the server is responsible for the simulation state. In the case of the AsteroidManager the server is the only one that can add or remove asteroids from the simulation. It also has the final say over the real SimulationState of each of the asteroids.</p>
<p>Because we want our simulation to be responsive on the client-side (even with some latency) we need to do some client-side processing of the simulation. What this means is that the client-side instance of the AsteroidManager should be allowed to draw, bounds asteroid against each other and update the asteroid positions.</p>
<p>To separate these two behaviours I have introduced a bool called IsHost to the AsteroidManager class. When IsHost is true our AsteroidManager will perform server functions as well as the functionality common to both the client and the server.</p>
<p>Most of the work is done in the Update method. The purpose of this method is to update each of the individual asteroids and then to perform some game logic such as handle asteroids that have move offscreen, handle collisions between asteroids, ensure the correct number of asteroids exist and finally to send out notifications of the current asteroid EntityStates.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8aa54e14-0da7-4016-b60b-f06ef1162c7a" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Update(<span style="color:#2b91af;">GameTime</span> gameTime)<br /> {<br />     <span style="color:#0000ff;">foreach</span> (<span style="color:#2b91af;">Asteroid</span> asteroid <span style="color:#0000ff;">in</span> <span style="color:#0000ff;">this</span>.Asteroids)<br />     {<br />         asteroid.Update(gameTime);<br />         <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.isHost)<br />         {<br />             <span style="color:#0000ff;">if</span> (!<span style="color:#0000ff;">this</span>.IsOnScreen(asteroid))<br />             {<br />                 asteroid.SimulationState = <span style="color:#0000ff;">this</span>.SelectRandomEntityState();<br />                 <span style="color:#0000ff;">this</span>.OnAsteroidStateChanged(asteroid);<br />             }<br />         }<br />     }</p>
<p>     <span style="color:#0000ff;">var</span> processedList = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">Asteroid</span>&gt;();<br />     <span style="color:#0000ff;">foreach</span> (<span style="color:#2b91af;">Asteroid</span> a1 <span style="color:#0000ff;">in</span> <span style="color:#0000ff;">this</span>.Asteroids)<br />     {<br />         processedList.Add(a1);<br />         <span style="color:#0000ff;">foreach</span> (<span style="color:#2b91af;">Asteroid</span> a2 <span style="color:#0000ff;">in</span> <span style="color:#0000ff;">this</span>.asteroids.Values.Except(processedList))<br />         {<br />             <span style="color:#0000ff;">if</span> (a1.IsCircleColliding(a2.Center, a2.CollisionRadius))<br />             {<br />                 <span style="color:#0000ff;">this</span>.BounceAsteroids(a1, a2);<br />             }<br />         }<br />     }</p>
<p>     <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.isHost)<br />     {<br />         <span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = <span style="color:#0000ff;">this</span>.asteroids.Count; i &lt; <span style="color:#0000ff;">this</span>.asteroidCount; i++)<br />         {<br />             <span style="color:#0000ff;">this</span>.AddAsteroid();<br />         }</p>
<p>         <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.hearbeatTimer.Stopwatch(200))<br />         {<br />             <span style="color:#0000ff;">foreach</span> (<span style="color:#0000ff;">var</span> asteroid <span style="color:#0000ff;">in</span> <span style="color:#0000ff;">this</span>.Asteroids)<br />             {<br />                 <span style="color:#0000ff;">this</span>.OnAsteroidStateChanged(asteroid);<br />             }<br />         }<br />     }<br /> }</div>
</p></div>
</p></div>
<p>In the first part of the Update method we enumerate all the asteroids and call their Update method. This will allow the asteroids to move around on the screen due to their positions being updated with the velocity vector.</p>
<p>Here we see the first server specific code where we test if an asteroid has been moved outside the bounds of the screen. When an asteroid is outside the bounds we choose a new random position and velocity and then raise the AsteroidStateChanged event.</p>
<p><strong>Note: </strong>I decided that I would make use of events to manage notifications of state changes in my simulation. The server instance of the game will bind to this event and send the appropriate network message to each of the clients. The client instance of the game does not bind to this event so even if it was raised it would never do anything about it. I found this technique to work quite nicely for this game. </p>
<p>The second part of the update method checks for collisions between asteroids and invokes a method to let the asteroids bounce by changing their velocity vectors. Once the colliding asteroids have been updated I once again raise the AsteroidStateChanged event so that the new state update will be sent to the clients.</p>
<p>The last part of the update method is purely server focused. The first thing I do is ensure that there are enough asteroids in the game. This code will never run on the client as it is the server’s responsibility to create asteroids.</p>
<p>The next part makes use of a Timer class to send updated EntityState values for each of the asteroids every 200ms. In an earlier design I was handling the heartbeat update in the game code itself, but it made sense for each manager to handle its own update. This heartbeat is basically our overriding update message to ensure that the client does not deviate too far from the server simulation.</p>
<h4>Sending Messages</h4>
<p>Our AsteroidManager class is now raising events when the asteroid EntityState changes. The next step is for our Game code to handle the events and send the appropriate network messages.</p>
<p>The following code shows the Initialize method in the game class:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6a63cc8f-990f-4366-ba31-8a0ad0908c3f" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> Initialize()<br /> {<br />     <span style="color:#008000;">// </span><span style="color:#00008b;">TODO: Add your initialization logic here</span><br />     <span style="color:#0000ff;">this</span>.networkManager.Connect();</p>
<p>     <span style="color:#0000ff;">var</span> randomNumberGenerator = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">MersenneTwister</span>();</p>
<p>     <span style="color:#0000ff;">this</span>.asteroidManager = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">AsteroidManager</span>(<span style="color:#0000ff;">this</span>.resolutionManager, randomNumberGenerator, <span style="color:#0000ff;">this</span>.IsHost);<br />     <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.IsHost)<br />     {<br />         <span style="color:#0000ff;">this</span>.asteroidManager.AsteroidStateChanged += (sender, e) <br />             =&gt; <span style="color:#0000ff;">this</span>.networkManager.SendMessage(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">UpdateAsteroidStateMessage</span>(e.Asteroid));<br />     }</p>
<p>     <span style="color:#0000ff;">base</span>.Initialize();<br /> }</div>
</p></div>
</p></div>
<p>You will notice that I use the Initialize method to instantiate my Manager objects. I used to have the code in the constructor but decided this felt more like initialization.</p>
<p><strong>Note: </strong>You might be wondering why the AsteroidManager isn’t an XNA game object. I will cover this in more detail in another blog post as it is more XNA related than mutliplayer game related.</p>
<p>The interresting part in the above code is the event handler I’m attaching to the AsteroidStateChanged event. Firstly it is only done when the game is running as a Host. Secondly I am calling a method on the INetworkManager interface called SendMessage. The message I’m sending is called the UpdateAsteroidStateMessage.</p>
<p>I like to encapsulate my network communications in message objects. I find this a really elegant way of handling messages with the added benefit of reducing message encoding errors.</p>
<p>Each of my messages inherit from the IGameMessage interface. </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:eea211da-fffd-42c9-a5c9-1cbc120986de" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">interface</span> <span style="color:#2b91af;">IGameMessage</span><br /> {<br />     <span style="color:#2b91af;">GameMessageTypes</span> MessageType { <span style="color:#0000ff;">get</span>; }</p>
<p>     <span style="color:#0000ff;">void</span> Encode(<span style="color:#2b91af;">NetOutgoingMessage</span> om);</p>
<p>     <span style="color:#0000ff;">void</span> Decode(<span style="color:#2b91af;">NetIncomingMessage</span> im);<br /> }</div>
</p></div>
</p></div>
<p>The MessageType property is encoded as the first value in any game message we send over the network. When we receive a game message we can then safely decode the first byte, cast it to the GameMessageType and then know what the rest of the message content should contain. You will see this in action later.</p>
<p>The Encode method is used to encode or write the contents of the message to the NetOutgoingMessage.</p>
<p>The Decode method is used to decode or read the contents from the NetIncomingMessage into the IGameMessage instance.</p>
<p>The implementation of the UpdateAsteroidStateMessage is as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:af19977c-85d1-4016-bb65-04c4b27b95ec" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> <span style="color:#2b91af;">UpdateAsteroidStateMessage</span> : <span style="color:#2b91af;">IGameMessage</span><br /> {<br />     <span style="color:#0000ff;">#region</span> Constructors and Destructors</p>
<p>     <span style="color:#0000ff;">public</span> UpdateAsteroidStateMessage(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br />     {<br />         <span style="color:#0000ff;">this</span>.Decode(im);<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> UpdateAsteroidStateMessage(<span style="color:#2b91af;">Asteroid</span> asteroid)<br />     {<br />         <span style="color:#0000ff;">this</span>.Id = asteroid.Id;<br />         <span style="color:#0000ff;">this</span>.Position = asteroid.SimulationState.Position;<br />         <span style="color:#0000ff;">this</span>.Velocity = asteroid.SimulationState.Velocity;<br />         <span style="color:#0000ff;">this</span>.Rotation = asteroid.SimulationState.Rotation;<br />         <span style="color:#0000ff;">this</span>.MessageTime = <span style="color:#2b91af;">NetTime</span>.Now;<br />     }</p>
<p>     <span style="color:#0000ff;">#endregion</span></p>
<p>     <span style="color:#0000ff;">#region</span> Properties</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">long</span> Id { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">double</span> MessageTime { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">Vector2</span> Position { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">float</span> Rotation { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">Vector2</span> Velocity { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">set</span>; }</p>
<p>     <span style="color:#0000ff;">#endregion</span></p>
<p>     <span style="color:#0000ff;">#region</span> Public Methods</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#2b91af;">GameMessageTypes</span> MessageType<br />     {<br />         <span style="color:#0000ff;">get</span> { <span style="color:#0000ff;">return</span> <span style="color:#2b91af;">GameMessageTypes</span>.UpdateAsteroidState; }<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Decode(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br />     {<br />         <span style="color:#0000ff;">this</span>.Id = im.ReadInt64();<br />         <span style="color:#0000ff;">this</span>.MessageTime = im.ReadDouble();<br />         <span style="color:#0000ff;">this</span>.Position = im.ReadVector2();<br />         <span style="color:#0000ff;">this</span>.Velocity = im.ReadVector2();<br />         <span style="color:#0000ff;">this</span>.Rotation = im.ReadSingle();<br />     }</p>
<p>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Encode(<span style="color:#2b91af;">NetOutgoingMessage</span> om)<br />     {<br />         om.Write(<span style="color:#0000ff;">this</span>.Id);<br />         om.Write(<span style="color:#0000ff;">this</span>.MessageTime);<br />         om.Write(<span style="color:#0000ff;">this</span>.Position);<br />         om.Write(<span style="color:#0000ff;">this</span>.Velocity);<br />         om.Write(<span style="color:#0000ff;">this</span>.Rotation);<br />     }</p>
<p>     <span style="color:#0000ff;">#endregion</span><br /> }</div>
</p></div>
</p></div>
<p>The key thing to note is how the Decode and Encode methods are mirrored. This is a very useful technique in managing your game messages and I can highly recommend this pattern.</p>
<p>Simply put, the Encode method writes each of the game message class variables to the NetOutgoingMessage. The sequence is very important.</p>
<p><strong>Note:</strong> I do not write the MessageType property. The reason for this is that your typically read this property before you call the Decode method and I want to keep them as similar as possible.</p>
<p>The Decode method then reads the variable types from the NetIncomingMessage class in the same sequence as it was encoded in.</p>
<p>The properties in the class store the values we want to send over the wire. The MessageTime property is interesting as it is not required to update the asteroid EntityState values. The MessageTime property is used to store the NetTime.Now value when the message was sent. This value is used by the client to determine the time delay from when then message was sent to when the message was received. This information is used to perform some client-side prediction on the asteroid position.</p>
<p>The next step is to look at how the server will send messages to the connected clients. </p>
<p>The server version of the SendMessage method on the INetworkManager interface is as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:745dee6b-7cf1-4059-8ed9-736c1045ea37" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SendMessage(<span style="color:#2b91af;">IGameMessage</span> gameMessage)<br /> {<br />     <span style="color:#2b91af;">NetOutgoingMessage</span> om = netServer.CreateMessage();<br />     om.Write((<span style="color:#0000ff;">byte</span>)gameMessage.MessageType);<br />     gameMessage.Encode(om);</p>
<p>     netServer.SendToAll(om, <span style="color:#2b91af;">NetDeliveryMethod</span>.ReliableUnordered);<br /> }</div>
</p></div>
</p></div>
<p>The first thing we do is to create a new NetOutGoingMessage by calling the CreateMessage method on the NetServer.</p>
<p>We then write the game message header which is a single byte defined by our MessageType property.</p>
<p>Thereafter we encode the rest of the message properties onto the NetOutgoingMessage.</p>
<p>And finally we call the SendToAll method on the NetServer which will send the message to all the connected clients.</p>
<p>As I mentioned earlier I am using the NetDeliveryMethod.ReliableUnordered to send my game messages.</p>
<h4>Receiving Messages</h4>
<p>The receiving of messages is handled with the rest of our message processing code. You will notice that I have introduced a new case in the switch statement for messages of type NetIncomingMessageType.Data as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c65c16d7-dabb-47a0-acc1-b20e2e8b4d0b" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.Data:<br />     <span style="color:#0000ff;">var</span> gameMessageType = (<span style="color:#2b91af;">GameMessageTypes</span>)im.ReadByte();<br />     <span style="color:#0000ff;">switch</span>(gameMessageType)<br />     {<br />         <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">GameMessageTypes</span>.UpdateAsteroidState:<br />             <span style="color:#0000ff;">this</span>.HandleUpdateAsteroidStateMessage(im);<br />             <span style="color:#0000ff;">break</span>;<br />     }<br />     <span style="color:#0000ff;">break</span>;</div>
</p></div>
</p></div>
<p>Our own game messages will always be of type Data. We can then ready the first byte, cast it to our GameMessageTypes enum and handle the appropriate message type.</p>
<p>I like to encapsulate my message handling code in a method with the corresponding name. In this case it is the HandleUpdateAsteroidStateMessage method.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3af19cf8-096a-4692-ae45-161cce934c67" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> HandleUpdateAsteroidStateMessage(<span style="color:#2b91af;">NetIncomingMessage</span> im)<br /> {<br />     <span style="color:#0000ff;">var</span> message = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">UpdateAsteroidStateMessage</span>(im);</p>
<p>     <span style="color:#0000ff;">var</span> timeDelay = (<span style="color:#0000ff;">float</span>) (<span style="color:#2b91af;">NetTime</span>.Now &#8211; im.SenderConnection.GetLocalTime(message.MessageTime));</p>
<p>     <span style="color:#2b91af;">Asteroid</span> asteroid = <span style="color:#0000ff;">this</span>.asteroidManager.GetAsteroid(message.Id) ??<br />                         <span style="color:#0000ff;">this</span>.asteroidManager.AddAsteroid(<br />                             message.Id, message.Position, message.Velocity, message.Rotation);</p>
<p>     asteroid.EnableSmoothing = <span style="color:#0000ff;">true</span>;</p>
<p>     <span style="color:#0000ff;">if</span> (asteroid.LastUpdateTime &lt; message.MessageTime)<br />     {<br />         asteroid.PrevDisplayState = (<span style="color:#2b91af;">EntityState</span>)asteroid.DisplayState.Clone();</p>
<p>         asteroid.SimulationState.Position = message.Position += (message.Velocity * timeDelay);</p>
<p>         asteroid.SimulationState.Velocity = message.Velocity;<br />         asteroid.SimulationState.Rotation = message.Rotation;</p>
<p>         asteroid.LastUpdateTime = message.MessageTime;<br />     }<br /> }</div>
</p></div>
</p></div>
<p>The first thing we do is to construct our UpdateAsteroidStateMessage from the NetIncomingMessage which will call our Decode method and populate all the game message properties.</p>
<p>The next step is to calculate the time delay since the message was sent and the current NetTime. The MessageTime we sent along with our game message comes in handy to do this.</p>
<p>Using the id from the game message I test to see if the asteroid already exists (if it does I retrieve it) and whether I need to create a new asteroid. Once the asteroid has been created or retrieved we can proceed to update it’s EntityState values.</p>
<p>The next check is to ensure that old messages i.e. messages received out of order are discarded.</p>
<p>Ignore the EnableSmoothing and PrevDisplayState code for now as I will cover this in a later article.</p>
<p>The important part here is the updating of the asteroid Position. You will notice that I am updating the asteroid position with the message position PLUS the velocity multiplied by the timeDelay. This is how I implement client-side prediction to make sure that our client is not running behind the server simulation.</p>
<p>You will notice that when you run the code that even with a simulated delay of 200ms the two simulations are synchronized.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:5f0ffde6-f622-493b-a5d3-137da1531f12" class="wlWriterEditableSmartContent">
<div><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='448' height='252' src='http://www.youtube.com/embed/NTsXyKEgqPM?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;hd=1&#038;wmode=transparent' frameborder='0'></iframe></span></div>
<div style="width:448px;clear:both;font-size:.8em;">Example output from Client and Server</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/126/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=126&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/02/22/lets-make-a-multiplayer-game-part-4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>
	</item>
		<item>
		<title>Let&#8217;s make a multiplayer game (part 3)</title>
		<link>http://dirkkok.wordpress.com/2012/02/21/lets-make-a-multiplayer-game-part-3/</link>
		<comments>http://dirkkok.wordpress.com/2012/02/21/lets-make-a-multiplayer-game-part-3/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 06:40:00 +0000</pubDate>
		<dc:creator>Dirk Kok</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Multiplayer]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">https://dirkkok.wordpress.com/?p=109</guid>
		<description><![CDATA[Unified Client/Server Game Code For this article series I want to have a single version of the game logic that can be applied to both the client and the server. For now I am going to make use of inversion of control via the INetworkManager interface to achieve the different networking behavior for the client &#8230; <a href="http://dirkkok.wordpress.com/2012/02/21/lets-make-a-multiplayer-game-part-3/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=109&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h4></h4>
<h4>Unified Client/Server Game Code</h4>
<p>For this article series I want to have a single version of the game logic that can be applied to both the client and the server. For now I am going to make use of inversion of control via the INetworkManager interface to achieve the different networking behavior for the client and server. (This is by no means the only way, I just chose this approach because I prefer it in this case.) </p>
<p>The INetworkManager interface has the following members which basically wrap calls to the NetServer and NetClient classes that I will explain later.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:aabe7471-fa6e-4c71-bdf9-04e272b11ae2" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">interface</span> <span style="color:#2b91af;">INetworkManager</span> : <span style="color:#2b91af;">IDisposable</span><br /> {<br />     <span style="color:#0000ff;">void</span> Connect();</p>
<p>     <span style="color:#0000ff;">void</span> Disconnect();</p>
<p>     <span style="color:#2b91af;">NetIncomingMessage</span> ReadMessage();</p>
<p>     <span style="color:#0000ff;">void</span> Recycle(<span style="color:#2b91af;">NetIncomingMessage</span> im);</p>
<p>     <span style="color:#2b91af;">NetOutgoingMessage</span> CreateMessage();<br /> }</div>
</p></div>
</p></div>
<p>Using the above interface my ExampleGame constructor is as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:32ef0dc3-4bcc-4243-8382-817a003babbe" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> ExampleGame(<span style="color:#2b91af;">INetworkManager</span> networkManager)<br /> {<br />     graphics = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">GraphicsDeviceManager</span>(<span style="color:#0000ff;">this</span>);<br />     Content.RootDirectory = <span style="color:#a31515;">&quot;Content&quot;</span>;</p>
<p>     <span style="color:#0000ff;">this</span>.networkManager = networkManager;<br /> }</div>
</p></div>
</p></div>
<p>The client and server console applications can therefore instantiate the ExampleGame class as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9601fb25-e0ae-457c-8d8a-15707de8d666" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> Main(<span style="color:#0000ff;">string</span>[] args)<br /> {<br />     <span style="color:#0000ff;">using</span> (<span style="color:#0000ff;">var</span> game = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">ExampleGame</span>(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">ServerNetworkManager</span>()))<br />     {<br />         game.Run();<br />     }<br /> }</div>
</p></div>
</p></div>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9675d38c-14e7-41f7-bdb1-7a0e019d127b" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> Main(<span style="color:#0000ff;">string</span>[] args)<br /> {<br />     <span style="color:#0000ff;">using</span> (<span style="color:#0000ff;">var</span> game = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">ExampleGame</span>(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">ClientNetworkManager</span>()))<br />     {<br />         game.Run();<br />     }<br /> }</div>
</p></div>
</p></div>
<h4>Setting up the Server</h4>
<p>The code required to set up a server is contained in the ServerNetworkManager class. The interesting part is the Connect method which is as follows.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:19bcecf8-5e49-411a-b584-3d7b4b2db053" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Connect()<br /> {<br />     <span style="color:#0000ff;">var</span> config = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">NetPeerConfiguration</span>(<span style="color:#a31515;">&quot;Asteroid&quot;</span>)<br />     {<br />         Port = <span style="color:#2b91af;">Convert</span>.ToInt32(<span style="color:#a31515;">&quot;14242&quot;</span>),<br />         <span style="color:#008000;">//SimulatedMinimumLatency = 0.2f, </span><br />         <span style="color:#008000;">//SimulatedLoss = 0.1f </span><br />     };<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.WarningMessage);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.VerboseDebugMessage);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.ErrorMessage);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.Error);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.DebugMessage);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.ConnectionApproval);</p>
<p>     netServer = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">NetServer</span>(config);<br />     netServer.Start();<br /> }</div>
</p></div>
</p></div>
<p>The first thing we need to do is set up a NetPeerConfiguration. For the server the only thing required is the port that our server will be listening on. Depending on your usage scenario you can let the user customize the port. In this case we will use a hardcoded value.</p>
<p>The next set of config.EnableMessageType method calls are used to tell the NetServer what type of messages to expect. I have exposed all the debug, warning and error messages as well as the ConnectionApproval message type.</p>
<p>The ConnectionApproval message type allows you to control if a client is allowed to connect. This is useful if you want to limit the number of connections or do some kind of authentication.</p>
<p>Once we’ve set up the config information we can instantiate our NetServer and call the start method. The server is now up and running and listening on the configured port.</p>
<p>You will notice some commented lines where I instantiate the NetPeerConfiguration class. These lines allow us to simulate latency and losses over the network. This is very handy for testing purposes to ensure that your game will be able to handle the real-world issues of internet gameplay.</p>
<h4>Setting up the Client</h4>
<p>The code required to set up a client is contained in the ClientNetworkManager class. Once again the interesting stuff happens in the Connect method.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:46433513-6dab-4550-9930-364f9b287cb8" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Connect()<br /> {<br />     <span style="color:#0000ff;">var</span> config = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">NetPeerConfiguration</span>(<span style="color:#a31515;">&quot;Asteroid&quot;</span>)<br />     {<br />         <span style="color:#008000;">//SimulatedMinimumLatency = 0.2f, </span><br />         <span style="color:#008000;">//SimulatedLoss = 0.1f</span><br />     };</p>
<p>     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.WarningMessage);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.VerboseDebugMessage);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.ErrorMessage);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.Error);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.DebugMessage);<br />     config.EnableMessageType(<span style="color:#2b91af;">NetIncomingMessageType</span>.ConnectionApproval);</p>
<p>     <span style="color:#0000ff;">this</span>.netClient = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">NetClient</span>(config);<br />     <span style="color:#0000ff;">this</span>.netClient.Start();</p>
<p>     <span style="color:#0000ff;">this</span>.netClient.Connect(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">IPEndPoint</span>(<span style="color:#2b91af;">NetUtility</span>.Resolve(<span style="color:#a31515;">&quot;127.0.0.1&quot;</span>), <span style="color:#2b91af;">Convert</span>.ToInt32(<span style="color:#a31515;">&quot;14242&quot;</span>)));<br /> }</div>
</p></div>
</p></div>
<p>You will notice that I don’t specify a client port in the configuration. You can do so if you want, but it’s not required.</p>
<p>The same message types as the server are enabled on the client and instead of a NetServer we instantiate a NetClient and call the Start method.</p>
<p>To make the connection to the server the client needs to connect to it. I have hardcoded the IP address and port in this case. In a real game you would allow the user to specify this information or provide some kind of server browser.</p>
<p>Calling the Connect method starts the handshaking process between the client and the server. Since we’ve enabled the ConnectionApproval message type we need to handle this message to complete the connection.</p>
<h4>Processing Network Messages</h4>
<p>Now that we have our client and server connection code we need to update the game to make use of it. I make the INetworkManager.Connect() call in the Initialize() method as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1e496b23-fb83-4786-8382-07771e58036b" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"><span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> Initialize()<br /> {<br />     <span style="color:#008000;">// </span><span style="color:#00008b;">TODO: Add your initialization logic here</span><br />     <span style="color:#0000ff;">this</span>.networkManager.Connect();</p>
<p>     <span style="color:#0000ff;">base</span>.Initialize();<br /> }</div>
</p></div>
</p></div>
<p>The next step is to make sure our game handles the network messages. I typically process the network messages in the Update method as follows:</p>
<p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2f45ed17-d941-4189-9e82-90e22b2e2bc4" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> Update(<span style="color:#2b91af;">GameTime</span> gameTime)<br /> {<br />     <span style="color:#008000;">// Allows the game to exit</span><br />     <span style="color:#0000ff;">if</span> (<span style="color:#2b91af;">Keyboard</span>.GetState(<span style="color:#2b91af;">PlayerIndex</span>.One).IsKeyDown(<span style="color:#2b91af;">Keys</span>.Escape))<br />         <span style="color:#0000ff;">this</span>.Exit();</p>
<p>     <span style="color:#008000;">// </span><span style="color:#00008b;">TODO: Add your update logic here</span><br />     <span style="color:#0000ff;">this</span>.ProcessNetworkMessages();</p>
<p>     <span style="color:#0000ff;">base</span>.Update(gameTime);<br /> }</p>
<p> <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">void</span> ProcessNetworkMessages()<br /> {<br />     <span style="color:#2b91af;">NetIncomingMessage</span> im;</p>
<p>     <span style="color:#0000ff;">while</span> ((im = <span style="color:#0000ff;">this</span>.networkManager.ReadMessage()) != <span style="color:#0000ff;">null</span>)<br />     {<br />         <span style="color:#0000ff;">switch</span> (im.MessageType)<br />         {<br />             <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.VerboseDebugMessage:<br />             <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.DebugMessage:<br />             <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.WarningMessage:<br />             <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.ErrorMessage:<br />                 <span style="color:#2b91af;">Console</span>.WriteLine(im.ReadString());<br />                 <span style="color:#0000ff;">break</span>;<br />             <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetIncomingMessageType</span>.StatusChanged:<br />                 <span style="color:#0000ff;">switch</span> ((<span style="color:#2b91af;">NetConnectionStatus</span>)im.ReadByte())<br />                 {<br />                     <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetConnectionStatus</span>.Connected:<br />                         <span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&quot;{</span><span style="color:#3cb371;">0}</span><span style="color:#a31515;"> Connected&quot;</span>, im.SenderEndpoint);<br />                         <span style="color:#0000ff;">break</span>;<br />                     <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetConnectionStatus</span>.Disconnected:<br />                         <span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&quot;{</span><span style="color:#3cb371;">0}</span><span style="color:#a31515;"> Disconnected&quot;</span>, im.SenderEndpoint);<br />                         <span style="color:#0000ff;">break</span>;<br />                     <span style="color:#0000ff;">case</span> <span style="color:#2b91af;">NetConnectionStatus</span>.RespondedAwaitingApproval:<br />                         im.SenderConnection.Approve();<br />                         <span style="color:#0000ff;">break</span>;<br />                 }<br />                 <span style="color:#0000ff;">break</span>;<br />         }</p>
<p>         <span style="color:#0000ff;">this</span>.networkManager.Recycle(im);<br />     }<br /> }</div>
</p></div>
</p></div>
</p>
<p>The above ProcessNetworkMessages() method is a typical example of how you would process network messages. The above code will continue to process messages until there are no more messages.</p>
<p>Each message will have a type that we can test for and then handle appropriately. You will notice that the types of messages I am checking for matches the types I enabled when I configured both the NetServer and NetClient instances.</p>
<p>When we’re done with a message we recycle it. You don’t have to recycle it, but according to the Lidgren documentation it is more efficient to do so. </p>
<p>The interesting case in the above example is the RespondedAwaitingApproval status type. This is where we can either Approve or Deny a connection attempt. Since we enabled the ConnectionApproval message type we have to call the im.SenderConnection.Approve() method to complete the connection process.</p>
<p>When you run the code you should see the following output in the client and server console windows.</p>
<p><a href="http://dirkkok.files.wordpress.com/2012/02/image2.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://dirkkok.files.wordpress.com/2012/02/image_thumb2.png?w=445&#038;h=201" width="445" height="201" /></a></p>
<p>The source code for this article series can be found on <a href="http://code.google.com/p/multiplayer-example/" target="_blank">google code</a>.</p>
<p>In the next article I will demonstrate how to get some asteroids flying around the screen synchronized on both the client and server.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dirkkok.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dirkkok.wordpress.com/109/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dirkkok.wordpress.com&#038;blog=2157195&#038;post=109&#038;subd=dirkkok&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dirkkok.wordpress.com/2012/02/21/lets-make-a-multiplayer-game-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/eef48470dd0b55f420b938cde0026fb9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Paladin</media:title>
		</media:content>

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