<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Ranger Sheck's Blog - Home</title>
  <id>tag:rangersheck.com,2008:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://rangersheck.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://rangersheck.com/" rel="alternate" type="text/html"/>
  <updated>2008-07-24T00:44:38Z</updated>
  <entry xml:base="http://rangersheck.com/">
    <author>
      <name>RangerSheck</name>
    </author>
    <id>tag:rangersheck.com,2008-07-24:221</id>
    <published>2008-07-24T00:40:00Z</published>
    <updated>2008-07-24T00:44:38Z</updated>
    <category term="PBBG"/>
    <category term="gadget"/>
    <category term="game development"/>
    <category term="igoogle"/>
    <category term="PBBG"/>
    <category term="pbbg"/>
    <category term="pbbg development"/>
    <category term="pbbgdev"/>
    <link href="http://rangersheck.com/2008/7/24/an-igoogle-gadget-for-your-game" rel="alternate" type="text/html"/>
    <title>An iGoogle Gadget for your Game</title>
<summary type="html">&lt;p&gt;If you’ve ever personalized a Google home page, you’ve seen the various gadgets that can be added. These gadgets can also be placed into other web pages, blogs, and so forth pretty easily, and they share a very similar framework with &#8220;gadgets&#8221; in other sites, such as MySpace&#8217;s new &lt;em&gt;MySpace Apps&lt;/em&gt;. In this article, I&#8217;ll show you how to make a simple gadget that pulls dynamic data from your game and displays it in a nice little box.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;If you’ve ever personalized a Google home page, you’ve seen the various gadgets that can be added. These gadgets can also be placed into other web pages, blogs, and so forth pretty easily, and they share a very similar framework with &#8220;gadgets&#8221; in other sites, such as MySpace&#8217;s new &lt;em&gt;MySpace Apps&lt;/em&gt;. In this article, I&#8217;ll show you how to make a simple gadget that pulls dynamic data from your game and displays it in a nice little box.&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;

	&lt;p&gt;Here&#8217;s a basic gadget I created for &lt;a href=&quot;http://aethora.com&quot;&gt;Aethora&lt;/a&gt; that shows a player&#8217;s list of characters and each character&#8217;s skill levels. It also displays the Health of each character, which is nice &#8211; if you&#8217;ve ever played Aethora, you know that inactive characters heal up as time passes. This gadget is handy for seeing at a glance which characters are ready to get back into action. A little minor JavaScript makes it interactive, allowing you to click on the skills link and expand each character&#8217;s skill list.&lt;/p&gt;


	&lt;p&gt;Rather than go into detail about how I created this gadget specifically, I&#8217;m going to make up a generic game called Fake &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; and explain how to build a gadget for it.&lt;/p&gt;


	&lt;h2&gt;0. What you need&lt;/h2&gt;


	&lt;p&gt;Before we get started, let&#8217;s run down a short list of requirements.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;A game to pull data from&lt;/li&gt;
		&lt;li&gt;Some knowledge of JavaScript&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://getfirebug.com&quot;&gt;Firebug&lt;/a&gt; is highly recommended&lt;/li&gt;
		&lt;li&gt;A design in mind: a gadget is not like a full web page, so give it a little thought. I did my Aethora gadget at 320&#215;300, but for this example, I started with a design that fits into 300&#215;200 pixels.&lt;/li&gt;
		&lt;li&gt;Reference: &lt;a href=&quot;http://code.google.com/apis/gadgets/docs/legacy/dev_guide.html&quot;&gt;Legacy Gadgets &lt;span class=&quot;caps&quot;&gt;API &lt;/span&gt;Developer&#8217;s Guide&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;1. Prepping the Data&lt;/h2&gt;


	&lt;p&gt;First we&#8217;ll need to create a page that will serve up our player&#8217;s data. We&#8217;ve got a couple of options when it comes to displaying data. We can use plain old text, perhaps &lt;span class=&quot;caps&quot;&gt;CSV&lt;/span&gt;-style, but it&#8217;s probably best if we use &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; or &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;. XML is typically good for generating well-formatted blocks of data intended to be used for a very broad range of applications. Parsing &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; data in JavaScript is not real fun; thankfully, we have &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;, which is much easier to work with. In this example, I&#8217;ll be using &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; for that reason.&lt;/p&gt;


	&lt;p&gt;Most languages provide simple methods for getting &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;-formatted data. In Ruby on Rails, there is a handy &lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveRecord/Serialization.html#M001014&quot;&gt;to_json method&lt;/a&gt; that can be called on any ActiveRecord object, and allows for options such as restricting which attributes get displayed, including method calls as attributes, and including associated objects. &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;(5.2.0 and up) provides a &lt;a href=&quot;http://php.net/manual/en/function.json-encode.php&quot;&gt;json-encode function&lt;/a&gt; that translates any variable (be it array, string, or any other type) into a &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; string.&lt;/p&gt;


	&lt;p&gt;Let&#8217;s do this example with a simple &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; file. Since this is &lt;em&gt;Fake &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt;&lt;/em&gt;, we&#8217;ll pretend each player in the game has four player characters (PCs) and each PC has some attributes. I&#8217;m going to fake the data as if I pulled it from a database, but really it&#8217;s just a bunch of arrays.&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&amp;lt;&lt;span class=&quot;i&quot;&gt;?p&lt;/span&gt;hp&lt;tt&gt;
