<?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>[lifebloom retain];</title>
	<atom:link href="http://www.lifebloomretain.com/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://www.lifebloomretain.com/blog</link>
	<description>Writings on healing trees and binary trees.</description>
	<lastBuildDate>Thu, 28 Jul 2011 04:26:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Other names for Lord Rhyolith (Heroic)</title>
		<link>http://www.lifebloomretain.com/blog/2011/other-names-for-lord-rhyolith-heroic</link>
		<comments>http://www.lifebloomretain.com/blog/2011/other-names-for-lord-rhyolith-heroic#comments</comments>
		<pubDate>Thu, 28 Jul 2011 04:26:04 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[firelands]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[warcraft]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=89</guid>
		<description><![CDATA[Lord RhyNGolith Lord Cryolith Lord Sigholith Lord Whyyyyyyolith Lord Recruitawarlockolith Lord HIYOOOOOOlith Giant walking turdmonster Additional suggestions welcome.]]></description>
			<content:encoded><![CDATA[<ol>
<li>Lord RhyNGolith</li>
<li>Lord Cryolith</li>
<li>Lord Sigholith</li>
<li>Lord Whyyyyyyolith</li>
<li>Lord Recruitawarlockolith</li>
<li>Lord HIYOOOOOOlith</li>
<li>Giant walking turdmonster</li>
</ol>
<p>Additional suggestions welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/other-names-for-lord-rhyolith-heroic/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The great suffix culling</title>
		<link>http://www.lifebloomretain.com/blog/2011/the-great-suffix-culling</link>
		<comments>http://www.lifebloomretain.com/blog/2011/the-great-suffix-culling#comments</comments>
		<pubDate>Wed, 27 Jul 2011 20:29:56 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[log parser]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[warcraft]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=87</guid>
		<description><![CDATA[When I wrote about suffix handling in my log parser before, I made mention of a bit of a code problem that I had in the source: An explosion of LP*Suffix classes, amounting to nearly forty of the blasted things. Most of these were empty or nearly-empty classes that served the purpose of replicating the [...]]]></description>
			<content:encoded><![CDATA[<p>When I wrote about suffix handling in my log parser before, I made mention of a bit of a code problem that I had in the source: An explosion of LP*Suffix classes, amounting to nearly forty of the blasted things. Most of these were empty or nearly-empty classes that served the purpose of replicating the base class LPSuffixFlag value with the class type. Basically, I was using the class hierarchy to duplicate the data that I was already storing, without these extra classes offering anything useful in the way of data functionality.</p>
<p>What they offered, instead, was a maintenance nightmare. The number of genuinely unique suffix formats is actually a relatively sparse ten. Suffixes break down into these formats:</p>
<ul>
<li>LPSuffix &#8212; Zero arguments</li>
<ul>
<li>Encodes: APPLIED, CAST_START, CAST_SUCCESS, CREATE, DESTROYED, DIED, DURABILITY_DAMAGE, DURABILITY_DAMAGE_ALL, INSTAKILL, KILL, REMOVED, RESURRECT, SHIELD, SPLIT, and SUMMON.</li>
</ul>
<li>LPAmountSuffix &#8212; One unsigned integer argument.</li>
<ul>
<li>Encodes: EXTRA_ATTACKS</li>
</ul>
<li>LPAmountStringSuffix &#8212; Two arguments. Unsigned integer followed by a string.</li>
<ul>
<li>Encodes: ENERGIZE</li>
</ul>
<li>LPDamageSuffix &#8212; Nine arguments, encoding the values of the DAMAGE suffix specifically.</li>
<li>LPDrainSuffix &#8212; Three arguments. An unsigned integer, then a string, then an unsigned integer.</li>
<ul>
<li>Encodes: DRAIN, LEECH</li>
</ul>
<li>LPHealSuffix &#8212; Four arguments, encoding the values of the HEAL suffix specifically.</li>
<li>LPSpellSuffix &#8212; Three arguments, making up an LPSpell.</li>
<ul>
<li>Encodes: DISPEL_FAILED, INTERRUPT</li>
</ul>
<li>LPSpellStringSuffix &#8212; Four arguments. An LPSpell plus an extra string.</li>
<ul>
<li>Encodes: AURA_BROKEN_SPELL, DISPEL, STOLEN</li>
</ul>
<li>LPStringSuffix &#8212; One string argument.</li>
<ul>
<li>Encodes: AURA_APPLIED, AURA_BROKEN, AURA_REFRESH, AURA_REMOVED, CAST_FAILED, SHIELD_MISSED, MISSED</li>
</ul>
<li>LPStringAmountSuffix &#8212; Two arguments. String followed by an unsigned integer.</li>
<ul>
<li>Encodes: AURA_APPLIED_DOSE, AURA_REMOVED_DOSE</li>
</ul>
</ul>
<p>The end result of all of this is a much more manageable code base, which is permitting me the opportunity to add some additional features (like pervasive string caching) to all of the suffixes instead of just a choice few. Once that&#8217;s done, the goal is to develop a hashing algorithm to override NSObject&#8217;s hash method and let me use a backing hash table to cache the suffixes as well.</p>
<p>The end goal, both in the code and in the parser&#8217;s RAM, is to eliminate redundancy. This was a good first step!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/the-great-suffix-culling/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data redundancy in the WoW combat log</title>
		<link>http://www.lifebloomretain.com/blog/2011/data-redundancy-in-the-wow-combat-log</link>
		<comments>http://www.lifebloomretain.com/blog/2011/data-redundancy-in-the-wow-combat-log#comments</comments>
		<pubDate>Tue, 26 Jul 2011 12:36:02 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[log parser]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[warcraft]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=83</guid>
		<description><![CDATA[I&#8217;ve been rewriting some of the my entry handling code today in an attempt to improve the speed and memory usage of the import code, which currently consumes approximately twice the input-text size in RAM, after parsing is complete. In doing so, I&#8217;ve seen that there are a lot of opportunities to reduce memory consumption [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been rewriting some of the my entry handling code today in an attempt to improve the speed and memory usage of the import code, which currently consumes approximately twice the input-text size in RAM, after parsing is complete. In doing so, I&#8217;ve seen that there are a lot of opportunities to reduce memory consumption by eliminating data redundancy in the code, by storing identical sections of each entry in a cache. I&#8217;ve done this in the past with actors, spells, and a few other things like aura type strings, but now I find that I should be extending the process to include entire prefixes and suffixes.</p>
<p>For instance, actors repeatedly causing the replenishment buff on the raid generate an enormous amount of identical or near-identical events to occur in rapid succession. There should be no reason why I should have to individually store all of these, if I can cache the identical potions in a hash table and place pointers in my LPEntry objects instead.</p>
<p>Work is ongoing! Adventure and excitement await!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/data-redundancy-in-the-wow-combat-log/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a log parser, step 2.2: Anatomy of Prefixes and Suffixes</title>
		<link>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-2-2-anatomy-of-prefixes-and-suffixes</link>
		<comments>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-2-2-anatomy-of-prefixes-and-suffixes#comments</comments>
		<pubDate>Tue, 19 Jul 2011 15:36:38 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[log parser]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[warcraft]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=78</guid>
		<description><![CDATA[It&#8217;s been a while since I wrote about anything at all, during which time I&#8217;ve been spending a lot of time working on other things, like raiding in Firelands! During this time, I&#8217;ve also taken a while to rethink some of the decisions I made about the structure of my log parser, especially the data [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_80" class="wp-caption alignright" style="width: 310px"><a href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/07/drypost.jpg"><img class="size-medium wp-image-80" title="drypost" src="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/07/drypost-300x283.jpg" alt="A dry post" width="300" height="283" /></a><p class="wp-caption-text">What a dry post may look like.</p></div>
<p>It&#8217;s been a while since I wrote about anything at all, during which time I&#8217;ve been spending a lot of time working on other things, like raiding in Firelands! During this time, I&#8217;ve also taken a while to rethink some of the decisions I made about the structure of my log parser, especially the data flow between the log file on disk and the combat log data structure in memory. Thus far, I have yet to step back and reinvent the wheel on my prefix and suffix handling, which still remains the bulk of the (lines of) code, so I&#8217;m happy to write about them here!</p>
<p>In any given night of combat log, I typically see approximately 33 entry types, meaning 33 unique pairings of PREFIX_SUFFIX. There are more legitimate versions that can appear, but are exceptionally rare in practice due to them being cases that people don&#8217;t often do, like enchanting weapons during raids. Still, with 33 combinations, it&#8217;s necessary to find a way of handling these data structures without writing special case code for each individual type. That&#8217;s where the prefix and suffix structures come in.</p>
<p>The base classes for these objects are the LPPrefix and LPSuffix classes. The interface for LPPrefix looks like this:</p>
<pre class="brush: objc; title: ; notranslate">
typedef enum {
	PREFIXUNKNOWN,
	SWING,
	RANGE,
	SPELL,
	SPELL_PERIODIC,
	SPELL_BUILDING,
	ENVIRONMENTAL,
	UNIT,
	ENCHANT,
	PARTY
} LPPrefixFlag;

@interface LPPrefix : NSObject {
	@private
    LPPrefixFlag flag;
}

@property (readonly) LPPrefixFlag flag;

-(id)init;
-(id)initWithArray:(NSArray *)args forLog:(LPCombatLog *)log;
-(id)initWithFlag:(LPPrefixFlag)f;
-(void)dealloc;
-(NSString *)description;

+(NSUInteger)numArgs;
+(NSString *)nameForFlag:(LPPrefixFlag)f;

// Interface to subclass properties.
-(LPSpell *)spell;
-(NSString *)type;
@end
</pre>
<p>LPSuffix is similar. There&#8217;s not much to this, in practice. A simple type descriptor and interfaces to allow subclasses to all use a common interface despite having varying types of data contained within. I&#8217;m not terribly happy with the presence of the &#8220;spell&#8221; and &#8220;type&#8221; methods, as they break the OO model slightly by requiring the superclass to be informed about interesting attributes of subclasses, but I made a decision in my code to store pointers only to the superclass, which makes display in an NSTableView with cocoa bindings awkward without this pass-through interface. I wish I knew a better way of doing this, but I&#8217;m a novice when it comes to the cocoa GUI library.</p>
<p>A concrete subclass of LPPrefix of note is the LPSpellPrefix class, one of the few prefixes to actually contain any interesting data other than a type.</p>
<pre class="brush: objc; title: ; notranslate">
@interface LPSpellPrefix : LPPrefix {
@private
    LPSpell *spell;
}

@property (readonly) LPSpell *spell;
</pre>
<p>Also of note is the LPSpell class.</p>
<pre class="brush: objc; title: ; notranslate">
@interface LPSpell : NSObject {
	@private
		NSString *name;
		uint64_t spellid;
		uint8_t school;
}

@property (readonly) NSString *name;
@property (readonly) uint64_t spellid;
@property (readonly) uint8_t school;

-(id)init;
-(id)initWithName: (NSString *)inName idString:(NSString *)inID schoolString:(NSString *)inSchool;
-(id)initWithName: (NSString *)inName spellid:(uint64_t)inID spellSchool:(uint8_t)inSchool;
-(void)dealloc;

+(id)keyForIDString:(NSString *)idstr;

-(NSString *)schoolDescriptor;
+(NSString *)descriptionForSchool:(uint8_t)school;

-(NSString *)description;
@end
</pre>
<p>The LPSpellPrefix class, then, encapsulates the &#8220;SPELL&#8221;, &#8220;SPELL_PERIODIC&#8221;, and &#8220;SPELL_BUILDING&#8221; prefixes shown at <a href="http://www.wowpedia.org/API_COMBAT_LOG_EVENT#Prefixes">Wowpedia</a>. It&#8217;s also constructed in a way that makes it store only unique copies of this data, using references into a backing NSDictionary of LPSpells to consolidate duplicates, but that&#8217;s a story for another day!</p>
<p>So that I&#8217;m not writing about suffixes without providing any information on what they look like, here&#8217;s the interface to LPDamageSuffix, used in events like SPELL_DAMAGE or SWING_DAMAGE. It&#8217;s one of the most common suffixes in the log.</p>
<pre class="brush: objc; title: ; notranslate">
@interface LPDamageSuffix : LPSuffix {
	@private
	NSUInteger damage, overkill;
	uint8_t school;
	NSUInteger resisted, blocked, absorbed;
	BOOL critical, glancing, crushing;
}

@property (readonly) NSUInteger damage;
@property (readonly) NSUInteger overkill;
@property (readonly) uint8_t school;
@property (readonly) NSUInteger resisted;
@property (readonly) NSUInteger blocked;
@property (readonly) NSUInteger absorbed;
@property (readonly) BOOL critical;
@property (readonly) BOOL glancing;
@property (readonly) BOOL crushing;

-(id)init;
-(id)initWithArray:(NSArray *)dArgs forLog:(LPCombatLog *)log;
-(void)dealloc;

-(NSString *)description;

+(NSUInteger)numArgs;
@end
</pre>
<p>In making the parser&#8217;s back end, one of the first tasks was to define and code up all of these classes, so that each combat log event could have a valid, unique combination of them to properly describe any event that happens. Of course, this has also led to some possibly weird combinations. For instance, my log parser could probably handle nonsensical combat log events like SPELL_BUILDING_AURA_BROKEN_SPELL or ENCHANT_DURABILITY_DAMAGE_ALL. The prefix and suffix handling is not, in any way, checked to make sure that it would appear in the game. If the combat log provides a valid string of content, then it&#8217;ll get parsed just like a proper entry.</p>
<p>The construction of the entry factory is going to be my next topic in this series, if I don&#8217;t do another post to describe the LPCombatLog implementation. The entry factory largely uses a series of array slices and some runtime reflection (and the numArgs method on every prefix/suffix) to construct combat log entries without knowing anything about the specifics of the individual prefix and suffix types.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-2-2-anatomy-of-prefixes-and-suffixes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Opinions on &#8220;Vengeance of the Void&#8221;</title>
		<link>http://www.lifebloomretain.com/blog/2011/opinions-on-vengeance-of-the-void</link>
		<comments>http://www.lifebloomretain.com/blog/2011/opinions-on-vengeance-of-the-void#comments</comments>
		<pubDate>Mon, 04 Jul 2011 04:35:13 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[rumors]]></category>
		<category><![CDATA[warcraft]]></category>
		<category><![CDATA[wowhead]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=72</guid>
		<description><![CDATA[Wowhead News is running a leak tonight of a supposed internal summary document of a new WoW expansion covering levels 86-90. MMO-Champion has just released a statement debunking the rumor, and I&#8217;m inclined to believe them, but having spent a tad over an hour compiling my thoughts on the concept, I think it&#8217;s sound to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.wowheadnews.com/blog=191853/new-expansion-rumored-to-be-vengeance-of-the-void">Wowhead News</a> is running a leak tonight of a supposed internal summary document of a new WoW expansion covering levels 86-90. MMO-Champion has just released a statement debunking the rumor, and I&#8217;m inclined to believe them, but having spent a tad over an hour compiling my thoughts on the concept, I think it&#8217;s sound to post this anyway. I think what I have to say here touches on a lot of issues that are currently affecting the game, and give some insight into what I think would work going forward.</p>
<p>So, that said, I wrote everything after this with the presumption that the rumor is true. Consider it a &#8220;What If?&#8221;</p>
<h2>A Return to Outland</h2>
<p>Taking us back to Outland is a smart move on Blizzard&#8217;s part, not because of where we need to go to fight the future, but because of where we have to go to fight the past. The Outland questing experience is, at this point, terrible. Boring quests, flat stories, and a lot of outstanding lore tied up in level 69-70 endgame content in Netherstorm and Shadowmoon Valley sum up to a frustrating and poorly executed gaming experience in the current day. By placing the next expansion in Outland, it would provide the 60-68 leveling zones with the needed economic and administrative backing to get the same sort of overhaul that the old world did for the release of Cataclysm.</p>
<p>Beyond that, WoW&#8217;s increasingly powerful engine and graphical technology could do wonders with the very beautiful Outland vistas. Zones like Nagrand and Netherstorm have some incredible potential that hasn&#8217;t necessarily been realized with the 2006-era technology used in The Burning Crusade.</p>
<h2>Tying Up Lore Loose Ends</h2>
<p>A lot of lore threads were left dangling in Burning Crusade that are crying out to be wrapped up. The fate of the demon hunters obviously factors into the leak, and was well-prepared for with the Illidan quests in Felwood that were introduced in Cataclysm. I&#8217;m particularly looking forward to a revivification of the neglected Draenei and Naaru storylines, especially in regard to the ruined Draenei settlements across outland in Shadowmoon Valley and Terokkar Forest.</p>
<p>While I&#8217;m most definitely an Alliance player, seeing the rumored expansion of the shadow priest lore would do wonders in giving some depth to the Forsaken, who are currently suffering from a bit of &#8220;Zombie Nazi Menace&#8221; syndrome. Presuming that at some point Lady Sylvanas will lose her plot armor and see some sort of comeuppance, it may even be possible for a delegation of the Cult of the Forgotten Shadow to take power in the Forsaken society, significantly changing the dynamic of both that race and the Horde in general.</p>
<p>Likewise, a return to Outland would likely pick open some scabs for the Alliance in the form of the unseen remnants of the original Outland expedition (*cough* Alleria *cough*) and the Sin&#8217;dorei in the form of Kael&#8217;thas&#8217;s remnants, still potentially pervading the Netherstorm and the battered, broken manaforges. That&#8217;s interesting plot fuel, and it&#8217;s being wasted currently.</p>
<h2>Evil A&#8217;dal? I guess the light DOES forsake its own, eh Bridenbrad?</h2>
<p>I don&#8217;t have a whole lot to say about A&#8217;dal being an antagonist except that hearing dozens of conspiracy theories about it all back in the days of Burning Crusade got old then, and it will still be old now. I suppose this answers some of the questions about why we were tasked with saving Millhouse Manastorm when he was, in reality, a Twilight Cultist. Also, a redemption of Illidan? Fun glowy blindfolds for everyone!</p>
<h2>Ethereals and Nagas</h2>
<p>To me, having the Protectorate join the Alliance feels very forced in much the same way that the Draenei were shoehorned into the Alliance narrative when, in reality, they would probably be too peaceful and wholesome to not be a neutral faction in another game. The Protectorate should have no beef with the Horde, which seriously makes me question what the motivation could be for attempting to generate enough of a rivalry between the two groups to push the Protectorate into the Alliance.</p>
<p>The Coralbreach naga joining the Horde seems equally unlikely, mostly because the Horde has evolved as a relatively xenophobic and distrustful entity. The orcs, and Garrosh in particular, have grown wary of outsiders polluting their way of life. The Forsken, Sin&#8217;dorei, and Darkspear Tribe have grown reclusive and withdrawn, turning inward to marshal their forces for the specific betterment of their own people. Meanwhile, the Tauren have developed into a strongly tribal society that practically looks ready to me to split off from the Horde and return to a nomadic lifestyle with fewer enemies to worry about. The Horde don&#8217;t seem to really be doing each other many favors, especially in terms of mutual support and defense. It&#8217;s hard to see how there&#8217;s going to be room in that milieu for members of a race that have attempted to flat-out destroy substantial regions of two different worlds.</p>
<p>Racial and and political ties are highly correlated in the WoW universe. There are no Alliance tauren or trolls, no Horde humans or night elves. All dwarves are now Alliance, and all orcs identify as Horde (welcome or not in the New Horde). How would that work with naga in the Horde? Would they take the Bilgewater Cartel approach and try to pretend like a very small niche population of a specific race is large enough to make a fully contributing member of the Horde? Maybe, but I think that&#8217;s wearing a little thin in the narrative, with no attempt to even hand wave the massive population difference that should exist in game terms between the sizes of the Alliance and Horde.</p>
<h2>Game Mechanics Are Fun</h2>
<p>Five new levels, refurbished zones, and no hint of new serious mechanics like stat changes or the like. To me, that says that we&#8217;re gearing up for a straight forward content expansion that won&#8217;t alter the status quo too much. I am concerned, however, that Cataclysm has shown us that a shallow endgame can be incredibly frustrating for certain players who end up feeling starved for interesting and diverse instance content. All of Cataclysm&#8217;s endgame content thus far &#8212; except for Bastion of Twilight &#8212; has been in the form of nostalgic re-imaginings of old settings (Blackwing Descent and Firelands) or small instances (Throne of the Four Winds). Blizzard hasn&#8217;t even been able to keep up with the development of what new, interesting content we were promised in the form of the Abyssal Maw, and we haven&#8217;t heard whisperings lately on the development of the anticipated War of the Ancients raid. What do, Blizz? Can you take another five-level expansion and give it enough legs in the endgame to keep us interested? I don&#8217;t want another seven month wait for seven bosses.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/opinions-on-vengeance-of-the-void/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fire fighting? Wasn&#8217;t that in Ulduar?</title>
		<link>http://www.lifebloomretain.com/blog/2011/fire-fighting-wasnt-that-in-ulduar</link>
		<comments>http://www.lifebloomretain.com/blog/2011/fire-fighting-wasnt-that-in-ulduar#comments</comments>
		<pubDate>Mon, 27 Jun 2011 17:11:11 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[firelands]]></category>
		<category><![CDATA[warcraft]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=69</guid>
		<description><![CDATA[Has it been an entire raiding tier already? Tomorrow, we get to venture into the elemental plane of fire to face Ragnaros! Again! Personally, I&#8217;m more interested in his lieutenant, Majordomo Frandral Staghelm, who has the dubious distinction of being one of the few genuinely hated lore figures, despite having been a closeted villain for [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_70" class="wp-caption alignright" style="width: 310px"><a href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/Screen-shot-2011-06-27-at-12.22.12-PM.png"><img class="size-medium wp-image-70" title="Screen shot 2011-06-27 at 12.22.12 PM" src="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/Screen-shot-2011-06-27-at-12.22.12-PM-300x187.png" alt="What my days have looked like for weeks." width="300" height="187" /></a><p class="wp-caption-text">Too much of this! Time to play some WoW!</p></div>
<p>Has it been an entire raiding tier already? Tomorrow, we get to venture into the elemental plane of fire to face Ragnaros! Again! Personally, I&#8217;m more interested in his lieutenant, Majordomo Frandral Staghelm, who has the dubious distinction of being one of the few genuinely hated lore figures, despite having been a closeted villain for more of his career, and who drops an awesome fire cat staff! Yeah!</p>
<p>Other things I&#8217;m looking forward to? The extension of the Hyjal lore is very appealing to me as a night elf and druid lore wonk, and there are several new pets that I&#8217;ll be picking up from the dailies there. I&#8217;m also hoping to find time this tier to start doing some rated battlegrounds with my guild, which never seemed very appealing to much of us during tier 11 &#8212; We never had a proper guild group, and those who wanted to do RBGs were pugging with other, more pvp-oriented guilds on Zul&#8217;jin.</p>
<p>I&#8217;d also like to actually finish an entire tier of content on every difficulty level for the first time since tier six. In the past, I&#8217;ve always had one or two bosses hanging loose at the end of a tier. I never finished sunwell at level, nor did I get that kill of Sarthartion-3D on ten (we did on 25)… we didn&#8217;t get Firefighter or Algalon 25, and then when I joined BRM, we never got our Tribute to Insanity 25, though we did score a 49-attempt Mad Skill, I think. Never did Light of Dawn at level, either, though not for lack of trying. This tier, we went 9/13 including a heroic Al&#8217;Akir 10 kill. Years of almost there, but never quite scoring that final check mark on any tiers since Burning Crusade.</p>
<p>The game has changed since then, though, and I&#8217;m looking forward to getting my ducks in a row and joining this tier with a clear head and fresh motivation. After spending 9, 10, and sometimes 14 hour days learning about Cocoa and programming my brains out for some time, setting up a blog and attempting to learn how to use GIMP and Inkwell to pretend to make graphics, and only logging in to WoW to do fire festival dailies and truegold cooldowns, I&#8217;m ready to play some more.</p>
<p>It&#8217;s time to marshal my cadre of alts, farm a ton of valor points to make my craftables on my druid, and knock down bosses like dominoes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/fire-fighting-wasnt-that-in-ulduar/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git support in XCode 4 is not good</title>
		<link>http://www.lifebloomretain.com/blog/2011/git-support-in-xcode-4-is-not-good</link>
		<comments>http://www.lifebloomretain.com/blog/2011/git-support-in-xcode-4-is-not-good#comments</comments>
		<pubDate>Sun, 26 Jun 2011 14:48:06 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[xcode 4]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=62</guid>
		<description><![CDATA[I had intended to continue my series on writing a WoW log parser this weekend, but a fairly substantial refactoring of the code has thrown a wrench into that. Thankfully, I decided to dip my toes into Git support in XCode to branch this refactoring, so now I have something new to write about! I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_66" class="wp-caption alignright" style="width: 310px"><a href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/scumbag-xcode-4-v2.jpg"><img class="size-medium wp-image-66" title="scumbag-xcode-4-v2" src="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/scumbag-xcode-4-v2-300x300.jpg" alt="Scumbag XCode 4" width="300" height="300" /></a><p class="wp-caption-text">This took me longer to make than the post. So worth it.</p></div>
<p>I had intended to continue my series on writing a WoW log parser this weekend, but a fairly substantial refactoring of the code has thrown a wrench into that. Thankfully, I decided to dip my toes into Git support in XCode to branch this refactoring, so now I have something new to write about!</p>
<p>I&#8217;m relatively new to the modern world of version controlling software. Years ago, I used CVS and dipped my toes into the then-young Subversion when writing some code in college, but for my own personal projects since then, I&#8217;ve not really bothered. I certainly never tied it into a modern IDE like XCode, having done most of my previous coding with vi, <a href="http://www.codingmonkeys.de/subethaedit/">SubEthaEdit</a>, and <a href="http://www.barebones.com/products/textwrangler/">TextWrangler</a>/BBEdit. On my kick recently of, &#8220;I&#8217;m going to stop programming like I&#8217;m in college!&#8221;, I spent a few hours this weekend trying to get XCode 4 to work properly with a <a href="https://github.com/">Git</a> repository that I created for my parser project. It didn&#8217;t go well, unfortunately.</p>
<p>XCode 4&#8242;s Git support seems simple enough. You have an option of creating a new project with a Git repository thrown in already, which is kind of neat, but my project is old and I didn&#8217;t want to try recreating it, so I had to manually create a repository from the command line and hook my project into it. That went fine, following <a href="http://developer.apple.com/library/mac/#documentation/ToolsLanguages/Conceptual/Xcode4UserGuide/SCM/SCM.html">Apple&#8217;s guide to doing exactly that</a>. What I wasn&#8217;t prepared for is that Apple&#8217;s instructions leave you with a very awkwardly set up Git repository, because they don&#8217;t teach you how to exclude files that are <em>constantly</em> changing, like the pervasive Mac OS .DS_Store metadata files, or XCode&#8217;s own project metadata files that store, seemingly, information like &#8220;Timestamp of last user inhale.&#8221; that is constantly in flux. This causes situations like what I experienced today. Commit my project, look at window and blink thinking, &#8220;Not bad!&#8221;&#8230; two seconds later, the XCode metadata is dirty again and wants to be recommitted. Repeat <em>ad nauseum</em>.</p>
<p>The answer to this is to set up a Git ignore file, which would have been fine, except you also have to find the files that have been ignored and manually remove them from git. Fine, that&#8217;s more work than this was worth, but I learned how.</p>
<p>Then I went to go push my local working copy of my project onto my AFP-mounted NAS volume (Named The TARDIS because it&#8217;s bigger on the inside) and I found out that XCode hates that, too, throwing me errors saying that the repository cannot be found while I&#8217;m staring at it in Finder.</p>
<p>Long story short: screw that noise! I&#8217;ll use snapshots until Apple decides to provide a more effective UI for their tool or a set of documentation that doesn&#8217;t constantly leave me scrambling for <a href="http://blog.mugunthkumar.com/articles/tutorial-setting-up-git-on-your-mac/">blog</a> <a href="http://blog.mugunthkumar.com/articles/tutorial-setting-up-git-on-your-mac/">posts</a> and <a href="http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects">stack overflow pages</a> and <a href="http://openradar.appspot.com/8951416">radar listings</a> to teach me the basic concepts via Google.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/git-support-in-xcode-4-is-not-good/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a log parser, step 2.1: Prefixes and Suffixes</title>
		<link>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-2-1-prefixes-and-suffixes</link>
		<comments>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-2-1-prefixes-and-suffixes#comments</comments>
		<pubDate>Thu, 23 Jun 2011 05:02:35 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[log parser]]></category>
		<category><![CDATA[warcraft]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=59</guid>
		<description><![CDATA[I wish I was an expert at string parsing. A mistress of code that could write some sort of amazing parsing tool with an actual grammar in lex/yacc or something and have it do amazing things and be magical… but I&#8217;m not. Knowing this, when it came time to write a string parser for my [...]]]></description>
			<content:encoded><![CDATA[<p>I wish I was an expert at string parsing. A mistress of code that could write some sort of amazing parsing tool with an actual grammar in lex/yacc or something and have it do amazing things and be magical… but I&#8217;m not. Knowing this, when it came time to write a string parser for my application, I went through a few ideas that didn&#8217;t work out before settling on one that sort of did. I&#8217;ll skip to the punch here and describe the one I settled on.<br />
A line in the WoWCombatLog.txt file has a certain format that is documented on <a href="http://www.wowpedia.org/API_COMBAT_LOG_EVENT">Wowpedia</a>. It has up to twenty-one entries, each keyed according to three conceptual portions of the line: The base, a prefix, and a suffix. The base is always the same, and can be safely parsed without understanding the rest of the line. It contains an entry, called &#8220;event&#8221; on Wowpedia, that has a string that looks like &#8220;SWING_DAMAGE&#8221; or &#8220;SPELL_AURA_APPLIED_DOSE&#8221; or some other compound term that acts as a key to the context for the rest of the line.<br />
Parsing one line of this is a four step process:</p>
<ol>
<li>Build an array of arguments that consumes the first nine strings in the input array (the timestamp is two strings as described in my previous post). This produces an array with four objects contained within: The the timestamp NSDate, type NSString, and two LPActor pointers that encapsulate three strings each for name, id, and flags. I also maintain a dictionary of actors that is searched here, so that each LPActor is only stored once.</li>
</ol>
<p style="text-align: center;">
<div id="attachment_60" class="wp-caption aligncenter" style="width: 442px"><a href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/baseArgs-Diagram.png"><img class="size-full wp-image-60 " title="baseArgs Diagram" src="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/baseArgs-Diagram.png" alt="A diagram of the baseArgs array." width="432" height="105" /></a><p class="wp-caption-text">What the baseArgs data structure looks like, transformed from the input.</p></div>
<ol>
<li>Parse the &#8220;type&#8221; NSString to determine the following values:
<ol>
<li>pFlag = Prefix flag</li>
<li>pArgC = Prefix argument count</li>
<li>sFlag = Suffix flag</li>
<li>sArgC = Suffix argument count</li>
</ol>
</li>
<li>Slice the input array starting at index 8 with length pArgC, and hand that slice to a method that builds an encapsulated LPPrefix subclass.</li>
<li>Slice the input array starting at index (8+pArgC) with length sArgC and hand that slice to a method that builds an encapsulated LPSuffix subclass.</li>
</ol>
<p>The construction of the (roughly fifty) LPPrefix and LPSuffix classes created for this program will be the subject of my next programming post, but for right now we&#8217;ll just use a conceptual forward declaration and say that a combination of runtime reflection and dynamic method dispatch lets that work pretty easily.</p>
<p>The resulting LPEntry object finally contains only the things constructed here. The base arguments, prefix, and suffix. In this structure, we can semantically encapsulate all of the possible events that can occur in the WoW combat log.</p>
<p>Three asides as I wrap this up. First a note on versioning: This post is for WoW version 4.1 and prior. As I understand it, next week in 4.2 we&#8217;re getting two more elements in the base arguments to represent the raid icons on the source and destination actors.</p>
<p>Secondly, the Wowpedia page I linked earlier for reference is sometimes wrong on argument counts. I can&#8217;t check at the moment to find which one because the whole curse network is down and Wowpedia along with it.</p>
<p>Finally, whoever at blizzard decided that some numbers (i.e. spell school flags) in some contexts should be in hex code and in others should be in decimal needs to check out a book on &#8220;Things someone parsing this should not have to pay attention to.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-2-1-prefixes-and-suffixes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thoughts on T12 Resto Druid Gearing</title>
		<link>http://www.lifebloomretain.com/blog/2011/thoughts-on-t12-resto-druid-gearing</link>
		<comments>http://www.lifebloomretain.com/blog/2011/thoughts-on-t12-resto-druid-gearing#comments</comments>
		<pubDate>Tue, 21 Jun 2011 15:48:37 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[firelands]]></category>
		<category><![CDATA[gearing]]></category>
		<category><![CDATA[resto druid]]></category>
		<category><![CDATA[spreadsheets]]></category>
		<category><![CDATA[warcraft]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=51</guid>
		<description><![CDATA[A pdf of my t12 resto druid gear choices. I was thinking about the choices we have for gear in firelands this morning, and as Borsk so commonly says, the answer was a spreadsheet. I spent some time doing my prep for loot council this tier by reading Hamlet&#8217;s awesome post over at Elitist Jerks. [...]]]></description>
			<content:encoded><![CDATA[<p><a title="T12 Resto Druid Gear Spreadsheet (Initial)" href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/t12-rdruid-gear.pdf"></a></p>
<p><a title="T12 Resto Druid Gear Spreadsheet (Initial)" href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/t12-rdruid-gear.pdf"> </a></p>
<div class="mceTemp"><a title="T12 Resto Druid Gear Spreadsheet (Initial)" href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/t12-rdruid-gear.pdf"></a>
<dl id="attachment_53" class="wp-caption alignright" style="width: 99px;"><a title="T12 Resto Druid Gear Spreadsheet (Initial)" href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/t12-rdruid-gear.pdf"></a>
<dt class="wp-caption-dt"><a href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/t12-rdruid-gear.pdf"><img class="size-full wp-image-53" title="t12 druid spreadsheet icon" src="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/Screen-shot-2011-06-21-at-11.33.26-AM.png" alt="Download the pdf!" width="89" height="103" /></a></dt>
<dd class="wp-caption-dd">A pdf of my t12 resto druid gear choices.</dd>
</dl>
</div>
<p>I was thinking about the choices we have for gear in firelands this morning, and as <a title="Borsked" href="http://www.borsked.com/">Borsk</a> so commonly says, the answer was a spreadsheet. I spent some time doing my prep for loot council this tier by reading <a title="Elitist Jerks" href="http://elitistjerks.com/f73/t110354-resto_cataclysm_release_updated_4_2_a/">Hamlet&#8217;s awesome post</a> over at Elitist Jerks. I made a document of every piece of gear I could find for this tier and went about picking obvious winners on the basis of, &#8220;More intellect is better, spirit is nice, meet haste goal, prefer mastery.&#8221;</p>
<p>The linked spreadsheet is the result for the normal-mode gear. Several choices will have to be rethought moving into heroics, though. The gloves, cloak, ring #2, and boots selected do not have heroic mode equivalents unless they become upgradable via the sunmote-2.0 system. I didn&#8217;t check that out, yet.</p>
<p>Blizzard seems to have learned their lesson about bracers this tier, as there are several wrist choices to pick from. Keeping it real, they&#8217;ve apparently stuck us in belt hell by way of recompense, as the only leather intellect belt that I could find in the 4.2 lists was a rep reward with crit/haste on it. I suppose hoping for a spirit/mastery, spirit/haste, or master/haste item was too optimistic! Also, we&#8217;ll be wearing a mismatched color scheme for the whole tier because there&#8217;s no heroic-colored belt. Fix it, please, Blizzard!</p>
<p>Sometimes I envy warriors and their ability to get a heroic-level item in every slot. I don&#8217;t think offhand that any tier of content has offered that for a druid, mostly owing to relics. This tier, the relics are supposedly upgradable, but we&#8217;re getting shafted on a belt!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/thoughts-on-t12-resto-druid-gearing/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building a log parser, step 1: Tokenization</title>
		<link>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-1-tokenization</link>
		<comments>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-1-tokenization#comments</comments>
		<pubDate>Tue, 21 Jun 2011 09:00:11 +0000</pubDate>
		<dc:creator>eranthe</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Warcraft]]></category>
		<category><![CDATA[log parser]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[warcraft]]></category>

		<guid isPermaLink="false">http://www.lifebloomretain.com/blog/?p=39</guid>
		<description><![CDATA[The WoW combat log, specifically its on-disk incarnation, is a hairy subject to address in my second blog post, I&#8217;m sure. I can&#8217;t imagine it has very mass-market appeal as a topic, but it&#8217;s been a major focus of my programming efforts over the last month or so, and what else am I going to [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_41" class="wp-caption alignright" style="width: 336px"><a href="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/Screen-shot-2011-06-21-at-12.18.22-AM.png"><img class="size-full wp-image-41 " title="combatlogs.png" src="http://www.lifebloomretain.com/blog/wp-content/uploads/2011/06/Screen-shot-2011-06-21-at-12.18.22-AM.png" alt="Combat logs!" width="326" height="227" /></a><p class="wp-caption-text">The one on the left is 210 MB and 1.35 million lines.</p></div>
<p>The WoW combat log, specifically its on-disk incarnation, is a hairy subject to address in my second blog post, I&#8217;m sure. I can&#8217;t imagine it has very mass-market appeal as a topic, but it&#8217;s been a major focus of my programming efforts over the last month or so, and what else am I going to write about, anyway? New spider pets for hunters in 4.2? Puh-leez. Fair warning, if you&#8217;re educated in the ways of computer science or basic string programming, this is going to look like child&#8217;s play. I don&#8217;t mean to over-elaborate on a simple subject, but it doesn&#8217;t matter because who reads this stuff anyway? Sheesh!</p>
<p>So, the combat log is, in theory, a pretty simple thing. It&#8217;s plain, UTF-8 encoded text that represents one action per line. Those actions are serialized as a (mostly) comma-delimited list of string tokens. The meaning behind each token depends on its position and on the values of a special type-token near the beginning of the line.</p>
<p>Having the meanings of each token dependent on value-decoding earlier tokens belies the modern day combat log&#8217;s roots as having a pseudo-English sentence structure. It also means that it requires a relatively intense tokenizing and parsing effort compared to more modern file formats, like XML, that are guaranteed to be machine-readable without writing lots of task-specific code.</p>
<p>But I digress. The important thing is that a line that used to look like a pretty unassuming English sentence now looks like this:</p>
<pre class="brush: plain; light: true; title: ; notranslate">5/19 00:00:00.960  SPELL_PERIODIC_HEAL,0x02000000011E5E3D,&quot;Eranthe&quot;,0x511,0x0200000001EBB45B,&quot;Tlazolteotl&quot;,0x512,64801,&quot;Rejuvenation&quot;,0x8,3541,0,0,nil</pre>
<p>That&#8217;s me (Eranthe) healing Tlazolteotl with the pre-hot tick of <a title="Rejuvenation" href="http://www.wowhead.com/spell=64801">Rejuvenation</a> from <a title="Gift of the Earthmother" href="http://www.wowhead.com/spell=51181">Gift of the Earthmother</a> for 3541 healing.</p>
<p>There are a few features that stand out. One is that the string isn&#8217;t actually comma-delimited like it pretends to be, because the timestamp at the beginning is space-delimited instead. Commas can also appear inside the quoted strings for names at several points. Another is that some numbers are in hex (designated by an 0x-prefix) and some others are in decimal, but that&#8217;s a topic for a very sarcastic paragraph in the upcoming post on the semantic parsing of this. Still, it&#8217;s easy to tokenize once you start doing it the way we learned in school and using a bunch of c-style switch statements while iterating over each character in the string. Out comes an ordered NSArray of NSStrings, each containing an un-delimited token.</p>
<p>If you&#8217;d like to tokenize a combat log line in Objective-C, well am I the girl for you! This method will take an NSString and give you back its tokens as an NSArray, as described above. It operates in O(n) for the string length. The first two tokens in the array encode the date and time for the timestamp separately. I glue them together later on when converting them into an NSDate. This will break if some wisecracking raider finds a way to include a double-quote character in his or her name.</p>
<pre class="brush: objc; collapse: true; light: false; title: ; toolbar: true; notranslate">
+(NSArray *)tokenizeString: (NSString *)input
{
	NSRange tokRange = NSMakeRange(0,0);
	NSUInteger length = [input length];
	BOOL escaped = NO;
	NSMutableArray *chunks = [[NSMutableArray alloc] initWithCapacity: 12];

	while ((tokRange.location + tokRange.length) &lt; length) {
		unichar here = [input characterAtIndex:(tokRange.location + tokRange.length)];
		if ((here == ' ' || here == ',') &amp;&amp; !escaped) {
			// We found the end of a token.
			NSString *token = [input substringWithRange: tokRange];
			if (here == ',' || (here == ' ' &amp;&amp; !([token isEqualToString: @&quot;&quot;]))) {
				[chunks addObject: token];
			}

			// We broke off this token, so move the pointer forward.
			tokRange.location = tokRange.location + tokRange.length + 1;
			tokRange.length = 0;
		} else if (here == '&quot;' &amp;&amp; !escaped) {
			// Found the beginning of a quoted string.
			escaped = true;
			// Also we don't want to capture the beginning quote.
			tokRange.location = tokRange.location + tokRange.length + 1;
			tokRange.length = 0;
		} else if (here == '&quot;') {
			// Found the end of a quoted string.
			escaped = false;

			[chunks addObject: [input substringWithRange: tokRange]];

			// Broke off this token, move the pointer forward.
			tokRange.location = tokRange.location + tokRange.length + 2;
			tokRange.length = 0;
		} else {
		    ++tokRange.length;
		}
	}

	// After the last delimiter, we need to chop off the last token.
	NSString *lastChunk = [input substringFromIndex: tokRange.location];
	NSString *trimmed = [lastChunk stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
	if (![trimmed isEqualToString: @&quot;&quot;])
		[chunks addObject: trimmed];

	return chunks;
}
</pre>
<p>From here, the question becomes, &#8220;What on Earth can I do with all of these tokens that I just made?&#8221; To answer that, it&#8217;s necessary to look into the semantic format of the line, and how you determine what each token means. Next time!</p>
<p>Before I forget, I should mention that there is a step 0 to building a log parser, which is efficient reading of a 200+ megabyte text file. I haven&#8217;t gotten to that part yet in my code, and instead read the whole file into memory and then deal with it from there. It&#8217;s inefficient and bad, but it&#8217;s one line of code compared to many!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifebloomretain.com/blog/2011/building-a-log-parser-step-1-tokenization/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

