<?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>Yeti Factory</title>
	<atom:link href="http://www.yeti-factory.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.yeti-factory.org</link>
	<description></description>
	<lastBuildDate>Fri, 31 Jul 2009 03:04:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>TextTumble: A summary of development for a fledgling iPhone game programmer</title>
		<link>http://www.yeti-factory.org/?p=65</link>
		<comments>http://www.yeti-factory.org/?p=65#comments</comments>
		<pubDate>Sun, 21 Jun 2009 01:20:12 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Objective C]]></category>
		<category><![CDATA[Text Tumble]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=65</guid>
		<description><![CDATA[This post was originally intended to be published in June.  I held off publishing it though, intending to expand upon it.  In retrospect, it&#8217;s pretty damn big, so I&#8217;m just going to let it ride, and address TextTumble&#8217;s approval process and release process in a separate post. -CZ

We made it!  249 days [...]]]></description>
			<content:encoded><![CDATA[<p><strong>This post was originally intended to be published in June.  I held off publishing it though, intending to expand upon it.  In retrospect, it&#8217;s pretty damn big, so I&#8217;m just going to let it ride, and address TextTumble&#8217;s approval process and release process in a separate post. -CZ</strong></p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz0081.jpg" border="0" alt="Excuse the slight cynicism, it's knee jerk." width="300" height="150" /></div>
<p><a href="http://magellanmedia.com/">We</a> made it!  249 days since the first source code commit, TextTumble is finished. At around 11:30 PM, I cracked the champagne</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/kf2p1.jpg" border="0" alt="kf2p.jpg" width="237" height="186" /></div>
<p>and sat back to enjoy the prospect of a job completed. While there is still some additional features that will be fit into the online scores and profiles, I feel very happy labeling the package with &#8220;1.0&#8243; (A version number whose significance can be daunting to a first timer like myself).  As it sits in Apple&#8217;s review queue now, I&#8217;d like to give you an abbreviated history of the game&#8217;s development.  I&#8217;m not going to offer much in the way of advice or instruction here; this is just telling a story. <img src='http://www.yeti-factory.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /><br />
<span id="more-65"></span>Sometime near mid September 2008, I went out for lunch with now co-owner of <a href="http://magellanmedia.com/">Magellan Media</a>, <a href="http://rogersmj.com/">Matt Rogers</a>.  Matt and I were co-workers at the <a href="http://www.indystar.com/">Indianapolis Star</a> (Matt recently left the Star to work at <a href="http://www.mediasauce.com/">mediasauce</a>), where we worked with a team of other artists and programmers to create local community sites.</p>
<p>Matt asked me to work together with him on a new game concept: create a falling-letter-tile word game for the iPhone.  At the time, one of the more popular games on the iPhone app store, <a href="http://www.semisecretsoftware.com/wurdle/">Wurdle</a>, was gaining in popularity, yet seemed to be generating a lot of derivative apps in the App Store.  Matt felt (a point which I believe to be still valid) that a new type of word game would capture the public&#8217;s attention as an alternative to the Wurdle-style game.</p>
<p>I was definitely interested; to say that I have long desired to enter into the game industry would be an understatement.  While in college, I had hacked together some simple mods for <a href="http://www.fileplanet.com/37438/30000/fileinfo/Gluttony-v.01">Unreal Tournament</a> and <a href="http://www.fileplanet.com/51772/50000/fileinfo/SabreMatch---Rune-Lightsabre-Combat-v.101">Rune</a>, but I had never stuck with a project long enough to see it polished and complete.  While many of the upper echelon of iPhone games on the App Store seem to be coming from game industry veterans breaking out on their own, the game that Matt and I would make would be our first.</p>
<p>Invigorated from that lunch, I told Matt that I would create a prototype and have it ready for him to check out a few days. On September 29, 2008, I sent Matt a video of the iPhone simulator that looked something like this:</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/quicktime-playerscreensnapz001.jpg" border="0" alt="QuickTime PlayerScreenSnapz001.jpg" width="200" height="242" /></div>
<p>I think that programming is full of many images like this: screenshots that on their own merits are entirely forgettable, but hold huge significance to the creator.  This image represents the very beginnings of not only the first game I intended to follow through to completion, but also the first publicly used application I&#8217;ve written using OpenGL, a long time career goal of mine.</p>
<p>Matt and I, both pleased that a prototype of the game&#8217;s basic interaction was put together so quickly, set a deadline for ourselves:  finish the game by Christmas.  It would be some hard, late nights, but I felt it would be possible.  And yes, I mean Christmas 2008.</p>
<p>Over the course of October and November, I began working late nights, trying to pull in the necessary components of the game: the word dictionary, the tile texturing, and the interface elements.  As I did this, I kept one goal in mind: keep all the code as simple as possible. I knew that attempting my first game would mean that I&#8217;d be spending more time rewriting code than writing new code, as I discovered newer and better ways to accomplish things.  I also knew that I could easily fall into the trap of writing over-architectured code when I encountered a problem, as an attempt to insulate myself from the dirty details of the problem.  Commits would look like this:</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/gitxscreensnapz001.jpg" border="0" alt="GitXScreenSnapz001.jpg" width="389" height="131" /></div>
<p>at once both encouraging me that I was accomplishing work quickly, and infuriating me that I was committing code that I knew was not what I intended to be there later on.</p>
<p>On November 19th, we hit our next big milestone: eliminating valid words.</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz009.jpg" border="0" alt="FirefoxScreenSnapz009.jpg" width="480" height="100" /></div>
<p>I was pleased that I was able to get this piece of functionality working, but I was concerned about our Christmas 2008 finish date.  The game was not nearly polished enough, and I had not done nearly enough code quality checks to feel anything close to happy regarding the game.  Additionally, there were features that I was beginning to feel were critical to the game&#8217;s success (in-game word definition lookup, global high scores and spelling statistics, pictowords, letter crashing) that were either nonexistent or so basic as to be laughable.  I told Matt that I was afraid we&#8217;d miss Christmas, but that I&#8217;d work hard on trying to be done as soon as possible.</p>
<p>Now would be a good time to mention that the game really had 3 people working on it.  While Matt worked on art resources and the website and I did the programming, my wife was consistently involved throughout the game&#8217;s creation as our sanity check.  As we began to reach a more iterative feature-bugfix-internal release cycle (that was nowhere near that formal), my wife began to be more involved in critiquing the basic flow and style of the game.  While Matt and I were avid video game players and had certain expectations of interface and game behavior, my wife was not: her analytical nature combined with her lack of prior bias  began to reveal flaws in our assumptions as to the game&#8217;s readiness for the public.  Our Christmas 2008 release became our Christmas 2008 hard-vacation-push to complete more work items.  I told relatives that I&#8217;d be spending the majority of my vacation programming for the game, but that I believed I&#8217;d have the majority done by February 2009.</p>
<p>I finished the year 2008 staying up late coding, trying to meet my own deadline.</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz010.jpg" border="0" alt="FirefoxScreenSnapz010.jpg" width="320" height="114" /></div>
<p>The months of January and February were difficult.  Personally I was having to work my day job at hospitals throughout most of those months, as my family was going through a difficult medical time. (I should note that I am very thankful to my department managers for allowing me the ability to even /do/ this)  Additionally, I learned just weeks into the new year that the entirety of the Gannett corporation (the parent company that owns many of the newspapers across the US, including the Indianapolis Star) would be enacting a furlough (unpaid week of leave) program to help account for huge losses in revenue:</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz0121.jpg" border="0" alt="FirefoxScreenSnapz012.jpg" width="480" height="108" /></div>
<p>I&#8217;d be lying if I didn&#8217;t say I was secretly overjoyed that I would be able to spend a week doing game development instead of web development; that joy was slightly bittersweet, however. I was reaching the awkward phase of a first-time project where certain rusty mechanisms in the game seemed like they might be better rewritten; would I benefit more by continuing a design that I was increasingly dissatisfied with, or by taking more time to redesign large internal components of the game?  I began to doubt many of my earlier decisions, but could not bring myself to wholesale remove whole sections of the game to make way for a rewrite.    I compromised:</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz011.jpg" border="0" alt="FirefoxScreenSnapz011.jpg" width="320" height="114" /></div>
<p>and, despite my own pessimism, succeeded:</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz013.jpg" border="0" alt="FirefoxScreenSnapz013.jpg" width="320" height="170" /></div>
<p>Throughout this time period, Matt had been revising our interface designs, collecting sounds for the game, and working on the promotional website. While we were not finished by the end of February, we were ready for a beta.  We put out the call on Twitter, and began to aggregate a collection of friends, co-workers, and some complete strangers, to check out our game, and help us figure out what might be broken, and what might just need some tweaking.  On March 1st, we packaged up the application and distributed it to our 15 beta testers.</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz014.jpg" border="0" alt="FirefoxScreenSnapz014.jpg" width="200" height="237" /></div>
<p>Immediately after having released the beta, I went right back to work.  The fact that people were using it served as fuel for me to become reinvested in the game, and I began to work longer and more nights throughout the week, polishing things, adjusting interface designs to meet Matt&#8217;s mockups, and generally get the game ready.  We received some very nice compliments from friends who we had play the game, but the game was definitely buggier than we had realized.</p>
<p>Towards the end of March, things were progressing slowly, but well, when it happened:</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz015.jpg" border="0" alt="FirefoxScreenSnapz015.jpg" width="480" height="132" /></div>
<p>Gannett had been steadily losing money, and was forced to institute another week of unpaid leave for all its workers.  I was once again enthusiastic at having a week to spend working on the game, but was cynical as well.  Two financial quarters involving furlough programs does not indicate that the rest of the year will be stable and secure to a pessimist such as myself; and, if my day job were to be lost, I would not have the liberty to continue working on the game for some time.  Whole months of work would be put on hold as I found another job and settled into that environment.</p>
<p>My wife and I talked, and we decided:  if there was to be any hope of finishing the game before I became unemployed, I would need to use my vacation time along with my furlough time, and work at top speed on getting the game to a polished, playable and fun state.</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz0161.jpg" border="0" alt="FirefoxScreenSnapz016.jpg" width="320" height="108" /></div>
<p>We released our second beta on April 14th to a larger (20+) yet much less active group of beta testers.  While we were achieving very favorable responses from players who we engaged in person, we weren&#8217;t receiving any feedback or significant recorded play time from any of our testers.</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/firefoxscreensnapz017.jpg" border="0" alt="FirefoxScreenSnapz017.jpg" width="480" height="201" /></div>
<p>This was our fault.  The phrase &#8220;beta test&#8221; implies something entirely different than what it is.  When we released /any/ beta test, it should have been with a stable and mostly realized game, instead of an unstable game that we were using to gauge user reactions from.  In other words, our beta was our very first form of public display of the game, and should have been more representative of what we wanted users to see in the end.</p>
<p>Work continued.  I had stopped attempting to predict when we would be &#8220;finished&#8221;, and jokingly just said &#8220;when it&#8217;s done&#8221; when asked.  I had no idea when the game would be done.  I had stopped primary gameplay development several times to add new features to the game, or improve gameplay performance.</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/atlasmakerscreensnapz001.jpg" border="0" alt="AtlasMakerScreenSnapz001.jpg" width="480" height="290" /></div>
<p>I created a tool called AtlasMaker (which I will put on GitHub sometime in the next month or so) that let us bundle our delivered graphics in memory easily, and added a decompress-word-dictionary-to-users-hard-drive-on-first-launch feature to the game that dropped our application size to 6MB. I then promptly removed that feature, and removed our SQL database of words entirely for an in-memory structure called a DAWG which offers much more efficient querying of words and storage on disk, allowing us to have much more performant pictowords (I&#8217;ll explain what I mean by pictowords in a future post).</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/img-0066.png" border="0" alt="IMG_0066.PNG" width="317" height="135" /></div>
<p>Things were nearing the end.  I could feel like everything I had wanted to be in the first version of the game was done.  I felt relaxed about the game.  It was stable, nearing bug free, and polished.  We released the third beta on June 3rd, along with a survey.    Our analytics program for the game was reporting low usage, though we were expecting that after the pretty slow uptake on beta 2.  Our survey, though on the large part favorable in terms of disposition of response, saw fairly poor rates of response. On June 11th, Matt and I met for lunch, and we set ourselves our final tasks for completion before submitting the game to Apple.</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/safariscreensnapz003.jpg" border="0" alt="SafariScreenSnapz003.jpg" width="349" height="131" /></div>
<p>June 18.  Not quite Christmas 2008.  Not by a long shot.  And what does the body of TextTumble look like, now that we&#8217;ve completed it?  Well, according to David A. Wheeler&#8217;s &#8216;SLOCCount&#8217; (an entirely arbitrary and only used to get some sort of wild ballpark look):</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/sloccount.png" border="0" alt="sloccount.png" width="480" height="231" /></div>
<p>Is this entirely accurate? No.  It&#8217;s not accurate because I didn&#8217;t keep track of actual hours spent creating the game; when I began, why would I? I was overjoyed to be working on my own video game.  When I began to actually question myself and wonder what the degree of profits the game must make to make video game making a sustainable personal activity, it was long since past the point where I could attempt to recall with any accuracy how much time I had spent on the game in the nights before then.</p>
<p>The number is very instructive though.  Our next games will be informed very much by the experience with TextTumble, and there will be a lot of thought given in the future as to how we can bring you the most fun experience while at the same time not overextending ourselves on the development effort.</p>
<p>I could not be happier, though.  It&#8217;s finished.  I expect that there might be one or two bugs that slipped by, but it is finished.  I can&#8217;t wait to have our first game available on the App Store, and moreso, I can&#8217;t wait to tell people about it.  One of our earliest testers told me on Twitter:  &#8220;I spent over half an hour to playing your game last night&#8221;; I was overjoyed, because this is something I&#8217;ve wanted to do for a very long time.</p>
<p>We&#8217;re still waiting to hear from Apple about TextTumble&#8217;s status in the store.  In the mean time, we&#8217;ll be creating videos, blog posts, and screenshots of the game, and showing you as much as we can about the game that we&#8217;re proud to have made.  I&#8217;ll also be releasing the source code for the internal tools I&#8217;ve built to help creating the game, as well as talking a bit more on the blog about development effort and techniques learned (largely from other iPhone developers), now that we&#8217;ve submitted the game.</p>
<p>Maybe it&#8217;s best summed up by:</p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/06/photo-1.jpg" border="0" alt="photo-1.jpg" width="319" height="227" /></div>
<p>Time for the next level. <img src='http://www.yeti-factory.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>Clearly, a month has passed since the original time of this post, and I have not done any of the source code release things I intended to do.  I&#8217;m publishing this post on the eve of the game&#8217;s availability in the app store, and right now all I can think about it is the next release.  Priorities change. <img src='http://www.yeti-factory.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  -CZ</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=65</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>&#8220;Toll Free Bridging&#8221; for your own data</title>
		<link>http://www.yeti-factory.org/?p=35</link>
		<comments>http://www.yeti-factory.org/?p=35#comments</comments>
		<pubDate>Wed, 29 Apr 2009 00:53:46 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Objective C]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=35</guid>
		<description><![CDATA[In the course of working on a quick side project, I came across a few interesting items of note for those working on Objective-C projects. 
I was looking for a way to recreate the behavior shown by some Core Foundation objects in that they may be cost-free casted to their equivalent type in the Cocoa [...]]]></description>
			<content:encoded><![CDATA[<p>In the course of working on a quick side project, I came across a few interesting items of note for those working on Objective-C projects. </p>
<p>I was looking for a way to recreate the behavior shown by some Core Foundation objects in that they may be cost-free casted to their equivalent type in the Cocoa framework.  An example:</p>
<pre>
CFStringRef my_string = CFSTR("a string");
NSString* also_my_string = (NSString*) my_string;
</pre>
<p>It turns out that, should you have a need to represent a struct also as a subclass of some <code>NSObject</code>, you can do so by having your struct include a member of type <code>Class</code> (or <code>struct objc_class*</code>) named <code>isa</code>.  The <code>isa</code> member is used by Objective C to access the table of methods and class hierarchy that your object (or struct, but we&#8217;re splitting hairs) is associated with.  A much more elaborate discussion regarding the <code>isa</code> member can be found at <a href="http://www.mikeash.com/?page=pyblog/friday-qa-2009-03-13-intro-to-the-objective-c-runtime.html">Mike Ash&#8217;s website</a>, which is damn near invaluable for learning more about Objective C.</p>
<p>Once you&#8217;e added the <code>isa</code> member to your struct, all that remains is to reflect your struct&#8217;s internal structure in the <code>NSObject</code> representation you&#8217;re creating.  While it may seem obvious to some, it should bear worth noting that the order of declaration in your <code>NSObject</code> subclass should mimic the order of declaration in your struct.  Here&#8217;s an example:</p>
<pre>
typedef struct {
  Class isa;
  int   some_number;
  BOOL  some_flag;
} MyDumbStruct;

@interface MyDumbObject : NSObject {
  int some_number;
  BOOL some_flag;
}
-(int) someMethod;
@end
</pre>
<p>Now that you&#8217;ve done this, you&#8217;ll be able to cast a properly created <code>MyDumbStruct</code> to a <code>MyDumbObject</code> instance.  I say properly created because you will need to populate the <code>isa</code> member of your struct with the pointer to the <code>Class</code> object that correctly represents the class your struct will be associated with.  You can do this by accessing the <code>class</code> method of the, ur, class in question.  For example:</p>
<pre>
MyDumbStruct s;
s.isa = [MyDumbObject class];
</pre>
<p>That&#8217;s it &#8211; and here&#8217;s what you end up with in terms of capability:</p>
<pre>
MyDumbStruct s = { .isa = [MyDumbObject class],
                   .some_number = 2,
                   .some_flag = TRUE };
MyDumbObject *o = &#038;s;
NSLog("My dumb object has a number: %i", [o someMethod]);
</pre>
<p>In my next post, I&#8217;ll show what I&#8217;ve been working on that actually uses this technique.</p>
<p>Addendum:  <a href="http://iphonedevelopertips.com/objective-c/objective-c-object-as-a-c-structure.html">This link</a> elaborates on what I described above; it also describes usage of the <code>@defs</code> keyword, which will allow you to only have to declare the member variables for your Object once, and have them inserted in your struct at compile time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=35</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Usable XCode?!?!</title>
		<link>http://www.yeti-factory.org/?p=33</link>
		<comments>http://www.yeti-factory.org/?p=33#comments</comments>
		<pubDate>Tue, 28 Apr 2009 01:04:45 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Emacs]]></category>
		<category><![CDATA[XCode]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=33</guid>
		<description><![CDATA[My usual user interface experience with Apple software is of the pattern:

Feel an app has a shortcoming
Work with shortcoming 
Curse shortcoming in bars / Twitter / work
Spend 10 minutes googling to see if someone else has experienced the problem, and find out the feature has been there all along, and has some shortcut key assigned [...]]]></description>
			<content:encoded><![CDATA[<p>My usual user interface experience with Apple software is of the pattern:</p>
<ul>
<li>Feel an app has a shortcoming</li>
<li>Work with shortcoming </li>
<li>Curse shortcoming in bars / Twitter / work</li>
<li>Spend 10 minutes googling to see if someone else has experienced the problem, and find out the feature has been there all along, and has some shortcut key assigned to it</li>
<li>Facepalm</li>
</ul>
<p>So, predictably, when I was griping over the lack of a quick file navigation feature like Emacs&#8217; C-X b or Textmate&#8217;s  ⌘-T, a few minutes googling solved my complaint.  </p>
<div style="text-align:center;"><img src="http://www.yeti-factory.org/wp-content/uploads/2009/04/xcodescreensnapz001.jpg" alt="XcodeScreenSnapz001.jpg" border="0" width="408" height="248" /></div>
<p>The Open Quickly option (shortcut: ⇧⌘D ) not only gives you quick file navigation, it also (as shown by the screenshot) gives you quick jump-to-symbol navigation.  I can only say: sweeeeet. (And also, facepalm.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=33</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Blog Redesign and some undocumented ERB</title>
		<link>http://www.yeti-factory.org/?p=24</link>
		<comments>http://www.yeti-factory.org/?p=24#comments</comments>
		<pubDate>Mon, 27 Apr 2009 04:30:40 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=24</guid>
		<description><![CDATA[(Update: Some minor clarification regarding the performance cost of eval())
Visitors to the site might notice that there was a drastic (and long called for) redesign of the site.  It is not, I assure you, the sudden manifestation of artistic ability on my part; rather, it was some great work done by Erik Goens, which [...]]]></description>
			<content:encoded><![CDATA[<p>(Update: Some minor clarification regarding the performance cost of eval())</p>
<p>Visitors to the site might notice that there was a drastic (and long called for) redesign of the site.  It is not, I assure you, the sudden manifestation of artistic ability on my part; rather, it was some great work done by <a href="http://corvusconceptions.com/">Erik Goens</a>, which has made the website look like something a little better than &#8220;derelict&#8221;.</p>
<p>I&#8217;ve got lots to say about Text Tumble, and maybe even a little bit to contribute about Objective C (pending some exploratory work on my own part), but I&#8217;m afraid I don&#8217;t have enough ready yet to go in depth.  So, in the short term, allow me to share a little bit of undocumented ERB capability that came to me by way of <a href="http://segment7.net/projects/ruby/snippets/erb_cache.rb">Eric Hodel&#8217;s Cached ERB Template class</a>.  </p>
<p>Background: ERB is the library used to drive most Rails templates.  When you write a view template and use this form:</p>
<pre>
This is my html file, &lt;%= @some_ruby_variable %&gt;
</pre>
<p>it will be processed by the ERB library (which is part of your <a href="http://ruby-doc.org/stdlib/">Ruby Standard Library</a>) and turned into Ruby code which may be executed.  You can see it for yourself in irb:</p>
<pre>
&gt; require "erb"
&gt; doc = ERB.new("this is my template &lt;%= @var %&gt;")
&gt; puts doc.src.inspect
</pre>
<p>The &#8220;src&#8221; attribute of the doc variable is the Ruby code that will be executed when the template is rendered.  You can evaluate it yourself, like so:</p>
<pre>
&gt; eval(doc.src)
</pre>
<p>or use the .result method to obtain the evaluated template result, like so:</p>
<pre>
&gt; doc.result
</pre>
<p>Each time you do this, you will evaluate the generated Ruby code anew.  The cost of evaluating Ruby code programmatically is not trivial &#8211; it requires parsing and interpreting the string of Ruby code as if it were a separate file that had been loaded into the specified context.   </p>
<p>You can bypass this by using some undocumented functions in the ERB library.  The important method to consider in this case is the method named: &#8220;def_method&#8221;.   def_method is a method that allows you to evaulate the ruby code and &#8220;compiles&#8221; it into a method, allowing you to call the method later on without re-evaluating the string. </p>
<p>For instance:</p>
<pre>
&gt; doc = ERB.new("foo bar <%= @baz %>")
&gt; class Test; end
&gt; doc.def_method(Test, "call_dynamic_method")
&gt; t = Test.new
&gt; puts t.call_dynamic_method
</pre>
<p><code>def_method</code> will take the generated Ruby source and evaluate it in a manner similar to this:</p>
<pre>
&gt; doc = ERB.new("foo bar <%= @baz %>")
&gt; method_name = "call_dynamic_method"
&gt; method_source = "def #{dynamic_method}; #{doc.src}; end"
&gt; Test.module_eval(method_source)
</pre>
<p>You can see a more elaborate version of this technique in the Rails source in <a href="http://apidock.com/rails/ActionView/Renderable/compile!">ActionView::Renderable#compile!</a>.  That means that, if you are using Rails, that the performance gains from this are already applied to you (and have been since Rails 1.0).  However, if you are using ERB on its own, it&#8217;s a good technique to have at hand.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=24</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spam Comments and Being Away</title>
		<link>http://www.yeti-factory.org/?p=22</link>
		<comments>http://www.yeti-factory.org/?p=22#comments</comments>
		<pubDate>Wed, 01 Apr 2009 16:53:12 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=22</guid>
		<description><![CDATA[I had to clean out a ton of spam comments caused by my momentary blog inattention.  Sorry if I deleted any of yours! 
]]></description>
			<content:encoded><![CDATA[<p>I had to clean out a ton of spam comments caused by my momentary blog inattention.  Sorry if I deleted any of yours! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=22</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL and the Update Loop</title>
		<link>http://www.yeti-factory.org/?p=15</link>
		<comments>http://www.yeti-factory.org/?p=15#comments</comments>
		<pubDate>Sun, 15 Feb 2009 18:18:53 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Text Tumble]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=15</guid>
		<description><![CDATA[A common technology use for a word based iPhone game is the inclusion of an SQLite database containing the word list of the game, to be queried when checking for potential matches to a sequence of characters.  While the ease of offloading data management to SQLite is certainly a boon (as opposed to creating [...]]]></description>
			<content:encoded><![CDATA[<p>A common technology use for a word based iPhone game is the inclusion of an SQLite database containing the word list of the game, to be queried when checking for potential matches to a sequence of characters.  While the ease of offloading data management to SQLite is certainly a boon (as opposed to creating your own data structure to load the word list at run time), it is important to keep several things in mind when doing so:</p>
<p>* Normalize your data. If you are querying the database for words, for example, ensure that your input data form matches your database data form before you issue your query.  Using a dictionary as an example, make sure the words in your dictionary are either all upper-case or all lower-case, and that your input data matches.  The difference between <code>SELECT word FROM dictionary WHERE UPPER(word) = UPPER(?)</code> and <code>SELECT word FROM dictionary WHERE word = ?</code> is at least n + 1 calls of UPPER.  Buy yourself that time with in advance data treatment.</p>
<p>* Query on change.  Chances are, your game state will only need to query when some user input or game event occurs.  Should this be the case, your data structures should be such that they only query the database when absolutely necessary.  For instance, using a word based game as an example again:  if the user has spelled CAPITULATE, and the I in CAPITULATE is removed, your data structure should already recognize that CAP and LATE are still words (based on the previous query that also showed CAPITULATE to be a word), and not query the database again to rediscover this.  While it places more of a burden on your game logic, you&#8217;ll avoid the cost of another scan across your dictionary against each potential word candidate.</p>
<p>* Indexes.  This should be obvious, but your database should be aggressively indexed if it will be queried during the update loop.  Create UNIQUE and PRIMARY indexes as relevant, and do so in advance.</p>
<p>* VACUUM. The <a href="http://www.sqlite.org/lang_vacuum.html">VACUUM</a> statement cleans up fragments left behind from successive INSERTs and DELETEs. You should VACUUM before shipping your database to clean up any work you&#8217;ve done in development, and if your database will be modified by the game, it&#8217;s a small thing to issue the statement during your game&#8217;s quit-cleanup phase.</p>
<p>* Cache failures or successes.  Consider creating an in-memory cache of failures or successes ( whichever is more likely to happen based on your requests ), and use it often.  You can whip together a simple <a href="http://en.wikipedia.org/wiki/Circular_buffer">ring buffer</a> in no time, or you can create something more complex that expires stale data based on access count or time of last access.</p>
<p>Most of this advice has been inferred through repeated performance optimization of Text Tumble.  If you&#8217;ve decided to do your database access in the update loop, this should help you shave off a few hours from your optimization work (and get closer to your target constant FPS <img src='http://www.yeti-factory.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=15</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby Bit For The Weekend</title>
		<link>http://www.yeti-factory.org/?p=13</link>
		<comments>http://www.yeti-factory.org/?p=13#comments</comments>
		<pubDate>Sat, 24 Jan 2009 06:14:17 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=13</guid>
		<description><![CDATA[I was looking over the code behind the New Relic RPM  plugin for Rails, and noticed a small bit of code in the following style:

@obj = SomeClass.new
# Do stuff
def @obj.a_new_method
  # add functionality
  # to obj, specifically
end

Without entering into the mostly futile discussion regarding the numerous goods / evils of this sort [...]]]></description>
			<content:encoded><![CDATA[<p>I was looking over the code behind the <a href="http://github.com/newrelic/rpm/tree/master">New Relic RPM </a> plugin for Rails, and noticed a small bit of code in the following style:</p>
<pre>
@obj = SomeClass.new
# Do stuff
def @obj.a_new_method
  # add functionality
  # to obj, specifically
end
</pre>
<p>Without entering into the mostly futile discussion regarding the numerous goods / evils of this sort of monkey patching, it was a cool piece of Ruby functionality I hadn&#8217;t yet seen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=13</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JQuery Style Function Chaining</title>
		<link>http://www.yeti-factory.org/?p=9</link>
		<comments>http://www.yeti-factory.org/?p=9#comments</comments>
		<pubDate>Thu, 22 Jan 2009 04:54:42 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=9</guid>
		<description><![CDATA[As I just posted, I recently had the chance to add JQuery style function chaining to my Spatial Query javascript library.  By function chaining, I mean the ability to do something like this:

$("div.of_interest").css("border", "solid 1px black").show()

A useful technique in situations where you plan on performing multiple operations on a given set of data.
I went [...]]]></description>
			<content:encoded><![CDATA[<p>As I just posted, I recently had the chance to add JQuery style function chaining to my <a href="http://github.com/netshade/spatial_query/tree">Spatial Query</a> javascript library.  By function chaining, I mean the ability to do something like this:</p>
<p><code><br />
$("div.of_interest").css("border", "solid 1px black").show()<br />
</code></p>
<p>A useful technique in situations where you plan on performing multiple operations on a given set of data.</p>
<p>I went straight to the source to determine how to create that sort of functionality &#8211; the <a href="http://github.com/JackDanger/jquery/tree/master">JQuery source</a>, mirrored on GitHub by <a href="http://github.com/JackDanger">JackDanger</a>.</p>
<p>The relevant code was in <a href="http://github.com/JackDanger/jquery/blob/a1fef992ba8b86c130ed27731709c57d259b7c2d/jquery/src/core.js">jquery/src/core.js</a>.  The simplified version of the technique could be stated like:</p>
<pre>var jQuery = function(selector, context){
  return new jQuery.fn.init(selector, context);
}

jQuery.fn = jQuery.prototype = {
  init : function(selector, context){
    /*
      Acquire the elements in question
    */
    return this;
  },
  // The rest of jQuery's functionality would
  // be defined in this prototype, such as
  // .each, .find, etc.

};

jQuery.fn.init.prototype = jQuery.fn;</pre>
<p>The line of particular interest is the line:</p>
<p><code><br />
jQuery.fn = jQuery.prototype = { // etc.<br />
</code></p>
<p>Here we assign the prototype to a separate variable, <code>jQuery.fn</code>, in order to refer to its members (namely the init function) in the main jQuery function. Then, in order to make sure that new instances of jQuery.fn.init have the methods declared in jQuery.prototype, we assign the jQuery.fn.init.prototype to the jQuery.prototype.</p>
<p>Now at this point, the jQuery function can return instances of &#8220;itself&#8221;.  In order to chain from one function to the next, functions of the jQuery.prototype will either return <code>this</code> or <code>jQuery(collection_of_elements)</code> to allow the chain to continue.</p>
<p>There are lots of other cool techniques in the jQuery source &#8211; they&#8217;re obviously having fun pushing Javascript to what limits they can find. <img src='http://www.yeti-factory.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=9</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spatial Query</title>
		<link>http://www.yeti-factory.org/?p=7</link>
		<comments>http://www.yeti-factory.org/?p=7#comments</comments>
		<pubDate>Tue, 20 Jan 2009 04:00:46 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=7</guid>
		<description><![CDATA[I recently had the need to build sets of polygons and compute an overall union of them; being the painfully naive person I am, I jumped right into the task thinking that it would be relatively easy.  A week later, I had finally arrived at a working polygon clipper modified for boolean operations on [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had the need to build sets of polygons and compute an overall union of them; being the painfully naive person I am, I jumped right into the task thinking that it would be relatively easy.  A week later, I had finally arrived at a working polygon clipper modified for boolean operations on poygons (mostly, see the <a href="http://github.com/netshade/spatial_query/blob/ec7102ea2d0f3a7e2b9699103c44f0d1f0d53aed/README">README</a>), but boy was it ugly.  Throughout the entire process, I kept thinking &#8220;wouldn&#8217;t it be nice if I had a decent Vector/Matrix/Polygon data structure&#8221;.  I made a few dirty attempts at writing something I liked looking at, but none of them were very satisfactory &#8211; really, I wanted something that looked a lot like JQuery.  Something that just took whatever data I threw at it, and most of the time did something sane with it.</p>
<p>So, I decided I&#8217;d write <a href="http://github.com/netshade/spatial_query/tree/master">Spatial Query</a>, a small JS library that lets you do all the gruntwork Vector/Matrix/Polygon work easily.  And some not so gruntwork stuff, that I just needed anyways &#8211; like generating a convex hull, or the union of two polygons.</p>
<pre>
  $p([[0,0], [0, 10], [10, 10], [10, 0]]).convex_hull_2d();
  $p([[0,0], [0, 10], [10, 10], [10, 0]]).union_2d([[5,5], [5, 7], [15, 7], [15, 5]]);
</pre>
<p>Since the project that spawned this library dealt with geometric data, there is also some functionality that will allow you to compute distances between latitude and longitude, as well as conversion between Latitude / Longitude and WSG84 coordinates:</p>
<pre>
  $ll([lat1, lon1]).distance_to([lat2, lon2]);
  $ll([lat1, lon1]).vector();
</pre>
<p>Better explanation and more is available in the <a href="http://github.com/netshade/spatial_query/blob/ec7102ea2d0f3a7e2b9699103c44f0d1f0d53aed/README">README</a></p>
<p>There are still some kinks in this version that I&#8217;ve got to iron out, so I&#8217;ve not even bothered assigning a number to it.  Consider it version zero point ugly.</p>
<p>Thanks to my employer, the Indianapolis Star, for letting me open this to the public.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=7</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Text Tumble: Getting Started</title>
		<link>http://www.yeti-factory.org/?p=3</link>
		<comments>http://www.yeti-factory.org/?p=3#comments</comments>
		<pubDate>Fri, 16 Jan 2009 21:31:43 +0000</pubDate>
		<dc:creator>netshade</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Text Tumble]]></category>

		<guid isPermaLink="false">http://www.yeti-factory.org/?p=3</guid>
		<description><![CDATA[It&#8217;s a tough thing, moving between web development (a world which is dominated by scripting languages) and game development.  I&#8217;ve been programming computers since I was 16, and for the majority of that time, I&#8217;ve been /paid/ to develop webpages, and /dreamed/ about developing video games.  
Now, here I am at 28, finally [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s a tough thing, moving between web development (a world which is dominated by scripting languages) and game development.  I&#8217;ve been programming computers since I was 16, and for the majority of that time, I&#8217;ve been /paid/ to develop webpages, and /dreamed/ about developing video games.  </p>
<p>Now, here I am at 28, finally doing that.  While I&#8217;ve worked on video game mods in the past, those really aren&#8217;t quite the same thing as doing a from scratch video game. (Even one that, were it not my own, I would think of simplistic &#8211; embarrassingly so, when compared to other games)    And, while I certainly can make my way among the major points of a more explicit memory management language (additionally, where resources may be constrained, though saying that the iPhone is memory constrained may receive different reactions from different developers), it&#8217;s rather like saying I can speak Spanish.  I&#8217;ve been trained to do so, and have been able to in limited situations, but my day to day usage is far different- (see, Ruby, JavaScript, Python, et al)</p>
<p>So getting started on iPhone development, while not impossible for me, introduced me to a different set of problems than I&#8217;m used to solving in web based apps.  </p>
<p> * OpenGL:  I&#8217;ve played with OpenGL in trivial apps off and on for years, always swearing I&#8217;d do a better job learning it, then never getting around to it.  Now that I actually AM using it, I feel like I have a lot to learn when it comes to how colors combine when objects are rendered over each other, or image bit alignment.  These aren&#8217;t things I need to know in the simple case, but I can see how becoming much more familiar with these things in the future will open a lot of graphical options to me.  </p>
<p> * Data structures:  Believe it or not, this one actually bothers me quite a bit.  I&#8217;ve spent a lot of time thinking about how to represent a list of entities in memory where my primary method of access would be spatial.  It may be naive, but I&#8217;ve been constantly thinking about how a &#8220;spatial hash&#8221; may work, and be implemented.  I&#8217;m kicking myself now for my silly list style representation, when I could have spent just a day looking through the Algorithms book beforehand and implemented a balanced interval tree instead.   This is a common thing for me, working with real time &#8220;physical&#8221; objects now &#8211; learning to reference my books and the internet FIRST, not after the fact.  </p>
<p> * Appreciation for physics: I feel like knowing and learning more about physical simulation will change me from being an average developer to being a /good/ developer.  While I don&#8217;t think I&#8217;ll ever author a paper on a topic, being more aware of where to turn for an equation that describes some physical phenomenon that accomplishes what I need (and being comfortable in how to translate that to actual code) will be invaluable.</p>
<p> * State : This is infuriating for me, as I should have known better.  Maintaining state, changes to state, and centralizing access to this information is something I should have known right from the beginning of TextTumble.  While the code is by no means unmaintainable, I see now the bad habits forming through independent has_done_x state flags littered through the code.  Surprisingly (to me), abstracting all this not only would reduce the noise in source code, it could also lead to efficiencies in rendering by abstracting the state change facility of OpenGL.  Only sending state changes to the hardware when they are necessary (obviously in retrospect) leads to an increase in framerate, which will obviously pay off later on.</p>
<p>  There&#8217;s more of course, but the sum is: I really couldn&#8217;t be any happier than I am right now, (re)learning things and finally making a game.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.yeti-factory.org/?feed=rss2&amp;p=3</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