&lt;/tt&gt;function make_up_stats() {&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;return&lt;/span&gt; array(&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Strength&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;rand(&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;i&quot;&gt;20&lt;/span&gt;),&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Wisdom&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;rand(&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;i&quot;&gt;20&lt;/span&gt;),&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Dexterity&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;rand(&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;i&quot;&gt;20&lt;/span&gt;),&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Luck&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;rand(&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;i&quot;&gt;20&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  );&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt; pretend we loaded some data from a database&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;gv&quot;&gt;$pc1&lt;/span&gt; = array(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Jack&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;i&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;i&quot;&gt;100&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;make_up_stats() );&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;gv&quot;&gt;$pc2&lt;/span&gt; = array(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Jannus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;i&quot;&gt;6&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;i&quot;&gt;25&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;make_up_stats() );&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;gv&quot;&gt;$pc3&lt;/span&gt; = array(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Samathia&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;i&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;i&quot;&gt;65&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;make_up_stats() );&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;gv&quot;&gt;$pc4&lt;/span&gt; = array(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Keleton&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;i&quot;&gt;6&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;i&quot;&gt;0&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt;make_up_stats() );&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;gv&quot;&gt;$pcs&lt;/span&gt; = array( &lt;span class=&quot;gv&quot;&gt;$pc1&lt;/span&gt;, &lt;span class=&quot;gv&quot;&gt;$pc2&lt;/span&gt;, &lt;span class=&quot;gv&quot;&gt;$pc3&lt;/span&gt;, &lt;span class=&quot;gv&quot;&gt;$pc4&lt;/span&gt; );&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;gv&quot;&gt;$player&lt;/span&gt; = array ( &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt; &lt;span class=&quot;gv&quot;&gt;$_GET&lt;/span&gt;[&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;user_login&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;], &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;pcs&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;=&amp;gt; &lt;span class=&quot;gv&quot;&gt;$pcs&lt;/span&gt; );&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt; output as &lt;span class=&quot;co&quot;&gt;JSON&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;echo json_encode(&lt;span class=&quot;gv&quot;&gt;$player&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;i&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Notice our flimsy little &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; script looks for a &#8216;user_login&#8217; parameter in the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; to determine the player&#8217;s username. Normally, we&#8217;d use this parameter to actually look up the player&#8217;s data and whatnot, but this tutorial is about iGoogle gadgets, so we&#8217;re faking it. If we were doing this for real, we might consider using &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; authentication or something like that. Aethora&#8217;s gadget does not require authentication, because the player and character stats that are being displayed are public anyway. The only real &#8220;danger&#8221;, so to speak, is that someone could display another player&#8217;s stats on their own web page using one of these gadgets (of course, they say imitation is the highest form of flattery, so I don&#8217;t consider that scenario much of a security breach).&lt;/p&gt;


	&lt;p&gt;Now we test our &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; script by pointing our browser to it. You can try this by going to my example at: &lt;a href=&quot;http://examples.rangersheck.com/fake_game_json.php?user_login=Ranger+Sheck&quot;&gt;http://examples.rangersheck.com/fake_game_json.php?user_login=Ranger+Sheck&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Notice the string of data blocked out with {}&#8217;s and []&#8217;s; that&#8217;s &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;, baby, and it translates to pure JavaScript!&lt;/p&gt;


	&lt;h2&gt;2. Creating a Gadget: the &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; definition file&lt;/h2&gt;


	&lt;p&gt;All iGoogle gadgets require a single &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; file to start with. Google prefers that you host this &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; file on your own server, but if you need to, you can use their &lt;a href=&quot;http://code.google.com/apis/gadgets/docs/legacy/gs.html#Scratchpad&quot;&gt;Google Gadgets Editor&lt;/a&gt; to host your &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; file. Since I want to break out my JavaScript and &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; for the sake of cleanliness, I&#8217;m going to host my &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; file on my own server.&lt;/p&gt;


	&lt;p&gt;The entire &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; block should be wrapped in a Module element. We start with a Module Prefs section. This is where we can set up the configuration for our little gadget as well as provide some miscellaneous data such as screenshots.&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;pp&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;Module&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;ta&quot;&gt;&amp;lt;ModulePrefs&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;title&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Fake RPG Character Sheets&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;scrolling&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;height&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;width&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;320&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;an&quot;&gt;description&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;This is an example of what you might do with a web-based game and igoogle gadgets.&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;an&quot;&gt;author&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Ranger Sheck&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;author_email&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;rangersheck@skipintrodevelopment.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;an&quot;&gt;title_url&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://rangersheck.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;an&quot;&gt;screenshot&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://examples.rangersheck.com/gadget/screenshot.png&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;an&quot;&gt;thumbnail&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://examples.rangersheck.com/gadget/screenshot-tn.png&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;ta&quot;&gt;&amp;lt;/ModulePrefs&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Next, we add as many UserPref elements as we need. Each of these UserPrefs can be set by the user when they install the gadget. In this case, we only need to know the login name they use for our game, and we're going to make it a required attribute.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;UserPref&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;player_login&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;display_name&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Fake RPG Login name (username):&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;required&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Here we can start displaying some HTML. When an iGoogle gadget is displayed on a page, it's actually being displayed inside an iframe. That makes it easy for us to set up whatever we want in terms of HTML, JavaScript, CSS. Notice here, I reference a .css file, a couple .js files. Then I stick in some real basic HTML that will make a nice little two-column layout. At the end, I use a couple of Google's _IG_... methods to grab the UserPref variables and to make a call to a function once the page is done loading.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;  &lt;span class=&quot;ta&quot;&gt;&amp;lt;Content&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;   &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;er&quot;&gt;&amp;lt;&lt;/span&gt;![CDATA[&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;ta&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://examples.rangersheck.com/gadget/fake-rpg-stats.css&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;            &lt;span class=&quot;an&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;stylesheet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;text/css&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;ta&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;ta&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://examples.rangersheck.com/gadget/utils.js&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;ta&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://examples.rangersheck.com/gadget/json2-min.js&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;ta&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://examples.rangersheck.com/gadget/fake-rpg-stats.js&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;content_div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;style&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;width:300px; background-color: #EEE; margin:0 auto;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;char_wrap&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;     &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;details_block&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;ta&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Fake RPG&lt;span class=&quot;ta&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;ta&quot;&gt;&amp;lt;h2&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;login_name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;ta&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;em&amp;gt;&lt;/span&gt;mouse over each character for details&lt;span class=&quot;ta&quot;&gt;&amp;lt;/em&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;     &lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;details&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;style&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;display:none;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;style&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;clear:both&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;ta&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;text/javascript&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      // Get userprefs&lt;tt&gt;
&lt;/tt&gt;      var prefs = new _IG_Prefs();&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;      // make JSON request once page loads&lt;tt&gt;
&lt;/tt&gt;      _IG_RegisterOnloadHandler(makeJSONRequest);&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;ta&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  ]]&lt;span class=&quot;er&quot;&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;ta&quot;&gt;&amp;lt;/Content&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/Module&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;3. Parsing the JSON and generating HTML&lt;/h2&gt;

&lt;p&gt;At the very end of the XML file, we are triggering a call to a function called makeJSONRequest. This is just a function I created myself in the file &lt;a href=&quot;http://examples.rangersheck.com/gadget/fake-rpg-stats.js&quot;&gt;fake-rpg-stats.js&lt;/a&gt;. Let's take a look at that file:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;function&lt;/span&gt; makeJSONRequest() {&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// This URL returns a JSON-encoded string that represents a JavaScript object&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;var&lt;/span&gt; url = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://yourdomain.com/fake_game_json.php?user_login=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;var&lt;/span&gt; url += &lt;span class=&quot;fu&quot;&gt;escape&lt;/span&gt;(prefs.getString(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;player_login&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;));&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// here we call the iGoogle method that grabs the text from the url and passes &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// it off to our responseHandler function&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// let's set the refreshInterval to tell it to grab the content every 10 minutes&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  _IG_FetchContent(url, responseHandler, { refreshInterval: (60 * 10) });&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;function&lt;/span&gt; responseHandler(response) {&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// display error if we got bad response&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; (response == &lt;span class=&quot;pc&quot;&gt;null&lt;/span&gt; || typeof(response) != &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;    msg = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;i&amp;gt;Invalid data. Response: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + response + &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + typeof(response) + &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&amp;lt;/i&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    $(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;content_div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).innerHTML = msg;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;return&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// parse the response string as JSON - note that the parser resides in the json2-min.js file&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;var&lt;/span&gt; player = JSON.&lt;span class=&quot;fu&quot;&gt;parse&lt;/span&gt;(response);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// we're creating two chunks of HTML - one for the left side and one for the right&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// on the left side, we stack up the character names in boxes&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// on the right side are blocks containin each of the PCs details - they all start out hidden&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;var&lt;/span&gt; pc_html = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;var&lt;/span&gt; hidden_pc_html = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// loop through player characters&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;r&quot;&gt;var&lt;/span&gt; p = 0; p &amp;lt; player.pcs.length ; p++) {&lt;tt&gt;
&lt;/tt&gt;    pc = player.pcs[p]&lt;tt&gt;
&lt;/tt&gt;    pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;div class=&amp;quot;char&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + pc.name + &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;/strong&amp;gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Level &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + pc.level + &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;   &lt;tt&gt;
&lt;/tt&gt;    hidden_pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;div style=&amp;quot;display:none&amp;quot; id=&amp;quot;pc_detail_&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + p + &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    hidden_pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + pc.name + &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;/strong&amp;gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    hidden_pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Health: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + colored_number(pc.health) + &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    hidden_pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Strength: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + pc.stats.Strength +&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    hidden_pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Wisdom: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + pc.stats.Wisdom +&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    hidden_pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Dexterity: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + pc.stats.Dexterity +&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    hidden_pc_html += &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Luck: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; + pc.stats.Luck +&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;br/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;  } &lt;span class=&quot;c&quot;&gt;// end player characters for loop&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// set login name header to our player's name&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  $(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;login_name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).innerHTML = player.name;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// fill in the left side&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  $(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;char_wrap&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).innerHTML = pc_html;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// fill in the hidden blocks on the right side&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  $(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;details&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).innerHTML = hidden_pc_html;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// now that the new HTML is generated, we can add some onmouseover functionality&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  setupRollovers();&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;A couple of things to note here. I've created some &quot;utility&quot; functions that you can find in the &lt;a href=&quot;http://examples.rangersheck.com/gadget/utils.js&quot;&gt;utils.js&lt;/a&gt; file. These are basically just some prototype-like shortcuts for grabbing HTML elements and showing or hiding them. Also, since we want to safely parse the JSON, I grabbed the &lt;a href=&quot;http://www.json.org/js.html&quot;&gt;parser from json.org&lt;/a&gt; and &lt;a href=&quot;http://examples.rangersheck.com/gadget/json2-min.js&quot;&gt;minified it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you've never worked with JSON before, go back and take a look at the code from 'fake-rpg-stats.js'. Notice how we assigned the whole block of data (after parsing it) to the player variable. This variable is a javascript object, or associative array. That means all of it's children can be accessed using an object-oriented notation or an array notation. I find OO-style more readable, so when I want the player's name, I use:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;player.name&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;but you could also use:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;player[&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Notice how player.pcs is an array containing the PCs, and each of those elements contains a few attributes like 'name' and 'level' as well as another array of 'stats'. It's pretty basic JavaScript to loop through our array of PCs, grab the attributes from each, and plug that data into a block of simple HTML.&lt;/p&gt;

&lt;h2&gt;4. DHTML Magic&lt;/h2&gt;

&lt;p&gt;You'll notice the HTML in both the XML file and the stuff generated by our JavaScript is pretty bare. I've kept all the styling in &lt;a href=&quot;http://examples.rangersheck.com/gadget/fake-rpg-stats.css&quot;&gt;fake-rpg-stats.css&lt;/a&gt;, and that's where you'll find the oh-so-fancy background images, text colorations, and block decoration. When you mouse-over each of the names in the left side of the widget, the &quot;stats&quot; for that character should appear on the right. The &quot;setupRollovers()&quot; function we call at the very end of our responseHandler can be found in that 'utils.js' file. This function &lt;a href=&quot;http://en.wikipedia.org/wiki/Unobtrusive_JavaScript&quot;&gt;unobtrusively&lt;/a&gt; grafts an &quot;onmouseover&quot; attribute onto each of the divs with the PC names in them on the left side. When the mouse goes over one of those divs, we want to hide all other player-detail divs and show only the one we moused over.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;function&lt;/span&gt; setupRollovers() {&lt;tt&gt;
&lt;/tt&gt;  pc_name_divs = &lt;span class=&quot;pt&quot;&gt;document&lt;/span&gt;.getElementById(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;char_wrap&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).getElementsByTagName(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;r&quot;&gt;var&lt;/span&gt; i = 0; i &amp;lt; pc_name_divs.length ; i++) {&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;// need a way to reference the index of this PC, so set a pc_id attribute&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    pc_name_divs[i].pc_id = i;&lt;tt&gt;
&lt;/tt&gt;    pc_name_divs[i].onmouseover = &lt;span class=&quot;r&quot;&gt;function&lt;/span&gt;() { switch_to_pc(&lt;span class=&quot;pc&quot;&gt;this&lt;/span&gt;.pc_id); };&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;// display this PC's stats and hide others&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;function&lt;/span&gt; switch_to_pc(p) {&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;// 'details' is hidden by default so we don't get the border with nothing inside&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  show(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;details&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;  pc_divs = &lt;span class=&quot;pt&quot;&gt;document&lt;/span&gt;.getElementById(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;details&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).getElementsByTagName(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;r&quot;&gt;var&lt;/span&gt; i = 0; i &amp;lt; pc_divs.length ; i++) {&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; (i == p) {&lt;tt&gt;
&lt;/tt&gt;      show(pc_divs[i].id);&lt;tt&gt;
&lt;/tt&gt;    } &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;      hide(pc_divs[i].id);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;h2&gt;5. Testing the code in iGoogle&lt;/h2&gt;

&lt;div&gt;&lt;em&gt;the finished gadget&lt;/em&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Assuming you have an iGoogle account, and you're logged in, testing your gadget out is pretty easy. I like to have a separate &quot;tab&quot; for testing purposes. If you've never added a tab to iGoogle, notice that there is a Home tab just below the search form. Next to that, there should be an &quot;Add tab&quot; link - just click that to add another tab and name it Testing. Once you're in a Testing tab, you can add the &quot;My Gadgets&quot; developer gadget. Go to &lt;a href=&quot;http://www.google.com/ig/directory?url=www.google.com/ig/modules/developer.xml&quot;&gt;this page&lt;/a&gt; and click the &quot;Add it now&quot; button.&lt;/p&gt;

&lt;p&gt;With this utility gadget, you can paste the URL of your base XML file into the &quot;Add a gadget&quot; form and your gadget will automatically show up under your Testing tab. Under normal circumstances, Google will cache your XML file, refreshing it only after an hour or so. During testing, this behavior can be quite the pain in the neck, but the &quot;My Gadgets&quot; gadget allows you to disable caching for your gadget just by unchecking a box. Note that this only bypasses the cached file for you. If this is a live gadget, any other users who are using will still only get an updated version of the XML file every hour or so. There is no way to tell Google to manually purge their cache of your gadget's XML file. If you make a change, your users will just have to wait until the cached version expires.&lt;/p&gt;

&lt;p&gt;Notice that when you add your gadget to iGoogle, it prompts you for the &quot;login name&quot; for &quot;Fake RPG&quot;. - That prompt comes from the UserPref requirement we set in the very beginning. Since I wrote the fake PHP script to take any username you give it, you can just type anything into this field and click Save. After that, your gadget should load. Note that a user can go back and change the value they entered for username by clicking the little down-arrow at the top right corner of the gadget, and then clicking &quot;Edit settings&quot;.&lt;/p&gt;

&lt;h2&gt;6. End Notes&lt;/h2&gt;

