Never before I have felt so connected to a Penny Arcade comic. I recently picked up Professor Layton and the Curious Village, a puzzle-adventure game for the Nintendo DS. After roughly 10 hours of game play, I've completed the game, so I thought I'd post some thoughts on it. Before we get to that, however, I'd like to explain how this game works.

Professor Layton is one of those hybrid titles like Puzzle Quest. It is neither an adventure game, nor is it a puzzle game; it's somewhere right in the middle. Layton himself is a private detective of sorts who is hired to figure out a puzzling will left behind by the late Baron Reinhold. Along with his assistant Luke, Layton quickly finds himself in an ever-increasing mysterious situation. There are twists and turns all over the place, and plenty of mysteries to be solved in the process.

Each person you meet will give you clues to the ever increasing list of mysteries you encounter, but only if you solve a puzzle for them. And by puzzle, I mostly mean 'brain teaser.' The puzzle difficulties are all over the place in this game. Some puzzles are easy to solve, while others will have you banging your head against a hard surface in frustration. There's a hint system in the game that offers you three hints per puzzle, which is often enough to help you figure things out, but sometimes the hints are themselves quite cryptic. Getting a hint costs you a 'hint coin,' of which there are a limited amount (though plenty are hidden throughout the game world). When you solve a puzzle successfully, you are awarded a number of 'picarats' (essentially points). Each puzzle is worth so many of these picarats, with harder puzzles being worth more. Answer incorrectly and the value awarded goes down. I'm not sure what this point system is good for. At one point you learn that if you get enough of these picarats, something special happens. I never saw anything happen as a result of my score, so I must not have gotten enough. But enough about these details. Let's jump into my review.

The Good

Gorgeous Graphics
Professor Layton is drawn in an anime-style, with a distinctly European vibe. This particular title feels a little like something Hayao Miyazaki and his friends at Studio Ghibli would do, much in the vein of Howl's Moving Castle (a great movie, by the way). Not only does the static art look great, but there are a number of animated cut-scenes which are stunningly nice to watch. Hopefully more games will make use of this visual style!
Interesting Story
The storyline is quite unique, which is refreshing. I really felt as if I were playing through a movie, and the twists and turns throughout the story were entertaining. Much of the writing is top-notch, and a few genuinely funny moments made me laugh out loud.
Plenty of Puzzles
There are a total of 120 puzzles in this game, which offers plenty of game-play time. I only found about 100 of the puzzles (some of them are hidden in various parts of the village), so I plan on playing through one more time to make sure I find everything. Several mini-games (or mini-puzzles, whichever you may prefer) are also made available to you as you play through. You must build a device with 'gizmos' that you find, repair a painting via scraps that you find, and furnish the living quarters of both the Professor and Luke. The publisher even offers weekly downloads of new puzzles, though I haven't tried out that feature.
Great Voice Acting
A few of the animated cut-scenes include voice acting, the quality of which is excellent. The characters sound believable, and it's clear that a lot of work went into giving each one a unique personality.

The Bad

Difficulty Extremes
One of the most frustrating aspects of this game is the wildly varying difficulty levels between puzzles. Some are very straightforward, while others are ultimate mind-benders. A few of the puzzles had fairly low difficulty ratings in game, but I found myself stuck, indicating to me that not all of them are rated as accurately as they should be.
Little Punishment for Failure
There is very little punishment for failure on any given puzzle. Suppose you have a puzzle that's worth 50 picarats. Each time you fail, the value comes down by 5. But this deduction only ever happens 3 times. So, regardless of how many times you try this particular puzzle, you will score at least 35 picarats. This essentially means that you can brute force each puzzle, especially those that offer multiple choice answers. This feels like a cheap way to beat the system (though it's a handy way to get past those truly difficult puzzles).
Repetitive Music
The music, while not gratingly annoying like in Puzzle Quest, is very repetitive. To my knowledge, there's no way to turn it off either. You could turn down the DS speaker volume, but you might miss the audio in a cut-scene as a result (and you definitely don't want to do that). An option to disable the game music would be very welcome.
Over-sensitive Handwriting Recognition
Handwriting recognition is used throughout the game for you to enter answers to various puzzles. It seems a little too sensitive to me, and doesn't give you nearly long enough to write some characters that require two or more strokes (the letters T and F for example). As a result, some trial-and-error is required in order to answer correctly.
Not Enough Voice Acting
As impressed as I was with the animated cut-scenes and voice acting, I was disappointed that there wasn't more of it. The little snippets we get are truly high quality, but more would have been great.
Little Replay Value
Once you've solved all the puzzles, there's very little to draw you back to this title. The weekly puzzle releases from the publisher are interesting, but I doubt I'll keep up with them.

