<?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>Push cx</title>
	<atom:link href="http://push.cx/feed" rel="self" type="application/rss+xml" />
	<link>http://push.cx</link>
	<description>A traveling geek&#039;s blog on development, games, and the web</description>
	<lastBuildDate>Thu, 19 Apr 2012 20:39:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Not Dead</title>
		<link>http://push.cx/2012/not-dead</link>
		<comments>http://push.cx/2012/not-dead#comments</comments>
		<pubDate>Tue, 27 Mar 2012 18:48:11 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[crash]]></category>
		<category><![CDATA[friends]]></category>
		<category><![CDATA[old jokes]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1837</guid>
		<description><![CDATA[i was just confused as to why you walk out of a car wreck and your biggest concern is missing my fake birthday Last Monday the top item on my to-do list was to give my friend Rob a call for his fake birthday. Then I got distracted. I&#8217;d borrowed a car for a weekend [...]]]></description>
			<content:encoded><![CDATA[<style>
blockquote.rob { background-color: #eef; }
blockquote.me  { background-color: #ffc; }
</style>

<blockquote class="rob">
i was just confused as to why you walk out of a car wreck and your biggest concern is missing my fake birthday
</blockquote>

<p>
Last Monday the top item on my to-do list was to give my friend Rob a call for his fake birthday. Then I got distracted.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTIvMDMvSU1HXzA0MDUuanBn"><img src="http://push.cx/wp-content/uploads/2012/03/IMG_0405-300x225.jpg" alt="" title="front bumper rigged to hang on" width="300" height="225" class="content aligncenter size-medium wp-image-1838" /></a>

<p>
I&#8217;d borrowed a car for a weekend trip to Madison and was returning on Monday, March 19. I was in the right lane of I-90 when a pickup in the left tried to lane-change into me in his haste to cut around the guy ahead of him. When I braked to avoid a collision, I spun out on the wet pavement and ground backwards to a halt along the crash barrier in the median. The back bumper disintegrated, the side of the car was scraped deeply enough to tear off a door handle, the front bumper was hanging half off.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTIvMDMvSU1HXzA0MDkuanBn"><img src="http://push.cx/wp-content/uploads/2012/03/IMG_0409-300x225.jpg" alt="" title="passenger door scratches" width="300" height="225" class="content aligncenter size-medium wp-image-1840" /></a>

<p>
With luck, and many thanks to automotive and highway engineers, I was uninjured. (The pickup drove off, of course.) The rest of my day was taken up with a police report, insurance report, damage estimates, and an early bedtime. All the usual fallout of a car crash.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTIvMDMvSU1HXzA0MTIuanBn"><img src="http://push.cx/wp-content/uploads/2012/03/IMG_0412-300x225.jpg" alt="" title="back tire, body crushed" width="300" height="225" class="content aligncenter size-medium wp-image-1842" /></a>

<p>
The next morning I was trading email with Rob and I told him the whole story of the crash, ending with:
</p>

<blockquote class="me">
Oh, which is all a long, elaborate excuse for saying I&#8217;m sorry I missed your birthday yesterday, Rob. Happy belated!
</blockquote>

<blockquote class="rob">
&#8230; thank you?
</blockquote>

<blockquote class="me">
Wasn&#8217;t it March 19 what you moved it to like 20 years ago because you were sick of having a birthday up against Christmas? I thought it was 3/19 and I&#8217;m sure it was some lead singer&#8217;s birthday&#8230;
</blockquote>

<blockquote class="rob">
guitar player. it was Pete Townshend from The Who<br /><br />

you got the date right. i was just confused as to why you walk out of a car wreck and your biggest concern is missing my fake birthday
</blockquote>

<p>
I&#8217;ve been chewing on this question, but the answer is easy: I&#8217;m really happy with where I am and what I&#8217;m doing with my life. The crash hasn&#8217;t made me think &#8220;Oh no, I&#8217;m wasting my life! I need to quit my job and work on <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20=">NearbyGamers</a> full-time! Or quit NearbyGamers and work 90-hour weeks! Or join a nunnery! Or win a triathlon!&#8221;
</p>

<p>
I wanted to get right back to what I was doing. I&#8217;ve thought deliberately about what kind of life I want, and I&#8217;m living it. And I can&#8217;t think of a better way to celebrate being alive than to enjoy a fond old joke with a friend.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTIvMDMvSU1HXzA0MjFfbW9kaWZpZWQuanBn"><img src="http://push.cx/wp-content/uploads/2012/03/IMG_0421_modified-300x225.jpg" alt="" title="rear of car, bumper and taillights missing" width="300" height="225" class="content aligncenter size-medium wp-image-1845" /></a> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1837" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2012/not-dead/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Timing</title>
		<link>http://push.cx/2011/timing</link>
		<comments>http://push.cx/2011/timing#comments</comments>
		<pubDate>Fri, 12 Aug 2011 22:47:43 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[Fantasy Adventure Game]]></category>
		<category><![CDATA[P]]></category>
		<category><![CDATA[so play we all]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1827</guid>
		<description><![CDATA[Luke, who writes backwards like DaVinci did some more game design with help from #bbg (on irc.freenode.net &#8211; anyone&#8217;s welcome to drop by to talk browser game development, it&#8217;s a great place). Reading his note photo, it looks like he&#8217;s breaking cards down into Settings, Characters, and Monsters. There&#8217;s not a lot more info, just [...]]]></description>
			<content:encoded><![CDATA[<p>
Luke, who <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuZmFudGFzeWFkdmVudHVyZWdhbWUuY29tLzIwMTEvMDgvMTAvZ2l0LWNoZWNrb3V0LWItc2ltX2NhcmRfZ2FtZS8=">writes backwards like DaVinci</a> did some more game design with help from #bbg (on irc.freenode.net &#8211; anyone&#8217;s welcome to drop by to talk browser game development, it&#8217;s a great place). Reading his note photo, it looks like he&#8217;s breaking cards down into Settings, Characters, and Monsters. There&#8217;s not a lot more info, just that he&#8217;s spending his hours planning out his game.
</p>

<p>
Speaking of hours, I missed responding to something in <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9wcmVzZW50aW5n">his previous update</a>:
</p>

<blockquote>
Eventually, I&#8217;m going to create web interfaces for a lot of this stuff, but for now I&#8217;ll have to do any settings and etc. by hand in the database. By the way, the interface work isn&#8217;t strictly game-related and can be handled outside of So Play We All hours.
</blockquote>

<p>
After the first week we said hours had to be budgeted towards code, but not marketing and blogging. It&#8217;s vague here, Jim, what are you referring to working on? If &#8220;interface&#8221; means HTML frontend, that&#8217;s code that&#8217;s gotta get counted, Luke and I both did a bunch of template work on budget.
</p>

<p>
Anyways, <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9pbm5vY2VuY2UtbG9zdA==">this week</a> Jim&#8217;s got some nice top-to-bottom functionality done in his rendering engine. It felt a bit like <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cub2Fxbi5jb20vMjAxMS9sYXppbmVzcy1wYXlzLW9mZg==">my update</a> about finishing off code from last week. He&#8217;s rendering a basic page:
</p>

<blockquote>
We do not have DisplayRegions yet, so I am just some simple text. However, this page is now valid XHTML and not simple plain-text!
</blockquote>

<p>
Congrats on the milestone, Jim.
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1827" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/timing/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Breakdowns</title>
		<link>http://push.cx/2011/breakdowns</link>
		<comments>http://push.cx/2011/breakdowns#comments</comments>
		<pubDate>Sat, 06 Aug 2011 05:20:59 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[Fantasy Adventure Game]]></category>
		<category><![CDATA[oaqn]]></category>
		<category><![CDATA[so play we all]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1824</guid>
		<description><![CDATA[When Jim asked me how many hours I could put to So Play We All this week, I said &#8220;Negative three&#8221;. That turned out to be pretty accurate, as I managed to drop on the floor all but the three most important things for my week. Unfortunately, Oaqn didn&#8217;t make that top three so I [...]]]></description>
			<content:encoded><![CDATA[<p>
When Jim asked me how many hours I could put to <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb3BsYXl3ZWFsbC5jb20=">So Play We All</a> this week, I said &#8220;Negative three&#8221;. That turned out to be pretty accurate, as I managed to drop on the floor all but the three most important things for my week. Unfortunately, Oaqn didn&#8217;t make that top three so I sent $20 each to Jim and Luke. So, let&#8217;s look at what I funded this week.
</p>

<p>
Luke <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuZmFudGFzeWFkdmVudHVyZWdhbWUuY29tLzIwMTEvMDgvMDMvaW4td2hpY2gtbHVrZS1nZXRzLXdyaXRlcnMtYmxvY2sv">had writer&#8217;s block</a>, so there&#8217;s not a lot to say there. I&#8217;m a bit puzzled that he doesn&#8217;t say &#8220;coder&#8217;s blocK&#8221; because the hours are budgeted towards that, but I can see how it&#8217;d be easy to open a code editor and then stare at it.
</p>

<p>
I&#8217;ve chatted with Luke a bit about his game design and thought it was pretty solid, similar to stuff I&#8217;d seen on <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zcXVpZGkubmV0L3RocmVlL2luZGV4LnBocA==">Three Hundred Mechanics</a> . This really sounds like he&#8217;s trying to see the entire design up-front and getting overwhelmed by it. His big questions are all certainly important ones, but maybe it&#8217;s worth figuring out if there&#8217;s a way to take smaller bites.
</p>

<p>
Jim&#8217;s got <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9wcmVzZW50aW5n">his first progress</a> that doesn&#8217;t sound to me like he&#8217;s reinventing a wheel. The template for a page is broken down into DisplayRegions, each of which has a Controller (&#8220;Component&#8221;) responsible for loading the right data.
</p>

<p>
It&#8217;s an interesting PHP-styled take on MVC. The top-level code that handles each request isn&#8217;t a controller action, it&#8217;s basically a template split into code/settings (&#8220;DisplayEngine&#8221;) and markup (&#8220;PageTemplate&#8221;). The <em>template</em> then lists what controllers and actions should be invoked to handle the request, which is a not how I&#8217;ve ever seen any web MVC work before. It feels pretty stereotypical of PHP to have a template running the show, and I wonder how much logic is going to leak into them as a result. A common pattern is that a section of a page with links to register and sign in &mdash; or, if there&#8217;s a user logged-in, to edit account settings and log out. Jim, in your system, where does that <kbd>if (logged_in()) { [settings/logout template] } else { [register/login template] }</kbd> live?
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1824" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/breakdowns/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Keeping Jim Busy</title>
		<link>http://push.cx/2011/keeping-jim-busy</link>
		<comments>http://push.cx/2011/keeping-jim-busy#comments</comments>
		<pubDate>Mon, 18 Jul 2011 23:58:00 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[so play we all]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1820</guid>
		<description><![CDATA[Oops, got totally distracted by flying back to Chicago and forgot to write my So Play We All response post on time, so there&#8217;s $10 each to Luke and Jim. Late but not lost, here&#8217;s that response. (Luke didn&#8217;t post an update this week, so I&#8217;m only responding to Jim.) This week, Jim had a [...]]]></description>
			<content:encoded><![CDATA[<p>
Oops, got totally distracted by flying back to Chicago and forgot to write my <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb3BsYXl3ZWFsbC5jb20=">So Play We All</a> response post on time, so there&#8217;s $10 each to Luke and Jim. Late but not lost, here&#8217;s that response. (Luke didn&#8217;t post an update this week, so I&#8217;m only responding to Jim.)
</p>

<p>
This week, Jim had a <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9iZXR3ZWVuLWZvcm1zLWFuZC1wYWdlcw==">brief but significant update</a>, writing:
</p>

<blockquote>
Well, after so many weeks of being seriously far behind, I&#8217;ll finally be making the progress towards being able to render a complete HTML page.
</blockquote>

<p>
He&#8217;s written his Page, Session, and Form classes to the point that he&#8217;s only held back by not being able to template pages from displaying real pages. I&#8217;m a little surprised he got votes in <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvbW11bml0eS5iYmdhbWV6b25lLm5ldC9wcm9qZWN0cy9zby1wbGF5LXdlLWFsbC13ZWVrLTctY29udGVudC1nZW5lcmF0aW9uL21zZzI0MzQyLw==">this week&#8217;s poll</a> without anything to demo, but it&#8217;s nice to hear things are coming together for him.
</p>

<p>
Actually, maybe I should be worried that he&#8217;s going to start displaying a game sometime soon. So let me mention a great Rails feature you should spend time reimplementing, Jim. The pending release of Rails 3.1 includes <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL3JhaWxzL3JhaWxzL2Jsb2IvbWFzdGVyL2FjdGlvbnBhY2svbGliL2FjdGlvbl9jb250cm9sbGVyL21ldGFsL3N0cmVhbWluZy5yYg==">HTTP streaming</a>, basically the ability to send parts of the page while still working on generating the page.
</p>

<p>
This is how PHP&#8217;s page-as-script model works out-of-the-box, but it often leads to bugs when state changes during the page rendering. I&#8217;ve seen a lot of browser based games with a bug where a page says you have 100 minerals in the header and then, lower in the page, say that you only have 50 because loading this page performed an action that spent 50 minerals. Having an explicit stage that builds and renders a page usually prevents these bugs at the cost of being able to send enough information for the client to get working at downloading page assets while the server is still performing work. Continuing to support that may cost Jim enough time in gold-plating to keep me comfortably ahead.
</p>

<p>
(But just in case it doesn&#8217;t the <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3dlYmxvZy5ydWJ5b25yYWlscy5vcmcvMjAxMS81LzIyL3JhaWxzLTMtMS1yZWxlYXNlLWNhbmRpZGF0ZQ==">3.1 announcement</a> also mentions an asset pipeline that compiles and compresses CSS and JS for faster pageloads. Have fun, Jim.)
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1820" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/keeping-jim-busy/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rewriting My Competitors</title>
		<link>http://push.cx/2011/rewriting-my-competitors</link>
		<comments>http://push.cx/2011/rewriting-my-competitors#comments</comments>
		<pubDate>Sat, 09 Jul 2011 10:48:23 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[code smells]]></category>
		<category><![CDATA[Fantasy Adventure]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[sessions]]></category>
		<category><![CDATA[so play we all]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1811</guid>
		<description><![CDATA[It&#8217;s really clear that the polls So Play We All are measuring progress. When we have a quiet week, there&#8217;s a lot fewer votes. This week, there were 4, evenly split between Luke and I. The SPWA site doesn&#8217;t have code to handle ties so it highligted me as winning, which I guess means the [...]]]></description>
			<content:encoded><![CDATA[<p>
  It&#8217;s really clear that the polls <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3NvcGxheXdlYWxsLmNvbQ==">So Play We All</a> are measuring progress. When we have a quiet week, there&#8217;s a lot fewer votes. This week, there were 4, evenly split between Luke and I. The SPWA site doesn&#8217;t have code to handle ties so it highligted me as winning, which I guess means the bugfix is not <em>my</em> problem. :)
</p>

<p>
  Luke <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuZmFudGFzeWFkdmVudHVyZWdhbWUuY29tLzIwMTEvMDcvMDYvYS1zcHJpbmctYnViYmxlcy11cC8=">laid down code</a> for cards. I know I&#8217;m helping the enemy, but I&#8217;ve got to tweak it. His code is:
</p>

<pre>&nbsp;
class CardController &lt; ApplicationController
  def play
    play_sym = <span style="color: #ff0000;">"play_#{@card}"</span>.<span style="">intern</span> <span style="color: #808080; font-style: italic;"># PH: this should be .to_sym</span>
    self.<span style="">send</span><span style="color: #66cc66;">&#40;</span>play_sym<span style="color: #66cc66;">&#41;</span>
    render :action =&gt; play_sym <span style="color: #b1b100;">and</span> <span style="color: #000066;">return</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
  def pocket
    pocket_sym = <span style="color: #ff0000;">"pocket_#{@card}"</span>.<span style="">intern</span>
    self.<span style="">send</span><span style="color: #66cc66;">&#40;</span>pocket_sym<span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">end</span> <span style="color: #808080; font-style: italic;"># PH: no explicit render here? Feels like a paste error</span>
&nbsp;
  protected
&nbsp;
  <span style="color: #808080; font-style: italic;"># plays</span>
  def play_roland
    <span style="color: #808080; font-style: italic;"># Play the game to see what happens when you play the Roland card!</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
  def play_water
    <span style="color: #808080; font-style: italic;"># Play the game to see what happens when you play the Water card!</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># pockets</span>
  def pocket_roland
    <span style="color: #808080; font-style: italic;"># Play the game to see what happens when you pocket the Roland card!</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
  def pocket_water
    <span style="color: #808080; font-style: italic;"># Play the game to see what happens when you pocket the Water card!</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
<span style="color: #b1b100;">end</span></pre>

I&#8217;d write this code as:

<pre>&nbsp;
class CardController &lt; ApplicationController
  <span style="color: #808080; font-style: italic;"># I'm guessing from usage above @card is just the name for a card as a string</span>
  <span style="color: #808080; font-style: italic;"># and that it's loaded from the url by a filter, note that I use it differently.</span>
  before_filter :load_card
  after_filter :default_render_card
  
  def play
    <span style="color: #0000ff;">@card</span>.<span style="">play</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
  def pocket
    <span style="color: #0000ff;">@card</span>.<span style="">pocket</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
  protected
&nbsp;
  def load_card
    <span style="color: #0000ff;">@name</span> = params<span style="color: #66cc66;">&#91;</span>:card<span style="color: #66cc66;">&#93;</span>
    <span style="color: #0000ff;">@card</span> = <span style="color: #ff0000;">"card/#{@name}"</span>.<span style="">camelize</span>.<span style="">constantize</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
  def default_render_card
    render :template =&gt; <span style="color: #ff0000;">"cards/#{request.action}/#{@name}"</span> <span style="color: #b1b100;">unless</span> performed?
  <span style="color: #b1b100;">end</span>
end
&nbsp;
<span style="color: #808080; font-style: italic;"># add in config/application.rb:</span>
module Oaqn
  class Application &lt; Rails::<span style="color: #006600;">Application</span>
    config.<span style="">autoload_paths</span> += <span style="color: #0000ff;">%W</span><span style="color: #66cc66;">&#40;</span><span style="color: #808080; font-style: italic;">#{config.root}/app/cards)</span>
  <span style="color: #b1b100;">end</span>
end
&nbsp;
<span style="color: #808080; font-style: italic;"># and then create app/cards/roland.rb:</span>
module Card
  module Roland
    def pocket
      <span style="color: #808080; font-style: italic;"># code for pocketing</span>
    <span style="color: #b1b100;">end</span>
&nbsp;
    def play
      <span style="color: #808080; font-style: italic;"># code for playing</span>
    <span style="color: #b1b100;">end</span>
  <span style="color: #b1b100;">end</span>
end</pre>

<p>
  So now the cards each get a source file to themselves, templates have their own per-action dirs (better swapped to per-card dirs, if there are more actions), there&#8217;s less duplicated code, and it&#8217;s far easier to test these smaller pieces. The only thing missing from this example is the fact that Luke may have to pass some game state into the methods. As long as there&#8217;s not too much it&#8217;s probably worth being explicit about.
</p>

<p class="update">
2011-07-09: Luke actually used this code and found it didn&#8217;t work as written. I found <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80MDc0ODMwL2FkZGluZy1saWItdG8tY29uZmlnLWF1dG9sb2FkLXBhdGhzLWkNCm4tcmFpbHMtMy1kb2VzLW5vdC1hdXRvbG9hZC1teS1tb2R1bGU=">an explanation</a>; either add &#8216;app&#8217; to <kbd>autoload_paths</kbd> instead of &#8216;app/cards&#8217;, or drop the Card wrapper.
</p>

<p>
  Meanwhile, in the past, Jim <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9jbGFzcy1zZXNzaW9u">wrote some PHP</a>, and I&#8217;m not touching that language.
</p>

<p>
  No, in seriousness, Jim talked about why he has some identifiers surrounded by __ (which I&#8217;d called <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAxMS9zbWFsbC1zdGVwcw==">python poisoning</a>). I haven&#8217;t dug into his code (again, PHP), but it looks like it might be an <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2MyLmNvbS9jZ2kvd2lraT9JbkJhbmRTaWduYWw=">InBandSignal</a> to reuse Events as framework steps.
</p>

<p>
  And then he talks about session fixation attacks, which are have been protected against out-of-the-box on PHP with the <kbd>session.use_only_cookies</kbd> setting for a while. I was a bit confused, I&#8217;m pretty sure he&#8217;s actually describing session capture attacks. Oh, and there was some other stuff about writing code to store sessions in the database. If you&#8217;re curious, Jim, here&#8217;s the code for a Rails app to do that, which appears commented-out in the stock config file for your editing convenience:
</p>

<pre>&nbsp;
  Oaqn::<span style="color: #006600;">Application</span>.<span style="">config</span>.<span style="">session_store</span> :active_record_store</pre>

<p>
  It includes support out of the box for keeping sessions in cookies (encrypted, of course), your SQL database via ActiveRecord, or Memcached. I&#8217;m curious, how much of your budget did you spend storing sessions?
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1811" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/rewriting-my-competitors/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Two Turnarounds</title>
		<link>http://push.cx/2011/two-turnarounds</link>
		<comments>http://push.cx/2011/two-turnarounds#comments</comments>
		<pubDate>Fri, 01 Jul 2011 10:49:32 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[Fantasy Adventure Game]]></category>
		<category><![CDATA[so play we all]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1809</guid>
		<description><![CDATA[I was really impressed by Luke in week five of So Play We All. He built a playtestable game fast and, more importantly, he learned from it. He&#8217;s]]></description>
			<content:encoded><![CDATA[<p>
  I was really impressed by Luke in week five of <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb3BsYXl3ZWFsbC5jb20=">So Play We All</a>. He built a playtestable game fast and, more importantly, he learned from it. He&#8217;s <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuZmFudGFzeWFkdmVudHVyZWdhbWUuY29tLzIwMTEvMDYvMjUvYW55b25lLWhhdmUtYS1yb2xhbmQv"\">decided to completely rework his gameplay</a>. Player interaction wasn&#8217;t what he wanted and he realized it would be a huge amount of work to write. It&#8217;s not easy to decide you&#8217;ve spent time building the wrong thing, and that maturity impressed me.
</p>

<p>
  And, you know, I&#8217;m a huge fan of card games, so it&#8217;s nice to see another one in development.
</p>

<p>
  As great as that is, Jim got my vote in <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvbW11bml0eS5iYmdhbWV6b25lLm5ldC9wcm9qZWN0cy9zby1wbGF5LXdlLWFsbC13ZWVrLTUtZ2FtZS13b3JsZC8=">this week&#8217;s poll</a>.
</p>

<p>
  In a post titled <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9kZWl0eS1kZXZlbG9wbWVudA==">Deity Development</a> he responds to some criticism and then links to the documentation for the abstract work I was hassling him about doing the last few weeks. I&#8217;m glad to tangibly see his progress, and it looks like he&#8217;s got a solid core built now.
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1809" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/two-turnarounds/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Recreating My Firefox Profile</title>
		<link>http://push.cx/2011/recreating-my-firefox-profile</link>
		<comments>http://push.cx/2011/recreating-my-firefox-profile#comments</comments>
		<pubDate>Sat, 25 Jun 2011 03:54:22 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[customization]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[nerd pride]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1798</guid>
		<description><![CDATA[With the release of Firefox 5 a few days ago, I thought it was time to recreate my Firefox profile. You may not know what it is because you only have one: it&#8217;s the set of your add-ons, bookmarks, history, and every other kind of customization you can do to Firefox. As a web developer, [...]]]></description>
			<content:encoded><![CDATA[<p>
  With the release of <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cubW96aWxsYS5jb20vYmxvZy8yMDExLzA2LzIxL21vemlsbGEtZGVsaXZlcnMtbmV3LXZlcnNpb24tb2YtZmlyZWZveC1maXJzdC13ZWItYnJvd3Nlci10by1zdXBwb3J0LWRvLW5vdC10cmFjay1vbi1tdWx0aXBsZS1wbGF0Zm9ybXMv">Firefox 5</a> a few days ago, I thought it was time to recreate my Firefox profile. You may not know what it is because you only have one: it&#8217;s the set of your add-ons, bookmarks, history, and every other kind of customization you can do to Firefox.
</p>

<p>
  As a web developer, I have a half-dozen for testing reasons, but one that I use for all of my personal browsing and most of my work. Very infrequently, I&#8217;ve noticed that it sometimes would have errors on web pages that other Firefox profiles didn&#8217;t. After some thinking, I realized that I&#8217;ve been copying the same Firefox profile nearly ten years, copying it between computers as I upgrade. And all the while I&#8217;ve been tinkering with it, poking around in its config files, testing extensions, changing options in about:config.
</p>

<p>
  I wanted a fairly mindless activity today, so I recreated my profile from scratch, re-installing all my extensions and configuring everything just the way I like it. It took a few hours, and my notes ended up surprisingly long.
</p>

<p>
  The few times I&#8217;ve thought about switching to Chrome I&#8217;ve looked for one or two of these add-ons and seen that there&#8217;s no equivalent. Now that I have these notes I can check comprehensively the next time I get the urge.
</p>

<p>
  The notes will mostly be of interest to web developers. My browser is pretty heavily customized with tools, privacy protections, and productivity tweaks (mostly to make it feel like vim and allow me to pull things offline easily). It&#8217;s an intimidating list to look at, but it&#8217;s ten years of small changes every few weeks all at once.
</p>


<h3>Add-Ons</h3>
<ul>
<li>AdBlock Plus http://adblockplus.org/en/

<ul>
<li>add EasyList (button in tab on startup)</li>
<li>&#8216;Options&#8217; menu, uncheck &#8216;Show tabs on Flash and Java&#8217;</li>
</ul>
</li>
<li>Better Privacy

<ul>
<li>select any LSOs you want to keep</li>
</ul>
</li>
<li>Cookie Monster

<ul>
<li>uncheck &#8220;Automatically Reload&#8230;&#8221;</li>
</ul>
</li>
<li>Download Statusbar

<ul>
<li>General

<ul>
<li>check &#8216;Download speed&#8217;</li>
<li>uncheck &#8216;Keep a download history</li>
<li>check &#8216;Clear finished downloads when the browser closes&#8217;</li>
<li>&#8216;Automatically clear these filetypes&#8217;: *</li>
<li>after 90 seconds</li>
</ul>
</li>
<li>Appearance &#8211; choose &#8216;Custom Style&#8217;

<ul>
<li>File Name Size: 9</li>
<li>Height: 13</li>
<li>check &#8216;Main Downloads Button&#8217;</li>
<li>check &#8216;Clear Finished Button&#8217;</li>
<li>check &#8216;Enable Speed Colors&#8217;</li>
</ul>
</li>
</ul>
</li>
<li>FacebookBlocker</li>
<li>Flashblock

<ul>
<li>check &#8216;Block Silverlight as well&#8217;</li>
<li>add any whitelist sites</li>
</ul>
</li>
<li>Greasemonkey</li>
<li>LeechBlock

<ul>
<li>block tvtropes.com</li>
<li>General &#8211; check all</li>
</ul>
</li>
<li>Pentadactyl
    <p>~/.pentadactylrc</p>
    <code lang=""><pre>
"1.0b4.3 (created: 2011/01/05 17:55:12)

loadplugins '\.(js|penta)$'
set guioptions=BrsC
set runtimepath=/home/harkins/.pentadactyl
set urlseparator=,,s

" vim: set ft=pentadactyl:
</pre></code>
</li>
<li>NoSquint

<ul>
<li>Zooming tab, uncheck &#8216;Show current zoom levels&#8217;</li>
<li>Set &#8216;Default full page zoom level&#8217; to 100%</li>
<li>Exceptions tab, add <em>.github.com, </em>.tumblr.com, <em>.blogspot.com, </em>.posterous.com</li>
</ul>
</li>
<li>Pixlr Grabber

<ul>
<li>uncheck &#8216;To edit images&#8217; and &#8216;To edit backgrounds&#8217;</li>
<li>select &#8216;Always save to desktop&#8217;</li>
</ul>
</li>
<li>Readability https://www.readability.com/addons</li>
<li>RefControl

<ul>
<li>click &#8216;Edit&#8217; button, choose &#8216;Block&#8217; and check &#8217;3rd Party requests only&#8217;</li>
<li>outside of settings, right click button at bottom of window, remove icon</li>
</ul>
</li>
<li>Sauce Launcher https://addons.mozilla.org/en-us/firefox/addon/sauce-launcher/</li>
<li>ScrapBook

<ul>
<li>Show up to: 10</li>
</ul>
</li>
<li>SQLite Manager

<ul>
<li>select &#8216;in a new tab&#8217;</li>
<li>uncheck &#8216;Always confirm&#8217;</li>
<li>uncheck everything in Prompts tab</li>
</ul>
</li>
<li>Tamper Data</li>
<li>Tree Style Tab

<ul>
<li>Appearance

<ul>
<li>Skin &#8216;Sidebar&#8217;</li>
<li>Tree Twisties: choose &#8216;None&#8217;</li>
</ul>
</li>
<li>Menu

<ul>
<li>uncheck all but &#8216;Reload this Tree&#8217; and &#8216;Close this Tree&#8217;</li>
</ul>
</li>
<li>New Tabs

<ul>
<li>uncheck &#8216;Always ask&#8217;</li>
<li>select &#8216;Open in new tabs&#8217;</li>
</ul>
</li>
<li>Tree

<ul>
<li>uncheck &#8216;When a tab gets focus&#8217;</li>
<li>check &#8216;Double-click on a tab&#8217;</li>
</ul>
</li>
<li>Advanced

<ul>
<li>uncheck &#8216;Enable Animation Effects&#8217;</li>
<li>uncheck &#8216;Show tree contents&#8217;</li>
</ul>
</li>
</ul>
</li>
<li>UnPlug

<ul>
<li>Integration &#8211; uncheck all but tools menu</li>
<li>Downloads &#8211; &#8216;Preferred download method&#8217;: Save as</li>
</ul>
</li>
<li>User Agent Switcher</li>
<li>Web Developer

<ul>
<li>General

<ul>
<li>Check to hide the context menu, confirmation, and informational</li>
</ul>
</li>
<li>Validation

<ul>
<li>select CSS 3</li>
</ul>
</li>
</ul>
</li>
</ul>



<h3>Incompatible</h3>
  <p>These aren&#8217;t yet compatible with Firefox 5, so they didn&#8217;t get into my notes.</p>

  <ul>
    <li><a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9zcGVlZC9wYWdlLXNwZWVkL2Rvd25sb2FkLmh0bWw=">Page Speed</a></li>
    <li><a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9hZGRvbnMubW96aWxsYS5vcmcvZW4tdXMvZmlyZWZveC9hZGRvbi9yZXN1cnJlY3QtcGFnZXMv">Resurrect Pages</a></li>
    <li><a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9hZGRvbnMubW96aWxsYS5vcmcvZW4tdXMvZmlyZWZveC9hZGRvbi95c2xvdy8=">YSlow</a></li>
  </ul>

<h3>GreaseMonkey Scripts</h3>
  <p>Sorry for the lack of titles, but this was annoying enough to compile already.</p>
  <p>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNTEyODE=">51281</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNjI3MDY=">62706</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNzcwNQ==">7705</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjM1NTU=">23555</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNTM1NDc=">53547</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNjAzMTQ=">60314</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMzg1MTY=">38516</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMzE4MDQ=">31804</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNTY2OTA=">56690</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMTAwNzQ2">100746</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMTA0NDg5">104489</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMzg5ODU=">38985</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNDUwMzI=">45032</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNzUyNjM=">75263</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNzc4MDE=">77801</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvOTQxMTI=">94112</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMzA2NDY=">30646</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjMxNzU=">23175</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjgzNzQ=">28374</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjkyNzk=">29279</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjk2ODI=">29682</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjk2ODE=">29681</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjk4Mjk=">29829</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjk4Mjg=">29828</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvOTUyOTg=">95298</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMjk2NjY=">29666</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNDkzNjY=">49366</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNzQzNDA=">74340</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNzYzMDA=">76300</a>
    <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvNDUwMzI=">45032</a>
  </p>

<h3>Toolbars</h3>
  <ul>
    <li>right click on the toolbar, uncheck Web Development toolbar</li>
    <li>right click again, choose &#8216;Customize&#8217;, choose &#8216;Use Small Icons&#8217; and remove:
      <ul>
        <li>read it later</li>
        <li>search box</li>
        <li>zoom buttons</li>
        <li>home button</li>
        <li>bookmarks button</li>
        <li>FireBug button</li>
        <li>drag GreaseMonkey button to status bar</li>
      </ul>
      </li>
  </ul>

<h3>Cookies</h3>
  <p>
    click on CookieMonster at bottom of window, click View Cookies, show exceptions.<br />
    &#8216;Allow&#8217; sites you regularly visit<br />
    &#8216;Block&#8217; google properties
  </p>

<h3>Bookmarks menu -> Show all Bookmarks</h3>
  <p>
    &#8216;Import and Backup&#8217; -> Back up to json in old profile, Import &#8216;Choose File&#8217; in new</br>
    Same with ScrapBook &#8211; open sidebar, Tools, Import / Export, select all&#8230;
  </p>

<h3>Edit -> Preferences</h3>
  <ul>
    <li>
    General
      <ul>
        <li>&#8216;When Firefox starts&#8217;: Show my windows and tabs</li>
        <li>&#8216;Home Page&#8217;: about:blank</li>
      </ul>
    </li>
    <li>
    Tabs
      <ul>
        <li>check everything but &#8216;When I open a link in a new tab&#8217;</li>
      </ul>
    </li>
    <li>
    Applications
      <ul>
        <li>search for VLC, Windows, and QuickTime, change items to &#8216;Always Ask&#8217;</li>
      </ul>
    </li>
    <li>
    Privacy
      <ul>
        <li>check &#8216;Tell web sites I do not want to be tracked&#8217;</li>
        <li>select &#8216;Firefox will&#8217;: Use custom settings for history</li>
        <li>select &#8216;Keep until&#8217;: I close Firefox</li>
        <li>select &#8216;When using the location bar, suggest&#8217;: History</li>
      </ul>
    </li>
    <li>
    Security
      <ul>
        <li>uncheck &#8216;Remember passwords for sites&#8217;</li>
      </ul>
    </li>
    <li>
    Advanced -> Update
      <ul><li>uncheck &#8216;Search Engines&#8217;</li></ul>
    </li>
  </ul>
  
<h3>about:config</h3>
  <ul>
    <li>browser.autofocus false</li>
    <li>browser.dom.window.dom.enabled true (new)</li>
    <li>browser.history_expire_days 30</li>
    <li>browser.tabs.animate false</li>
    <li>browser.tabs.closeButtons 2</li>
    <li>browser.tabs.loadBookmarksInBackground true</li>
    <li>browser.tabs.loadDivertedInBackground true</li>
    <li>browser.tabs.selectOwnerOnClose false</li>
    <li>browser.zoom.full false</li>
    <li>browser.jsannoyances.disabled true (new)</li>
    <li>downbar.display.clearButton false</li>
    <li>downbar.display.mainButton false</li>
    <li>downbar.display.percent true</li>
    <li>downbar.function.useAnimation false</li>
    <li>network.http.pipelining true</li>
    <li>network.http.pipelining.maxrequests 8</li>
    <li>network.prefetch-next false</li>
  </ul>

<h3>~/.mozilla/firefox/[profile]/chrome</h3>
  <h4>userChrome.css</h4>

  <pre>&nbsp;
    @<span style="color: #003366; font-weight: bold;">namespace</span> url<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
    <span style="color: #009900; font-style: italic;">/* don't bold active tab title */</span>
    <span style="color: #009900; font-style: italic;">/* no longer works, argh */</span>
    tab<span style="color: #66cc66;">&#91;</span>selected=<span style="color: #3366CC;">"true"</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#123;</span> font-weight: normal !important; <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #009900; font-style: italic;">/* stop TreeStyleTab's Sidebar theme from changing its color when in/active */</span>
    .<span style="color: #006600;">tabbrowser</span>-strip<span style="color: #66cc66;">&#91;</span>treestyletab-style=<span style="color: #3366CC;">"sidebar"</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span>treestyletab-mode=<span style="color: #3366CC;">"vertical"</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#123;</span>
      background-color: #ccc !important;
    <span style="color: #66cc66;">&#125;</span></pre>

  <h4>userContent.css</h4>

  <pre>&nbsp;
    <span style="color: #009900; font-style: italic;">/* indicate nofollow links with a dotted blue underline */</span>
    a<span style="color: #66cc66;">&#91;</span>rel~=nofollow<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#123;</span> border-bottom: 1px dotted blue !important; <span style="color: #66cc66;">&#125;</span></pre>

<p>
  Got any neat suggestions I&#8217;ve missed?
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1798" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/recreating-my-firefox-profile/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Small Steps</title>
		<link>http://push.cx/2011/small-steps</link>
		<comments>http://push.cx/2011/small-steps#comments</comments>
		<pubDate>Thu, 23 Jun 2011 08:50:48 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[Fantasy Adventure]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1795</guid>
		<description><![CDATA[In Week 5 of So Play We All, things were pretty quiet. I bugfixed and laid groundwork. Luke&#8230; uh&#8230; did something. I read his post and it sounds like he added some helpers but otherwise mostly just rewrote his story. It&#8217;s more enjoyable now (seriously, play it), but it doesn&#8217;t really feel structurally any different. [...]]]></description>
			<content:encoded><![CDATA[<p>
In Week 5 of <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb3BsYXl3ZWFsbC5jb20=">So Play We All</a>, things were pretty quiet. I <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cub2Fxbi5jb20vMjAxMS9hLXdob2xlLW5ldy13b3JsZA==">bugfixed and laid groundwork</a>. Luke&#8230; uh&#8230; did something. I read <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuZmFudGFzeWFkdmVudHVyZWdhbWUuY29tLzIwMTEvMDYvMjIvbmV2ZXItdHJ1c3QtYS1tYWdpY2lhbi10by1kby10aGUtYXJteXMtam9iLw==">his post</a> and it sounds like he added some helpers but otherwise mostly just rewrote his story. It&#8217;s more enjoyable now (seriously, <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5mYW50YXN5YWR2ZW50dXJlZ2FtZS5jb20=">play it</a>), but it doesn&#8217;t really feel structurally any different. There&#8217;s no added mechanics that I can see. I&#8217;m curious where he&#8217;s going, though.
</p>

<p>
  Meanwhile, Jim is apparently suffering from <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9kYXRhYmFzZS1ldmVudA==">Python poisoning</a>, because he&#8217;s naming events __LIKE_THIS__. He&#8217;s swirling into madness:
</p>

<blockquote>
  Once Version 1 is stable, I&#8217;ll compile a list of &#8220;official&#8221; Events that developers can utilize in their own projects.
</blockquote>

<p>
  No, I didn&#8217;t make that up. Not only is he thinking about a framework for multiple games, he&#8217;s thinking about a <em>published</em> framework for multiple games. Not, you know, his game. I see why Luke earlier used the phrase <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5qb2Vsb25zb2Z0d2FyZS5jb20vYXJ0aWNsZXMvZm9nMDAwMDAwMDAxOC5odG1s">architecture astronauts</a>. Jim, you are a great many abstractions away from writing a game, and I think the air is getting thin.
</p>

<p>
  More encouragingly, Jim&#8217;s been writing about some of the deities in his game world: <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vZGVpdHkvZGFuaQ==">Dani</a>, <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vZGVpdHkvcmhlZ2Fy">Rhegar</a>, <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vZGVpdHkvbnVyaQ==">Nuri</a>, <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vZGVpdHkvc2hpc2FuZQ==">Shisane</a>, and <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vZGVpdHkva2Vzb2s=">Kesok</a>. I understand the setting is largely based on long-gone-by D&amp;D campaigns. It&#8217;s great to see some player-facing information.
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1795" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/small-steps/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Craftsmanship Tour: New York Times</title>
		<link>http://push.cx/2011/craftsmanship-tour-new-york-times</link>
		<comments>http://push.cx/2011/craftsmanship-tour-new-york-times#comments</comments>
		<pubDate>Wed, 22 Jun 2011 18:07:54 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[craftsmanship tour]]></category>
		<category><![CDATA[idempotency]]></category>
		<category><![CDATA[journalism]]></category>
		<category><![CDATA[New York Times]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1762</guid>
		<description><![CDATA[In May, while visiting New York City, I dropped by the New York Times to code with Derek Willis and, impromptu, Dan Berko. I worked with both at the Washington Post (and saw many other familiar names on doors, online journalism is a small town). Derek&#8217;s got a great career arc. He climbed up the [...]]]></description>
			<content:encoded><![CDATA[<p>
In May, while visiting New York City, I dropped by the <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5ueXRpbWVzLmNvbQ==">New York Times</a> to code with <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3R3aXR0ZXIuY29tL2RlcmVrd2lsbGlz">Derek Willis</a> and, impromptu, <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3R3aXR0ZXIuY29tL2JlcmtvZA==">Dan Berko</a>. I worked with both at the <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=L3RhZy93YXNoaW5ndG9uLXBvc3Q=">Washington Post</a> (and saw many other familiar names on doors, online journalism is a small town).
</p>

<p>
Derek&#8217;s got a great career arc. He climbed up the ranks of journalism, covered Congress, and got involved in data-heavy projects. &#8220;Computer assisted reporting&#8221; is one of those terms that nobody quite loves but nobody&#8217;s successfully replaced (though it seems &#8220;database journalism&#8221; is gaining ground) and refers to collecting and analyzing data in databases. Derek got as interested in the &#8220;computers&#8221; as the &#8220;reporting&#8221; and has deliberately pushed his skills and career into software development. (*cough* sounds like a good topic for a <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cudGhlc2Nvb3Aub3Jn">quiet blog</a>, eh, Derek? *cough). I look at his <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2R3aWxsaXM=">GitHub profile</a> today and he&#8217;s been busily merging in contributions to his open source projects like his <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2R3aWxsaXMvdXNhdG9kYXktY2Vuc3Vz">USA Today Census gem</a>.
</p>

<p>
We started out the day looking around the FEC scraping code. In the States, the Federal Election Commission gives out lots of data from candidates filing required disclosure statements. We tidied up the database a little and then turned to the project for the day, which has just been publicly announced:
</p>

<blockquote>
Today we’re announcing the addition of paper campaign filings from Senate candidates and two party committees to our Campaign Finance API, which previously had only provided details of electronically filed reports. Now users can request and view the filings of any committee registered with the Federal Election Commission.

Unlike House and presidential candidates, current and would-be senators file their campaign reports first with the Secretary of the Senate, who then forwards them to the F.E.C. That agency then scans in the images from the paper filings and makes them available for viewing (an example). While an effort to require electronic filing for Senate candidates hasn’t gotten much traction this year, we have at least made the API’s set of filings more complete.
<cite><a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL29wZW4uYmxvZ3Mubnl0aW1lcy5jb20vMjAxMS8wNi8wMi9wYXBlci1maWxpbmdzLw==">New in the Campaign Finance API: Paper Filings</a></cite>
</blockquote>

<p>
  The scraper was previously ignoring the paper-only reports, but we updated it to recognize and categorize them. The categorization was a huge bit of nostalgia for me: take the noisy and sometimes inconsistent provided categories and map them onto a standard set of database categories (form_type, in the screenshot in the announcement).
</p>

<p>
  When we ran the scraper, it would complain and halt each time it reached an unknown category. We&#8217;d add that to a mapping table and restart from that point, but it was frustrating to have to keep an eye on it. So we set the scraper to ignore records that it didn&#8217;t have a mapping for and warn about the problem. We set the scraper to run (and hit the amazing Shake Shack for burgers) and came back to find a list of missing mappings. After adding that, we ran the scraper again to fill in the missing entries.
</p>

<p>
  This worked because the scraper only added entries it didn&#8217;t already have recorded. The term for this is <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2MyLmNvbS9jZ2kvd2lraT9JZGVtcG90ZW50RGVzaWdu">idempotency</a>, and it&#8217;s useful from the level of individual functions up to large, fairly complex programs like web scrapers. Every program fails, having an idempotent approach to the problem means you don&#8217;t have to keep careful track of many types of failure because you can fix things and re-run your program without worrying about duplicate records or updating things twice.
</p> 

<p>
Derek had to run off to catch a train, so I dropped in on Dan Berko. He was on one of the Post&#8217;s several other &#8220;web innovation&#8221; teams while I was there, so we helped each other with code occasionally but didn&#8217;t spend a lot of time coding together.
</p>

<p>
The New York Times has large and well-maintained internal tools for reporters and editors. The reporters have a CMS for writing stories and the editors have a budgeting system for planning what goes where in the paper. We improved communcation between these two a bit, so the budgeting tool could refer to a story in the CMS and pull metadata from there instead of requiring an editor to re-input it. 
</p>

<p>
  The UI was simple: if the editor links a story, several fields should be grayed out and a checkbox should indicate the link. If the editor unchecks the box, the link is broken and the fields become editable again. This started out with two code paths &#8211; one for linking a story, one for unlinking &#8211; and making sure on pageload that the UI was in the proper state. We&#8217;d barely started writing that when we saw it could be implemented even simpler:
</p>

<pre>&nbsp;
disable_if_linked_to_cms: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> checked = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'asset_cms_id'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">checked</span>;
  <span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">'asset_home_status_id'</span>, <span style="color: #3366CC;">'headline'</span>, etc.<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
      $<span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">disabled</span> = checked;
  <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>,
document.<span style="color: #006600;">observe</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'dom:loaded'</span>, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
  Event.<span style="color: #006600;">observe</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'asset_cms_id'</span>, <span style="color: #3366CC;">'click'</span>, Budget.<span style="color: #006600;">disable_if_linked_to_cms</span><span style="color: #66cc66;">&#41;</span>;
  Budget.<span style="color: #006600;">disable_if_linked_to_cms</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</pre>

<p>
When the checkbox is checked, all the form fields are disabled. When it&#8217;s unchecked, they&#8217;re not. The code runs on pageload and anytime the checkbox is toggled. I really liked this bit of code: we started out writing the simplest thing that came to mind, but soon we realized it could be reduced. The resulting code probably elicits a &#8220;So what, it&#8217;s not doing much?&#8221; reaction, which is far better than the previous &#8220;Now, let&#8217;s see, what&#8217;s this doing?&#8221; we would&#8217;ve had at first. The sign of the best code is that you immediately understand it, not that you have to stretch yourself to follow its solution.
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1762" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/craftsmanship-tour-new-york-times/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Now Featuring Monsters</title>
		<link>http://push.cx/2011/now-featuring-monsters</link>
		<comments>http://push.cx/2011/now-featuring-monsters#comments</comments>
		<pubDate>Sat, 18 Jun 2011 11:00:20 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[Fantasy Adventure Game]]></category>
		<category><![CDATA[grue]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[so play we all]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1783</guid>
		<description><![CDATA[The So Play We All theme this week was &#8220;core game objects&#8221; and the time budget was 3 hours. I did did well for myself, time to review the others&#8217; work &#8212; both of which included monsters. Luke did well this week as he started to build out his combat system, including party members who [...]]]></description>
			<content:encoded><![CDATA[<p>
The <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb3BsYXl3ZWFsbC5jb20=">So Play We All</a> theme this week was &#8220;core game objects&#8221; and the time budget was 3 hours. I did <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cub2Fxbi5jb20vMjAxMS9tYXBwaW5nLXRoZS13b3JsZA==">did well for myself</a>, time to review the others&#8217; work &mdash; both of which included monsters.
</p>

<p>
Luke <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuZmFudGFzeWFkdmVudHVyZWdhbWUuY29tLzIwMTEvMDYvMTIvZGlyZS1iZWFycy1hbmQtbXlzdGVyaWVzLW9oLW15Lw==">did well</a> this week as he started to build out his combat system, including party members who (unless he&#8217;s hacked it in, but it doesn&#8217;t look that way) respond to locations and enemies. It&#8217;s a start at gameplay, though your choices are pretty limited so far. I like the idea in the blog post about having party members you can configure but not directly control, it reminds me of Ogre Battle.
</p>

<p>
Also, he&#8217;s started the storyline, including &#8220;the fact that the bear can’t seem to find you is important&#8221;. When you <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZhbnRhc3lhZHZlbnR1cmVnYW1lLmNvbS8=">play</a>, the bear enemy appears to be completely incapable of attacking you. Just for wild-ass guessing&#8217;s sake, I&#8217;m going to guess the player starts as some kind of ghost. We&#8217;ll see how I did when the storyline takes shape.
</p>

<p>
Jim&#8230; <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9jb250cm9sbGluZy1jb250cm9sbGVycw==">continued to work</a> on the controllers for his web framework, as he did <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAxMS9zcHdhLXdlZWstMi1mdW5kaW5nLWFuZC1mb3Jtcw==">last week</a>. I felt like this:
</p>

<blockquote style="color: #e3e3e3; background-color: #000000; border-radius: 8px; font-family: courier, monospace;">
<p>&gt; Application creates CommandRouter and TemplateDisplay instances</p>

<p>I&#8217;m very happy for it.</p>

<p>&gt; Application retrieves Events from the CommandRouter for the current Post data (usually none)</p>

<p>So, it&#8217;s like how PHP populates $_GET and $_POST for you before invoking a script, but redundant.</p>

<p>&gt; Application retrieves Events from the CommandRouter for the current URI</p>

<p>Events are sounding awfully general purpose. Wasn&#8217;t this a game? I feel faint.</p>

<p>&gt; Application loops through the current events (events can be added while processing other events) and calls the CommandRouter->ProcessEvent() method for each one</p>

<p>It&#8217;s a generic message queueing system. The world is going dim&#8230;</p>

<p>&gt; CommandRouter creates any necessary controller and sub-display instance for the event and passes all data to any module event handlers registered for the current event</p>

<p>It is pitch black. You are likely to be eaten by a grue.</p>

<p>&gt; Created controllers determine models to use which add their data to the relevant Display objects (which are further applied to the TemplateDisplay instance)</p>

<p>No, really, a grue. It eats developers who don&#8217;t finish games.</p>

<p>&gt; Application renders the TemplateDisplay</p>

<p>The grue dies of boredom.</p>
</blockquote>

<p>
Jim <a href="">mentioned</a> he liked the Mortal Kombat drawing last week. I guess he didn&#8217;t click on it. It&#8217;s a link to a <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL21ha2VnYW1lcy50dW1ibHIuY29tL3Bvc3QvMTEzNjYyMzc2Ny9maW5pc2hpbmctYS1nYW1l">great article</a>, which includes:
</p>

<blockquote>
<p><b>3. DON’T ROLL YOUR OWN TECH IF YOU DON’T HAVE TO</b></p>

<p>
There are pros and cons to writing your own engine. But ask yourself, do you
really have to? Is what you want to do impossible to do with what’s already out
there or would you be reinventing the wheel? Of course, if you write your own
engine you can make it just perfect the way you like it. But be honest, how
often do you ever get past the engine to the game itself? Do you find yourself
making game engines more often than you do games?
</p>
</blockquote>

<p>
Bring the thunder, Jim.
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1783" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/now-featuring-monsters/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>SPWA Week 2: Funding and Forms</title>
		<link>http://push.cx/2011/spwa-week-2-funding-and-forms</link>
		<comments>http://push.cx/2011/spwa-week-2-funding-and-forms#comments</comments>
		<pubDate>Sat, 11 Jun 2011 00:03:25 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[satisficing]]></category>
		<category><![CDATA[so play we all]]></category>
		<category><![CDATA[templating]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1767</guid>
		<description><![CDATA[So Play We All is partly a motivation hack, with teammates/competitors and penalties to make sure we each put in time towards our games. Luke&#8217;s job sent him to a conference for almost all of the week, so he didn&#8217;t get to do any of his hours. He&#8217;s paying us both $20. To keep anyone [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb3BsYXl3ZWFsbC5jb20=">So Play We All</a> is partly a motivation hack, with teammates/competitors and penalties to make sure we each put in time towards our games. Luke&#8217;s job sent him to a conference for almost all of the week, so he didn&#8217;t get to do any of his hours. He&#8217;s paying us both $20. To keep anyone from falling behind, we&#8217;ve tweaked the rules to say that anyone who pays the penalty for missed hours can make them up when they have the time.
</p>

<p>
Meanwhile, Jim&#8217;s done great, getting code live for the first time. I took a screenshot:
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDYvU2VsZWN0aW9uXzAwMS5wbmc="><img src="http://push.cx/wp-content/uploads/2011/06/Selection_001.png" alt="Allabrilyn Exclusive First Screenshot!" title="Allabrilyn Exclusive First Screenshot!" width="767" height="32" class="alignnone size-full wp-image-1769" /></a>

<p>
The first page has a simple login form. There&#8217;s no way to register an account, and any login/password you enter gives you the above message. In his <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9sb25nLXdheS1jb2Rl">blog post</a>, Jim wrote about the code 
</p>

<blockquote>
At that point, it was a fairly easy task to take the user object and add its data to the display for rendering. I chose to go with something like:

<blockquote>
Hello %user%! Your account was created at %time% on %date% and you last logged in at %time% on %date%. Enjoy your stay!
</blockquote>
</blockquote>

<p>
<b>STOP IT</b>. You are writing a template language in a template language! Templates are the one thing PHP actually does pretty decently (well, it&#8217;s not <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5oYW1sLWxhbmcuY29t">Haml</a>, but it&#8217;s way better than <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3dpa2kuem9wZS5vcmcvWlBUL1RBTFNwZWNpZmljYXRpb24xNA==">TAL</a>)! Wrap PHP&#8217;s output buffering around <kbd>include()</kbd> and get on with your life before you find yourself implementing conditionals and loops.
</p>

<p>
This is part of a larger topic I have to respond to:
</p>

<blockquote>
<p>This is mostly because I had to rush myself just to even get this far and put in lots of sloppy code. So, I&#8217;ve decided that I don&#8217;t care how far ahead the others get, I am not going to worry about matching their pace.</p>

<p>Really, it was an unrealistic goal that I&#8217;m glad to be letting go of. They&#8217;re using a pre-built framework which means they have options to solve a lot of their issues right out of the box. I, on the other hand, have to implement even my low-level functionality. This means that I&#8217;m going to be slower to execute no matter what happens. That&#8217;s the price that I pay for wanting to use my own implementation. The positive upside is that once I manage to solve these issues, they&#8217;ll be solved for me in all of my future games and I&#8217;ll be able to skip this tedium the next time around. &#8230;</p>

<p>Sure, it slows me down in terms of this competition, however, I will have 100% control over every aspect of the process which is not something that I would have if I were to leverage Drupal to build the game.</p>
</blockquote>

<p>
I know you write good code, Jim, but <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TYXRpc2ZpY2U=">satisfice</a>, man. You&#8217;ve got the worst time demands of all of us. Luke and I aren&#8217;t barfing into our editors and making sure it passes a syntax check, we&#8217;re taking acceptable components from other people so we spend our time on the important bits.
</p>

<p>
Last week I <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cub2Fxbi5jb20vMjAxMS93ZWVrLTItcHJldHR5LXNoYW1lbGVzcw==">bought and added a theme to Oaqn</a>. I was hugely tempted to tear it apart and make sure everything was perfect, with semantic class names and no unused code and efficient selectors and and and&#8230; Instead I added achievements, a feature that will help inspire and retain players for the lifetime of my game. That code&#8217;s not perfect, either, I already know I&#8217;ll want to tweak it to add some kind of bronze/silver/gold upgrading medals &mdash; but now I&#8217;ve got something decent in place and I can get closer to a running game.
</p>

<a href=http://makegames.tumblr.com/post/1136623767/finishing-a-game""><img src="http://push.cx/wp-content/uploads/2011/06/finishgame01.jpg" alt="" title="Finish a game" width="500" height="300" class="alignnone size-full wp-image-1770" /></a>

<p>
<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL21ha2VnYW1lcy50dW1ibHIuY29tL3Bvc3QvMTEzNjYyMzc2Ny9maW5pc2hpbmctYS1nYW1l">Finish a game</a>. So Play We All.
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1767" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/spwa-week-2-funding-and-forms/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>SPWA Week 1 Response: Code Hassles and Kittens</title>
		<link>http://push.cx/2011/spwa-week-1-response-code-hassles-and-kittens</link>
		<comments>http://push.cx/2011/spwa-week-1-response-code-hassles-and-kittens#comments</comments>
		<pubDate>Fri, 03 Jun 2011 19:48:41 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[Fantasy Adventure]]></category>
		<category><![CDATA[so play we all]]></category>
		<category><![CDATA[web games]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1749</guid>
		<description><![CDATA[This week in So Play We All our topic was &#8220;Signup&#8221; and our budget was 4 hours. I originally pushed for more time, but I ended up glad that it was short as I hacked things out on the last day. I don&#8217;t need to belabor that, let&#8217;s look at how Luke and Jim did [...]]]></description>
			<content:encoded><![CDATA[<p>
This week in <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=L3RhZy9zby1wbGF5LXdlLWFsbA==">So Play We All</a> our topic was &#8220;Signup&#8221; and our budget was 4 hours. I originally pushed for more time, but I <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cub2Fxbi5jb20vd2Vlay0xLXNpZ251cA==">ended up glad</a> that it was short as I hacked things out on the last day. I don&#8217;t need to belabor that, let&#8217;s look at how Luke and Jim did with their games.
</p>

<h3>Allabrilyn</h3>

<p>
Jim wrote about a <a
href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9kaWZmaWN1bHQteWV0LXJld2FyZGluZw==">lot of
technical progress</a>, but unfortunately it all falls into the category of
invisible infrastructure, there&#8217;s nothing for a player to see. It really
reminded me what a huge boost <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5oZXJva3UuY29t">Heroku</a> is for
hosting: not only is initial deployment about 5 minutes, it prevents you from
spending time tinkering with your server setup for only minimal gains. (I don&#8217;t
know how he got more votes than me, I suspect sympathy from similarly
frustrated PHP coders.) 
</p>

<blockquote>
In all, it&#8217;s been a difficult 4 hours&#8230; but well worth the effort, in my opinion. I believe the extra headaches I&#8217;m taking now will allow me better flexibility in the long-term.
</blockquote>

<p>
The bulk of his post seems to be about improving his own <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9PYmplY3QtcmVsYXRpb25hbF9tYXBwZXI=">ORM</a> and site infrastructure. Ouch. It sounds like he&#8217;s written some nice code, but this contest is about building one game, not building the next ten games.
</p>

<p>
Maybe the Real Ultimate Power of Drupal will make it a breeze to drop in community features like a forum and a chat, but right now he has nothing to see and he&#8217;s falling behind.
</p>

<h3>Fantasy Adventure</h3>

<p>
I&#8217;m glad to hear <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=IGh0dHA6Ly9ibG9nLmZhbnRhc3lhZHZlbnR1cmVnYW1lLmNvbS8yMDExLzA2LzAxL2luLXdoaWNoLWx1a2UtcmVhbGl6ZXMtaGUtaGFzbnQtcGxhbm5lZC1lbm91Z2gv">Luke&#8217;s stepping up his game</a> after his brief blog posts for week 0. Not that I don&#8217;t mind easy competition, but I don&#8217;t want people to think I rigged the contest by setting myself up against a sucker. :)
</p>

<p>
In seriousness, Luke did great this week, he got my vote <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvbW11bml0eS5iYmdhbWV6b25lLm5ldC9wcm9qZWN0cy9zby1wbGF5LXdlLWFsbC13ZWVrLTEtc2lnbnVwLw==">in the poll</a>. We both used Devise for registration, but he got his basic install much faster and then streamlined it to make it easier for people to get into his game.
</p>

<p>
Yes, into his game! I&#8217;m not sure if it&#8217;s just static text or he created a basic player object with a few attributes, but he threw together a decent template and you could click around to move between different locations. Currently there&#8217;s just a bit of cute story to read, but that&#8217;s enough for the player&#8217;s imagination to start filling in gaps and imaging a world. (Also, bonus points for using <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3BsYWNla2l0dGVuLmNvbS8=">delightful PlaceKittens</a>, I&#8217;ve bookmarked that as a resource.)
</p>

<p>
That ability to fire the imagination is a great sign for Luke&#8217;s prospects. Time for me to go step up my game in response.
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1749" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/spwa-week-1-response-code-hassles-and-kittens/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SPWA Week 0 Response: A Strong Start</title>
		<link>http://push.cx/2011/spwa-week-0-response-a-strong-start</link>
		<comments>http://push.cx/2011/spwa-week-0-response-a-strong-start#comments</comments>
		<pubDate>Tue, 31 May 2011 18:05:59 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Allabrilyn]]></category>
		<category><![CDATA[Fantasy Adenture Game]]></category>
		<category><![CDATA[oaqn]]></category>
		<category><![CDATA[so play we all]]></category>
		<category><![CDATA[web games]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1745</guid>
		<description><![CDATA[As mentioned in the rules for So Play We All, we&#8217;re required to respond to each other&#8217;s progress update. I&#8217;m going to be doing the Oaqn progress updates on that blog but the feedback here, mostly to keep that blog focused. Showing off his superior time management skills, Jim quickly posted about Allabrilyn. It sounds [...]]]></description>
			<content:encoded><![CDATA[<p>
As mentioned in <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=LzIwMTEvc28tcGxheS13ZS1hbGw=">the rules</a> for <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb3BsYXl3ZWFsbC5jb20=">So Play We All</a>, we&#8217;re required to respond to each other&#8217;s progress update. I&#8217;m going to be doing the Oaqn <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cub2Fxbi5jb20vMjAxMS93ZWVrLTAtZ2V0dGluZy1zdGFydGVk">progress updates</a> on that blog but the feedback here, mostly to keep that blog focused.
</p>

<p>
Showing off his superior time management skills, Jim quickly <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vY29udGVudC9maXJzdA==">posted about Allabrilyn</a>. It sounds like a collectible card game (or maybe <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5pY3YyLmNvbS9hcnRpY2xlcy9pbmRleF9wcmludC5waHA/YXJ0aWNsZV9pZD0xNjk1OA==">LCG</a>). That the collectible elements are units for a tactical game is&#8230; <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=L3RhZy9hdGhlbmdl">awfully familiar</a>.
</p>

<p>
I dropped Athenge as a project because I realized I love the genre, but it&#8217;s actually really uncommon. Tactical wargames have a hardcore fanbase (a blessing and a curse), but it&#8217;s certainly not a big one. And building a game around PVP that&#8217;s mostly based on the player&#8217;s skill progression means there&#8217;s going to be a lot of dissatisfied bad players who don&#8217;t want to participate. So I think it&#8217;s great that Jim is building my kind of game, but I worry about his market. (And Jim &#8211; don&#8217;t just sell random packs, add a premium currency that players can use to auction/sell cards between themselves with so that you don&#8217;t create a secondary market that gives you support hassles but not income.)
</p>

<p>
Next up, Luke <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuZmFudGFzeWFkdmVudHVyZWdhbWUuY29tLzIwMTEvMDUvMjEvdGhleWxsLW5ldmVyLXNlZS1pdC1jb21pbmcv">explained Fantasy Adventure Game</a>. I loved this post (though of course, not so much that I voted for it over myself). He&#8217;s immediately willing to be imperfect in public by beginning with a terrible working title. It&#8217;s a great sign for <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cucHJvdG9zaGFyZS5jb20vMjAxMS8wNC9nZXR0aW5nLW92ZXItZW1iYXJyYXNzbWVudC1hbmQtZ2V0dGluZy1kb25lLw==">getting over embarrassment</a> to develop something great. I&#8217;m terribly jealous that he included financial info from the start; I&#8217;d wanted to but it slipped my mind. More guts!
</p>

<p>
As for the game itself, it leaves me a little flat. I&#8217;ve seen too many games default to fantasy; I hope he finds ways to turn his ignorance into interesting genre redefinition rather than middle-of-the-road generictown. It really sounds like it&#8217;s a single-player RPG (having not played KOL), so I think he&#8217;s going to have problems with producing content (items, quests, skills, etc.). Multiplayer interaction, competitive or cooperative, is wonderful content because you can set up systems that players fill up with content. It takes a fraction of the time to code a PVP game like chess than it does to write a text adventure like Adventure, and chess is probably fun for far longer because it becomes about other people, and people are interested in people.
</p>

<p>
I also have one criticism to level at both games: there&#8217;s nothing for the player to identify with. In Oaqn, the player controls a single caravan, that&#8217;s them in the world. (And I very likely will add some kind of human player avatar to play dress-up with eventually, because that&#8217;s even better.) In Allabrilyn and FA, the player controls a collection of characters, so there&#8217;s nothing for them to feel represented by or invest in the well-being of. This is why RPGs (and many other games) have a <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3R2dHJvcGVzLm9yZy9wbXdpa2kvcG13aWtpLnBocC9NYWluL0hlcm9pY01pbWU=">heroic mime</a> character leading the party, so the player has an empty template to fill up with their personality. It&#8217;s much harder to do that with a deck of cards or a small troupe, and it&#8217;s a powerful motivator for casual online games.
</p>

<p>
My lengthy braindump <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvbW11bml0eS5iYmdhbWV6b25lLm5ldC9wcm9qZWN0cy9zby1wbGF5LXdlLWFsbC13ZWVrLTAv">rocked this week&#8217;s poll</a>, with 6 votes for me, 1 for FA, and 0 for Jim (who I guess is not even active enough on the forums anymore to even vote for himself). I&#8217;m happy for that, but I think I&#8217;m going to face stiff competition that&#8217;s constantly thinking of things I&#8217;ve missed. So all I can do is plan to steal those things like revenue details for next week, muahaha! (Speaking of which, I&#8217;d better go put in my hours before I wind up owing these guys money.)
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1745" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/spwa-week-0-response-a-strong-start/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>So Play We All</title>
		<link>http://push.cx/2011/so-play-we-all</link>
		<comments>http://push.cx/2011/so-play-we-all#comments</comments>
		<pubDate>Mon, 23 May 2011 21:21:13 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Biz]]></category>
		<category><![CDATA[browser games]]></category>
		<category><![CDATA[oaqn]]></category>
		<category><![CDATA[so play we all]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1736</guid>
		<description><![CDATA[Peter Harkins, Jim C. Gadrow, and Luke Hutscal are each building an online game as part of a contest between us. Every week we&#8217;ll pick a new area of our games to code on and budget how many hours to spend on it. Every week, someone will be judged to have done the best. Anyone [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3g=">Peter Harkins</a>, <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5qZ2Fkcm93LmNvbQ==">Jim C. Gadrow</a>, and <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NyZWF0dXJlY3JlYXRpdmUuY29t">Luke Hutscal</a> are each building an online game as part of a contest between us. Every week we&#8217;ll pick a new area of our games to code on and budget how many hours to spend on it. Every week, someone will be judged to have done the best. Anyone who doesn&#8217;t put in the time pays the price by funding the others&#8217; games. Anyone who quits has to delete their entire codebase and all backups. 
</p>

<p class="update">
2011-06-13: We&#8217;ve built a website with the current rules and progress updates at <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb3BsYXl3ZWFsbC5jb20=">So Play We All</a>.
</p>

<h3>Our Rules</h3>

<ol>
<li>&#8220;<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3lvdXR1LmJlLzJ0SmpOVlZ3UkNZP3Q9MW0=">Fuck it, we&#8217;ll do it live.</a>&#8221; Games are live as currently developed, even if they suck, starting from &#8220;but it&#8217;s just a login screen&#8221;. Develop on master, develop on prod box if you have to, but don&#8217;t hold any code back.</li>
<li>Each week we&#8217;ll collectively choose how many hours to spend on our games and a non-mandatory topic. Anyone who doesn&#8217;t spend the time (or cheats and spends more) funds the other games by giving a $20 gift card to each other player for game-related expenses (eg. ThemeForest, Linode, AdWords). If you finish early, you rock. Boast a little bit and make the others bow to your awesomeness. (Exception for suiting up: if you have to wear a suit to a funeral, a close family wedding, or a court date, you are allowed to miss that week. No other exceptions, not even dismemberment.)</li>
<li>Deadline is Wednesday at noon GMT to deploy code and publish a blog post, schedule it to make it happen.</li>
<li>A <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5iYmdhbWV6b25lLm5ldA==">BBGameZone forum</a> poll judges who won that week, 24h window.</li>
<li>By Saturday noon GMT, write a blog post to respond to others&#8217; updates, talk smack, enjoy victory, critique game design, suggest improvements, etc.</li>
<li>Not just OK but encourage to find or buy assets: art, themes, libraries, modules. You can reuse your own pet library as long as it has been released publicly before that week, but outsourcing code is forbidden.</li>
<li>Whoever reaches $10k in profit first wins the contest. But whoever turns their game into a full-time job wins all the bragging rights.</li>
<li>Rules can change by unanimous acclaim.</li>
</ol>

<p>
So say we all. So play we all.
</p>

<h3>Week 0</h3>

<p>
We&#8217;ve already gotten under way, the goal for our first week was to pick a domain name, set up a blog, and write a blog post describing out game. Here&#8217;s my blog post about <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cub2Fxbi5jb20vMjAxMS93ZWVrLTAtZ2V0dGluZy1zdGFydGVk">Oaqn</a>, a game about trading. Please <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2NvbW11bml0eS5iYmdhbWV6b25lLm5ldC9wcm9qZWN0cy9zby1wbGF5LXdlLWFsbC13ZWVrLTAv">vote for it</a> on bbgz if you&#8217;re on the forums.
</p>

<p>
And here&#8217;s <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuZmFudGFzeWFkdmVudHVyZWdhbWUuY29tLzIwMTEvMDUvMjEvdGhleWxsLW5ldmVyLXNlZS1pdC1jb21pbmcv">Luke&#8217;s post</a> and <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuYWxsYWJyaWx5bi5jb20vbm9kZS8x">Jim&#8217;s post</a> about their games.
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1736" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/so-play-we-all/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Software Craftsmanship Tour: Aidan Rogers</title>
		<link>http://push.cx/2011/software-craftsmanship-tour-aidan-rogers</link>
		<comments>http://push.cx/2011/software-craftsmanship-tour-aidan-rogers#comments</comments>
		<pubDate>Wed, 30 Mar 2011 04:08:59 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[craftsmanship tour]]></category>
		<category><![CDATA[interfaces]]></category>
		<category><![CDATA[object orientation]]></category>
		<category><![CDATA[open question]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1731</guid>
		<description><![CDATA[A few weeks ago I met up with Aidan Rogers to hack on some code. Aidan and I were coworkers at Cambrian House a few years ago. Aidan and I hacked away at adding a feature to a Web App That Shall Not Be Named. User authentication was handled by Facebook or Twitter, so the [...]]]></description>
			<content:encoded><![CDATA[<p>
A few weeks ago I met up with <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3R3aXR0ZXIuY29tL2FpZGFuX3JvZ2Vycw==">Aidan Rogers</a> to hack on some code. Aidan and I were coworkers at <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=L3RhZ3MvY2FtYnJpYW4taG91c2U=">Cambrian House</a> a few years ago. 
</p>

<p>
Aidan and I hacked away at adding a feature to a Web App That Shall Not Be Named. User authentication was handled by Facebook or Twitter, so the feature was to fetch and list their friendships from their social network. The code in <kbd>app/models/user.rb</kbd> was straightforward, taking an object from authentication:
</p>

<pre>&nbsp;
<span style="color: #808080; font-style: italic;"># Update the database with the user's current list of friends.</span>
<span style="color: #808080; font-style: italic;"># Compares a fresh list to the existing list to minimize database writes.</span>
def update_friends<span style="color: #66cc66;">&#40;</span>auth<span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;"># fetch current list of friendships as hashes</span>
  provider_friendships = auth.<span style="">retrieve_friendships</span>
  <span style="color: #808080; font-style: italic;"># load already-stored friendships to hashes</span>
  stored_friendships = friendships.<span style="">send</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">"on_#{auth.provider}"</span><span style="color: #66cc66;">&#41;</span>.<span style="">map</span> <span style="color: #66cc66;">&#123;</span> |friend| <span style="color: #66cc66;">&#123;</span>:id =&gt; friend.<span style="">friend_id</span>, :name =&gt; friend.<span style="">friend_name</span><span style="color: #66cc66;">&#125;</span> <span style="color: #66cc66;">&#125;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># compare the two lists of hashes</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># add any new friends to the database</span>
  <span style="color: #66cc66;">&#40;</span>provider_friendships - stored_friendships<span style="color: #66cc66;">&#41;</span>.<span style="">each</span> <span style="color: #b1b100;">do</span> |friend|
    friendships.<span style="">create</span>!<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span>
      :friend_id =&gt; friend<span style="color: #66cc66;">&#91;</span>:id<span style="color: #66cc66;">&#93;</span>,
      :friend_name =&gt; friend<span style="color: #66cc66;">&#91;</span>:name<span style="color: #66cc66;">&#93;</span>,
      :provider =&gt; auth.<span style="">provider</span>,
    <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">end</span>
&nbsp;
  <span style="color: #808080; font-style: italic;"># delete any removed friends from the database</span>
  <span style="color: #66cc66;">&#40;</span>stored_friendships - provider_friendships<span style="color: #66cc66;">&#41;</span>.<span style="">each</span> <span style="color: #b1b100;">do</span> |friend|
    friendships.<span style="">destroy_all</span><span style="color: #66cc66;">&#40;</span>:conditions =&gt; <span style="color: #66cc66;">&#123;</span> :friend_id =&gt; = friend<span style="color: #66cc66;">&#91;</span>:id<span style="color: #66cc66;">&#93;</span>, :friend_name =&gt; friend<span style="color: #66cc66;">&#91;</span>:name<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">end</span>
end</pre>

<p>
That code isn&#8217;t very complicated, but it&#8217;s worth noting before you read the next snipped that we were both new to the Facebook/Twitter APIs and <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2MyLmNvbS9jZ2kvd2lraT9TcGlrZVNvbHV0aW9u">spiking</a> functionality rather than trying to write production quality code.
</p>

<p>
Keep that in mind as you read the code we added to the authentication object. It works, but it could definitely be better written (left as an exercise to the reader, because, well, we only spiked, so I haven&#8217;t actually written a better version to present).
</p>

<pre>&nbsp;
def retrieve_friendships
  <span style="color: #b1b100;">if</span> provider == <span style="color: #ff0000;">"facebook"</span>
    <span style="color: #808080; font-style: italic;"># made the Facebook API call</span>
    user = FbGraph::<span style="color: #006600;">User</span>.<span style="">me</span><span style="color: #66cc66;">&#40;</span>self.<span style="">data</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'credentials'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'token'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># map it to an array of hashes</span>
    <span style="color: #000066;">return</span> user.<span style="">friends</span>.<span style="">map</span> <span style="color: #b1b100;">do</span> |friend|
      <span style="color: #808080; font-style: italic;"># check against the db to load their id</span>
      existing = Authentication.<span style="">where</span><span style="color: #66cc66;">&#40;</span>:uid =&gt; friend.<span style="">identifier</span>, =
:provider =&gt; <span style="color: #ff0000;">'facebook'</span><span style="color: #66cc66;">&#41;</span>.<span style="">first</span>
      <span style="color: #66cc66;">&#123;</span> :friend =&gt; existing ? existing.<span style="">user</span> : nil,
        :provider_id =&gt; existing ? nil : friend.<span style="">identifier</span>,
        :provider =&gt; <span style="color: #ff0000;">'facebook'</span> <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">end</span>
  <span style="color: #b1b100;">elsif</span> provider == <span style="color: #ff0000;">"twitter"</span>
    <span style="color: #808080; font-style: italic;"># Returns only 20 users at a time - is it important enough at this = point to add all the code for iterating? (aidan)</span>
    <span style="color: #808080; font-style: italic;"># return Twitter.friends(nickname).users.map{ |friend| Hash[ :id =&gt; = friend.id, :name =&gt; friend.screen_name, :provider =&gt; 'twitter' ]}</span>
    <span style="color: #000066;">return</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
  <span style="color: #b1b100;">else</span>
    raise <span style="color: #ff0000;">"Refactor me"</span>
  <span style="color: #b1b100;">end</span>
end</pre>

<p>
Having the authentication object test what provider API it should be loading from is an obvious <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2MyLmNvbS9jZ2kvd2lraT9Db2RlU21lbGw=">code smell</a>, but it&#8217;s not the one I want to talk about.
</p>

<p>
There&#8217;s an implicit type in use. Aidan and I referred to it as a <kbd>FriendHash</kbd>, it&#8217;s a normalization for comparing friendship objects from the app&#8217;s database and from different API calls. FriendHash would be a data class with just a smidge of validation code to account for all three attributes.
</p>

<p>
I&#8217;ve noticed these sneaking around code in the interfaces between objects. I don&#8217;t quite have a name for them, but I realize it touches a bit on <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2MyLmNvbS9jZ2kvd2lraT9EZXNpZ25CeUNvbnRyYWN0">design by contract</a>. The part that smells to me is that this code is spread amongst many places that need to be updated in sync with each other (not that this is terribly better if you have a class for it, but at least you can grep for references to it). I&#8217;m not a big fan of data classes, so I don&#8217;t love this solution.
</p>

<p>
What really frustrates me is that I&#8217;ve got enough experience to have a tingling intuition when I am attempting to re-solve some problem that surely someone else has analyzed and offered solutions to, but my resesarch hasn&#8217;t turned anything up.
</p>

<p>
So I&#8217;m posting to hear what folks think of this situation. Have you read anyone writing about these quiet but complex data types at interfaces, or do you have ideas for how to address them?
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1731" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/software-craftsmanship-tour-aidan-rogers/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grind Without Progression in Die2Nite</title>
		<link>http://push.cx/2011/die2nite-grind</link>
		<comments>http://push.cx/2011/die2nite-grind#comments</comments>
		<pubDate>Mon, 07 Mar 2011 19:26:33 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[collaboration]]></category>
		<category><![CDATA[experience]]></category>
		<category><![CDATA[game design]]></category>
		<category><![CDATA[grind]]></category>
		<category><![CDATA[P]]></category>
		<category><![CDATA[prisoner's dilemma]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1715</guid>
		<description><![CDATA[I&#8217;ve been playing the game Die2Nite with a few friends, and I&#8217;m fascinated that it has no character advancement &#8212; no levels, no skills, no upgrades &#8212; but it has a terrible grind. The Setup You are a survivor of the zombie apocalypse in a town with up to 39 other players. It runs on [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;ve been playing the game <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kaWUybml0ZS5jb20=">Die2Nite</a> with a few friends, and I&#8217;m fascinated that it has no character advancement &mdash; no levels, no skills, no upgrades &mdash; but it has a terrible grind.
</p>

<h3>The Setup</h3>

<img src="http://push.cx/wp-content/uploads/2011/03/join_a_random_town.png" alt="" title="&quot;Join a Random Town&quot; screenshot" width="511" height="47" class="alignnone size-full wp-image-1721 content" />

<p>
You are a survivor of the zombie apocalypse in a town with up to 39 other players. It runs on a 24 hour cycle, and each day you get six Action Points (refillable 1-3 times per day, depending on what items are available) to scavenge for items and build up shared town defenses. If you die (which can happen individually or because your town is overrun in the nightly zombie attack), you can join right back into a new town tomorrow.
</p>

<img src="http://push.cx/wp-content/uploads/2011/03/town_gates.png" alt="" title="Town Gates, preparing to scavenge" width="578" height="330" class="alignnone size-full wp-image-1726 content" />
<p>
The core game mechanic is a sort of iterated prisoner&#8217;s dilemma, you have to choose to keep things back from the town or contribute to the town, and then socializing with other players to decide what defenses to spend your very limited resources on.
</p>

<p>
But the basic prisoner&#8217;s dilemma isn&#8217;t much of a choice, you learn after the first town or two that it is always much better to collaborate with your town, you cannot survive solo at all. But this does take you a town or two to learn.
</p>

<p>
The typical town is dominated largely by newbies who haven&#8217;t yet learned the necessity of collaboration. They don&#8217;t form a majority of members, but it only takes a handful of newbies to waste key early resources or disable town defenses shortly before the attack. The mechanisms required to police this are weak, the game simply doesn&#8217;t report who wasted the resources to start construction of the wrong building.
</p>

<img src="http://push.cx/wp-content/uploads/2011/03/construction_begins.png" alt="" title="Log notice that construction began, no indication of who did this" width="547" height="35" class="alignnone size-full wp-image-1728 content" />

<h3>The Grind</h3>

<img src="http://push.cx/wp-content/uploads/2011/03/achivements.png" alt="" title="Achievements screenshot" width="254" height="111" class="alignright size-full wp-image-1723 aside" />
<p>
This is where the grind comes into play. You can collect experience points that carry over between towns. There&#8217;s still no character improvement, the only benefit is unlocking the ability to play in towns that require 100xp. That is, in towns that have no newbies.
</p>

<p>
The typical newbie-ridden town fails in 1-3 days due to wasted resources and compromised defenses, so a good attempt will earn you 6xp, but 1-3 is typical. You&#8217;re staring at 20-40 towns, 2-3 real-life months, before you can start in a town without newbies.
</p>

<img src="http://push.cx/wp-content/uploads/2011/03/trapped_by_zombies.png" alt="" title="Trapped by Zombies" width="584" height="139" class="alignnone size-full wp-image-1725" />
<p>
Experience points <em>really do </em> track player experience in this scenario. The player will definitely be very well-experienced by the time they reach the milestone. But it&#8217;s incredibly frustrating because you&#8217;ll be playing the same game over and over: day 1 everyone yells to build a workshop but someone wastes the needed resources on a portal lock instead, day 2 a bunch of people get stranded outside of town and need rescue, day 3 the town fails. (Sometimes this all happens on day 1, or someone doesn&#8217;t give the needed click to turn on the defenses so there&#8217;s a total party kill of the town.)
</p>

<p>
I&#8217;m in a guild (&#8220;coalition&#8221;) with two friends so we&#8217;ll appear in the same town, but none of us has moved to get us into a new town in two weeks because the game is so boringly repetitive. We understand the basic mechanics, but we simply can&#8217;t play because there are too many newbies and idiots. I could see this being an awesome game to play with a dozen friends, but I don&#8217;t want to subject them to several months of grind to get to the &#8220;real game&#8221;.
</p>

<h3>A Solution</h3>

<p>
One thing the game does do right is that if you join a guild with 100xp-friends you can still be pulled along to their town. You probably won&#8217;t be a problem newbie because you&#8217;ll be relying on your friends in a town that&#8217;s already running smoothly.
</p>

<p>
Spitballing with <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5hbW1vbmxhdXJpdHplbi5jb20vYmxvZw==">Ammon</a> (who I&#8217;m currently staying with <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=L2NyYWZ0c21hbnNoaXAtY2FsZW5kYXI=">in Austin, TX</a>), I think one improvement would be to start sorting players by experience points immediately. In addition to the 100xp cutoff, put players into towns with similar amounts of XP every time they join a new town.
</p>

<p>
Each successive town the player joins they&#8217;ll see fewer newbies in a town that survives a little longer. Even if there&#8217;s a bit of a grind up to 100xp, it&#8217;ll be more fun because you&#8217;ll see new things each town.
</p>

<p>
Second, the game really needs to give complete disclosure of who spent resources so that experienced players can quickly and directly responds to newbie wastage. If a newbie already isn&#8217;t paying attention to the forums (where people always repost the now-standard Day 1 strategy), they&#8217;re not going to learn what not to do because no one knows who they are to reach out to (and perhaps smack) them.
</p>

<p>
I know a lot of my readers think about game design, what are your solutions? You have a game that&#8217;s built around collaboration with other players, but it&#8217;s frustrating because new players can&#8217;t effectively collaborate.
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1715" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/die2nite-grind/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Retracting my JungleDisk Recommendation</title>
		<link>http://push.cx/2011/retracting-my-jungledisk-recommendation</link>
		<comments>http://push.cx/2011/retracting-my-jungledisk-recommendation#comments</comments>
		<pubDate>Sat, 19 Feb 2011 19:12:07 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[JungleDisk]]></category>
		<category><![CDATA[tarsnap]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1694</guid>
		<description><![CDATA[Over the last few years I&#8217;ve recommended JungleDisk to a lot of people, so a blog post is the most efficient way to retract that recommendation. I&#8217;ve been increasingly dissatisfied with it since Rackspace bought the company. They added a monthly fee on top of storage costs for no reason, stopped issuing source code to [...]]]></description>
			<content:encoded><![CDATA[<p>
Over the last few years I&#8217;ve recommended JungleDisk to a lot of people, so a blog post is the most efficient way to retract that recommendation.
</p>

<p>
I&#8217;ve been increasingly dissatisfied with it since Rackspace bought the company. They added a monthly fee on top of storage costs for no reason, stopped issuing source code to a standalone program for retrieving data, performance hasn&#8217;t kept up with my growth in usage (open dialog to choose which files to back up, get coffee), it does an 80MB download on every startup, backups of even a few K finish with a tens-of-megs metadata upload, and now they plan to reduce client-side functionality.
</p>

<blockquote>
<h3>2. New Web-based User Interface</h3>
In the spirit of flexibility and accessibility, the next release will have the configuration and setup totally managed via a web-based user interface vs. one that is incorporated into the computer’s operating system.  In one simple interface, you will be able to manage every user and computer in a secure web experience that is familiar regardless if you are managing a Windows, Mac or Linux machine.  This aspect of the update has been a huge undertaking for us because we want this to be a great user experience.  Luckily, we have some pretty amazing talent that is helping us to build a truly awesome UI.
<cite><a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuanVuZ2xlZGlzay5jb20vMjAxMS8wMS8yNi90aGUtcm9hZC1haGVhZC0yLw==">The Road Ahead</a> from the JungleDIsk blog</code>
</blockquote>

<p>
While JungleDisk used to sport "you don't have to trust us" encryption, this new UI means they'll need to keep a list of all of your files. And as much as I love the web, the desktop UI to JungleDisk is already painfully slow and clunky; the web adds network latency, browser overhead, and a much-reduced selection of widgets.
</p>

<p>
This is the last straw for me. After surveying the field I've settled on <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RhcnNuYXAuY29t">tarsnap</a>. I'll write another post with more information on why I chose it and how I've set it up (it's a pretty low-level tool) when I've finished the big re-upload, cleaned up the remainders of JungleDisk, and settled into a regular rhythm.
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1694" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/retracting-my-jungledisk-recommendation/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dropbox and Git Play Well Together</title>
		<link>http://push.cx/2011/dropbox-and-git</link>
		<comments>http://push.cx/2011/dropbox-and-git#comments</comments>
		<pubDate>Tue, 15 Feb 2011 04:57:42 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1684</guid>
		<description><![CDATA[Chrys Wu asked me my thoughts about how to have easy access to a software project she&#8217;s working on so that she can conveniently access them from the several computers she uses regularly. Not all of them can be set up as development machines, so a standard version control system can&#8217;t be used alone. That [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Nocnlzd3UuY29t">Chrys Wu</a> asked me my thoughts about how to have easy access to a software project she&#8217;s working on so that she can conveniently access them from the several computers she uses regularly. Not all of them can be set up as development machines, so a standard version control system can&#8217;t be used alone.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly93d3cuZHJvcGJveC5jb20vcmVmZXJyYWxzL05URTFNRGN3TVRBNE9RP3NyYz1nbG9iYWw5"><img src="http://push.cx/wp-content/uploads/2011/02/dropbox-logo.png" alt="" title="Dropbox logo" width="231" height="60" class="alignright size-full wp-image-1697" /></a>
<p>
That calls for a way to sync files, and <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly93d3cuZHJvcGJveC5jb20vcmVmZXJyYWxzL05URTFNRGN3TVRBNE9RP3NyYz1nbG9iYWw5">Dropbox</a> is by far the most convenient way to do so. Dropbox Just Works to copy files between computers, whether on Linux, OS, or Windows. Even an IT department that doesn&#8217;t want to install a development suite will probably be OK with it.
</p>

<p>
But software always <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RvbS5wcmVzdG9uLXdlcm5lci5jb20vMjAwOS8wNS8xOS90aGUtZ2l0LXBhcmFibGUuaHRtbA==">calls for version control</a>, it&#8217;s essential to keep track of changes. Git happens to be the right version control software for her project, so here&#8217;s the steps we worked through to set up her environment.
</p>

<p>
First, she created her repository inside her Dropbox folder. We&#8217;ll call this the <kbd>dropbox</kbd> repo.
</p>

<pre>&nbsp;
desktop:~/Dropbox $ git init project
desktop:~/Dropbox $ <span style="color: #000066;">cd</span> project
desktop:~/Dropbox/project $ <span style="color: #808080; font-style: italic;"># create and commit first files</span></pre>

<p>
Now she has convenient access to her files across her computers, but there&#8217;s a pitfall: if she were to edit and commit to the <kbd>dropbox</kbd> repo on two machines that were offline, Dropbox would merge the git metadata in unpredictable ways. Each machine needs its own repository for work done in it, then changes can be deliberately pulled up to the authoritative Dropbox repository for integration. Edits done on a machine without git installed can be left in the Dropbox repo until they can be checked in, which works well enough for this scenario.
</p>

<p>
Creating a local repository is simple:
</p>

<pre>&nbsp;
laptop:~/ $ git clone ~/Dropbox/project
laptop:~/ $ git remote -v
origin  /home/username/Dropbox/project/ <span style="color: #66cc66;">&#40;</span>fetch<span style="color: #66cc66;">&#41;</span>
origin  /home/username/Dropbox/project/ <span style="color: #66cc66;">&#40;</span>push<span style="color: #66cc66;">&#41;</span>
laptop:~/ $ <span style="color: #000066;">cd</span> project
laptop:~/project/ $ git pull <span style="color: #808080; font-style: italic;"># to get the latest changes</span></pre>

<p>
The <kbd>laptop</kbd> repo shows that it knows about the <kbd>dropbox</kbd> repo, and a <kbd>git pull</kbd> will bring in any changes. But <kbd>git push</kbd> will give a <strong>giant error</strong>:
</p>

<pre>&nbsp;
laptop:~/project/ $ git push
Counting objects: <span style="color: #cc66cc;">157</span>, <span style="color: #b1b100;">done</span>.
Delta compression using up to <span style="color: #cc66cc;">2</span> threads.
Compressing objects: <span style="color: #cc66cc;">100</span>% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">152</span>/<span style="color: #cc66cc;">152</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #b1b100;">done</span>.
Writing objects: <span style="color: #cc66cc;">100</span>% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">157</span>/<span style="color: #cc66cc;">157</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #cc66cc;">982</span>.<span style="color: #cc66cc;">50</span> KiB, <span style="color: #b1b100;">done</span>.
Total <span style="color: #cc66cc;">157</span> <span style="color: #66cc66;">&#40;</span>delta <span style="color: #cc66cc;">44</span><span style="color: #66cc66;">&#41;</span>, reused <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&#40;</span>delta <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch <span style="color: #b1b100;">in</span> a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require <span style="color: #ff0000;">'git reset --hard'</span> to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can <span style="color: #000066;">set</span> <span style="color: #ff0000;">'receive.denyCurrentBranch'</span> configuration variable to
remote: error: <span style="color: #ff0000;">'ignore'</span> or <span style="color: #ff0000;">'warn'</span> <span style="color: #b1b100;">in</span> the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed <span style="color: #b1b100;">in</span> some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, <span style="color: #000066;">set</span>
remote: error: <span style="color: #ff0000;">'receive.denyCurrentBranch'</span> configuration variable to <span style="color: #ff0000;">'refuse'</span>.
To /home/username/Dropbox/project/
 ! <span style="color: #66cc66;">&#91;</span>remote rejected<span style="color: #66cc66;">&#93;</span> master -&gt; master <span style="color: #66cc66;">&#40;</span>branch is currently checked out<span style="color: #66cc66;">&#41;</span>
error: failed to push some refs to <span style="color: #ff0000;">'/home/username/Dropbox/project/'</span></pre>

<p>
This is one of git&#8217;s more <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3N0ZXZlLXBhcmtlci5vcmcvYXJ0aWNsZXMvb3RoZXJzL3N0ZXBoZW5zb24vaG9sZWhhd2cuc2h0bWw=">unix-like</a> error messages, in that it makes sense once you already understand it and happens because git is an incredibly powerful, flexible tool that assumes you know what you&#8217;re doing. Let&#8217;s walk through the error.
</p>

<p>
Everything down to the &#8220;Total&#8221; line is git giving you information about how it&#8217;s packaging the data to send between repositories and is normal.
</p>

<p>
The first paragraph is warning that you&#8217;re pushing code to what&#8217;s currently being worked on in the other repository (the &#8220;checked out branch&#8221;). Git can&#8217;t know that the other one is just files sitting around &#8211; what if it&#8217;s some other user&#8217;s, and he&#8217;s in the middle of editing things? Well, if someone else might be using it, we can&#8217;t update the files in the working copy, because it would trash his work. But if git doesn&#8217;t do that, the remote repo knows that it&#8217;s not at HEAD &#8211; meaning the next commit will confusingly create a branch.
</p>

<p>
The second paragraph is saying &#8220;If you&#8217;re sure you know what you&#8217;re doing, you can configure the remote repository to let you do this.&#8221;
</p>

<p>
The third is saying &#8220;Or you can just tell me to shut up.&#8221;
</p>

<p>
Finally, the last few lines are git attempting finish the push. It says &#8220;OK, with everything ready, I&#8217;m going to push&#8221; and then &#8220;Wait, I couldn&#8217;t push from my master to the remote master&#8221; and &#8220;you told me to push at least one branch and at least one failed&#8221; (in this case, excatly 1 and 1). In short, git is refusing to take the risk of maybe screwing up work.
</p>

<p>
There are two responses.
</p>

<p>
The first is to make the Dropbox repository a &#8220;bare repository&#8221;. That means it will have all the history of the project, but no checked-out, editable copies of the project. That would stop you from conveniently reading the files wherever you happened to be, though. When you have a repository on GitHub, that copy on their servers is a bare repo &#8211; GitHub doesn&#8217;t have any interest in editing the files and doesn&#8217;t want you to have this problem.
</p>

<p>
The second is simpler, and what you want to do for this situation. Pulling changes is always OK, because git knows you know what you&#8217;re doing with the current repo. So, from the <kbd>dropbox</kbd> repo:
</p>

<pre>&nbsp;
laptop:~/Dropbox/project $ git remote add laptop ~/project
laptop:~/Dropbox/project $ git pull laptop master <span style="color: #808080; font-style: italic;"># note that you have to name what branch to pull from</span>
From /home/username/project
 * branch           master -&gt; FETCH_HEAD</pre>

<p>
Git reports the path to the repo it&#8217;s pulling from and which branches it was able to update, in this case <kbd>master</kbd> from what it found on the remote <kbd>HEAD</kbd>. Success!
</p>

<p>
All that&#8217;s needed to add more machines is to run the <kbd>git clone</kbd> on them and then, from the <kbd>dropbox</kbd> repo, add them as remotes for pulling changes.
</p>

<p>
Dropbox and git play nicely when you need their different strengths.
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1684" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/dropbox-and-git/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Craftsmanship Tour: Jim Ray</title>
		<link>http://push.cx/2011/craftsmanship-tour-jim-ray</link>
		<comments>http://push.cx/2011/craftsmanship-tour-jim-ray#comments</comments>
		<pubDate>Mon, 14 Feb 2011 00:34:55 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[craftsmanship tour]]></category>
		<category><![CDATA[Devise]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1688</guid>
		<description><![CDATA[Last Tuesday I spent the afternoon with Jim Ray at the excellent Hooked coffeeshop in Denver, CO (and then I spent the next several days sick from a bad meal and recovering, so this post got delayed). We worked on FindAPair, a small web app he&#8217;s developing with Jeff Powell. Developers can list their city [...]]]></description>
			<content:encoded><![CDATA[<p>
Last Tuesday I spent the afternoon with <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3R3aXR0ZXIuY29tL2ppbWlyYXk=">Jim Ray</a> at the excellent <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5teXNwYWNlLmNvbS9ob29rZWRvbmNvbGZheA==">Hooked</a> coffeeshop in Denver, CO (and then I spent the next several days sick from a bad meal and recovering, so this post got delayed).
</p>

<p>
We worked on <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2ppbWlyYXkvZmluZGFwYWly">FindAPair</a>, a small web app he&#8217;s developing with <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5ub3NjZXRpcHN1bS5jb20v">Jeff Powell</a>. Developers can list their city and link to their Twitter and GitHub profiles to find other devs to pair with. (Yeah, this basic idea felt <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20=">pretty familiar</a>.)
</p>

<p>
First, Jim and I <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2ppbWlyYXkvZmluZGFwYWlyL2NvbW1pdC9jZmE5OGZmMmZmODliNzY4N2QxZDk5ZDdkNjhjYmEzNWY2ZjFkYTNl">added</a> some acceptance tests using <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2NhdmFsbGUvc3RlYWs=">Steak</a> to test profile editing. Steak is a DSL for acceptance in BDD, but closer to Ruby code than the popular <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2N1a2VzLmluZm8v">Cucumber</a>. Jim explained he chose Steak because this project does not have a non-technical customer who&#8217;d read, verify, and help write specs. Cucumber&#8217;s translation between text files and method calls would be unnecessary complexity.
</p>

<p>
FindAPair uses the wonderful <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL3BsYXRhZm9ybWF0ZWMvZGV2aXNl">Devise</a> library, so we followed <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL3BsYXRhZm9ybWF0ZWMvZGV2aXNlL3dpa2kvSG93LVRvOi1BbGxvdy11c2Vycy10by1zaWduX2luLXVzaW5nLXRoZWlyLXVzZXJuYW1lLW9yLWVtYWlsLWFkZHJlc3M=">the steps on the wiki</a> to allow people to log in by username as well as email address. It went pretty well, but we needed to do a little tweaking for Rails 3. Of course, we contributed back to the docs. One of the nice things about GitHub is how frictionless it is to share these small improvements.
</p>

<p>
Another interesting bit of coding was planning the URL structure of the site. The two major resources are users and the cities they live in. Jim wanted to have really simple URLs like <kbd>findapair.me/jimiray</kbd> or <kbd>findapair.me/denver</kbd>. He didn&#8217;t want to overlap the namespaces, but he couldn&#8217;t decide between them. As he was explaining the problem I thought back to the early days of the web and suggested putting cities at the root and users at <kbd>findapair.me/~jimiray</kbd>. Jim laughed, decided the audience was nerdy enough to remember it, so we <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cHM6Ly9naXRodWIuY29tL2ppbWlyYXkvZmluZGFwYWlyL2NvbW1pdC82N2QxNTgxNGZkMWNlYmEzODY3ODA4N2NlYjNhYjk2ZDNkYWZiZmQwI2RpZmYtMg==">committed it</a>.
</p>

<p>
I&#8217;m not going to recount all the little things we did, but it was a fun afternoon building what could be a great resource.
</p>

<p>
While I was programming with Jim, I was reminded of the importance of studying. I knew a lot more vim commands than Jim, but it&#8217;s not because I&#8217;m any smarter. When I started learning vim I quickly realized it was a far bigger topic than I could absorb at once, so I only learned enough to take care of my daily routine. After I was comfortable with that, I started reading the vim manual, but I read at most one chapter a week. Read a little, experiment, give it time to settle, refresh my reading in a few days, and then move on to something else. In the decade since then, I still watch for new information about vim, reading the <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3JlZGRpdC5jb20vci92aW0=">vim subreddit</a> and Twitter accounts like <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3R3aXR0ZXIuY29tL2xlYXJudmlt">learnvim</a> and <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3R3aXR0ZXIuY29tL2RvdHZpbXJj">dotvimrc</a>. It&#8217;s easy to skip over the stuff I already know. It&#8217;s easier to earn in small amounts over years than read one book and hope to retain everything.
</p>
 <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1688" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/craftsmanship-tour-jim-ray/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Craftsmanship Tour: David W. Allen</title>
		<link>http://push.cx/2011/craftsmanship-tour-david-w-allen</link>
		<comments>http://push.cx/2011/craftsmanship-tour-david-w-allen#comments</comments>
		<pubDate>Wed, 05 Jan 2011 03:50:18 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[craftsmanship tour]]></category>
		<category><![CDATA[graphs]]></category>
		<category><![CDATA[NearbyGamers]]></category>
		<category><![CDATA[software craftsmanship]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1647</guid>
		<description><![CDATA[I&#8217;m in Grand Junction, Colorado because it seemed as good as any a place to start traveling. I have family in Denver and plans to ski, so why not tour the state a while? Once I knew I was coming to Grand Junction, I remembered GitHub can be searched by location and I got curious, [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;m in Grand Junction, Colorado because it seemed as good as any a place to start traveling. I have family in Denver and plans to ski, so why not tour the state a while? Once I knew I was coming to Grand Junction, I remembered GitHub can be searched by location and I got curious, so I did the search.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDEvZ2l0aHViX3NlYXJjaC5wbmc="><img src="http://push.cx/wp-content/uploads/2011/01/github_search.png" alt="" title="GitHub search for users in Grand Junction" width="532" height="238" class="aligncenter size-full wp-image-1656 important" /></a>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDEvSU1HXzM5NzNfbW9kaWZpZWQuanBn"><img src="http://push.cx/wp-content/uploads/2011/01/IMG_3973_modified-150x150.jpg" alt="" title="Grand Valley from Colorado National Monument" width="150" height="150" class="alignright size-thumbnail wp-image-1663" /></a>
<p>
One result? If there&#8217;d been a hundred people I&#8217;d have been done right there, but if there&#8217;s exactly one person, well, why not say hi? So I sent an email that I think sounded like this:
</p>

<blockquote>
I realize I&#8217;m a complete stranger and the idea of wandering into people&#8217;s offices to work with them for a day sounds perfectly ridiculous, but would you like to grab coffee, talk code, do some pair programming?
</blockquote>

<p>
Perhaps I didn&#8217;t come off quite so badly because <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Rhdmlkd2FsbGVuLm5ldC8=">David</a> said &#8220;what the hell&#8221; and invited me to meet him for his workday at <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3RyYWRlcnNjb2ZmZWVhbmR0ZWEuY29tLw==">Traders Coffee</a>.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDEvU1RHXzQwODdfbW9kaWZpZWQuanBn"><img src="http://push.cx/wp-content/uploads/2011/01/STG_4087_modified-150x150.jpg" alt="" title="Colorado National Monument" width="150" height="150" class="alignright size-thumbnail wp-image-1662" /></a>
<p>
A side story: I happened to arrive before him and was looking around for him, and couldn&#8217;t see him. But I saw a woman surfing <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3N0YWNrb3ZlcmZsb3cuY29t">Stack Overflow</a>! I thought maybe this was someone David knew and invited along, so I had an awkward conversation where it quickly became clear she had no idea who I was or why I was introducing myself. If I&#8217;d been thinking quicker I&#8217;d have invited her to join us or at least given a business card, but my generic nerdly social phobia overwhelmed me and I excused myself. If you&#8217;re reading this and someone interrupted your Stack Overflow session to ask if you knew a guy you&#8217;d never heard of, sorry for the confusion, but if you&#8217;d like to grab coffee, talk code, maybe do some pair programming, I&#8217;m in town until Friday afternoon.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDEvSU1HXzQwNjRfbW9kaWZpZWQuanBn"><img src="http://push.cx/wp-content/uploads/2011/01/IMG_4064_modified-150x150.jpg" alt="" title="Rocks in a frozen stream" width="150" height="150" class="alignright size-thumbnail wp-image-1659" /></a>
<p>
As David and I sipped delicious lattes, I learned that he&#8217;s a mechanical engineer who got into software development around ten years ago as his job changed. He&#8217;s self-taught, he cracked the books and started experimenting. Along the way he attended some <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5jb25zdHJ1eC5jb20vUGFnZS5hc3B4P25pZD0xMg==">Construx Seminars</a>. Construx is the software firm started by <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdGV2ZV9NY0Nvbm5lbGw=">Steve McConnell</a>, the giant who strides above programmers bestowing books of wisdom and lore, so that gave David a good grounding.
</p>

<p>
A lot of our conversation was about how David has found it hard to improve his craft without other, ideally better, programmers around to work with. It&#8217;s referenced by the community aspect of the <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL21hbmlmZXN0by5zb2Z0d2FyZWNyYWZ0c21hbnNoaXAub3JnLw==">Software Craftsmanship Manifesto</a>. Programmers improve their craft by improving each other&#8217;s craft.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDEvSU1HXzQwMTFfbW9kaWZpZWQuanBn"><img src="http://push.cx/wp-content/uploads/2011/01/IMG_4011_modified-150x150.jpg" alt="" title="Chapel with birds nesting on roof" width="150" height="150" class="alignright size-thumbnail wp-image-1658" /></a>
<p>
As an example, David told me about his startup project <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy52ZWxvZ3JhZi5jb20=">veloGraf</a>. He and another developer are using graph algorithms to analyze social networks and I soon realized I only know enough graph theory to hang onto the ankles of the conversation. I hadn&#8217;t thought about it before, but David pointed out that <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20vdGFncw==">game tags</a> on NearbyGamers form a highly cyclical graph. Gamers add edges to the graph by listing what games they&#8217;re interested in playing and tags self-referentially describe themselves (eg. <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20vdGFncy9EdW5nZW9uc18mIzAzODtfRHJhZ29ucw==">Dungeons and Dragons</a> is tagged as a an <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20vdGFncy9EdW5nZW9uc18mIzAzODtfRHJhZ29ucw==">RPG</a>).
</p>

<p>
I demoed the site&#8217;s most computationally-expensive page, which shows <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20vbmVhcmJ5L0hhcmtpbnMvZ2FtZXJz">gamers who share tags, sorted by distance</a>. This page required some hacking to avoid a gigantic couple of joins that would&#8217;ve dragged in most of the rows in the RDBMS, but David chuckled because it&#8217;s the sort of problem a proper graph database doesn&#8217;t even notice. He&#8217;s tracking millions of nodes with many times more edges in order to extract interesting connections. The simple analyses he pointed out flaws in common algorithms that were <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3NpdmVycy5vcmcvb2J2aW91cw==">obvious</a> to him but surprising to me. I managed to give him some fodder for experiments to improve his algorithms, which says more about the value of a little collaboration than it does my graph chops.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDEvSU1HXzQwMDVfbW9kaWZpZWQuanBn"><img src="http://push.cx/wp-content/uploads/2011/01/IMG_4005_modified-150x150.jpg" alt="" title="Main St. sculpture" width="150" height="150" class="alignright size-thumbnail wp-image-1657" /></a>
<p>
David told me a tale of (mild) woe from a previous job. An experienced cowbody coder was developing the core of a product while supposedly mentoring interns. In reality, they were restricted to working on small, ancillary tasks so as not to destabilize the core or distract the cowboy. How do you fix this?
</p>

<p>
My best guess (share yours in the comments, please &#8211; it&#8217;s not an uncommon scenario) was to task the interns with adding automated testing. The cowboy will think of it as menial work, but the interns will be exposed to the whole system and have reasons to have conversations with him. And probably better to start with acceptance testing than unit testing to preempt the cowboy from whining that using unit tests to verify that his code works (as opposed to hack and hope and oh yeah, I forgot those two things were related) slows down his brilliance.
</p>

<p>
There&#8217;s a complacency I&#8217;ve seen that&#8217;s sort of related to the <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5wYXVsZ3JhaGFtLmNvbS9hdmcuaHRtbA==">Blub Paradox</a>. When a programmer succeeds at building their first product or two, they often get an panglossian sense of competence. They may think, &#8220;I&#8217;m good at my job, there&#8217;s people telling me I should learn these things, but I&#8217;m good at my job without them, ipso facto I don&#8217;t need to learn more.&#8221; Unless they&#8217;re around a noticeably better programmer or especially introspective, they may never realize how much more there is to learn and the possibility of much greater skill.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDEvSU1HXzQwOTNfbW9kaWZpZWQuanBn"><img src="http://push.cx/wp-content/uploads/2011/01/IMG_4093_modified-150x150.jpg" alt="" title="Pedestrian bridge across I70" width="150" height="150" class="alignright size-thumbnail wp-image-1660" /></a>
<p>
I think this is where <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5zb2Z0d2FyZS10aG91Z2h0cy5jb20vMjAwOS8wOC9uZXQtbmVnYXRpdmUtcHJvZHVjaW5nLXByb2dyYW1lci5odG1s">net negative producing programmers</a> come from. I joined a project with an NNPP once. I watched all commits to the repository (everybody does this, right?) and I realized nearly his every commit added a bug or the strong potential for future problems. There was feedback available in the rising bug count and frustration of trying to improve the codebase, but he didn&#8217;t have the experience to know that this experience was abnormal. (Or at least improvable.) As I and other developers started cleaning up the code, he recognized what had been happening and decided to reinvest in his career by attending training.
</p>

<a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvd3AtY29udGVudC91cGxvYWRzLzIwMTEvMDEvSU1HXzQwOTVfbW9kaWZpZWQuanBn"><img src="http://push.cx/wp-content/uploads/2011/01/IMG_4095_modified-150x150.jpg" alt="" title="Cross-country skiing on Grand Mesa" width="150" height="150" class="alignright size-thumbnail wp-image-1661" /></a>
<p>
I think this is why the nascent software craftsmanship movement has such potential. Programmers need to make steady improvement, however small, a core value of the profession. Currently there&#8217;s a &#8220;well, it works&#8221; when practice and mindful improvement could be a precept. The likeliest way I see that happening is masters of the craft mentoring apprentices. Every craft has its share of &#8220;just get it done&#8221;, but it doesn&#8217;t have to be the dominant culture.
</p>

<p>
<b>Update:</b> David has <a href="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Rhdmlkd2FsbGVuLm5ldC8yMDExLzAxL3NvZnR3YXJlLWNyYWZ0c21hbnNoaXAv">blogged his thoughts</a> on our wide-ranging conversation.
</p> <img src="http://push.cx/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1647" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2011/craftsmanship-tour-david-w-allen/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