&lt;p&gt;The iGoogle _IG_... functions come from an API that is currently being re-written by Google to conform more to the OpenSocial API. Changing over this example code to the new API is extremely easy. You'll only have to replace the three functions that start with _IG_. Most of them are just renamed using a gadgets.* namespace. The _IG_Fetch* functions are replaced by a more generic gadgets.io.makeRequest function that takes a parameter that specifies the type of content you're expecting to grab. In the new API, you can specify JSON as a content type, which means that you'll be able to drop the JSON parser library and skip the parsing step because Google's API will handle that stuff automatically.&lt;/p&gt;

&lt;p&gt;At this time (July, 2008), the Google's implementation of the OpenSocial API is not public. You can register to try it out in some kind of iGoogle &quot;Sandbox mode&quot;, but the gadgets.* stuff won't work for your general end-users at this time. It's worth checking out, however, because other sites that implement the OpenSocial API use the same gadgets.* format. I experimented a little with MySpace's implementation of &quot;gadgets&quot; (they call them Apps), but unfortunately, MySpace Apps don't use the UserPref setting (most likely as a security precaution - it's a minor miracle they are allowing any kind of javascript back into MySpace at all). So there's no way to prompt the user for their username on another, non-MySpace system. I haven't had time to experiment with the actual inter-linking of OpenSocial data, but I expect there's a way to use OpenSocial to get a MySpace App to act just like your iGoogle gadget. From what I can tell, MySpace uses a &lt;a href=&quot;http://developer.myspace.com/community/myspace/myopenspace.aspx#MyOpenSpace.MySpaceContainer.makeRequest&quot;&gt;makeRequest&lt;/a&gt; function which can be used to fetch XML or JSON data, very similarly to the Google implementation.&lt;/p&gt;

&lt;p&gt;That's all for now. Here's all the code I showed you in one archive: &lt;a href=&quot;http://examples.rangersheck.com/fake-rpg-gadget.zip&quot;&gt;fake-rpg-gadget.zip&lt;/a&gt;. Now get started on some gadgets of your own!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://rangersheck.com/">
    <author>
      <name>RangerSheck</name>
    </author>
    <id>tag:rangersheck.com,2008-06-28:217</id>
    <published>2008-06-28T00:54:00Z</published>
    <updated>2008-06-28T00:55:46Z</updated>
    <category term="Game Design"/>
    <category term="PBBG"/>
    <category term="game design"/>
    <category term="game development"/>
    <category term="pbbg"/>
    <category term="PBBG"/>
    <category term="web game"/>
    <link href="http://rangersheck.com/2008/6/28/game-design-principles-part-2" rel="alternate" type="text/html"/>
    <title>Game Design Principles - Part 2</title>
<content type="html">
            &lt;p&gt;Continuing from &lt;a href=&quot;/2008/6/28/game-design-principles&quot;&gt;Game Design Principles &#8211; Part 1&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Game Design Principles behind &lt;a href=&quot;http://aethora.com&quot;&gt;Aethora&lt;/a&gt; (5 through 9 of 9)&lt;/h2&gt;


	&lt;h3&gt;5. Good strategy should mean combining lots of different skills. The appearance of a successful strategy that utilizes only one or two skills is an indicator of imbalance.&lt;/h3&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/dunechaser/518821732/&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/lego-army.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Everyone who&#8217;s ever played a &lt;span class=&quot;caps&quot;&gt;MMORPG&lt;/span&gt; knows that balance is always an ongoing issue. The developers are always making adjustments to classes, abilities, equipment, and so forth. The sheer quantity and variety of factors that are involved make the concept of total balance something that&#8217;s impossible to achieve during the design phase. You can get pretty close, but one thing a designer has to remember &#8211; you design aspects of the game with certain intended uses, and the balancing you provide is based on those intended uses. When players get ahold of the game and start using things in ways you didn&#8217;t intend or anticipate, you&#8217;re going to discover new imbalances. It&#8217;s a fact, Jack.&lt;/p&gt;


	&lt;p&gt;So one easy rule of thumb that I&#8217;m using here, somewhat specific to Aethora, but in general I think a good strategy: If I notice that a player is gearing up all their characters with the same gear, then I can guess that they think they have found an attack or two that is far superior to other attacks. Sometimes, this strategy is a bad one. Other times, the player could be onto something &#8211; there may be an attack that makes a battle much easier to win and other attacks are inferior by comparison.&lt;/p&gt;


	&lt;p&gt;The overall point is, at least for Aethora, the game is party-based. A good party in any &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; should have some variety. Characters tend to fill different roles, such as melee, magic-user, healer, and so forth; or in common &lt;span class=&quot;caps&quot;&gt;MMORPG&lt;/span&gt;-speak: Tanks, DPSers (damage-dealers), Buffers, Healers, Crowd-Controllers, and various other &#8220;Support&#8221; roles. So, in Aethora, I want to see the good players using a broad mixture of skills in combat.&lt;/p&gt;


	&lt;h3&gt;6. Victory in combat on average should be decided by factors in this pecking order: Good strategy &amp;gt; Higher Skill Levels &amp;gt; Better Equipment&lt;/h3&gt;


	&lt;p&gt;Aethora is a tactical, or strategy &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt;. Party-based combat on a map is the core of combat, so I try to spend some time thinking about what makes map-based combat fun and challenging. I like to think of a tactical &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; almost as a game of chess; but instead of simply different move-patterns, the pieces have different offensive and defensive abilities. Since the game at it&#8217;s core is still a role-playing game, the whole point is to advance character development; so character skill levels should, of course, make a difference when it comes to combat. The secondary method of character development in an &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; has to do with acquiring better equipment, and clearly a well crafted longsword should outperform a rusty fire poker.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/peterjr1961/2190264036/&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/armor.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;So the goal of this principle is this: good equipment is no substitute for adequate skill levels, and skill levels are no substitute for good strategy. In other words, a player should still have a chance to win a fight in which they are outclassed in terms of equipment and skills, to a certain degree, as long as they employ good strategy. Likewise, if a player has a poor strategy going into a fight, expensive equipment will not save them.&lt;/p&gt;


	&lt;p&gt;To achieve the &#8220;Higher Skill Levels &amp;gt; Better Equipment&#8221; part of this principle, there is some real basic math going on. The combat formula uses some weighting to give advantage or disadvantage between attacker and defender skill levels, and then a lesser weighting when comparing attacker&#8217;s weapon strength with defender&#8217;s armor strength. Making &#8220;Good Strategy&#8221; the most important factor in combat is a little trickier, and it relies pretty heavily on principle #5.&lt;/p&gt;


	&lt;h3&gt;7. No &#8220;punishment&#8221; paths in missions (quests). Any path that &#8220;burns a bridge&#8221; should be roughly equal in benefits to any other path.&lt;/h3&gt;


	&lt;p&gt;Mission-writing has been a primary goal of our development team in the last few months, so I felt it necessary to lay down this particular ground rule. It&#8217;s very tempting to create a branching point where a player can chose to do the &#8220;right thing&#8221; or the &#8220;wrong thing&#8221;; after all, decision making is part of the challenge of doing quests or missions. So if a player chooses the &#8220;right thing&#8221;, maybe they get a little more gold in the end, or even a better piece of equipment as a reward; and that makes sense. However, it makes me a little uncomfortable to see a situation in which a player might do the &#8220;right thing&#8221; and gain access to another mission later on, where the player who picks the &#8220;wrong thing&#8221; ends up at a dead-end.&lt;/p&gt;


	&lt;p&gt;Mainly this principle has to do with Aethora being somewhat of a &#8220;casual&#8221; &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt;. I&#8217;d hate for a player to become frustrated and quit because they missed out on something when they took the wrong path &#8211; especially when the decision was tricky (and often these things are not obvious). Since this is an online game, and not a single-player game, there is no previous saved game to reload when you make a mistake.&lt;/p&gt;


	&lt;p&gt;So I devised a simple formula for &#8220;factors of mission outcome equality&#8221;: 