The Verdict

This was a fairly fun game, and I really loved the art direction. While each puzzle is unique, they get a little monotonous after completing 75 or so. I have to admit that I was really tired of the game by the end, but my desire to solve each mystery I uncovered kept me going. At least one sequel is planned for Professor Layton. Unless the gameplay is tweaked, I'm not sure I'll pick up any subsequent titles. But this initial offering was entertaining, at least for a little while. The eye candy and unique story are worth the price of admission. My final verdict: B

The Acid3 test for web browsers has been released. Drunken Fist has a number of screenshots that show the failure rate among the various top browsers. There are some really interesting results from the tests:

  • Safari 3: 39% success (latest nightlies are up to 87%)
  • Firefox 3: 59% success
  • Firefox 2: 50% success
  • Opera 9: 46% success
  • IE 7: 12% success
  • IE 6: 11% success

Safari is the surprising top dog in the list, but what I find most interesting is that Firefox 3 (which passes the Acid2 test) only hits 59% in the new test. I would have guessed that being Acid2 compliant would mean being nearly Acid3 compliant. Apparently, that isn't the case. It looks like web browsers still have a long way to go in the standards race.

I ran into an interesting side-effect with the foreach loop in Perl today. I'm surprised that I haven't hit this before, but it may be a subtle enough issue that it only pops up under the right circumstances. Here's a sample program that we'll use as an example:

#!/usr/bin/perl
use strict;
use warnings;

my @array = ("Test NUM", "Line NUM", "Part NUM");

for (my $i=0; $i < 3; $i++)
{
    foreach (@array)
    {
        s/NUM/$i/;
        print "$_\n";
    }
    print "------\n";
}

What should the output for this little script look like? Here's what I assumed it would be:

Test 0
Line 0
Part 0
------
Test 1
Line 1
Part 1
------
Test 2
Line 2
Part 2
------

But here's the actual output:

Test 0
Line 0
Part 0
------
Test 0
Line 0
Part 0
------
Test 0
Line 0
Part 0
------

So what's going on here? Well, it turns out that the foreach construct doesn't act quite like I thought it did. Let's isolate just that loop:

foreach (@array)
{
    s/NUM/$i/;
    print "$_\n";
}

We simply loop over each element of the array, we do a substitution, and we print the result. Pretty simple. Pay attention to the fact that we are storing each iteration through the loop in Perl's global $. The point here is that $ doesn't represent a copy of the array element, it represents the actual array element. From the Programming Perl book (which I highly recommend):

foreach VAR (LIST) {
    ...
}
If LIST consists entirely of assignable values (meaning variables, generally, not enumerated constants), you can modify each of those variables by modifying VAR inside the loop. That's because the foreach loop index variable is an implicit alias for each item in the list that you're looping over.

This is an interesting side effect, which can be unwanted in some cases. As a workaround, I simply created a temporary buffer to operate on in my substitution call:

foreach (@array)
{
    my $temp = $_;
    $temp =~ s/NUM/$i/;
    print "$temp\n";
}

An easy fix to a not-so-obvious problem.

Firefox 3 Gets Faster

Feb 28, 2008

A special nightly build of Firefox 3.0 has been released that greatly improves JavaScript performance. The build was run against the SunSpider JavaScript Benchmark, and the results are really surprising. From the article:

  1. Firefox 3 Nightly (PGO Optimized): 7263.8ms
  2. Firefox 3 Nightly (02/25/2008 build): 8219.4ms
  3. Opera 9.5.9807 Beta: 10824.0ms
  4. Firefox 3 Beta 3: 16080.6ms
  5. Safari 3.0.4 Beta: 18012.6ms
  6. Firefox 2.0.0.12: 29376.4ms
  7. Internet Explorer 7: 72375.0ms

This optimized build is nearly 4 times faster than the current release of Firefox, and 10 times faster than IE 7; pretty cool!

I have yet to switch to Firefox 3, mostly because lots of my favorite extensions don't yet work (including the ones I've written). There are a handful of changes that have to be made in order for extensions to work in the new environment, some of which aren't exactly trivial. As we get closer to an actual release, I'll do my best to update my extensions.

