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

<channel>
	<title>luminance &#187; JSON</title>
	<atom:link href="http://www.luminance.org/tag/json/feed" rel="self" type="application/rss+xml" />
	<link>http://www.luminance.org</link>
	<description>Programming and Game Development - Kevin Gadd's Personal Blog</description>
	<lastBuildDate>Thu, 29 Apr 2010 17:20:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Compiler-assisted Data Binding with LINQ</title>
		<link>http://www.luminance.org/code/2010/04/27/compiler-assisted-data-binding-with-linq</link>
		<comments>http://www.luminance.org/code/2010/04/27/compiler-assisted-data-binding-with-linq#comments</comments>
		<pubDate>Wed, 28 Apr 2010 07:33:05 +0000</pubDate>
		<dc:creator>Kael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://www.luminance.org/?p=866</guid>
		<description><![CDATA[When trying to write reliable, maintainable software, it&#8217;s important to try and minimize duplication. When you find yourself writing the same magic number in multiple places, you move it into a named constant to eliminate the duplication. When you find yourself writing the same expression multiple times, you move it into a named function, or [...]]]></description>
			<content:encoded><![CDATA[<p>When trying to write reliable, maintainable software, it&#8217;s important to try and minimize duplication. When you find yourself writing the same magic number in multiple places, you move it into a named constant to eliminate the duplication. When you find yourself writing the same expression multiple times, you move it into a named function, or perhaps a property. Sometimes, you find yourself dealing with higher level duplication &#8211; entire concepts and patterns that you find yourself writing again and again. Many modern languages provide tools to help you eliminate this kind of duplication: class inheritance allows you to share common logic between classes by inheriting that logic from a parent class, and generic types allow you to apply a generic pattern to multiple individual types. Both of these tools work with the aid of the compiler, so they interact well with debugging tools and allow you to catch most errors at compile time. Sometimes, though, you run into duplication that can&#8217;t easily be eliminated, even with the aid of the compiler.</p>
<p>In many graphical applications, a common pattern is the need to remember user preferences or inputs. Modern languages provide useful tools that can make this task simpler &#8211; for example, both Java and C# provide ways to automatically serialize an entire data structure into XML, which eliminates the need to manually read/write your preference values. Unfortunately, even with the aid of these features, you still find yourself with a lot of duplication &#8211; even if the runtime can automatically serialize your data structure, you still have to fill the structure out with your preferences, or read them back in manually. I&#8217;m going to demonstrate how you can use a little-known aspect of the new LINQ feature in C# 3.5 to eliminate duplication with the aid of the compiler.</p>
<p><a rel="attachment wp-att-869" href="http://www.luminance.org/wp-content/uploads/2010/04/PreferencesExample1.png"><img class="aligncenter size-full wp-image-869" title="Preferences Example Screenshot" src="http://www.luminance.org/wp-content/uploads/2010/04/PreferencesExample1.png" alt="" width="329" height="274" /></a></p>
<p>As an example, we&#8217;ll be using the simple application shown above. It&#8217;s a Windows Forms dialog box, with a few different controls, set up to remember user inputs between sessions. You can download the source code for this application below:</p>
<p><a href="http://luminance.org/articles/PreferencesExample1.zip">Preferences Example (v1)</a></p>
<p>If you run the application, input some values, and click OK, you&#8217;ll find that it stores your inputs in a JSON file in the %AppData%\PreferencesExample folder. If you run it again, you&#8217;ll see that it pulls your inputs back out of the JSON file to populate the UI.</p>
<p><span id="more-866"></span></p>
<p>Let&#8217;s take a look at the relevant parts of the source code:</p>
<pre>public void LoadPreferences () {
  if (!File.Exists(GetPrefsPath()))
    return;

  var serializer = new JavaScriptSerializer();
  var preferences = serializer.Deserialize&lt;Dictionary&lt;string, object&gt;&gt;(File.ReadAllText(GetPrefsPath()));

  checkBox1.Checked = (bool)preferences["checkBox1"];
  radioButton1.Checked = (bool)preferences["radioButton1"];
  radioButton2.Checked = (bool)preferences["radioButton2"];

  listBox1.SelectedIndices.Clear();
  var indices = preferences["listBox1"] as ArrayList;
  foreach (var index in indices)
    listBox1.SelectedIndices.Add((int)index);

  textBox1.Text = (string)preferences["textBox1"];
  dateTimePicker1.Value = (DateTime)preferences["dateTimePicker1"];
}

public void SavePreferences () {
  var preferences = new Dictionary&lt;string, object&gt;();

  preferences["checkBox1"] = checkBox1.Checked;
  preferences["radioButton1"] = radioButton1.Checked;
  preferences["radioButton2"] = radioButton2.Checked;
  preferences["listBox1"] = listBox1.SelectedIndices.Cast&lt;int&gt;().ToArray();
  preferences["textBox1"] = textBox1.Text;
  preferences["dateTimePicker1"] = dateTimePicker1.Value;

  if (!Directory.Exists(Path.GetDirectoryName(GetPrefsPath())))
    Directory.CreateDirectory(Path.GetDirectoryName(GetPrefsPath()));

  var serializer = new JavaScriptSerializer();
  File.WriteAllText(GetPrefsPath(), serializer.Serialize(preferences));
}
</pre>
<p>This application is relatively small &#8211; in particular, the JavaScriptSerializer handles a lot of the work involved in storing preferences for us. But regardless, we find ourselves having to list out all the control names multiple times, and some of those references to the controls are strings. Since they&#8217;re strings, that means that automatic refactoring tools, like the Rename tool in Visual Studio, won&#8217;t find them. As a result, this sort of code becomes difficult to maintain, especially in a larger codebase &#8211; changes are extremely error-prone and require careful, manual work.</p>
<p>What we want is a way to eliminate this duplication &#8211; a way to pull the list of controls and values out and store them in one place, so that we don&#8217;t have to specify them multiple times. Unfortunately, there&#8217;s no obvious way to do this in either Java or C#. While you can add the controls to a list quite easily, and walk over the list to get control names &#8211; eliminating part of the duplication &#8211; there&#8217;s no clean way to specify the particular fields/properties you wish to store.</p>
<p>Those of you familiar with reflection techniques may realize that you can eliminate the duplication by using reflection. By specifying a control and the name of the field we care about, we can use reflection to find that field and fetch its value. This technique will work, and other than the performance overhead of reflection, it will work well enough to ship in an application. However, it still suffers from the downside of breaking automated refactoring tools, and it&#8217;s somewhat error-prone due to the complexity involved in finding fields/properties via reflection.</p>
<p>One of the new features in C# 3.5 is support for &#8216;<a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx" target="_blank">Expression Trees</a>&#8216;. Expression trees allow you to convert a C# expression into a tree of objects that describe the expression and allow you to evaluate it. This feature is used to support LINQ &#8211; for example, when you write &#8216;where i &lt; 5&#8242; in a LINQ query, the &#8216;i &lt; 5&#8242; portion of the query is turned into an expression tree, that LINQ can then use to run the query &#8211; for example, by turning it into SQL. As it happens, we can use this feature to solve our problem!</p>
<p>In C# 3.5, virtually any expression we can write can be converted into a delegate using lambda syntax, like so:</p>
<pre>Func&lt;int, int&gt; func = (x) =&gt; x * 5;</pre>
<p>And, as part of the Expression Tree feature, we can convert that lambda into an expression tree, at compile time:</p>
<pre>Expression&lt;Func&lt;int, int&gt;&gt; expr = (x) =&gt; x * 5;</pre>
<p>The compiler provides us all the information we need to evaluate an expression within the expression tree &#8211; if the expression references a field, the expression tree will contain the object containing the field, along with the FieldInfo object representing the field. Using this knowledge, we can eliminate the duplication from our sample application: By using a single expression to represent each preference we want to store, we can list all of our preferences in a single place in our application, and use that list of expressions to both load and save preference values. Best of all, because the compiler gives us full information on the expressions, we know the exact data types involved, and we can find out the name of the field being stored, and even the name of the object containing the field &#8211; eliminating the need to name each preference manually.</p>
<p>Using this knowledge, we can write a simple helper class that represents a field or property reference, and construct instances of that class by passing it an expression. You can find the source code to the class here:<br />
<a href="http://code.google.com/p/fracture/source/browse/trunk/Squared/Util/Bind.cs">http://code.google.com/p/fracture/source/browse/trunk/Squared/Util/Bind.cs</a><br />
And we&#8217;ll be using it to eliminate the duplication from our sample application. The code is relatively small &#8211; a couple hundred lines &#8211; so by reading it you can easily see how to apply this technique for your own purposes, even if you don&#8217;t end up using my code.</p>
<p>The first step is to use expressions to build a list of all the values we want to store. We&#8217;ll do this by creating an array of bound members in the dialog box&#8217;s constructor:</p>
<pre>IBoundMember[] BoundMembers;

public MainDialog () {
  InitializeComponent();

  BoundMembers = new IBoundMember[] {
    BoundMember.New(() =&gt; checkBox1.Checked),
    BoundMember.New(() =&gt; radioButton1.Checked),
    BoundMember.New(() =&gt; radioButton2.Checked),
    BoundMember.New(() =&gt; listBox1.SelectedIndices),
    BoundMember.New(() =&gt; textBox1.Text),
    BoundMember.New(() =&gt; dateTimePicker1.Value)
  };
}
</pre>
<p>Note that all we have to do is create an expression that evaluates to the value we wish to store. The C# compiler will convert it into an expression tree that tells us which object contains the value, and the FieldInfo or PropertyInfo we can use to fetch the value.</p>
<p>To eliminate the need to specify the name of each preference, we can combine the name of the field/property along with the name of the control containing the field/property, like so:</p>
<pre>string GetMemberName (IBoundMember member) {
  return String.Format("{0}.{1}", ((Control)member.Target).Name, member.Name);
}
</pre>
<p>If we specify the Checked property of a RadioButton named radioButton2, this function will evaluate to &#8216;radioButton2.Checked&#8217;.</p>
<p>With these two pieces of functionality, we can now eliminate all the duplication from the old LoadPreferences and SavePreferences functions:</p>
<pre>public void LoadPreferences () {
  if (!File.Exists(GetPrefsPath()))
    return;

  var serializer = new JavaScriptSerializer();
  var preferences = serializer.Deserialize&lt;Dictionary&lt;string, object&gt;&gt;(File.ReadAllText(GetPrefsPath()));

  foreach (var bm in BoundMembers)
    bm.Value = preferences[GetMemberName(bm)];
}

public void SavePreferences () {
  var preferences = new Dictionary&lt;string, object&gt;();

  foreach (var bm in BoundMembers)
    preferences[GetMemberName(bm)] = bm.Value;

  if (!Directory.Exists(Path.GetDirectoryName(GetPrefsPath())))
    Directory.CreateDirectory(Path.GetDirectoryName(GetPrefsPath()));

  var serializer = new JavaScriptSerializer();
  File.WriteAllText(GetPrefsPath(), serializer.Serialize(preferences));
}</pre>
<p>Another thing you&#8217;ll notice is that the type casting from the original version is gone &#8211; since we have type information, we can automatically cast preference values to the appropriate type &#8211; and if we were using a strongly typed datastore, instead of JSON, we could actually store preferences directly in their correct type, without having to do any boxing or type casting.</p>
<p>If you download the source code for the revised example:<br />
<a href="http://luminance.org/articles/PreferencesExample2.zip">Preferences Example (v2)</a><br />
You can run it and see that while it works the first time, and correctly saves preferences to JSON, it fails when loading preferences back from JSON. This turns out to be because of the JSON serializer: While listBox1.SelectedIndices is of type SelectedIndexCollection, the list we get back from the JSON serializer is of type ArrayList. The two types aren&#8217;t convertible, so the application fails.</p>
<p>Luckily, we can easily solve this problem. Since this technique works for any field or property, we can simply define a property that handles type conversion so that we don&#8217;t get an error when trying to load the preference value from JSON, like this:</p>
<pre>// This has to be ArrayList since that's what we get back from the JSON serializer
ArrayList ListBox1_SelectedIndices {
  get {
    var result = new ArrayList();
    foreach (var index in listBox1.SelectedIndices)
      result.Add(index);
    return result;
  }
  set {
    listBox1.SelectedIndices.Clear();
    foreach (var index in value)
      listBox1.SelectedIndices.Add((int)index);
  }
}</pre>
<p>If we change the list in the dialog box constructor to reference this new property instead of referencing the listbox directly, we can run the application and it will now successfully load and save preferences.<br />
<a href="http://luminance.org/articles/PreferencesExample3.zip">Preferences Example (v3)</a></p>
<p>With this technique, you can easily handle automatically loading and saving values from almost any datastore &#8211; and do so efficiently, without any unnecessary duplication, thanks to the information we&#8217;re given by the compiler. As an example, here&#8217;s a simple implementation of an object that loads and saves preferences from a database using this technique:<br />
<a href="http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/Data/PropertySerializer.cs">http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/Data/PropertySerializer.cs</a></p>
<p>I hope this post has shown you something useful! In the future I&#8217;ll be showing some other interesting applications of this technique.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.luminance.org/code/2010/04/27/compiler-assisted-data-binding-with-linq/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Achievements and player data I</title>
		<link>http://www.luminance.org/gruedorf/2009/08/28/achievements-and-player-data-i</link>
		<comments>http://www.luminance.org/gruedorf/2009/08/28/achievements-and-player-data-i#comments</comments>
		<pubDate>Fri, 28 Aug 2009 09:35:37 +0000</pubDate>
		<dc:creator>Kael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Gruedorf]]></category>
		<category><![CDATA[achievements]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://www.luminance.org/?p=814</guid>
		<description><![CDATA[One of the things I&#8217;ve been working on lately is a way to collect and store data on play sessions, so I can track achievements for players and track where players spend the most time in a level, or where they die the most. There are lots of details to get right for a system [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things I&#8217;ve been working on lately is a way to collect and store data on play sessions, so I can track achievements for players and track where players spend the most time in a level, or where they die the most. There are lots of details to get right for a system like this, but I&#8217;ve at least gotten a prototype working and started experimenting with ways to visualize the data.</p>
<p>For a system like this you have a few important pieces:</p>
<ul>
<li>Your game needs to collect data during play sessions &#8211; in my case, I track important events like player/creature death, and periodically sample the player&#8217;s position to get a general idea of where players are in a given level during their session.</li>
<li>You need a way for your game to periodically report collected data to a remote server. You have to handle lots of edge cases here &#8211; for example, it&#8217;s likely some people will play without an active internet connection or suffer temporary loss of connection, so you need to batch up events to report later in this case &#8211; you definitely don&#8217;t want the game to fall over and choke without access to the internet, and if possible you want to avoid losing data too.</li>
<li>You need to build a set of services to collect data from the game. This typically means you also need services to handle things like uniquely identifying individual play sessions and computers, so that you can track achievements for individual players and perform analysis on individual sessions instead of only on a player&#8217;s entire play history.</li>
<li>You need to build an in-game frontend, to expose collected data to a player. This means turning your event data into user-friendly statistics &#8211; like a kill counter, or an achievement for killing a particular boss. One interesting challenge here is that you probably want to expose this information online, too, so that players can share their profiles and achievements.</li>
</ul>
<p>In this post, I&#8217;m going to cover the first two.</p>
<p><span id="more-814"></span></p>
<h2>Collecting Data</h2>
<p>So, first, you need a way to collect important player data. For it to be useful, you need to collect it in as consistent a format as possible; you don&#8217;t want every piece of data to have a unique set of parameters attached to it, for example, because that would make it impossible to perform any generic analysis of your data. Likewise, you want to try and keep your data &#8216;denormalized&#8217;, by storing as much relevant data together as possible. If you achieve both of these goals, you end up with a stream of &#8216;events&#8217; that represent the things you care about in a form that lets you inspect them individually or analyze them in large groups.</p>
<p>In my case, this step was actually quite straightforward. I already had a simple &#8216;event bus&#8217; integrated into the game, that I was previously using to synchronize animation and sound effects with gameplay. Given this, it was simple to create a data collector that attaches to the event bus and listens for events that it wants to collect.</p>
<p>I did, however, have to make some changes &#8211; many of my events didn&#8217;t expose the information necessary to be useful; for example, the event representing a player death didn&#8217;t contain any information to tell you who (or what) killed the player, so I had to tweak the game code to attach that to the event. Likewise, many other events didn&#8217;t include position information, which made it hard to get meaningful information about them &#8211; knowing that the player grabbed onto a ledge isn&#8217;t particularly useful if you don&#8217;t know *where* or *which ledge*. In some cases, the data collector attached important parameters into the events so that game objects wouldn&#8217;t have to; for example any event coming from the Player automatically has PlayerX and PlayerY parameters attached to it (since the Player is the source of the event, it is simple to extract a position and attach it to the event).</p>
<p>One thing that required some special treatment as well was recording the player&#8217;s position over time &#8211; while attaching position information to events gives you a general idea of the player&#8217;s location, it&#8217;s not very useful for figuring out where players are getting stuck or confused. To address this, I built a simple class that periodically samples the player&#8217;s position and adds it to a list. Every time the list reaches a certain size, its contents are batched up into a single event &#8211; a &#8216;HistoryBatch&#8217; &#8211; and sent to the data collector. This allows me to get fairly high-resolution position data without having to report hundreds of individual events every minute (which would have contained lots and lots of redundant information).</p>
<h2>Reporting Data</h2>
<p>Once you have your player data, you need to report it to your server (and probably store some of it locally, too). I honestly haven&#8217;t tackled the latter part yet, but here&#8217;s how I handled the former:</p>
<p>To handle periodically reporting events, I created a simple &#8216;Event Reporter&#8217; class that collaborates with the data collector. Essentially, the event reporter maintains a queue of pending events, and runs a thread that is responsible for sending batches of events to the remote server once the queue gets large enough. It automatically waits a certain amount of time between requests, and attempts to batch events into groups instead of reporting them one at a time as they occur. This allows me to get relatively low latency (if I want it) but still remain relatively efficient in my use of the network. Whenever the data collector gets an event, it adds it to the event reporter&#8217;s queue.</p>
<p>Once I have a batch of events ready to send to the server, I pack them together into a class that&#8217;s laid out optimally for network transmission. I then use .NET 3.5&#8217;s built in JSON serializer to convert the batch into a blob of JSON data ready to send to my remote server. A typical blob looks like this:</p>
<pre>{
  "PlayerId":xxxx,
  "SessionId":yyyy,
  "Events":[
    {"Type":"ActiveControllerChanged","Time":0,"Data":{
      "IsKeyboard":true,
      "ConnectedGamepads":0,
      "ActiveController":0
    }},
    {"Type":"LevelLoaded","Time":5436,"Data":"troupe"},
    {"Type":"HistoryBlock","Time":7788,"Data":{
      "LevelName":"troupe",
      "PlayerX":[-136,-74,35,192,209,209],
      "PlayerY":[588,875,920,920,920,920]
    }}
  ]
}</pre>
<p>As you can see, events are small when possible &#8211; they simply store the event type and the timestamp at which the event occurred, along with their associated information. In cases where an event has lots of information attached, I send a dictionary, but in some cases I can just send a single value. In the case of a history block, I make sure to send the X and Y coordinates as individual lists, so that I don&#8217;t have to waste time encoding &#8216;PlayerX&#8217; and &#8216;PlayerY&#8217; along with every individual coordinate. A batch of events has a player ID and a session ID attached, which allows me to analyze individual play sessions and track achievements. (Note that both of these IDs are randomly generated on the server, so they&#8217;re anonymous.)</p>
<p>The reporter starts an HTTP POST to send the JSON to the server, and goes to sleep until it&#8217;s finished. If the send fails, the events are left on the queue and the thread sleeps for a while so it can retry sending them later. Once a send completes, the reporter checks to see if the queue is empty &#8211; if the queue is now empty, it goes to sleep until the queue contains items again. If the queue still contains items, it sleeps for a short while and prepares to send another batch &#8211; this allows the event reporter to spend the majority of its time asleep, but still handle large bursts of events without sending a huge blob of events at the server in one POST (since that would be very likely to fail or time out.)</p>
<p>One important detail is that the reporter needs to be able to correctly report events even if the player quits. In my case, the player can quit at any time, and I can end up with a very large number of events in the queue at the time. To deal with this, once the game has finished tearing down, the event reporter is given around 30 seconds to report any remaining events to the server. This usually allows events to get through, but prevents the game from hanging indefinitely on exit (in the event that there&#8217;s some sort of network failure, or the event queue is <strong>really</strong> full). Since this occurs after teardown, the game window is gone so the player doesn&#8217;t get the impression that the game has hung, and since the reporter spends most of its time sleeping, they won&#8217;t see any significant CPU usage either.</p>
<p>The reporter also runs in its own isolated thread and uses its own task scheduler, instead of sharing resources with the game. This increases the likelihood that the game will be able to successfully report events in the case of a bug or crash, and also means that if the reporter fails for some reason &#8211; probably a network outage &#8211; it won&#8217;t take the game down with it.</p>
<p>In my next post, I&#8217;ll cover the remaining two items and show you some of the things you can do once you&#8217;ve gathered player data. In the interim, you can <a href="http://inferus-data.luminance.org/player/view?id=1115">take a look at my player profile</a>!</p>
<hr />
]]></content:encoded>
			<wfw:commentRss>http://www.luminance.org/gruedorf/2009/08/28/achievements-and-player-data-i/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