Chance for another mission = 100; unique piece of equipment = 10; monetary reward = 1&lt;/p&gt;


	&lt;p&gt;In other words, two branching mission paths that both offer another mission are roughly equal (100 vs 100). Two branching paths in which one offers gold but the other offers equipment are close enough to equal (10 vs 1). Branching paths in which one offers a new mission but the other offers only one piece of equipment are not close enough to equal (100 vs 10). But, if you really want to write two branching paths and let one lead to a new mission and another lead to a bag of unique equipment (like say 8 pieces, or 100 vs 80), then I&#8217;m more likely to allow such a choice (as long as the storyline makes sense, of course).&lt;/p&gt;


	&lt;p&gt;What we end up with is less chances for &#8220;right&#8221; and &#8220;wrong&#8221; paths and more paths that are just &#8220;different&#8221; &#8211; and I&#8217;ve found that these can be much more interesting. You can see that I&#8217;ve made an assumption here that what players want most of all is to do more missions; I think for the majority, that&#8217;s part of the fun of the game. Completing a quest or a mission is an accomplishment. Therefore, a chance for another mission outweighs material rewards many times over.&lt;/p&gt;


	&lt;h3&gt;8. The best RPGs incorporate fun and engaging gameplay as well as quality story lines. These are two dimensions on one grid; to cover the maximum amount of area possible, both dimensions need to be stretched.&lt;/h3&gt;


	&lt;p&gt;At this point, I&#8217;m going to take a moment and re-iterate that these principles are largely based on my personal opinions when it comes to role-playing games. The first part is easy: if gameplay &#8211; and by that, let&#8217;s be frank, I&#8217;m mostly referring to combat &#8211; is weak, then I&#8217;m not going to play a game. Combat needs to be interesting, engaging, should not feel overly formulaic, should not be too long and should not be too short. That&#8217;s a pretty tall order to live up to, but remember, this is a principle &#8211; an ideal &#8211; I&#8217;m aiming for. I&#8217;m not claiming that I&#8217;ve reached it 100% with Aethora.&lt;/p&gt;


	&lt;p&gt;To be honest, if the gameplay of a particular &lt;span class=&quot;caps&quot;&gt;CRPG&lt;/span&gt; is pretty good but the storyline is inane, there&#8217;s still a pretty good chance I will play the game. Let&#8217;s face it &#8211; storylines in CRPGs for the most part are pretty thin, so players have learned to deal with it. That being said, when I look back on my most memorable experiences with CRPGs, the games that had great storylines stand out the most.&lt;/p&gt;


	&lt;p&gt;So you see, these two factors can combine to make a great game. However, it&#8217;s my opinion that you&#8217;ll lose people quicker if gameplay is weak. If gameplay starts out good but becomes tedious later on, you may lose more people that way as well. Ranger Sheck&#8217;s inner voice: &#8220;If you want people to play the game, you better make the game fun to play.&#8221; But, then, I love to write, and I know how memorable a good storyline can be, so with this principle I&#8217;m recognizing that good stories are going to help make a mediocre game reach for greatness.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Image:Aybabtu.png&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/aybabtu.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I&#8217;m willing to bet some developers (especially browser-based games, where text is easier to work with than graphics) are going to disagree and claim that a good story should carry the most weight. I love a good story! And for that reason, I do a lot of reading. A lot. Even the best storyline in a game cannot come close to a good book, and so when I want a good story, I don&#8217;t want to sit in front of my computer screen and read page after page &#8211; I&#8217;ll sit down with a good book. That&#8217;s why it&#8217;s my opinion that quality writing can greatly enhance, but not carry, a &lt;span class=&quot;caps&quot;&gt;CRPG&lt;/span&gt;.&lt;/p&gt;


	&lt;h3&gt;9. There is a third dimension that is unique to online RPGs: player community and interaction. While more difficult to stretch, this dimension bears much greater potential.&lt;/h3&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/kurtxio/2182760200/&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/web.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;This last principle expands on the previous one, to serve as a reminder of why &#8220;online&#8221; role-playing games are different than offline CRPGs. Aethora needs a lot of work in this area, because other than buying and selling equipment to other players and some sharing of information through chat and forums, there isn&#8217;t much other player interaction. I recognize the fact that having a more interactive community really has a profound effect on the popularity and &#8220;stickiness&#8221; of an online &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt;. Therefore, this principle is here at the bottom, not because it&#8217;s the least important, but the one that Aethora needs the most work on.&lt;/p&gt;


	&lt;p&gt;I have some big plans in this area, and I just need to find some time to work on them:
 &#8211; Player crafting and tradeskills to increase market trading between players.
 &#8211; Contests and tournaments where players can face off against similar groups of NPCs and see who does the best
 &#8211; Player versus player combat (I&#8217;m still on the fence about this one, as the nature of a web-based game introduces a lot of potential issues)
 &#8211; The ability for players to own land and populate land with guardians &#8211; even to the point at which a player might create an entire &#8220;dungeon&#8221;, populate it with baddies and treasure and then invite other players to come try their hands at it. My ultimate goal, to put it simply, is to have ways for players to generate content.&lt;/p&gt;


	&lt;p&gt;Well, that about wraps it up. Comments? Questions?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://rangersheck.com/">
    <author>
      <name>RangerSheck</name>
    </author>
    <id>tag:rangersheck.com,2008-06-28:216</id>
    <published>2008-06-28T00:28:00Z</published>
    <updated>2008-06-28T00:55:58Z</updated>
    <category term="Game Design"/>
    <category term="PBBG"/>
    <category term="game design"/>
    <category term="game development"/>
    <category term="pbbg"/>
    <category term="PBBG"/>
    <category term="web game"/>
    <link href="http://rangersheck.com/2008/6/28/game-design-principles" rel="alternate" type="text/html"/>
    <title>Game Design Principles</title>
<content type="html">
            &lt;p&gt;A couple months ago, I made the change from being the sole developer and writer for my game and invited some of my players to join me in creating a design team. While all the coding responsibilities still rest on my shoulders, the other designers have been contributing artwork, mission plots, non-player character design, weapon and armor design, area design, and so forth. I quickly realized that while it&#8217;s possible for people to get a sense of what a coder&#8217;s thoughts and motivations are by playing their game, there are still many aspects of a game&#8217;s design that are not so easy to interpret.&lt;/p&gt;


	&lt;p&gt;When I set up a forum for our team to collaborate in, much of the initial conversation was brainstorming about changes or additions to make to the game. I found myself defending and explaining various methods and components of the current design and what those explanations meant for future design. I realized that while I am open to other ideas, there were certain things that I wasn&#8217;t likely to budge on. The more I thought about it, the more I began to understand that I had internalized a set of principles that guide the path of development for my game.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/walkercleaveland/1020606824/&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/stone.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Do I think all games should follow these design principles? Certainly not! Many parts of this list were born out of being unhappy with one particular aspect or another of a game that I otherwise enjoyed; some other parts were born out of recognizing which parts of existing games I think were done really well. But without a wide diversity of drivers and factors behind game development, where would we be?&lt;/p&gt;


	&lt;p&gt;So you may agree with these principles, and you may not. The perspective they are written from lies in the development of a role-playing game; specifically a computer role-playing game (CRPG), and more specifically than that, an online, web-based, strategy (or tactical) role-playing game. To date, combat is the largest aspect of my game, and since it is a tactical &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; in terms of a combat system, some of these principles might only make sense in that context. Others, however, are more universal.&lt;/p&gt;


	&lt;p&gt;As you read these, please take note: The words are mine, but the thoughts behind them come from an accumulation of years of experience in playing, thinking, and talking about games. I don&#8217;t claim any kind of exclusivity or originality on any of these concepts.&lt;/p&gt;


	&lt;h2&gt;Game Design Principles behind Aethora (1 through 4 of 9)&lt;/h2&gt;


	&lt;h3&gt;1. No wrong path for character development.&lt;/h3&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/taz/456653752/&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/arrows.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;This principle is at the top of the list for a reason &#8211; it&#8217;s the one that was the foundation for the character system in Aethora. This character system, while not 100% unique, is very rare in the broad range of RPGs out there, because it is classless. In a role playing game, you need roles, and in most games this role is chosen from the start as a job or a class. In some cases, it can be changed or it has branches later on in a character&#8217;s development. In Aethora&#8217;s case, the character has no class, but simply a set of skills. There are no levels, no experience, no points to spend. When you want your character to learn how to fight with a sword, you have to put a sword in their hand and get them to battle. The more you use a skill (against better and better enemies) the better you get.&lt;/p&gt;


	&lt;p&gt;The big seeds for this principle are in my frustration with pretty much any role-playing game. As much as I love to game, there are always those people out there with much more time on their hands. There is always someone to figure out which combination of race and class is the best, which branch is the best part of the skill tree to take, etc, etc. Inevitably, I&#8217;d be feeling like I made a mistake at some low level or even at the point of character creation that didn&#8217;t fully manifest itself until I got to a higher level and realized I&#8217;m just not as effective a character as I could be, but there&#8217;s no way to correct it without &#8220;re-rolling&#8221;.&lt;/p&gt;


	&lt;p&gt;In Aethora, you are not allowed to delete any characters; you can only change their name or appearance at any time. If you decide that one of the roles a PC is playing is not the ideal role for the balance of your party, you simply re-equip them and start them down the path that works for you. &lt;strong&gt;No regrets means no re-specing and no re-rolling.&lt;/strong&gt;&lt;/p&gt;


	&lt;h3&gt;2. Roleplaying for roleplaying&#8217;s sake, not as an excuse for convenience.&lt;/h3&gt;


	&lt;p&gt;This principle is not so much a hard and fast rule, but more of a guiding ideal. I think, at the core, what this comes down to is honesty. If players are given some obviously convenient excuse for the blockage of a path or method, then they are going to lose trust in the game designer. Blatant abuse of &#8220;magic&#8221; explanation or other non-explanation of game mechanics weakens immersion, and when immersion breaks down, a player is going to start to see the &#8220;human side&#8221; of the developer. If you&#8217;ve ever played Pencil and Paper role-playing game, you may remember some moments when your Dungeon Master tried to railroad you down a path that they had meticulously laid out for you. Sometimes a player&#8217;s natural reaction to being railroaded, oddly enough, is to try to jump off the tracks. This is the kind of thing that reminds a player that they are playing a game with limitations; and that&#8217;s what I mean by &#8220;weakening immersion&#8221;.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/mercurialn/2099735247/&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/teleport-sign.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Take the example of a 3D &lt;span class=&quot;caps&quot;&gt;MMORPG&lt;/span&gt;. A lot of times, travel can be a real pain for players in a ginormous 3D world. To keep people from getting frustrated, developers might introduce ridable mounts that increase travel speed. This example makes perfect sense &#8211; the player doesn&#8217;t have to stretch any imagination to get on a horse and move a little faster. Now say, after a while, the developers decide that players aren&#8217;t getting to all the new fancy areas they&#8217;ve put in, so they want to make travel even more convenient; so they introduce a magical teleport system where any player can walk up to an area and be beamed over to another area fairly easily. While the new system is certainly more convenient for players, this is, in my opinion, an example of breaking the &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; setting and simply making it easier to get to the hack-n-slashing. When a player has to cross a long expanse of land to get to their destination, they develop an appreciation for the vastness of the world their character inhabits. When they bounce around via a loosely-expounded teleportation device, the world becomes a lot smaller.&lt;/p&gt;


	&lt;h3&gt;3. Avoid imposing realism in favor of fun.&lt;/h3&gt;


	&lt;p&gt;In some ways, this principle is the opposite of #2, but it takes a slightly different mentality. When designing an &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; system, it&#8217;s tempting to try to be as realistic as possible, whether it&#8217;s in combat, travel, basic survival, etc. One of the classic examples is the notion of hunger. In EverQuest, like many text-based MUDs before it, a player is required to carry food and drink with them at all times. In the old MUDs, you used to have to manually eat and drink food until you were satiated. In Everquest, they automated it slightly by making your character  periodically eat something from their inventory. If the character had no food, they would start to get hungry (and eventually, once hungry enough, penalized in combat).&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/77106971@N00/1420127033/&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/groceries.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;For a lot of players, this type of realism is part of the challenge of role-playing. For many others, however, it becomes just a big pain in the neck. It&#8217;s not really very mentally challenging, unless you consider trying to remember to buy food when in town a mental challenge. For me as a player, it became the most annoying when I regularly ran out of food while out adventuring and sometimes had to trek back to town just to fill up.&lt;/p&gt;


	&lt;p&gt;Whenever something like that happens, the player feels like they are doing work rather than playing. Sometimes, you have to do a little work in an &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; &#8211; that&#8217;s the nature of that style of game. As long as it&#8217;s balanced by fun, then a little work is okay &#8211; but too much work overshadows fun. That&#8217;s kind of a key point, so I&#8217;m going to restate it: &lt;strong&gt;If I feel like a game is making me do too much work, I&#8217;m not going to play it.&lt;/strong&gt;&lt;/p&gt;


	&lt;h3&gt;4. Heroes don&#8217;t have time for pest control jobs, I don&#8217;t care how inexperienced they are.&lt;/h3&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/yaatra/258383522/&quot;&gt;&lt;img src=&quot;/assets/2008/6/28/rats.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;This principle might be specific to the setting, but honestly, I think it can be applied to most role-playing games out there. Ok, sure, the point of an &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; is that you start with small challenges and work up to larger challenges. But why, oh why, do I always have to start out killing rats? Don&#8217;t you think it would be a little more fun if we started our characters a little later in their careers? In D&#38;D terms, I&#8217;m talking about starting at level 3 or so instead of level 1; when I first start out let me fight some orcs instead of garden snakes. I mean, come on &#8211; can you even imagine trying to stab a rat with a dagger? Wouldn&#8217;t it make more sense for that shopkeeper to just put down some rat traps or some rat poison?&lt;/p&gt;


	&lt;p&gt;So why does a typical &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; start you out on pest control duty? To be honest, I think designers like to make those first couple of levels ridiculously easy so (a) you&#8217;ll get used to playing the game and (b) you&#8217;ll get addicted fast. All of us &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; addicts are sucked in by accomplishments. We live for that &#8220;ding&#8221; sound, and once we&#8217;ve gone from level one to level two, we feel like we&#8217;ve made an investment.&lt;/p&gt;


	&lt;p&gt;The &#8220;pest control&#8221; concept goes beyond those initial stages of character development, though. For this reason, I&#8217;ve made it one of my principles. Whenever you ask a player to: clear an area of infestation/invasion/etc; bring back N number of pelts/sashes/ears; scavenger hunt for ores/oysters/Easter eggs; in any kind of typical mindless hunter/gatherer scenario, you&#8217;re basically giving the player busywork. You&#8217;re not challenging them with making appropriate decisions or problem solving &#8211; you&#8217;re acting like that doddering old substitute teacher who would come in and make the class do macaroni pictures or origami rather than attempt the lesson on fractions.&lt;/p&gt;


	&lt;p&gt;Again, why do we see this style of &#8220;quest&#8221; so often in RPGs? They make good time-sinks. Sometimes mindless play is actually pretty entertaining; heck, sometimes that&#8217;s exactly what we&#8217;re looking for in a video game. But personally, I feel like there are enough opportunities in any online &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt; to go out and enjoy mindless combat. If I&#8217;m really on some kind of Quest or Mission, I want a little more of a challenge. To me, that&#8217;s what defines a Quest or Mission: it&#8217;s a challenge (and there&#8217;s a reward when it&#8217;s complete).&lt;/p&gt;


	&lt;p&gt;Continue reading principles 5 through 9 in &lt;a href=&quot;/2008/6/28/game-design-principles-part-2&quot;&gt;Game Design Principles &#8211; Part 2&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://rangersheck.com/">
    <author>
      <name>RangerSheck</name>
    </author>
    <id>tag:rangersheck.com,2008-03-18:206</id>
    <published>2008-03-18T15:23:00Z</published>
    <updated>2008-03-18T15:25:41Z</updated>
    <category term="PBBG"/>
    <category term="browser-based"/>
    <category term="javascript"/>
    <category term="PBBG"/>
    <category term="pbbg"/>
    <category term="programming"/>
    <category term="web-based"/>
    <link href="http://rangersheck.com/2008/3/18/introducing-moveablemap" rel="alternate" type="text/html"/>
    <title>Introducing MoveableMap</title>