As if we needed any more proof that CAPTCHAs don't always work, it seems that spammers have now successfully cracked the GMail CAPTCHA. A one-in-five success rate is being reported, and it appears that there are multiple bot-nets taking a tag-team approach in hacking the sign up process. This is particularly dangerous, since Google's domains are highly unlikely to be blocked by any website or ISP.

I don't know what the solution to this problem is (if I did I'd be rich), but hopefully Google will figure out a way to prevent this kind of nefarious activity from continuing to happen.

Slashdot is running a story on RoadRunner intercepting domain typos. My dad noticed this 'feature' a few weeks ago, and opted out via their preferences page. In addition to the Slashdot story, Ryan Govostes has an interesting article (written back in December) on the security holes lurking in this opt-out program. According to his post, one could wreak all kinds of havoc with TWC's poorly written page, enabling or disabling the service for essentially all RoadRunner customers. SQL injections also appear to be a possible line of exploits.

A little over a year ago, I inherited a productivity tool at work that allows users to enter weekly status reports for various products in our division. The tool is web-based and is written entirely in Perl. One of the mangers who uses this tool recently suggested a new feature, and I decided to implement it using cookies. Having never implemented cookies from a programming perspective, I was new to the subject and had to do some research on how to do it in Perl. It turns out to be quite easy, so I figured I would share my newfound knowledge:

Creating a Cookie

Although there are other ways to do this (as always with Perl), this tutorial will be making use of the CGI::Cookie module. It makes creating and reading cookies very easy, which is a good thing. Furthermore, this module ships with virtually all Perl distributions! Here's a chunk of code that creates a cookie:

use CGI qw(:all);

my $cgi = new CGI;
my $cookie = $cgi->cookie(-name => 'my_first_cookie',
                          -value => $someValueToStore,
                          -expires => '+1y',
                          -path => '/');

print $cgi->header(-cookie => $cookie);

I first import all of the CGI modules. This isn't exactly necessary, and it might be a little slower than using the :standard include directive, but I needed a number of sub-modules for the tool I was writing. I then create a new CGI object, and use it to call the cookie() subroutine. This routine takes a number of parameters, but the most important ones are shown.

The -name parameter is simply what you want to name this cookie. You should use something that clearly identifies what the cookie is being used for (though you should always be mindful of the associated security implications). The -value parameter is just that: the value you wish to store in the cookie. I believe cookies have a bounds of around 4K of storage, so remember to limit what you store. Next up is the -expires parameter, which specifies how far into the future (or past) the cookie should expire. The value of '+1y' that we specified in the example above indicates we should expire in one year's time. Values in the past (specified with a minus sign) simply indicate that the cookie should be expired immediately. No value will cause the cookie to expire when the user closes their browser. Finally, the -path parameter indicates for what paths on your site the cookie should apply. A value of '/cgi-bin/' for example will only allow the cookie to work for scripts in the /cgi-bin folder of your site. We specified '/' in our example above, which means the cookie is valid for any path at our site.

Finally we print our CGI header, passing along a -cookie parameter with our cookie variable. As always, the documentation for the CGI module will give you lots more information on what's available.

Reading a Cookie

Reading back the value stored in a cookie is even simpler:

use CGI qw(:all);

my $cgi = new CGI;
my $someValue= $cgi->cookie('my_first_cookie');

Again we create our CGI object, but this time we use it to read our cookie, simply by calling the cookie() routine with the name of the cookie we created before. If the cookie is found, the stored value is read and stored into our variable ($someValue in the example above). If the cookie is not found, a null value is returned.

One Gotcha

In the tool I was working with, I was handling storing and reading the cookie on the same page. Since we have to create our cookie via the header() call, I was concerned about how to handle the case where we weren't creating a cookie. The solution, it turns out, is pretty simple:

use CGI qw(:all);

my $cgi = new CGI;
unless (param())
{
    print $cgiquery->header;
}

