Home

Search Posts:

Archives

Login

January 2014

S M T W H F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

I'll confess to being a bit late to the game on picking up puppet, but now that I've finally jumped in I'm completely hooked. Put simply, puppet is a piece of software, written in ruby, which allows machines to pull configuration information from a central "puppetmaster."

First, a little background, and an explanation of why I've fallen in love with the idea of such a system.

Why I use puppet

I currently manage a relatively small environment. I have about 15 physical servers and about a dozen xen guests. I'd long assumed that puppet - or its spiritual predecessor, cfengine - would be a poor fit in my situation. After all, I'm not managing seas of identical boxes - most of these machines have several unique aspects which they do not share with anything else.

I had assumed that all of the true commonalities would be taken care of at kickstart/jumpstart time, and that modifications to these commonalities would be few and far between. If they needed to change, I would change them manually. Not a big deal.

Except that's not how it works in practice. You just can't keep everything the same manually when you're dealing with more than one machine, and at some point you will want to change things everywhere and you will mess up. So, when I tweaked my system config to use kerberos for pam authentication instead of LDAP, I changed it on the kickstart, and I changed it everywhere I remembered - but I missed some boxes.

And you know what? I didn't even realize this until I moved this config into puppet.

It goes beyond this, though. It's not only about making sure the commonalities are preserved across machines and that changes are kept in sync. Even in situations where you really do have a unique configuration - something that only matters in one place - you very well might need to duplicate the setup later. There are so many little things that are easy to do without thinking much about - all the countless permission management and account creation and directory creation tasks that you do now, that you sure as hell won't remember in 5 years. This is especially true if you're not even working there and some other guy needs to replicate your work.

Puppet gives you the chance to codify all of this, and combined with subversion or git you actually have a change control mechanism for server state. Need to add a mail alias? Who cares if you don't think you'll need it elsewhere - put it in puppet and check it in to svn. Now you have both the recipe needed to recreate this configuration elsewhere, but also a record of the change and (if you comment in your svn commit) the reason why it was changed.

The puppet language itself is so concise that it's easy to see what you've done, even if you failed to document it anywhere. In effect, the mere act of making a change now becomes documentation. That's incredibly powerful.

As well, puppet often forces you to do things the right way. Puppet is really good at managing things - as long as you do the right things. A prime example here is in package management - puppet can easily ensure that you have the appropriate RPM (or sun pkg, or debian apt, or gentoo emerge, etc) packages installed as defined in your puppet configuration. Simply add the definition to puppet, and the package will be installed.

Now, this is great, until you run into a piece of software that hasn't been packaged - say, a perl module. In the past, it would be really tempting to just fire up CPAN and let it do whatever the hell it is that CPAN does, installing the perl module wherever it sees fit. But puppet knows nothing of CPAN - if you use CPAN, you work against puppet. The "right way" is (and always has been) to build RPMs (or whatever your native package is) and maintain your own repository, but puppet practically forces you to do this. Once you start trusting puppet for everything, you start doing everything in a way that's more maintainable and predictable as a side effect - and that makes you better at your job.

That, in a nutshell, is why I use puppet. Now, onto how I use it.

Puppet guts

My initial assumptions about puppet were that it was basically a dumb configuration file repository - that you throw confs in the puppet master and they get slurped down by the clients, potentially modified by some templating mechanism where a config needs to vary slightly across multiple environments. Indeed, this is a supported (and sometimes necessary) way of distributing configuration information to puppet clients, but after digging in a bit more I realized that there's usually a better way.

Puppet goes beyond the simple "fileserver with templates" paradigm to, effectively, provide an abstraction layer that can describe aspects of a UNIX system in its own dialect. Configuration information is primarily written using the "puppet language," utilizing special "types" which are ruby classes capable of mapping the puppet language into raw configuration details needed by systems. Where these types are inadequate, one can do other lower-level tricks, like directly executing UNIX commands or inserting raw data directly into files.

This is a bit cumbersome to describe, but the following example should help make this more apparent:

service { [ "stunnel" ]:

enable => true,
ensure => running,
subscribe => File[stunnelconf],
}