<content type="html">
            &lt;p&gt;I posted this on my other, more tech/web-dev oriented blog, but since it&#8217;s a great tool (or at least example to learn from) for web-based game developers, I figured I&#8217;d mention it here.&lt;/p&gt;


	&lt;p&gt;MoveableMap is a javascript library (open source, &lt;span class=&quot;caps&quot;&gt;MIT&lt;/span&gt; license) that allows you to turn any block of &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; into a draggable, moveable entity within a viewport. Similar to the draggable behavior of Google Maps, but hopefully very easy to implement.&lt;/p&gt;


	&lt;p&gt;More information and demos can be found here:
&lt;a href=&quot;http://offtheline.net/2008/3/13/moveablemap-or-anything-else-in-a-viewport&quot; title=&quot;or anything else in a viewport&quot;&gt;MoveableMap&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://rangersheck.com/">
    <author>
      <name>RangerSheck</name>
    </author>
    <id>tag:rangersheck.com,2008-03-08:204</id>
    <published>2008-03-08T19:08:00Z</published>
    <updated>2008-03-08T19:41:42Z</updated>
    <category term="Game Design"/>
    <category term="PBBG"/>
    <category term="Statistics"/>
    <category term="browser-based"/>
    <category term="pbbg"/>
    <category term="PBBG"/>
    <category term="probability"/>
    <category term="programming"/>
    <category term="randomness"/>
    <category term="rpg"/>
    <category term="RPG"/>
    <category term="statistics"/>
    <category term="web-based"/>
    <link href="http://rangersheck.com/2008/3/8/statistics-what-are-the-real-odds" rel="alternate" type="text/html"/>
    <title>Statistics: What are the real odds?</title>
<summary type="html">&lt;p&gt;Wow, it&#8217;s been a while since my last post. I wish I had time to do this more often, but such is life.&lt;/p&gt;


	&lt;p&gt;I&#8217;ve been thinking a lot about statistics lately, and how they can be used in game design. We&#8217;ve all seen this problem in any game, particularly indie games (including a lot of browser-based game) &#8211; a problem with randomness. Sometimes a game doesn&#8217;t appear to leave enough to chance, and it becomes predictable. Other times a game is too random, to the point of frustrating a player when despite skill or a &#8220;better hand&#8221;, fate can easily turn against them.&lt;/p&gt;


	&lt;p&gt;This article will be the first in a series of probably three articles on statistics and randomness. Today I&#8217;d like to talk about what it means to consider the odds that an event might happen, given multiple attempts at it. For example: if an event has a 25% chance of occurring, you might expect that given 4 attempts at it, you&#8217;re pretty much guaranteed success. Given a second thought, we know that not to be exactly true. So what are those odds, anyway? More after the jump.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Wow, it&#8217;s been a while since my last post. I wish I had time to do this more often, but such is life.&lt;/p&gt;


	&lt;p&gt;I&#8217;ve been thinking a lot about statistics lately, and how they can be used in game design. We&#8217;ve all seen this problem in any game, particularly indie games (including a lot of browser-based game) &#8211; a problem with randomness. Sometimes a game doesn&#8217;t appear to leave enough to chance, and it becomes predictable. Other times a game is too random, to the point of frustrating a player when despite skill or a &#8220;better hand&#8221;, fate can easily turn against them.&lt;/p&gt;


	&lt;p&gt;This article will be the first in a series of probably three articles on statistics and randomness. Today I&#8217;d like to talk about what it means to consider the odds that an event might happen, given multiple attempts at it. For example: if an event has a 25% chance of occurring, you might expect that given 4 attempts at it, you&#8217;re pretty much guaranteed success. Given a second thought, we know that not to be exactly true. So what are those odds, anyway? More after the jump.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://flickr.com/photos/clearlyambiguous/55815919/&quot;&gt;&lt;img src=&quot;/assets/2008/3/8/coins.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Let&#8217;s start with a simpler example: the good ol&#8217; coin flip. Flip a coin once &#8211; what are the odds of getting heads? 1 out of 2, or 50%. If you flip a coin 8 times and it came up heads every single time, what are the odds of one more flip being heads? This is, of course, a trick question. The odds are still 50/50 because each flip of the coin is &lt;em&gt;unaffected&lt;/em&gt; by any other flip. The individual flips are &lt;em&gt;independent events&lt;/em&gt;. How about the probability that by flipping a coin twice, both times it comes up heads? There are four possible outcomes of two flips of a coin (H=heads, T=tails): HH, HT, TH, TT. Right there we can see that two heads occurs once out of four possible outcomes, so the chances are 1 in 4, or 25%.&lt;/p&gt;


	&lt;p&gt;This example leads us to the &lt;a href=&quot;http://en.wikipedia.org/wiki/Statistical_independence#Independent_events&quot;&gt;Multiplication Rule for Independent Events&lt;/a&gt;. Independently, each flip has a 50% chance of coming up heads. When events are independent, to find their cumulative probability, you can multiply their individual probabilities. Probabilities are always calculated as a number from 0 to 1; the equivalent of 0% to 100%. So to get the chance of a getting two heads out of two flips of a coin, we multiply:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;P(heads and heads) = P(heads) x P(heads) = 0.50&#215;0.50 = 0.25&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;In other words, 25%.&lt;/p&gt;


	&lt;p&gt;How does this relate to a game? Knowing how to calculate the cumulative odds that an event will occur can help identify when an event has been set up to happen too rarely. Imagine a scenario where a player has to search three chests and each time there is a 20% chance that a chest will contain some amulet. In order to get to a secret room, the player needs to get all three amulets. You might think that sure, the odds of getting the amulets from all three chests are against the player, but there&#8217;s still a pretty good chance. Let&#8217;s find out.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;P(amulet and amulet and amulet) = P(amulet)&lt;sup&gt;3&lt;/sup&gt; = (0.20)&lt;sup&gt;3&lt;/sup&gt; = 0.008&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;In other words, &lt;strong&gt;there&#8217;s a 0.8% of getting all three amulets&lt;/strong&gt;. Less than 1% &#8211; that&#8217;s pretty close to impossible! Even if the player is allowed to attempt the task periodically, it&#8217;s likely they will never achieve the goal.&lt;/p&gt;


	&lt;p&gt;Let&#8217;s try a different angle. What if we know what the percent chance is of an event and we want to know what are the odds that it will happen &lt;em&gt;at least once&lt;/em&gt; given a set number of trials? For example, taking the coin flip &#8211; if I flip a coin twice, what are the odds that I will get heads &lt;em&gt;at least once&lt;/em&gt;?&lt;/p&gt;


	&lt;p&gt;If you recall, the four possible outcomes of two flips of a coin (H=heads, T=tails): HH, HT, TH, TT. In this case, we win if the outcome is HH, HT, or TH. That&#8217;s 3 out of 4, or 75%. Another way to make the calculation is say the probability of the first coin getting heads is 0.50 (HH or HT), and the probability that the first coin was not heads but the second coin &lt;em&gt;was&lt;/em&gt; heads is 0.25 (TH). Since either of these combinations means success, we add them together:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;P(heads on first flip OR heads only on second flip) = 0.50 + 0.25 = 0.75&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Now of course, neither of those methods are very helpful when doing anything more complex than a couple coin flips. A third way we can look at the situation which lets us use the multiplication rule is to think of it in terms of what is the probability that the event &lt;em&gt;does not&lt;/em&gt; occur. In other words, what are the chances that both coin flips will come up tails? If we can find that, we can take the inverse of it to find the probability of our desired event.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;P(tails and tails) = (0.50)&lt;sup&gt;2&lt;/sup&gt; = 0.25&lt;br /&gt;