In this example, we print out a generic CGI header only if no parameters were passed in (i.e. the user didn't push us either a POST or GET). If we do have parameters, we want to create a cookie, and we'll send the header after we have done so. Pretty easy!

The long awaited Team Fortress 2 update arrives today! A new gameplay type, gold rush, is headlining this new release. A new control-point map, named "Badlands," has been released for Team Fortress 2, along with a slew of other new updates. A complete change log details what's new. In addition to the new map and game type, several other maps have been fixed, most importantly cp_dustbowl (which is still ridiculously hard to win as the BLU team).

Update: I was wrong about the game type. It looks like the new badlands map is simply a new control point map (which I'm still excited about trying).

Perl 5.10

Feb 11, 2008

I just found out about Perl 5.10, which has been out for some time now (released on December 18 ... how did I miss this?). The perldelta documentation goes into detail on what's new, but here's a brief overview of some of the features I find most appealing:

The 'feature' pragma

First and foremost is the feature pragma, which is used to turn on the new features added by 5.10. By default, the new features are disabled, and you explicitly have to request their support (a great idea, in my opinion). A simple use feature; statement will do the trick.

New 'Defined-Or' operator

A new // operator is now available, for handling the 'defined-or' case. For example:

$a // $b; # This is equivalent to the line below

defined $a : $a ? $b; # Same meaning as above

This new operator has the same precedence as the logical-or operator. In typical Perl fashion, the new operator is simply a shortcut that makes your scripts shorter and more difficult to read one month after you write it. ;)

Switch statements

At long last, Perl has a switch statement. The syntax here is quite different from other programming languages with which you might be familiar:

given ($state)
{
    when ("state_1") { $a = 1; }
    when (/^abcdef/) { $b = 2; }
    default { $c = 0; }
}

The various when tests allow for some powerful options, including: array slices, string compares, regular expression matches, and beyond.

Named captures in regular expressions

Suppose we want to read in a configuration file that contains lines with the following structure: option = value. Today, we could write a regular expression to capture these values like this: /(\w+) = (\w+)/. We would then access the captured values with $1 and $2.

In Perl 5.10, we could write the same expression like this: /(<?option>\w+) = (<?value>\w+)/. Now, the captured values are accessed through either the %+ or %- magical hashes, using each label as the key into each hash (see the perldelta documentation for the differences between the two hashes). This will make complex regular expressions much easier to decipher, and gets rid of the annoying parenthesis counting that we currently have to do.

Just 'say' it

The new say keyword is just like print, but it automatically adds a newline at the end of what it prints. How great is that? This simplifies printing code a little bit, especially for loops. Instead of print "$_\n" for @items; we can now use say for @items;. Clean and simple!

Stackable file tests

Doing multiple file tests is much easier now. Instead of if (-f $file and -w $file and -z $file) we can now write if (-f -w -z $file). Again, this makes things much cleaner.

Better error messages

Have you ever seen this error message? I know I have:

$str = "Hello $name! Today is $day and the time is $time.\n";

Use of uninitialized value in concatenation (.) or string at test.pl line 3.

In 5.10, this same error message will read:


$str = "Hello $name! Today is $day and the time is $time.\n";

Use of uninitialized value $time in
concatenation (.) or string at test.pl line 3.

Now I can know exactly where the error occurred! Finally!

And lots more

There are plenty of other new features that I haven't touched here: recursive regular expressions, a new smart matching operator, state ("static") variables, inside-out objects, and lots more. I'm really looking forward to trying out some of these new features.

Another game I finished recently is The Legend of Zelda: Phantom Hourglass for the Nintendo DS. This game took me quite a while to beat, mainly because there's so much to do (and I didn't do everything). I thought I'd write up a few thoughts I had.

The Good

