June 2007 Blog Posts

The Documentation Missing Link

I've been working on several different projects where I'm learning new stuff from scratch.  For example, I'm trying to write my own Subtext skin for my blog.  And as I read the documentation (or attend the meeting, or watch the presentation, etc.) that was created to convey the information to me, I realize that the creator of the material has always omitted the one thing that would suddenly allow the concept to click:

Context.

Picking on the Subtext skinning (since it's fresh in my mind): It might be super important to tell me which lines in file XYZ need to be changed to show me how to make it do something interesting, but if you don't tell me what file XYZ is and what its purpose is, the only thing I'm going to learn is that if you do this specific change, you'll get this specific result.  I don't have any context for why you made that change, so I can't really infer any other changes that I could potentially make.  All I learned was the example.

I had a friend who would explain game rules this way.  If she was trying to explain, say, Monopoly, rather than starting out with explaining how the pieces move or what the object of the game is, she'd start out right in the middle with something like how you get sent to jail and how you get out, or what happens to you if you roll doubles.  If you already know how to play and need a refresher, that's one thing, but for the new person you're trying to explain the game to, you're forgetting to provide context.

I see this happen a lot with folks who work on projects for a long time.  When it's time to demo the end result of the project, they jump right in at the middle, forgetting to explain the overall value of the project, why the audience should care, or what the audience is about to see.  The problem there is that the audience will more than likely just nod their heads and tell you that they understand when the truth is they don't.  Why didn't they get it?  No context.

So here's my public request to anyone trying to convey any information to anyone anywhere - provide context.  Your audience will thank you.

GTA4 Special Edition Contents

IGN has posted some great pictures revealing the contents of the Grand Theft Auto IV special edition.  I pre-ordered my copy.  Did you?
Soundtrack CD, lockbox, duffel bag, game, and book.

Gizmocafe - Xbox 360 and Media Center

I haven't gotten a chance to put my media center together yet, but I got a comment that points to a pretty decent article about using the Xbox 360 as a media center extender.  It may be easier than I thought.  Looks like the .VOB files you rip from DVDs are actually renamed .MPG files, which can be directly streamed.  I may have to try this out.

It would be easy enough to have the DVD backups on a drive and a virtual filesystem of symbolic links to all of the VOB files that have renamed targets (so "Cool Movie.mpg" would point to "Cool Movie/VIDEO_TS/VTS_01_1.VOB" and mask the whole rename issue).  Wouldnt' be hard to write a program that generates that filesystem.  I'll have to try it.

UPDATE: There seem to be two problems with the way Gizmocafe does things.  First, it's not really a proper DVD backup solution - it only works if your sole goal is streaming the movie.  Half of the reason I'm doing this is as a backup solution.  Second, you may have a little bit of fudging to do in the DVD ripping software to get movies with multiple VOB files to work.  For example, the movie Borat seems to have three separate VOB files - those would have to be connected to so they could stream in one continuous movie.  The Gizmocafe tutorial doesn't really address that.

Solution To The Guitar Hero Loose Whammy Bar Problem

O-rings around the base of the whammy barProblem: You have a Guitar Hero II X-Plorer controller for Xbox 360 and the whammy bar is loose. You want the whammy bar to tighten up without having to take apart your guitar and you don't want to go through the exchange process with RedOctane.

Solution: Get four (4) size AS568A-008 (3/16" inside diameter) neoprene o-rings. Slowly push each one over the end of the whammy bar (the neoprene will stretch, but take your time with it because you don't want to break the ring) and down to the base of the whammy bar as tight as you can. Four rings will cover the entire base of the whammy bar up until the bend. When they're on, it'll look like the picture.

The o-rings will generate just enough friction to make it so the whammy bar moves easily but will stay in place when you let go, leaving it in easy grasp for the next time you need it. Putting multiple rings on will keep the bottom one from slipping away from the guitar body and losing friction. Getting them to the bend in the whammy bar makes it just that much more secure because it'll take more effort for the rings to round the bend and come loose.

Too Much Detail: I tried several ring sizes and materials to get here. Size 8 is just big enough to barely go over the whammy bar end and still fit snugly around the bar proper. Neoprene is the right material because other materials either don't stretch quite enough or don't offer enough friction. For example, I bought some rings from the Home Depot plumbing section that had an "oily" or "slick" feel to them because they were probably Buna-N and treated for resistance to oils and liquids. (I blogged about how I was learning too much about o-rings.)

Where To Buy: I bought my o-rings at McMaster-Carr. In the search box on their site, put "AS568A" and it'll get you to the o-ring page. From there, select the "AS568A Dash Number" as "8" to get the ring size set. Finally, select "Neoprene" as the material. As of this writing, they only carry one product that matches those criteria. It's a bag of 100 o-rings that costs $2.48 (no, you can't get a smaller pack or buy individual rings - they're an industrial supply store, not a consumer goods shop). Shipping was about $5 via UPS ground for me.

We tried this out last night in a feverish game of GH2 and it works pretty well. The rings never had to be pushed down or adjusted, it just worked. A sub-$10 solution and not having to actually open up the guitar? Can't ask for much more than that.

UPDATE: While I'm happy to help folks out, I'm not in the o-ring business.  If you want some o-rings, head over to McMaster-Carr and pick some up.

posted @ Friday, June 22, 2007 8:26 AM | Feedback (6) | Filed Under [ Gaming ]

On A Mission For Nathan's Famous

Nathan's Famous Beef FranksI subscribe to Consumer Reports and yesterday they sent out a review of hot dogs so folks would know the best kind of dog based on flavor, cost, and... uh... "health content" in preparation for summer BBQs.

Hebrew National was rated the best, with Nathan's Famous coming in a close second.  Now, I've had both, and while I like both, there's just something about a good Nathan's Famous dog that I can't get over.  It's sort of like how Krispy Kreme donuts are just... better.

Anyway, that put me in a pregnancy-style craving for hot dogs.  Nathan's Famous hot dogs, to be specific.

After work, Jenn and I went on a mission.  A mission for Nathan's Famous.  Unfortunately, there are no Nathan's Famous restaurants in Oregon, so we had to search out the version you buy at the store (which is also excellent, but doesn't offer quite the atmosphere of the actual shop).

Costco - no luck.  I could have sworn I saw them there at one point, but not today.  Fred Meyer... aha!  There they are, sort of unobtrusive in the refrigerator case.  Come to me, sweet dogs.

Fired up the grill at home, threw the dogs on, and watched the flame fizzle out after about three minutes of cooking because we were out of gas.  Not to be stopped, the franks made their way quickly into the oven to be broiled to perfection.  (I can't stand boiled hot dogs.  Seriously.  No go.)

I ate two, but I swear I could have eaten the whole package.  I'll definitely be partaking this weekend (after refilling the grill tank).

When was the last time you went on a mission for food?

System.Collections.ObjectModel.KeyedCollection<T> CodeSmith Template

I've been converting a .NET 1.1 project over to .NET 2.0 and there are a lot of strongly-typed collections in the project that were generated by CodeSmith.  Most of these collections were based on the ArrayList template that came bundled with CodeSmith and all of them used the "GetByKey" facility the generator offered.

I'm trying to reduce the codebase and take advantage of generics where possible to get rid of things like this.  To that end, I've been converting most of these over to System.Collections.ObjectModel.KeyedCollection<T> (which also jives nicely with FxCop - the generated collections came bundled with several items that set FxCop off).

Ironically, that means I end up generating a very small amount of code (and corresponding XML documentation) for each of these collections - a class derived from KeyedCollection with the appropriate constructor overloads and the override for the GetKeyForItem method.  So I made a - wait for it - CodeSmith template to do exactly that.

If you're a CodeSmith user and you find yourself creating a lot of simple KeyedCollection implementations, grab the template and go to it.

Preordered Grand Theft Auto IV - Special Edition

Grand Theft Auto IV - Special EditionI gave in and hit the local GameStop during lunch today and pre-ordered my copy of Grand Theft Auto IV - Special Edition.

This version comes with (from the GameStop site)...

  • Grand Theft Auto IV the game with special packaging (a lock box).
  • The Sounds of Grand Theft Auto IV: A selection of our favorite music from the soundtrack of GTA IV. This album will only be available within the Special Edition package and will feature original tracks from some of today's hottest artists.
  • The Grand Theft Auto IV and Rockstar Games Art Book: This will be the 1st ever GTA art book to be published by Rockstar Games and will feature exclusive art unreleased anywhere else.
  • A Limited edition Grand Theft Auto IV/Rockstar Games bag which has been designed especially for this Special Edition
  • An exclusive Rockstar Games keychain to hold your lock box keys.

Yeah, I'm crazy, and yeah, it did cost me $90... $30 more than the game alone.  But I'm a GTA junkie, and they make this crap targeting me personally.  I can't say no.  I'm just as bad as the Halo junkies who will be paying megabucks for the version of Halo 3 with the mini replica helmet.

The thing is scheduled to ship on October 16.  If they could guarantee it would be in my hands on that day, I'd schedule my PTO right now.

posted @ Tuesday, June 19, 2007 12:34 PM | Feedback (1) | Filed Under [ Gaming ]

Removed Comments Email Address

The "comments" email address I had was pretty much just a spam magnet, so I've killed it.  If you need to get in touch with me, use the contact form on the blog, or send me an email directly (if you have my email address already).  Sorry for the inconvenience this may cause folks who, for some reason, had my actual email address down as "comments."

CR_Documentor - Maybe .NET 2.0/VS 2005 Only

I've been really struggling with the motivation to get CR_Documentor updated for Sandcastle support.  The problem is threefold:

  1. .NET 1.1 XSLT performance is pretty slow (slow enough that it's noticeable when the preview refreshes) so the code actually manually recurses through an XML document object and generates HTML on the fly.  Every time either rendering engine changes the way they do things (or fixes a defect), I have to manually implement that transformation in code using XmlNode and XmlDocument objects.  I can't just take the changes to the XSLT that the products include.
  2. Since I'm working at pre-compilation time, generating the method signature in a nice formatted way is a huge pain, and it's different for each rendering engine.  Doing this involves manually running around the parsed code tree in DXCore and converting the parsed nodes into nicely formatted, human readable HTML.
  3. CR_Documentor was originally a one-trick pony, so the rendering mechanism isn't really... "pluggable."  I started refactoring to get there, but because the generation of the HTML is so specific to each renderer and there's so much to it... frankly, I've gotten overwhelmed.

As I've said before, I can't open source the thing and get help because there are legal ramifications around it involving Lutz working at Microsoft now and the code originally being his.  I'd love to get some help on it, but it's not really a possibility.

Anyway, I started down the path of getting Sandcastle support in there and it's become pretty beastly.  What I'd like to do is actually make use of XSLT so I can vastly simplify the rendering for each preview type.  It would also allow me to more easily directly take the XSLT from the various products (NDoc, Sandcastle) and use them with very minor, if any, modifications.  Making it easier to take advantage of that would also make it easier for me to add new preview styles (Sandcastle, for example, has multiple templates available).

.NET 2.0 has vastly better XSLT performance than .NET 1.1 - enough that I think it'd be feasible to transform using XSLT rather than manual document manipulation.  However, if I convert to .NET 2.0, I have a few problems:

  1. I'll only be able to support Visual Studio 2005 and later.  (I'm pretty sure DXCore won't let me run .NET 2.0 plugins from inside VS 2003, though admittedly I haven't tried it.)
  2. I will probably have to remove features like the ability to highlight "unsupported tags" or set a "supported tag set" for troubleshooting your documentation.  I'll still be able to notify you of errors (like if your doc doesn't parse out right) but the supported tag set thing was only really workable because I had programmatic control over the rendering at that level.

Does anyone care?  Any big voices to continue supporting VS 2003?  If not, I'm going to scrap the garbage I've been trying to do to get this done and start working on getting it to transform using XSLT.

Learning Too Much About O-Rings

In our fervent Guitar Hero II playing, Jenn's whammy bar has gotten slightly loose.  (Yeah, that sounds dirty.)

Anyway, I thought that one way to fix it would be to get one or two tiny o-rings, put them around the whammy bar, and push them down as far as they'd go to create friction between the whammy bar and the guitar.  Hey, it's worth a shot.  (I've also contacted RedOctane to see if they have some suggestions.)

So I headed over to the local Home Depot and noticed they had like 20 different sizes of o-ring.  I made a guess at the size I needed and picked up a pack of 10 rings (you can't just buy one, and a pack only costs like $2).

I guessed wrong.  They were too small.

I went back later that day and got the next size up.  Too big.

So I went online this morning and started looking at o-rings.  First, I had no idea that there is a whole size scale for o-rings called "AS568A."  There are standard number codes that represent the possible sizes you can get.

Then, when you want to buy o-rings online, you can't really just search for "o-rings" - you need to search for "industrial supply."  Turns out most industrial supply places won't sell to consumers, and many that do offer you the awesome shipping options of "same day" or "next day," which, for a $2 pack of o-rings, costs about $20.  Oh, and buying o-rings at an industrial supply company still only costs around $2 - $3/pack, but there are 100 in a pack, not just 10.

I ended up getting two sizes of ring from McMaster-Carr, one of which, I'm sure, should fit.  And shipping was fairly reasonable at $4.50 for the two packs of rings.  Hopefully this will fix the whammy bar issue, but I can tell you right now I've learned far too much about o-rings.

Subtext Migration Complete!

SubtextI just finished converting over to Subtext, and, all things considered, it went reasonably well.

A lot of work went into the migration, though - a lot more than I really feel should have.  But at least I'm moved over.

What I ended up having to do:

  • Get a SQL 2005 database (pMachine was stored in MySQL).
  • Write a BlogML export utility for pMachine (which I will be contributing to the BlogML project).
  • Write a utility that creates a map of old IDs for my blog posts to new Subtext friendly URLs.
  • Write a converter that takes the ID map and generates a redirection utility in PHP to replace the old blog pages (so they'll get you to the new blog).
  • Write a utility that goes through the BlogML export and updates all URLs to the new Subtext URLs so the blog proper doesn't actually rely on the redirection mechanism for cross-post links and images.
  • Write a utility that goes through the BlogML export and updates all the comment text because there's a weird issue with Subtext BlogML import that converts all newlines to line break tags... and then encodes any line break tags you already have so they end up being visible.  Not pretty.
  • Manually break the BlogML export into three pieces - the request times out if you try to upload a 5MB BlogML file.
  • Install and configure Subtext.
  • Import all of the BlogML pieces.
  • Swap out all of the old pMachine pages with my redirection utility.
  • Update my old RSS feed so folks know they need to get the RSS through Feedburner.
  • Little fine-tuning things.  The BlogML import doesn't populate the author name or email in the Subtext database so I'm going to have to do some work there.  The Subtext configuration proper is easy, but you have to set things up (like your Feedburner name and stuff).

So I'm pretty much converted, which is super cool, as far as I'm concerned.  Things I want to do now that I've got myself moved over:

  • Category cleanup.  I've got a pretty crappy category breakdown and it's time to clean that up.
  • Custom skin.  I picked a decent stock theme for now, but I want the site to be me.
  • Blogroll and links.  I didn't really export the original set of links or anything, figuring I'll add links as I see their usefulness.  I already know of a couple of blogs that I read I should add.
  • "About" section.  The old "about me" section had seen better days and depended on the old pMachine code to generate its template.  I need to come up with a new section.
  • Script integration.  I want to get my little Xbox Gamercard popup thing working again, and the Amazon link script where they pop up a nice review and image of things you're interested in - that's neat.  I also want to add some other stuff, like a scrolling Twitter history deal and maybe a few other fun items.

Oh, and if anyone knows how to write a PHP page that will not only send the "Location" header but also let me change the status code, that'd be awesome.  I'm trying to do that in PHP 4-point-something-or-other so I don't have the ability to do much.  I've tried the http_redirect method and that doesn't work.  Right now I'm using header("Location: $newlocation") which is supposed to automatically throw out a 302 redirect status, but I'll be damned if I see anything other than a 200 come through when I watch in Fiddler.  The browser sees the "Location" header and displays the content from the right page in Subtext, but the URL in the browser doesn't change.

Regardless, I'm back in the saddle with a new blog package and finally feel like I'm living in the now.  Time to join up on the Subtext project and start contributing!

So Close to Subtext I Can Taste It

I've been working pretty hard on getting things ready to migrate this pMachine piece of crap blog over to Subtext:

  • I wrote a BlogML exporter for pMachine so I can get my entries out.
  • I've got an ID conversion mapping utility that runs through the BlogML and maps the old pMachine ID to the new Subtext friendly URL.
  • I've got a URL rewriting utility that takes the ID map and runs through the BlogML, finding any old links and updating them with the new URL in Subtext so cross-post links work.
  • I wrote a utility to get around a sort of crazy bug in Subtext comment import where newlines automatically get converted to line-break tags and line-break tags that already exist in the comment get encoded so they actually display.
  • I've got a converter that takes the ID mapping and converts it to a PHP array so I can use that array as part of a redirection mechanism that will take people hitting the old permalinks in pMachine format to the new Subtext location.
  • I've figured out how I'm going to handle the relocation of the images in posts and such so things should still work (pMachine has an interesting sort of macro substitution it uses for upload locations so it's not as straightforward as you might think).
All I really have left to do is a final test install/import of the data. Assuming that goes well, I should be able to do a pretty quick swap and import. I'm really looking forward to it. I already have some interesting ideas of things I'd like to do.

The Trouble With Intelligent Software

I'm working with a print program - Microsoft Publisher - on a little project at home and without going into a bunch of crap you don't care about, let it suffice to say I'm trying to get it to print full-bleed on my HP Deskjet 5940. It's just not happening.

The printer is fully capable of printing full-bleed on 8.5 x 11 paper. I've seen it work. But right now, I'm frustrated because no matter what I do, no matter what I try, there's always this half-inch border along the bottom of the page I'm trying to print.

I know what you're going to say - that you need that half inch because the printer has to have something to hang onto at the end as it prints the last bit on the page and pushes it out. I thought so, too, and since the stuff I'm printing is mostly at the bottom, I used the printer driver option to automatically rotate the thing I'm trying to print 180 degrees. Put the bottom at the top and there's no border, right? Or at least the border's reduced to that little quarter-inch bit that's always at the top?

Nope. Still getting the half inch, as though it was still printing the bottom of the page at the bottom.

After fussing with this for a half hour or so, using up probably 20 sheets of paper and more ink than it would have taken to print the whole project eight times over, I finally realized what it was:

Microsoft Publisher is trying to help.

Rather than letting the printer take care of the fact it can't print that last half inch, Publisher is actually determining the capabilities of my printer and sending the print job to the printer minus that half inch, anticipating the border the printer will require.

And there's the problem with software trying to be too smart. I'm not a big Publisher wiz by any means, but in no dialog I've seen has there been an option for "Stop trying to help me by optimizing the printer output and nuking the half inch I really wish was there." It's designed for folks who need the default options, making intelligent guesses at what needs to happen.

This is why I shy away from software that exposes only exposes the big "DO IT" button. Sometimes the big "DO IT" button is exactly what I need. Maybe even 70% of the time. The rest of the time, I need the options. If there's something you're going to automatically assume for me - especially with respect to printing when you're a printing program - I need to be able to override it. Ah, the trouble with intelligent software.

There Will Always Be Subject Matter Experts

I've started a new project where we're doing our best to get every developer familiar with all the parts of the system by moving people around a bit, XP style. The idea is that we want to break down the knowledge silos so there's not just one person who knows how each system works. I think that's a great idea. If someone wins the lottery (or gets hit by a bus), we don't want the whole project to crumble.

That said, there's a particular undertone to some of the moving that worries me: the notion that somehow we can get rid of subject matter experts and everyone will know everything about the system.

I don't think that's a realistic goal. I think it's a great idea to get folks familiar with how the various parts of the system work, but the system itself is far too big and there are too many changes going on over the course of time for anyone to keep intimate familiarity with the entire system in their head. At some point, you're going to have someone who has more knowledge about how one area of the system works than anyone else, and you're back to the knowledge silo of a subject matter expert.

The topic of skill set comes up here, too. Some people are better than others at certain tasks, be it due to education, experience, or both. Good idea: peer mentoring involving these folks. Bad idea: thinking you can make everyone on the team as proficient as experienced individual just by switching people around. Not everyone is a DBA. Not everyone is an architect. It's not realistic to expect you can swap people into those roles and hope the system comes out as coherent and high quality as if you just trusted the tasks to the folks with the relevant skill set.

From a time/savings standpoint, it also occurs to me that putting someone who is good at a task on that task will cost less and get the task done faster than if you decided to put a less familiar person on the task. And if you keep moving people around, you may never actually gain momentum - it's hard to work fast when you're trying to learn at the same time. Great experience for the developers, great knowledge distribution, not so great velocity.

There's a reason the phrase "jack of all trades, master of none" came about. It's great that folks want to be generalists, and spreading the wealth of knowledge is an admirable goal. But there will always be subject matter experts, and that's not a bad thing. Rather than try to get rid of them, I might recommend taking advantage of their expertise and doing a little peer mentoring to spread knowledge without trying to abolish the notion entirely. You'll educate your developers and be able to gain project momentum by targeting the specialized skill set to pertinent tasks, and that's a Good Thing.

Sopranos: What the Hell Was That?

I, like most of America, tuned in for The Sopranos series finale on Sunday night, stoked for a cool ending to a cool show. And, like most of America, I left with nothing.

When I say "nothing," I really mean it. The show didn't really have an ending, it just sort of "stopped." I picked up my remote control and flipped around to see if other channels were still broadcasting, pissed off thinking that I had lost my HBO signal at the last second. That's not actually what happened - that ridiculous "instant cut to black in the middle of a scene" thing they pulled... that was the ending.

To be clear, after I sat and thought about it for a while and talked to my wife about it, I got it - the whole uncertainty thing, life going on and Tony always looking over his shoulder, never knowing what's coming next. I get it.

I also get the whole "art vs. entertainment" debate. Was the show "art," where series creator David Chase just finishes up his creation and calls it done? Or was it "entertainment," where there should have been more fan service?

Does it even matter? The Sopranos was a great show, primarily driven by great characters, with an intriguing plot. This last season, which we waited a heck of a long time for, sort of jumped the shark by going entirely character driven and really just losing the whole "plot" portion. I watched week after week waiting for something to happen, and it only ever ended up being sort of the way Seinfeld described itself: A show about nothing.

Sure, we see Tony going around doing his mob thing and his family getting worried or going through trauma or whatever. But what actually happened in the last season? Aside from the last little bit where Tony's crew starts getting killed off and Phil Leotardo getting killed, nothing.

Now, I'm all for great characters and character development. They're integral parts of great storytelling. On the other hand, the word "story" is actually half of "storytelling," and you can't just lose the story part and just have character development.

The end of The Sopranos, to me, was the very definition of anticlimactic. If I had a time machine, I think I'd have to go back in time and tell myself not to watch because it'll only piss me off. Or maybe I'd have to grab David Chase and force him to call a mulligan and do it over. Much as it might be construed as art on some level, people watch for entertainment.

Noah's Nibblers

Travis Holds a Baby Goat - Click for the full albumYesterday Jenn and I went over to my parents' house because there were strange things afoot. My parents' condo association has this overgrown area they need to clear the vegetation from but they wanted to do it in an environmentally friendly way. After looking at all the options, they hired a company called Noah's Nibblers to do the work.

What they do is bring in goats - a lot of goats, like over 100 goats - and basically just cut them loose in the area that needs to be cleared. The goats eat the vegetation away, clearing the area without use of chemicals. Apparently they do a lot of work with the Army Corps of Engineers. I had no idea.

I've never seen that many goats in one place. I think my goat experience was pretty much limited to childrens' petting zoos and such. Seeing literally a herd of goats mowing their way through an area is definitely something new.

Along with the herd, they brought a baby goat with them, less than 24 hours old, that the mother had rejected. We got a chance to hold him and feed him, and it was neat to see him walk his first few steps.

Anyway, that made for a pretty interesting Saturday. I've posted some pictures in a web album for those who want to see more. I don't think the pictures really do it justice. The area they were eating down was on a hill, so it was tough to get a shot that really showed the craziness.