P(not both tails) = inverse of P(tails and tails) = 1 &#8211; 0.25 = 0.75&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;&lt;a href=&quot;http://flickr.com/photos/kahunna/1300007196/&quot;&gt;&lt;img src=&quot;/assets/2008/3/8/old-die.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;As you can see, the inverse of a probability is found by subtracting that probability from 1. All three methods have shown us that the chance of getting &lt;em&gt;at least one&lt;/em&gt; head out of two coin flips is 75%.&lt;/p&gt;


	&lt;p&gt;Now let&#8217;s think of a more useful scenario. Let&#8217;s go back to our three chests story, but this time we&#8217;ll say the player only has to get one amulet. The chance to get an amulet from a chest was 20%, so the odds that they &lt;em&gt;don&#8217;t get an amulet&lt;/em&gt; from a chest is 80%. They have three chances (because there are three chests), so let calculate the odds they don&#8217;t get a single amulet from any chest, then take the inverse again to find out if the player has a decent chance of getting at least one amulet:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;P(no amulet and no amulet and no amulet) = (0.80)&lt;sup&gt;3&lt;/sup&gt; = 0.512&lt;br /&gt;
P(at least one amulet) = 1 &#8211; 0.512 = 0.488&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;In other words, they have a 48.8% chance of getting at least one amulet in three tries.&lt;/p&gt;


	&lt;p&gt;Let&#8217;s take this example a little further, because I really want to point out a common misconception about odds. The chance to get an amulet is 20%, or one out of five. Logically, you might think that if you give a player 5 chances, they will be guaranteed to get the amulet once. This faulty logic is often referred to as the &lt;a href=&quot;http://en.wikipedia.org/wiki/Law_of_averages&quot;&gt;Law of Averages&lt;/a&gt; (which is not actually a &#8220;law&#8221; of real mathematics at all). Given what we&#8217;ve learned, let&#8217;s see what the real odds are for a player finding at least one amulet in 5 tries:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;P(no amulet and no amulet&#8230;.etc) = (0.80)&lt;sup&gt;5&lt;/sup&gt; = 0.32768&lt;br /&gt;
P(at least one amulet) = 1 &#8211; 0.32768 = 0.67232&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;&lt;a href=&quot;http://flickr.com/photos/lwr/2257952044/&quot;&gt;&lt;img src=&quot;/assets/2008/3/8/dice.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Given 5 tried, the chance of getting one amulet is actually only about 67%. It&#8217;s likely, but it&#8217;s far from a guaranteed success, isn&#8217;t it?&lt;/p&gt;


	&lt;p&gt;So how do you guarantee success based on probability? Well, you&#8217;re going to have to do it programmatically, because no combination of probabilities (other than all events getting a 100% chance) is ever going to combine to become 1.0. If you flip a coin 100 times, it&#8217;s extremely likely you&#8217;ll get at least one head, but technically there is one outcome that would result in 100 tails.&lt;/p&gt;


	&lt;p&gt;Let&#8217;s look at one last example so we can see how more chances increase the likelihood of a success. Let&#8217;s say a player is on a quest and has to get a special belt that some orcs wear. One out of ten orcs wear this belt, so we set up the game to give any slain orc a 10% chance to drop the belt. If the player kills just one orc, they&#8217;ve got a 10% chance to get their goal. Let&#8217;s look at the chances of getting a belt for 5, 10, and 20 slain orcs (notice that the chance of &lt;em&gt;not&lt;/em&gt; getting a belt is 90%):&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;P(at least one belt in 5) = 1 &#8211; (0.90)&lt;sup&gt;5&lt;/sup&gt; = 1 &#8211; 0.59 = 0.41 (&lt;em&gt;or 41%&lt;/em&gt;)&lt;br /&gt;
P(at least one belt in 10) = 1 &#8211; (0.90)&lt;sup&gt;10&lt;/sup&gt; = 1 &#8211; 0.35 = 0.65 (&lt;em&gt;or 65%&lt;/em&gt;)&lt;br /&gt;
P(at least one belt in 20) = 1 &#8211; (0.90)&lt;sup&gt;20&lt;/sup&gt; = 1 &#8211; 0.12 = 0.88 (&lt;em&gt;or 88%&lt;/em&gt;)&lt;br /&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Even after killing 20 orcs, there&#8217;s still only an 88% chance of success. When we said 10%, we were thinking the player would have to kill about 10 orcs, but turns out even killing 20 orcs is not as close to 100% as we&#8217;d like! Now that we&#8217;ve done the calculations, we can see that we may be frustrating players with these odds. Let&#8217;s readjust and try a 15% chance for an orc to drop a belt (85% chance they don&#8217;t drop one):&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;P(at least one belt in 5) = 1 &#8211; (0.85)&lt;sup&gt;5&lt;/sup&gt; = 1 &#8211; 0.44 = 0.56 (&lt;em&gt;or 56%&lt;/em&gt;)&lt;br /&gt;
P(at least one belt in 10) = 1 &#8211; (0.85)&lt;sup&gt;10&lt;/sup&gt; = 1 &#8211; 0.20 = 0.80 (&lt;em&gt;or 80%&lt;/em&gt;)&lt;br /&gt;
P(at least one belt in 20) = 1 &#8211; (0.85)&lt;sup&gt;20&lt;/sup&gt; = 1 &#8211; 0.04 = 0.96 (&lt;em&gt;or 96%&lt;/em&gt;)&lt;br /&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Hey, that&#8217;s a little more reasonable. We might even want to tweak it a little farther; at least now we have a method to determine the real odds.&lt;/p&gt;


	&lt;p&gt;In summary, when it comes to probabilities, don&#8217;t rely on &#8220;instinct&#8221; or faulty logic like the &#8220;Law&#8221; of Averages. Some simple calculations can give you a much more concrete idea of what kind of chances you&#8217;re giving your players.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://rangersheck.com/">
    <author>
      <name>RangerSheck</name>
    </author>
    <id>tag:rangersheck.com,2007-09-12:203</id>
    <published>2007-09-12T23:51:00Z</published>
    <updated>2007-09-13T00:00:28Z</updated>
    <category term="Game Design"/>
    <category term="PBBG"/>
    <category term="development"/>
    <category term="game design"/>
    <category term="game development"/>
    <category term="gamedev"/>
    <category term="web"/>
    <link href="http://rangersheck.com/2007/9/12/interface-design-in-a-pbbg-sound-familiar" rel="alternate" type="text/html"/>
    <title>Interface Design in a PBBG - Sound Familiar?</title>
<summary type="html">&lt;p&gt;Browser-Based Game designers, take note from some of the web-based app designers: the term &#8220;Look and Feel&#8221; means more than you think! Win back some of those players you frightened away by seeing your game through their eyes and giving them some familiarity to start with.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Browser-Based Game designers, take note from some of the web-based app designers: the term &#8220;Look and Feel&#8221; means more than you think! Win back some of those players you frightened away by seeing your game through their eyes and giving them some familiarity to start with.&lt;/p&gt;
&lt;h3&gt;Which came first?&lt;/h3&gt;


	&lt;p&gt;&lt;a href=&quot;http://flickr.com/photos/adobemac/161310004/&quot;&gt;&lt;img src=&quot;/assets/2007/9/12/chicken_egg.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;In the web-based application development communities, once in a while you see this kind of &lt;a href=&quot;http://en.wikipedia.org/wiki/Chicken_and_egg&quot;&gt;chicken and egg&lt;/a&gt; argument pop up. The question is, which design comes first, &lt;strong&gt;code&lt;/strong&gt; or &lt;strong&gt;interface&lt;/strong&gt;? A lot of solo developers like myself go right for the &lt;strong&gt;code&lt;/strong&gt;. After all, without a solid code design plan, with data models and business functionality, the application is useless. Google didn&#8217;t become the most popular search engine because it looked pretty; it works well, that&#8217;s how it became popular.&lt;/p&gt;


	&lt;p&gt;Your graphical people, of course, will go the other way. Google is the exception to the norm, they&#8217;ll tell you. Especially in today&#8217;s Web Too Oh world, first impression is key, because people can leave a website just as quickly as they arrive.&lt;/p&gt;


	&lt;p&gt;Of course, it&#8217;s more than just visual aesthetics. As websites move deeper into that &lt;a href=&quot;http://billhiggins.us/weblog/2007/05/17/the-uncanny-valley-of-user-interface-design/&quot;&gt;uncanny valley&lt;/a&gt; and look more and more like real-deal applications, designers and developers must take into consideration their site&#8217;s interact-ability. The key questions are: What does it look like from the client&#8217;s perspective? What does it feel like to the client?&lt;/p&gt;


	&lt;p&gt;So, I switched sides. Yes, I know &#8211; code base is very important. Data structure is very important. &lt;em&gt;However&lt;/em&gt;, let&#8217;s be frank &#8211; that&#8217;s the easy stuff. That&#8217;s the logical stuff. The hard part &#8211; the thing that sets you apart from everyone else (or makes you look the same) &#8211; is the interface. Not to mention, when you start your design from the interface side, you&#8217;ll find some things you would have missed. You think a lot harder about what it&#8217;s like to be in your client&#8217;s shoes.&lt;/p&gt;


	&lt;h3&gt;It talks like a duck, but walks like a Sasquatch&lt;/h3&gt;


	&lt;p&gt;&lt;a href=&quot;http://flickr.com/photos/chiceaux/85486910/&quot;&gt;&lt;img src=&quot;/assets/2007/9/12/sasquatch.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Familiarity is a design concept that becomes important here. The more your web-based application acts like real application, the more your clients are going to treat it like one. When they begin to recognize certain interface elements, they will start attempting to use other elements, like shortcuts, or they will start looking for familiar context menus, like the kind you get from right-clicking in a normal application. The moment they hit &lt;span class=&quot;caps&quot;&gt;CTRL&lt;/span&gt;-S expecting to save a record or a document and it doesn&#8217;t work, their trust in your site is broken. Their browser&#8217;s implementation for that key combo fires off and they are reminded once again that it&#8217;s not really a full blown application, it&#8217;s just a web site.&lt;/p&gt;


	&lt;p&gt;With browser-based games, the same problem exists. After all, computer games are nothing but &lt;em&gt;entertainment applications&lt;/em&gt;. As javascript, Flash, and other technologies allow web developers to create browser games that act more and more like full blown computer games (or even console or arcade games), we&#8217;re running into that &lt;em&gt;familiarity&lt;/em&gt; snag, but it&#8217;s &lt;strong&gt;two-fold&lt;/strong&gt;. Not only will your players be looking for familiar &lt;em&gt;interface&lt;/em&gt; elements, they will be looking for familiar &lt;em&gt;gameplay&lt;/em&gt; elements. Games are a lot more varied than business applications in both these respects, so it&#8217;s going to divide your client-base into two factions: (A) people that play tons of games and realize that every time they pick up a new game, they may have to learn some new gameplay concepts and they may have to master a new interface and (B) people that play only a few games and only really like something new when it closely resembles something they&#8217;ve seen before; if it doesn&#8217;t, then it better be something that&#8217;s not hard to learn or get the hang of.&lt;/p&gt;


	&lt;h3&gt;The Lost Players&lt;/h3&gt;


	&lt;p&gt;&lt;a href=&quot;http://flickr.com/photos/tea_time/1331769706/&quot;&gt;&lt;img src=&quot;/assets/2007/9/12/lost_cart.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;The big problem is, those people in that second group &#8211; that&#8217;s the majority, and those people will walk away the fastest. I&#8217;ve seen people on dev boards say time and time again, &#8220;well, if it doesn&#8217;t look great but it&#8217;s fun to play, I&#8217;ll enjoy it&#8221;. That&#8217;s probably true for a lot of people, even people in group B &#8211; the problem is, most of them are leaving before they get a chance to find out that a game is &#8220;fun to play&#8221;. They&#8217;re not going to take the time to leave you feedback either and let you know what turned them off.&lt;/p&gt;


