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

<channel>
	<title>NPCT &#187; Gaming</title>
	<atom:link href="http://www.nonperiodic.net/blog/category/computing/gaming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nonperiodic.net/blog</link>
	<description>Nonperiodic Central Trajectory</description>
	<lastBuildDate>Tue, 07 Apr 2009 03:01:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Rock Band &#8211; Best Cooperative Game Ever</title>
		<link>http://www.nonperiodic.net/blog/2008/05/07/rock-band-best-cooperative-game-ever/</link>
		<comments>http://www.nonperiodic.net/blog/2008/05/07/rock-band-best-cooperative-game-ever/#comments</comments>
		<pubDate>Wed, 07 May 2008 15:19:33 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/?p=389</guid>
		<description><![CDATA[Our downstairs neighbors, who are our very very good friends are moving away. They&#8217;re huge karaoke addicts and so we got them a fun parting gift: Rock Band for the PS2. This game is so much fun, it&#8217;s painful. Obviously, I know people have liked it, and Guitar Hero has been a big hit, but [...]]]></description>
			<content:encoded><![CDATA[<p>Our downstairs neighbors, who are our very very good friends are moving away.  They&#8217;re <b>huge</b> karaoke addicts and so we got them a fun parting gift: <a href="http://www.amazon.com/gp/product/B000WPYNJC/002-8373580-3781643?ie=UTF8&#038;tag=nonperiodicce-20&#038;linkCode=xm2&#038;camp=1789&#038;creativeASIN=B000WPYNJC">Rock Band for the PS2</a>.  This game is so much fun, it&#8217;s painful.  Obviously, I know people have liked it, and Guitar Hero has been a big hit, but I&#8217;ve never tried it.  What&#8217;s really, really neat, though is that it is the best cooperative gaming setup I&#8217;ve ever seen.  With the exception of minigames in Mario Party type games, cooperative play is pretty meager over all.  In Rock Band, however, everyone is on equal footing and contributing to the experience.  It&#8217;s pretty awesome.  We pulled it out at a little house party and <b>everyone</b> jumped in.  We&#8217;re planning a &#8220;battle of the bands&#8221; at an upcoming party where the bands are selected out of a hat and everyone has to do each instrument for at least one song.  It should be pretty hilarious.  The only disappointment is that all of the new downloadable content won&#8217;t be available for the PS2 version.  We&#8217;re already itching for new songs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/05/07/rock-band-best-cooperative-game-ever/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Video Card Ugliness</title>
		<link>http://www.nonperiodic.net/blog/2008/05/02/video-card-ugliness/</link>
		<comments>http://www.nonperiodic.net/blog/2008/05/02/video-card-ugliness/#comments</comments>
		<pubDate>Fri, 02 May 2008 15:03:15 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/?p=387</guid>
		<description><![CDATA[I have this fairly nice setup for my home office, since I work from home more or less exclusively. I like to play the occasional PC game, so I have a reasonable video card setup. I had two eVGA 7600GT video cards in an SLI configuration. Well, this all turned sour last Saturday. I pulled [...]]]></description>
			<content:encoded><![CDATA[<p>I have this fairly nice setup for my home office, since I work from home more or less exclusively.  I like to play the occasional PC game, so I have a reasonable video card setup.  I had two <a href="http://www.evga.com/products/moreinfo.asp?pn=256-P2-N550-AX">eVGA 7600GT</a> video cards in an <a href="http://en.wikipedia.org/wiki/Scalable_Link_Interface">SLI</a> configuration.  Well, this all turned sour last Saturday.  I pulled out the cards and&#8230;<br />
<center><br />
<a href='http://www.nonperiodic.net/blog/wp-content/uploads/2008/05/7600gt-1.jpg'><img src="http://www.nonperiodic.net/blog/wp-content/uploads/2008/05/7600gt-1-300x189.jpg" alt="Two broken eVGA 7600GT cards" title="7600gt-1" width="300" height="189" class="alignnone size-medium wp-image-383" /></a><a href='http://www.nonperiodic.net/blog/wp-content/uploads/2008/05/7600gt-2.jpg'><img src="http://www.nonperiodic.net/blog/wp-content/uploads/2008/05/7600gt-2-300x225.jpg" alt="Two broken eVGA 7600GT video cards" title="7600gt-2" width="300" height="225" class="alignnone size-medium wp-image-384" /></a><br />
</center><br />
Can you see the problem?  Here&#8217;s a pair of close-ups:<br />
<center><br />
<a href='http://www.nonperiodic.net/blog/wp-content/uploads/2008/05/7600gt-3.jpg'><img src="http://www.nonperiodic.net/blog/wp-content/uploads/2008/05/7600gt-3-300x225.jpg" alt="Two broken eVGA 7600GT video cards." title="7600gt-3" width="300" height="225" class="alignnone size-medium wp-image-385" /></a><a href='http://www.nonperiodic.net/blog/wp-content/uploads/2008/05/7600gt-4.jpg'><img src="http://www.nonperiodic.net/blog/wp-content/uploads/2008/05/7600gt-4-300x225.jpg" alt="Busted capacitors on a 7600GT" title="7600gt-4" width="300" height="225" class="alignnone size-medium wp-image-386" /></a><br />
</center><br />
So I ordered an upgrade (no SLI this time around, since I&#8217;m having to pay for it myself) of a <a href="http://www2.pny.com/8800-GT-512MB-PCIe-20-P2562C269.aspx">PNY 8800GT</a>.  It seems pretty nice and was only about $150 after rebate from <a href="http://www.newegg.com/">Newegg</a>.  I was tempted to go back to eVGA, but I had a pretty bad experience with them when I was setting this box up.  I decided to branch out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/05/02/video-card-ugliness/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>XML Stream Parsing in Erlang, II</title>
		<link>http://www.nonperiodic.net/blog/2008/02/19/xml-stream-parsing-in-erlang-ii/</link>
		<comments>http://www.nonperiodic.net/blog/2008/02/19/xml-stream-parsing-in-erlang-ii/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 21:37:13 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/02/19/xml-stream-parsing-in-erlang-ii/</guid>
		<description><![CDATA[In my previous post, I complained a lot about trying to get XML stream parsing working. Ultimately, I just decided to rip the guts out of ejabberd, rather than reinvent the wheel. The relevant files are xml_stream.erl, xml.erl, and expat_erl.c. You can see how to use it in ejabberd_receiver.erl. Frankly, these guys seem to have [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/">my previous post</a>, I complained a lot about trying to get XML stream parsing working.  Ultimately, I just decided to rip the guts out of ejabberd, rather than reinvent the wheel.  The relevant files are <a href="https://forge.process-one.net/browse/ejabberd/trunk/src/xml_stream.erl">xml_stream.erl</a>, <a href="https://forge.process-one.net/browse/ejabberd/trunk/src/xml.erl">xml.erl</a>, and <a href="https://forge.process-one.net/browse/ejabberd/trunk/src/expat_erl.c">expat_erl.c</a>.  You can see how to use it in <a href="https://forge.process-one.net/browse/ejabberd/trunk/src/ejabberd_receiver.erl">ejabberd_receiver.erl</a>.  Frankly, these guys seem to have it pretty well figured out.  The way I went about it is this: using the tcp-client <code>gen_fsm</code> from <a href="http://www.trapexit.org/Building_a_Non-blocking_TCP_server_using_OTP_principles">here</a>, I added init code to load up the library in start_link, with something like this:<br />
<verbatim><br />
    case erl_ddll:load_driver(&#8220;ebin&#8221;, expat_erl) of<br />
        ok -> ok;<br />
        {error, already_loaded} -> ok;<br />
	{error, Reason} -><br />
	    error_logger:error_msg(&#8220;Could not load expat driver: ~p~n&#8221;,<br />
				   erl_ddll:format_error(Reason))<br />
    end<br />
</verbatim><br />
I added a bit to the fsm state record to manage the xml state.  When a client connects and the process gets started for it in the <code>'WAIT_FOR_SOCKET'({socket_ready, Socket}, State) when is_port(Socket)</code> call, I initialize the xml parser <code>xml_stream:new(self())</code> and store that in the record.  Upon receiving data in <code>'WAIT_FOR_DATA'({data, Data},</code>, I call <code>NewXmlState = xml_stream:parse(XmlState, Data)</code> and update the record with the new state.  Then, messages just appear in the fsm queue and I handle them.  What I do, specifically, is set up another fsm and send it messages that have been parsed, so that it essentially abstracts away the tcp and the xml.  My plan is to add udp functionality that uses the same interface, so that datagrams look just like stanza&#8217;d messages and the process doesn&#8217;t need to know where the data came from.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/02/19/xml-stream-parsing-in-erlang-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML Stream Parsing in Erlang</title>
		<link>http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/</link>
		<comments>http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 22:53:20 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/</guid>
		<description><![CDATA[There&#8217;s a lively debate out there about how one should communicate with clients in a game, in particular UDP vs TCP. I won&#8217;t go into details about it, but you can read a lively debate here. The choice for my ridiculous game is TCP+UDP. I want to use TCP for various communications where I want [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a lively debate out there about how one should communicate with clients in a game, in particular UDP vs TCP.  I won&#8217;t go into details about it, but you can read a lively debate <a href="http://www.gamedev.net/community/forums/topic.asp?topic_id=319003">here</a>.  The choice for my ridiculous game is TCP+UDP.  I want to use TCP for various communications where I want reliability, and UDP for fast updates that can afford to be lost.  I don&#8217;t want to deal with having to build a reliable application protocol on top of UDP.  I like the idea that a player is connected to a game or not, and I can encapsulate that idea with TCP.</p>
<p>So, I decided that a good first step would be to implement a simple TCP server in Erlang, extending what I introduced <a href="http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/">in</a> <a href="http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-ii/">previous</a> <a href="http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-iii/">posts</a>. There are various examples out there, but I decided to follow &#8220;<a href="http://www.trapexit.org/Building_a_Non-blocking_TCP_server_using_OTP_principles">Building a Non-blocking TCP server using OTP principles</a>&#8221; on TrapExit.  Not too hard to do, and theoretically implements an echo server.  However, one gotcha is that when you setup the socket, you&#8217;ll use lots of <code>{packet, 2}</code> options and I didn&#8217;t realize at first that this is an application-layer thing that helps Erlang decide when to throw you an event.  So you <b>will not</b> be able to just log into telnet and bounce things off of your server, because telnet won&#8217;t know to include the packet length.  It&#8217;s easy enough to do this in Perl, by prepending a packed message length to your message, but be forewarned.  The easiest thing to do is to replace it with <code>{packet, line}</code> and then it will maybe do what you&#8217;re expecting.</p>
<p>Frankly, I found this whole thing a bit annoying, because it wasn&#8217;t clear from the documentation that <code>gen_fsm</code> was going to magically receive messages from the socket when data arrived.  But I eventually sorted this out and it seems to work okay.</p>
<p>Now what I want to do is to implement a simple XML-based protocol for my game.  The idea is that this will fit well with the finite state machine approach, and allows me to extend it to include new functionality pretty easily.  It&#8217;s not very good for bandwidth usage, but I don&#8217;t expect to send much data this way.  <a href="http://www.ejabberd.im/">ejabberd</a> is a good example of XML streaming in Erlang, and there are at least two libraries out there for parsing: <a href="http://www.erlang.org/doc/apps/xmerl/index.html">xmerl</a> (<a href="http://www.erlang.org/doc/apps/xmerl/index.html">User&#8217;s Guide</a>) and <a href="http://sourceforge.net/projects/erlsom/">erlsom</a>.  Since I want streamed parsing, I&#8217;ll need an event-based parser with something like SAX.  Neither of them have much documentation about event-driven usage (lack of documentation is starting to be my biggest problem with Erlang), but <a href="http://erlang.org/pipermail/erlang-questions/2007-February/025107.html">this thread</a> would imply that I&#8217;m better off with Erlsom.  Trying it out, however, it wouldn&#8217;t work without a complete document.  I want to implement something like the &#8220;stanzas&#8221; of XMPP.</p>
<p>Of course, for some reason, doing even the simplest things in Erlang is like pulling teeth.  I thought I&#8217;d play with xmerl to see if might do what I want.  I look at the sparse documentation, and at <a href="http://pragdave.pragprog.com/pragdave/2007/04/a_first_erlang_.html">this blog entry</a> and write the simplest possible program for parsing an xml file.<br />
<verbatim><br />
-module(lame).<br />
-include_lib(&#8220;xmerl/include/xmerl.hrl&#8221;).<br />
-export([ parsemo/0 ]).</p>
<p>parsemo() -><br />
    {Xml, Rest} = xmerl_scan:file(&#8220;foo.xml&#8221;),<br />
    io:format(&#8220;~p  ~p&#8221;, [Xml, Rest]).<br />
</verbatim><br />
foo.xml is just about the simplest thing you could imagine:<br />
<verbatim><br />
&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243; ?&gt;<br />
&lt;foo&gt;<br />
 bar<br />
&lt;/foo&gt;<br />
</verbatim></p>
<p>I try to run this thing, and get this:<br />
<verbatim><br />
Erlang (BEAM) emulator version 5.5.5 </p>
<p>Eshell V5.5.5  (abort with ^G)<br />
1> c(lame).<br />
{ok,lame}<br />
2> lame:parsemo().</p>
<p>=ERROR REPORT==== 18-Feb-2008::16:44:14 ===<br />
Error in process &lt;0.31.0> with exit value: {undef,[{xmerl_scan,file,["foo.xml"]},{lame,parsemo,0},<br />
{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]}</p>
<p>** exited: {undef,[{xmerl_scan,file,["foo.xml"]},<br />
                   {lame,parsemo,0},<br />
                   {erl_eval,do_apply,5},<br />
                   {shell,exprs,6},<br />
                   {shell,eval_loop,3}]} **<br />
</verbatim><br />
What the hell?  For one thing, there is almost no information about what is wrong.  This is a <b>huge</b> failing on the part of Erlang.  The error messages are ridiculous.  I <b>assume</b> that the problem is that it doesn&#8217;t know about xmerl and can&#8217;t resolve the function call.  It managed to load it just fine with the <code>include_lib</code>, but it doesn&#8217;t seem that it&#8217;s finding <code>xmerl_scan:file</code>.  I don&#8217;t even know where to begin, to figure out how to get Erlang to find the module.  I mean, am I insane?  This is the sort of thing that makes a tool a no-go for me.  I could write a streaming XML parser in Perl in about ten minutes.  I know this because I&#8217;ve done it before.  XML parsing is the sort of thing that should never have to be implemented in a modern development toolset &#8211; there should be clearly documented libraries with standard interfaces.</p>
<p>Taking a deep breath and looking at Section 6.7 of Joe Armstrong&#8217;s book, I see that this cryptic error message indicates one of four possible failure modes in trying to find <code>xmerl_scan:file</code>: 1) no module xmerl_scan, 2) xmerl_scan hasn&#8217;t been compiled, 3) xmerl_scan.beam can&#8217;t be found, 4) there are multiple versions of xmerl_scan floating around in the path.  I was under the impression that xmerl was included in the standard libraries.  I installed Erlang 5.5.5 via apt-get erlang-base-hipe (Ubuntu Gutsy), and it would seem that xmerl_scan is around, inasmuch as <code>man xmerl_scan</code> gives me the &#8220;docs.&#8221;  However, I&#8217;m not able to actually use it.</p>
<p>After much wringing of hands, I installed every erlang-related package I could find via apt-cache and eventually it seemed to work.  I have no idea what the problem was.  Now my silly parser outputs:<br />
<verbatim><br />
{xmlElement,foo,<br />
            foo,<br />
            [],<br />
            {xmlNamespace,[],[]},<br />
            [],<br />
            1,<br />
            [],<br />
            [{xmlText,[{foo,1}],1,[],&#8221;\n bar\n&#8221;,text}],<br />
            [],<br />
            &#8220;.&#8221;,<br />
            undeclared}  []<br />
</verbatim><br />
which is at least a step in the right direction.  When I try to run it on a partial string, however, we fail.  I think this is the behavior that xmerl intends to have.  I&#8217;m starting to think that implementing whatever ejabberd does is going to be the only way to resolve this, unfortunately.  So, I guess that&#8217;ll be next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting an Erlang Project, Part I</title>
		<link>http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/</link>
		<comments>http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/#comments</comments>
		<pubDate>Wed, 23 Jan 2008 04:05:27 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/</guid>
		<description><![CDATA[Per my previous post, I&#8217;m going to start a little Erlang project. I&#8217;ll call it &#8220;North Zulch,&#8221; or &#8220;NZ&#8221; in reference to the tiny little place where the family ranch is located. There are three things that I&#8217;ve had to solve over and over (or at least cut and paste over and over), in every [...]]]></description>
			<content:encoded><![CDATA[<p>Per <a href="http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/">my previous post</a>, I&#8217;m going to start a little Erlang project.  I&#8217;ll call it &#8220;North Zulch,&#8221; or &#8220;NZ&#8221;  in reference to the <a href="http://maps.google.com/maps?f=q&#038;hl=en&#038;geocode=&#038;time=&#038;date=&#038;ttype=&#038;q=North+Zulch,+TX&#038;ie=UTF8&#038;om=0&#038;ll=30.899279,-96.075783&#038;spn=0.209752,0.458679&#038;z=12&#038;iwloc=addr">tiny little place</a> where the family ranch is located.</p>
<p>There are three things that I&#8217;ve had to solve over and over (or at least cut and paste over and over), in every development project I&#8217;ve ever done.  These things are: build management, configuration, and logging.  These things have led me down every path one can imagine, in C/C++, Perl, Python and Java: <a href="http://www.gnu.org/software/make/">make</a>, <a href="http://ant.apache.org/">ant</a>, <a href="http://perldoc.perl.org/ExtUtils/MakeMaker.html">MakeMaker</a>, <a href="http://www.boost.org/">Boost</a>, <a href="logging.apache.org/log4j/">log4j</a>, <a href="http://log4cpp.sourceforge.net/">log4cpp</a>, <a href="http://commons.apache.org/configuration/">Commons Configuration</a>, whatever, I&#8217;ve probably tried to use it in a project at some point, and maybe rolled my own version as well.</p>
<p>So, the first thing I want to learn is how to manage a large project correctly in Erlang.  There seem to be two concepts for this sort of thing: <a href="http://www.erlang.org/doc/design_principles/applications.html">Applications</a> and <a href="http://www.erlang.org/doc/design_principles/release_structure.html">Releases</a>.  My understanding is that Applications let you bundle processes together into a coherent whole, while Releases let you make something &#8220;turn-key&#8221; and ready to run.  I should also mention that I want this to be a distributed project.  There are two basic reasons why you might want to have a distributed application: 1) reliability, and 2) scalability.  For the hypothetical MMO framework we want, we need both.  Sure, we don&#8217;t need the <a href="http://www.cincomsmalltalk.com/userblogs/ralph/blogView?showComments=true&#038;entry=3364027251">&#8220;Nine Nines&#8221;</a> of the telecom world, but if the MMO is successful people will want to get their fix, so maybe we want three nines.  Scalability is much more important.  Since we&#8217;re fantasizing anyway, let&#8217;s imagine that we want to be able to have around a million users on an unsharded world.  Obviously this is going to require a pretty hefty cluster of the sort of machines that are cheap to maintain and replace.  Anyway, regardless of the stupidity of these numbers, the point is that NZ needs to be a distributed application.</p>
<p>In practical terms, the most useful things I&#8217;ve seen for getting started have been <a href="http://www.kazmier.com/computer/port-howto/">this page</a> by Pete Kazmier, which talks about building an application using OTP principles, and <a href="http://www.trapexit.org/Building_An_OTP_Application">this page</a> at TrapExit, which has been down for several days.  Also, there seems to be a lot of stuff going on at <a href="http://www.erlware.org/erlware/index.html">Erlware</a>.  The goal there seems to be to make a unified system like <a href=" http://sourceware.org/autobook/">autotools</a> for making Erlang code available to the public.  That is a noble goal to be sure, but at this point <a href="http://www.erlware.org/tools/sinan/index.html">Sinan</a> and friends just seem like another learning curve to climb.  In addition, the only <a href="http://www.erlware.org/erlware/tutorial.html">tutorial</a> around for the build system claims that the tool is broken.</p>
<p>The TrapExit page says</p>
<blockquote><p>
You will need to download the reference build system for this tutorial, this can be found at www.erlware.org under downloads otp_base-vsn
</p></blockquote>
<p>but it doesn&#8217;t look to me like there&#8217;s a downloads section at <a href="http://www.erlware.org/">erlware.org</a>.  After some digging it appears that you can get the OTP base from <a href="http://code.google.com/p/otp-base/">Google Code</a>.  To complicate matters, there are two versions there.  It seems that <a href="http://otp-base.googlecode.com/files/otp_base-R1-1.tgz">otp_base-R1-1.tgz</a> is the stable release.  I untarred this file and got an <code>otp</code> directory and various directories beneath it.  I <code>cd otp/tools/utilities</code> and execute <code>./appgen north_zulch nz</code> (the first argument is the application name and the second argument is going to be prefixed to everything), which spewed out a bunch of osbcenities:</p>
<pre>
[: 11: ==: unexpected operator
[: 24: ==: unexpected operator
[: 18: ==: unexpected operator
[: 32: ==: unexpected operator
-- SNIP --
[: 18: ==: unexpected operator
[: 32: ==: unexpected operator
rm: missing operand
Try `rm --help' for more information.

north_zulch has been generated and placed under lib/north_zulch
north_zulch_rel has been generated and placed under release/north_zulch_rel
</pre>
<p>I'm on Ubuntu Gutsy Gibbon, and it turns out that these are because the shell scripts start with <code>#!/bin/sh</code> when they really want <code>#!/bin/bash</code>.  The error about <code>rm: missing operand</code> is because there's a command to remove Subversion directories and there aren't any in the tarball.  So I went through and changed the shebang line in <code>otp/tools/.appgen/subsitute.sh</code>, <code>otp/tools/.appgen/rename.sh</code>, and <code>otp/tools/utilities/appgen</code>.  Then I ran my command again and got</p>
<pre>
moving blank_app_rel.config.src to north_zulch_rel.config.src
moving blank_app_rel.rel.src to north_zulch_rel.rel.src
replacing %%APP_NAME%% with north_zulch in north_zulch_rel/north_zulch_rel.rel.src
moving ba_server.erl to nz_server.erl
moving ba_sup.erl to nz_sup.erl
moving blank_app.app.src to north_zulch.app.src
moving blank_app.appup.src to north_zulch.appup.src
moving blank_app.erl to north_zulch.erl
/home/rpa/Desktop/otp-diff2/tools/.appgen
replacing %%APP_NAME_UPPER_CASE%% with NORTH_ZULCH in north_zulch/Makefile
replacing %%APP_NAME_UPPER_CASE%% with NORTH_ZULCH in north_zulch/vsn.mk
replacing %%APP_NAME%% with north_zulch in north_zulch/src/Makefile
replacing %%APP_NAME_UPPER_CASE%% with NORTH_ZULCH in north_zulch/src/Makefile
replacing %%PFX%% with nz in north_zulch/src/Makefile
replacing %%APP_NAME%% with north_zulch in north_zulch/src/north_zulch.erl
replacing %%PFX%% with nz in north_zulch/src/north_zulch.erl
replacing %%PFX%% with nz in north_zulch/src/nz_sup.erl
replacing %%APP_NAME%% with north_zulch in north_zulch/src/nz_sup.erl
replacing %%PFX%% with nz in north_zulch/src/nz_server.erl
replacing %%APP_NAME%% with north_zulch in north_zulch/src/nz_server.erl
north_zulch has been generated and placed under lib/north_zulch
north_zulch_rel has been generated and placed under release/north_zulch_rel
</pre>
<p>which I am assuming means success.  As promised, this created directories <code>otp/lib/north_zulch</code> and <code>otp/release/north_zulch/rel</code> with various things beneath them.  A significant file here is <code>otp/lib/north_zulch/vsn.mk</code> which contains the version number.  I'm going to leave it at <code>1.0</code> for now.  In that same directory are <code>include</code> which are for shared macro and record definitions, and <code>src</code> where all the Erlang code files go.  Significantly, I'm going to include <code>north_zulch</code> and <code>nz</code> in everything I write here, but you'll obviously want to change that for your application.</p>
<p>In the <code>src</code> directory are various stubs.  The <code>north_zulch.erl</code> defines the "application callback module."  You can think of a callback module as an approximation to deriving from an asbract base class with virtual functions.  The function names are there, and they'll get called under certain well-defined circumstances.  It's up to you to make them do something reasonable.  There are three functions exported so that the application OTP module knows what to do with us.  <code>start/2</code> is called to get us going, <code>shutdown/0</code> is called to get us to end, and <code>stop/1</code> is called when we're all done. We look at these and compare them to the docs <a href="http://www.erlang.org/doc/design_principles/applications.html">here</a>.</p>
<pre>
start(Type, StartArgs) ->
    case nz_sup:start_link(StartArgs) of
	{ok, Pid} ->
	    {ok, Pid};
	Error ->
	    Error
    end.
</pre>
<p>We get two arguments.  <code>Type</code> is an atom that will generally be <code>normal</code> for non-distributed applications. The distributed case is more complicated, so we'll look at that later down the road.  We see that the default thing to do is to just try to run <code>nz_sup:start_link(StartArgs)</code> which starts up a Supervisor, regardless of the atom in <code>Type</code>.  This appears to be the only value that the <a href="http://www.erlang.org/doc/apps/kernel/index.html">spec</a> identifies in the non-distributed case, so we'll roll with it.  In any case, if all goes well, we have to return <code>{ok, Pid, State}</code>.  If <code>State</code> is left out, then it just uses <code>[]</code>.  We'll ignore <code>State</code> for now.  <code>Pid</code> is the process id of the main Supervisor, the boss.  If <code>start_link</code> (which we'll talk about in a sec) goes well, it gives us <code>Pid</code>.  The <code>stop/1</code> function is pretty trivial and is called after everything is done.  As far as I can tell, <code>shutdown/0</code> is not actually part of the Application interface, and is just a convenient way for you to shut down your application if you want to.  It just goes up and tells the Application module that it wants to be turned off:</p>
<pre>
shutdown() ->
    application:stop(north_zulch).
</pre>
<p>With that big file under our belt, we now look at <code>nz_sup.erl</code> which contains the code for the supervisor.  The <a href="http://www.erlang.org/doc/design_principles/sup_princ.html">Supervisor</a> (also, the <a href="http://www.erlang.org/doc/man/supervisor.html">spec</a>) is a great idea to build as a system primitive.  I think I've implemented it at least five times in various projects.  The basic idea is, manage some underlings and make sure they do their thing, while isolating yourself from their errors.  If one fails, start up another, modulo your configurable policy about such things.  The docs have more info on restart behaviors.  We export, for our own purposes, the function <code>start_link/1</code>, which got called by <code>start/1</code> in the previous file:</p>
<pre>
start_link(StartArgs) ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).
</pre>
<p>This just turns around and tells the Supervisor API that we want to be fired up as a supervisor callback module. <code>supervisor:start_link/3</code> has three arguments.  The first is a tuple that tells the Supervisor module who we are.  The first bit of the tuple can be <code>local</code> or <code>global</code>.  The second is the name of the appropriate callback module, which in this case is <code>?SERVER</code>.  What does that mean? Well, things that start with a question mark in Erlang are macros. Up at the top of the file is</p>
<pre>
-define(SERVER, ?MODULE).
</pre>
<p>which defines it.  <code>?MODULE</code> <a href="http://erlang.org/doc/reference_manual/macros.html">is a special one</a> with the module name.  Back to <code>start_link/3</code>, we also specify the name of the callback module - this one - using <code>?MODULE</code>, and any arguments we want to pass along to <code>init/1</code>, which is the other significant function we need to export to use the supervisor:</p>
<pre>
init([]) ->
    RestartStrategy    = one_for_one,
    MaxRestarts        = 1000,
    MaxTimeBetRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxTimeBetRestarts},

    ChildSpecs =
	[
	 {nz_server,
	  {nz_server, start_link, []},
	  permanent,
	  1000,
	  worker,
	  [nz_server]}
	 ],
    {ok,{SupFlags, ChildSpecs}}.
</pre>
<p>This is pretty much where all the guts of the supervisor's behavior are.  The one argument you get is whatever you handed to <code>start_link/3</code> before, so you could pass around various application data if you wanted.  We're not worrying about this at the moment, though, and we're just going to look at what this gets up to.  First off, we define some variables that control the supervisor's behavior. <code>RestartStrategy</code> determines what restarting should occur should a child fail.  If <code>MaxRestarts</code> failures occur before <code>MaxTimeBetRestarts</code> seconds, then all children are cancelled and the supervisor terminates itself.  We construct a list of child specifications, that in this case only contains one element: the specs for managing the <code>nz_server</code> process.   Within this specification are:</p>
<pre>
	 {nz_server,
	  {nz_server, start_link, []},
	  permanent,
	  1000,
	  worker,
	  [nz_server]}
</pre>
<p>The first component is a name that the supervisor uses to keep track of this child.  In this case, we use the term <code>nz_server</code>, since there's only one.  The second component is a Module-Function-Arguments triplet that tells the supervisor what function should be called in the child.  We're going to look at this later, but the function is <code>start_link/0</code> in the <code>nz_server</code> module.  The next argument can be <code>permanent</code>, <code>transient</code>, or <code>temporary</code> and specifies what should happen if it dies.  The fourth argument specifies how long we should wait around for a termination signal to be handled by a child.  We can create trees of supervisors, so the fifth argument specifies whether this is a worker or a supervisor itself.  The final element will generally be a single-element list with the name of the callback module of the worker, in this case <code>nz_server</code>.  We return a tuple with these two specs together and they tell the Supervisor how it should act, and how is should initialize its children.</p>
<p>The final source file we examine is <code>nz_server.erl</code>, which implements the application-specific work.  At the very top of the file, we see</p>
<pre>
-behaviour(gen_server).
</pre>
<p>which means that it implements the <a href="http://www.erlang.org/doc/man/gen_server.html">gen_server</a> (also, <a href="http://www.erlang.org/doc/design_principles/gen_server_concepts.html">here</a>) behaviour as a callback.  The callbacks we need to define for this module to do its thing are <code>init/1</code>, <code>handle_call/3</code>, <code>handle_cast/2</code>, <code>handle_info/2</code>, <code>terminate, and </code><code>code_change/3</code>.  Again, if you come from a background like C++ or Java, you can think of these approximately as virtual event-handling functions.  Rather than an <code>onMouseClick()</code> type override, we have various functions that are called when the server receives Erlang messages.  These are all exported so that the gen_server module can get to them.</p>
<p>There are also two interface functions that are defined that don't really have anything to do with gen_server.  The first is <code>start_link/0</code>, which we mentioned before.  This is called by the Supervisor to get things going:</p>
<pre>
start_link() ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
</pre>
<p>You can see that we immediately just hand control off to the generic server.  It takes a couple of arguments.  The first is a tuple that is like the previous <code>start_link</code> in that we're telling it to look for this module and to register a name locally.  The other "local" function is <code>stop/0</code> which provides an interface to shutting down gen_server by sending it an asynchronous message.  </p>
<p>To actually do anything interesting, we'll need to implement the gen_server functions.  I'll leave that to the next installment.  We'll also look at releases, configurations and logging, which is what we said we were after in the first place!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Off On an Erlang Adventure</title>
		<link>http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/</link>
		<comments>http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/#comments</comments>
		<pubDate>Tue, 22 Jan 2008 22:57:52 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/</guid>
		<description><![CDATA[I have decided for some reason that it would be fun to play with massively scalable systems. In particular, I thought it would be a hilarious waste of time to work on an MMO engine. I&#8217;m not sure why this seems like a good idea, given that I have more than enough on my plate [...]]]></description>
			<content:encoded><![CDATA[<p>I have decided for some reason that it would be fun to play with massively scalable systems.  In particular, I thought it would be a hilarious waste of time to work on an MMO engine.  I&#8217;m not sure why this seems like a good idea, given that I have more than enough on my plate as it is, but I justified it by saying that time that I might&#8217;ve spent <i>playing</i> a game will now be spent <i>creating</i> a game.  We&#8217;ll see how it goes.</p>
<p>For scalability, and for an excuse to learn something new, I thought I&#8217;d play with <a href="http://erlang.org">Erlang</a>.  Erlang is a functional programming language that is completely geared toward concurrency.  It&#8217;s not so fast with the number-crunching we&#8217;d expect to do with a game for physics and collision detection, but it is really well-suited for having zillions of semi-independent entities wandering around.  Hopefully we can figure out a way to offload hard core number crunching to C via an FFI interface of some kind, but we&#8217;ll cross that bridge when we get to it.  For now, I&#8217;m just trying to learn how to build a real-life application in Erlang.</p>
<p>Most of the documentation on Erlang seems to revolve around learning functional programming.  I feel pretty good about FP already, due to having taken <a href="http://sicp.csail.mit.edu/">6.001</a> back in the day.  Tutorials about implementing the factorial function in Erlang aren&#8217;t really what I&#8217;m looking for.  I&#8217;ve ordered <a href="http://www.amazon.com/gp/product/193435600X?ie=UTF8&#038;tag=nonperiodicce-20&#038;linkCode=xm2&#038;camp=1789&#038;creativeASIN=193435600X">Programming Erlang</a> from Amazon and it&#8217;s due to arrive on Friday, so hopefully that&#8217;ll get me going.  Stay tuned and maybe this will all be useful to you, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mario Party 8</title>
		<link>http://www.nonperiodic.net/blog/2007/12/30/mario-party-8/</link>
		<comments>http://www.nonperiodic.net/blog/2007/12/30/mario-party-8/#comments</comments>
		<pubDate>Sun, 30 Dec 2007 14:09:13 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2007/12/30/mario-party-8/</guid>
		<description><![CDATA[We got our Wii primarily as a party-game machine. I certainly enjoy my games, but tend to prefer the PC. We figured the Wii would be fun for when we&#8217;re hanging out with friends and family. This has certainly been the case, and we&#8217;ve enjoyed hours of Wii Sports at Thanksgiving and Christmas. To that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/B000LSJKAM?ie=UTF8&#038;tag=nonperiodicce-20&#038;linkCode=xm2&#038;camp=1789&#038;creativeASIN=B000LSJKAM"><img src="http://ecx.images-amazon.com/images/I/51QgCA4XxTL._AA280_.jpg" /></a><br />
We got our Wii primarily as a party-game machine.  I certainly enjoy my games, but tend to prefer the PC.  We figured the Wii would be fun for when we&#8217;re hanging out with friends and family.  This has certainly been the case, and we&#8217;ve enjoyed hours of Wii Sports at Thanksgiving and Christmas.  To that end, one of the first games we got was Mario Party 8, which is intended for this sort of party-game play.  It has been a bit disappointing however.  The minigames are a lot of fun, but the board game format that you have to play through can be a bit tedious.  The weird circus guy in the talking hat is creepy and there&#8217;s too much text that is difficult to turn off.  We just want a bunch of loosely strung together minigames that can be played with a beer in one hand.  Also, it seems like they cheaped out by not actually having the guy voice the text. Instead, it just prints it on the screen and he makes a chirping sound.  Also, we find ourselves wishing that we could play the game with our Miis.  I suppose it wouldn&#8217;t be &#8220;Mario&#8221; party if they did that, but I think the game would work a little better if everyone could play with the same Miis that we&#8217;ve been using for Wii Sports and Wii Play.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2007/12/30/mario-party-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HL2 Deathmatching</title>
		<link>http://www.nonperiodic.net/blog/2007/11/29/hl2-deathmatching/</link>
		<comments>http://www.nonperiodic.net/blog/2007/11/29/hl2-deathmatching/#comments</comments>
		<pubDate>Thu, 29 Nov 2007 14:33:30 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2007/11/29/hl2-deathmatching/</guid>
		<description><![CDATA[Over the past several months, I&#8217;ve found myself enjoying a good bit of Half Life 2 Deathmatch. It&#8217;s nothing complicated, just good fun running around getting as many frags as you can. Most maps give you access to the majority of the HL2 weapons, including the gravity gun. It&#8217;s quite fun to run around with [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past several months, I&#8217;ve found myself enjoying a good bit of Half Life 2 Deathmatch.  It&#8217;s nothing complicated, just good fun running around getting as many frags as you can.  Most maps give you access to the majority of the HL2 weapons, including the gravity gun.  It&#8217;s quite fun to run around with the grav gun and get kills with toilets and whatnot.  My favorite approach is to toss down a grenade and then quickly switch to the gravity gun and pick it up, hold it for a sec and then shoot it at your opponent.  You can often get a multikill this way.  I&#8217;ve been playing on the <a href="http://www.skulshock.com/">Skul&#8217;Shock</a> and <a href="http://www.soulsinexile.com/">Souls In Exile</a> servers and the folks on both of those have been a lot of fun to play with.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2007/11/29/hl2-deathmatching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Review: Wii Play</title>
		<link>http://www.nonperiodic.net/blog/2007/11/13/wii-play/</link>
		<comments>http://www.nonperiodic.net/blog/2007/11/13/wii-play/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 16:38:40 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2007/11/13/wii-play/</guid>
		<description><![CDATA[When I bought our Wii a couple of weeks ago, I immediately bought Wii Play, because friends had told me that while the game is not worth $50, you effectively get the game for $10 if you were going to buy another remote anyway. This pretty much sums things up. The games are not all [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/B000KRXAGE?ie=UTF8&#038;tag=nonperiodicce-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=B000KRXAGE"><img /><img src="http://ecx.images-amazon.com/images/I/31ZQ3sVgx3L._AA_SL160_.jpg" border="0" alt="" /></a>When I bought our Wii a couple of weeks ago, I immediately bought <a href="http://www.amazon.com/gp/product/B000KRXAGE?ie=UTF8&#038;tag=nonperiodicce-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=B000KRXAGE"><img border="0" src="31ZQ3sVgx3L._AA_SL160_.jpg"/>Wii Play</a>, because friends had told me that while the game is not worth $50, you effectively get the game for $10 if you were going to buy another remote anyway.  This pretty much sums things up.  The games are not all that impressive, but $10 is about right.  However, I think when we take the Wii back to our parents&#8217; place for Thanksgiving and Christmas we will be glad to have Wii Play.  The reason is that those simple games give nice introductions to using the Wii remote in various game situations.  It will provide a nice prelude for our parents and relatives to the more complicated games, giving them a feel for how the motion sensing works.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2007/11/13/wii-play/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bought a Wii</title>
		<link>http://www.nonperiodic.net/blog/2007/10/24/bought-a-wii/</link>
		<comments>http://www.nonperiodic.net/blog/2007/10/24/bought-a-wii/#comments</comments>
		<pubDate>Wed, 24 Oct 2007 14:45:47 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2007/10/24/bought-a-wii/</guid>
		<description><![CDATA[I just got a Wii for my birthday! It was a little early, but I convinced Brenda that if we didn&#8217;t get one now, it would be impossible to get one closer to the holidays. In fact, WiiTracker almost never reports any in stock. The local Target, Wal-Mart, Circuit City and Best Buy are perpetually [...]]]></description>
			<content:encoded><![CDATA[<p>I just got a Wii for my birthday!  It was a little early, but I convinced Brenda that if we didn&#8217;t get one now, it would be impossible to get one closer to the holidays.  In fact, <a href="http://wiitracker.com">WiiTracker</a> almost never reports any in stock.  The local Target, Wal-Mart, Circuit City and Best Buy are perpetually out of them.  By random chance, however, I walked into a GameStop and they had one in stock, so I bought it on the spot.  I also picked up WiiPlay, which comes with an extra remote, and bought an extra Nunchuk.  We&#8217;ve had a good time the last couple of nights messing around with Wii Sports and the WiiPlay games.  Really simple and intuitive.  Brenda has never been much for video games, but we&#8217;ve had a really good time playing these silly things together.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2007/10/24/bought-a-wii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