The "service" type comes with puppet, and it's an abstraction of - surprise - services. It takes many potential arguments, but in my case I'm calling it on a service named "stunnel" and defining "enable" as "true", "ensure" as "running", and "subscribe" as "File[stunnelconf]". In this context, that means that I want the service enabled on boot, that the service should be running (or made to run if it's not) when puppet runs, and that when the "File" resource named "stunnelconf" changes the daemon should be restarted (thus if the configuration changes you need not do a manual restart).

The magic in this is that "service" is smart enough to handle a wide array of different mechanisms for launching and monitoring states of services. On CentOS machines, the puppet "service" type will manage the service with a combination of calling init scripts and running the redhat-specific "chkconfig" mechanism. On a Solaris 10 box, however, this same type would manage stunnel through the SMF system, calling the svcadm utility (or possibly hooking directly into the API - I'm not sure). The beauty here is that the puppet "service" type knows all of this, and the wildly different systems are presented to you as exactly the same construct in the puppet language. I no longer need to care about the differing underlying mechanisms - I tell puppet I want the service turned on, and it does all of the actual work for me.

Things that can be managed with the included puppet "types" include user accounts, groups, yum repositories, packages, file permissions, cron jobs, mail aliases... well, there are quite a few of them, and the puppet type reference goes into great detail on their capabilities.

Now, it would be nice to have native types for every resource, but understandably there are many occasions where no type is available. You could create your own puppet type in ruby to handle such a situation, but this would take a chunk of time and it might not be worth the extra effort.

Luckily, the puppet language itself gives you enough tools to abstract configuration elements through the use of templates and the included "file" type. It's not quite as powerful as writing your own full-fledged type, but it's also much more straightforward and much easier to implement.

As an example, here's a snippet of how I pull in my snmp config:

file {"/etc/snmp/snmpd.conf":

content => template("snmp/snmpd.conf.erb","snmp/$snmpextra.erb"),
mode => 0644,
alias => snmpconf,
}

That "$snmpextra" thing is a puppet variable. In my case here, I have a base snmpd.conf.erb file, which is an ERB template that contains my most basic snmp config. However, I also have an optional additional template which is appended if the $snmpextra variable is defined. In this way, I can keep one "master" configuration, but I can add additional local configurations as needed. Note that the ERB templates themselves can contain ruby code that inserts text based on puppet variables or facts, but they need not do so - they could be a simple configuration file copied directly from a working config.

In case you're wondering what a "fact" is, it's a snippet of system information provided by puppet's "facter" helper utility. Just as puppet types can abstract configuration directives, facter is a standalone utility that's used to abstract the gathering of system metadata. Whenever puppet is run, facter collects a series of "facts" about a system, and these facts can be used to make decisions in the puppet language or within ERB templates.

So, for example, here I check for the $operatingsystem fact and include a different class based on that fact:

class legato::client {

case $operatingsystem {
centos: { include legato::client::centos }
solaris { include legato::client::solaris }
}
}

Note that, in the puppet language, a "class" is not like a "class" in object oriented programming - rather, it describes a bundle of configuration directives, and you can apply them with the "include" statement. In this snippet, I pull in the legato::client::centos class for centos machines, and the legato::client::solaris class for Solaris machines. In cases where there is no native puppet type, you can manage operating system specific details in this way.

Conclusion

That's the basic gist of what puppet can do and how I use it, but there are many details that are documented on its excellent wiki, which you really should read if you're interested in the software. I highly recommend it, even if you're only dealing with a handful of systems - I've come to rely on puppet, not only to help me to get things done, but also to make sure I do them the right way.

I'm starting to feel like we've seen this before, somewhere. You have the Bush administration telling us there's a dire crisis, and that we have to do exactly what he says or the terrorists financial bogeyman will win.

Well, surely, he wouldn't lie to us again.

It is a bit strange to see the Democrats all gung ho this time, though. Isn't this the party for labor unions and the "working man?" You know, redistributing wealth downward, not upward? I guess at the end of the day anything that expands the power of the federal government - and the executive in particular, since they seem to think Obama will win - is A-OK by them.

When I heard that the bill was sunk, I eagerly looked up the roll call in the hopes that my representative, David Price, might have done the right thing. Unfortunately, he did not. Fortunately, I get to vote against him in November.

Everything else be damned, I'll be a one issue voter over this. Attempting to rob the taxpayers of almost a trillion dollars to fund a failed business model is not something that can go unpunished.

Let's take a trip back - way back. Before the perpetual war on terror, before the federal government got into the business of wealth redistribution - back to when the country was born.

The founders were not asking questions about drilling for oil or bailing out banks - they had real things to figure out. They were asking how they could create an entity that was powerful enough to preserve the rights of its citizens and member states, yet constrained enough that it could never be used to violate these rights. More than this, even, they had to ask what these "rights" even were.

History conspired to place Jefferson, a man of the Enlightenment, behind the Declaration of Independence, and thus managed to irrevocably tie the philosophy of John Locke with the birth of the new nation.

Jefferson - and those who agreed with him - feared power, and rightly so. They had witnessed the abuse of power first hand, and they felt that such power was anathema to a society of free men. The Constitution and the Bill of Rights were drafted to shackle the federal government, to prevent any man or group of men from acting as a despot.

The Jeffersonian view of government was essentially classical liberalism. The core tenet of classical liberalism is that of inalienable rights, as Jefferson described them in the Declaration of Independence - rights that all men share, rights that may not be forfeit to government. Rather than government granting its citizens rights, the citizenry grants its government certain powers to be used only to protect these rights.

These core rights of man were referred to by Locke as "life, liberty, and property." While it is perhaps unfortunate that the text of the Declaration of Independence contains a modified version of this phrase, the 5th amendment still contains Locke's version:

No person shall... be deprived of life, liberty, or property, without due process of law; nor shall private property be taken for public use, without just compensation.

It is clear that protection of private property from the federal government was a key consideration of the founders in general. Madison summed it up quite nicely:

... the government of the United States is a definite government, confined to specified objects. It is not like the state governments, whose powers are more general. Charity is no part of the legislative duty of the government.

In this quote you also get a real sense of how the Constitution was designed to restrain the government. The original republicans had no notion that the Constitution would become a "living document" the way that our current judicial system likes to view it. To them, it was "living" only in the sense that there were provisions through which it could be modified. What the Constitution said is what the Constitution meant, and the articles contained therein could not be violated by the government. Where it is unclear or inadequate, it is meant to be amended, but it is not meant to be reinterpreted - it is meant to be obeyed.

It's also clear that the states were meant to "pick up the slack," performing all the other responsibilities of government. While the federal government's powers were clearly enumerated in the Constitution, the States' were not. Citizens were allowed to grant their respective states additional powers as they saw fit, but they could never do this to the federal government without a Constitutional amendment.

Over time, due to real and imagined threats, the federal government has gradually expanded its scope well beyond this original intent, and essentially violates the intent of the Constitution with almost every action it engages in. Since the Supreme Court claims to be the ultimate arbiter of what the Constitution means, the document - which was intended to cripple the federal government - is now placed at the mercy of the institution it was meant to restrain.

Some of the Unconstitutional acts of the government are so obvious that they're ludicrous on the face of it. The "war on drugs" is one of the more flagrant violations - it should be quite telling that in 1919 a Constitutional amendment was required for the federal government to outlaw alcohol, but a mere 50 years later Nixon and his friends in congress managed to outlaw drugs entirely on their own.

Other government programs, though, are more insidious. The worst perhaps are those that people feel compelled to engage in out of altruism, as with the various welfare programs operated under the umbrella of Social Security. While presumably these programs really were created with the best of intentions, such wealth redistribution is well beyond the original scope of the federal government. Indeed, any such actions should have been taken by the states; but now we all come to largely accept them.

In our current political climate, our candidates for national office do not run on platforms of defending the Constitution or protecting the freedoms of the states. Instead, they run on platforms of morality legislation and wealth redistribution - both of which are outside of the scope of the federal government. The most frustrating, perhaps, are the promises of token tax cuts - they have the gall claim that if you vote for them they'll do you a favor by stealing a little bit less from you.

You could argue that all this is just fine. That the federal government should wield such power. That it should be in the business of regulating activities between consenting adults. That it should be able to redistribute wealth to the poor.

These are discussions worth having. We live in a democracy - we have a framework for making such things happen.

But we, as a people, as a union of states, never asked for these things in the only way we are able - by amending the Constitution. Instead, our government took these things and told us they were for our own good.

And, over time, we believed it. Maybe we wanted the government to reach into somebody else's pocket and give us a cut of their wealth. Maybe we wanted the government to reach into other peoples' bedrooms and stop them from engaging in activities we believe to be perverse.

We, as a people, stopped asking how to keep the government under control, and instead started asking how we could use the government to control everybody else. And feeding off of this, the government itself took more and more, playing off of these desires in the populace to bypass the Constitution, bit by bit.

Now, every election, the government offers back to us a fraction of what it takes. Token tax cuts, funding for our local school systems - money that they never had the right to take in the first place.

I'll end this post with the words of Ben Franklin:

When the people find that they can vote themselves money, that will herald the end of the republic.

This past weekend, Warhammer online held a "preview weekend" beta event for people who had pre-ordered the game.

I got the invitation email on Friday - for an event that starts on Friday and runs to Sunday. Fine, whatever. But WAR is a 10 GB download, and I was slowly slurping it down via torrent - and there was no way I could finish the download in time. The only chance of getting the file in time was to use Fileplanet.

Fileplanet is horrible. It doesn't work in Firefox. Oh, it seems to - until you go to download something, at which point you notice that the captcha doesn't work. So, I jump through the hoops in IE, and finally get to a download link - but it's not just a normal http or ftp link, no, it's some proprietary thing that requires the Fileplanet IE toolbar.

Eventually I got the stupid thing downloading, and sometime Friday afternoon it finished. I logged in remotely via VNC to poke around.

First thing of note - there's not really an installer. You just end up with a directory that contains "setup.exe" which does nothing but add some registry keys and create some Windows shortcuts. I like this.

Feeling adventurous, I fired up the patcher from work. It did its thing for a bit and seemed to get everything in the appropriate state.

I didn't get a chance to play for real until Saturday. I figured I'd start off with an Empire Warrior Priest, since their healing mechanic seemed interesting - they basically have to melee to build up mana for healing.

Character creation is pretty straightforward. Just like with WoW and many other modern games, you don't get to set attributes or anything like that - you aren't given a chance to gimp your character at creation time. Also like WoW, appearance options are very limited - no body type choices, no sliders of any sort, you've just got 6-10 options each for face/hair/hair color/eye color/skin color.

I selected a female model. First thing I noticed was her ridiculous posture - she's arching her back in a completely improbable manner. I went through the various options, not really sure what I was looking for. I quickly realized that all of the facial expressions could best be described as "snarling" or "insane." I grabbed one that looked a little less demented, and I ended up selecting a hair model based on the fact that it had no clipping issues.

By this point I'm already underwhelmed by the character appearance. Art direction looks like some kind of hybrid between DAoC and WoW - very cartoony like WoW, but lacking the vitality and cheer, instead feeling just generally "drab" as did DAoC. On top of this, the graphics just look inexplicably "old" - the models and textures really do not look like they belong in a modern game. I know this game's focus is on large scale PvP, and pretty/detailed models just don't work well in such an environment, but I still find this a bit disappointing.

Enter the game. I'm in some kind of town, with a bunch of other noobs - time to get to killing foozles.

Immediately I notice the strange character animations. It's hard to describe with words, but when you run, your character's arms and legs seem to splay in a jerky and ridiculous manner. It looks very unnatural. It's even more odd when you strafe run, and you see your character move at an angle. Really weird.

OK, so killing foozles. I see a green dot on my radar, pretty clearly something I should look into. Looks like this guy is the foozle master - he wants me to go out and kill stuff. Got it, guy. He was also kind enough to mark the kill zone on my map, which is a pretty basic feature notable only due to the fact that WoW still lacks it.

On with the killing. I find some foozles and start whacking them. As it turns out, the warrior priest seems to really suck at killing stuff - I have a crappy nuke that does minimal damage, and a melee ability that does a bit more damage. Combat works like this, generally:

- pull with crappy nuke
- use melee attack
- keep hitting melee attack button until dead

This normally takes ~30-45 seconds per (even level) monster, which feels excruciatingly long.

The WP does have healing abilities, but I never really needed them in PvE until I ended up facing an "elite" (which I guess was part of a public quest). I could usually just stand there and whack stuff to death by hitting "2" on my keyboard over and over.

I completed the quest by killing the raiders. Yay for me. Got my XP and kept looking for more quests. Rinse and repeat. One nice thing is that the quest givers aren't all concentrated in a single area, and instead they sort of "follow" you as you move through the zone. This may not hold true at higher levels, but at low levels anyway you actually have a good sense that you're progressing geographically as you play.

There are a couple of slightly different quests as you move along - one where you shoot stuff with a cannon, one where you talk to people and convince them to join the war effort. But it's all basically the same stuff.

At level 3 or 4, I got another melee ability, which was some sort of debuff. I couldn't really tell that it did much, but hey, it was another button to push. So then combat switched over to nuke, debuff, spam damage ability.

At this point I was starting to become a little bored of the whole thing, so I decided to mix it up a bit by doing some RvR. This is supposed to be the "deal" with WAR - people of any level can hop in and contribute in battleground scenarios or open world PvP. If you're a lowbie, like me, your effective level is increased in RvR areas, so you aren't totally useless (as would be the case with WoW).

The first tier human "scenario" (the WAR equivalent of WoW battlegrounds) is a pretty straightforward zone control game. It plays out a lot like EotS or AB in WoW - people run around and zerg stuff. I believe it only had 3 control points though, which is helpful, as I never really liked how thinly you were spread in the WoW maps.

Here I get to learn how the WP works in PvP. My nuke is useless, so I'm thinking healing should be my primary tactic - but mana is used up quickly, and has to be replenished through melee. So typically what I'd do is sit back in healbot mode until I ran out of mana, then jump in with my hammer and get to town.

My heals were useful but not really impressive - not sure if this gets better over time, or if that's just "how it is" with healing in WAR. I could get off several before having to go in and hit people. This is when things got rough.

My melee felt really weak, so the only time I'd engage in melee combat was to restore my mana. It seemed like a sort of last ditch thing - OK, out of mana, time to go run in and die. I could actually survive a pretty substantial beating by self healing, but what would happen is I would run up, melee, get enough mana to heal, but be hurt enough that I'd have to use that mana on myself. And my damage output was so low I was basically treading water.

I guess this tactic is good as a distraction, but not much more. I'm soaking up damage, but not really dishing it out, and I can't really heal any of my allies since I need to focus entirely in keeping myself alive.

So I did this a few times, and leveled up. That's nice - you earn both realm rank and normal XP during the course of RvR, so you can largely avoid PvE (though PvE leveling does seem substantially faster). Not so nice is that, about 50% of the time, my system would lock up in RvR.

Anyway, bored with the WP and tired of the lockups, I put the game down for a while. On Sunday I updated my drivers and started anew with a High Elf Shadow Warrior, which is, basically, a Ranger.

I used the female model again, and the elf models didn't seem noticeably better than the Empire models. But they do have a tiara. That's kinda cool I guess.

Elf starting area is basically the same. Kill some foozles, level up, move on. I found playing the Shadow Warrior to be much preferable to playing the WP, as I killed things far more quickly and had a wider range of useful abilities. I started with a long cast time high damage shot, and quickly added a DoT shot and a debuff shot. They all seemed useful.

It is with this character that the game's comically bad pathing became apparent. Mobs would react in seemingly arbitrary fashion when you hit them at range - sometimes they would just stand there until dead, others they would run in a random direction, and sometimes they would actually run towards you and attempt to melee. Probably only about 50% of the time did mobs do what I would consider the "right" thing, the rest of the time they seemed to spazz out at least partially. This plays to the advantage of the Shadow Warrior.

Around level 5 I hit a quest that sent me to the elf scenario. I didn't recall seeing an equivalent quest in the Empire area, but it is possible that I'd just missed it. I went in, didn't crash (for a change!), and had a good time. The elf scenario is also a zone control map, but with a twist - there's a "nuclear option" which can trigger the death of everybody around the control points. This can really help reset things if one side ends up dominating.

I found that having a good ranged ability was incredibly useful in this setting. The DoT shot doesn't do a TON of damage, but it's easy to hit a lot of people with it and run away, so you can actually do good damage with minimal risk. The long range aimed shot does good solid damage and its range is good enough that you can have most classes substantially injured before they get up on you. At the worst you can snipe and then run away while letting your team's melee folks get up in the fray. I really enjoyed this playstyle, and consistently found myself near the top of damage done with very few deaths, despite being a lower level.

Oh, this is also where I first encountered Dark Elves. Apparently the DE females' defining characteristic is "not wearing any clothing," which is a practice I normally approve of. However, the models and their animations looked really odd to me, and there's something really strange about being gang banged by a bunch of goth vampire chicks in their underwear. I have conflicting feelings about this.

So, the big questions - is it any good? How does it compare to WoW? As a whole, WoW and WAR are strikingly and disappointingly similar. Combat plays out about the same, minus a few twists, and the basic PvE questing model seems identical (though WAR does have you sort of progress "through" a zone without as much backtracking, instead of the sort of hub-and-spoke thing WoW does). WAR's PvE has a lot of issues, though - the dreadfully slow combat and the pathing issues are clear even at lower levels.

WoW's art direction, animation, modeling, and just general visual quality are all very much better, despite using an older engine with seemingly lower poly counts. I've heard that the capital cities are impressive, but I didn't make it that far and can't comment. I don't know how WAR manages to do so poorly here, but it does. I guess they just don't care.

Where WAR differentiates itself, though, is as an RvR game. Unlike WoW, where PvP is *never* the primary focus, with WAR you can completely avoid the PvE game if you so desire (and I do desire). This alone is what makes WAR appealing to me, despite its weaknesses. I think Mythic has really missed the mark with their painfully slow WoW-esque combat, but their focus on RvR outweighs this for me (at least enough that I'll be giving the game a shot after release).

In short - will play. Great if you're burned out on WoW and want something similar. Probably not so great if you want something new and different.

Continuing my practice of playing the best games from a year ago, I recently picked up Bioshock on steam for $15.

Having recently defeated Mass Effect on normal and having been horribly disappointed with the difficulty level, I set the slider to "hard" and got going. The opening sequence is completely chaotic - your plane crashes in the middle of the Atlantic ocean, your character swims to the surface, and suddenly you're placed in control. There's only one thing you can do, of course, and that's to swim to the light house and go inside.

Light house? What the hell?

So, you go inside, and discover the marvelous dystopia that is Rapture, a decaying steampunk-style underwater city, founded by a man wishing to create a society free from government regulation where the only law is capitalism.

In this environment, Rapture's scientists were able to further genetic research to the point where they could rewrite a human's genetic structure on the fly. Aided by a material known as ADAM, they were even able to unlock psychic potential in humans, granting them superhuman abilities such as telekenisis or the ability to shoot lightning from their fingertips.

But something went wrong. Really wrong. While most of the remaining population of Rapture has acquired superhuman abilities through the use of ADAM, mentally they've effectively devolved - no longer "normal" humans, they've spliced their genes to the point that they've gone mad.

Of course, at first, you don't know any of this. Everything is revealed slowly, through the environment - signs with slogans on them, posters, audio recordings left behind. Nothing is laid out for you in an intro movie or a cut scene. All you know is that you're in an underwater city, and you've got to fight off a bunch of freaks to survive. You (seemingly inexplicably, though this is explained later) shoot yourself up with a genetic modification, and take off to save the day (or at least save your own ass).

For a large portion of the game, your directives come from a mysterious person known as "Atlas," who communicates with you via radio - giving you instructions and a bit of useful information here and there. Atlas wants you to kill Andrew Ryan (an anagram for Ayn Rand - get it?), the founder of Rapture, whom he blames for its current state of decay.

The storytelling mechanism worked really well on me. Your character has a... complex... back story that even he is not aware of, and you (and he) only learn of it by exploring Rapture and collecting clues. The game never comes out and tells you who you are, but over time it does become clear - this is not your first time in Rapture. You relive the past as you discover the effects of it in the decay surrounding you. And, while the main story arc of the game is really quite linear, it doesn't usually *feel* that way given the way you can uncover bits and pieces of the past outside of the main plot.

Combat in Bioshock has a large emphasis on ammo conservation. You have "plasmids" (telepathic powers) and traditional weapons. You start off with only two plasmid slots, but have the ability to upgrade them later (to 6 or 8, I believe), and you acquire weapons over time (up to 6 or 7). Plasmids use up EVE, weapons use up ammo, and neither is exactly overabundant - no weapon is ever completely obsoleted in Bioshock, even though you get more powerful weapons as you progress, because ammo is sparse enough that you'll almost surely need the lowly pistol (or the surprisingly effective wrench) even late in the game. Each weapon (except the wrench) also has multiple ammo types, which are more effective against different sorts of enemies.

There are a couple of character advancement options, as well. Along with the active use "plasmids," there are passive effect "gene tonics" that confer bonuses to various abilities. For example, there are bonuses to fire damage, bonuses to hacking ability, bonuses to run speed, and the like. These can be adjusted later - as with plasmids, there is a limited number of slots that can be upgraded over time by spending ADAM.

Oh, and speaking of ADAM, it's vitally important to character improvement and there's really only one way to get it - from entities known as "little sisters." ADAM is incredibly valuable, and hard to reproduce - so valuable, in fact, that as violence broke out in Rapture scientists devised a method to harvest the substance from the dead. The "little sisters" are former orphans, genetically conditioned and brainwashed to harvest ADAM from the dead. They're not alone, though - they're protected by "boss" type creatures known as "Big Daddies."

To get the ADAM, you have to kill the Big Daddies, and then you can leach it out of the little sisters - either getting a small amount by opting to "cure" them, or getting a larger amount by "harvesting" them (resulting in their death).

There are also all sorts of ways in which you can interact with the environment, most notably in hacking security systems and other machines. You can make the security turrets work for you.

Really, though, it all comes back to the storytelling. I liked the combat, for sure, and I loved the setting, but the clear win for Bioshock is the way the story is revealed through the environment. The story itself is OK - pretty convoluted, with quite a few plot holes and cliches, but certainly not bad by video game standards. But the masterful way it's revealed completely overshadows its shortcomings, to the point that I managed to completely overlook them until I'd finished the game.

As I see it, Bioshock essentially has 3 "acts." The first "act" culminates in a meeting with Atlas that goes horribly wrong, and the second leads to the climactic confrontation with Andrew Ryan and the revelation of your character's true nature. The third "act" is your character's response to this revelation, and his final attempt to gain his freedom.

Acts I and II are marvelous. There are some clever plot twists, especially leading up to the end of act II, which I honestly didn't even see coming. The third act is the weakest of the three, as all of the big mysteries are resolved by the end of act II and all that's left is the cleanup, but it's still quite solid.

Now, a point of much contention - the ending cinematics. I hope it's not too much of a spoiler when I tell you that there are 2 endings, one in which your character is "good" and another in which he's "evil." It's clearly black and white, and the only determining factor is whether you've harvested the little sisters (even harvesting ONE of them gives you the "bad" ending). I feel like this is a complete copout, and a really big disappointment - I think I would've been happier without any sort of ending at all.

But really, this is only a minor gripe. The styling, gameplay, storytelling... it's all just so top notch, I can't help but love this game. I'll go ahead and call it the best FPS I've ever played, and one of the best single player games I've played, period.

Hell, it's almost as good as Portal.

You should be using RSS.

I started using an RSS aggregator in earnest once Google Reader showed up. I'd used other RSS readers before that, but they were all clunky, slow, annoying... well, they all sucked. Liferea and Thunderbird were "OK," but not OK enough for me to completely drink the RSS kool-aid.

Some RSS readers are stupid. They set off alerts or bells or stuff popping up on your screen. They're useless.

Google Reader, on the other hand, basically redefines how you access the web - it essentially takes everything you tell it to and puts it in ONE place. It can handle dozens, hundreds of feeds. You can put every site you ever check in there. And then, when you feel like it, you can see what's been added and read it without leaving the reader UI. No flash ads, no javascript, no navigation menus, no extra sidebar crap - just the post content. It doesn't shout at you. It doesn't yell at you. It just sits there, collecting interwebs for you.

Google reader is a hosted web application, accessible via any modern browser with javascript enabled. This makes life as an end user really simple - you don't have to maintain your feed list on multiple clients. Your clients don't have to do all the work of aggregation themselves (which, when you have a few dozen feeds checking every 10 minutes, starts to become an issue). You can access it from any system with a modern browser.

Google reader is more than that, though - it's also got the best UI of any aggregator I've seen.

By default, reader will only display items that are non-empty - so feeds that have no unread items just get out of your way. This sounds pretty basic, but in practice it works really well. There's no UI penalty for adding a site that's updated every 3 months - most of the time, it's not in the UI at all, but when it *is* updated, you'll know it.

Reader has categories. You can dump all of your friends' weblogs into a "friends" category, and instead of accessing each feed individually you can access them all simply by selecting that category.

Once you select a category or a feed, all of its unread items (by default) show up in their entirety in the right hand pane. You can navigate through these items by vi keybindings, which works REALLY well - so even though a long item consumes the entire pane, you can skip it very quickly just by hitting "j". I was skeptical of this method at first, but it actually works much better than a traditional "list" view (which reader also supports).

The downside to google reader? Well, google now knows almost *everything* about your web usage, even more than they could have gleaned by their existing tracking mechanisms.

It's about 1 p.m. At the beach. And I'm in the water.

--

Annie and I had driven in the night before. The dog rode in the back of the car, walled off from us by her collapsed crate which sat vertically on the floor, wedged against the back of our seats. She hates the car, but at least this time she didn't throw up. Not for lack of trying, though - I guess it helped that we didn't feed her first.

We'd gotten a late start. It was my fault, of course, it always is - I had been running around, cramming cables and batteries and other crap into my laptop bag. Triple checking the door locks. Making sure to leave lights on - only the compact fluorescents, since the incandescents wasted so much energy - but not too many. There's a balance to meet, somewhere, between making the house look occupied and making the house look like somebody was trying to make the house look occupied. This is more art than science.

--

I bob on top of the waves, occasionally floating on my back, sometimes doing some actual swimming. I'm a shitty swimmer, though - this is about the only swimming I ever do. The buoyancy of the salt water is an enormous help, and even I can easily stay afloat despite the waves. Still, I should have used the asthma medicine before coming out.

--

I had known this would be a difficult trip, and I'd been steeling myself as we drove through the nameless backwater between Raleigh and the coast. No, this was not going to be a happy family get together - it would be brutal, stressful, dominated with concern for my 85 year old grandfather, whose health had been in sharp decline for the past year. I've only known my grandfather to exist in a permanent state of gradual decline - he had reached his physical and mental prime before I was even born. By the time I had become old enough actually appreciate him for who he was, he was already starting to slowly disappear.

But this trip would be something different - this past year had been even worse. The man he was - the man I had never fully known - had been slipping away at an ever increasing pace. We knew this was inevitable, but none of us were ready. It shouldn't have been happening yet. And yet, it was.

When we had arrived at the house, around 9:30 p.m., my grandfather was already asleep. We checked in with my parents and my sister and went on down to bed.

--

The waves are a bit choppy. I guess the tide is going out - it sure feels that way. There aren't many people in the water, due to the rough ocean. I can see a guy on a boogie board to the east, I can see 3 kids playing up near the shore to the west. The kids seem to be having a good time, yelling at each other, splashing water at each other. Most people are just relaxing on the sand.

--

We took the dogs for a walk shortly after we woke up this morning. Dahlia seemed to be afraid of the ocean, and there was nothing we could do to coax her in. I suppose you can't blame her for that - there's definitely something ominous about the endless wall of water, reaching to the horizon, with waves rolling in and crashing down upon you. Besides, why risk it? There was so much biomass washed up on the shore, she was in dog heaven already.

There was some kind of military vessel in the water. I kept trying to figure out what it was, staring at it through the cheap binoculars I'd gotten for free with a Leatherman pocket knife, looking up naval vessels on my phone. I finally decided it was a Ticonderoga.

When we got back to the house, my grandfather was up. He had his cane, but he couldn't really move on his own; somebody had to help him every step of the way. I think he remembered who I was, despite not knowing my name - but as for Annie, he might as well have never even met her.

It pained me to see him like this, his physical state ranging from convalescent to incapacitated, his mood fluctuating between despair and obliviousness, his mental faculties between vague comprehension and complete disorientation. And as hard as this was on me and my sister, I knew it had to be much worse on my mother and her brother. Their entire lives had been anchored by this man's presence. The last year had changed the equation - he was no longer their father, but their dependent.

Looking at him, I thought this would probably be his last beach trip. It was a depressing thought, and it got me thinking about 30 years from now, when my parents would be in this spot, and then 30 years from that, when I might be too. Is that the best we can hope to do? Is this the reward for surviving to old age? Being forced to sit around, waiting for death, as it steals a little piece of you every day?

--

Somebody is shouting something. I know what they're shouting, but my brain rejects the possibility. This is not something that can happen. Not to me. This doesn't happen. I'm sure I didn't really hear that.

I look to the shore to the west. I see two kids.

I hear the sound again. I can't deny what it is any more - there's no way any reasonable person could. I turn my head to the southwest, out towards the open ocean. I see the third kid.

Fuck.

He's out there. Way the fuck out there. How the fuck did he get out there? His scream for help is the most desperate thing I've ever heard, the most panicked sound I can imagine. This is a 7 year old kid, and he thinks he's going to fucking die.

I have maybe half a second of rational thought before my brain shuts off. I know the tide's going out. I know the current is strong out there. I don't think I can beat it, not with a kid on me, not without albuterol...

And then, like that, the thinking stops.

Right arm forward, kick kick kick, left arm forward, kick kick kick.

The kid gets closer. I don't know how. I don't know how far I've gone, I don't even remember deciding to move. The adrenaline keeps me pushing, swimming as hard as I can with the current, moving further and further away from the world.

Here he is. He looks fucking terrified, but he's staying afloat, his little head bobbing above the swells.

"Are you OK?" I ask, panting.

"Yeah," he says.

"Grab on," I say.

He grabs my left forearm. I can't think of any way to do a front crawl with a kid holding onto me, so I guess that's as good a place to grab as any.

"Let's go," I say.

I can feel it now, the current, dragging us away from safety. Is this a rip tide? How the hell should I know? There aren't any giant arrows in the water telling me where the current is or where to swim to escape it. Do I swim at a 90 degree angle? Do I just try to move towards the shore?

Fuck it.

I swim towards the shore, using my free limbs in some kind of bastard dog paddle. I'm fighting the current. I'm out of breath. The kid hangs on admirably. I'm making progress. Maybe we'll make it.

We're getting closer, but I'm getting weaker. I'd burned so much energy getting out there, I've left nothing to get myself back. The adrenaline is wearing off - I start thinking again, thinking dark thoughts. I feel the drag of the current against me, now almost freezing me in place. I'm no longer moving. I think I'm going to fucking die. I think we're both going to fucking die. I've never felt so alone.

The kid keeps hanging on.

Why is nobody moving? Why aren't they helping? I can see the tent on the shore where my family is, but they're not moving. They're not coming to save me. I'm on my own. Me and the kid. Nobody is coming. I'm going to fucking die.

"Sweetie?" There's a woman here. I don't know where she came from. I didn't see her until now.

"Are you OK sweetie?" She's not talking to me. She's talking to the kid. Her kid.

"Mom, I'm scared," the kid says.

"It's OK sweetie, I'm here."

She's got a life jacket. She has a fucking life jacket.

I hand the kid off. They float on the jacket. I float on my own.

I'm still panicking. Even without the kid, my progress is abysmal. Their progress is equally slow, but with the life jacket they have more time to spare. I can stay afloat due to the buoyancy of the salt water, but I feel my energy draining. I try to see if I can touch the bottom yet - I can't.

Now somebody is moving on the beach. Somebody thinks something is wrong.

I look behind me. A wave - a big wave. Finally - I can feel it transfer some of its collasal momentum to me. "Fuck, come on waves," I find myself saying. I briefly regret using profanity around the kid, but all things considered I doubt the mom will hold it against me.

The waves roll in. I can see that the guy moving towards the beach now is my dad, but I don't need him any more. I can feel my rubbery legs touch the uneven sand underneath the surf.

I stagger onto the shore. I know the sand under my feet is burning hot. I don't feel it.

"Are you all right buddy?" My dad meets me as I walk up.

"Yeah" I say.

I make my way to the tent, where everybody else is sitting. I sit down on one of those flimsy $5 beach chairs that you expect to collapse at any minute. Cheap shit. Why even bother.

"Is everything OK? You look a little tired," somebody asks.

"Yeah," I say. "Can somebody pass me a beer?"

I'm a big fan of using the "right tool for the job," so it's with a little reluctance that I confess to my latest technological sin - using Rails to create a largely static "web 1.0" style web site. I know, I'm totally square and not hip at all.

It's a common scenario - you have a few "base" pages that are modified infrequently. Things like "about this site" or "history" or what have you - things that you might manage with a CMS of some sort. The data on these pages needs to be somewhat free-form, since they're all effectively "one offs," but they also need to share the same general page layout, menus, other stylistic elements.

Realistically, server side includes can meet this niche reasonably well. But if and when the content does need to change (or pages need to be removed or added), you're faced with editing flat files on the server which can be cumbersome for minor edits (especially if the system is designed to allow edits from novice users). You also are limited to static html, which is problematic if you want your menus or status text to change based on the state of your application or its content.

Anyway, long story short, I decided that creating a simple Rails resource for this purpose wasn't a bad idea. Even though rails was designed for more complex applications, it's quite capable of doing simple tasks like this, and in some ways I found it faster to work with than flat files. You also gain the ability to use ruby statements within your layouts, and you can use hpricot or another processor to tidy up possibly mis-entered HTML before it hits the browser.

Now, there are some considerations.

Firstly, do you use a real resource, or do you rely on view fallthrough with no actions defined in the controller? You can completely eschew typical MVC methods and just create views that match the names of your pages, with the net result being your content is all stored in flat html.erb view files. This has some advantages - namely, you can use ruby directly within the page content - but I ultimately decided to use a full MVC, RESTful resource instead, with each page being an instance of a "page" model with its content and metadata stored in the database. The primary advantage of this method is that you can edit and create new pages directly from the browser.

Next, I had to decide whether to manually map routes or to rely on map.resources. I struggled a bit with this decision - there are some advantages to manually mapping each page, either at the apache level or with routes.rb. The RESTful URL scheme is not entirely suited for these sorts of pages - you end up with an extra level in the namespace for the controller (foo.com/controller/ID) if you rely on map.resources, whereas you can map pages directly off of the root if you go for manual routes. In the end I stuck with map.resources, but this is a question that demands real consideration.

You also have to decide if you want to use the typical rails convention of "look up by primary key," which I feel is especially poor for this endeavor. I fixed this by modifying "to_param" in my model to refer to a different field (such as "shortname") and modified my controller's find statements to search accordingly. This allows you to set or change the URL when creating or modifying pages, so you have "pretty" URLs like foo.com/pages/home instead of foo.com/pages/2.

In the end, I'm OK with the results. I can see this as being more of a win for a site that's already planning to use RoR for some heavier lifting and wants to unify everything on that platform - I don't think it makes the most sense when (as I've done) creating a rails app specifically for this purpose. It's honestly not bad, even so - the spool up time with rails was not really that much worse than using apache SSI, and the flexibility gained from it is potentially nice.

I made a little site for wedding related things. Annie chose the color scheme based on a flower we saw in Asheville.

I also finally upgraded to gallery2, and I hacked up the css to kinda match the color scheme, but I'm aware that it's a bit wonky.

I know I'm late to the party, but I picked up the Orange Box for $30 last month and tore through Portal in one sitting. What a great game.

Portal's gameplay is pretty straightforward: you're given a gun that can create two portals which allow you to traverse sections of rooms. It's a concept so simple, in fact, that it's hard to envision an entire game built around it, which is precisely why I find Portal so impressive. Despite its simplicity, I never felt bored, and the puzzles continued to surprise me all the way to the end.

The quirky running monologue from the AI character and the brilliant end credits really round out the game, too. It's easy to imagine these details being neglected, but the game is much richer for their presence and quality. Would people still talk so much about Portal had they not discovered that the cake was a lie? I doubt it.

For what it's worth, I've barely touched the rest of Orange Box. Don't let the short length - about 4 hours total - fool you: Portal alone is worth the cost of the Orange Box, and it's the best game I've played in the last few years. HL2 and TF2 are just neat little bonuses.