Let&#8217;s look at some possible reasons for new players to give up on your game within five minutes:
	&lt;ul&gt;
	&lt;li&gt;They got lost. Right from the beginning, they didn&#8217;t know what to do.&lt;/li&gt;
		&lt;li&gt;They thought they were getting into a game they would already know how to play (they were wrong).&lt;/li&gt;
		&lt;li&gt;They thought they were playing a game that would be &lt;em&gt;easy&lt;/em&gt; because it&#8217;s a game on the web (they were wrong).&lt;/li&gt;
		&lt;li&gt;They saw half-assed graphics and figured the game was unfinished and not worth their time.&lt;/li&gt;
		&lt;li&gt;They found little on-screen help and a separate manual consisting of tons of pages that were hard to read and probably uninteresting.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Some of these people, they&#8217;re on their coffee breaks, they&#8217;re killing time, they&#8217;ve got a meeting in 20 minutes; they&#8217;re looking to web-based games as a spend amounts of time in varied increments. Maybe they want to kill 10 minutes, maybe they want to kill an hour or two. If you hit them over the head with some interface that looks and acts like nothing they&#8217;ve ever seen before, and a game that plays like nothing they&#8217;ve seen before, they&#8217;re going to get frustrated and look for something easier.&lt;/p&gt;


	&lt;h3&gt;The Balancing Act&lt;/h3&gt;


	&lt;p&gt;&lt;a href=&quot;http://flickr.com/photos/55192999@N00/436033119/&quot;&gt;&lt;img src=&quot;/assets/2007/9/12/balancing.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Obviously, we don&#8217;t want to make cookie cutter games that all look and feel the same way. I&#8217;m suggesting that when you can create familiarity, you create comfort, and you alleviate frustration. When you can&#8217;t make an element familiar, whether it&#8217;s an interface element or a gameplay element, then make sure it&#8217;s easy. Easy to use, easy to understand &#8211; look at it from the perspective of someone else (someone who&#8217;s not a developer). The key is to find that balance between the unique and the familiar.&lt;/p&gt;


	&lt;p&gt;Many games pride themselves on their &lt;em&gt;depth&lt;/em&gt;. Too much complexity translates to a bunch of white noise, static, to the first time player. When you want to add complexity, do it in bite-sized increments &#8211; open up features one at a time to players after they get comfortable with the basics. During development, only add new features when you&#8217;re sure the simpler parts are solid. Honestly, it&#8217;s better to have a few concepts that work really well and look really good than a whole box of unfinished pieces (with lots of &#8220;potential&#8221;).&lt;/p&gt;


	&lt;p&gt;And definitely don&#8217;t hit your players with all the information available up front, let them discover some things on their own &#8211; it&#8217;s part of the reward of playing a &lt;strong&gt;Persistent&lt;/strong&gt; BBG.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://rangersheck.com/">
    <author>
      <name>RangerSheck</name>
    </author>
    <id>tag:rangersheck.com,2007-06-04:3</id>
    <published>2007-06-04T05:02:00Z</published>
    <updated>2007-06-24T16:18:17Z</updated>
    <category term="Game Design"/>
    <category term="crpg"/>
    <category term="game design"/>
    <category term="gaming"/>
    <category term="mmorpg"/>
    <category term="role playing game"/>
    <category term="rpg"/>
    <link href="http://rangersheck.com/2007/6/4/the-death-penalty-handling-defeat-in-crpg-design" rel="alternate" type="text/html"/>
    <title>The Death Penalty - Handling Defeat in CRPG Design</title>