Classic Zelda Gameplay
Phantom Hourglass is as much Zelda fun as I've had since the SNES classic A Link to the Past. Puzzles in the game are quite challenging, the action is spot on, and there's a laundry list of side quests and challenges. This is classic Zelda, through and through, and that's a very good thing.
Excellent Use of the DS Hardware
As I have mentioned before, Phantom Hourglass makes great use of the Nintendo DS hardware. The touch screen controls are incredible (I hope future games use it as good as this title did), and clever use of the microphone really added a new dimension to the gameplay.
Great Writing
The writing in this Zelda title is particularly strong. There are a lot of really great scenes, and the ending is one of the best I've experienced in a while. Over the course of the game, I really grew fond of the various characters, which is rare for me in a game like this.
Fun Side Quests
A large portion of the game is spent sailing various oceans on a ship. Several side quests go along with this game play, including treasure salvage and fishing. The treasure salvage mini-game is pretty fun, and there's plenty of fun to be had on the high seas.
Bottomless Wallet
This is the first Zelda title I know of where Link has no apparent limit to the number of Rupies he can pick up (if there was a limit, I didn't hit it). Finally!

The Bad

Annoying Repetition
One of the main 'puzzles' in the game involves traversing through the temple of the Ocean King. You end up having to go through this Temple 4 or 5 times, which gets old pretty quick. As you gain new items, you can go through the temple quicker, but it still gets a little tedious.
Insanely Difficult Puzzles
A few of the puzzles throughout the game are insanely difficult. "Maze Island" is impossible to do without a guide of some sort, which really frustrated me. Thankfully, there aren't many of these.

The Verdict

This title is a must own. If you don't own this, go out and buy it immediately. My final rating: A+

Slashdot is running a story on how Time-Warner is considering moving to a per-gigabyte service fee. According to them, 5 percent of their customers use over 50 percent of the network. So, because of these few "bad apples," they'll make everyone pay more. Steven Levy of the Washington Post has an interesting theory that Time-Warner is trying to hobble movie rentals via iTunes (trying to keep their pay-per-view stuff alive in the process).

I hope above anything else that this 'idea' of theirs never sees the light of day. Capping folks at 5-gigabytes (which is their current idea ... can you believe that?) is incredibly poor judgment. This kind of thing will single-handedly destroy the online viewing capabilities of Netflix, it will ruin online gaming, and it will make MSDN subscriptions irrelevant.

And that might just be Time-Warner's ultimate goal. Let's hope they fail in every way possible.

Last weekend I finally finished Metroid Prime 3. Here are some quick thoughts I had on the game:

What I Liked

  • The "Morph Ball" mode is incredibly fun. In essence, you become a pinball and get to roll through a number of tracks. There were plenty of puzzles that used this gameplay, and it ended up being my favorite part of the game.
  • The Wii-mote and Nunchuck controls work surprisingly well. This is the first FPS experience I've had with the Wii, and I was quite pleased.
  • Backtracking is well used in the game. There are plenty of areas that are inaccessible until you get certain powerups, forcing you to really explore every nook and cranny of every map.

What I Didn't Like

  • Loading times aren't what they should be. Levels are loaded in an on-demand fashion, and there are some times when the delay gets in the way.
  • The game feels a little too easy. Firefights end up being "how fast can you pull the trigger." Weapon powerups are obtained in a few places, but they never feel more powerful.

All in all, I highly recommend this game; it's a strong A in my book.

Here's a super great tip I learned from an article at Lifehacker.

My laptop here at work, a Lenovo ThinkPad, has a tremendously loud beep (through headphones, it will nearly blow your ears out). This beep occurs every so often when I'm typing faster than the computer thinks I should, and I end up pressing several keys on the keyboard at once. Thankfully, there's now a way to disable this annoying sound!

To temporarily disable the beep: net stop beep To permanently disable the beep: sc config beep start= disabled

In the latter command, note the space between the equals and the word 'disabled.' I'm not sure if that's necessary or not, but including it worked for me. The space is indeed required (thanks Dustin). I had no idea that a Windows service was responsible for this annoyance!

The MinWin Concept

Jan 28, 2008

There's an interesting article at InformationWeek about the new Windows architecture that Microsoft is developing. Windows 7, which is slated to be the successor to Vista, will use a new "MinWin" architecture. Essentially, the Windows core will be stripped down to the bare essentials, and additional functionality will be supplied through modules. According to the article, Eric Traut, a Microsoft distinguished engineer, demoed a version of the Windows core running with only a 25 MB footprint (as opposed to the 4 GB footprint of Vista).

I think this is a step in the right direction. Hard drive size increases have made sloppy programming, resulting in software bloat, much more prevalent. It's time to step back, trim the fat, and work towards leaner software.

My mom and I are watching Larry King last night, and he's talking with Robert Kiyosaki, a businessman and motivational speaker. The subject of conversation is the tanking US economy. Mr. Kiyosaki is wearing a hideously ugly suit and tie. On the phone with Larry and Robert is Donald Trump. The following scene ensues:

KING: Real estate is a good deal, even if you don't have the money. Donald, what's your feelings about the Bush administration and their handling of the crisis? TRUMP: I think the first thing I'd do if I were the president is I'd ask Robert to go out and buy a new suit and tie. That would help the economy and it would help Robert.

Zing! Who knew The Donald had such a great sense of humor? :D

TF2 Update Sneak Peek

Jan 23, 2008

PC Gamer apparently got a sneak peek at the updates coming for Team Fortress 2. Not too long ago, Valve teased the community with a somewhat cryptic message, saying that a 'large scale modification' was planned for the game.

According to the article, this large scale modification includes unlockable weapons for each class, which will be selectable from a load out screen. These changes will be rolled out to the Medic class first. The first weapon described is a new medi-gun that will permanently boost your teammates' health to 200% their normal values (instead of the temporary 150% boost that the current medi-gun supplies). There are no details yet on the second weapon, but it will be another medi-gun that will alter the class in a different way. It sounds like the first gun will be unlockable by acquiring half of the 35 new achievements coming for the Medic class, while the second update will be unlocked after acquiring them all. It should be interesting to see how this new feature pans out.

Another announcement is the new game type being planned, in which the attacking team will have to accompany a mine cart from one end of a map to the other. The article linked above goes into more depth about this game type, and it sounds super fun. In short, I can't wait for these updates!

There are a few gripes I've got with iTunes, all of which revolve around my subscriptions to podcasts:

1. Large downloads freeze iTunes (and sometimes the entire system) upon completion.
When a large (~250 to 500 MB) video podcast file has completed downloading, iTunes will completely freeze up. It feels to me like this hang is related to copying the file from a temporary download location to the intended destination (which is undoubtedly what iTunes is doing). Seeing as iTunes is a multi-threaded application, this should not, under any circumstance, happen. It should spawn a child thread to do the copy operation in the background, so that I can still use the application. Every once in a while, I even see my entire system hang up during this operation, which is doubly bad.
2. Some video files cannot be recycled immediately after viewing them.
After completing a video podcast, I find that I cannot immediately recycle the corresponding file from within iTunes. If I try to do so, the entry in iTunes is removed, but the file does not get removed! To recycle the file properly, I have to shut down iTunes, start it back up, and delete the entry. Somewhere a handle isn't being released properly, and the file remains locked. Again, this is a bug that could easily be solved.
3. The Windows screen saver screws up video playback.
If you have iTunes installed on a Windows system, try this experiment. Get a video file through iTunes (a video podcast for example), and start it playing. Pause the video and walk away from your computer for a while. Allow the screen saver to turn on and, when it has, come back to your computer. When the screen saver is cleared, try to play the video again. What happens? No video! This particular bug has existed for years (I've seen forum references to this bug as far back as iTunes 5 and 6), and it's apparently a known bug at Apple. That they don't get around to fixing it is very intriguing to me.

Matt Cutts has posted three security tips for WordPress users. Here's a quick overview:

  1. Protect your wp-admin directory with an .htaccess file
  2. Protect your wp-content/plugins folder with either a blank index.html or an .htaccess file
  3. Keep your WordPress install up to date by keeping tabs on the WordPress development blog

I was already doing item 1, though I don't currently handle IP white-listing (that's an appealing idea). Item 2 was something I didn't even know to do. When I checked to see if my plugins were listed, they did indeed show up. I have since corrected this issue. Item 3 is a no-brainer.

Matt also suggests removing the WordPress meta tag from your theme's header.php file (which I have also done). This particular "bonus" tip doesn't add a whole lot, but it at leasts cuts down on your broadcasting what version of WordPress you have installed.

Sun Purchases MySQL

Jan 18, 2008

It seems as if Sun Microsystems has purchased MySQL. I don't fully understand the motivation behind this purchase, but Sun must have some plan; otherwise they wouldn't have paid one billion dollars for the company. In my opinion, Sun doesn't have the greatest track record in software, so it should be interesting to see what happens as a result of this change. According to the official MySQL post:

Will MySQL’s support for other programming languages and operating systems now be given less attention? Absolutely not. MySQL is still being managed by the same people, and the charter is still the same.

We can only hope.

I got an email this morning mentioning the following:

This is just a notice that your DreamHost Account #XXXXX has a balance of $71.34 (including any charges not due until 2009-01-23), with $71.34 due (since 2008-12-23).

What?!? I renewed my subscription about a year ago (if I remember correctly), and I got a 2 year renewal, meaning that I should still have about a year left. Furthermore, I completely used rewards money to pay my bill (since I had it available), so my credit card was never charged to begin with. Thankfully, the credit card they have on file for me had expired, but I've lost all of my referral rewards! Needless to say, I was pretty upset by this. Then I found this post over at their emergency status blog: "billing issues". It seems like something went wrong, they know about it, and are fixing it.

I have yet to get my money back, and I have no doubt they'll fix the problem, but it bothers me nonetheless. This problem, coupled with the DreamHost hack seen back in June, are starting to concern me. Not to mention the fact that the server this blog is hosted on has degraded in performance drastically over the past several months. It might be time for me to find another web host. I'll be sure to keep you posted.

Update: To their credit, DreamHost has corrected the issue.