<content type="html">
            &lt;p&gt;&lt;img src=&quot;/assets/2007/6/4/terminator_robot_sm.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Computer Role-Playing Games are notorious for lacking in actual &#8216;Role-Playing&#8217;.&lt;/strong&gt; Your typical hack-n-slash &lt;span class=&quot;caps&quot;&gt;CRPG&lt;/span&gt; takes the mechanical concepts behind pencil-and-paper role-playing games and automates them, giving these games a much greater focus on combat more than anything else. Once the mathematical base of a &lt;span class=&quot;caps&quot;&gt;CRPG&lt;/span&gt; is established, often times the role-playing aspect is grafted on afterward, like fake skin on a robot. On the surface, it looks like a role-playing game, but underneath beats the gear-filled heart of a cold, calculating mechano-man.&lt;/p&gt;


	&lt;p&gt;Due to the combat-centric nature of most CRPGs, &lt;strong&gt;one of most malformed aspects of their &#8216;role-play&#8217; is Death.&lt;/strong&gt; CRPGs provide faster and more plentiful combat, which inevitably leads to a great deal more death than a pencil-and-paper RP session. Depending on the game setting, unchecked death of both non-player and player characters alike can really distort any kind of believable storyline. Many CRPGs go out of their way to explain the use of magic and divine intervention in their settings, but most of the time not only is the death of character usually extremely temporary, character &#8220;respawning&#8221; is generally flimsily explained (if at all). Non-player death fits into two categories: either non-player entities stay dead once killed, never to be heard of again, nor have their deaths questioned by anyone else; or upon death some cosmic timer ticks over and respawns them periodically.&lt;/p&gt;


	&lt;p&gt;I&#8217;d like to talk about the abuse of death and non-player entities some time, but today I want to focus on player death. In a pencil-and-paper &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt;, death is usually permanent. If you have a generous Game Master, there may be ways around it, but chances are pretty good that there&#8217;s going to be a creative plot-line to go along with any form of resurrection. In a single-player &lt;span class=&quot;caps&quot;&gt;CRPG&lt;/span&gt;, death is usually pseudo-permanent; I say pseudo because you can always reload a saved game. If the game is party-based, then you may have that typical flimsily-constructed method of resurrection (e.g. take them to church and say a little prayer/pay a little cash and presto, alive again).&lt;/p&gt;


	&lt;p&gt;In an online &lt;span class=&quot;caps&quot;&gt;CRPG&lt;/span&gt;, you don&#8217;t have the luxury of reloading a saved game. To keep people from just giving up, game designers need a way for players to respawn. &lt;strong&gt;Let&#8217;s face it, no one is going to keep coming back to a game if they have to make a new character every time they die.&lt;/strong&gt; The old telnet-based MUDs set the standard for player respawning &#8211; upon death, you found yourself back in your home town (usually in a church or other sanctuary). You probably lost a level and all of your equipment and maybe even your gold. Banks became extremely important to players that needed to get back into the game after a death and may have stashed extra equipment and money. MMORPGs started out following the &lt;span class=&quot;caps&quot;&gt;MUD&lt;/span&gt; standards; however, as time goes on, MMORPGs attract more players who have less and less gaming experience (RPG or otherwise), and have subsequently softened the blow of Death, so to speak. In many MMORPGs, dying does not result in loss of equipment or skills or levels or whatever. A player may lose &#8220;experience points&#8221;, or in some cases merely acquire an &#8220;experience debt&#8221; that has to be worked off.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/2007/6/4/underworld.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;In many cases, whatever the Death Penalty, &lt;strong&gt;player revival typically goes unexplained.&lt;/strong&gt; In your average fantasy &lt;span class=&quot;caps&quot;&gt;MMORPG&lt;/span&gt;, you die, you respawn at some kind of &#8220;home point&#8221;, and maybe you have to sit out some &#8220;death effects&#8221;. No one lets you know which god kindly plucked your body out of one place and trans-dimensionally reconstituted it in another place, dusting you off, patting your behind and wishing you well on your next adventure. A notable exception to this norm (speaking primarily of fantasy-based MMORPGs) is PlaneShift, in which if you die you awaken in the underworld. Not much explanation is needed for that situation, and I think it&#8217;s a creative way to deal with death. That being said, if you&#8217;re not familiar with the game, navigating your way out of the maze-like underworld can take you nearly an hour (unless you&#8217;re lucky enough to run into another lost soul who knows where they are going).&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;What&#8217;s a computer role-playing game designer to do?&lt;/strong&gt; History shows us that any integration of player death/resurrection and a believable role-playing storyline ain&#8217;t gonna happen. So we expect players to accept resurrection (with weapons and armor still in tact) as a run-of-the-mill activity. &lt;em&gt;Happens all the time, no big deal.&lt;/em&gt; They accept magic and monsters and all the rest of it, why should we focus on believable death scenarios?&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/2007/6/4/skeletor.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Sadly, &lt;strong&gt;we&#8217;re forced to resort to using death as a venue for penalizing a player&lt;/strong&gt; for biting off more than they can chew. This is the part where role-playing collides with game-play. The more you attempt to incorporate story-like role-playing into character death and recovery, the harder the game becomes. When death is frustrating, players quit, and with persistent online games, the loss of a player is the loss of regular revenue. So designers are forced to turn their backs on role-playing to compensate. In my opinion, as the years go by many games have over-softened the Death Penalty. This is especially true of MMORPGs, who prefer to keep players no matter what and often sacrifice &lt;strong&gt;challenge&lt;/strong&gt; for &lt;strong&gt;revenue.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;When I was in the initial planning stages of design for &lt;a href=&quot;http://aethora.com&quot;&gt;Pioneers of Aethora&lt;/a&gt;, I had a bug up my butt over the ever-weakening Death Penalty I&#8217;d seen in MMORPGs. In my game design, a player has a collection of eight characters, four of which can be placed into an active party at any given time. You go into combat with your four characters, facing off against a group of non-player characters. Winner takes all. The role-playing explanation is that defeat means surrender, and the victors should strip everything away from the defeated, no matter which side wins. The losers walk away empty-handed. Sounds fair, right? And &lt;strong&gt;I got out of trying to explain death, because no one actually dies!&lt;/strong&gt; Meanwhile, since you have eight characters total, you can bench injured characters and give them a rest while you play with fresh characters. No divine intervention or beam-me-back-to-town tricks called for. I thought I had the role-playing aspect and the death penalty nicely wrapped up.&lt;/p&gt;


	&lt;p&gt;Of course, &lt;strong&gt;there were a couple problems.&lt;/strong&gt; First of all, defeated characters lost all their equipment &#8211; not just what they were wearing and wielding, but what they had in their inventories as well. Since there is no bank (as of yet) in Aethora, the only way to stash extra equipment is to move it around and make sure it&#8217;s not in the inventory of any active characters. Obviously, this kind of stock-piling is quite the pain in the neck &#8211; but failing to do so would result in a player losing a ton of equipment in a defeat. Secondly, there is no way to judge what the ability of your opponents will be before you jump into a battle &#8211; in some areas, the encounters occur randomly without your choice to engage. This problem makes it possible for players to end up in combat they could never win. Finally, &lt;strong&gt;there was no way to retreat from battle.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Some players just dealt with these issues. Other players I believe accepted the penalty for what it was, but I fear many may have lost interest in the game along the way in unspoken frustration or perhaps even boredom &#8211; acquiring new equipment might mean going back to fighting enemies well below the player&#8217;s challenge level. One player (who happens to be a real life friend of mine) suddenly became extremely vocal about the issue a few weeks ago, and I decided to reevaluate my game&#8217;s Death Penalty. After mulling over the possibilities, I came up with some options that I feel provide some kind of balance to those &lt;strong&gt;ever-conflicting forces: role-playing, challenge, and player enjoyment.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;First off, I changed the loss of equipment to be only the equipment being worn and wielded by the characters upon defeat. The non-player characters aren&#8217;t carrying unused equipment around anyway, so it still seems fair. The RP explanation? The victors can only walk away with so much stuff, so they assume your best gear is the gear you went into battle with. Secondly, adding the ability to flee from battle was essential. There is no real role-playing reason for keeping this feature out of the game, my reason was purely mechanical. In &lt;em&gt;Pioneers of Aethora&lt;/em&gt;, skills are earned in real-time during combat &#8211; you take a swing with a sword, you have a chance of increasing your sword skill right at that moment. So my concern was that allowing players to flee from battle might entice some players to go into fights and notch up a few skills, then run off. Therefore, in order to maintain some challenge, fleeing characters lose a few skill points.&lt;/p&gt;


	&lt;p&gt;It&#8217;s actually worked out rather well so far. If a player senses defeat, they can choose whether they will lose equipment or skill points on a character-by-character basis. Since the fleeing option has been implemented, I&#8217;ve seen it used quite often. What&#8217;s encouraging is that a player who flees from battle often enters another battle somewhere else shortly afterward &#8211; a sign that the death penalty is not deterring defeated players from continuing play.&lt;/p&gt;


	&lt;p&gt;The party-system in &lt;em&gt;Pioneers of Aethora&lt;/em&gt; plays a large role in making &lt;strong&gt;defeat&lt;/strong&gt; play well with &lt;strong&gt;role-play.&lt;/strong&gt; MMORPGs and other CRPGs don&#8217;t have that luxury if a player represents just one character, but can&#8217;t they do better than &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;RETURNING TO HOME POINT&lt;/span&gt;&lt;/strong&gt;?&lt;/p&gt;


	&lt;p&gt;(if you&#8217;ve held on to the story this long and want to read the short blurb I wrote for the players, it&#8217;s in &lt;a href=&quot;http://docs.aethora.com/2007/6/3/june-update&quot;&gt;this update&lt;/a&gt;, with links to more details in the in-game forums. Registration required to read the in-game forums.)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://rangersheck.com/">
    <author>
      <name>RangerSheck</name>
    </author>
    <id>tag:rangersheck.com,2007-05-29:2</id>
    <published>2007-05-29T18:29:00Z</published>
    <updated>2007-06-24T17:06:42Z</updated>
    <category term="PBBG"/>
    <category term="browser-based"/>
    <category term="development"/>
    <category term="PBBG"/>
    <link href="http://rangersheck.com/2007/5/29/pbbg-persistent-browser-based-games" rel="alternate" type="text/html"/>
    <title>PBBG - Persistent Browser-Based Games</title>
<content type="html">
            &lt;p&gt;Today I learned a new acronym: &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;PBBG&lt;/span&gt;&lt;/strong&gt;. Persistent Browser-Based Game. Acronyms are great because they are these kind of self-importing entities that have the potential to carve something substantial into the world&#8217;s vocabulary. Just by the very act of instantiating a new acronym, you&#8217;ve taken the first step towards establishment, acceptance, and eventually, &lt;em&gt;household knowledge&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Ok, maybe that&#8217;s a bit extreme, but one thing you can say about an acronym &#8211; the subject of an acronym is being talked about enough and with enough consistency to warrant abbreviation.&lt;/p&gt;


	&lt;p&gt;I&#8217;m here to embrace &lt;span class=&quot;caps&quot;&gt;PBBG&lt;/span&gt;. I happen to be the sole developer of a &lt;span class=&quot;caps&quot;&gt;PBBG&lt;/span&gt; (a label I applied just today, of course) called &lt;a href=&quot;http://aethora.com&quot; title=&quot;Pioneers of Aethora&quot;&gt;Pioneers of Aethora&lt;/a&gt; (more about that later). It&#8217;s actually an extreme convenience for this acronym to come along. I&#8217;ve been googling about, trying to find suitable testers for my game, and lemme tell ya &#8211; it&#8217;s hard to nail down what a &lt;span class=&quot;caps&quot;&gt;PBBG&lt;/span&gt; is. You&#8217;ve got your web-based games, probably 99% of which are Flash-based and are most definitely &lt;em&gt;not&lt;/em&gt; &lt;em&gt;persistent&lt;/em&gt; (unless you count scoreboards). Then there&#8217;s &#8220;online RPGs&#8221;, which typically lands you in &lt;span class=&quot;caps&quot;&gt;MMORPG&lt;/span&gt;-dreaming land. Or you can try &#8220;Indie games&#8221;, which will probably help you find some great sites and forums, but I&#8217;ve noticed that&#8217;s these places are usually looking at downloadable/installable games (they&#8217;re usually receptive to web-based games to some degree, but it&#8217;s not their focus). Lastly, trying to search on anything too generic with &#8220;rpg&#8221; in it drums up a whole lotta stuff about Pen and Paper RPGs (including independently produced P&amp;amp;P RPGs, which I would have found extremely cool at one time).&lt;/p&gt;


	&lt;p&gt;So what exactly is a &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;PBBG&lt;/span&gt;&lt;/em&gt;? Well, there&#8217;s a definition at &lt;a href=&quot;http://pbbg.com/&quot;&gt;http://pbbg.com/&lt;/a&gt; that&#8217;s pretty good. Essentially, we&#8217;re talking a game that you play in your browser; as in &lt;em&gt;no installable/executable&lt;/em&gt;. But it&#8217;s not one of these puzzle/casual/action/arcade kinds of games where you play, get a score, try to beat your score, get addicted, try to beat everyone else&#8217;s score, etc. Instead, the game is &lt;em&gt;persistent&lt;/em&gt;. Typically, this means it&#8217;s going to be a role-playing game of some kind. You create a character (or characters, or a kingdom, or a pet monster), you play a little, you go away, you come back tomorrow and pick up where you left off.&lt;/p&gt;


	&lt;p&gt;It&#8217;s the pretty standard concept behind an &lt;span class=&quot;caps&quot;&gt;RPG&lt;/span&gt;, but I&#8217;m glad someone created this acronym to distinguish these browser-based RPGs from other web-based games, and as well from non-browser based &#8220;online/multiplayer&#8221; RPGs.&lt;/p&gt;


	&lt;p&gt;It&#8217;s not just the name, or the acronym, however, that makes me happy about this; it&#8217;s the fact that we&#8217;re witnessing a new gaming genre being established. Sure, it may be yet another spinoff or sub-genre of some pre-existing concepts, but the scaffolding for this &lt;span class=&quot;caps&quot;&gt;PBBG&lt;/span&gt; genre has some very unique and exciting characteristics. The last couple years have been all about Web 2.0, and while it&#8217;s hard to distinguish hype from reality, there are aspects of Web 2.0 that lend themselves very nicely to web-based gaming.&lt;/p&gt;


Let&#8217;s consider some of the hurdles an independent game developer faces when constructing a game.
&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;UI development&lt;/em&gt;. Personally, I&#8217;ve started work on a few games myself that began as text-based, and when it came time to start adding a graphical interface, well&#8230; that just steepened my learning curve a bit, didn&#8217;t it? With a web-based game, you can do a hellavalotta presentation with &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt;, and when you need to, javascript can fill in the cracks.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Data retention&lt;/em&gt;. Serializing classes and writing them to files, reading them later, trying to keep them indexed, etc. I never got very far with that part either. With a &lt;span class=&quot;caps&quot;&gt;PBBG&lt;/span&gt;, you&#8217;re most likely developing with a language that has built-in hooks into any database you could think of (not to mention memory caching options).&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;Networking.&lt;/em&gt; I never got this far with any of my games. I had a lot of spectacular plans, lemme tell ya, but it wasn&#8217;t gonna happen. Obviously, not an issue in PBBGs &#8211; you get the networking for free.&lt;/li&gt;
&lt;/ul&gt;
There&#8217;s probably other stuff I&#8217;m not thinking of. All this &lt;span class=&quot;caps&quot;&gt;PBBG&lt;/span&gt; talk makes me think there are others out there just like me &#8211; big aspirations for developing a game independently, but too many obstacles. Now I&#8217;ve got &lt;a href=&quot;http://aethora.com&quot; title=&quot;Pioneers of Aethora&quot;&gt;this game&lt;/a&gt; that&#8217;s downright playable. The progress of web technology has given us a new platform, a new sandbox to play in, where our unrealistic and perpetually unfinished projects can get closer to actuality. Just like the youtubers who suddenly discovered that they too could film a video and share it with thousands of people, we&#8217;re realizing that we can develop our own multiplayer, networked, persistent games.

	&lt;p&gt;And we don&#8217;t have to use C. Or C++. Or C#. Or (as Q-Bert would say) C#$%^&amp;amp;.&lt;/p&gt;


	&lt;p&gt;Have &lt;a href=&quot;http://kingdomofloathing.com&quot; title=&quot;Kingdom of Loathing&quot;&gt;Kingdom of Loathing&lt;/a&gt; and &lt;a href=&quot;http://neopets.com/&quot; title=&quot;Neopets&quot;&gt;Neopets&lt;/a&gt; paved the way for a gaming revolution? Or just another cool acronym? Here&#8217;s hoping it&#8217;s both.&lt;/p&gt;
          </content>  </entry>
</feed>
